55 lines
1.4 KiB
Python
55 lines
1.4 KiB
Python
import time
|
|
from interruptingcow import timeout
|
|
|
|
from mqtt import MqttMessage
|
|
from workers.base import BaseWorker
|
|
|
|
REQUIREMENTS = ['bluepy']
|
|
|
|
|
|
# Bluepy might need special settings
|
|
# sudo setcap 'cap_net_raw,cap_net_admin+eip' /usr/local/lib/python3.6/dist-packages/bluepy/bluepy-helper
|
|
|
|
class MiscaleWorker(BaseWorker):
|
|
|
|
SCAN_TIMEOUT = 5
|
|
|
|
def status_update(self):
|
|
return [MqttMessage(topic=self.format_topic('weight/kg'), payload=self._get_weight())]
|
|
|
|
def _get_weight(self):
|
|
from bluepy import btle
|
|
|
|
scan_processor = ScanProcessor(self.mac)
|
|
scanner = btle.Scanner().withDelegate(scan_processor)
|
|
scanner.scan(self.SCAN_TIMEOUT, passive=True)
|
|
|
|
with timeout(self.SCAN_TIMEOUT, exception=TimeoutError('Retrieving the weight from {} device {} timed out after {} seconds'.format(repr(self), self.mac, self.SCAN_TIMEOUT))):
|
|
while scan_processor.weight is None:
|
|
time.sleep(1)
|
|
return scan_processor.weight
|
|
|
|
return -1
|
|
|
|
|
|
class ScanProcessor():
|
|
def __init__(self, mac):
|
|
self._mac = mac
|
|
self._weight = None
|
|
|
|
def handleDiscovery(self, dev, isNewDev, _):
|
|
if dev.addr == self.mac.lower() and isNewDev:
|
|
for (sdid, desc, data) in dev.getScanData():
|
|
if data.startswith('1d18') and sdid == 22:
|
|
measured = int((data[8:10] + data[6:8]), 16) * 0.01
|
|
|
|
self._weight = round(measured / 2, 2)
|
|
|
|
@property
|
|
def mac(self):
|
|
return self._mac
|
|
|
|
@property
|
|
def weight(self):
|
|
return self._weight
|