Here is a standalone implementation able to display received packets from your toothbrush. By piping into an external program it is easy to make the information available to Home Assistant over MQTT (see example).
Only tested on Linux. Battery level not implemented (yet if available at all).
i hacked together a worker for bt-mqtt-gateway that collects the info that this script collects from my oral-b-toothbrushes. i hope to file a pull request there soon. this is the bt-mqtt-gateway-worker that works fine for me so far. needs a bit of polishing …
(@molobrakos implementation got me into dependency hell which i couldn’t solve on raspbian.)
import time
from interruptingcow import timeout
from bluepy.btle import Scanner, DefaultDelegate
from mqtt import MqttMessage
from workers.base import BaseWorker
from logger import _LOGGER
import sys
from datetime import datetime
import codecs
REQUIREMENTS = ['bluepy']
class ScanDelegate(DefaultDelegate):
def __init__(self):
DefaultDelegate.__init__(self)
def handleDiscovery(self, dev, isNewDev, isNewData):
if isNewDev:
_LOGGER.debug("Discovered new device: %s" % dev.addr)
class ToothbrushWorker(BaseWorker):
def searchmac(self, devices, mac):
for dev in devices:
if dev.addr == mac.lower():
return dev
return None
def status_update(self):
scanner = Scanner().withDelegate(ScanDelegate())
devices = scanner.scan(5.0)
ret = []
for name, mac in self.devices.items():
device = self.searchmac(devices, mac)
if device is None:
ret.append(MqttMessage(topic=self.format_topic(name+'/presence'), payload="0"))
else:
ret.append(MqttMessage(topic=self.format_topic(name+'/presence/rssi'), payload=device.rssi))
ret.append(MqttMessage(topic=self.format_topic(name+'/presence'), payload="1"))
_LOGGER.debug("text: %s" % device.getValueText(255) )
bytes_ = bytearray(bytes.fromhex(device.getValueText(255)))
ret.append(MqttMessage(topic=self.format_topic(name+'/running'), payload=bytes_[5] ))
ret.append(MqttMessage(topic=self.format_topic(name+'/pressure'), payload=bytes_[6] ))
ret.append(MqttMessage(topic=self.format_topic(name+'/time'), payload=bytes_[7]*60 + bytes_[8] ))
ret.append(MqttMessage(topic=self.format_topic(name+'/mode'), payload=bytes_[9] ))
ret.append(MqttMessage(topic=self.format_topic(name+'/quadrant'), payload=bytes_[10] ))
return ret
Requested 'dbus-1 >= 1.8' but version of dbus is 1.6.8
Requested 'cairo >= 1.13.1' but version of cairo is 1.12.16
the versions that i could install via apt-get were not new enough. i could compile a newer version of dbus by myself, but failed getting or compiling cairo >= 1.13.1
does gatttool -b {$mac} --char-read --uuid=0x2A19 -t public
or gatttool -b {$mac} --char-read --uuid=0x2A19 -t random
return a HEX value (replace {$mac} with the MAC Address? Is so that’s reading the bluetooth battery level (I use this for my BLE Bike light, Smart Watch, and other bike sensors)
I have a bit of a convoluted setup of Home Assistant doing the following:-
The Bluetooth LE Device Tracker detects the device comes into range
This runs a REST command when the BLE device comes into range calling a webpage on my PiHole server
This writes a flag file to disk
Every 60 seconds a cron task looks for these flag files and if one exists runs the gattool command (public version and if that fails random - it’s a mixed bag as to which works)
The output of this command is written to a JSON file
This also calls http://hassip:8123/api/states/sensor.{$sensor} to update Home Assistant.
Another cron runs every 10 minutes resubmitting the data from the JSON Files to Home Assistant (so you don’t have to wait for the device to be used again when HASS restarts - they appear within 10 minutes)
It’s convoluted as I needed to use a Bluetooth Adapter which isn’t already in use for presence detection so it uses the Bluetooth Adapter on my UniFi Controlled / Pi Hole Machine. All the devices I have keep the BLE Active for 10 minutes so this works fine for me.
Coupled with a few other ways of gathering battery level gives a centralised display of battery levels https://i.imgur.com/GoEdK9n.png
did anybody managed to change the color of the led using any of the integrations?
it is possible to change it through the app, but so far I have not seen any integration that would pick up that topic.
The smart Oral-B toothbrushes use BLE to communicate with their app so you can track your brushing. It would be amazing if someone with the know-how could leverage the power of the new Bluetooth BLE in 2022.8.0 to create an Oral-B integration to track the data without sending it over to Oral-B servers.
They are already working with the Passive BLE Monitor custom component. The author of that component has played a big part on the new official integration, so it may be ported at some point in the future.