ceiling_light.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. from __future__ import annotations
  2. from typing import Any
  3. from ..const.light import (
  4. DEFAULT_COLOR_TEMP,
  5. CeilingLightColorMode,
  6. ColorMode,
  7. )
  8. from .base_light import SwitchbotSequenceBaseLight
  9. from .device import update_after_operation
  10. # Private mapping from device-specific color modes to original ColorMode enum
  11. _CEILING_LIGHT_COLOR_MODE_MAP = {
  12. CeilingLightColorMode.COLOR_TEMP: ColorMode.COLOR_TEMP,
  13. CeilingLightColorMode.NIGHT: ColorMode.COLOR_TEMP,
  14. CeilingLightColorMode.MUSIC: ColorMode.EFFECT,
  15. CeilingLightColorMode.UNKNOWN: ColorMode.OFF,
  16. }
  17. CEILING_LIGHT_CONTROL_HEADER = "570F5401"
  18. class SwitchbotCeilingLight(SwitchbotSequenceBaseLight):
  19. """Representation of a Switchbot ceiling light."""
  20. _turn_on_command = f"{CEILING_LIGHT_CONTROL_HEADER}01FF01FFFF"
  21. _turn_off_command = f"{CEILING_LIGHT_CONTROL_HEADER}02FF01FFFF"
  22. _set_brightness_command = f"{CEILING_LIGHT_CONTROL_HEADER}01FF01{{}}"
  23. _set_color_temp_command = f"{CEILING_LIGHT_CONTROL_HEADER}01FF01{{}}"
  24. _get_basic_info_command = ["5702", "570f5581"]
  25. @property
  26. def color_modes(self) -> set[ColorMode]:
  27. """Return the supported color modes."""
  28. return {ColorMode.COLOR_TEMP}
  29. @property
  30. def color_mode(self) -> ColorMode:
  31. """Return the current color mode."""
  32. device_mode = CeilingLightColorMode(self._get_adv_value("color_mode") or 10)
  33. return _CEILING_LIGHT_COLOR_MODE_MAP.get(device_mode, ColorMode.OFF)
  34. @update_after_operation
  35. async def set_brightness(self, brightness: int) -> bool:
  36. """Set brightness."""
  37. assert 0 <= brightness <= 100, "Brightness must be between 0 and 100"
  38. hex_brightness = f"{brightness:02X}"
  39. color_temp = self._state.get("cw", DEFAULT_COLOR_TEMP)
  40. hex_data = f"{hex_brightness}{color_temp:04X}"
  41. result = await self._send_command(self._set_brightness_command.format(hex_data))
  42. return self._check_command_result(result, 0, {1})
  43. async def get_basic_info(self) -> dict[str, Any] | None:
  44. """Get device basic settings."""
  45. if not (
  46. res := await self._get_multi_commands_results(self._get_basic_info_command)
  47. ):
  48. return None
  49. _version_info, _data = res
  50. self._state["cw"] = int.from_bytes(_data[3:5], "big")
  51. return {
  52. "isOn": bool(_data[1] & 0b10000000),
  53. "color_mode": _data[1] & 0b01000000,
  54. "brightness": _data[2] & 0b01111111,
  55. "cw": self._state["cw"],
  56. "firmware": _version_info[2] / 10.0,
  57. }