@willieee802/zigbee-herdsman-converters 19.44.4 → 19.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (591) hide show
  1. package/CHANGELOG.md +1101 -0
  2. package/dist/converters/actions.d.ts.map +1 -1
  3. package/dist/converters/actions.js +2 -0
  4. package/dist/converters/actions.js.map +1 -1
  5. package/dist/converters/fromZigbee.d.ts +1 -150
  6. package/dist/converters/fromZigbee.d.ts.map +1 -1
  7. package/dist/converters/fromZigbee.js +183 -3044
  8. package/dist/converters/fromZigbee.js.map +1 -1
  9. package/dist/converters/toZigbee.d.ts +0 -121
  10. package/dist/converters/toZigbee.d.ts.map +1 -1
  11. package/dist/converters/toZigbee.js +289 -2386
  12. package/dist/converters/toZigbee.js.map +1 -1
  13. package/dist/devices/ITCommander.d.ts.map +1 -1
  14. package/dist/devices/ITCommander.js +2 -1
  15. package/dist/devices/ITCommander.js.map +1 -1
  16. package/dist/devices/acova.d.ts.map +1 -1
  17. package/dist/devices/acova.js +69 -2
  18. package/dist/devices/acova.js.map +1 -1
  19. package/dist/devices/adeo.d.ts.map +1 -1
  20. package/dist/devices/adeo.js +35 -3
  21. package/dist/devices/adeo.js.map +1 -1
  22. package/dist/devices/adurosmart.js +1 -1
  23. package/dist/devices/adurosmart.js.map +1 -1
  24. package/dist/devices/amina.d.ts.map +1 -1
  25. package/dist/devices/amina.js +47 -10
  26. package/dist/devices/amina.js.map +1 -1
  27. package/dist/devices/aurora_lighting.d.ts.map +1 -1
  28. package/dist/devices/aurora_lighting.js +15 -0
  29. package/dist/devices/aurora_lighting.js.map +1 -1
  30. package/dist/devices/automaton.d.ts.map +1 -1
  31. package/dist/devices/automaton.js +1 -0
  32. package/dist/devices/automaton.js.map +1 -1
  33. package/dist/devices/avatto.d.ts.map +1 -1
  34. package/dist/devices/avatto.js +29 -24
  35. package/dist/devices/avatto.js.map +1 -1
  36. package/dist/devices/awox.d.ts.map +1 -1
  37. package/dist/devices/awox.js +41 -3
  38. package/dist/devices/awox.js.map +1 -1
  39. package/dist/devices/bacchus.d.ts.map +1 -1
  40. package/dist/devices/bacchus.js +75 -0
  41. package/dist/devices/bacchus.js.map +1 -1
  42. package/dist/devices/bitron.d.ts.map +1 -1
  43. package/dist/devices/bitron.js +29 -2
  44. package/dist/devices/bitron.js.map +1 -1
  45. package/dist/devices/bosch.d.ts.map +1 -1
  46. package/dist/devices/bosch.js +70 -50
  47. package/dist/devices/bosch.js.map +1 -1
  48. package/dist/devices/bticino.d.ts.map +1 -1
  49. package/dist/devices/bticino.js +11 -1
  50. package/dist/devices/bticino.js.map +1 -1
  51. package/dist/devices/byun.d.ts.map +1 -1
  52. package/dist/devices/byun.js +40 -3
  53. package/dist/devices/byun.js.map +1 -1
  54. package/dist/devices/candeo.d.ts.map +1 -1
  55. package/dist/devices/candeo.js +262 -9
  56. package/dist/devices/candeo.js.map +1 -1
  57. package/dist/devices/centralite.d.ts +9 -0
  58. package/dist/devices/centralite.d.ts.map +1 -1
  59. package/dist/devices/centralite.js +44 -5
  60. package/dist/devices/centralite.js.map +1 -1
  61. package/dist/devices/{aubess.d.ts → cigol.d.ts} +1 -1
  62. package/dist/devices/cigol.d.ts.map +1 -0
  63. package/dist/devices/cigol.js +260 -0
  64. package/dist/devices/cigol.js.map +1 -0
  65. package/dist/devices/cleverio.js +2 -2
  66. package/dist/devices/cleverio.js.map +1 -1
  67. package/dist/devices/climax.d.ts.map +1 -1
  68. package/dist/devices/climax.js +15 -1
  69. package/dist/devices/climax.js.map +1 -1
  70. package/dist/devices/ctm.d.ts.map +1 -1
  71. package/dist/devices/ctm.js +845 -496
  72. package/dist/devices/ctm.js.map +1 -1
  73. package/dist/devices/custom_devices_diy.d.ts +183 -1
  74. package/dist/devices/custom_devices_diy.d.ts.map +1 -1
  75. package/dist/devices/custom_devices_diy.js +390 -33
  76. package/dist/devices/custom_devices_diy.js.map +1 -1
  77. package/dist/devices/daewoo.d.ts +3 -0
  78. package/dist/devices/daewoo.d.ts.map +1 -0
  79. package/dist/devices/daewoo.js +198 -0
  80. package/dist/devices/daewoo.js.map +1 -0
  81. package/dist/devices/danfoss.d.ts.map +1 -1
  82. package/dist/devices/danfoss.js +1270 -296
  83. package/dist/devices/danfoss.js.map +1 -1
  84. package/dist/devices/databyte.d.ts.map +1 -1
  85. package/dist/devices/databyte.js +47 -3
  86. package/dist/devices/databyte.js.map +1 -1
  87. package/dist/devices/datek.d.ts.map +1 -1
  88. package/dist/devices/datek.js +202 -41
  89. package/dist/devices/datek.js.map +1 -1
  90. package/dist/devices/dawon_dns.d.ts.map +1 -1
  91. package/dist/devices/dawon_dns.js +14 -1
  92. package/dist/devices/dawon_dns.js.map +1 -1
  93. package/dist/devices/develco.d.ts.map +1 -1
  94. package/dist/devices/develco.js +145 -64
  95. package/dist/devices/develco.js.map +1 -1
  96. package/dist/devices/diyruz.d.ts.map +1 -1
  97. package/dist/devices/diyruz.js +444 -20
  98. package/dist/devices/diyruz.js.map +1 -1
  99. package/dist/devices/domraem.d.ts.map +1 -1
  100. package/dist/devices/domraem.js +7 -0
  101. package/dist/devices/domraem.js.map +1 -1
  102. package/dist/devices/easyaccess.d.ts.map +1 -1
  103. package/dist/devices/easyaccess.js +22 -2
  104. package/dist/devices/easyaccess.js.map +1 -1
  105. package/dist/devices/easyiot.d.ts.map +1 -1
  106. package/dist/devices/easyiot.js +767 -5
  107. package/dist/devices/easyiot.js.map +1 -1
  108. package/dist/devices/echostar.d.ts.map +1 -1
  109. package/dist/devices/echostar.js +25 -1
  110. package/dist/devices/echostar.js.map +1 -1
  111. package/dist/devices/ecodim.d.ts.map +1 -1
  112. package/dist/devices/ecodim.js +8 -0
  113. package/dist/devices/ecodim.js.map +1 -1
  114. package/dist/devices/ecolink.d.ts.map +1 -1
  115. package/dist/devices/ecolink.js +12 -0
  116. package/dist/devices/ecolink.js.map +1 -1
  117. package/dist/devices/efekta.d.ts.map +1 -1
  118. package/dist/devices/efekta.js +1615 -60
  119. package/dist/devices/efekta.js.map +1 -1
  120. package/dist/devices/eglo.d.ts.map +1 -1
  121. package/dist/devices/eglo.js +203 -17
  122. package/dist/devices/eglo.js.map +1 -1
  123. package/dist/devices/elko.d.ts.map +1 -1
  124. package/dist/devices/elko.js +20 -22
  125. package/dist/devices/elko.js.map +1 -1
  126. package/dist/devices/engo.d.ts.map +1 -1
  127. package/dist/devices/engo.js +201 -0
  128. package/dist/devices/engo.js.map +1 -1
  129. package/dist/devices/enocean.d.ts.map +1 -1
  130. package/dist/devices/enocean.js +132 -4
  131. package/dist/devices/enocean.js.map +1 -1
  132. package/dist/devices/ensystec.d.ts +3 -0
  133. package/dist/devices/ensystec.d.ts.map +1 -0
  134. package/dist/devices/ensystec.js +1200 -0
  135. package/dist/devices/ensystec.js.map +1 -0
  136. package/dist/devices/eurotronic.d.ts +78 -1
  137. package/dist/devices/eurotronic.d.ts.map +1 -1
  138. package/dist/devices/eurotronic.js +244 -40
  139. package/dist/devices/eurotronic.js.map +1 -1
  140. package/dist/devices/ewelink.d.ts.map +1 -1
  141. package/dist/devices/ewelink.js +154 -2
  142. package/dist/devices/ewelink.js.map +1 -1
  143. package/dist/devices/fantem.js +1 -1
  144. package/dist/devices/fantem.js.map +1 -1
  145. package/dist/devices/fireangel.d.ts.map +1 -1
  146. package/dist/devices/fireangel.js +12 -1
  147. package/dist/devices/fireangel.js.map +1 -1
  148. package/dist/devices/frankever.d.ts.map +1 -1
  149. package/dist/devices/frankever.js +96 -0
  150. package/dist/devices/frankever.js.map +1 -1
  151. package/dist/devices/frient.d.ts.map +1 -1
  152. package/dist/devices/frient.js +15 -0
  153. package/dist/devices/frient.js.map +1 -1
  154. package/dist/devices/girier.js +1 -1
  155. package/dist/devices/girier.js.map +1 -1
  156. package/dist/devices/gledopto.js +1 -1
  157. package/dist/devices/gledopto.js.map +1 -1
  158. package/dist/devices/gmmts.d.ts.map +1 -1
  159. package/dist/devices/gmmts.js +59 -55
  160. package/dist/devices/gmmts.js.map +1 -1
  161. package/dist/devices/halo_smart_labs.d.ts +3 -0
  162. package/dist/devices/halo_smart_labs.d.ts.map +1 -0
  163. package/dist/devices/halo_smart_labs.js +918 -0
  164. package/dist/devices/halo_smart_labs.js.map +1 -0
  165. package/dist/devices/handshake_finland.d.ts +3 -0
  166. package/dist/devices/handshake_finland.d.ts.map +1 -0
  167. package/dist/devices/handshake_finland.js +15 -0
  168. package/dist/devices/handshake_finland.js.map +1 -0
  169. package/dist/devices/heiman.d.ts.map +1 -1
  170. package/dist/devices/heiman.js +1361 -147
  171. package/dist/devices/heiman.js.map +1 -1
  172. package/dist/devices/heimgard_technologies.d.ts.map +1 -1
  173. package/dist/devices/heimgard_technologies.js +13 -0
  174. package/dist/devices/heimgard_technologies.js.map +1 -1
  175. package/dist/devices/hive.d.ts.map +1 -1
  176. package/dist/devices/hive.js +11 -0
  177. package/dist/devices/hive.js.map +1 -1
  178. package/dist/devices/ikea.d.ts.map +1 -1
  179. package/dist/devices/ikea.js +185 -135
  180. package/dist/devices/ikea.js.map +1 -1
  181. package/dist/devices/iluminize.d.ts.map +1 -1
  182. package/dist/devices/iluminize.js +8 -7
  183. package/dist/devices/iluminize.js.map +1 -1
  184. package/dist/devices/immax.d.ts.map +1 -1
  185. package/dist/devices/immax.js +3 -1
  186. package/dist/devices/immax.js.map +1 -1
  187. package/dist/devices/index.d.ts.map +1 -1
  188. package/dist/devices/index.js +20 -2
  189. package/dist/devices/index.js.map +1 -1
  190. package/dist/devices/innr.d.ts.map +1 -1
  191. package/dist/devices/innr.js +34 -2
  192. package/dist/devices/innr.js.map +1 -1
  193. package/dist/devices/inovelli.d.ts.map +1 -1
  194. package/dist/devices/inovelli.js +41 -2348
  195. package/dist/devices/inovelli.js.map +1 -1
  196. package/dist/devices/iris.d.ts.map +1 -1
  197. package/dist/devices/iris.js +13 -1
  198. package/dist/devices/iris.js.map +1 -1
  199. package/dist/devices/javis.d.ts.map +1 -1
  200. package/dist/devices/javis.js +39 -1
  201. package/dist/devices/javis.js.map +1 -1
  202. package/dist/devices/jxuan.d.ts.map +1 -1
  203. package/dist/devices/jxuan.js +37 -2
  204. package/dist/devices/jxuan.js.map +1 -1
  205. package/dist/devices/kami.d.ts.map +1 -1
  206. package/dist/devices/kami.js +21 -2
  207. package/dist/devices/kami.js.map +1 -1
  208. package/dist/devices/keen_home.d.ts.map +1 -1
  209. package/dist/devices/keen_home.js +13 -3
  210. package/dist/devices/keen_home.js.map +1 -1
  211. package/dist/devices/klikaanklikuit.d.ts.map +1 -1
  212. package/dist/devices/klikaanklikuit.js +7 -0
  213. package/dist/devices/klikaanklikuit.js.map +1 -1
  214. package/dist/devices/kmpcil.d.ts.map +1 -1
  215. package/dist/devices/kmpcil.js +44 -5
  216. package/dist/devices/kmpcil.js.map +1 -1
  217. package/dist/devices/konke.d.ts.map +1 -1
  218. package/dist/devices/konke.js +10 -1
  219. package/dist/devices/konke.js.map +1 -1
  220. package/dist/devices/lds.d.ts.map +1 -1
  221. package/dist/devices/lds.js +7 -0
  222. package/dist/devices/lds.js.map +1 -1
  223. package/dist/devices/led_trading.d.ts.map +1 -1
  224. package/dist/devices/led_trading.js +13 -13
  225. package/dist/devices/led_trading.js.map +1 -1
  226. package/dist/devices/leedarson.d.ts.map +1 -1
  227. package/dist/devices/leedarson.js +140 -1
  228. package/dist/devices/leedarson.js.map +1 -1
  229. package/dist/devices/legrand.d.ts.map +1 -1
  230. package/dist/devices/legrand.js +73 -42
  231. package/dist/devices/legrand.js.map +1 -1
  232. package/dist/devices/lellki.d.ts.map +1 -1
  233. package/dist/devices/lellki.js +3 -1
  234. package/dist/devices/lellki.js.map +1 -1
  235. package/dist/devices/letv.d.ts.map +1 -1
  236. package/dist/devices/letv.js +16 -2
  237. package/dist/devices/letv.js.map +1 -1
  238. package/dist/devices/lidl.d.ts.map +1 -1
  239. package/dist/devices/lidl.js +26 -6
  240. package/dist/devices/lidl.js.map +1 -1
  241. package/dist/devices/lincukoo.d.ts.map +1 -1
  242. package/dist/devices/lincukoo.js +92 -31
  243. package/dist/devices/lincukoo.js.map +1 -1
  244. package/dist/devices/linkind.d.ts.map +1 -1
  245. package/dist/devices/linkind.js +14 -1
  246. package/dist/devices/linkind.js.map +1 -1
  247. package/dist/devices/linptech.d.ts.map +1 -1
  248. package/dist/devices/linptech.js +3 -1
  249. package/dist/devices/linptech.js.map +1 -1
  250. package/dist/devices/livingwise.d.ts.map +1 -1
  251. package/dist/devices/livingwise.js +2 -1
  252. package/dist/devices/livingwise.js.map +1 -1
  253. package/dist/devices/livolo.d.ts.map +1 -1
  254. package/dist/devices/livolo.js +612 -20
  255. package/dist/devices/livolo.js.map +1 -1
  256. package/dist/devices/lixee.d.ts.map +1 -1
  257. package/dist/devices/lixee.js +46 -44
  258. package/dist/devices/lixee.js.map +1 -1
  259. package/dist/devices/lonsonho.d.ts.map +1 -1
  260. package/dist/devices/lonsonho.js +18 -11
  261. package/dist/devices/lonsonho.js.map +1 -1
  262. package/dist/devices/lumi.d.ts.map +1 -1
  263. package/dist/devices/lumi.js +877 -155
  264. package/dist/devices/lumi.js.map +1 -1
  265. package/dist/devices/lytko.d.ts.map +1 -1
  266. package/dist/devices/lytko.js +205 -556
  267. package/dist/devices/lytko.js.map +1 -1
  268. package/dist/devices/makegood.d.ts.map +1 -1
  269. package/dist/devices/makegood.js +5 -1
  270. package/dist/devices/makegood.js.map +1 -1
  271. package/dist/devices/mazda.js +7 -7
  272. package/dist/devices/mazda.js.map +1 -1
  273. package/dist/devices/meazon.d.ts.map +1 -1
  274. package/dist/devices/meazon.js +82 -20
  275. package/dist/devices/meazon.js.map +1 -1
  276. package/dist/devices/megaman.d.ts +4 -0
  277. package/dist/devices/megaman.d.ts.map +1 -0
  278. package/dist/devices/megaman.js +48 -0
  279. package/dist/devices/megaman.js.map +1 -0
  280. package/dist/devices/mercator.d.ts.map +1 -1
  281. package/dist/devices/mercator.js +20 -5
  282. package/dist/devices/mercator.js.map +1 -1
  283. package/dist/devices/miboxer.d.ts.map +1 -1
  284. package/dist/devices/miboxer.js +3 -1
  285. package/dist/devices/miboxer.js.map +1 -1
  286. package/dist/devices/mill.d.ts.map +1 -1
  287. package/dist/devices/mill.js +33 -7
  288. package/dist/devices/mill.js.map +1 -1
  289. package/dist/devices/moes.d.ts.map +1 -1
  290. package/dist/devices/moes.js +89 -15
  291. package/dist/devices/moes.js.map +1 -1
  292. package/dist/devices/msh.d.ts +3 -0
  293. package/dist/devices/msh.d.ts.map +1 -0
  294. package/dist/devices/msh.js +93 -0
  295. package/dist/devices/msh.js.map +1 -0
  296. package/dist/devices/muller_licht.d.ts.map +1 -1
  297. package/dist/devices/muller_licht.js +11 -0
  298. package/dist/devices/muller_licht.js.map +1 -1
  299. package/dist/devices/multir.d.ts.map +1 -1
  300. package/dist/devices/multir.js +12 -1
  301. package/dist/devices/multir.js.map +1 -1
  302. package/dist/devices/multiterm.js +2 -2
  303. package/dist/devices/multiterm.js.map +1 -1
  304. package/dist/devices/namron.d.ts.map +1 -1
  305. package/dist/devices/namron.js +488 -128
  306. package/dist/devices/namron.js.map +1 -1
  307. package/dist/devices/neo.d.ts.map +1 -1
  308. package/dist/devices/neo.js +151 -192
  309. package/dist/devices/neo.js.map +1 -1
  310. package/dist/devices/netica.d.ts +3 -0
  311. package/dist/devices/netica.d.ts.map +1 -0
  312. package/dist/devices/netica.js +153 -0
  313. package/dist/devices/netica.js.map +1 -0
  314. package/dist/devices/niko.d.ts.map +1 -1
  315. package/dist/devices/niko.js +10 -8
  316. package/dist/devices/niko.js.map +1 -1
  317. package/dist/devices/nodon.d.ts.map +1 -1
  318. package/dist/devices/nodon.js +6 -4
  319. package/dist/devices/nodon.js.map +1 -1
  320. package/dist/devices/nous.d.ts.map +1 -1
  321. package/dist/devices/nous.js +160 -61
  322. package/dist/devices/nous.js.map +1 -1
  323. package/dist/devices/nue_3a.d.ts.map +1 -1
  324. package/dist/devices/nue_3a.js +2 -0
  325. package/dist/devices/nue_3a.js.map +1 -1
  326. package/dist/devices/onesti.d.ts +11 -1
  327. package/dist/devices/onesti.d.ts.map +1 -1
  328. package/dist/devices/onesti.js +30 -6
  329. package/dist/devices/onesti.js.map +1 -1
  330. package/dist/devices/onokom.d.ts.map +1 -1
  331. package/dist/devices/onokom.js +1152 -2309
  332. package/dist/devices/onokom.js.map +1 -1
  333. package/dist/devices/orvibo.d.ts +17 -1
  334. package/dist/devices/orvibo.d.ts.map +1 -1
  335. package/dist/devices/orvibo.js +71 -4
  336. package/dist/devices/orvibo.js.map +1 -1
  337. package/dist/devices/owon.d.ts.map +1 -1
  338. package/dist/devices/owon.js +382 -62
  339. package/dist/devices/owon.js.map +1 -1
  340. package/dist/devices/paul_neuhaus.d.ts.map +1 -1
  341. package/dist/devices/paul_neuhaus.js +9 -0
  342. package/dist/devices/paul_neuhaus.js.map +1 -1
  343. package/dist/devices/paulmann.js +2 -2
  344. package/dist/devices/paulmann.js.map +1 -1
  345. package/dist/devices/perenio.d.ts.map +1 -1
  346. package/dist/devices/perenio.js +57 -39
  347. package/dist/devices/perenio.js.map +1 -1
  348. package/dist/devices/philips.d.ts.map +1 -1
  349. package/dist/devices/philips.js +194 -53
  350. package/dist/devices/philips.js.map +1 -1
  351. package/dist/devices/plaid.d.ts.map +1 -1
  352. package/dist/devices/plaid.js +18 -1
  353. package/dist/devices/plaid.js.map +1 -1
  354. package/dist/devices/plugwise.d.ts.map +1 -1
  355. package/dist/devices/plugwise.js +307 -26
  356. package/dist/devices/plugwise.js.map +1 -1
  357. package/dist/devices/profalux.d.ts.map +1 -1
  358. package/dist/devices/profalux.js +25 -1
  359. package/dist/devices/profalux.js.map +1 -1
  360. package/dist/devices/pushok.d.ts.map +1 -1
  361. package/dist/devices/pushok.js +44 -0
  362. package/dist/devices/pushok.js.map +1 -1
  363. package/dist/devices/qa.d.ts.map +1 -1
  364. package/dist/devices/qa.js +80 -32
  365. package/dist/devices/qa.js.map +1 -1
  366. package/dist/devices/repenic_ltd.d.ts +3 -0
  367. package/dist/devices/repenic_ltd.d.ts.map +1 -0
  368. package/dist/devices/repenic_ltd.js +97 -0
  369. package/dist/devices/repenic_ltd.js.map +1 -0
  370. package/dist/devices/robb.d.ts.map +1 -1
  371. package/dist/devices/robb.js +13 -1
  372. package/dist/devices/robb.js.map +1 -1
  373. package/dist/devices/rtx.js +1 -1
  374. package/dist/devices/rtx.js.map +1 -1
  375. package/dist/devices/salus_controls.d.ts.map +1 -1
  376. package/dist/devices/salus_controls.js +44 -17
  377. package/dist/devices/salus_controls.js.map +1 -1
  378. package/dist/devices/samotech.js +2 -2
  379. package/dist/devices/samotech.js.map +1 -1
  380. package/dist/devices/sber.d.ts.map +1 -1
  381. package/dist/devices/sber.js +435 -26
  382. package/dist/devices/sber.js.map +1 -1
  383. package/dist/devices/schneider_electric.d.ts.map +1 -1
  384. package/dist/devices/schneider_electric.js +808 -252
  385. package/dist/devices/schneider_electric.js.map +1 -1
  386. package/dist/devices/securifi.d.ts.map +1 -1
  387. package/dist/devices/securifi.js +24 -1
  388. package/dist/devices/securifi.js.map +1 -1
  389. package/dist/devices/sengled.d.ts.map +1 -1
  390. package/dist/devices/sengled.js +5 -4
  391. package/dist/devices/sengled.js.map +1 -1
  392. package/dist/devices/shada.d.ts +3 -0
  393. package/dist/devices/shada.d.ts.map +1 -0
  394. package/dist/devices/{aubess.js → shada.js} +7 -20
  395. package/dist/devices/shada.js.map +1 -0
  396. package/dist/devices/shelly.d.ts.map +1 -1
  397. package/dist/devices/shelly.js +646 -61
  398. package/dist/devices/shelly.js.map +1 -1
  399. package/dist/devices/shinasystem.d.ts.map +1 -1
  400. package/dist/devices/shinasystem.js +75 -16
  401. package/dist/devices/shinasystem.js.map +1 -1
  402. package/dist/devices/siglis.d.ts.map +1 -1
  403. package/dist/devices/siglis.js +26 -0
  404. package/dist/devices/siglis.js.map +1 -1
  405. package/dist/devices/sinope.d.ts.map +1 -1
  406. package/dist/devices/sinope.js +163 -83
  407. package/dist/devices/sinope.js.map +1 -1
  408. package/dist/devices/slacky_diy.d.ts.map +1 -1
  409. package/dist/devices/slacky_diy.js +3007 -69
  410. package/dist/devices/slacky_diy.js.map +1 -1
  411. package/dist/devices/smarli.d.ts.map +1 -1
  412. package/dist/devices/smarli.js +4 -5
  413. package/dist/devices/smarli.js.map +1 -1
  414. package/dist/devices/smartthings.d.ts +25 -0
  415. package/dist/devices/smartthings.d.ts.map +1 -1
  416. package/dist/devices/smartthings.js +62 -11
  417. package/dist/devices/smartthings.js.map +1 -1
  418. package/dist/devices/somfy.d.ts.map +1 -1
  419. package/dist/devices/somfy.js +14 -1
  420. package/dist/devices/somfy.js.map +1 -1
  421. package/dist/devices/sonoff.d.ts +42 -1
  422. package/dist/devices/sonoff.d.ts.map +1 -1
  423. package/dist/devices/sonoff.js +5161 -2007
  424. package/dist/devices/sonoff.js.map +1 -1
  425. package/dist/devices/sprut.d.ts.map +1 -1
  426. package/dist/devices/sprut.js +5 -4
  427. package/dist/devices/sprut.js.map +1 -1
  428. package/dist/devices/stello.d.ts.map +1 -1
  429. package/dist/devices/stello.js +6 -24
  430. package/dist/devices/stello.js.map +1 -1
  431. package/dist/devices/stelpro.d.ts +51 -1
  432. package/dist/devices/stelpro.d.ts.map +1 -1
  433. package/dist/devices/stelpro.js +86 -23
  434. package/dist/devices/stelpro.js.map +1 -1
  435. package/dist/devices/sunricher.d.ts.map +1 -1
  436. package/dist/devices/sunricher.js +215 -29
  437. package/dist/devices/sunricher.js.map +1 -1
  438. package/dist/devices/tech.d.ts.map +1 -1
  439. package/dist/devices/tech.js +35 -35
  440. package/dist/devices/tech.js.map +1 -1
  441. package/dist/devices/terncy.d.ts.map +1 -1
  442. package/dist/devices/terncy.js +398 -2
  443. package/dist/devices/terncy.js.map +1 -1
  444. package/dist/devices/third_reality.d.ts +42 -1
  445. package/dist/devices/third_reality.d.ts.map +1 -1
  446. package/dist/devices/third_reality.js +521 -110
  447. package/dist/devices/third_reality.js.map +1 -1
  448. package/dist/devices/tuya.d.ts.map +1 -1
  449. package/dist/devices/tuya.js +3139 -814
  450. package/dist/devices/tuya.js.map +1 -1
  451. package/dist/devices/ubisys.d.ts.map +1 -1
  452. package/dist/devices/ubisys.js +11 -8
  453. package/dist/devices/ubisys.js.map +1 -1
  454. package/dist/devices/vesternet.d.ts.map +1 -1
  455. package/dist/devices/vesternet.js +7 -0
  456. package/dist/devices/vesternet.js.map +1 -1
  457. package/dist/devices/viessmann.d.ts.map +1 -1
  458. package/dist/devices/viessmann.js +107 -4
  459. package/dist/devices/viessmann.js.map +1 -1
  460. package/dist/devices/vsmart.d.ts.map +1 -1
  461. package/dist/devices/vsmart.js +11 -0
  462. package/dist/devices/vsmart.js.map +1 -1
  463. package/dist/devices/weiser.d.ts.map +1 -1
  464. package/dist/devices/weiser.js +6 -0
  465. package/dist/devices/weiser.js.map +1 -1
  466. package/dist/devices/wirenboard.d.ts.map +1 -1
  467. package/dist/devices/wirenboard.js +124 -21
  468. package/dist/devices/wirenboard.js.map +1 -1
  469. package/dist/devices/wmun.d.ts.map +1 -1
  470. package/dist/devices/wmun.js +3 -2
  471. package/dist/devices/wmun.js.map +1 -1
  472. package/dist/devices/woolley.d.ts.map +1 -1
  473. package/dist/devices/woolley.js +6 -9
  474. package/dist/devices/woolley.js.map +1 -1
  475. package/dist/devices/woox.js +2 -2
  476. package/dist/devices/woox.js.map +1 -1
  477. package/dist/devices/xyzroe.d.ts.map +1 -1
  478. package/dist/devices/xyzroe.js +16 -4
  479. package/dist/devices/xyzroe.js.map +1 -1
  480. package/dist/devices/yale.d.ts.map +1 -1
  481. package/dist/devices/yale.js +138 -40
  482. package/dist/devices/yale.js.map +1 -1
  483. package/dist/devices/yandex.d.ts.map +1 -1
  484. package/dist/devices/yandex.js +93 -11
  485. package/dist/devices/yandex.js.map +1 -1
  486. package/dist/devices/yokis.d.ts.map +1 -1
  487. package/dist/devices/yokis.js +122 -85
  488. package/dist/devices/yokis.js.map +1 -1
  489. package/dist/devices/zbeacon.d.ts.map +1 -1
  490. package/dist/devices/zbeacon.js +0 -7
  491. package/dist/devices/zbeacon.js.map +1 -1
  492. package/dist/devices/zemismart.d.ts.map +1 -1
  493. package/dist/devices/zemismart.js +148 -11
  494. package/dist/devices/zemismart.js.map +1 -1
  495. package/dist/devices/zigbeetlc.js +1 -1
  496. package/dist/devices/zigbeetlc.js.map +1 -1
  497. package/dist/index.d.ts +1 -1
  498. package/dist/index.d.ts.map +1 -1
  499. package/dist/index.js +40 -35
  500. package/dist/index.js.map +1 -1
  501. package/dist/lib/bosch.d.ts.map +1 -1
  502. package/dist/lib/bosch.js +212 -42
  503. package/dist/lib/bosch.js.map +1 -1
  504. package/dist/lib/constants.d.ts +99 -17
  505. package/dist/lib/constants.d.ts.map +1 -1
  506. package/dist/lib/constants.js +15 -2
  507. package/dist/lib/constants.js.map +1 -1
  508. package/dist/lib/develco.d.ts +11 -0
  509. package/dist/lib/develco.d.ts.map +1 -1
  510. package/dist/lib/develco.js +78 -9
  511. package/dist/lib/develco.js.map +1 -1
  512. package/dist/lib/exposes.d.ts +11 -10
  513. package/dist/lib/exposes.d.ts.map +1 -1
  514. package/dist/lib/exposes.js +7 -48
  515. package/dist/lib/exposes.js.map +1 -1
  516. package/dist/lib/heiman.d.ts.map +1 -1
  517. package/dist/lib/heiman.js +34 -14
  518. package/dist/lib/heiman.js.map +1 -1
  519. package/dist/lib/ikea.d.ts +17 -0
  520. package/dist/lib/ikea.d.ts.map +1 -1
  521. package/dist/lib/ikea.js +46 -20
  522. package/dist/lib/ikea.js.map +1 -1
  523. package/dist/lib/inovelli.d.ts +86 -0
  524. package/dist/lib/inovelli.d.ts.map +1 -0
  525. package/dist/lib/inovelli.js +2580 -0
  526. package/dist/lib/inovelli.js.map +1 -0
  527. package/dist/lib/ledvance.d.ts +4 -4
  528. package/dist/lib/ledvance.d.ts.map +1 -1
  529. package/dist/lib/ledvance.js +23 -7
  530. package/dist/lib/ledvance.js.map +1 -1
  531. package/dist/lib/legacy.d.ts +21 -2
  532. package/dist/lib/legacy.d.ts.map +1 -1
  533. package/dist/lib/legacy.js +29 -2
  534. package/dist/lib/legacy.js.map +1 -1
  535. package/dist/lib/legrand.d.ts +65 -6
  536. package/dist/lib/legrand.d.ts.map +1 -1
  537. package/dist/lib/legrand.js +188 -9
  538. package/dist/lib/legrand.js.map +1 -1
  539. package/dist/lib/light.d.ts +1 -1
  540. package/dist/lib/light.d.ts.map +1 -1
  541. package/dist/lib/light.js +2 -2
  542. package/dist/lib/light.js.map +1 -1
  543. package/dist/lib/lumi.d.ts +88 -44
  544. package/dist/lib/lumi.d.ts.map +1 -1
  545. package/dist/lib/lumi.js +1813 -59
  546. package/dist/lib/lumi.js.map +1 -1
  547. package/dist/lib/modernExtend.d.ts +19 -14
  548. package/dist/lib/modernExtend.d.ts.map +1 -1
  549. package/dist/lib/modernExtend.js +37 -35
  550. package/dist/lib/modernExtend.js.map +1 -1
  551. package/dist/lib/namron.d.ts +131 -28
  552. package/dist/lib/namron.d.ts.map +1 -1
  553. package/dist/lib/namron.js +723 -42
  554. package/dist/lib/namron.js.map +1 -1
  555. package/dist/lib/nodon.d.ts.map +1 -1
  556. package/dist/lib/nodon.js +3 -1
  557. package/dist/lib/nodon.js.map +1 -1
  558. package/dist/lib/philips.d.ts +106 -2
  559. package/dist/lib/philips.d.ts.map +1 -1
  560. package/dist/lib/philips.js +945 -44
  561. package/dist/lib/philips.js.map +1 -1
  562. package/dist/lib/sonoff.d.ts +77 -10
  563. package/dist/lib/sonoff.d.ts.map +1 -1
  564. package/dist/lib/sonoff.js +165 -34
  565. package/dist/lib/sonoff.js.map +1 -1
  566. package/dist/lib/sunricher.d.ts +1 -1
  567. package/dist/lib/sunricher.d.ts.map +1 -1
  568. package/dist/lib/sunricher.js +6 -8
  569. package/dist/lib/sunricher.js.map +1 -1
  570. package/dist/lib/tuya.d.ts +558 -13
  571. package/dist/lib/tuya.d.ts.map +1 -1
  572. package/dist/lib/tuya.js +1518 -10
  573. package/dist/lib/tuya.js.map +1 -1
  574. package/dist/lib/types.d.ts +9 -6
  575. package/dist/lib/types.d.ts.map +1 -1
  576. package/dist/lib/ubisys.d.ts +1 -1
  577. package/dist/lib/ubisys.d.ts.map +1 -1
  578. package/dist/lib/ubisys.js +60 -5
  579. package/dist/lib/ubisys.js.map +1 -1
  580. package/dist/lib/utils.d.ts +5 -8
  581. package/dist/lib/utils.d.ts.map +1 -1
  582. package/dist/lib/utils.js +30 -17
  583. package/dist/lib/utils.js.map +1 -1
  584. package/dist/lib/zosung.d.ts +69 -6
  585. package/dist/lib/zosung.d.ts.map +1 -1
  586. package/dist/lib/zosung.js +113 -1
  587. package/dist/lib/zosung.js.map +1 -1
  588. package/dist/models-index.json +1 -1
  589. package/package.json +2 -2
  590. package/dist/devices/aubess.d.ts.map +0 -1
  591. package/dist/devices/aubess.js.map +0 -1
@@ -35,9 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.thermostat_keypad_lockout = exports.thermostat_temperature_display_mode = exports.thermostat_programming_operation_mode = exports.thermostat_control_sequence_of_operation = exports.acova_thermostat_system_mode = exports.thermostat_system_mode = exports.thermostat_weekly_schedule = exports.thermostat_remote_sensing = exports.effect = exports.light_color_colortemp = exports.light_colortemp_startup = exports.light_onoff_brightness = exports.light_hue_saturation_move = exports.light_hue_saturation_step = exports.light_color_and_colortemp_via_color = exports.light_colortemp_move = exports.light_colortemp_step = exports.light_brightness_move = exports.light_brightness_step = exports.ballast_config = exports.level_config = exports.occupancy_timeout = exports.cover_mode = exports.cover_position_tilt = exports.cover_state = exports.squawk = exports.warning_simple = exports.ias_max_duration = exports.warning = exports.cover_via_brightness = exports.lock_userstatus = exports.pincode_lock = exports.lock_sound_volume = exports.lock_auto_relock_time = exports.lock = exports.light_color_options = exports.light_color_mode = exports.power_on_behavior = exports.battery_voltage = exports.battery_percentage_remaining = exports.arm_mode = exports.zcl_command = exports.identify = exports.factory_reset = exports.command = exports.write = exports.read = exports.light_colortemp = exports.light_color = exports.on_off = void 0;
37
37
  exports.humidity = exports.temperature = exports.dcpower = exports.dcvoltage = exports.dccurrent = exports.accurrent_neutral = exports.accurrent_phase_c = exports.accurrent_phase_b = exports.accurrent = exports.acvoltage_phase_c = exports.acvoltage_phase_b = exports.acvoltage = exports.powerfactor = exports.electrical_measurement_power_reactive = exports.frequency = exports.currentsummreceived = exports.currenttier4summdelivered = exports.currenttier3summdelivered = exports.currenttier2summdelivered = exports.currenttier1summdelivered = exports.currentsummdelivered = exports.metering_extended_status = exports.metering_status = exports.metering_power = exports.electrical_measurement_power_phase_c = exports.electrical_measurement_power_phase_b = exports.electrical_measurement_power = exports.thermostat_ac_louver_position = exports.thermostat_max_cool_setpoint_limit = exports.thermostat_min_cool_setpoint_limit = exports.thermostat_max_heat_setpoint_limit = exports.thermostat_min_heat_setpoint_limit = exports.thermostat_running_mode = exports.thermostat_relay_status_log = exports.thermostat_setpoint_raise_lower = exports.thermostat_unoccupied_cooling_setpoint = exports.thermostat_occupied_cooling_setpoint = exports.thermostat_unoccupied_heating_setpoint = exports.thermostat_occupied_heating_setpoint = exports.thermostat_running_state = exports.thermostat_pi_heating_demand = exports.thermostat_clear_weekly_schedule = exports.thermostat_occupancy = exports.thermostat_local_temperature_calibration = exports.thermostat_outdoor_temperature = exports.thermostat_local_temperature = exports.fan_speed = exports.fan_mode = exports.thermostat_temperature_setpoint_hold_duration = exports.thermostat_temperature_setpoint_hold = void 0;
38
- exports.danfoss_icon_application = exports.danfoss_multimaster_role = exports.danfoss_system_status_water = exports.danfoss_heat_supply_request = exports.danfoss_system_status_code = exports.danfoss_icon2_pre_heat_status = exports.danfoss_icon2_pre_heat = exports.danfoss_schedule_type_used = exports.danfoss_floor_max_setpoint = exports.danfoss_floor_min_setpoint = exports.danfoss_floor_sensor_mode = exports.danfoss_room_status_code = exports.danfoss_output_status = exports.danfoss_regulation_setpoint_offset = exports.danfoss_adaptation_control = exports.danfoss_adaptation_settings = exports.danfoss_adaptation_status = exports.danfoss_preheat_status = exports.danfoss_load_estimate = exports.danfoss_load_room_mean = exports.danfoss_load_balancing_enable = exports.danfoss_window_open_external = exports.danfoss_window_open_internal = exports.danfoss_window_open_feature = exports.danfoss_trigger_time = exports.danfoss_day_of_week = exports.danfoss_heat_required = exports.danfoss_heat_available = exports.danfoss_algorithm_scale_factor = exports.danfoss_viewing_direction = exports.danfoss_radiator_covered = exports.danfoss_external_measured_room_sensor = exports.danfoss_thermostat_vertical_orientation = exports.danfoss_mounted_mode_control = exports.danfoss_mounted_mode_active = exports.danfoss_thermostat_occupied_heating_setpoint_scheduled = exports.danfoss_thermostat_occupied_heating_setpoint = exports.hue_wall_switch_device_mode = exports.kmpcil_res005_on_off = exports.tuya_relay_din_led_indicator = exports.SPZ01_power_outage_memory = exports.STS_PRS_251_beep = exports.LS21001_alert_behaviour = exports.ZigUP_lock = exports.livolo_cover_options = exports.livolo_cover_position = exports.livolo_cover_state = exports.livolo_dimmer_level = exports.livolo_switch_on_off = exports.livolo_socket_switch_on_off = void 0;
39
- exports.viessmann_window_open_force = exports.viessmann_window_open = exports.TS0210_sensitivity = exports.ZM35HQ_attr = exports.moes_cover_calibration = exports.tuya_cover_reversal = exports.tuya_cover_calibration = exports.ts0216_alarm = exports.ts0216_volume = exports.ts0216_duration = exports.TS0003_curtain_switch = exports.scene_rename = exports.scene_remove_all = exports.scene_remove = exports.scene_add = exports.scene_recall = exports.scene_store = exports.heiman_ir_remote = exports.ts0201_temperature_humidity_alarm = exports.power_source = exports.diyruz_zintercom_config = exports.diyruz_airsense_config = exports.diyruz_geiger_config = exports.TYZB01_on_off = exports.diyruz_freepad_on_off_config = exports.legrand_power_alarm = exports.bticino_4027C_cover_position = exports.bticino_4027C_cover_state = exports.tint_scene = exports.ptvo_switch_analog_input = exports.ptvo_switch_uart = exports.ptvo_switch_trigger = exports.DTB190502A1_LED = exports.stelpro_thermostat_outdoor_temperature = exports.stelpro_peak_demand_event_icon = exports.eurotronic_mirror_display = exports.eurotronic_child_lock = exports.eurotronic_trv_mode = exports.eurotronic_valve_position = exports.eurotronic_current_heating_setpoint = exports.eurotronic_error_status = exports.eurotronic_host_flags = exports.EMIZB_132_mode = exports.tuya_led_controller = exports.tuya_led_control = exports.easycode_auto_relock = exports.namron_thermostat_child_lock = exports.namron_thermostat = exports.ZMCSW032D_cover_position = exports.danfoss_icon_forced_heating_cooling = void 0;
40
- exports.TS110E_light_onoff_brightness = exports.TS110E_onoff_brightness = exports.TS110E_options = exports.ptvo_switch_light_brightness = exports.light_onoff_restorable_brightness = exports.ignore_rate = exports.ignore_transition = exports.led_on_motion = exports.tuya_operation_mode = exports.sihas_set_people = exports.wiser_sed_thermostat_keypad_lockout = exports.wiser_sed_thermostat_local_temperature_calibration = exports.wiser_sed_occupied_heating_setpoint = exports.wiser_sed_zone_mode = exports.wiser_vact_calibrate_valve = exports.wiser_zone_mode = exports.wiser_hact_config = exports.wiser_fip_setting = exports.schneider_thermostat_keypad_lockout = exports.schneider_thermostat_pi_heating_demand = exports.schneider_thermostat_control_sequence_of_operation = exports.schneider_thermostat_occupied_heating_setpoint = exports.schneider_thermostat_system_mode = exports.schneider_temperature_measured_value = exports.wiser_dimmer_mode = exports.schneider_dimmer_mode = exports.idlock_relock_enabled = exports.idlock_lock_mode = exports.idlock_service_mode = exports.idlock_rfid_enable = exports.idlock_master_pin_mode = exports.dawondns_only_off = exports.viessmann_assembly_mode = void 0;
38
+ exports.ignore_rate = exports.ignore_transition = exports.TS0003_curtain_switch = exports.scene_rename = exports.scene_remove_all = exports.scene_remove = exports.scene_add = exports.scene_recall = exports.scene_store = exports.power_source = exports.TYZB01_on_off = exports.tint_scene = void 0;
41
39
  const zigbee_herdsman_1 = require("@willieee802/zigbee-herdsman");
42
40
  const libColor = __importStar(require("../lib/color"));
43
41
  const constants = __importStar(require("../lib/constants"));
@@ -50,18 +48,10 @@ const utils = __importStar(require("../lib/utils"));
50
48
  const utils_1 = require("../lib/utils");
51
49
  const NS = "zhc:tz";
52
50
  const manufacturerOptions = {
53
- sunricher: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SHENZHEN_SUNRICHER_TECHNOLOGY_LTD },
54
51
  lumi: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.LUMI_UNITED_TECHOLOGY_LTD_SHENZHEN, disableDefaultResponse: true },
55
- eurotronic: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.NXP_SEMICONDUCTORS },
56
- danfoss: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DANFOSS_A_S },
57
- hue: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SIGNIFY_NETHERLANDS_B_V },
58
52
  ikea: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.IKEA_OF_SWEDEN },
59
53
  sinope: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SINOPE_TECHNOLOGIES },
60
- stello: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.STELPRO },
61
- stelpro: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.STELPRO },
62
54
  tint: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.MUELLER_LICHT_INTERNATIONAL_INC },
63
- legrand: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.LEGRAND_GROUP, disableDefaultResponse: true },
64
- viessmann: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.VIESSMANN_ELEKTRONIK_GMBH },
65
55
  };
66
56
  exports.on_off = {
67
57
  key: ["state", "on_time", "off_wait_time"],
@@ -103,30 +93,9 @@ exports.light_color = {
103
93
  const newColor = libColor.Color.fromConverterArg(value);
104
94
  const newState = {};
105
95
  const transtime = utils.getTransition(entity, key, meta).time;
106
- const supportsHueAndSaturation = utils.getMetaValue(entity, meta.mapped, "supportsHueAndSaturation", "allEqual", true);
107
- const supportsEnhancedHue = utils.getMetaValue(entity, meta.mapped, "supportsEnhancedHue", "allEqual", true);
108
- if (newColor.isHSV() && !supportsHueAndSaturation) {
109
- // The color we got is HSV but the bulb does not support Hue/Saturation mode
110
- throw new Error("This light does not support Hue/Saturation, please use X/Y instead.");
111
- }
112
- if (newColor.isRGB() || newColor.isXY()) {
113
- // Convert RGB to XY color mode because Zigbee doesn't support RGB (only x/y and hue/saturation)
114
- const xy = newColor.isRGB() ? newColor.rgb.gammaCorrected().toXY().rounded(4) : newColor.xy;
115
- // Some bulbs e.g. RB 185 C don't turn to red (they don't respond at all) when x: 0.701 and y: 0.299
116
- // is send. These values are e.g. send by Home Assistant when clicking red in the color wheel.
117
- // If we slightly modify these values the bulb will respond.
118
- // https://github.com/home-assistant/home-assistant/issues/31094
119
- if (utils.getMetaValue(entity, meta.mapped, "applyRedFix", "allEqual", false) && xy.x === 0.701 && xy.y === 0.299) {
120
- xy.x = 0.7006;
121
- xy.y = 0.2993;
122
- }
123
- newState.color_mode = constants.colorModeLookup[1];
124
- newState.color = xy.toObject();
125
- const colorx = utils.mapNumberRange(xy.x, 0, 1, 0, 65535);
126
- const colory = utils.mapNumberRange(xy.y, 0, 1, 0, 65535);
127
- await entity.command("lightingColorCtrl", "moveToColor", { transtime, colorx, colory, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
128
- }
129
- else if (newColor.isHSV()) {
96
+ const supportsHueAndSaturation = utils.getMetaValue(entity, meta.mapped, "supportsHueAndSaturation", "allEqual", false);
97
+ const supportsEnhancedHue = utils.getMetaValue(entity, meta.mapped, "supportsEnhancedHue", "allEqual", false);
98
+ if (newColor.isHSV() && supportsHueAndSaturation) {
130
99
  const hsv = newColor.hsv;
131
100
  const hsvCorrected = hsv.colorCorrected(meta);
132
101
  newState.color_mode = constants.colorModeLookup[0];
@@ -161,6 +130,28 @@ exports.light_color = {
161
130
  await entity.command("lightingColorCtrl", "moveToSaturation", { transtime, saturation, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
162
131
  }
163
132
  }
133
+ else if (newColor.isRGB() || newColor.isXY() || newColor.isHSV()) {
134
+ // convert RGB/HSV to XY color mode
135
+ // (many devices only support XY, some support also HSV, but RGB is not supported at all)
136
+ const xy = newColor.isRGB()
137
+ ? newColor.rgb.gammaCorrected().toXY().rounded(4)
138
+ : newColor.isHSV()
139
+ ? newColor.hsv.colorCorrected(meta).toXY().rounded(4)
140
+ : newColor.xy;
141
+ // Some bulbs e.g. RB 185 C don't turn to red (they don't respond at all) when x: 0.701 and y: 0.299
142
+ // is send. These values are e.g. send by Home Assistant when clicking red in the color wheel.
143
+ // If we slightly modify these values the bulb will respond.
144
+ // https://github.com/home-assistant/home-assistant/issues/31094
145
+ if (utils.getMetaValue(entity, meta.mapped, "applyRedFix", "allEqual", false) && xy.x === 0.701 && xy.y === 0.299) {
146
+ xy.x = 0.7006;
147
+ xy.y = 0.2993;
148
+ }
149
+ newState.color_mode = constants.colorModeLookup[1];
150
+ newState.color = xy.toObject();
151
+ const colorx = utils.mapNumberRange(xy.x, 0, 1, 0, 65535);
152
+ const colory = utils.mapNumberRange(xy.y, 0, 1, 0, 65535);
153
+ await entity.command("lightingColorCtrl", "moveToColor", { transtime, colorx, colory, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
154
+ }
164
155
  else {
165
156
  throw new Error("Invalid color");
166
157
  }
@@ -292,9 +283,18 @@ exports.arm_mode = {
292
283
  secondsRemain = Math.round(value.delay);
293
284
  delayUntil = performance.now() + value.delay * 1000;
294
285
  }
286
+ let audibleNotif = 0;
287
+ if (value.audiblenotif != null) {
288
+ utils.assertNumber(value.audiblenotif, "audiblenotif");
289
+ if (!utils.isInRange(0, 255, value.audiblenotif)) {
290
+ throw new Error(`Invalid audiblenotif value: ${value.audiblenotif} (expected ${0} to ${255})`);
291
+ }
292
+ audibleNotif = Math.round(value.audiblenotif);
293
+ }
295
294
  globalStore.putValue(entity, "panelStatus", panelStatus);
296
295
  globalStore.putValue(entity, "delayUntil", delayUntil);
297
- const payload = { panelstatus: panelStatus, secondsremain: secondsRemain, audiblenotif: 0, alarmstatus: 0 };
296
+ globalStore.putValue(entity, "audibleNotif", audibleNotif);
297
+ const payload = { panelstatus: panelStatus, secondsremain: secondsRemain, audiblenotif: audibleNotif, alarmstatus: 0 };
298
298
  await entity.commandResponse("ssIasAce", "panelStatusChanged", payload);
299
299
  },
300
300
  };
@@ -694,18 +694,20 @@ exports.level_config = {
694
694
  utils.assertObject(value, key);
695
695
  // onOffTransitionTime - range 0x0000 to 0xffff - optional
696
696
  if (value.on_off_transition_time != null) {
697
- let onOffTransitionTimeValue = Number(value.on_off_transition_time);
697
+ let onOffTransitionTimeValue = Number(value.on_off_transition_time) * 10;
698
698
  if (onOffTransitionTimeValue > 65535)
699
699
  onOffTransitionTimeValue = 65535;
700
700
  if (onOffTransitionTimeValue < 0)
701
701
  onOffTransitionTimeValue = 0;
702
702
  await entity.write("genLevelCtrl", { onOffTransitionTime: onOffTransitionTimeValue }, utils.getOptions(meta.mapped, entity));
703
- Object.assign(state, { on_off_transition_time: onOffTransitionTimeValue });
703
+ Object.assign(state, { on_off_transition_time: onOffTransitionTimeValue / 10 });
704
704
  }
705
705
  // onTransitionTime - range 0x0000 to 0xffff - optional
706
706
  // 0xffff = use onOffTransitionTime
707
707
  if (value.on_transition_time != null) {
708
708
  let onTransitionTimeValue = value.on_transition_time;
709
+ if (typeof onTransitionTimeValue === "number")
710
+ onTransitionTimeValue *= 10;
709
711
  if (typeof onTransitionTimeValue === "string" && onTransitionTimeValue.toLowerCase() === "disabled") {
710
712
  onTransitionTimeValue = 65535;
711
713
  }
@@ -721,12 +723,16 @@ exports.level_config = {
721
723
  if (onTransitionTimeValue === 65535) {
722
724
  onTransitionTimeValue = "disabled";
723
725
  }
724
- Object.assign(state, { on_transition_time: onTransitionTimeValue });
726
+ Object.assign(state, {
727
+ on_transition_time: typeof onTransitionTimeValue === "number" ? onTransitionTimeValue / 10 : onTransitionTimeValue,
728
+ });
725
729
  }
726
730
  // offTransitionTime - range 0x0000 to 0xffff - optional
727
731
  // 0xffff = use onOffTransitionTime
728
732
  if (value.off_transition_time != null) {
729
733
  let offTransitionTimeValue = value.off_transition_time;
734
+ if (typeof offTransitionTimeValue === "number")
735
+ offTransitionTimeValue *= 10;
730
736
  if (typeof offTransitionTimeValue === "string" && offTransitionTimeValue.toLowerCase() === "disabled") {
731
737
  offTransitionTimeValue = 65535;
732
738
  }
@@ -742,7 +748,9 @@ exports.level_config = {
742
748
  if (offTransitionTimeValue === 65535) {
743
749
  offTransitionTimeValue = "disabled";
744
750
  }
745
- Object.assign(state, { off_transition_time: offTransitionTimeValue });
751
+ Object.assign(state, {
752
+ off_transition_time: typeof offTransitionTimeValue === "number" ? offTransitionTimeValue / 10 : offTransitionTimeValue,
753
+ });
746
754
  }
747
755
  // startUpCurrentLevel - range 0x00 to 0xff - optional
748
756
  // 0x00 = return to minimum supported level
@@ -2079,1715 +2087,149 @@ exports.humidity = {
2079
2087
  };
2080
2088
  // #endregion
2081
2089
  // #region Non-generic converters
2082
- exports.livolo_socket_switch_on_off = {
2083
- key: ["state"],
2090
+ exports.tint_scene = {
2091
+ key: ["tint_scene"],
2084
2092
  convertSet: async (entity, key, value, meta) => {
2085
- if (typeof value !== "string") {
2086
- return;
2087
- }
2088
- const state = value.toLowerCase();
2089
- let oldstate = 1;
2090
- if (state === "on") {
2091
- oldstate = 108;
2092
- }
2093
- let channel = 1.0;
2094
- const postfix = meta.endpoint_name || "left";
2095
- await entity.command("genOnOff", "toggle", {}, { transactionSequenceNumber: 0 });
2096
- const payloadOn = { 1: { value: Buffer.from([1, 0, 0, 0, 0, 0, 0, 0]), type: 1 } };
2097
- const payloadOff = { 1: { value: Buffer.from([0, 0, 0, 0, 0, 0, 0, 0]), type: 1 } };
2098
- const payloadOnRight = { 1: { value: Buffer.from([2, 0, 0, 0, 0, 0, 0, 0]), type: 2 } };
2099
- const payloadOffRight = { 1: { value: Buffer.from([0, 0, 0, 0, 0, 0, 0, 0]), type: 2 } };
2100
- const payloadOnBottomLeft = { 1: { value: Buffer.from([4, 0, 0, 0, 0, 0, 0, 0]), type: 4 } };
2101
- const payloadOffBottomLeft = { 1: { value: Buffer.from([0, 0, 0, 0, 0, 0, 0, 0]), type: 4 } };
2102
- const payloadOnBottomRight = { 1: { value: Buffer.from([8, 0, 0, 0, 0, 0, 0, 0]), type: 136 } };
2103
- const payloadOffBottomRight = { 1: { value: Buffer.from([0, 0, 0, 0, 0, 0, 0, 0]), type: 136 } };
2104
- if (postfix === "left") {
2105
- await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: oldstate, transtime: channel, optionsMask: 0, optionsOverride: 0 });
2106
- await entity.write("genPowerCfg", state === "on" ? payloadOn : payloadOff, {
2107
- manufacturerCode: 0x1ad2,
2108
- disableDefaultResponse: true,
2109
- disableResponse: true,
2110
- reservedBits: 3,
2111
- direction: 1,
2112
- transactionSequenceNumber: 0xe9,
2113
- });
2114
- return { state: { state: value.toUpperCase() } };
2115
- }
2116
- if (postfix === "right") {
2117
- channel = 2.0;
2118
- await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: oldstate, transtime: channel, optionsMask: 0, optionsOverride: 0 });
2119
- await entity.write("genPowerCfg", state === "on" ? payloadOnRight : payloadOffRight, {
2120
- manufacturerCode: 0x1ad2,
2121
- disableDefaultResponse: true,
2122
- disableResponse: true,
2123
- reservedBits: 3,
2124
- direction: 1,
2125
- transactionSequenceNumber: 0xe9,
2126
- });
2127
- return { state: { state: value.toUpperCase() } };
2128
- }
2129
- if (postfix === "bottom_right") {
2130
- await entity.write("genPowerCfg", state === "on" ? payloadOnBottomRight : payloadOffBottomRight, {
2131
- manufacturerCode: 0x1ad2,
2132
- disableDefaultResponse: true,
2133
- disableResponse: true,
2134
- reservedBits: 3,
2135
- direction: 1,
2136
- transactionSequenceNumber: 0xe9,
2137
- });
2138
- return { state: { state: value.toUpperCase() } };
2139
- }
2140
- if (postfix === "bottom_left") {
2141
- await entity.write("genPowerCfg", state === "on" ? payloadOnBottomLeft : payloadOffBottomLeft, {
2142
- manufacturerCode: 0x1ad2,
2143
- disableDefaultResponse: true,
2144
- disableResponse: true,
2145
- reservedBits: 3,
2146
- direction: 1,
2147
- transactionSequenceNumber: 0xe9,
2148
- });
2149
- return { state: { state: value.toUpperCase() } };
2150
- }
2151
- return { state: { state: value.toUpperCase() } };
2152
- },
2153
- convertGet: async (entity, key, meta) => {
2154
- await entity.command("genOnOff", "toggle", {}, { transactionSequenceNumber: 0 });
2093
+ await entity.write("genBasic", { 16389: { value, type: 0x20 } }, manufacturerOptions.tint);
2155
2094
  },
2156
2095
  };
2157
- exports.livolo_switch_on_off = {
2158
- key: ["state"],
2096
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2097
+ exports.TYZB01_on_off = {
2098
+ key: ["state", "time_in_seconds"],
2159
2099
  convertSet: async (entity, key, value, meta) => {
2100
+ const result = await exports.on_off.convertSet(entity, key, value, meta);
2160
2101
  utils.assertString(value, key);
2161
- const postfix = meta.endpoint_name || "left";
2162
- const state = value.toLowerCase() === "on" ? 108 : 1;
2163
- let channel = 1;
2164
- if (postfix === "left") {
2165
- channel = 1.0;
2102
+ const lowerCaseValue = value.toLowerCase();
2103
+ if (!["on", "off"].includes(lowerCaseValue)) {
2104
+ return result;
2166
2105
  }
2167
- else if (postfix === "right") {
2168
- channel = 2.0;
2106
+ const messageKeys = Object.keys(meta.message);
2107
+ const timeInSecondsValue = (() => {
2108
+ if (messageKeys.includes("state")) {
2109
+ return meta.message.time_in_seconds;
2110
+ }
2111
+ if (meta.endpoint_name) {
2112
+ return meta.message[`time_in_seconds_${meta.endpoint_name}`];
2113
+ }
2114
+ return null;
2115
+ })();
2116
+ if (!timeInSecondsValue) {
2117
+ return result;
2169
2118
  }
2170
- else {
2171
- return;
2119
+ const timeInSeconds = Number(timeInSecondsValue);
2120
+ if (!Number.isInteger(timeInSeconds) || timeInSeconds < 0 || timeInSeconds > 0xfffe) {
2121
+ throw new Error("The time_in_seconds value must be convertible to an integer in the range: <0x0000, 0xFFFE>");
2172
2122
  }
2173
- await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: state, transtime: channel, optionsMask: 0, optionsOverride: 0 });
2174
- return { state: { state: value.toUpperCase() } };
2123
+ const on = lowerCaseValue === "on";
2124
+ await entity.command("genOnOff", "onWithTimedOff", {
2125
+ ctrlbits: 0,
2126
+ ontime: on ? 0 : timeInSeconds.valueOf(),
2127
+ offwaittime: on ? timeInSeconds.valueOf() : 0,
2128
+ }, utils.getOptions(meta.mapped, entity));
2129
+ return result;
2130
+ },
2131
+ convertGet: async (entity, key, meta) => {
2132
+ await entity.read("genOnOff", ["onOff"]);
2175
2133
  },
2134
+ };
2135
+ exports.power_source = {
2136
+ key: ["power_source", "charging"],
2176
2137
  convertGet: async (entity, key, meta) => {
2177
- await entity.command("genOnOff", "toggle", {}, { transactionSequenceNumber: 0 });
2138
+ await entity.read("genBasic", ["powerSource"]);
2178
2139
  },
2179
2140
  };
2180
- exports.livolo_dimmer_level = {
2181
- key: ["brightness", "brightness_percent", "level"],
2141
+ exports.scene_store = {
2142
+ key: ["scene_store"],
2182
2143
  convertSet: async (entity, key, value, meta) => {
2183
- // upscale to 100
2184
- value = Number(value);
2185
- utils.assertNumber(value, key);
2186
- // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
2187
- let newValue;
2188
- if (key === "level") {
2189
- if (value >= 0 && value <= 1000) {
2190
- newValue = utils.mapNumberRange(value, 0, 1000, 0, 100);
2191
- }
2192
- else {
2193
- throw new Error("Dimmer level is out of range 0..1000");
2194
- }
2144
+ const isGroup = utils.isGroup(entity);
2145
+ const groupid = isGroup ? entity.groupID : value.group_id != null ? value.group_id : 0;
2146
+ let sceneid = value;
2147
+ let scenename = null;
2148
+ if (typeof value === "object") {
2149
+ sceneid = value.ID;
2150
+ scenename = value.name;
2195
2151
  }
2196
- else if (key === "brightness_percent") {
2197
- if (value >= 0 && value <= 100) {
2198
- newValue = Math.round(value);
2199
- }
2200
- else {
2201
- throw new Error("Dimmer brightness_percent is out of range 0..100");
2152
+ utils.assertNumber(sceneid, "ID");
2153
+ if (groupid === 0 && sceneid === 0) {
2154
+ // From Zigbee spec:
2155
+ // "Scene identifier 0x00, along with group identifier 0x0000, is reserved for the global scene used by the OnOff cluster"
2156
+ throw new Error("Scene ID 0 cannot be used with group ID 0 (reserved).");
2157
+ }
2158
+ const response = await entity.command("genScenes", "store", { groupid, sceneid }, utils.getOptions(meta.mapped, entity));
2159
+ if (isGroup) {
2160
+ if (meta.membersState) {
2161
+ for (const member of entity.members) {
2162
+ utils.saveSceneState(member, sceneid, groupid, meta.membersState[member.getDevice().ieeeAddr], scenename);
2163
+ }
2202
2164
  }
2203
2165
  }
2166
+ else if (response.status === 0) {
2167
+ utils.saveSceneState(entity, sceneid, groupid, meta.state, scenename);
2168
+ }
2204
2169
  else {
2205
- if (value >= 0 && value <= 255) {
2206
- newValue = utils.mapNumberRange(value, 0, 255, 0, 100);
2207
- }
2208
- else {
2209
- throw new Error("Dimmer brightness is out of range 0..255");
2210
- }
2170
+ throw new Error(`Scene add not successful ('${zigbee_herdsman_1.Zcl.Status[response.status]}')`);
2211
2171
  }
2212
- await entity.command("genOnOff", "toggle", {}, { transactionSequenceNumber: 0 });
2213
- const payload = { 769: { value: Buffer.from([newValue, 0, 0, 0, 0, 0, 0, 0]), type: 1 } };
2214
- await entity.write("genPowerCfg", payload, {
2215
- manufacturerCode: 0x1ad2,
2216
- disableDefaultResponse: true,
2217
- disableResponse: true,
2218
- reservedBits: 3,
2219
- direction: 1,
2220
- transactionSequenceNumber: 0xe9,
2221
- writeUndiv: true,
2222
- });
2223
- return {
2224
- state: { brightness_percent: newValue, brightness: utils.mapNumberRange(newValue, 0, 100, 0, 255), level: newValue * 10 },
2225
- };
2226
- },
2227
- convertGet: async (entity, key, meta) => {
2228
- await entity.command("genOnOff", "toggle", {}, { transactionSequenceNumber: 0 });
2229
- },
2230
- };
2231
- exports.livolo_cover_state = {
2232
- key: ["state"],
2233
- convertSet: async (entity, key, value, meta) => {
2234
- utils.assertEndpoint(entity);
2235
- // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
2236
- let payload;
2237
- const options = {
2238
- frameType: 0,
2239
- manufacturerCode: 0x1ad2,
2240
- disableDefaultResponse: true,
2241
- disableResponse: true,
2242
- reservedBits: 3,
2243
- direction: 1,
2244
- writeUndiv: true,
2245
- transactionSequenceNumber: 0xe9,
2246
- };
2247
- switch (value) {
2248
- case "OPEN":
2249
- payload = { attrId: 0x0000, selector: null, elementData: [0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] };
2250
- break;
2251
- case "CLOSE":
2252
- payload = { attrId: 0x0000, selector: null, elementData: [0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] };
2253
- break;
2254
- case "STOP":
2255
- payload = { attrId: 0x0000, selector: null, elementData: [0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] };
2256
- break;
2257
- default:
2258
- throw new Error(`Value '${value}' is not a valid cover position (must be one of 'OPEN' or 'CLOSE')`);
2259
- }
2260
- await entity.writeStructured("genPowerCfg",
2261
- // @ts-expect-error workaround write custom payload
2262
- [payload], options);
2263
- return {
2264
- state: {
2265
- moving: true,
2266
- },
2267
- };
2268
- },
2269
- };
2270
- exports.livolo_cover_position = {
2271
- key: ["position"],
2272
- convertSet: async (entity, key, value, meta) => {
2273
- utils.assertNumber(value, key);
2274
- const position = 100 - value;
2275
- await entity.command("genOnOff", "toggle", {}, { transactionSequenceNumber: 0 });
2276
- const payload = { 1025: { value: [position, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], type: 1 } };
2277
- await entity.write("genPowerCfg", payload, {
2278
- manufacturerCode: 0x1ad2,
2279
- disableDefaultResponse: true,
2280
- disableResponse: true,
2281
- reservedBits: 3,
2282
- direction: 1,
2283
- transactionSequenceNumber: 0xe9,
2284
- writeUndiv: true,
2285
- });
2286
- return {
2287
- state: {
2288
- position: value,
2289
- moving: true,
2290
- },
2291
- };
2172
+ logger_1.logger.info("Successfully stored scene", NS);
2173
+ return { state: {} };
2292
2174
  },
2293
2175
  };
2294
- exports.livolo_cover_options = {
2295
- key: ["options"],
2176
+ exports.scene_recall = {
2177
+ key: ["scene_recall"],
2296
2178
  convertSet: async (entity, key, value, meta) => {
2297
- utils.assertObject(value);
2298
- const options = {
2299
- frameType: 0,
2300
- manufacturerCode: 0x1ad2,
2301
- disableDefaultResponse: true,
2302
- disableResponse: true,
2303
- reservedBits: 3,
2304
- direction: 1,
2305
- writeUndiv: true,
2306
- transactionSequenceNumber: 0xe9,
2307
- };
2308
- if (value.motor_direction != null) {
2309
- // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
2310
- let direction;
2311
- switch (value.motor_direction) {
2312
- case "FORWARD":
2313
- direction = 0x00;
2314
- break;
2315
- case "REVERSE":
2316
- direction = 0x80;
2317
- break;
2318
- default:
2319
- throw new Error(`livolo_cover_options: ${value.motor_direction} is not a valid motor direction \
2320
- (must be one of 'FORWARD' or 'REVERSE')`);
2179
+ const groupid = utils.isGroup(entity) ? entity.groupID : 0;
2180
+ utils.assertNumber(value);
2181
+ const sceneid = value;
2182
+ await entity.command("genScenes", "recall", { groupid, sceneid, transitionTime: 0xffff }, utils.getOptions(meta.mapped, entity));
2183
+ const addColorMode = (newState) => {
2184
+ if (newState.color_temp !== undefined) {
2185
+ newState.color_mode = constants.colorModeLookup[2];
2186
+ }
2187
+ else if (newState.color !== undefined) {
2188
+ if (newState.color.x !== undefined) {
2189
+ newState.color_mode = constants.colorModeLookup[1];
2190
+ }
2191
+ else {
2192
+ newState.color_mode = constants.colorModeLookup[0];
2193
+ }
2321
2194
  }
2322
- const payload = { 4865: { value: [direction, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] } };
2323
- await entity.write("genPowerCfg",
2324
- // @ts-expect-error workaround write custom payload
2325
- payload, options);
2326
- }
2327
- if (value.motor_speed != null) {
2328
- if (value.motor_speed < 20 || value.motor_speed > 40) {
2329
- throw new Error("livolo_cover_options: Motor speed is out of range (20-40)");
2195
+ return newState;
2196
+ };
2197
+ if (utils.isGroup(entity)) {
2198
+ const membersState = {};
2199
+ for (const member of entity.members) {
2200
+ let recalledState = utils.getSceneState(member, sceneid, groupid);
2201
+ if (recalledState) {
2202
+ // add color_mode if saved state does not contain it
2203
+ if (recalledState.color_mode === undefined) {
2204
+ recalledState = addColorMode(recalledState);
2205
+ }
2206
+ Object.assign(recalledState, libColor.syncColorState(recalledState, meta.state, entity, meta.options));
2207
+ membersState[member.getDevice().ieeeAddr] = recalledState;
2208
+ }
2209
+ else {
2210
+ logger_1.logger.warning(`Unknown scene was recalled for ${member.getDevice().ieeeAddr}, can't restore state.`, NS);
2211
+ membersState[member.getDevice().ieeeAddr] = {};
2212
+ }
2330
2213
  }
2331
- const payload = { 4609: { value: [value.motor_speed, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00] } };
2332
- await entity.write("genPowerCfg",
2333
- // @ts-expect-error workaround write custom payload
2334
- payload, options);
2214
+ logger_1.logger.info("Successfully recalled group scene", NS);
2215
+ return { membersState };
2335
2216
  }
2336
- },
2337
- };
2338
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2339
- exports.ZigUP_lock = {
2340
- key: ["led"],
2341
- convertSet: async (entity, key, value, meta) => {
2342
- const lookup = { off: "lockDoor", on: "unlockDoor", toggle: "toggleDoor" };
2343
- await entity.command("closuresDoorLock", utils.getFromLookup(value, lookup), { pincodevalue: Buffer.alloc(0) });
2344
- },
2345
- };
2346
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2347
- exports.LS21001_alert_behaviour = {
2348
- key: ["alert_behaviour"],
2349
- convertSet: async (entity, key, value, meta) => {
2350
- const lookup = { siren_led: 3, siren: 2, led: 1, nothing: 0 };
2351
- await entity.write("genBasic", { 16394: { value: utils.getFromLookup(value, lookup), type: 32 } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.LEEDARSON_LIGHTING_CO_LTD, disableDefaultResponse: true });
2352
- return { state: { alert_behaviour: value } };
2353
- },
2354
- };
2355
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2356
- exports.STS_PRS_251_beep = {
2357
- key: ["beep"],
2358
- convertSet: async (entity, key, value, meta) => {
2359
- await entity.command("genIdentify", "identify", { identifytime: value }, utils.getOptions(meta.mapped, entity));
2360
- },
2361
- };
2362
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2363
- exports.SPZ01_power_outage_memory = {
2364
- key: ["power_outage_memory"],
2365
- convertSet: async (entity, key, value, meta) => {
2366
- await entity.write("genOnOff", { 8192: { value: value ? 0x01 : 0x00, type: 0x20 } });
2367
- return { state: { power_outage_memory: value } };
2368
- },
2369
- };
2370
- exports.tuya_relay_din_led_indicator = {
2371
- key: ["indicator_mode"],
2372
- convertSet: async (entity, key, value, meta) => {
2373
- utils.assertString(value, key);
2374
- value = value.toLowerCase();
2375
- const lookup = { off: 0x00, on_off: 0x01, off_on: 0x02 };
2376
- const payload = utils.getFromLookup(value, lookup);
2377
- await entity.write("genOnOff", { 32769: { value: payload, type: 0x30 } });
2378
- return { state: { indicator_mode: value } };
2379
- },
2380
- };
2381
- exports.kmpcil_res005_on_off = {
2382
- key: ["state"],
2383
- convertSet: async (entity, key, value, meta) => {
2384
- utils.assertString(value, key);
2385
- const options = { disableDefaultResponse: true };
2386
- value = value.toLowerCase();
2387
- utils.assertString(value, key);
2388
- utils.validateValue(value, ["toggle", "off", "on"]);
2389
- if (value === "toggle") {
2390
- if (meta.state.state === undefined) {
2391
- throw new Error("Cannot toggle, state not known yet");
2217
+ let recalledState = utils.getSceneState(entity, sceneid, groupid);
2218
+ if (recalledState) {
2219
+ // add color_mode if saved state does not contain it
2220
+ if (recalledState.color_mode === undefined) {
2221
+ recalledState = addColorMode(recalledState);
2392
2222
  }
2393
- const payload = { 85: { value: meta.state.state === "OFF" ? 0x01 : 0x00, type: 0x10 } };
2394
- await entity.write("genBinaryOutput", payload, options);
2395
- return { state: { state: meta.state.state === "OFF" ? "ON" : "OFF" } };
2223
+ Object.assign(recalledState, libColor.syncColorState(recalledState, meta.state, entity, meta.options));
2224
+ logger_1.logger.info("Successfully recalled scene", NS);
2225
+ return { state: recalledState };
2396
2226
  }
2397
- const payload = { 85: { value: value.toUpperCase() === "OFF" ? 0x00 : 0x01, type: 0x10 } };
2398
- await entity.write("genBinaryOutput", payload, options);
2399
- return { state: { state: value.toUpperCase() } };
2400
- },
2401
- convertGet: async (entity, key, meta) => {
2402
- await entity.read("genBinaryOutput", ["presentValue"]);
2403
- },
2404
- };
2405
- exports.hue_wall_switch_device_mode = {
2406
- key: ["device_mode"],
2407
- convertSet: async (entity, key, value, meta) => {
2408
- utils.assertString(value);
2409
- const values = ["single_rocker", "single_push_button", "dual_rocker", "dual_push_button"];
2410
- utils.validateValue(value, values);
2411
- await entity.write("genBasic", { 52: { value: values.indexOf(value), type: 48 } }, manufacturerOptions.hue);
2412
- },
2413
- convertGet: async (entity, key, meta) => {
2414
- await entity.read("genBasic", [0x0034], manufacturerOptions.hue);
2415
- },
2416
- };
2417
- exports.danfoss_thermostat_occupied_heating_setpoint = {
2418
- key: ["occupied_heating_setpoint"],
2419
- convertSet: async (entity, key, value, meta) => {
2420
- utils.assertNumber(value, key);
2421
- const payload = {
2422
- // 1: "User Interaction" Changes occupied heating setpoint and triggers an aggressive reaction
2423
- // of the actuator as soon as control SW runs, to replicate the behavior of turning the dial on the eTRV.
2424
- setpointType: 1,
2425
- setpoint: Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100,
2426
- };
2427
- await entity.command("hvacThermostat", "danfossSetpointCommand", payload, manufacturerOptions.danfoss);
2428
- },
2429
- convertGet: async (entity, key, meta) => {
2430
- await entity.read("hvacThermostat", ["occupiedHeatingSetpoint"]);
2431
- },
2432
- };
2433
- exports.danfoss_thermostat_occupied_heating_setpoint_scheduled = {
2434
- key: ["occupied_heating_setpoint_scheduled"],
2435
- convertSet: async (entity, key, value, meta) => {
2436
- utils.assertNumber(value, key);
2437
- const payload = {
2438
- // 0: "Schedule Change" Just changes occupied heating setpoint. No special behavior,
2439
- // the PID control setpoint will be update with the new setpoint.
2440
- setpointType: 0,
2441
- setpoint: Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100,
2442
- };
2443
- await entity.command("hvacThermostat", "danfossSetpointCommand", payload, manufacturerOptions.danfoss);
2444
- },
2445
- convertGet: async (entity, key, meta) => {
2446
- await entity.read("hvacThermostat", ["occupiedHeatingSetpoint"]);
2447
- },
2448
- };
2449
- exports.danfoss_mounted_mode_active = {
2450
- key: ["mounted_mode_active"],
2451
- convertGet: async (entity, key, meta) => {
2452
- await entity.read("hvacThermostat", ["danfossMountedModeActive"], manufacturerOptions.danfoss);
2453
- },
2454
- };
2455
- exports.danfoss_mounted_mode_control = {
2456
- key: ["mounted_mode_control"],
2457
- convertSet: async (entity, key, value, meta) => {
2458
- await entity.write("hvacThermostat", { danfossMountedModeControl: value }, manufacturerOptions.danfoss);
2459
- return { state: { mounted_mode_control: value } };
2460
- },
2461
- convertGet: async (entity, key, meta) => {
2462
- await entity.read("hvacThermostat", ["danfossMountedModeControl"], manufacturerOptions.danfoss);
2227
+ logger_1.logger.warning(`Unknown scene was recalled for ${entity.deviceIeeeAddress}, can't restore state.`, NS);
2228
+ return { state: {} };
2463
2229
  },
2464
2230
  };
2465
- exports.danfoss_thermostat_vertical_orientation = {
2466
- key: ["thermostat_vertical_orientation"],
2467
- convertSet: async (entity, key, value, meta) => {
2468
- await entity.write("hvacThermostat", { danfossThermostatOrientation: value }, manufacturerOptions.danfoss);
2469
- return { state: { thermostat_vertical_orientation: value } };
2470
- },
2471
- convertGet: async (entity, key, meta) => {
2472
- await entity.read("hvacThermostat", ["danfossThermostatOrientation"], manufacturerOptions.danfoss);
2473
- },
2474
- };
2475
- exports.danfoss_external_measured_room_sensor = {
2476
- key: ["external_measured_room_sensor"],
2477
- convertSet: async (entity, key, value, meta) => {
2478
- await entity.write("hvacThermostat", { danfossExternalMeasuredRoomSensor: value }, manufacturerOptions.danfoss);
2479
- return { state: { external_measured_room_sensor: value } };
2480
- },
2481
- convertGet: async (entity, key, meta) => {
2482
- await entity.read("hvacThermostat", ["danfossExternalMeasuredRoomSensor"], manufacturerOptions.danfoss);
2483
- },
2484
- };
2485
- exports.danfoss_radiator_covered = {
2486
- key: ["radiator_covered"],
2487
- convertSet: async (entity, key, value, meta) => {
2488
- await entity.write("hvacThermostat", { danfossRadiatorCovered: value }, manufacturerOptions.danfoss);
2489
- return { state: { radiator_covered: value } };
2490
- },
2491
- convertGet: async (entity, key, meta) => {
2492
- await entity.read("hvacThermostat", ["danfossRadiatorCovered"], manufacturerOptions.danfoss);
2493
- },
2494
- };
2495
- exports.danfoss_viewing_direction = {
2496
- key: ["viewing_direction"],
2497
- convertSet: async (entity, key, value, meta) => {
2498
- await entity.write("hvacUserInterfaceCfg", { danfossViewingDirection: value }, manufacturerOptions.danfoss);
2499
- return { state: { viewing_direction: value } };
2500
- },
2501
- convertGet: async (entity, key, meta) => {
2502
- await entity.read("hvacUserInterfaceCfg", ["danfossViewingDirection"], manufacturerOptions.danfoss);
2503
- },
2504
- };
2505
- exports.danfoss_algorithm_scale_factor = {
2506
- key: ["algorithm_scale_factor"],
2507
- convertSet: async (entity, key, value, meta) => {
2508
- await entity.write("hvacThermostat", { danfossAlgorithmScaleFactor: value }, manufacturerOptions.danfoss);
2509
- return { state: { algorithm_scale_factor: value } };
2510
- },
2511
- convertGet: async (entity, key, meta) => {
2512
- await entity.read("hvacThermostat", ["danfossAlgorithmScaleFactor"], manufacturerOptions.danfoss);
2513
- },
2514
- };
2515
- exports.danfoss_heat_available = {
2516
- key: ["heat_available"],
2517
- convertSet: async (entity, key, value, meta) => {
2518
- await entity.write("hvacThermostat", { danfossHeatAvailable: value }, manufacturerOptions.danfoss);
2519
- return { state: { heat_available: value } };
2520
- },
2521
- convertGet: async (entity, key, meta) => {
2522
- await entity.read("hvacThermostat", ["danfossHeatAvailable"], manufacturerOptions.danfoss);
2523
- },
2524
- };
2525
- exports.danfoss_heat_required = {
2526
- key: ["heat_required"],
2527
- convertGet: async (entity, key, meta) => {
2528
- await entity.read("hvacThermostat", ["danfossHeatRequired"], manufacturerOptions.danfoss);
2529
- },
2530
- };
2531
- exports.danfoss_day_of_week = {
2532
- key: ["day_of_week"],
2533
- convertSet: async (entity, key, value, meta) => {
2534
- const payload = { danfossDayOfWeek: utils.getKey(constants.thermostatDayOfWeek, value, undefined, Number) };
2535
- await entity.write("hvacThermostat", payload, manufacturerOptions.danfoss);
2536
- return { state: { day_of_week: value } };
2537
- },
2538
- convertGet: async (entity, key, meta) => {
2539
- await entity.read("hvacThermostat", ["danfossDayOfWeek"], manufacturerOptions.danfoss);
2540
- },
2541
- };
2542
- exports.danfoss_trigger_time = {
2543
- key: ["trigger_time"],
2544
- convertSet: async (entity, key, value, meta) => {
2545
- await entity.write("hvacThermostat", { danfossTriggerTime: value }, manufacturerOptions.danfoss);
2546
- return { state: { trigger_time: value } };
2547
- },
2548
- convertGet: async (entity, key, meta) => {
2549
- await entity.read("hvacThermostat", ["danfossTriggerTime"], manufacturerOptions.danfoss);
2550
- },
2551
- };
2552
- exports.danfoss_window_open_feature = {
2553
- key: ["window_open_feature"],
2554
- convertSet: async (entity, key, value, meta) => {
2555
- await entity.write("hvacThermostat", { danfossWindowOpenFeatureEnable: value }, manufacturerOptions.danfoss);
2556
- return { state: { window_open_feature: value } };
2557
- },
2558
- convertGet: async (entity, key, meta) => {
2559
- await entity.read("hvacThermostat", ["danfossWindowOpenFeatureEnable"], manufacturerOptions.danfoss);
2560
- },
2561
- };
2562
- exports.danfoss_window_open_internal = {
2563
- key: ["window_open_internal"],
2564
- convertGet: async (entity, key, meta) => {
2565
- await entity.read("hvacThermostat", ["danfossWindowOpenInternal"], manufacturerOptions.danfoss);
2566
- },
2567
- };
2568
- exports.danfoss_window_open_external = {
2569
- key: ["window_open_external"],
2570
- convertSet: async (entity, key, value, meta) => {
2571
- await entity.write("hvacThermostat", { danfossWindowOpenExternal: value }, manufacturerOptions.danfoss);
2572
- return { state: { window_open_external: value } };
2573
- },
2574
- convertGet: async (entity, key, meta) => {
2575
- await entity.read("hvacThermostat", ["danfossWindowOpenExternal"], manufacturerOptions.danfoss);
2576
- },
2577
- };
2578
- exports.danfoss_load_balancing_enable = {
2579
- key: ["load_balancing_enable"],
2580
- convertSet: async (entity, key, value, meta) => {
2581
- await entity.write("hvacThermostat", { danfossLoadBalancingEnable: value }, manufacturerOptions.danfoss);
2582
- return { state: { load_balancing_enable: value } };
2583
- },
2584
- convertGet: async (entity, key, meta) => {
2585
- await entity.read("hvacThermostat", ["danfossLoadBalancingEnable"], manufacturerOptions.danfoss);
2586
- },
2587
- };
2588
- exports.danfoss_load_room_mean = {
2589
- key: ["load_room_mean"],
2590
- convertSet: async (entity, key, value, meta) => {
2591
- await entity.write("hvacThermostat", { danfossLoadRoomMean: value }, manufacturerOptions.danfoss);
2592
- return { state: { load_room_mean: value } };
2593
- },
2594
- convertGet: async (entity, key, meta) => {
2595
- await entity.read("hvacThermostat", ["danfossLoadRoomMean"], manufacturerOptions.danfoss);
2596
- },
2597
- };
2598
- exports.danfoss_load_estimate = {
2599
- key: ["load_estimate"],
2600
- convertGet: async (entity, key, meta) => {
2601
- await entity.read("hvacThermostat", ["danfossLoadEstimate"], manufacturerOptions.danfoss);
2602
- },
2603
- };
2604
- exports.danfoss_preheat_status = {
2605
- key: ["preheat_status"],
2606
- convertGet: async (entity, key, meta) => {
2607
- await entity.read("hvacThermostat", ["danfossPreheatStatus"], manufacturerOptions.danfoss);
2608
- },
2609
- };
2610
- exports.danfoss_adaptation_status = {
2611
- key: ["adaptation_run_status"],
2612
- convertGet: async (entity, key, meta) => {
2613
- await entity.read("hvacThermostat", ["danfossAdaptionRunStatus"], manufacturerOptions.danfoss);
2614
- },
2615
- };
2616
- exports.danfoss_adaptation_settings = {
2617
- key: ["adaptation_run_settings"],
2618
- convertSet: async (entity, key, value, meta) => {
2619
- await entity.write("hvacThermostat", { danfossAdaptionRunSettings: value }, manufacturerOptions.danfoss);
2620
- return { state: { adaptation_run_settings: value } };
2621
- },
2622
- convertGet: async (entity, key, meta) => {
2623
- await entity.read("hvacThermostat", ["danfossAdaptionRunSettings"], manufacturerOptions.danfoss);
2624
- },
2625
- };
2626
- exports.danfoss_adaptation_control = {
2627
- key: ["adaptation_run_control"],
2628
- convertSet: async (entity, key, value, meta) => {
2629
- await entity.write("hvacThermostat", { danfossAdaptionRunControl: utils.getKey(constants.danfossAdaptionRunControl, value, value, Number) }, manufacturerOptions.danfoss);
2630
- return { state: { adaptation_run_control: value } };
2631
- },
2632
- convertGet: async (entity, key, meta) => {
2633
- await entity.read("hvacThermostat", ["danfossAdaptionRunControl"], manufacturerOptions.danfoss);
2634
- },
2635
- };
2636
- exports.danfoss_regulation_setpoint_offset = {
2637
- key: ["regulation_setpoint_offset"],
2638
- convertSet: async (entity, key, value, meta) => {
2639
- await entity.write("hvacThermostat", { danfossRegulationSetpointOffset: value }, manufacturerOptions.danfoss);
2640
- return { state: { regulation_setpoint_offset: value } };
2641
- },
2642
- convertGet: async (entity, key, meta) => {
2643
- await entity.read("hvacThermostat", ["danfossRegulationSetpointOffset"], manufacturerOptions.danfoss);
2644
- },
2645
- };
2646
- exports.danfoss_output_status = {
2647
- key: ["output_status"],
2648
- convertGet: async (entity, key, meta) => {
2649
- await entity.read("hvacThermostat", ["danfossOutputStatus"], manufacturerOptions.danfoss);
2650
- },
2651
- };
2652
- exports.danfoss_room_status_code = {
2653
- key: ["room_status_code"],
2654
- convertGet: async (entity, key, meta) => {
2655
- await entity.read("hvacThermostat", ["danfossRoomStatusCode"], manufacturerOptions.danfoss);
2656
- },
2657
- };
2658
- exports.danfoss_floor_sensor_mode = {
2659
- key: ["room_floor_sensor_mode"],
2660
- convertGet: async (entity, key, meta) => {
2661
- await entity.read("hvacThermostat", ["danfossRoomFloorSensorMode"], manufacturerOptions.danfoss);
2662
- },
2663
- };
2664
- exports.danfoss_floor_min_setpoint = {
2665
- key: ["floor_min_setpoint"],
2666
- convertSet: async (entity, key, value, meta) => {
2667
- utils.assertNumber(value, key);
2668
- const danfossFloorMinSetpoint = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
2669
- await entity.write("hvacThermostat", { danfossFloorMinSetpoint }, manufacturerOptions.danfoss);
2670
- return { state: { floor_min_setpoint: value } };
2671
- },
2672
- convertGet: async (entity, key, meta) => {
2673
- await entity.read("hvacThermostat", ["danfossFloorMinSetpoint"], manufacturerOptions.danfoss);
2674
- },
2675
- };
2676
- exports.danfoss_floor_max_setpoint = {
2677
- key: ["floor_max_setpoint"],
2678
- convertSet: async (entity, key, value, meta) => {
2679
- utils.assertNumber(value, key);
2680
- const danfossFloorMaxSetpoint = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
2681
- await entity.write("hvacThermostat", { danfossFloorMaxSetpoint }, manufacturerOptions.danfoss);
2682
- return { state: { floor_max_setpoint: value } };
2683
- },
2684
- convertGet: async (entity, key, meta) => {
2685
- await entity.read("hvacThermostat", ["danfossFloorMaxSetpoint"], manufacturerOptions.danfoss);
2686
- },
2687
- };
2688
- exports.danfoss_schedule_type_used = {
2689
- key: ["schedule_type_used"],
2690
- convertGet: async (entity, key, meta) => {
2691
- await entity.read("hvacThermostat", ["danfossScheduleTypeUsed"], manufacturerOptions.danfoss);
2692
- },
2693
- };
2694
- exports.danfoss_icon2_pre_heat = {
2695
- key: ["icon2_pre_heat"],
2696
- convertGet: async (entity, key, meta) => {
2697
- await entity.read("hvacThermostat", ["danfossIcon2PreHeat"], manufacturerOptions.danfoss);
2698
- },
2699
- };
2700
- exports.danfoss_icon2_pre_heat_status = {
2701
- key: ["icon2_pre_heat_status"],
2702
- convertGet: async (entity, key, meta) => {
2703
- await entity.read("hvacThermostat", ["danfossIcon2PreHeatStatus"], manufacturerOptions.danfoss);
2704
- },
2705
- };
2706
- exports.danfoss_system_status_code = {
2707
- key: ["system_status_code"],
2708
- convertGet: async (entity, key, meta) => {
2709
- await entity.read("haDiagnostic", ["danfossSystemStatusCode"], manufacturerOptions.danfoss);
2710
- },
2711
- };
2712
- exports.danfoss_heat_supply_request = {
2713
- key: ["heat_supply_request"],
2714
- convertGet: async (entity, key, meta) => {
2715
- await entity.read("haDiagnostic", ["danfossHeatSupplyRequest"], manufacturerOptions.danfoss);
2716
- },
2717
- };
2718
- exports.danfoss_system_status_water = {
2719
- key: ["system_status_water"],
2720
- convertGet: async (entity, key, meta) => {
2721
- await entity.read("haDiagnostic", ["danfossSystemStatusWater"], manufacturerOptions.danfoss);
2722
- },
2723
- };
2724
- exports.danfoss_multimaster_role = {
2725
- key: ["multimaster_role"],
2726
- convertGet: async (entity, key, meta) => {
2727
- await entity.read("haDiagnostic", ["danfossMultimasterRole"], manufacturerOptions.danfoss);
2728
- },
2729
- };
2730
- exports.danfoss_icon_application = {
2731
- key: ["icon_application"],
2732
- convertGet: async (entity, key, meta) => {
2733
- await entity.read("haDiagnostic", ["danfossIconApplication"], manufacturerOptions.danfoss);
2734
- },
2735
- };
2736
- exports.danfoss_icon_forced_heating_cooling = {
2737
- key: ["icon_forced_heating_cooling"],
2738
- convertGet: async (entity, key, meta) => {
2739
- await entity.read("haDiagnostic", ["danfossIconForcedHeatingCooling"], manufacturerOptions.danfoss);
2740
- },
2741
- };
2742
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2743
- exports.ZMCSW032D_cover_position = {
2744
- key: ["position", "tilt"],
2745
- convertSet: async (entity, key, value, meta) => {
2746
- utils.assertNumber(value, key);
2747
- if (meta.options.time_close != null && meta.options.time_open != null) {
2748
- const sleepSeconds = async (s) => {
2749
- return await new Promise((resolve) => setTimeout(resolve, s * 1000));
2750
- };
2751
- const oldPosition = meta.state.position;
2752
- if (value === 100) {
2753
- await entity.command("closuresWindowCovering", "upOpen", {}, utils.getOptions(meta.mapped, entity));
2754
- }
2755
- else if (value === 0) {
2756
- await entity.command("closuresWindowCovering", "downClose", {}, utils.getOptions(meta.mapped, entity));
2757
- }
2758
- else {
2759
- if (utils.isNumber(oldPosition) && oldPosition > value) {
2760
- const delta = oldPosition - value;
2761
- utils.assertNumber(meta.options.time_open);
2762
- const mutiplicateur = meta.options.time_open / 100;
2763
- const timeBeforeStop = delta * mutiplicateur;
2764
- await entity.command("closuresWindowCovering", "downClose", {}, utils.getOptions(meta.mapped, entity));
2765
- await sleepSeconds(timeBeforeStop);
2766
- await entity.command("closuresWindowCovering", "stop", {}, utils.getOptions(meta.mapped, entity));
2767
- }
2768
- else if (utils.isNumber(oldPosition) && oldPosition < value) {
2769
- const delta = value - oldPosition;
2770
- utils.assertNumber(meta.options.time_close);
2771
- const mutiplicateur = meta.options.time_close / 100;
2772
- const timeBeforeStop = delta * mutiplicateur;
2773
- await entity.command("closuresWindowCovering", "upOpen", {}, utils.getOptions(meta.mapped, entity));
2774
- await sleepSeconds(timeBeforeStop);
2775
- await entity.command("closuresWindowCovering", "stop", {}, utils.getOptions(meta.mapped, entity));
2776
- }
2777
- }
2778
- return { state: { position: value } };
2779
- }
2780
- },
2781
- convertGet: async (entity, key, meta) => {
2782
- const isPosition = key === "position";
2783
- await entity.read("closuresWindowCovering", [isPosition ? "currentPositionLiftPercentage" : "currentPositionTiltPercentage"]);
2784
- },
2785
- };
2786
- exports.namron_thermostat = {
2787
- key: [
2788
- "lcd_brightness",
2789
- "button_vibration_level",
2790
- "floor_sensor_type",
2791
- "sensor",
2792
- "powerup_status",
2793
- "floor_sensor_calibration",
2794
- "dry_time",
2795
- "mode_after_dry",
2796
- "temperature_display",
2797
- "window_open_check",
2798
- "hysterersis",
2799
- "display_auto_off_enabled",
2800
- "alarm_airtemp_overvalue",
2801
- "away_mode",
2802
- ],
2803
- convertSet: async (entity, key, value, meta) => {
2804
- if (key === "lcd_brightness") {
2805
- const lookup = { low: 0, mid: 1, high: 2 };
2806
- const payload = { 4096: { value: utils.getFromLookup(value, lookup), type: zigbee_herdsman_1.Zcl.DataType.ENUM8 } };
2807
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2808
- }
2809
- else if (key === "button_vibration_level") {
2810
- const lookup = { off: 0, low: 1, high: 2 };
2811
- const payload = { 4097: { value: utils.getFromLookup(value, lookup), type: zigbee_herdsman_1.Zcl.DataType.ENUM8 } };
2812
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2813
- }
2814
- else if (key === "floor_sensor_type") {
2815
- const lookup = { "10k": 1, "15k": 2, "50k": 3, "100k": 4, "12k": 5 };
2816
- const payload = { 4098: { value: utils.getFromLookup(value, lookup), type: zigbee_herdsman_1.Zcl.DataType.ENUM8 } };
2817
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2818
- }
2819
- else if (key === "sensor") {
2820
- const lookup = { air: 0, floor: 1, both: 2 };
2821
- const payload = { 4099: { value: utils.getFromLookup(value, lookup), type: zigbee_herdsman_1.Zcl.DataType.ENUM8 } };
2822
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2823
- }
2824
- else if (key === "powerup_status") {
2825
- const lookup = { default: 0, last_status: 1 };
2826
- const payload = { 4100: { value: utils.getFromLookup(value, lookup), type: zigbee_herdsman_1.Zcl.DataType.ENUM8 } };
2827
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2828
- }
2829
- else if (key === "floor_sensor_calibration") {
2830
- utils.assertNumber(value);
2831
- const payload = { 4101: { value: Math.round(value * 10), type: 0x28 } }; // INT8S
2832
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2833
- }
2834
- else if (key === "dry_time") {
2835
- const payload = { 4102: { value: value, type: 0x20 } }; // INT8U
2836
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2837
- }
2838
- else if (key === "mode_after_dry") {
2839
- const lookup = { off: 0, manual: 1, auto: 2, away: 3 };
2840
- const payload = { 4103: { value: utils.getFromLookup(value, lookup), type: zigbee_herdsman_1.Zcl.DataType.ENUM8 } };
2841
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2842
- }
2843
- else if (key === "temperature_display") {
2844
- const lookup = { room: 0, floor: 1 };
2845
- const payload = { 4104: { value: utils.getFromLookup(value, lookup), type: zigbee_herdsman_1.Zcl.DataType.ENUM8 } };
2846
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2847
- }
2848
- else if (key === "window_open_check") {
2849
- utils.assertNumber(value);
2850
- const payload = { 4105: { value: value * 2, type: 0x20 } };
2851
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2852
- }
2853
- else if (key === "hysterersis") {
2854
- utils.assertNumber(value);
2855
- const payload = { 4106: { value: value * 10, type: 0x20 } };
2856
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2857
- }
2858
- else if (key === "display_auto_off_enabled") {
2859
- const lookup = { disabled: 0, enabled: 1 };
2860
- const payload = { 4107: { value: utils.getFromLookup(value, lookup), type: zigbee_herdsman_1.Zcl.DataType.ENUM8 } };
2861
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2862
- }
2863
- else if (key === "alarm_airtemp_overvalue") {
2864
- const payload = { 8193: { value: value, type: 0x20 } };
2865
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2866
- }
2867
- else if (key === "away_mode") {
2868
- const payload = { 8194: { value: Number(value === "ON"), type: 0x30 } };
2869
- await entity.write("hvacThermostat", payload, manufacturerOptions.sunricher);
2870
- }
2871
- },
2872
- convertGet: async (entity, key, meta) => {
2873
- switch (key) {
2874
- case "lcd_brightness":
2875
- await entity.read("hvacThermostat", [0x1000], manufacturerOptions.sunricher);
2876
- break;
2877
- case "button_vibration_level":
2878
- await entity.read("hvacThermostat", [0x1001], manufacturerOptions.sunricher);
2879
- break;
2880
- case "floor_sensor_type":
2881
- await entity.read("hvacThermostat", [0x1002], manufacturerOptions.sunricher);
2882
- break;
2883
- case "sensor":
2884
- await entity.read("hvacThermostat", [0x1003], manufacturerOptions.sunricher);
2885
- break;
2886
- case "powerup_status":
2887
- await entity.read("hvacThermostat", [0x1004], manufacturerOptions.sunricher);
2888
- break;
2889
- case "floor_sensor_calibration":
2890
- await entity.read("hvacThermostat", [0x1005], manufacturerOptions.sunricher);
2891
- break;
2892
- case "dry_time":
2893
- await entity.read("hvacThermostat", [0x1006], manufacturerOptions.sunricher);
2894
- break;
2895
- case "mode_after_dry":
2896
- await entity.read("hvacThermostat", [0x1007], manufacturerOptions.sunricher);
2897
- break;
2898
- case "temperature_display":
2899
- await entity.read("hvacThermostat", [0x1008], manufacturerOptions.sunricher);
2900
- break;
2901
- case "window_open_check":
2902
- await entity.read("hvacThermostat", [0x1009], manufacturerOptions.sunricher);
2903
- break;
2904
- case "hysterersis":
2905
- await entity.read("hvacThermostat", [0x100a], manufacturerOptions.sunricher);
2906
- break;
2907
- case "display_auto_off_enabled":
2908
- await entity.read("hvacThermostat", [0x100b], manufacturerOptions.sunricher);
2909
- break;
2910
- case "alarm_airtemp_overvalue":
2911
- await entity.read("hvacThermostat", [0x2001], manufacturerOptions.sunricher);
2912
- break;
2913
- case "away_mode":
2914
- await entity.read("hvacThermostat", [0x2002], manufacturerOptions.sunricher);
2915
- break;
2916
- default: // Unknown key
2917
- throw new Error(`Unhandled key toZigbee.namron_thermostat.convertGet ${key}`);
2918
- }
2919
- },
2920
- };
2921
- exports.namron_thermostat_child_lock = {
2922
- key: ["child_lock"],
2923
- convertSet: async (entity, key, value, meta) => {
2924
- const keypadLockout = Number(value === "LOCK");
2925
- await entity.write("hvacUserInterfaceCfg", { keypadLockout });
2926
- return { state: { child_lock: value } };
2927
- },
2928
- convertGet: async (entity, key, meta) => {
2929
- await entity.read("hvacUserInterfaceCfg", ["keypadLockout"]);
2930
- },
2931
- };
2932
- exports.easycode_auto_relock = {
2933
- key: ["auto_relock"],
2934
- convertSet: async (entity, key, value, meta) => {
2935
- await entity.write("closuresDoorLock", { autoRelockTime: value ? 1 : 0 }, utils.getOptions(meta.mapped, entity));
2936
- return { state: { auto_relock: value } };
2937
- },
2938
- };
2939
- exports.tuya_led_control = {
2940
- key: ["brightness", "color", "color_temp"],
2941
- options: [exposes.options.color_sync()],
2942
- convertSet: async (entity, key, value, meta) => {
2943
- if (key === "brightness" &&
2944
- meta.state.color_mode === constants.colorModeLookup[2] &&
2945
- meta.message.color == null &&
2946
- meta.message.color_temp == null) {
2947
- const level = Number(value);
2948
- await entity.command("genLevelCtrl", "moveToLevel", { level, transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
2949
- globalStore.putValue(entity, "brightness", level);
2950
- return { state: { brightness: level } };
2951
- }
2952
- if (key === "brightness" && utils.isNumber(meta.message.color_temp)) {
2953
- const level = Number(value);
2954
- await entity.command("lightingColorCtrl", "tuyaRgbMode", { enable: 0 });
2955
- await entity.command("lightingColorCtrl", "moveToColorTemp", {
2956
- colortemp: utils.mapNumberRange(meta.message.color_temp, 500, 154, 0, 254),
2957
- transtime: 0,
2958
- optionsMask: 0,
2959
- optionsOverride: 0,
2960
- }, utils.getOptions(meta.mapped, entity));
2961
- await entity.command("genLevelCtrl", "moveToLevel", { level, transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
2962
- globalStore.putValue(entity, "brightness", level);
2963
- const newState = {
2964
- brightness: level,
2965
- color_mode: constants.colorModeLookup[2],
2966
- color_temp: meta.message.color_temp,
2967
- };
2968
- return { state: libColor.syncColorState(newState, meta.state, entity, meta.options) };
2969
- }
2970
- if (key === "color_temp") {
2971
- utils.assertNumber(value, key);
2972
- const level = globalStore.getValue(entity, "brightness") || 100;
2973
- await entity.command("lightingColorCtrl", "tuyaRgbMode", { enable: 0 });
2974
- await entity.command("lightingColorCtrl", "moveToColorTemp", { colortemp: utils.mapNumberRange(value, 500, 154, 0, 254), transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
2975
- await entity.command("genLevelCtrl", "moveToLevel", { level, transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
2976
- const newState = {
2977
- brightness: level,
2978
- color_mode: constants.colorModeLookup[2],
2979
- color_temp: value,
2980
- };
2981
- return { state: libColor.syncColorState(newState, meta.state, entity, meta.options) };
2982
- }
2983
- const zclData = {
2984
- brightness: globalStore.getValue(entity, "brightness") || 100,
2985
- // @ts-expect-error ignore
2986
- hue: utils.mapNumberRange(meta.state.color.h, 0, 360, 0, 254) || 100,
2987
- // @ts-expect-error ignore
2988
- saturation: utils.mapNumberRange(meta.state.color.s, 0, 100, 0, 254) || 100,
2989
- transtime: 0,
2990
- };
2991
- if (utils.isObject(value)) {
2992
- if (value.h) {
2993
- zclData.hue = utils.mapNumberRange(value.h, 0, 360, 0, 254);
2994
- }
2995
- if (value.hue) {
2996
- zclData.hue = utils.mapNumberRange(value.hue, 0, 360, 0, 254);
2997
- }
2998
- if (value.s) {
2999
- zclData.saturation = utils.mapNumberRange(value.s, 0, 100, 0, 254);
3000
- }
3001
- if (value.saturation) {
3002
- zclData.saturation = utils.mapNumberRange(value.saturation, 0, 100, 0, 254);
3003
- }
3004
- if (value.b) {
3005
- zclData.brightness = Number(value.b);
3006
- }
3007
- if (value.brightness) {
3008
- zclData.brightness = Number(value.brightness);
3009
- }
3010
- if (typeof value === "number") {
3011
- zclData.brightness = value;
3012
- }
3013
- }
3014
- if (meta.message.color != null) {
3015
- if (utils.isObject(meta.message.color)) {
3016
- if (meta.message.color.h) {
3017
- zclData.hue = utils.mapNumberRange(meta.message.color.h, 0, 360, 0, 254);
3018
- }
3019
- if (meta.message.color.s) {
3020
- zclData.saturation = utils.mapNumberRange(meta.message.color.s, 0, 100, 0, 254);
3021
- }
3022
- if (meta.message.color.b) {
3023
- zclData.brightness = Number(meta.message.color.b);
3024
- }
3025
- if (meta.message.color.brightness) {
3026
- zclData.brightness = Number(meta.message.color.brightness);
3027
- }
3028
- }
3029
- }
3030
- await entity.command("lightingColorCtrl", "tuyaRgbMode", { enable: 1 });
3031
- await entity.command("lightingColorCtrl", "tuyaMoveToHueAndSaturationBrightness", zclData, utils.getOptions(meta.mapped, entity));
3032
- globalStore.putValue(entity, "brightness", zclData.brightness);
3033
- const newState = {
3034
- brightness: zclData.brightness,
3035
- color: {
3036
- h: utils.mapNumberRange(zclData.hue, 0, 254, 0, 360),
3037
- hue: utils.mapNumberRange(zclData.hue, 0, 254, 0, 360),
3038
- s: utils.mapNumberRange(zclData.saturation, 0, 254, 0, 100),
3039
- saturation: utils.mapNumberRange(zclData.saturation, 0, 254, 0, 100),
3040
- },
3041
- color_mode: constants.colorModeLookup[0],
3042
- };
3043
- return { state: libColor.syncColorState(newState, meta.state, entity, meta.options) };
3044
- },
3045
- convertGet: async (entity, key, meta) => {
3046
- await entity.read("lightingColorCtrl", ["currentHue", "currentSaturation", "tuyaBrightness", "tuyaRgbMode", "colorTemperature"]);
3047
- },
3048
- };
3049
- exports.tuya_led_controller = {
3050
- key: ["state", "color"],
3051
- convertSet: async (entity, key, value, meta) => {
3052
- if (key === "state") {
3053
- utils.assertString(value, key);
3054
- if (value.toLowerCase() === "off") {
3055
- await entity.command("genOnOff", "offWithEffect", { effectid: 0x01, effectvariant: 0x01 }, utils.getOptions(meta.mapped, entity));
3056
- }
3057
- else {
3058
- await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: 255, transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
3059
- }
3060
- return { state: { state: value.toUpperCase() } };
3061
- }
3062
- if (key === "color") {
3063
- utils.assertObject(value);
3064
- const hue = utils.mapNumberRange(value.h, 0, 360, 0, 254);
3065
- const saturation = utils.mapNumberRange(value.s, 0, 100, 0, 254);
3066
- const transtime = 0;
3067
- const direction = 0;
3068
- await entity.command("lightingColorCtrl", "moveToHue", { hue, transtime, direction, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
3069
- await entity.command("lightingColorCtrl", "moveToSaturation", { saturation, transtime, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
3070
- }
3071
- },
3072
- convertGet: async (entity, key, meta) => {
3073
- if (key === "state") {
3074
- await entity.read("genOnOff", ["onOff"]);
3075
- }
3076
- else if (key === "color") {
3077
- await entity.read("lightingColorCtrl", ["currentHue", "currentSaturation"]);
3078
- }
3079
- },
3080
- };
3081
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3082
- exports.EMIZB_132_mode = {
3083
- key: ["interface_mode"],
3084
- convertSet: async (entity, key, value, meta) => {
3085
- const endpoint = meta.device.getEndpoint(2);
3086
- const lookup = {
3087
- norwegian_han: { value: 0x0200, acVoltageDivisor: 10, acCurrentDivisor: 10 },
3088
- norwegian_han_extra_load: { value: 0x0201, acVoltageDivisor: 10, acCurrentDivisor: 10 },
3089
- aidon_meter: { value: 0x0202, acVoltageDivisor: 10, acCurrentDivisor: 10 },
3090
- kaifa_and_kamstrup: { value: 0x0203, acVoltageDivisor: 10, acCurrentDivisor: 1000 },
3091
- };
3092
- await endpoint.write("seMetering", { 770: { value: utils.getFromLookup(value, lookup).value, type: 49 } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DEVELCO });
3093
- // As the device reports the incorrect divisor, we need to set it here
3094
- // https://github.com/Koenkk/zigbee-herdsman-converters/issues/974#issuecomment-604347303
3095
- // Values for norwegian_han and aidon_meter have not been been checked
3096
- endpoint.saveClusterAttributeKeyValue("haElectricalMeasurement", {
3097
- acVoltageMultiplier: 1,
3098
- acVoltageDivisor: utils.getFromLookup(value, lookup).acVoltageDivisor,
3099
- acCurrentMultiplier: 1,
3100
- acCurrentDivisor: utils.getFromLookup(value, lookup).acCurrentDivisor,
3101
- });
3102
- return { state: { interface_mode: value } };
3103
- },
3104
- };
3105
- exports.eurotronic_host_flags = {
3106
- key: ["eurotronic_host_flags", "system_mode"],
3107
- convertSet: async (entity, key, value, meta) => {
3108
- const origValue = value;
3109
- await entity.read("hvacThermostat", [0x4008], manufacturerOptions.eurotronic);
3110
- // calculate bit value
3111
- let bitValue = 0x01; // bit 0 always 1
3112
- if (meta.state.mirror_display === "ON") {
3113
- bitValue |= 0x02;
3114
- }
3115
- if (value === constants.thermostatSystemModes[0]) {
3116
- // off
3117
- bitValue |= 0x20;
3118
- }
3119
- else if (value === constants.thermostatSystemModes[4]) {
3120
- // "heat"
3121
- bitValue |= 0x04;
3122
- }
3123
- else {
3124
- // auto
3125
- bitValue |= 0x10;
3126
- }
3127
- if (meta.state.child_lock === "LOCK") {
3128
- bitValue |= 0x80;
3129
- }
3130
- value = bitValue;
3131
- const payload = { 16392: { value, type: 0x22 } };
3132
- await entity.write("hvacThermostat", payload, manufacturerOptions.eurotronic);
3133
- return { state: { [key]: origValue } };
3134
- },
3135
- convertGet: async (entity, key, meta) => {
3136
- await entity.read("hvacThermostat", [0x4008], manufacturerOptions.eurotronic);
3137
- },
3138
- };
3139
- exports.eurotronic_error_status = {
3140
- key: ["eurotronic_error_status"],
3141
- convertGet: async (entity, key, meta) => {
3142
- await entity.read("hvacThermostat", [0x4002], manufacturerOptions.eurotronic);
3143
- },
3144
- };
3145
- exports.eurotronic_current_heating_setpoint = {
3146
- key: ["current_heating_setpoint"],
3147
- convertSet: async (entity, key, value, meta) => {
3148
- utils.assertNumber(value, key);
3149
- const val = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
3150
- const payload = { 16387: { value: val, type: 0x29 } };
3151
- await entity.write("hvacThermostat", payload, manufacturerOptions.eurotronic);
3152
- },
3153
- convertGet: async (entity, key, meta) => {
3154
- await entity.read("hvacThermostat", [0x4003], manufacturerOptions.eurotronic);
3155
- },
3156
- };
3157
- exports.eurotronic_valve_position = {
3158
- key: ["eurotronic_valve_position", "valve_position"],
3159
- convertSet: async (entity, key, value, meta) => {
3160
- const payload = { 16385: { value, type: 0x20 } };
3161
- await entity.write("hvacThermostat", payload, manufacturerOptions.eurotronic);
3162
- return { state: { [key]: value } };
3163
- },
3164
- convertGet: async (entity, key, meta) => {
3165
- await entity.read("hvacThermostat", [0x4001], manufacturerOptions.eurotronic);
3166
- },
3167
- };
3168
- exports.eurotronic_trv_mode = {
3169
- key: ["eurotronic_trv_mode", "trv_mode"],
3170
- convertSet: async (entity, key, value, meta) => {
3171
- const payload = { 16384: { value, type: 0x30 } };
3172
- await entity.write("hvacThermostat", payload, manufacturerOptions.eurotronic);
3173
- return { state: { [key]: value } };
3174
- },
3175
- convertGet: async (entity, key, meta) => {
3176
- await entity.read("hvacThermostat", [0x4000], manufacturerOptions.eurotronic);
3177
- },
3178
- };
3179
- exports.eurotronic_child_lock = {
3180
- key: ["eurotronic_child_lock", "child_lock"],
3181
- convertSet: async (entity, key, value, meta) => {
3182
- await entity.read("hvacThermostat", [0x4008], manufacturerOptions.eurotronic);
3183
- // calculate bit value
3184
- let bitValue = 0x01; // bit 0 always 1
3185
- if (meta.state.mirror_display === "ON") {
3186
- bitValue |= 0x02;
3187
- }
3188
- if (meta.state.system_mode === constants.thermostatSystemModes[0]) {
3189
- // off
3190
- bitValue |= 0x20;
3191
- }
3192
- else if (meta.state.system_mode === constants.thermostatSystemModes[4]) {
3193
- // "heat"
3194
- bitValue |= 0x04;
3195
- }
3196
- else {
3197
- // auto
3198
- bitValue |= 0x10;
3199
- }
3200
- if (value === "LOCK") {
3201
- bitValue |= 0x80;
3202
- }
3203
- const origValue = value;
3204
- value = bitValue;
3205
- const payload = { 16392: { value, type: 0x22 } };
3206
- await entity.write("hvacThermostat", payload, manufacturerOptions.eurotronic);
3207
- return { state: { [key]: origValue } };
3208
- },
3209
- };
3210
- exports.eurotronic_mirror_display = {
3211
- key: ["eurotronic_mirror_display", "mirror_display"],
3212
- convertSet: async (entity, key, value, meta) => {
3213
- await entity.read("hvacThermostat", [0x4008], manufacturerOptions.eurotronic);
3214
- // calculate bit value
3215
- let bitValue = 0x01; // bit 0 always 1
3216
- if (value === "ON") {
3217
- bitValue |= 0x02;
3218
- }
3219
- if (meta.state.system_mode === constants.thermostatSystemModes[0]) {
3220
- // off
3221
- bitValue |= 0x20;
3222
- }
3223
- else if (meta.state.system_mode === constants.thermostatSystemModes[4]) {
3224
- // "heat"
3225
- bitValue |= 0x04;
3226
- }
3227
- else {
3228
- // auto
3229
- bitValue |= 0x10;
3230
- }
3231
- if (meta.state.child_lock === "LOCK") {
3232
- bitValue |= 0x80;
3233
- }
3234
- const origValue = value;
3235
- value = bitValue;
3236
- const payload = { 16392: { value, type: 0x22 } };
3237
- await entity.write("hvacThermostat", payload, manufacturerOptions.eurotronic);
3238
- return { state: { [key]: origValue } };
3239
- },
3240
- convertGet: async (entity, key, meta) => {
3241
- await entity.read("hvacThermostat", [0x4008], manufacturerOptions.eurotronic);
3242
- },
3243
- };
3244
- exports.stelpro_peak_demand_event_icon = {
3245
- key: ["peak_demand_icon"],
3246
- convertSet: async (entity, key, value, meta) => {
3247
- const hours = Number(value);
3248
- const seconds = hours * 3600;
3249
- if (seconds < 0 || seconds > 65535) {
3250
- throw new Error("Peak demand duration must be between 0 and 18 hours");
3251
- }
3252
- const payload = {
3253
- 16645: {
3254
- value: seconds,
3255
- type: zigbee_herdsman_1.Zcl.DataType.UINT16,
3256
- },
3257
- };
3258
- await entity.write("hvacThermostat", payload);
3259
- return { state: { [key]: hours } };
3260
- },
3261
- };
3262
- exports.stelpro_thermostat_outdoor_temperature = {
3263
- key: ["outdoor_temperature_display"],
3264
- convertSet: async (entity, key, value, meta) => {
3265
- utils.assertNumber(value, key);
3266
- if (value < -32 || value > 119) {
3267
- throw new Error("Outdoor temperature must be between -32 and 119 degrees Celsius");
3268
- }
3269
- await entity.write("hvacThermostat", { StelproOutdoorTemp: value * 100 });
3270
- },
3271
- };
3272
- exports.DTB190502A1_LED = {
3273
- key: ["LED"],
3274
- convertSet: async (entity, key, value, meta) => {
3275
- if (value === "default") {
3276
- value = 1;
3277
- }
3278
- const lookup = {
3279
- OFF: 0,
3280
- ON: 1,
3281
- };
3282
- value = utils.getFromLookup(value, lookup);
3283
- // Check for valid data
3284
- utils.assertNumber(value, key);
3285
- if ((value >= 0 && value < 2) === false)
3286
- value = 0;
3287
- const payload = {
3288
- 16400: {
3289
- value,
3290
- type: 0x21,
3291
- },
3292
- };
3293
- await entity.write("genBasic", payload);
3294
- },
3295
- };
3296
- exports.ptvo_switch_trigger = {
3297
- key: ["trigger", "interval"],
3298
- convertSet: async (entity, key, value, meta) => {
3299
- utils.assertNumber(value, key);
3300
- utils.assertEndpoint(entity);
3301
- if (key === "trigger") {
3302
- await entity.command("genOnOff", "onWithTimedOff", { ctrlbits: 0, ontime: Math.round(value / 100), offwaittime: 0 });
3303
- }
3304
- else if (key === "interval") {
3305
- const cluster = "genOnOff";
3306
- if (entity.supportsInputCluster(cluster) || entity.supportsOutputCluster(cluster)) {
3307
- await entity.configureReporting(cluster, [
3308
- {
3309
- attribute: "onOff",
3310
- minimumReportInterval: value,
3311
- maximumReportInterval: value,
3312
- reportableChange: 0,
3313
- },
3314
- ]);
3315
- }
3316
- else if (utils.hasEndpoints(meta.device, [1])) {
3317
- const endpoint = meta.device.getEndpoint(1);
3318
- await endpoint.configureReporting("genBasic", [
3319
- {
3320
- attribute: "zclVersion",
3321
- minimumReportInterval: value,
3322
- maximumReportInterval: value,
3323
- reportableChange: 0,
3324
- },
3325
- ]);
3326
- }
3327
- }
3328
- },
3329
- };
3330
- exports.ptvo_switch_uart = {
3331
- key: ["action"],
3332
- convertSet: async (entity, key, value, meta) => {
3333
- if (!value) {
3334
- return;
3335
- }
3336
- const payload = { 14: { value, type: 0x42 } };
3337
- for (const endpoint of meta.device.endpoints) {
3338
- const cluster = "genMultistateValue";
3339
- if (endpoint.supportsInputCluster(cluster) || endpoint.supportsOutputCluster(cluster)) {
3340
- await endpoint.write(cluster, payload);
3341
- return;
3342
- }
3343
- }
3344
- await entity.write("genMultistateValue", payload);
3345
- },
3346
- };
3347
- exports.ptvo_switch_analog_input = {
3348
- key: ["l1", "l2", "l3", "l4", "l5", "l6", "l7", "l8", "l9", "l10", "l11", "l12", "l13", "l14", "l15", "l16"],
3349
- convertGet: async (entity, key, meta) => {
3350
- const epId = Number.parseInt(key.substr(1, 2), 10);
3351
- if (utils.hasEndpoints(meta.device, [epId])) {
3352
- const endpoint = meta.device.getEndpoint(epId);
3353
- await endpoint.read("genAnalogInput", ["presentValue", "description"]);
3354
- }
3355
- },
3356
- convertSet: async (entity, key, value, meta) => {
3357
- const epId = Number.parseInt(key.substr(1, 2), 10);
3358
- if (utils.hasEndpoints(meta.device, [epId])) {
3359
- const endpoint = meta.device.getEndpoint(epId);
3360
- let cluster = "genLevelCtrl";
3361
- if (endpoint.supportsInputCluster(cluster) || endpoint.supportsOutputCluster(cluster)) {
3362
- const value2 = Number(value);
3363
- if (Number.isNaN(value2)) {
3364
- return;
3365
- }
3366
- const payload = { currentLevel: value2 };
3367
- await endpoint.write(cluster, payload);
3368
- return;
3369
- }
3370
- cluster = "genAnalogInput";
3371
- if (endpoint.supportsInputCluster(cluster) || endpoint.supportsOutputCluster(cluster)) {
3372
- const value2 = Number(value);
3373
- if (Number.isNaN(value2)) {
3374
- return;
3375
- }
3376
- const payload = { presentValue: value2 };
3377
- await endpoint.write(cluster, payload);
3378
- return;
3379
- }
3380
- }
3381
- return;
3382
- },
3383
- };
3384
- exports.tint_scene = {
3385
- key: ["tint_scene"],
3386
- convertSet: async (entity, key, value, meta) => {
3387
- await entity.write("genBasic", { 16389: { value, type: 0x20 } }, manufacturerOptions.tint);
3388
- },
3389
- };
3390
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3391
- exports.bticino_4027C_cover_state = {
3392
- key: ["state"],
3393
- options: [exposes.options.invert_cover()],
3394
- convertSet: async (entity, key, value, meta) => {
3395
- utils.assertString(value);
3396
- const invert = !(utils.getMetaValue(entity, meta.mapped, "coverInverted", "allEqual", false)
3397
- ? !meta.options.invert_cover
3398
- : meta.options.invert_cover);
3399
- const lookup = invert
3400
- ? { open: "upOpen", close: "downClose", stop: "stop", on: "upOpen", off: "downClose" }
3401
- : { open: "downClose", close: "upOpen", stop: "stop", on: "downClose", off: "upOpen" };
3402
- value = value.toLowerCase();
3403
- utils.validateValue(value, Object.keys(lookup));
3404
- let position = 50;
3405
- if (value === "open") {
3406
- position = 100;
3407
- }
3408
- else if (value === "close") {
3409
- position = 0;
3410
- }
3411
- await entity.command("closuresWindowCovering", utils.getFromLookup(value, lookup), {}, utils.getOptions(meta.mapped, entity));
3412
- return { state: { position } };
3413
- },
3414
- };
3415
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3416
- exports.bticino_4027C_cover_position = {
3417
- key: ["position"],
3418
- options: [exposes.options.invert_cover(), exposes.options.no_position_support()],
3419
- convertSet: async (entity, key, value, meta) => {
3420
- const invert = !(utils.getMetaValue(entity, meta.mapped, "coverInverted", "allEqual", false)
3421
- ? !meta.options.invert_cover
3422
- : meta.options.invert_cover);
3423
- utils.assertNumber(value, key);
3424
- let newPosition = value;
3425
- if (meta.options.no_position_support) {
3426
- newPosition = value >= 50 ? 100 : 0;
3427
- }
3428
- const position = newPosition;
3429
- if (invert) {
3430
- newPosition = 100 - newPosition;
3431
- }
3432
- await entity.command("closuresWindowCovering", "goToLiftPercentage", { percentageliftvalue: newPosition }, utils.getOptions(meta.mapped, entity));
3433
- return { state: { position: position } };
3434
- },
3435
- convertGet: async (entity, key, meta) => {
3436
- await entity.read("closuresWindowCovering", ["currentPositionLiftPercentage"]);
3437
- },
3438
- };
3439
- exports.legrand_power_alarm = {
3440
- key: ["power_alarm"],
3441
- convertSet: async (entity, key, value, meta) => {
3442
- const enableAlarm = !(value === "DISABLE" || value === false);
3443
- const payloadBolean = { 61441: { value: enableAlarm ? 0x01 : 0x00, type: 0x10 } };
3444
- const payloadValue = { 61442: { value: value, type: 0x29 } };
3445
- await entity.write("haElectricalMeasurement", payloadValue);
3446
- await entity.write("haElectricalMeasurement", payloadBolean);
3447
- // To have consistent information in the system.
3448
- await entity.read("haElectricalMeasurement", [0xf000, 0xf001, 0xf002]);
3449
- },
3450
- convertGet: async (entity, key, meta) => {
3451
- await entity.read("haElectricalMeasurement", [0xf000, 0xf001, 0xf002]);
3452
- },
3453
- };
3454
- exports.diyruz_freepad_on_off_config = {
3455
- key: ["switch_type", "switch_actions"],
3456
- convertGet: async (entity, key, meta) => {
3457
- await entity.read("genOnOffSwitchCfg", ["switchType", "switchActions"]);
3458
- },
3459
- convertSet: async (entity, key, value, meta) => {
3460
- const switchTypesLookup = {
3461
- toggle: 0x00,
3462
- momentary: 0x01,
3463
- multifunction: 0x02,
3464
- };
3465
- const switchActionsLookup = {
3466
- on: 0x00,
3467
- off: 0x01,
3468
- toggle: 0x02,
3469
- };
3470
- const intVal = Number(value);
3471
- const switchType = utils.getFromLookup(value, switchTypesLookup, intVal);
3472
- const switchActions = utils.getFromLookup(value, switchActionsLookup, intVal);
3473
- const payloads = {
3474
- switch_type: { switchType },
3475
- switch_actions: { switchActions },
3476
- };
3477
- await entity.write("genOnOffSwitchCfg", payloads[key]);
3478
- return { state: { [`${key}`]: value } };
3479
- },
3480
- };
3481
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3482
- exports.TYZB01_on_off = {
3483
- key: ["state", "time_in_seconds"],
3484
- convertSet: async (entity, key, value, meta) => {
3485
- const result = await exports.on_off.convertSet(entity, key, value, meta);
3486
- utils.assertString(value, key);
3487
- const lowerCaseValue = value.toLowerCase();
3488
- if (!["on", "off"].includes(lowerCaseValue)) {
3489
- return result;
3490
- }
3491
- const messageKeys = Object.keys(meta.message);
3492
- const timeInSecondsValue = (() => {
3493
- if (messageKeys.includes("state")) {
3494
- return meta.message.time_in_seconds;
3495
- }
3496
- if (meta.endpoint_name) {
3497
- return meta.message[`time_in_seconds_${meta.endpoint_name}`];
3498
- }
3499
- return null;
3500
- })();
3501
- if (!timeInSecondsValue) {
3502
- return result;
3503
- }
3504
- const timeInSeconds = Number(timeInSecondsValue);
3505
- if (!Number.isInteger(timeInSeconds) || timeInSeconds < 0 || timeInSeconds > 0xfffe) {
3506
- throw new Error("The time_in_seconds value must be convertible to an integer in the range: <0x0000, 0xFFFE>");
3507
- }
3508
- const on = lowerCaseValue === "on";
3509
- await entity.command("genOnOff", "onWithTimedOff", {
3510
- ctrlbits: 0,
3511
- ontime: on ? 0 : timeInSeconds.valueOf(),
3512
- offwaittime: on ? timeInSeconds.valueOf() : 0,
3513
- }, utils.getOptions(meta.mapped, entity));
3514
- return result;
3515
- },
3516
- convertGet: async (entity, key, meta) => {
3517
- await entity.read("genOnOff", ["onOff"]);
3518
- },
3519
- };
3520
- exports.diyruz_geiger_config = {
3521
- key: ["sensitivity", "led_feedback", "buzzer_feedback", "sensors_count", "sensors_type", "alert_threshold"],
3522
- convertSet: async (entity, key, rawValue, meta) => {
3523
- const lookup = {
3524
- OFF: 0x00,
3525
- ON: 0x01,
3526
- };
3527
- const sensorsTypeLookup = {
3528
- "СБМ-20/СТС-5/BOI-33": "0",
3529
- "СБМ-19/СТС-6": "1",
3530
- Others: "2",
3531
- };
3532
- let value = utils.getFromLookup(rawValue, lookup, Number(rawValue));
3533
- if (key === "sensors_type") {
3534
- // @ts-expect-error ignore
3535
- value = utils.getFromLookup(rawValue, sensorsTypeLookup, Number(rawValue));
3536
- }
3537
- const payloads = {
3538
- sensitivity: { 61440: { value, type: 0x21 } },
3539
- led_feedback: { 61441: { value, type: 0x10 } },
3540
- buzzer_feedback: { 61442: { value, type: 0x10 } },
3541
- sensors_count: { 61443: { value, type: 0x20 } },
3542
- sensors_type: { 61444: { value, type: 0x30 } },
3543
- alert_threshold: { 61445: { value, type: 0x23 } },
3544
- };
3545
- await entity.write("msIlluminanceLevelSensing", payloads[key]);
3546
- return {
3547
- state: { [key]: rawValue },
3548
- };
3549
- },
3550
- convertGet: async (entity, key, meta) => {
3551
- const payloads = {
3552
- sensitivity: ["msIlluminanceLevelSensing", 0xf000],
3553
- led_feedback: ["msIlluminanceLevelSensing", 0xf001],
3554
- buzzer_feedback: ["msIlluminanceLevelSensing", 0xf002],
3555
- sensors_count: ["msIlluminanceLevelSensing", 0xf003],
3556
- sensors_type: ["msIlluminanceLevelSensing", 0xf004],
3557
- alert_threshold: ["msIlluminanceLevelSensing", 0xf005],
3558
- };
3559
- await entity.read(payloads[key][0], [payloads[key][1]]);
3560
- },
3561
- };
3562
- exports.diyruz_airsense_config = {
3563
- key: ["led_feedback", "enable_abc", "threshold1", "threshold2", "temperature_offset", "pressure_offset", "humidity_offset"],
3564
- convertSet: async (entity, key, rawValue, meta) => {
3565
- const lookup = { OFF: 0x00, ON: 0x01 };
3566
- const value = utils.getFromLookup(rawValue, lookup, Number(rawValue));
3567
- const payloads = {
3568
- led_feedback: ["msCO2", { 515: { value, type: 0x10 } }],
3569
- enable_abc: ["msCO2", { 514: { value, type: 0x10 } }],
3570
- threshold1: ["msCO2", { 516: { value, type: 0x21 } }],
3571
- threshold2: ["msCO2", { 517: { value, type: 0x21 } }],
3572
- temperature_offset: ["msTemperatureMeasurement", { 528: { value, type: 0x29 } }],
3573
- pressure_offset: ["msPressureMeasurement", { 528: { value, type: 0x2b } }],
3574
- humidity_offset: ["msRelativeHumidity", { 528: { value, type: 0x29 } }],
3575
- };
3576
- await entity.write(payloads[key][0], payloads[key][1]);
3577
- return {
3578
- state: { [key]: rawValue },
3579
- };
3580
- },
3581
- convertGet: async (entity, key, meta) => {
3582
- const payloads = {
3583
- led_feedback: ["msCO2", 0x0203],
3584
- enable_abc: ["msCO2", 0x0202],
3585
- threshold1: ["msCO2", 0x0204],
3586
- threshold2: ["msCO2", 0x0205],
3587
- temperature_offset: ["msTemperatureMeasurement", 0x0210],
3588
- pressure_offset: ["msPressureMeasurement", 0x0210],
3589
- humidity_offset: ["msRelativeHumidity", 0x0210],
3590
- };
3591
- await entity.read(payloads[key][0], [payloads[key][1]]);
3592
- },
3593
- };
3594
- exports.diyruz_zintercom_config = {
3595
- key: ["mode", "sound", "time_ring", "time_talk", "time_open", "time_bell", "time_report"],
3596
- convertSet: async (entity, key, rawValue, meta) => {
3597
- const lookup = { OFF: 0x00, ON: 0x01 };
3598
- const modeOpenLookup = { never: "0", once: "1", always: "2", drop: "3" };
3599
- let value = utils.getFromLookup(rawValue, lookup, Number(rawValue));
3600
- if (key === "mode") {
3601
- // @ts-expect-error ignore
3602
- value = utils.getFromLookup(rawValue, modeOpenLookup, Number(rawValue));
3603
- }
3604
- const payloads = {
3605
- mode: { 81: { value, type: 0x30 } },
3606
- sound: { 82: { value, type: 0x10 } },
3607
- time_ring: { 83: { value, type: 0x20 } },
3608
- time_talk: { 84: { value, type: 0x20 } },
3609
- time_open: { 85: { value, type: 0x20 } },
3610
- time_bell: { 87: { value, type: 0x20 } },
3611
- time_report: { 86: { value, type: 0x20 } },
3612
- };
3613
- await entity.write("closuresDoorLock", payloads[key]);
3614
- return {
3615
- state: { [key]: rawValue },
3616
- };
3617
- },
3618
- convertGet: async (entity, key, meta) => {
3619
- const payloads = {
3620
- mode: 0x0051,
3621
- sound: 0x0052,
3622
- time_ring: 0x0053,
3623
- time_talk: 0x0054,
3624
- time_open: 0x0055,
3625
- time_bell: 0x0057,
3626
- time_report: 0x0056,
3627
- };
3628
- const v = utils.getFromLookup(key, payloads);
3629
- await entity.read("closuresDoorLock", [v]);
3630
- },
3631
- };
3632
- exports.power_source = {
3633
- key: ["power_source", "charging"],
3634
- convertGet: async (entity, key, meta) => {
3635
- await entity.read("genBasic", ["powerSource"]);
3636
- },
3637
- };
3638
- exports.ts0201_temperature_humidity_alarm = {
3639
- key: ["alarm_humidity_max", "alarm_humidity_min", "alarm_temperature_max", "alarm_temperature_min"],
3640
- convertSet: async (entity, key, value, meta) => {
3641
- switch (key) {
3642
- case "alarm_temperature_max":
3643
- case "alarm_temperature_min":
3644
- case "alarm_humidity_max":
3645
- case "alarm_humidity_min": {
3646
- // await entity.write('manuSpecificTuya2', {[key]: value});
3647
- // instead write as custom attribute to override incorrect herdsman dataType from uint16 to int16
3648
- // https://github.com/Koenkk/zigbee-herdsman/blob/v0.13.191/src/zcl/definition/cluster.ts#L4235
3649
- const keyToAttributeLookup = {
3650
- alarm_temperature_max: 0xd00a,
3651
- alarm_temperature_min: 0xd00b,
3652
- alarm_humidity_max: 0xd00d,
3653
- alarm_humidity_min: 0xd00e,
3654
- };
3655
- const payload = { [keyToAttributeLookup[key]]: { value: value, type: zigbee_herdsman_1.Zcl.DataType.INT16 } };
3656
- await entity.write("manuSpecificTuya2", payload);
3657
- break;
3658
- }
3659
- default: // Unknown key
3660
- logger_1.logger.warning(`Unhandled key ${key}`, NS);
3661
- }
3662
- },
3663
- };
3664
- exports.heiman_ir_remote = {
3665
- key: ["send_key", "create", "learn", "delete", "get_list"],
3666
- convertSet: async (entity, key, value, meta) => {
3667
- const options = {
3668
- // Don't send a manufacturerCode (otherwise set in herdsman):
3669
- // https://github.com/Koenkk/zigbee-herdsman-converters/pull/2827
3670
- // @ts-expect-error ignore
3671
- manufacturerCode: null,
3672
- ...utils.getOptions(meta.mapped, entity),
3673
- };
3674
- switch (key) {
3675
- case "send_key":
3676
- utils.assertObject(value);
3677
- await entity.command("heimanSpecificInfraRedRemote", "sendKey", { id: value.id, keyCode: value.key_code }, options);
3678
- break;
3679
- case "create":
3680
- utils.assertObject(value);
3681
- await entity.command("heimanSpecificInfraRedRemote", "createId", { modelType: value.model_type }, options);
3682
- break;
3683
- case "learn":
3684
- utils.assertObject(value);
3685
- await entity.command("heimanSpecificInfraRedRemote", "studyKey", { id: value.id, keyCode: value.key_code }, options);
3686
- break;
3687
- case "delete":
3688
- utils.assertObject(value);
3689
- await entity.command("heimanSpecificInfraRedRemote", "deleteKey", { id: value.id, keyCode: value.key_code }, options);
3690
- break;
3691
- case "get_list":
3692
- await entity.command("heimanSpecificInfraRedRemote", "getIdAndKeyCodeList", {}, options);
3693
- break;
3694
- default: // Unknown key
3695
- throw new Error(`Unhandled key ${key}`);
3696
- }
3697
- },
3698
- };
3699
- exports.scene_store = {
3700
- key: ["scene_store"],
3701
- convertSet: async (entity, key, value, meta) => {
3702
- const isGroup = utils.isGroup(entity);
3703
- const groupid = isGroup ? entity.groupID : value.group_id != null ? value.group_id : 0;
3704
- let sceneid = value;
3705
- let scenename = null;
3706
- if (typeof value === "object") {
3707
- sceneid = value.ID;
3708
- scenename = value.name;
3709
- }
3710
- utils.assertNumber(sceneid, "ID");
3711
- if (groupid === 0 && sceneid === 0) {
3712
- // From Zigbee spec:
3713
- // "Scene identifier 0x00, along with group identifier 0x0000, is reserved for the global scene used by the OnOff cluster"
3714
- throw new Error("Scene ID 0 cannot be used with group ID 0 (reserved).");
3715
- }
3716
- const response = await entity.command("genScenes", "store", { groupid, sceneid }, utils.getOptions(meta.mapped, entity));
3717
- if (isGroup) {
3718
- if (meta.membersState) {
3719
- for (const member of entity.members) {
3720
- utils.saveSceneState(member, sceneid, groupid, meta.membersState[member.getDevice().ieeeAddr], scenename);
3721
- }
3722
- }
3723
- }
3724
- else if (response.status === 0) {
3725
- utils.saveSceneState(entity, sceneid, groupid, meta.state, scenename);
3726
- }
3727
- else {
3728
- throw new Error(`Scene add not successful ('${zigbee_herdsman_1.Zcl.Status[response.status]}')`);
3729
- }
3730
- logger_1.logger.info("Successfully stored scene", NS);
3731
- return { state: {} };
3732
- },
3733
- };
3734
- exports.scene_recall = {
3735
- key: ["scene_recall"],
3736
- convertSet: async (entity, key, value, meta) => {
3737
- const groupid = utils.isGroup(entity) ? entity.groupID : 0;
3738
- utils.assertNumber(value);
3739
- const sceneid = value;
3740
- await entity.command("genScenes", "recall", { groupid, sceneid, transitionTime: 0xffff }, utils.getOptions(meta.mapped, entity));
3741
- const addColorMode = (newState) => {
3742
- if (newState.color_temp !== undefined) {
3743
- newState.color_mode = constants.colorModeLookup[2];
3744
- }
3745
- else if (newState.color !== undefined) {
3746
- if (newState.color.x !== undefined) {
3747
- newState.color_mode = constants.colorModeLookup[1];
3748
- }
3749
- else {
3750
- newState.color_mode = constants.colorModeLookup[0];
3751
- }
3752
- }
3753
- return newState;
3754
- };
3755
- if (utils.isGroup(entity)) {
3756
- const membersState = {};
3757
- for (const member of entity.members) {
3758
- let recalledState = utils.getSceneState(member, sceneid, groupid);
3759
- if (recalledState) {
3760
- // add color_mode if saved state does not contain it
3761
- if (recalledState.color_mode === undefined) {
3762
- recalledState = addColorMode(recalledState);
3763
- }
3764
- Object.assign(recalledState, libColor.syncColorState(recalledState, meta.state, entity, meta.options));
3765
- membersState[member.getDevice().ieeeAddr] = recalledState;
3766
- }
3767
- else {
3768
- logger_1.logger.warning(`Unknown scene was recalled for ${member.getDevice().ieeeAddr}, can't restore state.`, NS);
3769
- membersState[member.getDevice().ieeeAddr] = {};
3770
- }
3771
- }
3772
- logger_1.logger.info("Successfully recalled group scene", NS);
3773
- return { membersState };
3774
- }
3775
- let recalledState = utils.getSceneState(entity, sceneid, groupid);
3776
- if (recalledState) {
3777
- // add color_mode if saved state does not contain it
3778
- if (recalledState.color_mode === undefined) {
3779
- recalledState = addColorMode(recalledState);
3780
- }
3781
- Object.assign(recalledState, libColor.syncColorState(recalledState, meta.state, entity, meta.options));
3782
- logger_1.logger.info("Successfully recalled scene", NS);
3783
- return { state: recalledState };
3784
- }
3785
- logger_1.logger.warning(`Unknown scene was recalled for ${entity.deviceIeeeAddress}, can't restore state.`, NS);
3786
- return { state: {} };
3787
- },
3788
- };
3789
- exports.scene_add = {
3790
- key: ["scene_add"],
2231
+ exports.scene_add = {
2232
+ key: ["scene_add"],
3791
2233
  convertSet: async (entity, key, value, meta) => {
3792
2234
  utils.assertObject(value);
3793
2235
  utils.assertNumber(value.ID, "ID");
@@ -3867,7 +2309,7 @@ exports.scene_add = {
3867
2309
  }
3868
2310
  else if (newColor.isHSV()) {
3869
2311
  const hsvCorrected = newColor.hsv.colorCorrected(meta);
3870
- if (utils.getMetaValue(entity, meta.mapped, "supportsEnhancedHue", "allEqual", true)) {
2312
+ if (utils.getMetaValue(entity, meta.mapped, "supportsEnhancedHue", "allEqual", false)) {
3871
2313
  const hScaled = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 65535);
3872
2314
  const sScaled = utils.mapNumberRange(hsvCorrected.saturation, 0, 100, 0, 254);
3873
2315
  extensionfieldsets.push({
@@ -3881,563 +2323,147 @@ exports.scene_add = {
3881
2323
  // When the bulb or all bulbs in a group do not support enhanchedHue,
3882
2324
  const colorXY = hsvCorrected.toXY();
3883
2325
  const xScaled = utils.mapNumberRange(colorXY.x, 0, 1, 0, 65535);
3884
- const yScaled = utils.mapNumberRange(colorXY.y, 0, 1, 0, 65535);
3885
- extensionfieldsets.push({
3886
- clstId: 768,
3887
- len: 4,
3888
- extField: [xScaled, yScaled],
3889
- });
3890
- }
3891
- state.color_mode = constants.colorModeLookup[0];
3892
- state.color = newColor.hsv.toObject(false, false);
3893
- }
3894
- }
3895
- }
3896
- /*
3897
- * Remove scene first
3898
- *
3899
- * Multiple add scene calls will result in the current and previous
3900
- * payloads to be merged. Resulting in unexpected behavior when
3901
- * trying to replace a scene.
3902
- *
3903
- * We accept a SUCCESS or NOT_FOUND as a result of the remove call.
3904
- */
3905
- const removeresp = await entity.command("genScenes", "remove", { groupid, sceneid }, utils.getOptions(meta.mapped, entity));
3906
- if (isGroup || (utils.isObject(removeresp) && (removeresp.status === 0 || removeresp.status === 133 || removeresp.status === 139))) {
3907
- const addSceneCommand = Number.isInteger(transtime) ? "add" : "enhancedAdd";
3908
- const commandTransitionTime = addSceneCommand === "enhancedAdd" ? Math.floor(transtime * 10) : transtime;
3909
- const response = await entity.command("genScenes", addSceneCommand, { groupid, sceneid, scenename: "", transtime: commandTransitionTime, extensionfieldsets }, utils.getOptions(meta.mapped, entity));
3910
- if (isGroup) {
3911
- if (meta.membersState) {
3912
- for (const member of entity.members) {
3913
- utils.saveSceneState(member, sceneid, groupid, state, scenename);
3914
- }
3915
- }
3916
- }
3917
- else {
3918
- utils.assertObject(response);
3919
- if (response.status === 0) {
3920
- utils.saveSceneState(entity, sceneid, groupid, state, scenename);
3921
- }
3922
- else {
3923
- throw new Error(`Scene add not successful ('${zigbee_herdsman_1.Zcl.Status[response.status]}')`);
3924
- }
3925
- }
3926
- }
3927
- else {
3928
- const status = utils.isObject(removeresp) ? zigbee_herdsman_1.Zcl.Status[removeresp.status] : "unknown";
3929
- throw new Error(`Scene add unable to remove existing scene ('${status}')`);
3930
- }
3931
- logger_1.logger.info("Successfully added scene", NS);
3932
- return { state: {} };
3933
- },
3934
- };
3935
- exports.scene_remove = {
3936
- key: ["scene_remove"],
3937
- convertSet: async (entity, key, value, meta) => {
3938
- const isGroup = utils.isGroup(entity);
3939
- utils.assertNumber(value);
3940
- const groupid = isGroup ? entity.groupID : 0;
3941
- const sceneid = value;
3942
- const response = await entity.command("genScenes", "remove", { groupid, sceneid }, utils.getOptions(meta.mapped, entity));
3943
- if (isGroup) {
3944
- if (meta.membersState) {
3945
- for (const member of entity.members) {
3946
- utils.deleteSceneState(member, sceneid, groupid);
3947
- }
3948
- }
3949
- }
3950
- else if (response.status === 0) {
3951
- utils.deleteSceneState(entity, sceneid, groupid);
3952
- }
3953
- else {
3954
- throw new Error(`Scene remove not successful ('${zigbee_herdsman_1.Zcl.Status[response.status]}')`);
3955
- }
3956
- logger_1.logger.info("Successfully removed scene", NS);
3957
- },
3958
- };
3959
- exports.scene_remove_all = {
3960
- key: ["scene_remove_all"],
3961
- convertSet: async (entity, key, value, meta) => {
3962
- const groupid = utils.isGroup(entity) ? entity.groupID : 0;
3963
- // In case `entity` is a group, the response is `undefined`, mock it.
3964
- const response = (await entity.command("genScenes", "removeAll", { groupid }, utils.getOptions(meta.mapped, entity))) ?? { status: 0 };
3965
- utils.assertObject(response);
3966
- if (utils.isGroup(entity)) {
3967
- if (meta.membersState) {
3968
- for (const member of entity.members) {
3969
- utils.deleteSceneState(member);
3970
- }
3971
- }
3972
- }
3973
- else if (response.status === 0) {
3974
- utils.deleteSceneState(entity);
3975
- }
3976
- else {
3977
- throw new Error(`Scene remove all not successful ('${zigbee_herdsman_1.Zcl.Status[response.status]}')`);
3978
- }
3979
- logger_1.logger.info("Successfully removed all scenes", NS);
3980
- },
3981
- };
3982
- exports.scene_rename = {
3983
- key: ["scene_rename"],
3984
- convertSet: (entity, key, value, meta) => {
3985
- utils.assertObject(value);
3986
- const isGroup = utils.isGroup(entity);
3987
- const sceneid = value.ID;
3988
- const scenename = value.name;
3989
- const groupid = isGroup ? entity.groupID : value.group_id != null ? value.group_id : 0;
3990
- if (isGroup) {
3991
- if (meta.membersState) {
3992
- for (const member of entity.members) {
3993
- const state = utils.getSceneState(member, sceneid, groupid);
3994
- if (state) {
3995
- utils.saveSceneState(member, sceneid, groupid, state, scenename);
3996
- }
3997
- }
3998
- }
3999
- }
4000
- else {
4001
- const state = utils.getSceneState(entity, sceneid, groupid);
4002
- if (!state) {
4003
- throw new Error("No such scene in device meta data");
4004
- }
4005
- utils.saveSceneState(entity, sceneid, groupid, state, scenename);
4006
- }
4007
- logger_1.logger.info("Successfully renamed scene", NS);
4008
- },
4009
- };
4010
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4011
- exports.TS0003_curtain_switch = {
4012
- key: ["state"],
4013
- convertSet: async (entity, key, value, meta) => {
4014
- utils.assertString(value, key);
4015
- utils.assertEndpoint(entity);
4016
- const lookup = { close: 1, stop: 2, open: 1 };
4017
- value = value.toLowerCase();
4018
- utils.validateValue(value, Object.keys(lookup));
4019
- const endpointID = utils.getFromLookup(value, lookup);
4020
- const endpoint = entity.getDevice().getEndpoint(endpointID);
4021
- await endpoint.command("genOnOff", "on", {}, utils.getOptions(meta.mapped, entity));
4022
- },
4023
- convertGet: async (entity, key, meta) => {
4024
- await entity.read("genOnOff", ["onOff"]);
4025
- },
4026
- };
4027
- exports.ts0216_duration = {
4028
- key: ["duration"],
4029
- convertSet: async (entity, key, value, meta) => {
4030
- await entity.write("ssIasWd", { maxDuration: value });
4031
- },
4032
- convertGet: async (entity, key, meta) => {
4033
- await entity.read("ssIasWd", ["maxDuration"]);
4034
- },
4035
- };
4036
- exports.ts0216_volume = {
4037
- key: ["volume"],
4038
- convertSet: async (entity, key, value, meta) => {
4039
- utils.assertNumber(value);
4040
- if (["_TYZB01_sbpc1zrb"].includes(meta.device.manufacturerName)) {
4041
- const volume = value === 0 ? 0 : utils.mapNumberRange(value, 1, 100, 100, 33);
4042
- await entity.write("ssIasWd", { 2: { value: volume, type: 0x20 } });
4043
- return;
4044
- }
4045
- await entity.write("ssIasWd", { 2: { value: utils.mapNumberRange(value, 0, 100, 100, 10), type: 0x20 } });
4046
- },
4047
- convertGet: async (entity, key, meta) => {
4048
- await entity.read("ssIasWd", [0x0002]);
4049
- },
4050
- };
4051
- exports.ts0216_alarm = {
4052
- key: ["alarm"],
4053
- convertSet: async (entity, key, value, meta) => {
4054
- const info = value ? (2 << 4) + (1 << 2) + 0 : 0;
4055
- await entity.command("ssIasWd", "startWarning", { startwarninginfo: info, warningduration: 0, strobedutycycle: 0, strobelevel: 3 }, utils.getOptions(meta.mapped, entity));
4056
- },
4057
- };
4058
- exports.tuya_cover_calibration = {
4059
- key: ["calibration", "calibration_to_open", "calibration_to_close", "calibration_time", "calibration_time_to_open", "calibration_time_to_close"],
4060
- convertSet: async (entity, key, value, meta) => {
4061
- if (key.startsWith("calibration_time")) {
4062
- utils.assertNumber(value, key);
4063
- const calibration_time = value * 10;
4064
- if (key === "calibration_time" || key === "calibration_time_to_open") {
4065
- await entity.write("closuresWindowCovering", { moesCalibrationTime: calibration_time });
4066
- }
4067
- else if (key === "calibration_time_to_close") {
4068
- await meta.device.getEndpoint(2).write("closuresWindowCovering", { moesCalibrationTime: calibration_time });
4069
- }
4070
- return { state: { [key]: value } };
4071
- }
4072
- utils.assertString(value, key);
4073
- const lookup = { ON: 0, OFF: 1 };
4074
- value = value.toUpperCase();
4075
- const calibration = utils.getFromLookup(value, lookup);
4076
- if (key === "calibration" || key === "calibration_to_open") {
4077
- await entity.write("closuresWindowCovering", { tuyaCalibration: calibration });
4078
- }
4079
- else if (key === "calibration_to_close") {
4080
- await meta.device.getEndpoint(2).write("closuresWindowCovering", { tuyaCalibration: calibration });
4081
- }
4082
- return { state: { [key]: value } };
4083
- },
4084
- convertGet: async (entity, key, meta) => {
4085
- if (key === "calibration" || key === "calibration_to_open") {
4086
- await entity.read("closuresWindowCovering", ["tuyaCalibration"]);
4087
- }
4088
- else if (key === "calibration_to_close") {
4089
- await meta.device.getEndpoint(2).read("closuresWindowCovering", ["tuyaCalibration"]);
4090
- }
4091
- else if (key === "calibration_time" || key === "calibration_time_to_open") {
4092
- await entity.read("closuresWindowCovering", ["moesCalibrationTime"]);
4093
- }
4094
- else if (key === "calibration_time_to_close") {
4095
- await meta.device.getEndpoint(2).read("closuresWindowCovering", ["moesCalibrationTime"]);
4096
- }
4097
- },
4098
- };
4099
- exports.tuya_cover_reversal = {
4100
- key: ["motor_reversal"],
4101
- convertSet: async (entity, key, value, meta) => {
4102
- utils.assertString(value, key);
4103
- const lookup = { ON: 1, OFF: 0 };
4104
- value = value.toUpperCase();
4105
- const reversal = utils.getFromLookup(value, lookup);
4106
- await entity.write("closuresWindowCovering", { tuyaMotorReversal: reversal });
4107
- return { state: { motor_reversal: value } };
4108
- },
4109
- convertGet: async (entity, key, meta) => {
4110
- await entity.read("closuresWindowCovering", ["tuyaMotorReversal"]);
4111
- },
4112
- };
4113
- exports.moes_cover_calibration = {
4114
- key: ["calibration_time"],
4115
- convertSet: async (entity, key, value, meta) => {
4116
- utils.assertNumber(value);
4117
- const calibration = value * 10;
4118
- await entity.write("closuresWindowCovering", { moesCalibrationTime: calibration });
4119
- return { state: { calibration_time: value } };
4120
- },
4121
- convertGet: async (entity, key, meta) => {
4122
- await entity.read("closuresWindowCovering", ["moesCalibrationTime"]);
4123
- },
4124
- };
4125
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4126
- exports.ZM35HQ_attr = {
4127
- key: ["sensitivity", "keep_time"],
4128
- convertSet: async (entity, key, value, meta) => {
4129
- switch (key) {
4130
- case "sensitivity":
4131
- await entity.write("ssIasZone", { currentZoneSensitivityLevel: utils.getFromLookup(value, { low: 0, medium: 1, high: 2 }) });
4132
- break;
4133
- case "keep_time":
4134
- await entity.write("ssIasZone", { 61441: { value: utils.getFromLookup(value, { 30: 0, 60: 1, 120: 2 }), type: 0x20 } });
4135
- break;
4136
- default: // Unknown key
4137
- throw new Error(`Unhandled key ${key}`);
4138
- }
4139
- },
4140
- convertGet: async (entity, key, meta) => {
4141
- // Apparently, reading values may interfere with a commandStatusChangeNotification for changed occupancy.
4142
- // Therefore, read "zoneStatus" as well.
4143
- await entity.read("ssIasZone", ["currentZoneSensitivityLevel", 61441, "zoneStatus"]);
4144
- },
4145
- };
4146
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4147
- exports.TS0210_sensitivity = {
4148
- key: ["sensitivity"],
4149
- convertSet: async (entity, key, value, meta) => {
4150
- value = utils.toNumber(value, "sensitivity");
4151
- await entity.write("ssIasZone", { currentZoneSensitivityLevel: value });
4152
- return { state: { sensitivity: value } };
4153
- },
4154
- };
4155
- exports.viessmann_window_open = {
4156
- key: ["window_open"],
4157
- convertGet: async (entity, key, meta) => {
4158
- await entity.read("hvacThermostat", ["viessmannWindowOpenInternal"], manufacturerOptions.viessmann);
4159
- },
4160
- };
4161
- exports.viessmann_window_open_force = {
4162
- key: ["window_open_force"],
4163
- convertSet: async (entity, key, value, meta) => {
4164
- if (typeof value === "boolean") {
4165
- await entity.write("hvacThermostat", { viessmannWindowOpenForce: value ? 1 : 0 }, manufacturerOptions.viessmann);
4166
- return { state: { window_open_force: value } };
4167
- }
4168
- logger_1.logger.error("window_open_force must be a boolean!", NS);
4169
- },
4170
- convertGet: async (entity, key, meta) => {
4171
- await entity.read("hvacThermostat", ["viessmannWindowOpenForce"], manufacturerOptions.viessmann);
4172
- },
4173
- };
4174
- exports.viessmann_assembly_mode = {
4175
- key: ["assembly_mode"],
4176
- convertGet: async (entity, key, meta) => {
4177
- await entity.read("hvacThermostat", ["viessmannAssemblyMode"], manufacturerOptions.viessmann);
4178
- },
4179
- };
4180
- exports.dawondns_only_off = {
4181
- key: ["state"],
4182
- convertSet: async (entity, key, value, meta) => {
4183
- utils.assertString(value, key);
4184
- const lowerValue = value.toLowerCase();
4185
- utils.validateValue(lowerValue, ["off"]);
4186
- await entity.command("genOnOff", lowerValue, {}, utils.getOptions(meta.mapped, entity));
4187
- },
4188
- convertGet: async (entity, key, meta) => {
4189
- await entity.read("genOnOff", ["onOff"]);
4190
- },
4191
- };
4192
- exports.idlock_master_pin_mode = {
4193
- key: ["master_pin_mode"],
4194
- convertSet: async (entity, key, value, meta) => {
4195
- await entity.write("closuresDoorLock", { 16384: { value: value === true ? 1 : 0, type: 0x10 } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4196
- return { state: { master_pin_mode: value } };
4197
- },
4198
- convertGet: async (entity, key, meta) => {
4199
- await entity.read("closuresDoorLock", [0x4000], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4200
- },
4201
- };
4202
- exports.idlock_rfid_enable = {
4203
- key: ["rfid_enable"],
4204
- convertSet: async (entity, key, value, meta) => {
4205
- await entity.write("closuresDoorLock", { 16385: { value: value === true ? 1 : 0, type: 0x10 } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4206
- return { state: { rfid_enable: value } };
4207
- },
4208
- convertGet: async (entity, key, meta) => {
4209
- await entity.read("closuresDoorLock", [0x4001], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4210
- },
4211
- };
4212
- exports.idlock_service_mode = {
4213
- key: ["service_mode"],
4214
- convertSet: async (entity, key, value, meta) => {
4215
- const lookup = { deactivated: 0, random_pin_1x_use: 5, random_pin_24_hours: 6 };
4216
- await entity.write("closuresDoorLock", { 16387: { value: utils.getFromLookup(value, lookup), type: 0x20 } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4217
- return { state: { service_mode: value } };
4218
- },
4219
- convertGet: async (entity, key, meta) => {
4220
- await entity.read("closuresDoorLock", [0x4003], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4221
- },
4222
- };
4223
- exports.idlock_lock_mode = {
4224
- key: ["lock_mode"],
4225
- convertSet: async (entity, key, value, meta) => {
4226
- const lookup = { auto_off_away_off: 0, auto_on_away_off: 1, auto_off_away_on: 2, auto_on_away_on: 3 };
4227
- await entity.write("closuresDoorLock", { 16388: { value: utils.getFromLookup(value, lookup), type: 0x20 } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4228
- return { state: { lock_mode: value } };
4229
- },
4230
- convertGet: async (entity, key, meta) => {
4231
- await entity.read("closuresDoorLock", [0x4004], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4232
- },
4233
- };
4234
- exports.idlock_relock_enabled = {
4235
- key: ["relock_enabled"],
4236
- convertSet: async (entity, key, value, meta) => {
4237
- await entity.write("closuresDoorLock", { 16389: { value: value === true ? 1 : 0, type: 0x10 } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4238
- return { state: { relock_enabled: value } };
4239
- },
4240
- convertGet: async (entity, key, meta) => {
4241
- await entity.read("closuresDoorLock", [0x4005], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4242
- },
4243
- };
4244
- exports.schneider_dimmer_mode = {
4245
- key: ["dimmer_mode"],
4246
- convertSet: async (entity, key, value, meta) => {
4247
- const lookup = { RC: 1, RL: 2 };
4248
- const mode = utils.getFromLookup(value, lookup);
4249
- await entity.write("lightingBallastCfg", { 57344: { value: mode, type: 0x30 } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC });
4250
- return { state: { dimmer_mode: value } };
4251
- },
4252
- convertGet: async (entity, key, meta) => {
4253
- await entity.read("lightingBallastCfg", [0xe000], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC });
4254
- },
4255
- };
4256
- exports.wiser_dimmer_mode = {
4257
- key: ["dimmer_mode"],
4258
- convertSet: async (entity, key, value, meta) => {
4259
- await entity.write("lightingBallastCfg", { wiserControlMode: utils.getKey(constants.wiserDimmerControlMode, value, value, Number) }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC });
4260
- return { state: { dimmer_mode: value } };
4261
- },
4262
- convertGet: async (entity, key, meta) => {
4263
- await entity.read("lightingBallastCfg", ["wiserControlMode"], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SCHNEIDER_ELECTRIC });
2326
+ const yScaled = utils.mapNumberRange(colorXY.y, 0, 1, 0, 65535);
2327
+ extensionfieldsets.push({
2328
+ clstId: 768,
2329
+ len: 4,
2330
+ extField: [xScaled, yScaled],
2331
+ });
2332
+ }
2333
+ state.color_mode = constants.colorModeLookup[0];
2334
+ state.color = newColor.hsv.toObject(false, false);
2335
+ }
2336
+ }
2337
+ }
2338
+ /*
2339
+ * Remove scene first
2340
+ *
2341
+ * Multiple add scene calls will result in the current and previous
2342
+ * payloads to be merged. Resulting in unexpected behavior when
2343
+ * trying to replace a scene.
2344
+ *
2345
+ * We accept a SUCCESS or NOT_FOUND as a result of the remove call.
2346
+ */
2347
+ const removeresp = await entity.command("genScenes", "remove", { groupid, sceneid }, utils.getOptions(meta.mapped, entity));
2348
+ if (isGroup || (utils.isObject(removeresp) && (removeresp.status === 0 || removeresp.status === 133 || removeresp.status === 139))) {
2349
+ const addSceneCommand = Number.isInteger(transtime) ? "add" : "enhancedAdd";
2350
+ const commandTransitionTime = addSceneCommand === "enhancedAdd" ? Math.floor(transtime * 10) : transtime;
2351
+ const response = await entity.command("genScenes", addSceneCommand, { groupid, sceneid, scenename: "", transtime: commandTransitionTime, extensionfieldsets }, utils.getOptions(meta.mapped, entity));
2352
+ if (isGroup) {
2353
+ if (meta.membersState) {
2354
+ for (const member of entity.members) {
2355
+ utils.saveSceneState(member, sceneid, groupid, state, scenename);
2356
+ }
2357
+ }
2358
+ }
2359
+ else {
2360
+ utils.assertObject(response);
2361
+ if (response.status === 0) {
2362
+ utils.saveSceneState(entity, sceneid, groupid, state, scenename);
2363
+ }
2364
+ else {
2365
+ throw new Error(`Scene add not successful ('${zigbee_herdsman_1.Zcl.Status[response.status]}')`);
2366
+ }
2367
+ }
2368
+ }
2369
+ else {
2370
+ const status = utils.isObject(removeresp) ? zigbee_herdsman_1.Zcl.Status[removeresp.status] : "unknown";
2371
+ throw new Error(`Scene add unable to remove existing scene ('${status}')`);
2372
+ }
2373
+ logger_1.logger.info("Successfully added scene", NS);
2374
+ return { state: {} };
4264
2375
  },
4265
2376
  };
4266
- exports.schneider_temperature_measured_value = {
4267
- key: ["temperature_measured_value"],
2377
+ exports.scene_remove = {
2378
+ key: ["scene_remove"],
4268
2379
  convertSet: async (entity, key, value, meta) => {
2380
+ const isGroup = utils.isGroup(entity);
4269
2381
  utils.assertNumber(value);
4270
- utils.assertEndpoint(entity);
4271
- await entity.report("msTemperatureMeasurement", { measuredValue: Math.round(value * 100) });
4272
- },
4273
- };
4274
- exports.schneider_thermostat_system_mode = {
4275
- key: ["system_mode"],
4276
- convertSet: (entity, key, value, meta) => {
4277
- utils.assertEndpoint(entity);
4278
- const systemMode = utils.getKey(constants.thermostatSystemModes, value, undefined, Number);
4279
- entity.saveClusterAttributeKeyValue("hvacThermostat", { systemMode: systemMode });
4280
- return { state: { system_mode: value } };
4281
- },
4282
- };
4283
- exports.schneider_thermostat_occupied_heating_setpoint = {
4284
- key: ["occupied_heating_setpoint"],
4285
- convertSet: (entity, key, value, meta) => {
4286
- utils.assertNumber(value, key);
4287
- utils.assertEndpoint(entity);
4288
- const occupiedHeatingSetpoint = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
4289
- entity.saveClusterAttributeKeyValue("hvacThermostat", { occupiedHeatingSetpoint: occupiedHeatingSetpoint });
4290
- return { state: { occupied_heating_setpoint: value } };
4291
- },
4292
- };
4293
- exports.schneider_thermostat_control_sequence_of_operation = {
4294
- key: ["control_sequence_of_operation"],
4295
- convertSet: (entity, key, value, meta) => {
4296
- utils.assertEndpoint(entity);
4297
- const val = utils.getKey(constants.thermostatControlSequenceOfOperations, value, value, Number);
4298
- entity.saveClusterAttributeKeyValue("hvacThermostat", { ctrlSeqeOfOper: val });
4299
- return { state: { control_sequence_of_operation: value } };
4300
- },
4301
- };
4302
- exports.schneider_thermostat_pi_heating_demand = {
4303
- key: ["pi_heating_demand"],
4304
- convertSet: (entity, key, value, meta) => {
4305
- utils.assertEndpoint(entity);
4306
- entity.saveClusterAttributeKeyValue("hvacThermostat", { pIHeatingDemand: value });
4307
- return { state: { pi_heating_demand: value } };
4308
- },
4309
- };
4310
- exports.schneider_thermostat_keypad_lockout = {
4311
- key: ["keypad_lockout"],
4312
- convertSet: async (entity, key, value, meta) => {
4313
- utils.assertEndpoint(entity);
4314
- const keypadLockout = utils.getKey(constants.keypadLockoutMode, value, value, Number);
4315
- await entity.write("hvacUserInterfaceCfg", { keypadLockout });
4316
- entity.saveClusterAttributeKeyValue("hvacUserInterfaceCfg", { keypadLockout });
4317
- return { state: { keypad_lockout: value } };
4318
- },
4319
- };
4320
- exports.wiser_fip_setting = {
4321
- key: ["fip_setting"],
4322
- convertSet: async (entity, key, value, meta) => {
4323
- utils.assertString(value, key);
4324
- const zoneLookup = { manual: 1, schedule: 2, energy_saver: 3, holiday: 6 };
4325
- const zonemodeNum = utils.getFromLookup(meta.state.zone_mode, zoneLookup);
4326
- const fipLookup = { comfort: 0, "comfort_-1": 1, "comfort_-2": 2, energy_saving: 3, frost_protection: 4, off: 5 };
4327
- value = value.toLowerCase();
4328
- utils.validateValue(value, Object.keys(fipLookup));
4329
- const fipmodeNum = utils.getFromLookup(value, fipLookup);
4330
- const payload = {
4331
- zonemode: zonemodeNum,
4332
- fipmode: fipmodeNum,
4333
- reserved: 0xff,
4334
- };
4335
- await entity.command("hvacThermostat", "wiserSmartSetFipMode", payload, { srcEndpoint: 11, disableDefaultResponse: true });
4336
- return { state: { fip_setting: value } };
4337
- },
4338
- convertGet: async (entity, key, meta) => {
4339
- await entity.read("hvacThermostat", [0xe020]);
4340
- },
4341
- };
4342
- exports.wiser_hact_config = {
4343
- key: ["hact_config"],
4344
- convertSet: async (entity, key, value, meta) => {
4345
- utils.assertString(value, key);
4346
- const lookup = { unconfigured: 0x00, setpoint_switch: 0x80, setpoint_fip: 0x82, fip_fip: 0x83 };
4347
- value = value.toLowerCase();
4348
- const mode = utils.getFromLookup(value, lookup);
4349
- await entity.write("hvacThermostat", { 57361: { value: mode, type: 0x18 } });
4350
- return { state: { hact_config: value } };
4351
- },
4352
- convertGet: async (entity, key, meta) => {
4353
- await entity.read("hvacThermostat", [0xe011]);
4354
- },
4355
- };
4356
- exports.wiser_zone_mode = {
4357
- key: ["zone_mode"],
4358
- convertSet: async (entity, key, value, meta) => {
4359
- const lookup = { manual: 1, schedule: 2, energy_saver: 3, holiday: 6 };
4360
- const zonemodeNum = utils.getFromLookup(value, lookup);
4361
- await entity.write("hvacThermostat", { 57360: { value: zonemodeNum, type: 0x30 } });
4362
- return { state: { zone_mode: value } };
4363
- },
4364
- convertGet: async (entity, key, meta) => {
4365
- await entity.read("hvacThermostat", [0xe010]);
2382
+ const groupid = isGroup ? entity.groupID : 0;
2383
+ const sceneid = value;
2384
+ const response = await entity.command("genScenes", "remove", { groupid, sceneid }, utils.getOptions(meta.mapped, entity));
2385
+ if (isGroup) {
2386
+ if (meta.membersState) {
2387
+ for (const member of entity.members) {
2388
+ utils.deleteSceneState(member, sceneid, groupid);
2389
+ }
2390
+ }
2391
+ }
2392
+ else if (response.status === 0) {
2393
+ utils.deleteSceneState(entity, sceneid, groupid);
2394
+ }
2395
+ else {
2396
+ throw new Error(`Scene remove not successful ('${zigbee_herdsman_1.Zcl.Status[response.status]}')`);
2397
+ }
2398
+ logger_1.logger.info("Successfully removed scene", NS);
4366
2399
  },
4367
2400
  };
4368
- exports.wiser_vact_calibrate_valve = {
4369
- key: ["calibrate_valve"],
2401
+ exports.scene_remove_all = {
2402
+ key: ["scene_remove_all"],
4370
2403
  convertSet: async (entity, key, value, meta) => {
4371
- await entity.command("hvacThermostat", "wiserSmartCalibrateValve", {}, { srcEndpoint: 11, disableDefaultResponse: true });
4372
- return { state: { calibrate_valve: value } };
4373
- },
4374
- };
4375
- exports.wiser_sed_zone_mode = {
4376
- key: ["zone_mode"],
4377
- convertSet: (entity, key, value, meta) => {
4378
- return { state: { zone_mode: value } };
2404
+ const groupid = utils.isGroup(entity) ? entity.groupID : 0;
2405
+ // In case `entity` is a group, the response is `undefined`, mock it.
2406
+ const response = (await entity.command("genScenes", "removeAll", { groupid }, utils.getOptions(meta.mapped, entity))) ?? { status: 0 };
2407
+ utils.assertObject(response);
2408
+ if (utils.isGroup(entity)) {
2409
+ if (meta.membersState) {
2410
+ for (const member of entity.members) {
2411
+ utils.deleteSceneState(member);
2412
+ }
2413
+ }
2414
+ }
2415
+ else if (response.status === 0) {
2416
+ utils.deleteSceneState(entity);
2417
+ }
2418
+ else {
2419
+ throw new Error(`Scene remove all not successful ('${zigbee_herdsman_1.Zcl.Status[response.status]}')`);
2420
+ }
2421
+ logger_1.logger.info("Successfully removed all scenes", NS);
4379
2422
  },
4380
2423
  };
4381
- exports.wiser_sed_occupied_heating_setpoint = {
4382
- key: ["occupied_heating_setpoint"],
2424
+ exports.scene_rename = {
2425
+ key: ["scene_rename"],
4383
2426
  convertSet: (entity, key, value, meta) => {
4384
- utils.assertNumber(value, key);
4385
- utils.assertEndpoint(entity);
4386
- const occupiedHeatingSetpoint = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
4387
- entity.saveClusterAttributeKeyValue("hvacThermostat", { occupiedHeatingSetpoint });
4388
- return { state: { occupied_heating_setpoint: value } };
4389
- },
4390
- };
4391
- exports.wiser_sed_thermostat_local_temperature_calibration = {
4392
- key: ["local_temperature_calibration"],
4393
- convertSet: async (entity, key, value, meta) => {
4394
- utils.assertNumber(value);
4395
- await entity.write("hvacThermostat", { localTemperatureCalibration: Math.round(value * 10) }, { srcEndpoint: 11, disableDefaultResponse: true });
4396
- return { state: { local_temperature_calibration: value } };
4397
- },
4398
- };
4399
- exports.wiser_sed_thermostat_keypad_lockout = {
4400
- key: ["keypad_lockout"],
4401
- convertSet: async (entity, key, value, meta) => {
4402
- await entity.write("hvacUserInterfaceCfg", { keypadLockout: utils.getKey(constants.keypadLockoutMode, value, value, Number) }, { srcEndpoint: 11, disableDefaultResponse: true });
4403
- return { state: { keypad_lockout: value } };
4404
- },
4405
- };
4406
- exports.sihas_set_people = {
4407
- key: ["people"],
4408
- convertSet: async (entity, key, value, meta) => {
4409
- const endpoint = meta.device.endpoints.find((e) => e.supportsInputCluster("genAnalogInput"));
4410
- await endpoint.write("genAnalogInput", { presentValue: value });
4411
- },
4412
- convertGet: async (entity, key, meta) => {
4413
- const endpoint = meta.device.endpoints.find((e) => e.supportsInputCluster("genAnalogInput"));
4414
- await endpoint.read("genAnalogInput", ["presentValue"]);
2427
+ utils.assertObject(value);
2428
+ const isGroup = utils.isGroup(entity);
2429
+ const sceneid = value.ID;
2430
+ const scenename = value.name;
2431
+ const groupid = isGroup ? entity.groupID : value.group_id != null ? value.group_id : 0;
2432
+ if (isGroup) {
2433
+ if (meta.membersState) {
2434
+ for (const member of entity.members) {
2435
+ const state = utils.getSceneState(member, sceneid, groupid);
2436
+ if (state) {
2437
+ utils.saveSceneState(member, sceneid, groupid, state, scenename);
2438
+ }
2439
+ }
2440
+ }
2441
+ }
2442
+ else {
2443
+ const state = utils.getSceneState(entity, sceneid, groupid);
2444
+ if (!state) {
2445
+ throw new Error("No such scene in device meta data");
2446
+ }
2447
+ utils.saveSceneState(entity, sceneid, groupid, state, scenename);
2448
+ }
2449
+ logger_1.logger.info("Successfully renamed scene", NS);
4415
2450
  },
4416
2451
  };
4417
- exports.tuya_operation_mode = {
4418
- key: ["operation_mode"],
2452
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2453
+ exports.TS0003_curtain_switch = {
2454
+ key: ["state"],
4419
2455
  convertSet: async (entity, key, value, meta) => {
4420
- // modes:
4421
- // 0 - 'command' mode. keys send commands. useful for group control
4422
- // 1 - 'event' mode. keys send events. useful for handling
4423
2456
  utils.assertString(value, key);
4424
- const endpoint = meta.device.getEndpoint(1);
4425
- await endpoint.write("genOnOff", { tuyaOperationMode: utils.getFromLookup(value, { command: 0, event: 1 }) });
4426
- return { state: { operation_mode: value.toLowerCase() } };
4427
- },
4428
- convertGet: async (entity, key, meta) => {
4429
- const endpoint = meta.device.getEndpoint(1);
4430
- await endpoint.read("genOnOff", ["tuyaOperationMode"]);
4431
- },
4432
- };
4433
- exports.led_on_motion = {
4434
- key: ["led_on_motion"],
4435
- convertSet: async (entity, key, value, meta) => {
4436
- await entity.write("ssIasZone", { 16384: { value: value === true ? 1 : 0, type: 0x10 } }, { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4437
- return { state: { led_on_motion: value } };
2457
+ utils.assertEndpoint(entity);
2458
+ const lookup = { close: 1, stop: 2, open: 1 };
2459
+ value = value.toLowerCase();
2460
+ utils.validateValue(value, Object.keys(lookup));
2461
+ const endpointID = utils.getFromLookup(value, lookup);
2462
+ const endpoint = entity.getDevice().getEndpoint(endpointID);
2463
+ await endpoint.command("genOnOff", "on", {}, utils.getOptions(meta.mapped, entity));
4438
2464
  },
4439
2465
  convertGet: async (entity, key, meta) => {
4440
- await entity.read("ssIasZone", [0x4000], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
2466
+ await entity.read("genOnOff", ["onOff"]);
4441
2467
  },
4442
2468
  };
4443
2469
  // #endregion
@@ -4451,127 +2477,4 @@ exports.ignore_rate = {
4451
2477
  convertSet: async (entity, key, value, meta) => { },
4452
2478
  };
4453
2479
  // #endregion
4454
- exports.light_onoff_restorable_brightness = {
4455
- /**
4456
- * Some devices reset brightness to 100% when turned on, even if previous brightness was different
4457
- * This uses the stored state of the device to restore to the previous brightness level when turning on
4458
- */
4459
- key: ["state", "brightness", "brightness_percent"],
4460
- options: [exposes.options.transition()],
4461
- convertSet: async (entity, key, value, meta) => {
4462
- const deviceState = meta.state || {};
4463
- const message = meta.message;
4464
- const state = utils.isString(message.state) ? message.state.toLowerCase() : null;
4465
- const hasBrightness = message.brightness != null || message.brightness_percent != null;
4466
- // Add brightness if command is 'on' and we can restore previous value
4467
- if (state === "on" && !hasBrightness && utils.isNumber(deviceState.brightness) && deviceState.brightness > 0) {
4468
- message.brightness = deviceState.brightness;
4469
- }
4470
- return await exports.light_onoff_brightness.convertSet(entity, key, value, meta);
4471
- },
4472
- convertGet: async (entity, key, meta) => {
4473
- return await exports.light_onoff_brightness.convertGet(entity, key, meta);
4474
- },
4475
- };
4476
- exports.ptvo_switch_light_brightness = {
4477
- key: ["brightness", "brightness_percent", "transition"],
4478
- options: [exposes.options.transition()],
4479
- convertSet: async (entity, key, value, meta) => {
4480
- if (key === "transition") {
4481
- return;
4482
- }
4483
- const cluster = "genLevelCtrl";
4484
- utils.assertEndpoint(entity);
4485
- if (entity.supportsInputCluster(cluster) || entity.supportsOutputCluster(cluster)) {
4486
- const message = meta.message;
4487
- let brightness;
4488
- if (message.brightness != null) {
4489
- brightness = Number(message.brightness);
4490
- }
4491
- else if (message.brightness_percent != null)
4492
- brightness = Math.round(Number(message.brightness_percent) * 2.55);
4493
- if (brightness !== undefined && brightness === 0) {
4494
- message.state = "off";
4495
- message.brightness = 1;
4496
- }
4497
- return await exports.light_onoff_brightness.convertSet(entity, key, value, meta);
4498
- }
4499
- throw new Error("LevelControl not supported on this endpoint.");
4500
- },
4501
- convertGet: async (entity, key, meta) => {
4502
- const cluster = "genLevelCtrl";
4503
- utils.assertEndpoint(entity);
4504
- if (entity.supportsInputCluster(cluster) || entity.supportsOutputCluster(cluster)) {
4505
- return await exports.light_onoff_brightness.convertGet(entity, key, meta);
4506
- }
4507
- throw new Error("LevelControl not supported on this endpoint.");
4508
- },
4509
- };
4510
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4511
- exports.TS110E_options = {
4512
- key: ["min_brightness", "max_brightness", "light_type", "switch_type"],
4513
- convertSet: async (entity, key, value, meta) => {
4514
- let payload = null;
4515
- if (key === "min_brightness" || key === "max_brightness") {
4516
- const id = key === "min_brightness" ? 64515 : 64516;
4517
- payload = { [id]: { value: utils.mapNumberRange(utils.toNumber(value, key), 1, 255, 0, 1000), type: 0x21 } };
4518
- }
4519
- else if (key === "light_type" || key === "switch_type") {
4520
- utils.assertString(value, "light_type/switch_type");
4521
- const lookup = key === "light_type" ? { led: 0, incandescent: 1, halogen: 2 } : { momentary: 0, toggle: 1, state: 2 };
4522
- payload = { 64514: { value: lookup[value], type: 0x20 } };
4523
- }
4524
- await entity.write("genLevelCtrl", payload, utils.getOptions(meta.mapped, entity));
4525
- return { state: { [key]: value } };
4526
- },
4527
- convertGet: async (entity, key, meta) => {
4528
- let id = null;
4529
- if (key === "min_brightness")
4530
- id = 64515;
4531
- if (key === "max_brightness")
4532
- id = 64516;
4533
- if (key === "light_type" || key === "switch_type")
4534
- id = 64514;
4535
- await entity.read("genLevelCtrl", [id]);
4536
- },
4537
- };
4538
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4539
- exports.TS110E_onoff_brightness = {
4540
- key: ["state", "brightness"],
4541
- convertSet: async (entity, key, value, meta) => {
4542
- const { message, state } = meta;
4543
- if (message.state === "OFF" || (message.state != null && message.brightness == null)) {
4544
- return await exports.on_off.convertSet(entity, key, value, meta);
4545
- }
4546
- if (message.brightness != null) {
4547
- // set brightness
4548
- if (state.state === "OFF") {
4549
- await entity.command("genOnOff", "on", {}, utils.getOptions(meta.mapped, entity));
4550
- }
4551
- const brightness = utils.toNumber(message.brightness, "brightness");
4552
- const level = utils.mapNumberRange(brightness, 0, 254, 0, 1000);
4553
- await entity.command("genLevelCtrl", "moveToLevelTuya", { level, transtime: 100 }, utils.getOptions(meta.mapped, entity));
4554
- return { state: { state: "ON", brightness } };
4555
- }
4556
- },
4557
- convertGet: async (entity, key, meta) => {
4558
- if (key === "state")
4559
- await exports.on_off.convertGet(entity, key, meta);
4560
- if (key === "brightness")
4561
- await entity.read("genLevelCtrl", [61440]);
4562
- },
4563
- };
4564
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4565
- exports.TS110E_light_onoff_brightness = {
4566
- ...exports.light_onoff_brightness,
4567
- convertSet: async (entity, key, value, meta) => {
4568
- const { message } = meta;
4569
- if (message.state === "ON" || (typeof message.brightness === "number" && message.brightness > 1)) {
4570
- // Does not turn off with physical press when turned on with just moveToLevelWithOnOff, required on before.
4571
- // https://github.com/Koenkk/zigbee2mqtt/issues/15902#issuecomment-1382848150
4572
- await entity.command("genOnOff", "on", {}, utils.getOptions(meta.mapped, entity));
4573
- }
4574
- return await exports.light_onoff_brightness.convertSet(entity, key, value, meta);
4575
- },
4576
- };
4577
2480
  //# sourceMappingURL=toZigbee.js.map