__init__.py 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. """Library to handle connection with Switchbot"""
  2. import binascii
  3. import logging
  4. import bluepy
  5. UUID = "cba20d00-224d-11e6-9fb8-0002a5d5c51b"
  6. HANDLE = "cba20002-224d-11e6-9fb8-0002a5d5c51b"
  7. PRESS_KEY = "570100"
  8. ON_KEY = "570101"
  9. OFF_KEY = "570102"
  10. _LOGGER = logging.getLogger(__name__)
  11. class Switchbot:
  12. """Representation of a Switchbot."""
  13. def __init__(self, mac) -> None:
  14. self._mac = mac
  15. self._device = None
  16. def _connect(self) -> bool:
  17. if self._device is not None:
  18. _LOGGER.debug("Disconnecting")
  19. try:
  20. self._device.disconnect()
  21. except bluepy.btle.BTLEException:
  22. pass
  23. try:
  24. _LOGGER.debug("Connecting")
  25. self._device = bluepy.btle.Peripheral(self._mac,
  26. bluepy.btle.ADDR_TYPE_RANDOM)
  27. except bluepy.btle.BTLEException:
  28. _LOGGER.warning("Failed to connect to Switchbot", exc_info=True)
  29. return False
  30. return True
  31. def _sendpacket(self, key, retry=2) -> bool:
  32. if self._device is None and not self._connect():
  33. _LOGGER.error("Can not connect to switchbot.")
  34. return False
  35. try:
  36. _LOGGER.debug("Prepare to send")
  37. hand_service = self._device.getServiceByUUID(UUID)
  38. hand = hand_service.getCharacteristics(HANDLE)[0]
  39. _LOGGER.debug("Sending command, %s", key)
  40. hand.write(binascii.a2b_hex(key))
  41. except bluepy.btle.BTLEException:
  42. if retry < 1 or not self._connect():
  43. _LOGGER.error("Can not connect to switchbot.", exc_info=True)
  44. return False
  45. _LOGGER.warning("Can not connect to switchbot. Retrying")
  46. return self._sendpacket(key, retry-1)
  47. return True
  48. def turn_on(self) -> None:
  49. """Turn device on."""
  50. return self._sendpacket(ON_KEY)
  51. def turn_off(self) -> None:
  52. """Turn device off."""
  53. return self._sendpacket(OFF_KEY)
  54. def press(self) -> None:
  55. """Press command to device."""
  56. return self._sendpacket(PRESS_KEY)