bot.py 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. """Library to handle connection with Switchbot."""
  2. from __future__ import annotations
  3. import logging
  4. from typing import Any
  5. from .device import DEVICE_SET_EXTENDED_KEY, DEVICE_SET_MODE_KEY, SwitchbotDevice
  6. # Bot keys
  7. PRESS_KEY = "570100"
  8. ON_KEY = "570101"
  9. OFF_KEY = "570102"
  10. DOWN_KEY = "570103"
  11. UP_KEY = "570104"
  12. class Switchbot(SwitchbotDevice):
  13. """Representation of a Switchbot."""
  14. def __init__(self, *args: Any, **kwargs: Any) -> None:
  15. """Switchbot Bot/WoHand constructor."""
  16. super().__init__(*args, **kwargs)
  17. self._inverse: bool = kwargs.pop("inverse_mode", False)
  18. async def update(self, interface: int | None = None) -> None:
  19. """Update mode, battery percent and state of device."""
  20. await self.get_device_data(retry=self._retry_count, interface=interface)
  21. async def turn_on(self) -> bool:
  22. """Turn device on."""
  23. result = await self._send_command(ON_KEY)
  24. return self._check_command_result(result, 0, {1, 5})
  25. async def turn_off(self) -> bool:
  26. """Turn device off."""
  27. result = await self._send_command(OFF_KEY)
  28. return self._check_command_result(result, 0, {1, 5})
  29. async def hand_up(self) -> bool:
  30. """Raise device arm."""
  31. result = await self._send_command(UP_KEY)
  32. return self._check_command_result(result, 0, {1, 5})
  33. async def hand_down(self) -> bool:
  34. """Lower device arm."""
  35. result = await self._send_command(DOWN_KEY)
  36. return self._check_command_result(result, 0, {1, 5})
  37. async def press(self) -> bool:
  38. """Press command to device."""
  39. result = await self._send_command(PRESS_KEY)
  40. return self._check_command_result(result, 0, {1, 5})
  41. async def set_switch_mode(
  42. self, switch_mode: bool = False, strength: int = 100, inverse: bool = False
  43. ) -> bool:
  44. """Change bot mode."""
  45. mode_key = format(switch_mode, "b") + format(inverse, "b")
  46. strength_key = f"{strength:0{2}x}" # to hex with padding to double digit
  47. result = await self._send_command(DEVICE_SET_MODE_KEY + strength_key + mode_key)
  48. return self._check_command_result(result, 0, {1})
  49. async def set_long_press(self, duration: int = 0) -> bool:
  50. """Set bot long press duration."""
  51. duration_key = f"{duration:0{2}x}" # to hex with padding to double digit
  52. result = await self._send_command(DEVICE_SET_EXTENDED_KEY + "08" + duration_key)
  53. return self._check_command_result(result, 0, {1})
  54. async def get_basic_info(self) -> dict[str, Any] | None:
  55. """Get device basic settings."""
  56. if not (_data := await self._get_basic_info()):
  57. return None
  58. return {
  59. "battery": _data[1],
  60. "firmware": _data[2] / 10.0,
  61. "strength": _data[3],
  62. "timers": _data[8],
  63. "switchMode": bool(_data[9] & 16),
  64. "inverseDirection": bool(_data[9] & 1),
  65. "holdSeconds": _data[10],
  66. }
  67. def switch_mode(self) -> Any:
  68. """Return true or false from cache."""
  69. # To get actual position call update() first.
  70. return self._get_adv_value("switchMode")
  71. def is_on(self) -> Any:
  72. """Return switch state from cache."""
  73. # To get actual position call update() first.
  74. value = self._get_adv_value("isOn")
  75. if value is None:
  76. return None
  77. if self._inverse:
  78. return not value
  79. return value