bt-mqtt-gateway
bt-mqtt-gateway copied to clipboard
New device Inkbird IBS-TH1 (plus)
Hi there,
I modified the toothbrush.py to work with Inkbird IBS-TH1 (plus) Smart Sensor. https://www.ink-bird.com/products-smart-sensor-ibsth1.html
Just put the following code in a new file workers/ibsth1.py and complete your configuration in config.yaml (see below):
import time
from mqtt import MqttMessage
from workers.base import BaseWorker
import logger
REQUIREMENTS = ["bluepy"]
_LOGGER = logger.get(__name__)
class Ibsth1Worker(BaseWorker):
def searchmac(self, devices, mac):
for dev in devices:
if dev.addr == mac.lower():
return dev
return None
def status_update(self):
from bluepy.btle import Scanner, DefaultDelegate
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)
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"
)
)
readBuffer=device.getValueText(255)
_LOGGER.debug("text: %s" % readBuffer)
if readBuffer is not None:
bytes_ = bytearray(bytes.fromhex(readBuffer))
temperature_raw_value = bytes_[1] * 256 + bytes_[0]
if temperature_raw_value >= 0x8000:
temperature_ibsth1=(temperature_raw_value - 0x10000) / 100
else:
temperature_ibsth1=temperature_raw_value / 100
ret.append(
MqttMessage(
topic=self.format_topic(name + "/externalSensor"), payload=bytes_[4]
)
)
ret.append(
MqttMessage(
topic=self.format_topic(name + "/battery"), payload=bytes_[7]
)
)
ret.append(
MqttMessage(
topic=self.format_topic(name + "/temperature"),
payload=temperature_ibsth1,
)
)
ret.append(
MqttMessage(
topic=self.format_topic(name + "/humidity"),
payload=(bytes_[3] * 256 + bytes_[2])/100,
)
)
yield ret
Example configuration in config.yaml:
ibsth1:
args:
devices:
ibsth1: xx:xx:xx:xx:xx:xx
topic_prefix: inkbird
update_interval: 60
Best regards and feel free to add to the repository.
Best, Chris
Hi @gigaphreak , I've been trying this on a Pi Zero and now on Pi4, and on both cases getting the below error. Is this something you have observed?
Fatal error while executing worker command: BTLEManagementError
Traceback (most recent call last):
File "./gateway.py", line 107, in <module>
raise e
File "./gateway.py", line 89, in <module>
mqtt.publish(_WORKERS_QUEUE.get(timeout=10).execute())
File "/application/workers_manager.py", line 55, in execute
for message in self._callback(*self._args):
File "/application/workers/ibsth1.py", line 32, in status_update
devices = scanner.scan(5.0)
File "/usr/local/lib/python3.8/site-packages/bluepy/btle.py", line 854, in scan
self.stop()
File "/usr/local/lib/python3.8/site-packages/bluepy/btle.py", line 803, in stop
self._mgmtCmd(self._cmd()+"end")
File "/usr/local/lib/python3.8/site-packages/bluepy/btle.py", line 312, in _mgmtCmd
raise BTLEManagementError("Failed to execute management command '%s'" % (cmd), rsp)
bluepy.btle.BTLEManagementError: Failed to execute management command 'scanend' (code: 11, error: Rejected)
Thanks @gigaphreak!! This seems to work well as-is.
However, for two devices, I found that while this script outputs the expected return, the workers_manager doubles the first device in the message.
For example, I added a debug to print out the payload returned by this worker:
DEBUG bt-mqtt-gw.workers.ibsth1 ibsth1.py:96:status_update - ret: [{'topic': 'inkbird/ibs1/presence/rssi', 'payload': '-86'}, {'topic': 'inkbird/ibs1/presence', 'payload': '1'}, {'topic': 'inkbird/ibs1/externalSensor', 'payload': '0'}, {'topic': 'inkbird/ibs1/battery', 'payload': '28'}, {'topic': 'inkbird/ibs1/temperature', 'payload': '11.74'}, {'topic': 'inkbird/ibs1/humidity', 'payload': '55.99'}, {'topic': 'inkbird/ibs2/presence/rssi', 'payload': '-74'}, {'topic': 'inkbird/ibs2/presence', 'payload': '1'}, {'topic': 'inkbird/ibs2/externalSensor', 'payload': '0'}, {'topic': 'inkbird/ibs2/battery', 'payload': '98'}, {'topic': 'inkbird/ibs2/temperature', 'payload': '16.82'}, {'topic': 'inkbird/ibs2/humidity', 'payload': '66.5'}]```
But in the standard debug output, note that device 1 (ibs1) is duplicated twice:
DEBUG bt-mqtt-gw.workers_manager workers_manager.py:57:execute - Execution result of command Ibsth1Worker.status_update: [{'topic': 'inkbird/ibs1/presence/rssi', 'payload': '-86'}, {'topic': 'inkbird/ibs1/presence', 'payload': '1'}, {'topic': 'inkbird/ibs1/externalSensor', 'payload': '0'}, {'topic': 'inkbird/ibs1/battery', 'payload': '28'}, {'topic': 'inkbird/ibs1/temperature', 'payload': '11.74'}, {'topic': 'inkbird/ibs1/humidity', 'payload': '55.99'}, {'topic': 'inkbird/ibs1/presence/rssi', 'payload': '-86'}, {'topic': 'inkbird/ibs1/presence', 'payload': '1'}, {'topic': 'inkbird/ibs1/externalSensor', 'payload': '0'}, {'topic': 'inkbird/ibs1/battery', 'payload': '28'}, {'topic': 'inkbird/ibs1/temperature', 'payload': '11.74'}, {'topic': 'inkbird/ibs1/humidity', 'payload': '55.99'}, {'topic': 'inkbird/ibs2/presence/rssi', 'payload': '-74'}, {'topic': 'inkbird/ibs2/presence', 'payload': '1'}, {'topic': 'inkbird/ibs2/externalSensor', 'payload': '0'}, {'topic': 'inkbird/ibs2/battery', 'payload': '98'}, {'topic': 'inkbird/ibs2/temperature', 'payload': '16.82'}, {'topic': 'inkbird/ibs2/humidity', 'payload': '66.5'}]
@zewelor is this expected?
Maybe you have duplicated ibs1 in config ? I don't see other reason for now.
Thanks for this, this also works with the Inkbird IBS-P01B pool thermometer which I'm using in my hot tub. Thanks to this I can now see it's temperature in home-assistant 🙂