83 lines
2.8 KiB
Python
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
|