python-sonicare icon indicating copy to clipboard operation
python-sonicare copied to clipboard

Feature Request: Integrate with Home Assistant

Open IIAIronWolf opened this issue 3 years ago • 37 comments

I would love to see this make its way into a Home Assistant integration.

IIAIronWolf avatar Jul 06 '21 05:07 IIAIronWolf

Same here Alternatively or in addition an app for iphone to implement apple health data localy rather than the data greedy sonicare app by Philips

lars-dev avatar Dec 12 '21 16:12 lars-dev

would be very nice if somebody could make this happen :D

u20p17 avatar Oct 12 '22 07:10 u20p17

With the new BLE support in Home Assistant and the ability to use esphome devices as bluetooth proxies, this would be a great time this integration. You can see support for many other devices being added (i.e. oral-b, swtichbot, etc)

https://github.com/Bluetooth-Devices

The predecessor to this repo was a custom integration called Passive BLE Monitor and it had a process to request new sensors - https://custom-components.github.io/ble_monitor/sensor_request I do not have a BLE enabled sonicare at this point but perhaps someone else does and could work on this.

apaperclip avatar Nov 02 '22 01:11 apaperclip

The sonicare toothbrushes were not compatible with the 'old' passive BLE Monitor, because it has an active communication protocoll... Nevertheless, I think it should work with the new BLE support in HomeAssistant, because the bluetooth proxis now also can handle active communication. I have not the knowhow to make an custom component for this, but I could help an developer with testing and generating logs in order to make it working... :) Maybe somebody has the knowhow and has time to develop it (Y)

u20p17 avatar Nov 02 '22 08:11 u20p17

I agree that getting this into Home Assistant would be awesome. Even though we don't know what all the BLE services translate to, just getting the basic on/off state into Home Assistant would be helpful for many automations. @bdraco I have seen you pop up a few times in your work with Home Assistant/BLE stuff, and I think you recently worked on the Oral-B integration. Do you think basic Sonicare integration is a possibility, given this project? How big of a lift would that be, in your opinion? This might be something we could all work on together, if necessary (and with your guidance!)

villasenor avatar Nov 02 '22 23:11 villasenor

Even though we don't know what all the BLE services translate to, just getting the basic on/off state into Home Assistant would be helpful for many automations.

The page from the repo owner has a lot of info about what is available - https://blog.johannes-mittendorfer.com/artikel/2020/10/my-toothbrush-streams-gyroscope-data

apaperclip avatar Nov 03 '22 12:11 apaperclip

From the docs it doesn’t look like the device has data in the advertisements so it requires an active connection which makes it much more difficult to integrate.

It’s possible it actually does but someone with the device would have to do that investigation

bdraco avatar Nov 03 '22 13:11 bdraco

Thanks for taking a look! I have the device and I think a few others here do as well. What should I look for? And what's the best way to collect and analyze that data?

villasenor avatar Nov 03 '22 18:11 villasenor

And what's the best way to collect and analyze that data?

https://community.home-assistant.io/t/oral-b-support-toothbrush-model-3764/483732/2?u=bdraco

bdraco avatar Nov 03 '22 18:11 bdraco

Thanks for taking a look! I have the device and I think a few others here do as well. What should I look for? And what's the best way to collect and analyze that data?

I was going to say if you don't have a BT-attached HA close enough to the toothbrush, I like the nRF connect app on my phone to see what is advertised as a quick test. But then I realized its a toothbrush and pictured you standing by your HA instance in somewhere like the basement brushing your teeth trying to capture data.

Also, the kids Sonicare seems to have BT abilities and is only ~30 USD if someone was looking for one.

apaperclip avatar Nov 03 '22 19:11 apaperclip

And what's the best way to collect and analyze that data?

https://community.home-assistant.io/t/oral-b-support-toothbrush-model-3764/483732/2?u=bdraco

Hi, i activated the debug log for bluetooth in HomeAssistant and started my toothbrush... ;) in the logs I found the following:

2022-11-03 21:26:15.983 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] kuehlung-lowboard: 61:A7:80:AC:98:0C AdvertisementData(manufacturer_data={76: b'\x10\x07\x14\x1f\xa6\xa6\x05\xa9H'}, tx_power=-127, rssi=-75) connectable: True match: set() rssi: -75
2022-11-03 21:26:28.470 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] kuehlung-lowboard: 45:E0:E5:16:24:A6 AdvertisementData(manufacturer_data={76: b'\x10\x05%\x18\xdc\xb2\xef'}, tx_power=-127, rssi=-71) connectable: True match: set() rssi: -71
2022-11-03 21:30:57.249 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] F0:9E:4A:85:6A:0A: D8:CB:3C:A4:C5:3F AdvertisementData(manufacturer_data={89: b'\xd8\xcb<\xa4\xc5?'}, rssi=-101) connectable: True match: set() rssi: -101
2022-11-03 21:31:59.213 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] kuehlung-lowboard: 18:57:98:5D:F1:FD AdvertisementData(manufacturer_data={6: b'\x01\t \x02+>a\xa2Fy\xc8@\xd7\xa5n\xd1\xb8\x85\xba\x96\x96\x1b_\xe7\xfd\xc6\x07'}, tx_power=-127, rssi=-65) connectable: True match: set() rssi: -65

Is this information useful?

u20p17 avatar Nov 03 '22 20:11 u20p17

2022-11-03 21:26:15.983 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] kuehlung-lowboard: 61:A7:80:AC:98:0C AdvertisementData(manufacturer_data={76: b'\x10\x07\x14\x1f\xa6\xa6\x05\xa9H'}, tx_power=-127, rssi=-75) connectable: True match: set() rssi: -75

This is likely an apple device

2022-11-03 21:26:28.470 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] kuehlung-lowboard: 45:E0:E5:16:24:A6 AdvertisementData(manufacturer_data={76: b'\x10\x05%\x18\xdc\xb2\xef'}, tx_power=-127, rssi=-71) connectable: True match: set() rssi: -71

This is likely an apple device

2022-11-03 21:31:59.213 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] kuehlung-lowboard: 18:57:98:5D:F1:FD AdvertisementData(manufacturer_data={6: b'\x01\t \x02+>a\xa2Fy\xc8@\xd7\xa5n\xd1\xb8\x85\xba\x96\x96\x1b_\xe7\xfd\xc6\x07'}, tx_power=-127, rssi=-65) connectable: True match: set() rssi: -65

This is likely a microsoft device



    

  

Is this information useful?

None of them are likely tooth brushes

All the oralB ones will be {220: aka https://github.com/hbldh/bleak/blob/aa24332a39952880005705155629df423fbad1aa/bleak/backends/_manufacturers.py#L226

bdraco avatar Nov 03 '22 20:11 bdraco

now i found the right log entries:

2022-11-03 21:10:13.431 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] F0:9E:4A:85:6A:0A: 24:E5:AA:06:A2:BD AdvertisementData(local_name='Philips Sonicare', rssi=-97) connectable: True match: set() rssi: -97
2022-11-03 21:10:14.014 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] F0:9E:4A:85:6A:0A: 24:E5:AA:06:A2:BD AdvertisementData(local_name='Philips Sonicare', service_uuids=['477ea600-a260-11e4-ae37-0002a5d50001'], rssi=-93) connectable: True match: set() rssi: -93
2022-11-03 21:24:12.960 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] F0:9E:4A:85:6A:0A: 24:E5:AA:06:A2:BD AdvertisementData(local_name='Philips Sonicare', service_uuids=['477ea600-a260-11e4-ae37-0002a5d50001'], rssi=-92) connectable: True match: set() rssi: -92
2022-11-03 21:24:20.461 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] Philips Sonicare (24:E5:AA:06:A2:BD): Switching from F0:9E:4A:85:6A:0A[True] to kuehlung-lowboard[True] (new rssi:-79 - threshold:5 > old rssi:-92)

@bdraco , does this help?

u20p17 avatar Nov 03 '22 20:11 u20p17

now i found the right log entries:

2022-11-03 21:10:13.431 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] F0:9E:4A:85:6A:0A: 24:E5:AA:06:A2:BD AdvertisementData(local_name='Philips Sonicare', rssi=-97) connectable: True match: set() rssi: -97
2022-11-03 21:10:14.014 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] F0:9E:4A:85:6A:0A: 24:E5:AA:06:A2:BD AdvertisementData(local_name='Philips Sonicare', service_uuids=['477ea600-a260-11e4-ae37-0002a5d50001'], rssi=-93) connectable: True match: set() rssi: -93
2022-11-03 21:24:12.960 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] F0:9E:4A:85:6A:0A: 24:E5:AA:06:A2:BD AdvertisementData(local_name='Philips Sonicare', service_uuids=['477ea600-a260-11e4-ae37-0002a5d50001'], rssi=-92) connectable: True match: set() rssi: -92
2022-11-03 21:24:20.461 DEBUG (MainThread) [homeassistant.components.bluetooth.manager] Philips Sonicare (24:E5:AA:06:A2:BD): Switching from F0:9E:4A:85:6A:0A[True] to kuehlung-lowboard[True] (new rssi:-79 - threshold:5 > old rssi:-92)

@bdraco , does this help?

That's the one. Looks like there isn't anything useful in the advertisement so the device would require an active connection. That makes it a poor candidate to integrate as an active connection would drain the battery.

bdraco avatar Nov 03 '22 20:11 bdraco

hmm, you mean that the toothbrush would need a permanent active connetion to HA? or only when you are brushing the teeth? in the second case I think that the battery shouldn't be the huge problem, because (at least for me) I put the toothbrush on the charger evertime I finished with the brushing... But I understand that the integration will not be that easy due to the fact, that an active connection is needed. Wouldn't it be possible to use the python code from this repo as a starting point for the custom component? (sorry for the (maybe) stupid question, but I am not a python programmer nor I am into developing custom components... ;) )

u20p17 avatar Nov 03 '22 20:11 u20p17

hmm, you mean that the toothbrush would need a permanent active connetion to HA?

Yes, otherwise you wouldn't know when it turns on and off

or only when you are brushing the teeth? in the second case I think that the battery shouldn't be the huge problem, because (at least for me) I put the toothbrush on the charger evertime I finished with the brushing...

But I understand that the integration will not be that easy due to the fact, that an active connection is needed.

BLE adapters have limits to how many connections they can handle at the same time. Some can only handle 1, some will only handle 3, and some of the better ones will handle up to 9. As such holding an active connection comes at a premium since the majority of devices only need an active connection for a few seconds when you are interacting with them.

Wouldn't it be possible to use the python code from this repo as a starting point for the custom component? (sorry for the (maybe) stupid question, but I am not a python programmer nor I am into developing custom components... ;) )

This code doesn't use bleak so it would be quite difficult to integration into HA as you'd have to rewrite the bulk of it

bdraco avatar Nov 03 '22 20:11 bdraco

Hmm. Yeah I think only initiating the active connection when HA hears an advertisement (which I think would only happen when the toothbrush is picked up/turned on? I'd need to test.), or even manually activating the "listening" via another automation is a reasonable compromise. I would also be willing to deploy a dedicated ESP BLE Proxy for something like this, so I'm not worried about the number of connections. I also don't think an active connection is needed all the time. The way the app works, is that you have to open the app and connect it to the toothbrush while you are using it. There is no passive data collection into the app. Do you have any example integrations for other devices that use an active connection? If so, I could maybe look at adapting that.

villasenor avatar Nov 03 '22 21:11 villasenor

Hmm. Yeah I think only initiating the active connection when HA hears an advertisement (which I think would only happen when the toothbrush is picked up/turned on? I'd need to test.), or even manually activating the "listening" via another automation is a reasonable compromise.

You may find its sending advertisements regardless if its on or not.

I would also be willing to deploy a dedicated ESP BLE Proxy for something like this, so I'm not worried about the number of connections. I also don't think an active connection is needed all the time. The way the app works, is that you have to open the app and connect it to the toothbrush while you are using it. There is no passive data collection into the app. Do you have any example integrations for other devices that use an active connection? If so, I could maybe look at adapting that.

You could look at led-ble as its an always connected integration

bdraco avatar Nov 03 '22 21:11 bdraco

Thanks! If I can find some time, I'll play around with this. If anyone else wants to work on this as well, feel free!

villasenor avatar Nov 04 '22 00:11 villasenor

Quick update! Did some testing this evening with the Sonicare DiamondClean Smart (HX993X) BLE brush. If the brush has been laying motionless for a period of time, all BLE activity stops. I tested this while it was in the charger, and laying on a table. As soon as the brush is "woken up" (either by removing from the charger, or just moving it [gyroscope]) it starts advertising a timestamp. Once the brush is awake, I'm able to interrogate it for services. So it looks like triggering a manual "listen" wouldn't be necessary. A library could theoretically scan for a particular device ID's timestamp advertisement, or filter by Serial Number which is exposed over the Device Information Service. So it seems like once an advertisement is detected, an active BLE connection could be established? I'll come back to this as I have time. This is currently a very low priority project but I'd love to see it working :)

villasenor avatar Nov 09 '22 06:11 villasenor

nice learnings 👍 hope to hear from you soon again ;)

u20p17 avatar Nov 09 '22 07:11 u20p17

Hi all, repo owner here. Sorry for not replying earlier, but unfortunately the Bluetooth part of my toothbrush broke and I can't help with your project.

This code doesn't use bleak so it would be quite difficult to integration into HA as you'd have to rewrite the bulk of it

I should have used bleak from the beginning but was not aware of it's existence.

If the brush has been laying motionless for a period of time, all BLE activity stops

Yes, very annoying during development.

Happy to help if you need some additional information!

joushx avatar Nov 09 '22 10:11 joushx

Hi @joushx! No worries. I mean yeah I really haven't done much BLE development so this will be new for me. If you have time to help migrate to bleak that would be awesome but I'll eventually find some time to play with this. Any tips are welcome!

It's really just going to be a matter of listening for the passive advertisement, initiating an active connection, and then continually poll state (or watch for push updates? Not sure what options are available for BLE dev) until the device disconnects. Disconnect can be an assumed state of "off". Polling might drain the battery but as long as it is charged right after I think it's probably fine.

Also, if anyone else is interested in working on this, please feel free to jump in!

villasenor avatar Nov 09 '22 21:11 villasenor

@villasenor

I also have not much experience with bleak but would be willing to help code a lib for it. If we build a lib based on bleak, is it easier to integrate in HA?

What would be a good approach to start porting, so that integrating into HA is as flexible and easy as it can get? I have a device and would like to at least figure out when it's on or off.

peteh avatar Dec 26 '22 18:12 peteh

@peteh I feel much the same way just state would be great. I haven't done any major BLE dev, so I'm not sure what the best practices are. Based on what @bdraco said, it sounds like bleak is the way to go for Home Assistant integration? I'm not sure why...maybe there is already a hook for it with the BLE proxies and stuff? My current knowledge of the HA Bluetooth stack turns to magic pretty quick haha but I'm willing to learn.

villasenor avatar Dec 28 '22 00:12 villasenor

If you use bleak the proxies will just work with no additional code

bdraco avatar Dec 28 '22 01:12 bdraco

So porting this stuff to bleak should be a good starting point.

peteh avatar Dec 28 '22 13:12 peteh

Hi, I started a project and got the very basics and made an example to read the battery soc via bleak. However, I have never really used it before so I don't know how to properly design a lib with bleak and asyncio.

https://github.com/peteh/python-bleaksonicare

If somebody wants to join the work, feel free to join.

peteh avatar Jan 20 '23 22:01 peteh

Awesome! I'll take a look at this when I can. Thanks so much for jumping in, @peteh!

@bdraco - I know you probably have a million things on your plate, but if you get a second to glance at the repo that @peteh has started on (https://github.com/peteh/python-bleaksonicare), I think that would be helpful to make sure we are headed in the right direction. Thanks so much, everyone!

villasenor avatar Jan 24 '23 03:01 villasenor

My plan is to make a bleak based lib similar to this and then use it to create another repo integrating it into HA. As I'm pretty busy and can only work on it every now and then, help is really appreciated.

peteh avatar Jan 24 '23 18:01 peteh