Open cjattard opened 1 year ago
{"result":[{"breakdownWarning":0,"createdAt":"2022-11-23T14:43:13.000Z","expectedCleanWater":0,"expectedUseElectricity":0.0,"filterExpectedDays":0,"filterPercent":94,"filterUpdatedAt":"2022-11-25T09:27:07.000Z","filterWarning":0,"firmware":47,"hardware":2,"id":100027248,"isNightNoDisturbing":0,"lackWarning":0,"mac":"xxxxxxxxxx","mode":2,"name":"Water Bowl","powerStatus":1,"recordAutomaticAddWater":0,"relation":{"userId":"10022xxxx"},"runStatus":0,"secret":"c1b6f470c84c","settings":{"disturbConfig":2,"disturbMultiTime":[{"repeats":"1,2,3,4,5,6,7","time":[1320,360]}],"lampRingBrightness":1,"lampRingGoOutTime":1440,"lampRingLightUpTime":0,"lampRingSwitch":1,"lightConfig":2,"lightMultiTime":[{"repeats":"1,2,3,4,5,6,7","time":[360,1320]}],"noDisturbingEndTime":360,"noDisturbingStartTime":1320,"noDisturbingSwitch":0,"smartSleepTime":1,"smartWorkingTime":2},"sn":"31220321S3xxxx","timezone":0.0,"todayCleanWater":0,"todayPumpRunTime":33619,"todayUseElectricity":0.0,"typeCode":4,"updateAt":"2022-11-25T09:27:07.000Z","userId":"10022xxxx","voltage":-1,"waterPumpRunTime":151118}]}
img5.petkit.cn\/discovery\/2022\/8\/17\/62fc9686c09fd9000d48ab48Zxxxxxx","maintenanceMode":"http:\/\/img5.petkit.cn\/discovery\/2022\/8\/17\/62fc973ec09fd9000d48ab5eixxxxxx"}},"w5":{"deviceData":{"recordAutomaticAddWater":1,"timezone":0,"updateAt":"2022-08-08T07:26:28.000Z","secret":"c4dadxxxxxx","mac":"a4c1xxxxxx","relation":{"petIds":["1331669"],"userId":"596381"},"mode":2,"waterPumpRunTime":4064239,"createdAt":"2022-03-14T01:55:44.000Z","expectedCleanWater":-1,"powerStatus":1,"breakdownWarning":0,"id":-1,"sn":"31220226S30041","filterWarning":0,"firmware":36,"lackWarning":0,"runStatus":1,"hardware":2,"settings":{"smartSleepTime":1,"noDisturbingEndTime":360,"noDisturbingStartTime":1320,"noDisturbingSwitch":0,"smartWorkingTime":3,"lampRingLightUpTime":0,"lampRingBrightness":2,"lampRingGoOutTime":1440,"lampRingSwitch":1},"isNightNoDisturbing":0,"todayPumpRunTime":23040,"filterUpdatedAt":"2022-08-08T07:26:28.000Z","todayCleanWater":500,"todayUseElectricity":0.0048,"userId":"596381","typeCode":4,"voltage":0,"filterExpectedDays":15,"filterPercent":37.5,"name":"\u667A\u80FD\u996E\u6C34\u673A","expectedUseElectricity":0.0048},"shareUrl":{"url":"https:\/\/bit.ly\/3SYYQEq"},"gifs":{"springWater":"http:\/\/img5.petkit.cn\/discovery\/2022\/8\/17\/62fc99f7c09fd9000xxxxxx","stopWater":"http:\/\/img5.petkit.cn\/discovery\/2022\/8\/23\/6304bbec102cc8000dexxxxxx","smartMode":"http:\/\/img5.petkit.cn\/discovery\/2022\/8\/29\/630c2baee3bc46000d3xxxxxx"}},
+1
Need more packet capture records.
'devices': [{'type': 'W5', 'data': {'mode': 1, 'createdAt': '2023-01-09T23:21:36.000Z', 'settings': {'disturbConfig': 2, 'disturbMultiTime': [], 'lampRingBrightness': 1, 'lampRingGoOutTime': 1320, 'lampRingLightUpTime': 480, 'lampRingSwitch': 1, 'lightConfig': 2, 'lightMultiTime': [], 'noDisturbingEndTime': 360, 'noDisturbingStartTime': 1320, 'noDisturbingSwitch': 0, 'smartSleepTime': 3, 'smartWorkingTime': 3}, 'name': 'EVERSWEET', 'id': xxxxxx, 'filterWarning': 0, 'lackWarning': 0, 'runStatus': 1, 'relation': {'petIds': ['xxxx', 'xxxxx'], 'userId': 'xxxx'}, 'typeCode': 4}},
I think the key items are 'filterWarning': 0, 'lackWarning': 0, 'runStatus': 1
Quick and dirty fix to get the status if the device is running or needs water. In init.py change line 335:
@property
def state(self):
sta = self.data.get('state') or 0
dic = {
'1': 'online',
'2': 'offline',
'3': 'feeding',
'4': 'mate_ota',
'5': 'device_error',
'6': 'battery_mode',
}
if self.device_type == 'w5':
sta = self.data.get('lackWarning')
dic = {
'0': 'OK',
'1': 'ERROR',
}
return dic.get(f'{sta}'.strip(), sta)
Quick and dirty fix to get the status if the device is running or needs water. In init.py change line 335:
@property def state(self): sta = self.data.get('state') or 0 dic = { '1': 'online', '2': 'offline', '3': 'feeding', '4': 'mate_ota', '5': 'device_error', '6': 'battery_mode', } if self.device_type == 'w5': sta = self.data.get('lackWarning') dic = { '0': 'OK', '1': 'ERROR', } return dic.get(f'{sta}'.strip(), sta)
Thankyou, just added this workaround and it works a treat. thank you.
Hi, I purchased a new Petkit EVERSWEET 3 PRO water fountain today. The updated integration is able to pull it in, but, the data seems off. Fountain is full, new filter, etc. working in the official app. The HACS integration pulls in the following:
binary_sensor.w5_1XXXXXX95_food_state = on [device class problem, therefore saying its empty? It's full] sensor.w5_1XXXXXX95_state = off [the fountain is on and functioning]
I did notice that the sensors are > 1 hr old, maybe not picking it up? Is there a way to force an update? Everything is functional on the official app. Happy to help troubleshoot, US [Americas] based. I have a feeder and litterbox both working well.
Thanks
@yieldhog Regarding the water fountain status - this is due to how Petkit handles updating the data. I've had this problem for months now as I originally integrated the water fountain via Node Red. If a compatible feeder/petkit device with bluetooth is paired to the water fountain (for remote access), the associated device doesn't seem to be periodically polling the water fountain to update its status on PetKit's servers. Updating the status requires you to open up the PetKit app which will then initiate updating the data (either via direct bluetooth connection from your phone or the remote access initiating the associated device to start a bluetooth connection to the water fountain).
It is a big flaw in how they have the system set up right now and I've complained to them about this months ago - Even using their own app, there is no way of knowing the water is out via a notification from the PetKit app unless you manually open up the PetKit app and start the bluetooth connection one way or the other (via direct connection or via associated device during remote access).
I'll have to sniff around and see if something is sent during remote access that can be replicated as a means of getting associated devices to connect to the water fountain to poll for an update.
@al-one I have been able to sniff out the ble endpoints needed to force an associated device to poll the water fountain for updates.
Step 1:
A POST request is made to the ble/connect
endpoint:
POST /latest/ble/connect HTTP/1.1
Host: api.petkt.com
X-Session: <Redacted>
Content-Type: application/x-www-form-urlencoded
Accept: */*
X-Location: <Redacted>
Proxy-Connection: keep-alive
X-Timezone: -5.0
F-Session: <Redacted>
Accept-Language: en-US;q=1, it-US;q=0.9
Accept-Encoding: gzip, deflate
X-Api-Version: 8.28.0
X-Client: ios(15.1;iPhone14,3)
Content-Length: 40
User-Agent: PETKIT/8.28.0 (iPhone; iOS 15.1; Scale/3.00)
Connection: keep-alive
X-TimezoneId: America/New_York
X-Img-Version: 1
X-Locale: en_US
The body is a URLEncoded form as seen below:
bleId=<Water Fountain ID>
mac=<Water Fountain MAC>
type=<Explained Below>
Regarding the type
field: This is a combination of the "typeCode" of the device that is associated with the Water Fountain and the "typeCode" of the Water Fountain - For example, the D4 feeder that I have linked to my Water Fountain has a typeCode of 1 and the Water Fountain has a typeCode of 4. So, in the URLEncoded form above I'd set the type to 14
to get the D4 feeder to initiate a BLE connection to the W5 Water Fountain.
If the connection is successful the response body is as follows:
{
"result": {
"state": 1
}
}
Step 2:
A POST request is made to the ble/poll
endpoint:
The requests is the exact same as in Step 1, except to the poll endpoint instead of connect endpoint. Note this requests also sends a URLEncoded form with the bleId, mac, and type.
The response to this call is as follows:
{
"result": 0
}
If the device fails to connect and the connection is timed out, the response is as follows:
{
"result": -1
}
At this point, data for the water fountain should reflect up-to-date data. Having polled the device, we can then close the connection.
Step 3:
Close the BLE connection by making a POST request to the ble/cancel
endpoint:
The requests is the exact same format as seen in step one and uses the same URLEncoded form. If we don't disconnect then the connection will eventually time out.
Determine if user has set up BLE relay:
In order to determine if polling the Water Fountain via a BLE connection is even possible, we first need to determine if a user has set up the relay function. This can be easily done by looking at the response from the http://api.petkt.com/latest/discovery/device_roster
endpoint. If a relay is set up, the key hasRelay
is set to True.
Determine the associated device:
In order to compose the correct type
to be sent for the BLE connection, we need to know what device is being connected to the Water Fountain. One way to do this is to send a POST request to http://api.petkt.com/latest/ble/ownSupportBleDevices
with no content. The response contains a list of devices that support a remote connection and can be used to connect to the Water Fountain.
Since I only have one, my response looks like this:
{
"result": [
{
"id": Redacted,
"lowVersion": 0,
"mac": "Redacted",
"name": "Milo’s Feeder",
"pim": 1,
"sn": "Redacted",
"typeId": 11
}
]
}
We can use this endpoint to look up the device, by id, and fetch its typeCode. This can then be used to create the correct type to be sent to the ble/connect and ble/poll endpoints.
Only issue I can see with this is a scenario where a user has multiple supported BLE relay devices, so, we'd need to see the response that would be generated there and how the BLE connection is handled in such a scenario.
Hope this helps!
Can these APIs be called through service: petkit.request_api
in automation ?
It could, but there are a few problems that would need to be addressed:
I wouldn't have a problem doing this on my install, but it may be beyond reach for every day HA users. Handling this internally in the integration would be more user friendly.
@yieldhog Regarding the water fountain status - this is due to how Petkit handles updating the data. I've had this problem for months now as I originally integrated the water fountain via Node Red. If a compatible feeder/petkit device with bluetooth is paired to the water fountain (for remote access), the associated device doesn't seem to be periodically polling the water fountain to update its status on PetKit's servers. Updating the status requires you to open up the PetKit app which will then initiate updating the data (either via direct bluetooth connection from your phone or the remote access initiating the associated device to start a bluetooth connection to the water fountain).
It is a big flaw in how they have the system set up right now and I've complained to them about this months ago - Even using their own app, there is no way of knowing the water is out via a notification from the PetKit app unless you manually open up the PetKit app and start the bluetooth connection one way or the other (via direct connection or via associated device during remote access).
I'll have to sniff around and see if something is sent during remote access that can be replicated as a means of getting associated devices to connect to the water fountain to poll for an update.
@RobertD502 Thanks, I think that's exactly right. My water fountain ran out a couple of times and I wasn't notified until I actually opened the app and checked, defeating the entire purpose of the system. This is beyond my scope in terms of programming, but I'm happy to test any possible solutions.
@RobertD502 would it matter if I only have one BLE device? I have a Feeder Mini (wifi, works great w/ this integration) and Pura X litter box (wifi, also works great).
@RobertD502 would it matter if I only have one BLE device? I have a Feeder Mini (wifi, works great w/ this integration) and Pura X litter box (wifi, also works great).
Do you have the relay set up in the app (I don't own one, but I believe the Pura X is compatible and can be used as a relay for the water fountain)? I have two feeder minis, but had to get a third (D4 - I think it is the fresh element solo) because the mini can't be used as a relay for the water fountain.
I have the Pura x so happy to help with any testing if it’s useful.
I was wondering. In the config in this amazing repo we can specify the refresh / polling rate. (Mine is currently 3 mins) could there be the ability to include the app code in that module - tricking Petkit into thinking the app was opened?
I'm not quite sure what you mean by my app.
@cjattard The stuff that I posted was to showcase how the BLE relay works. It most certainly can be implemented. However, it looks like the original author prefers to have users make undefined API calls via the service in this integration. The downside to that is that you have to figure out the typeCodes of the two devices (the main device and the water fountain) on your own in order to construct the proper type
key that is sent.
@RobertD502 I took a look at the Petkit app and it appears to be periodically relaying .. unfortunately my devices are probably 30' apart so they may not have a great BLE connection. I am happy to try and test using the service call, but, I'm not exactly sure what commands to send. For example, I tried one of your urls above and received {"error":{"code":5,"msg":"Login session expired. Please log in again."}} -- not exactly sure how to format to login.
If you took a look at the PETKIT app (opened it) then it automatically turned on the relay at that time, which would falsely be perceived as the relay periodically turning on and updating data.
Regarding using the endpoints: that I would take up with the original author. I've deleted the integration as I'm not a fan of how sensors are handled/not grouped by device and implemented my own way of pulling in data.
@yieldhog Just got done with the initial code for the backend library. It is limited to D4 feeders, mini feeders, and w5 water fountains at this moment. I'll get to work on building out the integration starting tomorrow and will definitely need some testers / access to litter boxes to get them integrated properly.
@RobertD502 very cool, I’m happy to help test
i'm happy to test too, got the Pura X litter box, Fresh Element feeder, and the w5 water bowl.
If either of you use discord, you can reach me at the Home Assistant PetKit server. I can keep you updated on there/discuss questions.
Hello, I have this service up and running on my Pura X litterbox and petkit feeder - it's probably the killer integration for me for home assistant! so Thankyou.
I have recently bought the Petkit EVERSWEET 3 PRO water fountain, the API is exposing the following information:
I presume these attributes would need assigning some form of type to be able to be used by home assistant.
full disclosure I am a novice at coding but anything I can do to help provide support or diagnostics guidance I would be more than up for learning here.
Thanks