This node module lets you connect to the sure petcare server and fetch/controll pet and device data.
⚠️ Important:Petcare has problems with the timeline(see reviews in paly store) this affects also the behavior for this code:
- Sometimes the
message
anddirect_message
listener is getting updates delayed- The computed property
pets
can have wrong values
I use this module in a project to send/command the surepetcare data over a telegram chat. You can find it here: https://github.com/Shokodev/mauzis
npm i node-surepetcare
import PetCare from 'node-surepetcare';
try {
const petcare = new PetCare({
mail:"your petcare mail",
password:"your petcare password"
});
petcare.on("message", (msg) => {
// Here you can listen for pre defined messages
//look in the "message events" section for more details
console.log(msg);
});
petcare.on("direct_message", (msg) => {
//* Here you can listen for unfiltered messages
//look in the "direct_message events" section for more details
console.log(msg);
});
petcare.on("started", (start) => {
//This event will be fired as soon as the initializing is done
//after creating a new instance of PetCare
console.log(start);
});
petcare.on("info", (info) => {
//Listen for info events like when a door command was triggert and so on
console.log(info);
});
petcare.on("error", (err) => {
//In case you need to notify somthing otherwise errors will be logged to the console
console.log(err);
});
} catch(err){
console.log(err);
}
By creating a new instance, you have to pass in a credentails otherwise an error will be thrown.
const petcare = new PetCare({
mail:"your petcare mail",
password:"your petcare password"
});
The constructor accepts also a options object in which some default settings can be overwritten. See in the options section for more details
const petcare = new PetCare({
mail:"your petcare mail",
password:"your petcare password"
},options);
- As soon as the instance is created it automatically begins to poll the sure petcare server (default every 10s).
- There starts also a automatic relogin by a node-cron job for updating the account token. (default every day at 11:00 and 23:00)
name | parameters | description |
---|---|---|
setDoorState | doorName :String command :Number (0=open) (1=lock_in) (2=lock_out) (3=lock_all) |
use this to look/unlook a flap/door |
setPetPlace | petName :String command :Number (1=inside) (2=outside) |
set your pet whereavout In/Outside |
resetFeeder | feederName :String command :Number (1=left) (2=right) (3=both) |
reset your feeder bowls |
resetFeeders | command :Number (1=left) (2=right) (3=both) |
reset all your feeders at once |
getTimelineEntriesBackTo | date :Date |
get all timeline entries back to the date you passed in be patient if go back to a long time ago |
getDeviceReport | - | get a report as String of all your devices and their battery levels |
getPetReport | - | get a report as String of all your pet whereabouts and states of your doors/flaps |
name | description |
---|---|
household | see below @ household property |
pets | see below @ pets property |
felaqua_level | current level of felaqua in ml (if you have one) |
This property is updated in every poll and holds the surepetcare data. The structure of this object is the same as in the surepetcare and is diffrent for every user. You can easy inspect what you get there by using a browser. Go to https://www.surepetcare.io/ hit F12 and look in the network tab for the second "start" XHR. What you can see there under data will be in the houshold property
This property holds computed data of all pets depending on what devices you have. It is updated by every poll as well.
Structure:
"name of pet": {
"props like list below"
},
"name of other pet": {
"props like list below"
},
etc.
name
name of petpetID
id of petdevice
assigned feeder deviceplace
whereabout of petdeviceName
assigned feeder device namerightTarget
*fill target of right bowlleftTarget
*fill target of left bowlcurrentLeft
*current gram in left bowlcurrentRight
*current gram in right bowllastEatenLeft
*lasttime ate in grams of left bowllastEatenRight
*lasttime ate in grams of right bowleatenLeftSoFar
*has eaten today so far in grams of left bowleatenRightSoFar
*has eaten today so far in grams of left bowldrank
*drank so far todaylastFillLeft
*lasttime filled in left bowllastFillRight
*lasttime filled in right bowleatenLeft
*has eaten since last filling in grams of left bowleatenRight
*has eaten since last filling in grams of right bowl
*if you are using just one bowl, all infos should be just in the "left" props
In this listener you get updates from petcare in pre defined strings which can be custom overwritten with the options object
- Pet goes through a door => option:
petMovementText
(type 0) - Unknown movement of door => option:
unknownMovementText
(type 7) - Filling bowl/bowls => option:
filledBowlText
(type 21) - Pet has eaten => option:
petHasEatonText
(type 22) - Feeder was reseted => option:
resetFeederText
(type 24) - Battery threshold reached => option:
batteryLowText
(type 1) - Pet drank => option:
petDrankText
(type 29) - Filling Felaqua => option:
felaquaFillText
(type 30) - Reminder Fresh Water for Felaqua => option:
felaquaReminderText
(type 32) - Unknown Felaqua drinking => option:
felaquaUnknownDrinkerText
(type 34)
In this listener you get all the timeline events of surepetcare in the same structure as the server sends it. The message object structure can differ from type to type, best way to see how your needed msg is structured is to use a browser again. Go to https://www.surepetcare.io/ hit F12 and look in the network tab for a number entry as in the screen shot. (The number is your houshold id)
You can pass in a options property to the constructor of the PetCare Class to overwrite some settings and the messages of the message events listener
Here is a example of a full options object of all possible settings, as I use it (In swiss german 😛):
const options = {
update_polling_seconds: 10,
message_throttle_ms: 100,
battery_full: 1.4,
battery_low: 1.15,
login_cycle: '0 11,23 * * *',
somethingWrongMsg: "öpis isch nid guet😑",
successMsg: "ok 😊",
doorOpenText: "offe",
doorlockedInText:"zue vo inne",
doorlockedOutText:"zue vo usse",
doorlockedAllText:"ganz zue",
petInsideText: "dinne",
petOutsideText: "dusse",
tareLeftText: "links",
tareRightText: "rechts",
tareBothText: "uf beidne site",
doorIsAlready: (doorName, state) => `${doorName} isch dänk scho ${state}😝`,
petIsAlready: (petName, state) => `${petName} is isch dänk ${state}🙄`,
petMovementText: (petName, bit) => bit === 1 ?
`${petName} isch jetz dinne, Hello ${petName} 😍` :
bit === 2 ? `${petName} isch use, stay safe ❤️` :
`${petName} het dürs törli gluegt 👀`,
unknownMovementText: (bit) =>
bit === 2 ? "Het äuä öper d Hang durs törli gha..." :
"Es angers chätzli het id stube gluegt 😺",
petHasEatenText: (petName, left, right) => `${petName} hat gässe:\n ${left}g droche & ${right}g nass`,
filledBowlText: (bowlName, left, right) => `${bowlName} gfüllt mit:\n ${left}g droche & ${right}g nass`,
resetFeederText: (bowlName, tareVal) => `${bowlName} isch ${tareVal} zrüggsetzt worde`,
batteryLowText: () => `ignore`,
petDrankText: (petName,val) => `${petName} het ${val}ml drunke💧`,
felaquaFillText:(deviceName,val) => `${deviceName} mit ${val}ml befüllt`,
felaquaReminderText: (deviceName) => `${deviceName} set neus wasser ha`,
felaquaUnknownDrinkerText: (deviceName, val) => `Igrendöpper het ${val}ml drunke us ${deviceName}`,
petWhereaboutText:(petName,where) => `${petName} isch ${where} ${where === "dinne" ? '😊': '🧐'}`
}