Skip to content
This repository has been archived by the owner on Oct 26, 2023. It is now read-only.

Commit

Permalink
Added retry to switchbot worker (#255)
Browse files Browse the repository at this point in the history
* Added retry to switchbot worker

* fixed missing import

Co-authored-by: Ignacio Movellán <ignacio.movellancastillejo@amadeus.com>
  • Loading branch information
ignacio-mov and Ignacio Movellán authored Jun 28, 2022
1 parent 3677833 commit 03c8f56
Showing 1 changed file with 38 additions and 48 deletions.
86 changes: 38 additions & 48 deletions workers/switchbot.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
from builtins import staticmethod
import logging

from mqtt import MqttMessage

from workers.base import BaseWorker
from workers.base import BaseWorker, retry
import logger

REQUIREMENTS = ["bluepy"]
_LOGGER = logger.get(__name__)

STATE_ON = "ON"
STATE_OFF = "OFF"
CODES = {
STATE_ON: "570101",
STATE_OFF: "570102",
"PRESS": "570100"
}

SERVICE_UUID = "cba20d00-224d-11e6-9fb8-0002a5d5c51b"
CHARACTERISTIC_UUID = "cba20002-224d-11e6-9fb8-0002a5d5c51b"


class SwitchbotWorker(BaseWorker):
Expand All @@ -25,86 +30,71 @@ 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,
)
ret += self.update_device_state(name, bot["state"])
return ret

def on_command(self, topic, value):
from bluepy import btle
import binascii
from bluepy.btle import Peripheral
from bluepy.btle import BTLEException

_, _, device_name, _ = topic.split("/")

bot = self.devices[device_name]

value = value.decode("utf-8")
switch_func = retry(switch_state, retries=self.command_retries)

# It needs to be on separate if because first if can change method
value = value.decode("utf-8")

_LOGGER.debug(
_LOGGER.info(
"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",

# If status doesn't change, the switchbot shouldn't move
if bot['state'] == value:
_LOGGER.debug(
"Ignoring %s on %s device '%s' with state %s",
value,
repr(self),
device_name,
bot["mac"],
type(e).__name__,
bot["state"],
)
return []

try:
return self.update_device_state(device_name, value)
except btle.BTLEException as e:
switch_func(bot, value)
except BTLEException as e:
logger.log_exception(
_LOGGER,
"Error during update of %s device '%s' (%s): %s",
"Error setting %s on %s device '%s' (%s): %s",
value,
repr(self),
device_name,
bot["mac"],
type(e).__name__,
suppress=True,
)
return []

return self.update_device_state(device_name, value)

def update_device_state(self, name, value):
return [MqttMessage(topic=self.format_state_topic(name), payload=value)]


def switch_state(bot, value):
import binascii
from bluepy.btle import Peripheral

bot["bot"] = Peripheral(bot["mac"], "random")
hand_service = bot["bot"].getServiceByUUID(SERVICE_UUID)
hand = hand_service.getCharacteristics(CHARACTERISTIC_UUID)[0]
hand.write(binascii.a2b_hex(CODES[value]))
bot["bot"].disconnect()
bot['state'] = STATE_ON if bot['state'] == STATE_OFF else STATE_OFF

0 comments on commit 03c8f56

Please sign in to comment.