light_strip.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. from __future__ import annotations
  2. from typing import Any
  3. from ..const import SwitchbotModel
  4. from ..const.light import ColorMode, RGBICStripLightColorMode, StripLightColorMode
  5. from .base_light import SwitchbotSequenceBaseLight
  6. from .device import SwitchbotEncryptedDevice
  7. # Private mapping from device-specific color modes to original ColorMode enum
  8. _STRIP_LIGHT_COLOR_MODE_MAP = {
  9. StripLightColorMode.RGB: ColorMode.RGB,
  10. StripLightColorMode.SCENE: ColorMode.EFFECT,
  11. StripLightColorMode.MUSIC: ColorMode.EFFECT,
  12. StripLightColorMode.CONTROLLER: ColorMode.EFFECT,
  13. StripLightColorMode.COLOR_TEMP: ColorMode.COLOR_TEMP,
  14. StripLightColorMode.UNKNOWN: ColorMode.OFF,
  15. }
  16. _RGBICWW_STRIP_LIGHT_COLOR_MODE_MAP = {
  17. RGBICStripLightColorMode.SEGMENTED: ColorMode.EFFECT,
  18. RGBICStripLightColorMode.RGB: ColorMode.RGB,
  19. RGBICStripLightColorMode.SCENE: ColorMode.EFFECT,
  20. RGBICStripLightColorMode.MUSIC: ColorMode.EFFECT,
  21. RGBICStripLightColorMode.CONTROLLER: ColorMode.EFFECT,
  22. RGBICStripLightColorMode.COLOR_TEMP: ColorMode.COLOR_TEMP,
  23. RGBICStripLightColorMode.UNKNOWN: ColorMode.OFF,
  24. }
  25. LIGHT_STRIP_CONTROL_HEADER = "570F4901"
  26. COMMON_EFFECTS = {
  27. "christmas": [
  28. "570F49070200033C01",
  29. "570F490701000600009902006D0EFF0021",
  30. "570F490701000603009902006D0EFF0021",
  31. ],
  32. "halloween": ["570F49070200053C04", "570F490701000300FF6A009E00ED00EA0F"],
  33. "sunset": [
  34. "570F49070200033C3C",
  35. "570F490701000900FF9000ED8C04DD5800",
  36. "570F490701000903FF2E008E0B004F0500",
  37. "570F4907010009063F0010270056140033",
  38. ],
  39. "vitality": [
  40. "570F49070200053C02",
  41. "570F490701000600C5003FD9530AEC9800",
  42. "570F490701000603FFDF0000895500468B",
  43. ],
  44. "flashing": [
  45. "570F49070200053C02",
  46. "570F4907010006000000FF00FF00FF0000",
  47. "570F490701000603FFFF0000FFFFA020F0",
  48. ],
  49. "strobe": ["570F49070200043C02", "570F490701000300FF00E19D70FFFF0515"],
  50. "fade": [
  51. "570F49070200043C04",
  52. "570F490701000500FF5481FF00E19D70FF",
  53. "570F490701000503FF0515FF7FEB",
  54. ],
  55. "smooth": [
  56. "570F49070200033C02",
  57. "570F4907010007000036FC00F6FF00ED13",
  58. "570F490701000703F6FF00FF8300FF0800",
  59. "570F490701000706FF00E1",
  60. ],
  61. "forest": [
  62. "570F49070200033C06",
  63. "570F490701000400006400228B223CB371",
  64. "570F49070100040390EE90",
  65. ],
  66. "ocean": [
  67. "570F49070200033C06",
  68. "570F4907010007004400FF0061FF007BFF",
  69. "570F490701000703009DFF00B2FF00CBFF",
  70. "570F49070100070600E9FF",
  71. ],
  72. "autumn": [
  73. "570F49070200043C05",
  74. "570F490701000700D10035922D13A16501",
  75. "570F490701000703AB9100DD8C00F4AA29",
  76. "570F490701000706E8D000",
  77. ],
  78. "cool": [
  79. "570F49070200043C04",
  80. "570F490701000600001A63006C9A00468B",
  81. "570F490701000603009DA50089BE4378B6",
  82. ],
  83. "flow": [
  84. "570F49070200033C02",
  85. "570F490701000600FF00D8E100FFAA00FF",
  86. "570F4907010006037F00FF5000FF1900FF",
  87. ],
  88. "relax": [
  89. "570F49070200033C03",
  90. "570F490701000400FF8C00FF7200FF1D00",
  91. "570F490701000403FF5500",
  92. ],
  93. "modern": [
  94. "570F49070200043C03",
  95. "570F49070100060089231A5F8969829E5A",
  96. "570F490701000603BCB05EEDBE5AFF9D60",
  97. ],
  98. "rose": [
  99. "570F49070200043C04",
  100. "570F490701000500FF1969BC215F7C0225",
  101. "570F490701000503600C2B35040C",
  102. ],
  103. }
  104. RGBIC_EFFECTS = {
  105. "romance": [
  106. "570F490D01350100FF10EE",
  107. "570F490D0363",
  108. ],
  109. "energy": [
  110. "570F490D01000300ED070F34FF14FFE114",
  111. "570F490D03FA",
  112. ],
  113. "heartbeat": [
  114. "570F490D01020400FFDEADFE90FDFF9E3D",
  115. "570F490D01020403FCBAFD",
  116. "570F490D03FA",
  117. ],
  118. "party": [
  119. "570F490D01030400FF8A47FF524DFF4DEE",
  120. "570F490D010304034DFF8C",
  121. "570F490D03FA",
  122. ],
  123. "dynamic": [
  124. "570F490D010403004DFFFB4DFF4FFFBF4D",
  125. "570F490D03FA",
  126. ],
  127. "mystery": [
  128. "570F490D01050300F660F6F6D460C6F660",
  129. "570F490D03FA",
  130. ],
  131. "lightning": [
  132. "570F490D01340100FFD700",
  133. "570F490D03FA",
  134. ],
  135. "rock": [
  136. "570F490D01090300B0F6606864FCFFBC3D",
  137. "570F490D03FA",
  138. ],
  139. "starlight": [
  140. "570F490D010A0100FF8C00",
  141. "570F490D0363",
  142. ],
  143. "valentine_day": [
  144. "570F490D010C0300FDE0FFFFCC8AD7FF8A",
  145. "570F490D03FA",
  146. ],
  147. "dream": [
  148. "570F490D010E0300A3E5FF73F019FFA8E5",
  149. "570F490D03FA",
  150. ],
  151. "alarm": [
  152. "570F490D013E0100FF0000",
  153. "570F490D03FA",
  154. ],
  155. "fireworks": [
  156. "570F490D01110300FFAA33FFE233FF5CDF",
  157. "570F490D03FA",
  158. ],
  159. "waves": [
  160. "570F490D013D01001E90FF",
  161. "570F490D03FA",
  162. ],
  163. "christmas": [
  164. "570F490D01380400DC143C228B22DAA520",
  165. "570F490D0363",
  166. "570F490D0138040332CD32",
  167. "570F490D0363",
  168. ],
  169. "rainbow": [
  170. "570F490D01160600FF0000FF7F00FFFF00",
  171. "570F490D03FA",
  172. "570F490D0116060300FF000000FF9400D3",
  173. "570F490D03FA",
  174. ],
  175. "game": [
  176. "570F490D011A0400D05CFF668FFFFFEFD5",
  177. "570F490D0363",
  178. "570F490D011A0403FFC55C",
  179. "570F490D0363",
  180. ],
  181. "halloween": [
  182. "570F490D01320300FF8C009370DB32CD32",
  183. "570F490D0364",
  184. ],
  185. "meditation": [
  186. "570F490D013502001E90FF9370DB",
  187. "570F490D0364",
  188. ],
  189. "starlit_sky": [
  190. "570F490D010D010099C8FF",
  191. "570F490D0364",
  192. ],
  193. "sleep": [
  194. "570F490D01370300FF8C002E4E3E3E3E5E",
  195. "570F490D0364",
  196. ],
  197. "movie": [
  198. "570F490D013602001919704B0082",
  199. "570F490D0364",
  200. ],
  201. "sunrise": [
  202. "570F490D013F0200FFD700FF4500",
  203. "570F490D03FA",
  204. "570F490D03FA",
  205. ],
  206. "sunset": [
  207. "570F490D01390300FF4500FFA500483D8B",
  208. "570F490D0363",
  209. "570F490D0363",
  210. ],
  211. "new_year": [
  212. "570F490D013F0300FF0000FFD700228B22",
  213. "570F490D0364",
  214. ],
  215. "cherry_blossom": [
  216. "570F490D01400200FFB3C1FF69B4",
  217. "570F490D0364",
  218. ],
  219. }
  220. class SwitchbotLightStrip(SwitchbotSequenceBaseLight):
  221. """Representation of a Switchbot light strip."""
  222. _effect_dict = COMMON_EFFECTS
  223. _turn_on_command = f"{LIGHT_STRIP_CONTROL_HEADER}01"
  224. _turn_off_command = f"{LIGHT_STRIP_CONTROL_HEADER}02"
  225. _set_rgb_command = f"{LIGHT_STRIP_CONTROL_HEADER}12{{}}"
  226. _set_color_temp_command = f"{LIGHT_STRIP_CONTROL_HEADER}11{{}}"
  227. _set_brightness_command = f"{LIGHT_STRIP_CONTROL_HEADER}14{{}}"
  228. _get_basic_info_command = ["570003", "570f4A01"]
  229. @property
  230. def color_modes(self) -> set[ColorMode]:
  231. """Return the supported color modes."""
  232. return {ColorMode.RGB}
  233. @property
  234. def color_mode(self) -> ColorMode:
  235. """Return the current color mode."""
  236. device_mode = StripLightColorMode(self._get_adv_value("color_mode") or 10)
  237. return _STRIP_LIGHT_COLOR_MODE_MAP.get(device_mode, ColorMode.OFF)
  238. async def get_basic_info(self) -> dict[str, Any] | None:
  239. """Get device basic settings."""
  240. if not (
  241. res := await self._get_multi_commands_results(self._get_basic_info_command)
  242. ):
  243. return None
  244. _version_info, _data = res
  245. self._state["r"] = _data[3]
  246. self._state["g"] = _data[4]
  247. self._state["b"] = _data[5]
  248. self._state["cw"] = int.from_bytes(_data[7:9], "big")
  249. return {
  250. "isOn": bool(_data[1] & 0b10000000),
  251. "brightness": _data[2] & 0b01111111,
  252. "r": self._state["r"],
  253. "g": self._state["g"],
  254. "b": self._state["b"],
  255. "cw": self._state["cw"],
  256. "color_mode": _data[10] & 0b00001111,
  257. "firmware": _version_info[2] / 10.0,
  258. }
  259. class SwitchbotStripLight3(SwitchbotEncryptedDevice, SwitchbotLightStrip):
  260. """Support for switchbot strip light3 and floor lamp."""
  261. _model = SwitchbotModel.STRIP_LIGHT_3
  262. @property
  263. def color_modes(self) -> set[ColorMode]:
  264. """Return the supported color modes."""
  265. return {ColorMode.RGB, ColorMode.COLOR_TEMP}
  266. class SwitchbotCandleWarmerLamp(SwitchbotEncryptedDevice, SwitchbotLightStrip):
  267. """Support for Switchbot Candle Warmer Lamp."""
  268. _model = SwitchbotModel.CANDLE_WARMER_LAMP
  269. _effect_dict = {}
  270. _set_rgb_command = ""
  271. _set_color_temp_command = ""
  272. @property
  273. def color_modes(self) -> set[ColorMode]:
  274. """Return the supported color modes."""
  275. return {ColorMode.BRIGHTNESS}
  276. @property
  277. def color_mode(self) -> ColorMode:
  278. """Return the current color mode."""
  279. return ColorMode.BRIGHTNESS
  280. async def get_basic_info(self) -> dict[str, Any] | None:
  281. """Get device basic settings."""
  282. if not (
  283. res := await self._get_multi_commands_results(self._get_basic_info_command)
  284. ):
  285. return None
  286. _version_info, _data = res
  287. return {
  288. "isOn": bool(_data[1] & 0b10000000),
  289. "brightness": _data[2] & 0b01111111,
  290. "firmware": _version_info[2] / 10.0,
  291. }
  292. class SwitchbotRgbicLight(SwitchbotEncryptedDevice, SwitchbotLightStrip):
  293. """Support for Switchbot RGBIC lights."""
  294. _model = SwitchbotModel.RGBICWW_STRIP_LIGHT
  295. _effect_dict = RGBIC_EFFECTS
  296. @property
  297. def color_modes(self) -> set[ColorMode]:
  298. """Return the supported color modes."""
  299. return {ColorMode.RGB, ColorMode.COLOR_TEMP}
  300. @property
  301. def color_mode(self) -> ColorMode:
  302. """Return the current color mode."""
  303. device_mode = RGBICStripLightColorMode(self._get_adv_value("color_mode") or 10)
  304. return _RGBICWW_STRIP_LIGHT_COLOR_MODE_MAP.get(device_mode, ColorMode.OFF)
  305. class SwitchbotRgbicNeonLight(SwitchbotEncryptedDevice, SwitchbotLightStrip):
  306. """Support for Switchbot RGBIC Neon lights."""
  307. _model = SwitchbotModel.RGBIC_NEON_ROPE_LIGHT
  308. _effect_dict = RGBIC_EFFECTS
  309. @property
  310. def color_modes(self) -> set[ColorMode]:
  311. """Return the supported color modes."""
  312. return {ColorMode.RGB}
  313. @property
  314. def color_mode(self) -> ColorMode:
  315. """Return the current color mode."""
  316. return ColorMode.RGB