Files
AS137430 bc681fd85f Added support for Switchbot (#60)
* Added worker for Switchbot

* config.yaml example for switchbot
2019-03-07 17:15:53 +01:00

83 lines
2.8 KiB
Python

from builtins import staticmethod
import logging
from mqtt import MqttMessage
from workers.base import BaseWorker
import logger
REQUIREMENTS = ['bluepy']
_LOGGER = logger.get(__name__)
STATE_ON = 'ON'
STATE_OFF = 'OFF'
class SwitchbotWorker(BaseWorker):
def _setup(self):
_LOGGER.info("Adding %d %s devices", len(self.devices), repr(self))
for name, mac in self.devices.items():
_LOGGER.info("Adding %s device '%s' (%s)", repr(self), name, mac)
self.devices[name] = {"bot":None,"state":STATE_OFF,"mac":mac}
def format_state_topic(self, *args):
return '/'.join([self.state_topic_prefix, *args])
def status_update(self):
from bluepy import btle
ret = []
_LOGGER.debug("Updating %d %s devices", len(self.devices), repr(self))
for name, bot in self.devices.items():
_LOGGER.debug("Updating %s device '%s' (%s)", repr(self), name, bot["mac"])
try:
ret += self.update_device_state(name, bot["state"])
except btle.BTLEException as e:
logger.log_exception(_LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), name, bot["mac"], type(e).__name__, suppress=True)
return ret
def on_command(self, topic, value):
from bluepy import btle
import binascii
from bluepy.btle import Peripheral
_, _ , device_name, _ = topic.split('/')
bot = self.devices[device_name]
value = value.decode('utf-8')
# It needs to be on separate if because first if can change method
_LOGGER.debug("Setting %s on %s device '%s' (%s)", value, repr(self), device_name, bot["mac"])
try:
bot["bot"] = Peripheral(bot["mac"],"random")
hand_service = bot["bot"].getServiceByUUID("cba20d00-224d-11e6-9fb8-0002a5d5c51b")
hand = hand_service.getCharacteristics("cba20002-224d-11e6-9fb8-0002a5d5c51b")[0]
if value == STATE_ON:
hand.write(binascii.a2b_hex("570101"))
elif value == STATE_OFF:
hand.write(binascii.a2b_hex("570102"))
elif value == "PRESS":
hand.write(binascii.a2b_hex("570100"))
bot["bot"].disconnect()
except btle.BTLEException as e:
logger.log_exception(_LOGGER, "Error setting %s on %s device '%s' (%s): %s", value, repr(self), device_name, bot["mac"], type(e).__name__)
return []
try:
return self.update_device_state(device_name, value)
except btle.BTLEException as e:
logger.log_exception(_LOGGER, "Error during update of %s device '%s' (%s): %s", repr(self), device_name, bot["mac"], type(e).__name__, suppress=True)
return []
def update_device_state(self, name, value):
ret = []
ret.append(MqttMessage(topic=self.format_state_topic(name), payload=value))
return ret
def device_for(self, mac):
for key in self.devices:
if key.addr == mac:
return key