1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- """Library to handle connection with Switchbot"""
- import time
- import binascii
- import logging
- import bluepy
- DEFAULT_RETRY_COUNT = 3
- DEFAULT_RETRY_TIMEOUT = .2
- UUID = "cba20d00-224d-11e6-9fb8-0002a5d5c51b"
- HANDLE = "cba20002-224d-11e6-9fb8-0002a5d5c51b"
- PRESS_KEY = "570100"
- ON_KEY = "570101"
- OFF_KEY = "570102"
- _LOGGER = logging.getLogger(__name__)
- class Switchbot:
- """Representation of a Switchbot."""
- def __init__(self, mac, retry_count=DEFAULT_RETRY_COUNT) -> None:
- self._mac = mac
- self._device = None
- self._retry_count = retry_count
- def _connect(self) -> None:
- if self._device is not None:
- return
- try:
- _LOGGER.debug("Connecting to Switchbot...")
- self._device = bluepy.btle.Peripheral(self._mac,
- bluepy.btle.ADDR_TYPE_RANDOM)
- _LOGGER.debug("Connected to Switchbot.")
- except bluepy.btle.BTLEException:
- _LOGGER.debug("Failed connecting to Switchbot.", exc_info=True)
- self._device = None
- raise
- def _disconnect(self) -> None:
- if self._device is None:
- return
- _LOGGER.debug("Disconnecting")
- try:
- self._device.disconnect()
- except bluepy.btle.BTLEException:
- _LOGGER.warning("Error disconnecting from Switchbot.", exc_info=True)
- finally:
- self._device = None
- def _writekey(self, key) -> bool:
- _LOGGER.debug("Prepare to send")
- hand_service = self._device.getServiceByUUID(UUID)
- hand = hand_service.getCharacteristics(HANDLE)[0]
- _LOGGER.debug("Sending command, %s", key)
- write_result = hand.write(binascii.a2b_hex(key), withResponse=True)
- if not write_result:
- _LOGGER.error("Sent command but didn't get a response from Switchbot confirming command was sent. "
- "Please check the Switchbot.")
- else:
- _LOGGER.info("Successfully sent command to Switchbot (MAC: %s).", self._mac)
- return write_result
- def _sendcommand(self, key, retry) -> bool:
- send_success = False
- try:
- self._connect()
- send_success = self._writekey(key)
- except bluepy.btle.BTLEException:
- _LOGGER.warning("Error talking to Switchbot.", exc_info=True)
- finally:
- self._disconnect()
- if send_success:
- return True
- if retry < 1:
- _LOGGER.error("Switchbot communication failed. Stopping trying.", exc_info=True)
- return False
- _LOGGER.warning("Cannot connect to Switchbot. Retrying (remaining: %d)...", retry)
- time.sleep(DEFAULT_RETRY_TIMEOUT)
- return self._sendcommand(key, retry - 1)
- def turn_on(self) -> bool:
- """Turn device on."""
- return self._sendcommand(ON_KEY, self._retry_count)
- def turn_off(self) -> bool:
- """Turn device off."""
- return self._sendcommand(OFF_KEY, self._retry_count)
- def press(self) -> bool:
- """Press command to device."""
- return self._sendcommand(PRESS_KEY, self._retry_count)
|