From what I can see in Home Assistant logs it does seem to send passive data but very sporadically, anywhere from (very roughly) 15 - 45 minutes apart. I have found killing the app and reconnecting forces the data to update which makes sense (and is handy for testing) and leads me on to my next question…
Regarding your comment below instead of a BLE integration would it be possible to force or emulate a connection to the app eg every 5 or 10 minutes to get consistent data?
I have not investigated if the fountain advertises its data passively, but I’d assume an active connection is required since, even with petkit’s BLE relay, an active connection to the fountain is made before any data is sent to the relay device. It would also explain why the PetKit app won’t update any fountain data / notify you about the water level being empty unless it is open and establishes an active connection to the water fountain.*
The integration already emulates what the app does: uses another PetKit device as a BLE relay (via the cloud) when connecting remotely. Regarding timing: the next release will include a higher period of time between BLE relay initiations and even a separate option for users to change it if they want to. From my own testing with different polling intervals over the past several months, their water fountains are just inconsistent with data, no way around it. I’ve even encountered using their app to connect directly (no BLE relay) to the water fountain and it states that water is running when physically I can see the water fountain is completely out of water.
Do you plan to add support for these devices? If you do, how soon can we expect it? I want to decide for the devices for my cat and you’re the deciding factor!
hi is there any update on the petkit yumshare support? i just bought the dual hopper and it doesn’t seem to be picking it up. i have two - a solo and a dual hopper. only the solo is working. thanks
I took some inspiration from your script as well as @RobertD502 's library, plus a metric ton of packet sniffing, and managed build a relatively simple python library around it, to expose most of the controls to MQTT, to enable HA’s MQTT Discovery.
It supports connecting to the W5-family of Petkit Water Fountains via Bluetooth Low Energy, without any Petkit WiFi enabled products.
There’s a few caveats, in terms of the secret being exchanged with the device, and scheduling of Do Not Disturb as well as Lights Out. Hopefully I get around to address the last two - but will have a hard time fixing (correct) generation of secrets, as I only have two devices and thus not nearly enough to reverse engineer the algorithm used.
So, for a bit of shameless self-promotion and plugging, you can find the library here, should it tickle your fancy: PetkitW5BLEMQTT
Change the path to the correct, for your python site-packages directory. You can find the path this way: python -c "import site; print(site.getsitepackages())"
To find the address of your petkit device, you can run this command: bluetoothctl scan le
PetKit devices will be prefixed with “Petkit” in the name
Afterwards you run the script this way: python main.py --address "A1:B2:C3:D4:E5:F6" --mqtt --mqtt_broker "broker.example.com" --mqtt_port 1883 --mqtt_user "user" --mqtt_password "password" --logging_level "INFO"
Remeber to change the arguments to suit your environment.
I’ll be adding a systemd service file in the future, until then the script can be run inside screen to achieve session persistency.
Please note - as the secret is not implemented, you will need to restart the script after the first run, to ensure that the non-compliant secret has been set to the device. This will stop the app from working, until power has been cycled!
Thanks - and sorry for hijacking your thread. Seemed like the right place to highlight it to the ones chasing a pure BLE integration
I’ve been through the app code multiple times, but it seems they’re generating the secret on the server side and delivering it as a response to the signup function within W5BleClient – the call consists of Serial Number, MAC address and the Device ID.
The security on the API seems rather … missing - so at some point I’ll try and write a script for poking at their API with data I’ve authored, in order to see if it’ll eat anything and hopefully derive their algorithm.
Not a problem at all. Interesting info….I haven’t looked into it, but I know that no info about the secret is transmitted to the initiating device (phone) when using the BLE relay function - my assumption is that the API is called and the server talks to the relaying device itself which is told what command to execute and the secret. Sniffing the communication between server and relay device on your network would be too complicated for the majority of users, so I don’t see grabbing the secret in this method being very useful.
Couple of questions come to mind:
Have you tried hooking into the app and seeing the exact data that is being transmitted/how it is being built along the way from phone to server? I guess the response could be captured by re-doing the registration process, but that wouldn’t be very user friendly and wouldn’t give us any info about what is going on server-side.
Have you investigated, when dealing with a reset water fountain that isn’t associated with an account/hasn’t been set up, if it can be used without needing to send a secret to it? Or, does the water fountain expect to go through a setup process? If it can be used when not associated with a PETKIT account, then users can remove/reset their water fountain(s) from their PETKIT account and rely solely on Home Assistant for controlling it/them.
I used to use the PetKit Integration with my PuraMax. However, after recently purchasing a new Element Solo auto feeder and adding it to the PetKit app, I noticed that the integration couldn’t discover the new feeder.
May I know how can I add the new PetKit device in HomeAssistant through the integration? Many thanks
Yes, it’s the feeder I bought
After I reloaded the integration, there’re still 2 devices only. One is PuraMax and one is my Pet.
Am I missing something?
Thanks a lot.
I’ve been through the code a couple of times, after intercepting the traffic using HTTP Toolkit and dumping the Bluetooth communication to btsnoop_hci.log (analyzed using Wireshark) – replicating the API calls is no issue at all, and the response is consistent across multiple calls with the same Serial Number, MAC and Device ID. The biggest concern in that regard, is the traffic being transferred using HTTP.
The entire initialization process seems to be transparent to the user, and happen in the background as part of the “Connecting to device” screen in the app.
It’s specifically the command 73 that sets the secret, and thus initializes the device - which is sent after 213, which retrieves the device ID for the API call to w5/signup.
I’ve tried with non-initialized water fountains, but they disconnect if command 73 is not issued, and thus not setting a secret. When the secret has been set, the connection initialization skips command 73 and goes directly to 213, 86 (contains the secret in bytes 3-8) and then 84 setting the date and time.
Device will respond to 86 with either a 1 or 0 – which seems to indicate if the secret was correct or not. This can be circumvented if the device has not been registered and thus not received the correct secret, or if 73 is reissued with a new secret - with the caveat that the app will not communicate with the device, unless its been power cycled.
Unfortunately there is no simultaneous use of the BLE connection, as the device stops advertising when a connection has been established - so regardless of the secret, the app and the library cannot be used at the same time.