bulb.py 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. from __future__ import annotations
  2. from typing import Any
  3. from ..const.light import BulbColorMode, ColorMode
  4. from .base_light import SwitchbotSequenceBaseLight
  5. # Private mapping from device-specific color modes to original ColorMode enum
  6. _BULB_COLOR_MODE_MAP = {
  7. BulbColorMode.COLOR_TEMP: ColorMode.COLOR_TEMP,
  8. BulbColorMode.RGB: ColorMode.RGB,
  9. BulbColorMode.DYNAMIC: ColorMode.EFFECT,
  10. BulbColorMode.UNKNOWN: ColorMode.OFF,
  11. }
  12. COLOR_BULB_CONTROL_HEADER = "570F4701"
  13. class SwitchbotBulb(SwitchbotSequenceBaseLight):
  14. """Representation of a Switchbot bulb."""
  15. _turn_on_command = f"{COLOR_BULB_CONTROL_HEADER}01"
  16. _turn_off_command = f"{COLOR_BULB_CONTROL_HEADER}02"
  17. _set_rgb_command = f"{COLOR_BULB_CONTROL_HEADER}12{{}}"
  18. _set_color_temp_command = f"{COLOR_BULB_CONTROL_HEADER}13{{}}"
  19. _set_brightness_command = f"{COLOR_BULB_CONTROL_HEADER}14{{}}"
  20. _get_basic_info_command = ["570003", "570f4801"]
  21. _effect_dict = {
  22. "Colorful": ["570F4701010300"],
  23. "Flickering": ["570F4701010301"],
  24. "Breathing": ["570F4701010302"],
  25. }
  26. @property
  27. def color_modes(self) -> set[ColorMode]:
  28. """Return the supported color modes."""
  29. return {ColorMode.RGB, ColorMode.COLOR_TEMP}
  30. @property
  31. def color_mode(self) -> ColorMode:
  32. """Return the current color mode."""
  33. device_mode = BulbColorMode(self._get_adv_value("color_mode") or 10)
  34. return _BULB_COLOR_MODE_MAP.get(device_mode, ColorMode.OFF)
  35. async def get_basic_info(self) -> dict[str, Any] | None:
  36. """Get device basic settings."""
  37. if not (
  38. res := await self._get_multi_commands_results(self._get_basic_info_command)
  39. ):
  40. return None
  41. _version_info, _data = res
  42. self._state["r"] = _data[3]
  43. self._state["g"] = _data[4]
  44. self._state["b"] = _data[5]
  45. self._state["cw"] = int.from_bytes(_data[6:8], "big")
  46. return {
  47. "isOn": bool(_data[1] & 0b10000000),
  48. "brightness": _data[2] & 0b01111111,
  49. "r": self._state["r"],
  50. "g": self._state["g"],
  51. "b": self._state["b"],
  52. "cw": self._state["cw"],
  53. "color_mode": _data[10] & 0b00001111,
  54. "firmware": _version_info[2] / 10.0,
  55. }