@willieee802/zigbee-herdsman-converters 19.44.0 → 19.44.2

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 (1609) hide show
  1. package/dist/converters/actions.d.ts +36 -0
  2. package/dist/converters/actions.d.ts.map +1 -0
  3. package/dist/converters/actions.js +137 -0
  4. package/dist/converters/actions.js.map +1 -0
  5. package/dist/converters/fromZigbee.d.ts +293 -0
  6. package/dist/converters/fromZigbee.d.ts.map +1 -0
  7. package/dist/converters/fromZigbee.js +5192 -0
  8. package/dist/converters/fromZigbee.js.map +1 -0
  9. package/dist/converters/toZigbee.d.ts +235 -0
  10. package/dist/converters/toZigbee.d.ts.map +1 -0
  11. package/dist/converters/toZigbee.js +4577 -0
  12. package/dist/converters/toZigbee.js.map +1 -0
  13. package/dist/devices/ITCommander.d.ts +3 -0
  14. package/dist/devices/ITCommander.d.ts.map +1 -0
  15. package/dist/devices/ITCommander.js +73 -0
  16. package/dist/devices/ITCommander.js.map +1 -0
  17. package/dist/devices/acova.d.ts +3 -0
  18. package/dist/devices/acova.d.ts.map +1 -0
  19. package/dist/devices/acova.js +124 -0
  20. package/dist/devices/acova.js.map +1 -0
  21. package/dist/devices/acuity_brands_lighting.d.ts +3 -0
  22. package/dist/devices/acuity_brands_lighting.d.ts.map +1 -0
  23. package/dist/devices/acuity_brands_lighting.js +61 -0
  24. package/dist/devices/acuity_brands_lighting.js.map +1 -0
  25. package/dist/devices/adeo.d.ts +3 -0
  26. package/dist/devices/adeo.d.ts.map +1 -0
  27. package/dist/devices/adeo.js +518 -0
  28. package/dist/devices/adeo.js.map +1 -0
  29. package/dist/devices/adurosmart.d.ts +3 -0
  30. package/dist/devices/adurosmart.d.ts.map +1 -0
  31. package/dist/devices/adurosmart.js +235 -0
  32. package/dist/devices/adurosmart.js.map +1 -0
  33. package/dist/devices/aeotec.d.ts +3 -0
  34. package/dist/devices/aeotec.d.ts.map +1 -0
  35. package/dist/devices/aeotec.js +95 -0
  36. package/dist/devices/aeotec.js.map +1 -0
  37. package/dist/devices/airam.d.ts +3 -0
  38. package/dist/devices/airam.d.ts.map +1 -0
  39. package/dist/devices/airam.js +102 -0
  40. package/dist/devices/airam.js.map +1 -0
  41. package/dist/devices/airzone_aidoo.d.ts +3 -0
  42. package/dist/devices/airzone_aidoo.d.ts.map +1 -0
  43. package/dist/devices/airzone_aidoo.js +77 -0
  44. package/dist/devices/airzone_aidoo.js.map +1 -0
  45. package/dist/devices/ajax_online.d.ts +3 -0
  46. package/dist/devices/ajax_online.d.ts.map +1 -0
  47. package/dist/devices/ajax_online.js +83 -0
  48. package/dist/devices/ajax_online.js.map +1 -0
  49. package/dist/devices/akuvox.d.ts +3 -0
  50. package/dist/devices/akuvox.d.ts.map +1 -0
  51. package/dist/devices/akuvox.js +65 -0
  52. package/dist/devices/akuvox.js.map +1 -0
  53. package/dist/devices/alchemy.d.ts +3 -0
  54. package/dist/devices/alchemy.d.ts.map +1 -0
  55. package/dist/devices/alchemy.js +54 -0
  56. package/dist/devices/alchemy.js.map +1 -0
  57. package/dist/devices/aldi.d.ts +3 -0
  58. package/dist/devices/aldi.d.ts.map +1 -0
  59. package/dist/devices/aldi.js +54 -0
  60. package/dist/devices/aldi.js.map +1 -0
  61. package/dist/devices/alecto.d.ts +3 -0
  62. package/dist/devices/alecto.d.ts.map +1 -0
  63. package/dist/devices/alecto.js +91 -0
  64. package/dist/devices/alecto.js.map +1 -0
  65. package/dist/devices/amina.d.ts +3 -0
  66. package/dist/devices/amina.d.ts.map +1 -0
  67. package/dist/devices/amina.js +360 -0
  68. package/dist/devices/amina.js.map +1 -0
  69. package/dist/devices/anchor.d.ts +3 -0
  70. package/dist/devices/anchor.d.ts.map +1 -0
  71. package/dist/devices/anchor.js +47 -0
  72. package/dist/devices/anchor.js.map +1 -0
  73. package/dist/devices/atlantic.d.ts +3 -0
  74. package/dist/devices/atlantic.d.ts.map +1 -0
  75. package/dist/devices/atlantic.js +147 -0
  76. package/dist/devices/atlantic.js.map +1 -0
  77. package/dist/devices/atsmart.d.ts +3 -0
  78. package/dist/devices/atsmart.d.ts.map +1 -0
  79. package/dist/devices/atsmart.js +47 -0
  80. package/dist/devices/atsmart.js.map +1 -0
  81. package/dist/devices/aubess.d.ts +3 -0
  82. package/dist/devices/aubess.d.ts.map +1 -0
  83. package/dist/devices/aubess.js +60 -0
  84. package/dist/devices/aubess.js.map +1 -0
  85. package/dist/devices/aurora_lighting.d.ts +3 -0
  86. package/dist/devices/aurora_lighting.d.ts.map +1 -0
  87. package/dist/devices/aurora_lighting.js +347 -0
  88. package/dist/devices/aurora_lighting.js.map +1 -0
  89. package/dist/devices/automaton.d.ts +3 -0
  90. package/dist/devices/automaton.d.ts.map +1 -0
  91. package/dist/devices/automaton.js +64 -0
  92. package/dist/devices/automaton.js.map +1 -0
  93. package/dist/devices/avatto.d.ts +3 -0
  94. package/dist/devices/avatto.d.ts.map +1 -0
  95. package/dist/devices/avatto.js +635 -0
  96. package/dist/devices/avatto.js.map +1 -0
  97. package/dist/devices/awox.d.ts +3 -0
  98. package/dist/devices/awox.d.ts.map +1 -0
  99. package/dist/devices/awox.js +352 -0
  100. package/dist/devices/awox.js.map +1 -0
  101. package/dist/devices/axis.d.ts +3 -0
  102. package/dist/devices/axis.d.ts.map +1 -0
  103. package/dist/devices/axis.js +59 -0
  104. package/dist/devices/axis.js.map +1 -0
  105. package/dist/devices/bacchus.d.ts +3 -0
  106. package/dist/devices/bacchus.d.ts.map +1 -0
  107. package/dist/devices/bacchus.js +902 -0
  108. package/dist/devices/bacchus.js.map +1 -0
  109. package/dist/devices/bankamp.d.ts +3 -0
  110. package/dist/devices/bankamp.d.ts.map +1 -0
  111. package/dist/devices/bankamp.js +47 -0
  112. package/dist/devices/bankamp.js.map +1 -0
  113. package/dist/devices/bega.d.ts +3 -0
  114. package/dist/devices/bega.d.ts.map +1 -0
  115. package/dist/devices/bega.js +68 -0
  116. package/dist/devices/bega.js.map +1 -0
  117. package/dist/devices/belkin.d.ts +3 -0
  118. package/dist/devices/belkin.d.ts.map +1 -0
  119. package/dist/devices/belkin.js +47 -0
  120. package/dist/devices/belkin.js.map +1 -0
  121. package/dist/devices/bitron.d.ts +3 -0
  122. package/dist/devices/bitron.d.ts.map +1 -0
  123. package/dist/devices/bitron.js +357 -0
  124. package/dist/devices/bitron.js.map +1 -0
  125. package/dist/devices/bituo_technik.d.ts +3 -0
  126. package/dist/devices/bituo_technik.d.ts.map +1 -0
  127. package/dist/devices/bituo_technik.js +487 -0
  128. package/dist/devices/bituo_technik.js.map +1 -0
  129. package/dist/devices/blaupunkt.d.ts +3 -0
  130. package/dist/devices/blaupunkt.d.ts.map +1 -0
  131. package/dist/devices/blaupunkt.js +64 -0
  132. package/dist/devices/blaupunkt.js.map +1 -0
  133. package/dist/devices/blitzwolf.d.ts +3 -0
  134. package/dist/devices/blitzwolf.d.ts.map +1 -0
  135. package/dist/devices/blitzwolf.js +77 -0
  136. package/dist/devices/blitzwolf.js.map +1 -0
  137. package/dist/devices/bosch.d.ts +3 -0
  138. package/dist/devices/bosch.d.ts.map +1 -0
  139. package/dist/devices/bosch.js +1381 -0
  140. package/dist/devices/bosch.js.map +1 -0
  141. package/dist/devices/bouffalo_lab.d.ts +3 -0
  142. package/dist/devices/bouffalo_lab.d.ts.map +1 -0
  143. package/dist/devices/bouffalo_lab.js +47 -0
  144. package/dist/devices/bouffalo_lab.js.map +1 -0
  145. package/dist/devices/box.d.ts +3 -0
  146. package/dist/devices/box.d.ts.map +1 -0
  147. package/dist/devices/box.js +370 -0
  148. package/dist/devices/box.js.map +1 -0
  149. package/dist/devices/brimate.d.ts +3 -0
  150. package/dist/devices/brimate.d.ts.map +1 -0
  151. package/dist/devices/brimate.js +51 -0
  152. package/dist/devices/brimate.js.map +1 -0
  153. package/dist/devices/brun_holding.d.ts +3 -0
  154. package/dist/devices/brun_holding.d.ts.map +1 -0
  155. package/dist/devices/brun_holding.js +59 -0
  156. package/dist/devices/brun_holding.js.map +1 -0
  157. package/dist/devices/bseed.d.ts +3 -0
  158. package/dist/devices/bseed.d.ts.map +1 -0
  159. package/dist/devices/bseed.js +53 -0
  160. package/dist/devices/bseed.js.map +1 -0
  161. package/dist/devices/bticino.d.ts +3 -0
  162. package/dist/devices/bticino.d.ts.map +1 -0
  163. package/dist/devices/bticino.js +111 -0
  164. package/dist/devices/bticino.js.map +1 -0
  165. package/dist/devices/bubendorff.d.ts +3 -0
  166. package/dist/devices/bubendorff.d.ts.map +1 -0
  167. package/dist/devices/bubendorff.js +47 -0
  168. package/dist/devices/bubendorff.js.map +1 -0
  169. package/dist/devices/busch_jaeger.d.ts +3 -0
  170. package/dist/devices/busch_jaeger.d.ts.map +1 -0
  171. package/dist/devices/busch_jaeger.js +163 -0
  172. package/dist/devices/busch_jaeger.js.map +1 -0
  173. package/dist/devices/byun.d.ts +3 -0
  174. package/dist/devices/byun.d.ts.map +1 -0
  175. package/dist/devices/byun.js +60 -0
  176. package/dist/devices/byun.js.map +1 -0
  177. package/dist/devices/calex.d.ts +3 -0
  178. package/dist/devices/calex.d.ts.map +1 -0
  179. package/dist/devices/calex.js +87 -0
  180. package/dist/devices/calex.js.map +1 -0
  181. package/dist/devices/candeo.d.ts +3 -0
  182. package/dist/devices/candeo.d.ts.map +1 -0
  183. package/dist/devices/candeo.js +887 -0
  184. package/dist/devices/candeo.js.map +1 -0
  185. package/dist/devices/casaia.d.ts +3 -0
  186. package/dist/devices/casaia.d.ts.map +1 -0
  187. package/dist/devices/casaia.js +95 -0
  188. package/dist/devices/casaia.js.map +1 -0
  189. package/dist/devices/cel.d.ts +3 -0
  190. package/dist/devices/cel.d.ts.map +1 -0
  191. package/dist/devices/cel.js +49 -0
  192. package/dist/devices/cel.js.map +1 -0
  193. package/dist/devices/centralite.d.ts +28 -0
  194. package/dist/devices/centralite.d.ts.map +1 -0
  195. package/dist/devices/centralite.js +440 -0
  196. package/dist/devices/centralite.js.map +1 -0
  197. package/dist/devices/chacon.d.ts +3 -0
  198. package/dist/devices/chacon.d.ts.map +1 -0
  199. package/dist/devices/chacon.js +57 -0
  200. package/dist/devices/chacon.js.map +1 -0
  201. package/dist/devices/cleode.d.ts +3 -0
  202. package/dist/devices/cleode.d.ts.map +1 -0
  203. package/dist/devices/cleode.js +47 -0
  204. package/dist/devices/cleode.js.map +1 -0
  205. package/dist/devices/cleverio.d.ts +3 -0
  206. package/dist/devices/cleverio.d.ts.map +1 -0
  207. package/dist/devices/cleverio.js +74 -0
  208. package/dist/devices/cleverio.js.map +1 -0
  209. package/dist/devices/climax.d.ts +3 -0
  210. package/dist/devices/climax.d.ts.map +1 -0
  211. package/dist/devices/climax.js +184 -0
  212. package/dist/devices/climax.js.map +1 -0
  213. package/dist/devices/commercial_electric.d.ts +3 -0
  214. package/dist/devices/commercial_electric.d.ts.map +1 -0
  215. package/dist/devices/commercial_electric.js +47 -0
  216. package/dist/devices/commercial_electric.js.map +1 -0
  217. package/dist/devices/cree.d.ts +3 -0
  218. package/dist/devices/cree.d.ts.map +1 -0
  219. package/dist/devices/cree.js +47 -0
  220. package/dist/devices/cree.js.map +1 -0
  221. package/dist/devices/ctm.d.ts +3 -0
  222. package/dist/devices/ctm.d.ts.map +1 -0
  223. package/dist/devices/ctm.js +1411 -0
  224. package/dist/devices/ctm.js.map +1 -0
  225. package/dist/devices/current_products_corp.d.ts +3 -0
  226. package/dist/devices/current_products_corp.d.ts.map +1 -0
  227. package/dist/devices/current_products_corp.js +60 -0
  228. package/dist/devices/current_products_corp.js.map +1 -0
  229. package/dist/devices/custom_devices_diy.d.ts +3 -0
  230. package/dist/devices/custom_devices_diy.d.ts.map +1 -0
  231. package/dist/devices/custom_devices_diy.js +1302 -0
  232. package/dist/devices/custom_devices_diy.js.map +1 -0
  233. package/dist/devices/cwd.d.ts +3 -0
  234. package/dist/devices/cwd.d.ts.map +1 -0
  235. package/dist/devices/cwd.js +47 -0
  236. package/dist/devices/cwd.js.map +1 -0
  237. package/dist/devices/cy_lighting.d.ts +3 -0
  238. package/dist/devices/cy_lighting.d.ts.map +1 -0
  239. package/dist/devices/cy_lighting.js +47 -0
  240. package/dist/devices/cy_lighting.js.map +1 -0
  241. package/dist/devices/danalock.d.ts +3 -0
  242. package/dist/devices/danalock.d.ts.map +1 -0
  243. package/dist/devices/danalock.js +61 -0
  244. package/dist/devices/danalock.js.map +1 -0
  245. package/dist/devices/danfoss.d.ts +3 -0
  246. package/dist/devices/danfoss.d.ts.map +1 -0
  247. package/dist/devices/danfoss.js +793 -0
  248. package/dist/devices/danfoss.js.map +1 -0
  249. package/dist/devices/databyte.d.ts +3 -0
  250. package/dist/devices/databyte.d.ts.map +1 -0
  251. package/dist/devices/databyte.js +90 -0
  252. package/dist/devices/databyte.js.map +1 -0
  253. package/dist/devices/datek.d.ts +3 -0
  254. package/dist/devices/datek.d.ts.map +1 -0
  255. package/dist/devices/datek.js +303 -0
  256. package/dist/devices/datek.js.map +1 -0
  257. package/dist/devices/dawon_dns.d.ts +3 -0
  258. package/dist/devices/dawon_dns.d.ts.map +1 -0
  259. package/dist/devices/dawon_dns.js +314 -0
  260. package/dist/devices/dawon_dns.js.map +1 -0
  261. package/dist/devices/develco.d.ts +3 -0
  262. package/dist/devices/develco.d.ts.map +1 -0
  263. package/dist/devices/develco.js +1113 -0
  264. package/dist/devices/develco.js.map +1 -0
  265. package/dist/devices/digi.d.ts +3 -0
  266. package/dist/devices/digi.d.ts.map +1 -0
  267. package/dist/devices/digi.js +24 -0
  268. package/dist/devices/digi.js.map +1 -0
  269. package/dist/devices/direct_signs.d.ts +3 -0
  270. package/dist/devices/direct_signs.d.ts.map +1 -0
  271. package/dist/devices/direct_signs.js +47 -0
  272. package/dist/devices/direct_signs.js.map +1 -0
  273. package/dist/devices/diyruz.d.ts +3 -0
  274. package/dist/devices/diyruz.d.ts.map +1 -0
  275. package/dist/devices/diyruz.js +397 -0
  276. package/dist/devices/diyruz.js.map +1 -0
  277. package/dist/devices/dlink.d.ts +3 -0
  278. package/dist/devices/dlink.d.ts.map +1 -0
  279. package/dist/devices/dlink.js +72 -0
  280. package/dist/devices/dlink.js.map +1 -0
  281. package/dist/devices/dnake.d.ts +3 -0
  282. package/dist/devices/dnake.d.ts.map +1 -0
  283. package/dist/devices/dnake.js +47 -0
  284. package/dist/devices/dnake.js.map +1 -0
  285. package/dist/devices/domraem.d.ts +3 -0
  286. package/dist/devices/domraem.d.ts.map +1 -0
  287. package/dist/devices/domraem.js +75 -0
  288. package/dist/devices/domraem.js.map +1 -0
  289. package/dist/devices/dowsing_reynolds.d.ts +3 -0
  290. package/dist/devices/dowsing_reynolds.d.ts.map +1 -0
  291. package/dist/devices/dowsing_reynolds.js +47 -0
  292. package/dist/devices/dowsing_reynolds.js.map +1 -0
  293. package/dist/devices/dqsmart.d.ts +3 -0
  294. package/dist/devices/dqsmart.d.ts.map +1 -0
  295. package/dist/devices/dqsmart.js +50 -0
  296. package/dist/devices/dqsmart.js.map +1 -0
  297. package/dist/devices/dresden_elektronik.d.ts +3 -0
  298. package/dist/devices/dresden_elektronik.d.ts.map +1 -0
  299. package/dist/devices/dresden_elektronik.js +167 -0
  300. package/dist/devices/dresden_elektronik.js.map +1 -0
  301. package/dist/devices/easyaccess.d.ts +3 -0
  302. package/dist/devices/easyaccess.d.ts.map +1 -0
  303. package/dist/devices/easyaccess.js +67 -0
  304. package/dist/devices/easyaccess.js.map +1 -0
  305. package/dist/devices/easyiot.d.ts +3 -0
  306. package/dist/devices/easyiot.d.ts.map +1 -0
  307. package/dist/devices/easyiot.js +359 -0
  308. package/dist/devices/easyiot.js.map +1 -0
  309. package/dist/devices/eatonhalo_led.d.ts +3 -0
  310. package/dist/devices/eatonhalo_led.d.ts.map +1 -0
  311. package/dist/devices/eatonhalo_led.js +47 -0
  312. package/dist/devices/eatonhalo_led.js.map +1 -0
  313. package/dist/devices/echostar.d.ts +3 -0
  314. package/dist/devices/echostar.d.ts.map +1 -0
  315. package/dist/devices/echostar.js +61 -0
  316. package/dist/devices/echostar.js.map +1 -0
  317. package/dist/devices/ecodim.d.ts +3 -0
  318. package/dist/devices/ecodim.d.ts.map +1 -0
  319. package/dist/devices/ecodim.js +274 -0
  320. package/dist/devices/ecodim.js.map +1 -0
  321. package/dist/devices/ecolink.d.ts +3 -0
  322. package/dist/devices/ecolink.d.ts.map +1 -0
  323. package/dist/devices/ecolink.js +57 -0
  324. package/dist/devices/ecolink.js.map +1 -0
  325. package/dist/devices/ecosmart.d.ts +3 -0
  326. package/dist/devices/ecosmart.d.ts.map +1 -0
  327. package/dist/devices/ecosmart.js +115 -0
  328. package/dist/devices/ecosmart.js.map +1 -0
  329. package/dist/devices/ecozy.d.ts +3 -0
  330. package/dist/devices/ecozy.d.ts.map +1 -0
  331. package/dist/devices/ecozy.js +85 -0
  332. package/dist/devices/ecozy.js.map +1 -0
  333. package/dist/devices/edp.d.ts +3 -0
  334. package/dist/devices/edp.d.ts.map +1 -0
  335. package/dist/devices/edp.js +70 -0
  336. package/dist/devices/edp.js.map +1 -0
  337. package/dist/devices/efekta.d.ts +3 -0
  338. package/dist/devices/efekta.d.ts.map +1 -0
  339. package/dist/devices/efekta.js +8230 -0
  340. package/dist/devices/efekta.js.map +1 -0
  341. package/dist/devices/eglo.d.ts +3 -0
  342. package/dist/devices/eglo.d.ts.map +1 -0
  343. package/dist/devices/eglo.js +142 -0
  344. package/dist/devices/eglo.js.map +1 -0
  345. package/dist/devices/elko.d.ts +27 -0
  346. package/dist/devices/elko.d.ts.map +1 -0
  347. package/dist/devices/elko.js +306 -0
  348. package/dist/devices/elko.js.map +1 -0
  349. package/dist/devices/enbrighten.d.ts +3 -0
  350. package/dist/devices/enbrighten.d.ts.map +1 -0
  351. package/dist/devices/enbrighten.js +152 -0
  352. package/dist/devices/enbrighten.js.map +1 -0
  353. package/dist/devices/engo.d.ts +3 -0
  354. package/dist/devices/engo.d.ts.map +1 -0
  355. package/dist/devices/engo.js +1041 -0
  356. package/dist/devices/engo.js.map +1 -0
  357. package/dist/devices/enkin.d.ts +3 -0
  358. package/dist/devices/enkin.d.ts.map +1 -0
  359. package/dist/devices/enkin.js +14 -0
  360. package/dist/devices/enkin.js.map +1 -0
  361. package/dist/devices/enocean.d.ts +3 -0
  362. package/dist/devices/enocean.d.ts.map +1 -0
  363. package/dist/devices/enocean.js +150 -0
  364. package/dist/devices/enocean.js.map +1 -0
  365. package/dist/devices/envilar.d.ts +3 -0
  366. package/dist/devices/envilar.d.ts.map +1 -0
  367. package/dist/devices/envilar.js +131 -0
  368. package/dist/devices/envilar.js.map +1 -0
  369. package/dist/devices/espressif.d.ts +3 -0
  370. package/dist/devices/espressif.d.ts.map +1 -0
  371. package/dist/devices/espressif.js +61 -0
  372. package/dist/devices/espressif.js.map +1 -0
  373. package/dist/devices/essentialb.d.ts +3 -0
  374. package/dist/devices/essentialb.d.ts.map +1 -0
  375. package/dist/devices/essentialb.js +133 -0
  376. package/dist/devices/essentialb.js.map +1 -0
  377. package/dist/devices/essentials.d.ts +3 -0
  378. package/dist/devices/essentials.d.ts.map +1 -0
  379. package/dist/devices/essentials.js +150 -0
  380. package/dist/devices/essentials.js.map +1 -0
  381. package/dist/devices/eucontrols.d.ts +3 -0
  382. package/dist/devices/eucontrols.d.ts.map +1 -0
  383. package/dist/devices/eucontrols.js +47 -0
  384. package/dist/devices/eucontrols.js.map +1 -0
  385. package/dist/devices/eurotronic.d.ts +3 -0
  386. package/dist/devices/eurotronic.d.ts.map +1 -0
  387. package/dist/devices/eurotronic.js +278 -0
  388. package/dist/devices/eurotronic.js.map +1 -0
  389. package/dist/devices/evanell.d.ts +3 -0
  390. package/dist/devices/evanell.d.ts.map +1 -0
  391. package/dist/devices/evanell.js +66 -0
  392. package/dist/devices/evanell.js.map +1 -0
  393. package/dist/devices/evn.d.ts +3 -0
  394. package/dist/devices/evn.d.ts.map +1 -0
  395. package/dist/devices/evn.js +97 -0
  396. package/dist/devices/evn.js.map +1 -0
  397. package/dist/devices/evology.d.ts +3 -0
  398. package/dist/devices/evology.d.ts.map +1 -0
  399. package/dist/devices/evology.js +60 -0
  400. package/dist/devices/evology.js.map +1 -0
  401. package/dist/devices/evvr.d.ts +3 -0
  402. package/dist/devices/evvr.d.ts.map +1 -0
  403. package/dist/devices/evvr.js +47 -0
  404. package/dist/devices/evvr.js.map +1 -0
  405. package/dist/devices/ewelink.d.ts +3 -0
  406. package/dist/devices/ewelink.d.ts.map +1 -0
  407. package/dist/devices/ewelink.js +326 -0
  408. package/dist/devices/ewelink.js.map +1 -0
  409. package/dist/devices/ezex.d.ts +3 -0
  410. package/dist/devices/ezex.d.ts.map +1 -0
  411. package/dist/devices/ezex.js +47 -0
  412. package/dist/devices/ezex.js.map +1 -0
  413. package/dist/devices/ezviz.d.ts +3 -0
  414. package/dist/devices/ezviz.d.ts.map +1 -0
  415. package/dist/devices/ezviz.js +47 -0
  416. package/dist/devices/ezviz.js.map +1 -0
  417. package/dist/devices/fantem.d.ts +3 -0
  418. package/dist/devices/fantem.d.ts.map +1 -0
  419. package/dist/devices/fantem.js +112 -0
  420. package/dist/devices/fantem.js.map +1 -0
  421. package/dist/devices/feibit.d.ts +3 -0
  422. package/dist/devices/feibit.d.ts.map +1 -0
  423. package/dist/devices/feibit.js +335 -0
  424. package/dist/devices/feibit.js.map +1 -0
  425. package/dist/devices/fireangel.d.ts +3 -0
  426. package/dist/devices/fireangel.d.ts.map +1 -0
  427. package/dist/devices/fireangel.js +96 -0
  428. package/dist/devices/fireangel.js.map +1 -0
  429. package/dist/devices/frankever.d.ts +3 -0
  430. package/dist/devices/frankever.d.ts.map +1 -0
  431. package/dist/devices/frankever.js +67 -0
  432. package/dist/devices/frankever.js.map +1 -0
  433. package/dist/devices/frient.d.ts +3 -0
  434. package/dist/devices/frient.d.ts.map +1 -0
  435. package/dist/devices/frient.js +84 -0
  436. package/dist/devices/frient.js.map +1 -0
  437. package/dist/devices/futurehome.d.ts +3 -0
  438. package/dist/devices/futurehome.d.ts.map +1 -0
  439. package/dist/devices/futurehome.js +137 -0
  440. package/dist/devices/futurehome.js.map +1 -0
  441. package/dist/devices/ge.d.ts +3 -0
  442. package/dist/devices/ge.d.ts.map +1 -0
  443. package/dist/devices/ge.js +130 -0
  444. package/dist/devices/ge.js.map +1 -0
  445. package/dist/devices/gewiss.d.ts +3 -0
  446. package/dist/devices/gewiss.d.ts.map +1 -0
  447. package/dist/devices/gewiss.js +148 -0
  448. package/dist/devices/gewiss.js.map +1 -0
  449. package/dist/devices/gidealed.d.ts +3 -0
  450. package/dist/devices/gidealed.d.ts.map +1 -0
  451. package/dist/devices/gidealed.js +47 -0
  452. package/dist/devices/gidealed.js.map +1 -0
  453. package/dist/devices/giderwel.d.ts +3 -0
  454. package/dist/devices/giderwel.d.ts.map +1 -0
  455. package/dist/devices/giderwel.js +47 -0
  456. package/dist/devices/giderwel.js.map +1 -0
  457. package/dist/devices/giex.d.ts +3 -0
  458. package/dist/devices/giex.d.ts.map +1 -0
  459. package/dist/devices/giex.js +114 -0
  460. package/dist/devices/giex.js.map +1 -0
  461. package/dist/devices/girier.d.ts +3 -0
  462. package/dist/devices/girier.d.ts.map +1 -0
  463. package/dist/devices/girier.js +51 -0
  464. package/dist/devices/girier.js.map +1 -0
  465. package/dist/devices/gledopto.d.ts +3 -0
  466. package/dist/devices/gledopto.d.ts.map +1 -0
  467. package/dist/devices/gledopto.js +1395 -0
  468. package/dist/devices/gledopto.js.map +1 -0
  469. package/dist/devices/gmmts.d.ts +3 -0
  470. package/dist/devices/gmmts.d.ts.map +1 -0
  471. package/dist/devices/gmmts.js +2267 -0
  472. package/dist/devices/gmmts.js.map +1 -0
  473. package/dist/devices/gmy.d.ts +3 -0
  474. package/dist/devices/gmy.d.ts.map +1 -0
  475. package/dist/devices/gmy.js +47 -0
  476. package/dist/devices/gmy.js.map +1 -0
  477. package/dist/devices/gs.d.ts +3 -0
  478. package/dist/devices/gs.d.ts.map +1 -0
  479. package/dist/devices/gs.js +121 -0
  480. package/dist/devices/gs.js.map +1 -0
  481. package/dist/devices/gumax.d.ts +3 -0
  482. package/dist/devices/gumax.d.ts.map +1 -0
  483. package/dist/devices/gumax.js +47 -0
  484. package/dist/devices/gumax.js.map +1 -0
  485. package/dist/devices/halemeier.d.ts +3 -0
  486. package/dist/devices/halemeier.d.ts.map +1 -0
  487. package/dist/devices/halemeier.js +142 -0
  488. package/dist/devices/halemeier.js.map +1 -0
  489. package/dist/devices/hampton_bay.d.ts +3 -0
  490. package/dist/devices/hampton_bay.d.ts.map +1 -0
  491. package/dist/devices/hampton_bay.js +68 -0
  492. package/dist/devices/hampton_bay.js.map +1 -0
  493. package/dist/devices/heatit.d.ts +3 -0
  494. package/dist/devices/heatit.d.ts.map +1 -0
  495. package/dist/devices/heatit.js +47 -0
  496. package/dist/devices/heatit.js.map +1 -0
  497. package/dist/devices/heiman.d.ts +3 -0
  498. package/dist/devices/heiman.d.ts.map +1 -0
  499. package/dist/devices/heiman.js +2092 -0
  500. package/dist/devices/heiman.js.map +1 -0
  501. package/dist/devices/heimgard_technologies.d.ts +3 -0
  502. package/dist/devices/heimgard_technologies.d.ts.map +1 -0
  503. package/dist/devices/heimgard_technologies.js +189 -0
  504. package/dist/devices/heimgard_technologies.js.map +1 -0
  505. package/dist/devices/hej.d.ts +3 -0
  506. package/dist/devices/hej.d.ts.map +1 -0
  507. package/dist/devices/hej.js +126 -0
  508. package/dist/devices/hej.js.map +1 -0
  509. package/dist/devices/hfh.d.ts +3 -0
  510. package/dist/devices/hfh.d.ts.map +1 -0
  511. package/dist/devices/hfh.js +47 -0
  512. package/dist/devices/hfh.js.map +1 -0
  513. package/dist/devices/hilux.d.ts +3 -0
  514. package/dist/devices/hilux.d.ts.map +1 -0
  515. package/dist/devices/hilux.js +54 -0
  516. package/dist/devices/hilux.js.map +1 -0
  517. package/dist/devices/hive.d.ts +3 -0
  518. package/dist/devices/hive.d.ts.map +1 -0
  519. package/dist/devices/hive.js +798 -0
  520. package/dist/devices/hive.js.map +1 -0
  521. package/dist/devices/hoftronic.d.ts +3 -0
  522. package/dist/devices/hoftronic.d.ts.map +1 -0
  523. package/dist/devices/hoftronic.js +56 -0
  524. package/dist/devices/hoftronic.js.map +1 -0
  525. package/dist/devices/homeseer.d.ts +3 -0
  526. package/dist/devices/homeseer.d.ts.map +1 -0
  527. package/dist/devices/homeseer.js +53 -0
  528. package/dist/devices/homeseer.js.map +1 -0
  529. package/dist/devices/hommyn.d.ts +3 -0
  530. package/dist/devices/hommyn.d.ts.map +1 -0
  531. package/dist/devices/hommyn.js +60 -0
  532. package/dist/devices/hommyn.js.map +1 -0
  533. package/dist/devices/honyar.d.ts +3 -0
  534. package/dist/devices/honyar.d.ts.map +1 -0
  535. package/dist/devices/honyar.js +167 -0
  536. package/dist/devices/honyar.js.map +1 -0
  537. package/dist/devices/hornbach.d.ts +3 -0
  538. package/dist/devices/hornbach.d.ts.map +1 -0
  539. package/dist/devices/hornbach.js +138 -0
  540. package/dist/devices/hornbach.js.map +1 -0
  541. package/dist/devices/hzc_electric.d.ts +3 -0
  542. package/dist/devices/hzc_electric.d.ts.map +1 -0
  543. package/dist/devices/hzc_electric.js +102 -0
  544. package/dist/devices/hzc_electric.js.map +1 -0
  545. package/dist/devices/icasa.d.ts +3 -0
  546. package/dist/devices/icasa.d.ts.map +1 -0
  547. package/dist/devices/icasa.js +174 -0
  548. package/dist/devices/icasa.js.map +1 -0
  549. package/dist/devices/idinio.d.ts +3 -0
  550. package/dist/devices/idinio.d.ts.map +1 -0
  551. package/dist/devices/idinio.js +47 -0
  552. package/dist/devices/idinio.js.map +1 -0
  553. package/dist/devices/ihorn.d.ts +3 -0
  554. package/dist/devices/ihorn.d.ts.map +1 -0
  555. package/dist/devices/ihorn.js +105 -0
  556. package/dist/devices/ihorn.js.map +1 -0
  557. package/dist/devices/ikea.d.ts +3 -0
  558. package/dist/devices/ikea.d.ts.map +1 -0
  559. package/dist/devices/ikea.js +1241 -0
  560. package/dist/devices/ikea.js.map +1 -0
  561. package/dist/devices/ilightsin.d.ts +3 -0
  562. package/dist/devices/ilightsin.d.ts.map +1 -0
  563. package/dist/devices/ilightsin.js +59 -0
  564. package/dist/devices/ilightsin.js.map +1 -0
  565. package/dist/devices/iluminize.d.ts +3 -0
  566. package/dist/devices/iluminize.d.ts.map +1 -0
  567. package/dist/devices/iluminize.js +385 -0
  568. package/dist/devices/iluminize.js.map +1 -0
  569. package/dist/devices/ilux.d.ts +3 -0
  570. package/dist/devices/ilux.d.ts.map +1 -0
  571. package/dist/devices/ilux.js +47 -0
  572. package/dist/devices/ilux.js.map +1 -0
  573. package/dist/devices/imhotepcreation.d.ts +3 -0
  574. package/dist/devices/imhotepcreation.d.ts.map +1 -0
  575. package/dist/devices/imhotepcreation.js +240 -0
  576. package/dist/devices/imhotepcreation.js.map +1 -0
  577. package/dist/devices/immax.d.ts +3 -0
  578. package/dist/devices/immax.d.ts.map +1 -0
  579. package/dist/devices/immax.js +471 -0
  580. package/dist/devices/immax.js.map +1 -0
  581. package/dist/devices/imou.d.ts +3 -0
  582. package/dist/devices/imou.d.ts.map +1 -0
  583. package/dist/devices/imou.js +109 -0
  584. package/dist/devices/imou.js.map +1 -0
  585. package/dist/devices/index.d.ts +4 -0
  586. package/dist/devices/index.d.ts.map +1 -0
  587. package/dist/devices/index.js +738 -0
  588. package/dist/devices/index.js.map +1 -0
  589. package/dist/devices/innr.d.ts +3 -0
  590. package/dist/devices/innr.d.ts.map +1 -0
  591. package/dist/devices/innr.js +1033 -0
  592. package/dist/devices/innr.js.map +1 -0
  593. package/dist/devices/inovelli.d.ts +3 -0
  594. package/dist/devices/inovelli.d.ts.map +1 -0
  595. package/dist/devices/inovelli.js +2474 -0
  596. package/dist/devices/inovelli.js.map +1 -0
  597. package/dist/devices/insta.d.ts +3 -0
  598. package/dist/devices/insta.d.ts.map +1 -0
  599. package/dist/devices/insta.js +182 -0
  600. package/dist/devices/insta.js.map +1 -0
  601. package/dist/devices/intuis.d.ts +3 -0
  602. package/dist/devices/intuis.d.ts.map +1 -0
  603. package/dist/devices/intuis.js +95 -0
  604. package/dist/devices/intuis.js.map +1 -0
  605. package/dist/devices/iolloi.d.ts +3 -0
  606. package/dist/devices/iolloi.d.ts.map +1 -0
  607. package/dist/devices/iolloi.js +48 -0
  608. package/dist/devices/iolloi.js.map +1 -0
  609. package/dist/devices/iotperfect.d.ts +3 -0
  610. package/dist/devices/iotperfect.d.ts.map +1 -0
  611. package/dist/devices/iotperfect.js +60 -0
  612. package/dist/devices/iotperfect.js.map +1 -0
  613. package/dist/devices/iris.d.ts +3 -0
  614. package/dist/devices/iris.d.ts.map +1 -0
  615. package/dist/devices/iris.js +208 -0
  616. package/dist/devices/iris.js.map +1 -0
  617. package/dist/devices/istar.d.ts +3 -0
  618. package/dist/devices/istar.d.ts.map +1 -0
  619. package/dist/devices/istar.js +61 -0
  620. package/dist/devices/istar.js.map +1 -0
  621. package/dist/devices/jasco.d.ts +3 -0
  622. package/dist/devices/jasco.d.ts.map +1 -0
  623. package/dist/devices/jasco.js +63 -0
  624. package/dist/devices/jasco.js.map +1 -0
  625. package/dist/devices/javis.d.ts +3 -0
  626. package/dist/devices/javis.d.ts.map +1 -0
  627. package/dist/devices/javis.js +77 -0
  628. package/dist/devices/javis.js.map +1 -0
  629. package/dist/devices/jethome.d.ts +3 -0
  630. package/dist/devices/jethome.d.ts.map +1 -0
  631. package/dist/devices/jethome.js +120 -0
  632. package/dist/devices/jethome.js.map +1 -0
  633. package/dist/devices/jiawen.d.ts +3 -0
  634. package/dist/devices/jiawen.d.ts.map +1 -0
  635. package/dist/devices/jiawen.js +54 -0
  636. package/dist/devices/jiawen.js.map +1 -0
  637. package/dist/devices/jumitech.d.ts +3 -0
  638. package/dist/devices/jumitech.d.ts.map +1 -0
  639. package/dist/devices/jumitech.js +47 -0
  640. package/dist/devices/jumitech.js.map +1 -0
  641. package/dist/devices/jxuan.d.ts +3 -0
  642. package/dist/devices/jxuan.d.ts.map +1 -0
  643. package/dist/devices/jxuan.js +85 -0
  644. package/dist/devices/jxuan.js.map +1 -0
  645. package/dist/devices/kami.d.ts +3 -0
  646. package/dist/devices/kami.d.ts.map +1 -0
  647. package/dist/devices/kami.js +51 -0
  648. package/dist/devices/kami.js.map +1 -0
  649. package/dist/devices/keen_home.d.ts +3 -0
  650. package/dist/devices/keen_home.d.ts.map +1 -0
  651. package/dist/devices/keen_home.js +155 -0
  652. package/dist/devices/keen_home.js.map +1 -0
  653. package/dist/devices/klikaanklikuit.d.ts +3 -0
  654. package/dist/devices/klikaanklikuit.d.ts.map +1 -0
  655. package/dist/devices/klikaanklikuit.js +54 -0
  656. package/dist/devices/klikaanklikuit.js.map +1 -0
  657. package/dist/devices/kmpcil.d.ts +3 -0
  658. package/dist/devices/kmpcil.d.ts.map +1 -0
  659. package/dist/devices/kmpcil.js +212 -0
  660. package/dist/devices/kmpcil.js.map +1 -0
  661. package/dist/devices/konke.d.ts +3 -0
  662. package/dist/devices/konke.d.ts.map +1 -0
  663. package/dist/devices/konke.js +207 -0
  664. package/dist/devices/konke.js.map +1 -0
  665. package/dist/devices/ksentry.d.ts +3 -0
  666. package/dist/devices/ksentry.d.ts.map +1 -0
  667. package/dist/devices/ksentry.js +47 -0
  668. package/dist/devices/ksentry.js.map +1 -0
  669. package/dist/devices/kurvia.d.ts +3 -0
  670. package/dist/devices/kurvia.d.ts.map +1 -0
  671. package/dist/devices/kurvia.js +49 -0
  672. package/dist/devices/kurvia.js.map +1 -0
  673. package/dist/devices/kwikset.d.ts +3 -0
  674. package/dist/devices/kwikset.d.ts.map +1 -0
  675. package/dist/devices/kwikset.js +153 -0
  676. package/dist/devices/kwikset.js.map +1 -0
  677. package/dist/devices/lanesto.d.ts +3 -0
  678. package/dist/devices/lanesto.d.ts.map +1 -0
  679. package/dist/devices/lanesto.js +47 -0
  680. package/dist/devices/lanesto.js.map +1 -0
  681. package/dist/devices/lds.d.ts +3 -0
  682. package/dist/devices/lds.d.ts.map +1 -0
  683. package/dist/devices/lds.js +54 -0
  684. package/dist/devices/lds.js.map +1 -0
  685. package/dist/devices/led_trading.d.ts +3 -0
  686. package/dist/devices/led_trading.d.ts.map +1 -0
  687. package/dist/devices/led_trading.js +108 -0
  688. package/dist/devices/led_trading.js.map +1 -0
  689. package/dist/devices/ledvance.d.ts +3 -0
  690. package/dist/devices/ledvance.d.ts.map +1 -0
  691. package/dist/devices/ledvance.js +407 -0
  692. package/dist/devices/ledvance.js.map +1 -0
  693. package/dist/devices/leedarson.d.ts +3 -0
  694. package/dist/devices/leedarson.d.ts.map +1 -0
  695. package/dist/devices/leedarson.js +180 -0
  696. package/dist/devices/leedarson.js.map +1 -0
  697. package/dist/devices/legrand.d.ts +3 -0
  698. package/dist/devices/legrand.d.ts.map +1 -0
  699. package/dist/devices/legrand.js +809 -0
  700. package/dist/devices/legrand.js.map +1 -0
  701. package/dist/devices/lellki.d.ts +3 -0
  702. package/dist/devices/lellki.d.ts.map +1 -0
  703. package/dist/devices/lellki.js +162 -0
  704. package/dist/devices/lellki.js.map +1 -0
  705. package/dist/devices/letsled.d.ts +3 -0
  706. package/dist/devices/letsled.d.ts.map +1 -0
  707. package/dist/devices/letsled.js +47 -0
  708. package/dist/devices/letsled.js.map +1 -0
  709. package/dist/devices/letv.d.ts +3 -0
  710. package/dist/devices/letv.d.ts.map +1 -0
  711. package/dist/devices/letv.js +86 -0
  712. package/dist/devices/letv.js.map +1 -0
  713. package/dist/devices/leviton.d.ts +3 -0
  714. package/dist/devices/leviton.d.ts.map +1 -0
  715. package/dist/devices/leviton.js +160 -0
  716. package/dist/devices/leviton.js.map +1 -0
  717. package/dist/devices/lg.d.ts +3 -0
  718. package/dist/devices/lg.d.ts.map +1 -0
  719. package/dist/devices/lg.js +61 -0
  720. package/dist/devices/lg.js.map +1 -0
  721. package/dist/devices/lidl.d.ts +3 -0
  722. package/dist/devices/lidl.d.ts.map +1 -0
  723. package/dist/devices/lidl.js +669 -0
  724. package/dist/devices/lidl.js.map +1 -0
  725. package/dist/devices/lifecontrol.d.ts +3 -0
  726. package/dist/devices/lifecontrol.d.ts.map +1 -0
  727. package/dist/devices/lifecontrol.js +141 -0
  728. package/dist/devices/lifecontrol.js.map +1 -0
  729. package/dist/devices/lightsolutions.d.ts +3 -0
  730. package/dist/devices/lightsolutions.d.ts.map +1 -0
  731. package/dist/devices/lightsolutions.js +90 -0
  732. package/dist/devices/lightsolutions.js.map +1 -0
  733. package/dist/devices/lincukoo.d.ts +3 -0
  734. package/dist/devices/lincukoo.d.ts.map +1 -0
  735. package/dist/devices/lincukoo.js +788 -0
  736. package/dist/devices/lincukoo.js.map +1 -0
  737. package/dist/devices/linkind.d.ts +3 -0
  738. package/dist/devices/linkind.d.ts.map +1 -0
  739. package/dist/devices/linkind.js +251 -0
  740. package/dist/devices/linkind.js.map +1 -0
  741. package/dist/devices/linptech.d.ts +3 -0
  742. package/dist/devices/linptech.d.ts.map +1 -0
  743. package/dist/devices/linptech.js +157 -0
  744. package/dist/devices/linptech.js.map +1 -0
  745. package/dist/devices/livingwise.d.ts +3 -0
  746. package/dist/devices/livingwise.d.ts.map +1 -0
  747. package/dist/devices/livingwise.js +115 -0
  748. package/dist/devices/livingwise.js.map +1 -0
  749. package/dist/devices/livolo.d.ts +3 -0
  750. package/dist/devices/livolo.d.ts.map +1 -0
  751. package/dist/devices/livolo.js +263 -0
  752. package/dist/devices/livolo.js.map +1 -0
  753. package/dist/devices/lixee.d.ts +3 -0
  754. package/dist/devices/lixee.d.ts.map +1 -0
  755. package/dist/devices/lixee.js +2038 -0
  756. package/dist/devices/lixee.js.map +1 -0
  757. package/dist/devices/lonsonho.d.ts +3 -0
  758. package/dist/devices/lonsonho.d.ts.map +1 -0
  759. package/dist/devices/lonsonho.js +310 -0
  760. package/dist/devices/lonsonho.js.map +1 -0
  761. package/dist/devices/ls.d.ts +3 -0
  762. package/dist/devices/ls.d.ts.map +1 -0
  763. package/dist/devices/ls.js +152 -0
  764. package/dist/devices/ls.js.map +1 -0
  765. package/dist/devices/lubeez.d.ts +3 -0
  766. package/dist/devices/lubeez.d.ts.map +1 -0
  767. package/dist/devices/lubeez.js +47 -0
  768. package/dist/devices/lubeez.js.map +1 -0
  769. package/dist/devices/lumi.d.ts +3 -0
  770. package/dist/devices/lumi.d.ts.map +1 -0
  771. package/dist/devices/lumi.js +5345 -0
  772. package/dist/devices/lumi.js.map +1 -0
  773. package/dist/devices/lupus.d.ts +3 -0
  774. package/dist/devices/lupus.d.ts.map +1 -0
  775. package/dist/devices/lupus.js +94 -0
  776. package/dist/devices/lupus.js.map +1 -0
  777. package/dist/devices/lutron.d.ts +3 -0
  778. package/dist/devices/lutron.d.ts.map +1 -0
  779. package/dist/devices/lutron.js +81 -0
  780. package/dist/devices/lutron.js.map +1 -0
  781. package/dist/devices/lux.d.ts +3 -0
  782. package/dist/devices/lux.d.ts.map +1 -0
  783. package/dist/devices/lux.js +87 -0
  784. package/dist/devices/lux.js.map +1 -0
  785. package/dist/devices/lytko.d.ts +3 -0
  786. package/dist/devices/lytko.d.ts.map +1 -0
  787. package/dist/devices/lytko.js +1809 -0
  788. package/dist/devices/lytko.js.map +1 -0
  789. package/dist/devices/m_elec.d.ts +3 -0
  790. package/dist/devices/m_elec.d.ts.map +1 -0
  791. package/dist/devices/m_elec.js +68 -0
  792. package/dist/devices/m_elec.js.map +1 -0
  793. package/dist/devices/makegood.d.ts +3 -0
  794. package/dist/devices/makegood.d.ts.map +1 -0
  795. package/dist/devices/makegood.js +117 -0
  796. package/dist/devices/makegood.js.map +1 -0
  797. package/dist/devices/matcall_bv.d.ts +3 -0
  798. package/dist/devices/matcall_bv.d.ts.map +1 -0
  799. package/dist/devices/matcall_bv.js +54 -0
  800. package/dist/devices/matcall_bv.js.map +1 -0
  801. package/dist/devices/mazda.d.ts +3 -0
  802. package/dist/devices/mazda.d.ts.map +1 -0
  803. package/dist/devices/mazda.js +146 -0
  804. package/dist/devices/mazda.js.map +1 -0
  805. package/dist/devices/meazon.d.ts +3 -0
  806. package/dist/devices/meazon.d.ts.map +1 -0
  807. package/dist/devices/meazon.js +95 -0
  808. package/dist/devices/meazon.js.map +1 -0
  809. package/dist/devices/mercator.d.ts +3 -0
  810. package/dist/devices/mercator.d.ts.map +1 -0
  811. package/dist/devices/mercator.js +242 -0
  812. package/dist/devices/mercator.js.map +1 -0
  813. package/dist/devices/miboxer.d.ts +3 -0
  814. package/dist/devices/miboxer.d.ts.map +1 -0
  815. package/dist/devices/miboxer.js +304 -0
  816. package/dist/devices/miboxer.js.map +1 -0
  817. package/dist/devices/micromatic.d.ts +3 -0
  818. package/dist/devices/micromatic.d.ts.map +1 -0
  819. package/dist/devices/micromatic.js +47 -0
  820. package/dist/devices/micromatic.js.map +1 -0
  821. package/dist/devices/mill.d.ts +3 -0
  822. package/dist/devices/mill.d.ts.map +1 -0
  823. package/dist/devices/mill.js +52 -0
  824. package/dist/devices/mill.js.map +1 -0
  825. package/dist/devices/mindy.d.ts +3 -0
  826. package/dist/devices/mindy.d.ts.map +1 -0
  827. package/dist/devices/mindy.js +379 -0
  828. package/dist/devices/mindy.js.map +1 -0
  829. package/dist/devices/modular.d.ts +3 -0
  830. package/dist/devices/modular.d.ts.map +1 -0
  831. package/dist/devices/modular.js +47 -0
  832. package/dist/devices/modular.js.map +1 -0
  833. package/dist/devices/moes.d.ts +3 -0
  834. package/dist/devices/moes.d.ts.map +1 -0
  835. package/dist/devices/moes.js +2368 -0
  836. package/dist/devices/moes.js.map +1 -0
  837. package/dist/devices/muller_licht.d.ts +3 -0
  838. package/dist/devices/muller_licht.d.ts.map +1 -0
  839. package/dist/devices/muller_licht.js +366 -0
  840. package/dist/devices/muller_licht.js.map +1 -0
  841. package/dist/devices/multir.d.ts +3 -0
  842. package/dist/devices/multir.d.ts.map +1 -0
  843. package/dist/devices/multir.js +152 -0
  844. package/dist/devices/multir.js.map +1 -0
  845. package/dist/devices/multiterm.d.ts +3 -0
  846. package/dist/devices/multiterm.d.ts.map +1 -0
  847. package/dist/devices/multiterm.js +119 -0
  848. package/dist/devices/multiterm.js.map +1 -0
  849. package/dist/devices/namron.d.ts +3 -0
  850. package/dist/devices/namron.d.ts.map +1 -0
  851. package/dist/devices/namron.js +2004 -0
  852. package/dist/devices/namron.js.map +1 -0
  853. package/dist/devices/nanoleaf.d.ts +3 -0
  854. package/dist/devices/nanoleaf.d.ts.map +1 -0
  855. package/dist/devices/nanoleaf.js +47 -0
  856. package/dist/devices/nanoleaf.js.map +1 -0
  857. package/dist/devices/nedis.d.ts +3 -0
  858. package/dist/devices/nedis.d.ts.map +1 -0
  859. package/dist/devices/nedis.js +87 -0
  860. package/dist/devices/nedis.js.map +1 -0
  861. package/dist/devices/neo.d.ts +3 -0
  862. package/dist/devices/neo.d.ts.map +1 -0
  863. package/dist/devices/neo.js +526 -0
  864. package/dist/devices/neo.js.map +1 -0
  865. package/dist/devices/net2grid.d.ts +3 -0
  866. package/dist/devices/net2grid.d.ts.map +1 -0
  867. package/dist/devices/net2grid.js +64 -0
  868. package/dist/devices/net2grid.js.map +1 -0
  869. package/dist/devices/netvox.d.ts +3 -0
  870. package/dist/devices/netvox.d.ts.map +1 -0
  871. package/dist/devices/netvox.js +71 -0
  872. package/dist/devices/netvox.js.map +1 -0
  873. package/dist/devices/nexelec.d.ts +3 -0
  874. package/dist/devices/nexelec.d.ts.map +1 -0
  875. package/dist/devices/nexelec.js +47 -0
  876. package/dist/devices/nexelec.js.map +1 -0
  877. package/dist/devices/niko.d.ts +3 -0
  878. package/dist/devices/niko.d.ts.map +1 -0
  879. package/dist/devices/niko.js +769 -0
  880. package/dist/devices/niko.js.map +1 -0
  881. package/dist/devices/ninja_blocks.d.ts +3 -0
  882. package/dist/devices/ninja_blocks.d.ts.map +1 -0
  883. package/dist/devices/ninja_blocks.js +60 -0
  884. package/dist/devices/ninja_blocks.js.map +1 -0
  885. package/dist/devices/niviss.d.ts +3 -0
  886. package/dist/devices/niviss.d.ts.map +1 -0
  887. package/dist/devices/niviss.js +47 -0
  888. package/dist/devices/niviss.js.map +1 -0
  889. package/dist/devices/nobo.d.ts +3 -0
  890. package/dist/devices/nobo.d.ts.map +1 -0
  891. package/dist/devices/nobo.js +88 -0
  892. package/dist/devices/nobo.js.map +1 -0
  893. package/dist/devices/nodon.d.ts +3 -0
  894. package/dist/devices/nodon.d.ts.map +1 -0
  895. package/dist/devices/nodon.js +483 -0
  896. package/dist/devices/nodon.js.map +1 -0
  897. package/dist/devices/nordtronic.d.ts +3 -0
  898. package/dist/devices/nordtronic.d.ts.map +1 -0
  899. package/dist/devices/nordtronic.js +95 -0
  900. package/dist/devices/nordtronic.js.map +1 -0
  901. package/dist/devices/nous.d.ts +3 -0
  902. package/dist/devices/nous.d.ts.map +1 -0
  903. package/dist/devices/nous.js +367 -0
  904. package/dist/devices/nous.js.map +1 -0
  905. package/dist/devices/novo.d.ts +3 -0
  906. package/dist/devices/novo.d.ts.map +1 -0
  907. package/dist/devices/novo.js +53 -0
  908. package/dist/devices/novo.js.map +1 -0
  909. package/dist/devices/nue_3a.d.ts +3 -0
  910. package/dist/devices/nue_3a.d.ts.map +1 -0
  911. package/dist/devices/nue_3a.js +359 -0
  912. package/dist/devices/nue_3a.js.map +1 -0
  913. package/dist/devices/nyce.d.ts +3 -0
  914. package/dist/devices/nyce.d.ts.map +1 -0
  915. package/dist/devices/nyce.js +124 -0
  916. package/dist/devices/nyce.js.map +1 -0
  917. package/dist/devices/onenuo.d.ts +3 -0
  918. package/dist/devices/onenuo.d.ts.map +1 -0
  919. package/dist/devices/onenuo.js +83 -0
  920. package/dist/devices/onenuo.js.map +1 -0
  921. package/dist/devices/onesti.d.ts +3 -0
  922. package/dist/devices/onesti.d.ts.map +1 -0
  923. package/dist/devices/onesti.js +265 -0
  924. package/dist/devices/onesti.js.map +1 -0
  925. package/dist/devices/onokom.d.ts +3 -0
  926. package/dist/devices/onokom.d.ts.map +1 -0
  927. package/dist/devices/onokom.js +2715 -0
  928. package/dist/devices/onokom.js.map +1 -0
  929. package/dist/devices/openlumi.d.ts +3 -0
  930. package/dist/devices/openlumi.d.ts.map +1 -0
  931. package/dist/devices/openlumi.js +47 -0
  932. package/dist/devices/openlumi.js.map +1 -0
  933. package/dist/devices/orvibo.d.ts +12 -0
  934. package/dist/devices/orvibo.d.ts.map +1 -0
  935. package/dist/devices/orvibo.js +715 -0
  936. package/dist/devices/orvibo.js.map +1 -0
  937. package/dist/devices/orztech.d.ts +3 -0
  938. package/dist/devices/orztech.d.ts.map +1 -0
  939. package/dist/devices/orztech.js +195 -0
  940. package/dist/devices/orztech.js.map +1 -0
  941. package/dist/devices/osram.d.ts +3 -0
  942. package/dist/devices/osram.d.ts.map +1 -0
  943. package/dist/devices/osram.js +513 -0
  944. package/dist/devices/osram.js.map +1 -0
  945. package/dist/devices/oujiabao.d.ts +3 -0
  946. package/dist/devices/oujiabao.d.ts.map +1 -0
  947. package/dist/devices/oujiabao.js +51 -0
  948. package/dist/devices/oujiabao.js.map +1 -0
  949. package/dist/devices/owon.d.ts +3 -0
  950. package/dist/devices/owon.d.ts.map +1 -0
  951. package/dist/devices/owon.js +888 -0
  952. package/dist/devices/owon.js.map +1 -0
  953. package/dist/devices/ozsmartthings.d.ts +3 -0
  954. package/dist/devices/ozsmartthings.d.ts.map +1 -0
  955. package/dist/devices/ozsmartthings.js +47 -0
  956. package/dist/devices/ozsmartthings.js.map +1 -0
  957. package/dist/devices/paul_neuhaus.d.ts +3 -0
  958. package/dist/devices/paul_neuhaus.d.ts.map +1 -0
  959. package/dist/devices/paul_neuhaus.js +190 -0
  960. package/dist/devices/paul_neuhaus.js.map +1 -0
  961. package/dist/devices/paulmann.d.ts +3 -0
  962. package/dist/devices/paulmann.d.ts.map +1 -0
  963. package/dist/devices/paulmann.js +426 -0
  964. package/dist/devices/paulmann.js.map +1 -0
  965. package/dist/devices/peq.d.ts +3 -0
  966. package/dist/devices/peq.d.ts.map +1 -0
  967. package/dist/devices/peq.js +60 -0
  968. package/dist/devices/peq.js.map +1 -0
  969. package/dist/devices/perenio.d.ts +3 -0
  970. package/dist/devices/perenio.d.ts.map +1 -0
  971. package/dist/devices/perenio.js +461 -0
  972. package/dist/devices/perenio.js.map +1 -0
  973. package/dist/devices/philio.d.ts +3 -0
  974. package/dist/devices/philio.d.ts.map +1 -0
  975. package/dist/devices/philio.js +48 -0
  976. package/dist/devices/philio.js.map +1 -0
  977. package/dist/devices/philips.d.ts +3 -0
  978. package/dist/devices/philips.d.ts.map +1 -0
  979. package/dist/devices/philips.js +4948 -0
  980. package/dist/devices/philips.js.map +1 -0
  981. package/dist/devices/plaid.d.ts +3 -0
  982. package/dist/devices/plaid.d.ts.map +1 -0
  983. package/dist/devices/plaid.js +61 -0
  984. package/dist/devices/plaid.js.map +1 -0
  985. package/dist/devices/plugwise.d.ts +3 -0
  986. package/dist/devices/plugwise.d.ts.map +1 -0
  987. package/dist/devices/plugwise.js +217 -0
  988. package/dist/devices/plugwise.js.map +1 -0
  989. package/dist/devices/profalux.d.ts +3 -0
  990. package/dist/devices/profalux.d.ts.map +1 -0
  991. package/dist/devices/profalux.js +215 -0
  992. package/dist/devices/profalux.js.map +1 -0
  993. package/dist/devices/prolight.d.ts +3 -0
  994. package/dist/devices/prolight.d.ts.map +1 -0
  995. package/dist/devices/prolight.js +111 -0
  996. package/dist/devices/prolight.js.map +1 -0
  997. package/dist/devices/purmo.d.ts +3 -0
  998. package/dist/devices/purmo.d.ts.map +1 -0
  999. package/dist/devices/purmo.js +91 -0
  1000. package/dist/devices/purmo.js.map +1 -0
  1001. package/dist/devices/pushok.d.ts +3 -0
  1002. package/dist/devices/pushok.d.ts.map +1 -0
  1003. package/dist/devices/pushok.js +736 -0
  1004. package/dist/devices/pushok.js.map +1 -0
  1005. package/dist/devices/qa.d.ts +3 -0
  1006. package/dist/devices/qa.d.ts.map +1 -0
  1007. package/dist/devices/qa.js +445 -0
  1008. package/dist/devices/qa.js.map +1 -0
  1009. package/dist/devices/qmotion.d.ts +3 -0
  1010. package/dist/devices/qmotion.d.ts.map +1 -0
  1011. package/dist/devices/qmotion.js +69 -0
  1012. package/dist/devices/qmotion.js.map +1 -0
  1013. package/dist/devices/qoto.d.ts +3 -0
  1014. package/dist/devices/qoto.d.ts.map +1 -0
  1015. package/dist/devices/qoto.js +83 -0
  1016. package/dist/devices/qoto.js.map +1 -0
  1017. package/dist/devices/quirky.d.ts +8 -0
  1018. package/dist/devices/quirky.d.ts.map +1 -0
  1019. package/dist/devices/quirky.js +47 -0
  1020. package/dist/devices/quirky.js.map +1 -0
  1021. package/dist/devices/quotra.d.ts +3 -0
  1022. package/dist/devices/quotra.d.ts.map +1 -0
  1023. package/dist/devices/quotra.js +54 -0
  1024. package/dist/devices/quotra.js.map +1 -0
  1025. package/dist/devices/rademacher.d.ts +3 -0
  1026. package/dist/devices/rademacher.d.ts.map +1 -0
  1027. package/dist/devices/rademacher.js +61 -0
  1028. package/dist/devices/rademacher.js.map +1 -0
  1029. package/dist/devices/radium.d.ts +3 -0
  1030. package/dist/devices/radium.d.ts.map +1 -0
  1031. package/dist/devices/radium.js +47 -0
  1032. package/dist/devices/radium.js.map +1 -0
  1033. package/dist/devices/raex.d.ts +3 -0
  1034. package/dist/devices/raex.d.ts.map +1 -0
  1035. package/dist/devices/raex.js +47 -0
  1036. package/dist/devices/raex.js.map +1 -0
  1037. package/dist/devices/rgb_genie.d.ts +3 -0
  1038. package/dist/devices/rgb_genie.d.ts.map +1 -0
  1039. package/dist/devices/rgb_genie.js +277 -0
  1040. package/dist/devices/rgb_genie.js.map +1 -0
  1041. package/dist/devices/robb.d.ts +3 -0
  1042. package/dist/devices/robb.d.ts.map +1 -0
  1043. package/dist/devices/robb.js +492 -0
  1044. package/dist/devices/robb.js.map +1 -0
  1045. package/dist/devices/roome.d.ts +3 -0
  1046. package/dist/devices/roome.d.ts.map +1 -0
  1047. package/dist/devices/roome.js +51 -0
  1048. package/dist/devices/roome.js.map +1 -0
  1049. package/dist/devices/rtx.d.ts +3 -0
  1050. package/dist/devices/rtx.d.ts.map +1 -0
  1051. package/dist/devices/rtx.js +143 -0
  1052. package/dist/devices/rtx.js.map +1 -0
  1053. package/dist/devices/salus_controls.d.ts +3 -0
  1054. package/dist/devices/salus_controls.d.ts.map +1 -0
  1055. package/dist/devices/salus_controls.js +222 -0
  1056. package/dist/devices/salus_controls.js.map +1 -0
  1057. package/dist/devices/samotech.d.ts +3 -0
  1058. package/dist/devices/samotech.d.ts.map +1 -0
  1059. package/dist/devices/samotech.js +123 -0
  1060. package/dist/devices/samotech.js.map +1 -0
  1061. package/dist/devices/saswell.d.ts +3 -0
  1062. package/dist/devices/saswell.d.ts.map +1 -0
  1063. package/dist/devices/saswell.js +120 -0
  1064. package/dist/devices/saswell.js.map +1 -0
  1065. package/dist/devices/sber.d.ts +3 -0
  1066. package/dist/devices/sber.d.ts.map +1 -0
  1067. package/dist/devices/sber.js +1921 -0
  1068. package/dist/devices/sber.js.map +1 -0
  1069. package/dist/devices/scanproducts.d.ts +3 -0
  1070. package/dist/devices/scanproducts.d.ts.map +1 -0
  1071. package/dist/devices/scanproducts.js +54 -0
  1072. package/dist/devices/scanproducts.js.map +1 -0
  1073. package/dist/devices/schlage.d.ts +3 -0
  1074. package/dist/devices/schlage.d.ts.map +1 -0
  1075. package/dist/devices/schlage.js +60 -0
  1076. package/dist/devices/schlage.js.map +1 -0
  1077. package/dist/devices/schneider_electric.d.ts +10 -0
  1078. package/dist/devices/schneider_electric.d.ts.map +1 -0
  1079. package/dist/devices/schneider_electric.js +2801 -0
  1080. package/dist/devices/schneider_electric.js.map +1 -0
  1081. package/dist/devices/schwaiger.d.ts +3 -0
  1082. package/dist/devices/schwaiger.d.ts.map +1 -0
  1083. package/dist/devices/schwaiger.js +105 -0
  1084. package/dist/devices/schwaiger.js.map +1 -0
  1085. package/dist/devices/seastar_intelligence.d.ts +3 -0
  1086. package/dist/devices/seastar_intelligence.d.ts.map +1 -0
  1087. package/dist/devices/seastar_intelligence.js +52 -0
  1088. package/dist/devices/seastar_intelligence.js.map +1 -0
  1089. package/dist/devices/securifi.d.ts +3 -0
  1090. package/dist/devices/securifi.d.ts.map +1 -0
  1091. package/dist/devices/securifi.js +79 -0
  1092. package/dist/devices/securifi.js.map +1 -0
  1093. package/dist/devices/sengled.d.ts +6 -0
  1094. package/dist/devices/sengled.d.ts.map +1 -0
  1095. package/dist/devices/sengled.js +395 -0
  1096. package/dist/devices/sengled.js.map +1 -0
  1097. package/dist/devices/senoro.d.ts +3 -0
  1098. package/dist/devices/senoro.d.ts.map +1 -0
  1099. package/dist/devices/senoro.js +64 -0
  1100. package/dist/devices/senoro.js.map +1 -0
  1101. package/dist/devices/sercomm.d.ts +3 -0
  1102. package/dist/devices/sercomm.d.ts.map +1 -0
  1103. package/dist/devices/sercomm.js +193 -0
  1104. package/dist/devices/sercomm.js.map +1 -0
  1105. package/dist/devices/shade_control.d.ts +3 -0
  1106. package/dist/devices/shade_control.d.ts.map +1 -0
  1107. package/dist/devices/shade_control.js +61 -0
  1108. package/dist/devices/shade_control.js.map +1 -0
  1109. package/dist/devices/shelly.d.ts +3 -0
  1110. package/dist/devices/shelly.d.ts.map +1 -0
  1111. package/dist/devices/shelly.js +1304 -0
  1112. package/dist/devices/shelly.js.map +1 -0
  1113. package/dist/devices/shenzhen_homa.d.ts +3 -0
  1114. package/dist/devices/shenzhen_homa.d.ts.map +1 -0
  1115. package/dist/devices/shenzhen_homa.js +143 -0
  1116. package/dist/devices/shenzhen_homa.js.map +1 -0
  1117. package/dist/devices/shinasystem.d.ts +3 -0
  1118. package/dist/devices/shinasystem.d.ts.map +1 -0
  1119. package/dist/devices/shinasystem.js +1322 -0
  1120. package/dist/devices/shinasystem.js.map +1 -0
  1121. package/dist/devices/shyugj.d.ts +3 -0
  1122. package/dist/devices/shyugj.d.ts.map +1 -0
  1123. package/dist/devices/shyugj.js +53 -0
  1124. package/dist/devices/shyugj.js.map +1 -0
  1125. package/dist/devices/siglis.d.ts +3 -0
  1126. package/dist/devices/siglis.d.ts.map +1 -0
  1127. package/dist/devices/siglis.js +440 -0
  1128. package/dist/devices/siglis.js.map +1 -0
  1129. package/dist/devices/sikom.d.ts +3 -0
  1130. package/dist/devices/sikom.d.ts.map +1 -0
  1131. package/dist/devices/sikom.js +64 -0
  1132. package/dist/devices/sikom.js.map +1 -0
  1133. package/dist/devices/silicon_labs.d.ts +3 -0
  1134. package/dist/devices/silicon_labs.d.ts.map +1 -0
  1135. package/dist/devices/silicon_labs.js +47 -0
  1136. package/dist/devices/silicon_labs.js.map +1 -0
  1137. package/dist/devices/simon.d.ts +3 -0
  1138. package/dist/devices/simon.d.ts.map +1 -0
  1139. package/dist/devices/simon.js +54 -0
  1140. package/dist/devices/simon.js.map +1 -0
  1141. package/dist/devices/simpla_home.d.ts +3 -0
  1142. package/dist/devices/simpla_home.d.ts.map +1 -0
  1143. package/dist/devices/simpla_home.js +97 -0
  1144. package/dist/devices/simpla_home.js.map +1 -0
  1145. package/dist/devices/sinope.d.ts +3 -0
  1146. package/dist/devices/sinope.d.ts.map +1 -0
  1147. package/dist/devices/sinope.js +2015 -0
  1148. package/dist/devices/sinope.js.map +1 -0
  1149. package/dist/devices/siterwell.d.ts +3 -0
  1150. package/dist/devices/siterwell.d.ts.map +1 -0
  1151. package/dist/devices/siterwell.js +107 -0
  1152. package/dist/devices/siterwell.js.map +1 -0
  1153. package/dist/devices/skydance.d.ts +3 -0
  1154. package/dist/devices/skydance.d.ts.map +1 -0
  1155. package/dist/devices/skydance.js +138 -0
  1156. package/dist/devices/skydance.js.map +1 -0
  1157. package/dist/devices/slacky_diy.d.ts +3 -0
  1158. package/dist/devices/slacky_diy.d.ts.map +1 -0
  1159. package/dist/devices/slacky_diy.js +3694 -0
  1160. package/dist/devices/slacky_diy.js.map +1 -0
  1161. package/dist/devices/slv.d.ts +3 -0
  1162. package/dist/devices/slv.d.ts.map +1 -0
  1163. package/dist/devices/slv.js +77 -0
  1164. package/dist/devices/slv.js.map +1 -0
  1165. package/dist/devices/smarli.d.ts +3 -0
  1166. package/dist/devices/smarli.d.ts.map +1 -0
  1167. package/dist/devices/smarli.js +99 -0
  1168. package/dist/devices/smarli.js.map +1 -0
  1169. package/dist/devices/smart9.d.ts +3 -0
  1170. package/dist/devices/smart9.d.ts.map +1 -0
  1171. package/dist/devices/smart9.js +58 -0
  1172. package/dist/devices/smart9.js.map +1 -0
  1173. package/dist/devices/smart_home_pty.d.ts +3 -0
  1174. package/dist/devices/smart_home_pty.d.ts.map +1 -0
  1175. package/dist/devices/smart_home_pty.js +54 -0
  1176. package/dist/devices/smart_home_pty.js.map +1 -0
  1177. package/dist/devices/smartenit.d.ts +3 -0
  1178. package/dist/devices/smartenit.d.ts.map +1 -0
  1179. package/dist/devices/smartenit.js +77 -0
  1180. package/dist/devices/smartenit.js.map +1 -0
  1181. package/dist/devices/smartthings.d.ts +26 -0
  1182. package/dist/devices/smartthings.d.ts.map +1 -0
  1183. package/dist/devices/smartthings.js +571 -0
  1184. package/dist/devices/smartthings.js.map +1 -0
  1185. package/dist/devices/smartwings.d.ts +3 -0
  1186. package/dist/devices/smartwings.d.ts.map +1 -0
  1187. package/dist/devices/smartwings.js +60 -0
  1188. package/dist/devices/smartwings.js.map +1 -0
  1189. package/dist/devices/smlight.d.ts +3 -0
  1190. package/dist/devices/smlight.d.ts.map +1 -0
  1191. package/dist/devices/smlight.js +73 -0
  1192. package/dist/devices/smlight.js.map +1 -0
  1193. package/dist/devices/soanalarm.d.ts +3 -0
  1194. package/dist/devices/soanalarm.d.ts.map +1 -0
  1195. package/dist/devices/soanalarm.js +58 -0
  1196. package/dist/devices/soanalarm.js.map +1 -0
  1197. package/dist/devices/sohan_electric.d.ts +3 -0
  1198. package/dist/devices/sohan_electric.d.ts.map +1 -0
  1199. package/dist/devices/sohan_electric.js +49 -0
  1200. package/dist/devices/sohan_electric.js.map +1 -0
  1201. package/dist/devices/solaredge.d.ts +3 -0
  1202. package/dist/devices/solaredge.d.ts.map +1 -0
  1203. package/dist/devices/solaredge.js +47 -0
  1204. package/dist/devices/solaredge.js.map +1 -0
  1205. package/dist/devices/soma.d.ts +3 -0
  1206. package/dist/devices/soma.d.ts.map +1 -0
  1207. package/dist/devices/soma.js +47 -0
  1208. package/dist/devices/soma.js.map +1 -0
  1209. package/dist/devices/somfy.d.ts +3 -0
  1210. package/dist/devices/somfy.d.ts.map +1 -0
  1211. package/dist/devices/somfy.js +173 -0
  1212. package/dist/devices/somfy.js.map +1 -0
  1213. package/dist/devices/somgoms.d.ts +3 -0
  1214. package/dist/devices/somgoms.d.ts.map +1 -0
  1215. package/dist/devices/somgoms.js +80 -0
  1216. package/dist/devices/somgoms.js.map +1 -0
  1217. package/dist/devices/sonoff.d.ts +42 -0
  1218. package/dist/devices/sonoff.d.ts.map +1 -0
  1219. package/dist/devices/sonoff.js +4921 -0
  1220. package/dist/devices/sonoff.js.map +1 -0
  1221. package/dist/devices/sowilo.d.ts +3 -0
  1222. package/dist/devices/sowilo.d.ts.map +1 -0
  1223. package/dist/devices/sowilo.js +47 -0
  1224. package/dist/devices/sowilo.js.map +1 -0
  1225. package/dist/devices/spacetronik.d.ts +3 -0
  1226. package/dist/devices/spacetronik.d.ts.map +1 -0
  1227. package/dist/devices/spacetronik.js +53 -0
  1228. package/dist/devices/spacetronik.js.map +1 -0
  1229. package/dist/devices/spotmau.d.ts +3 -0
  1230. package/dist/devices/spotmau.d.ts.map +1 -0
  1231. package/dist/devices/spotmau.js +74 -0
  1232. package/dist/devices/spotmau.js.map +1 -0
  1233. package/dist/devices/sprut.d.ts +3 -0
  1234. package/dist/devices/sprut.d.ts.map +1 -0
  1235. package/dist/devices/sprut.js +328 -0
  1236. package/dist/devices/sprut.js.map +1 -0
  1237. package/dist/devices/stello.d.ts +3 -0
  1238. package/dist/devices/stello.d.ts.map +1 -0
  1239. package/dist/devices/stello.js +142 -0
  1240. package/dist/devices/stello.js.map +1 -0
  1241. package/dist/devices/stelpro.d.ts +3 -0
  1242. package/dist/devices/stelpro.d.ts.map +1 -0
  1243. package/dist/devices/stelpro.js +376 -0
  1244. package/dist/devices/stelpro.js.map +1 -0
  1245. package/dist/devices/sunricher.d.ts +30 -0
  1246. package/dist/devices/sunricher.d.ts.map +1 -0
  1247. package/dist/devices/sunricher.js +2337 -0
  1248. package/dist/devices/sunricher.js.map +1 -0
  1249. package/dist/devices/superled.d.ts +3 -0
  1250. package/dist/devices/superled.d.ts.map +1 -0
  1251. package/dist/devices/superled.js +47 -0
  1252. package/dist/devices/superled.js.map +1 -0
  1253. package/dist/devices/swann.d.ts +3 -0
  1254. package/dist/devices/swann.d.ts.map +1 -0
  1255. package/dist/devices/swann.js +69 -0
  1256. package/dist/devices/swann.js.map +1 -0
  1257. package/dist/devices/sylvania.d.ts +3 -0
  1258. package/dist/devices/sylvania.d.ts.map +1 -0
  1259. package/dist/devices/sylvania.js +223 -0
  1260. package/dist/devices/sylvania.js.map +1 -0
  1261. package/dist/devices/tapestry.d.ts +3 -0
  1262. package/dist/devices/tapestry.d.ts.map +1 -0
  1263. package/dist/devices/tapestry.js +52 -0
  1264. package/dist/devices/tapestry.js.map +1 -0
  1265. package/dist/devices/task_lighting.d.ts +3 -0
  1266. package/dist/devices/task_lighting.d.ts.map +1 -0
  1267. package/dist/devices/task_lighting.js +47 -0
  1268. package/dist/devices/task_lighting.js.map +1 -0
  1269. package/dist/devices/tci.d.ts +3 -0
  1270. package/dist/devices/tci.d.ts.map +1 -0
  1271. package/dist/devices/tci.js +68 -0
  1272. package/dist/devices/tci.js.map +1 -0
  1273. package/dist/devices/tcl.d.ts +3 -0
  1274. package/dist/devices/tcl.d.ts.map +1 -0
  1275. package/dist/devices/tcl.js +47 -0
  1276. package/dist/devices/tcl.js.map +1 -0
  1277. package/dist/devices/tech.d.ts +3 -0
  1278. package/dist/devices/tech.d.ts.map +1 -0
  1279. package/dist/devices/tech.js +213 -0
  1280. package/dist/devices/tech.js.map +1 -0
  1281. package/dist/devices/technicolor.d.ts +3 -0
  1282. package/dist/devices/technicolor.d.ts.map +1 -0
  1283. package/dist/devices/technicolor.js +85 -0
  1284. package/dist/devices/technicolor.js.map +1 -0
  1285. package/dist/devices/terncy.d.ts +3 -0
  1286. package/dist/devices/terncy.d.ts.map +1 -0
  1287. package/dist/devices/terncy.js +192 -0
  1288. package/dist/devices/terncy.js.map +1 -0
  1289. package/dist/devices/the_light_group.d.ts +3 -0
  1290. package/dist/devices/the_light_group.d.ts.map +1 -0
  1291. package/dist/devices/the_light_group.js +145 -0
  1292. package/dist/devices/the_light_group.js.map +1 -0
  1293. package/dist/devices/third_reality.d.ts +3 -0
  1294. package/dist/devices/third_reality.d.ts.map +1 -0
  1295. package/dist/devices/third_reality.js +1067 -0
  1296. package/dist/devices/third_reality.js.map +1 -0
  1297. package/dist/devices/tis_control.d.ts +3 -0
  1298. package/dist/devices/tis_control.d.ts.map +1 -0
  1299. package/dist/devices/tis_control.js +47 -0
  1300. package/dist/devices/tis_control.js.map +1 -0
  1301. package/dist/devices/titan_products.d.ts +3 -0
  1302. package/dist/devices/titan_products.d.ts.map +1 -0
  1303. package/dist/devices/titan_products.js +58 -0
  1304. package/dist/devices/titan_products.js.map +1 -0
  1305. package/dist/devices/tlwglobal.d.ts +3 -0
  1306. package/dist/devices/tlwglobal.d.ts.map +1 -0
  1307. package/dist/devices/tlwglobal.js +64 -0
  1308. package/dist/devices/tlwglobal.js.map +1 -0
  1309. package/dist/devices/tnce.d.ts +3 -0
  1310. package/dist/devices/tnce.d.ts.map +1 -0
  1311. package/dist/devices/tnce.js +54 -0
  1312. package/dist/devices/tnce.js.map +1 -0
  1313. package/dist/devices/tplink.d.ts +3 -0
  1314. package/dist/devices/tplink.d.ts.map +1 -0
  1315. package/dist/devices/tplink.js +77 -0
  1316. package/dist/devices/tplink.js.map +1 -0
  1317. package/dist/devices/trust.d.ts +3 -0
  1318. package/dist/devices/trust.d.ts.map +1 -0
  1319. package/dist/devices/trust.js +180 -0
  1320. package/dist/devices/trust.js.map +1 -0
  1321. package/dist/devices/tubeszb.d.ts +3 -0
  1322. package/dist/devices/tubeszb.d.ts.map +1 -0
  1323. package/dist/devices/tubeszb.js +56 -0
  1324. package/dist/devices/tubeszb.js.map +1 -0
  1325. package/dist/devices/tuya.d.ts +3 -0
  1326. package/dist/devices/tuya.d.ts.map +1 -0
  1327. package/dist/devices/tuya.js +24771 -0
  1328. package/dist/devices/tuya.js.map +1 -0
  1329. package/dist/devices/ubisys.d.ts +3 -0
  1330. package/dist/devices/ubisys.d.ts.map +1 -0
  1331. package/dist/devices/ubisys.js +1295 -0
  1332. package/dist/devices/ubisys.js.map +1 -0
  1333. package/dist/devices/uhome.d.ts +3 -0
  1334. package/dist/devices/uhome.d.ts.map +1 -0
  1335. package/dist/devices/uhome.js +60 -0
  1336. package/dist/devices/uhome.js.map +1 -0
  1337. package/dist/devices/universal_electronics_inc.d.ts +3 -0
  1338. package/dist/devices/universal_electronics_inc.d.ts.map +1 -0
  1339. package/dist/devices/universal_electronics_inc.js +156 -0
  1340. package/dist/devices/universal_electronics_inc.js.map +1 -0
  1341. package/dist/devices/vav.d.ts +3 -0
  1342. package/dist/devices/vav.d.ts.map +1 -0
  1343. package/dist/devices/vav.js +57 -0
  1344. package/dist/devices/vav.js.map +1 -0
  1345. package/dist/devices/vbled.d.ts +3 -0
  1346. package/dist/devices/vbled.d.ts.map +1 -0
  1347. package/dist/devices/vbled.js +47 -0
  1348. package/dist/devices/vbled.js.map +1 -0
  1349. package/dist/devices/vesternet.d.ts +3 -0
  1350. package/dist/devices/vesternet.d.ts.map +1 -0
  1351. package/dist/devices/vesternet.js +355 -0
  1352. package/dist/devices/vesternet.js.map +1 -0
  1353. package/dist/devices/viessmann.d.ts +3 -0
  1354. package/dist/devices/viessmann.d.ts.map +1 -0
  1355. package/dist/devices/viessmann.js +120 -0
  1356. package/dist/devices/viessmann.js.map +1 -0
  1357. package/dist/devices/villeroy_boch.d.ts +3 -0
  1358. package/dist/devices/villeroy_boch.d.ts.map +1 -0
  1359. package/dist/devices/villeroy_boch.js +54 -0
  1360. package/dist/devices/villeroy_boch.js.map +1 -0
  1361. package/dist/devices/vimar.d.ts +3 -0
  1362. package/dist/devices/vimar.d.ts.map +1 -0
  1363. package/dist/devices/vimar.js +140 -0
  1364. package/dist/devices/vimar.js.map +1 -0
  1365. package/dist/devices/visonic.d.ts +3 -0
  1366. package/dist/devices/visonic.d.ts.map +1 -0
  1367. package/dist/devices/visonic.js +134 -0
  1368. package/dist/devices/visonic.js.map +1 -0
  1369. package/dist/devices/vrey.d.ts +3 -0
  1370. package/dist/devices/vrey.d.ts.map +1 -0
  1371. package/dist/devices/vrey.js +48 -0
  1372. package/dist/devices/vrey.js.map +1 -0
  1373. package/dist/devices/vsmart.d.ts +3 -0
  1374. package/dist/devices/vsmart.d.ts.map +1 -0
  1375. package/dist/devices/vsmart.js +442 -0
  1376. package/dist/devices/vsmart.js.map +1 -0
  1377. package/dist/devices/wally.d.ts +3 -0
  1378. package/dist/devices/wally.d.ts.map +1 -0
  1379. package/dist/devices/wally.js +60 -0
  1380. package/dist/devices/wally.js.map +1 -0
  1381. package/dist/devices/waxman.d.ts +3 -0
  1382. package/dist/devices/waxman.d.ts.map +1 -0
  1383. package/dist/devices/waxman.js +83 -0
  1384. package/dist/devices/waxman.js.map +1 -0
  1385. package/dist/devices/weiser.d.ts +3 -0
  1386. package/dist/devices/weiser.d.ts.map +1 -0
  1387. package/dist/devices/weiser.js +54 -0
  1388. package/dist/devices/weiser.js.map +1 -0
  1389. package/dist/devices/weten.d.ts +3 -0
  1390. package/dist/devices/weten.d.ts.map +1 -0
  1391. package/dist/devices/weten.js +83 -0
  1392. package/dist/devices/weten.js.map +1 -0
  1393. package/dist/devices/wirenboard.d.ts +3 -0
  1394. package/dist/devices/wirenboard.d.ts.map +1 -0
  1395. package/dist/devices/wirenboard.js +715 -0
  1396. package/dist/devices/wirenboard.js.map +1 -0
  1397. package/dist/devices/wisdom.d.ts +3 -0
  1398. package/dist/devices/wisdom.d.ts.map +1 -0
  1399. package/dist/devices/wisdom.js +47 -0
  1400. package/dist/devices/wisdom.js.map +1 -0
  1401. package/dist/devices/wmun.d.ts +3 -0
  1402. package/dist/devices/wmun.d.ts.map +1 -0
  1403. package/dist/devices/wmun.js +61 -0
  1404. package/dist/devices/wmun.js.map +1 -0
  1405. package/dist/devices/woolley.d.ts +3 -0
  1406. package/dist/devices/woolley.d.ts.map +1 -0
  1407. package/dist/devices/woolley.js +96 -0
  1408. package/dist/devices/woolley.js.map +1 -0
  1409. package/dist/devices/woox.d.ts +3 -0
  1410. package/dist/devices/woox.d.ts.map +1 -0
  1411. package/dist/devices/woox.js +194 -0
  1412. package/dist/devices/woox.js.map +1 -0
  1413. package/dist/devices/wyze.d.ts +3 -0
  1414. package/dist/devices/wyze.d.ts.map +1 -0
  1415. package/dist/devices/wyze.js +59 -0
  1416. package/dist/devices/wyze.js.map +1 -0
  1417. package/dist/devices/xal.d.ts +3 -0
  1418. package/dist/devices/xal.d.ts.map +1 -0
  1419. package/dist/devices/xal.js +61 -0
  1420. package/dist/devices/xal.js.map +1 -0
  1421. package/dist/devices/xenon.d.ts +4 -0
  1422. package/dist/devices/xenon.d.ts.map +1 -0
  1423. package/dist/devices/xenon.js +65 -0
  1424. package/dist/devices/xenon.js.map +1 -0
  1425. package/dist/devices/xinghuoyuan.d.ts +3 -0
  1426. package/dist/devices/xinghuoyuan.d.ts.map +1 -0
  1427. package/dist/devices/xinghuoyuan.js +47 -0
  1428. package/dist/devices/xinghuoyuan.js.map +1 -0
  1429. package/dist/devices/xyzroe.d.ts +3 -0
  1430. package/dist/devices/xyzroe.d.ts.map +1 -0
  1431. package/dist/devices/xyzroe.js +511 -0
  1432. package/dist/devices/xyzroe.js.map +1 -0
  1433. package/dist/devices/yale.d.ts +3 -0
  1434. package/dist/devices/yale.d.ts.map +1 -0
  1435. package/dist/devices/yale.js +686 -0
  1436. package/dist/devices/yale.js.map +1 -0
  1437. package/dist/devices/yandex.d.ts +3 -0
  1438. package/dist/devices/yandex.d.ts.map +1 -0
  1439. package/dist/devices/yandex.js +677 -0
  1440. package/dist/devices/yandex.js.map +1 -0
  1441. package/dist/devices/ynoa.d.ts +3 -0
  1442. package/dist/devices/ynoa.d.ts.map +1 -0
  1443. package/dist/devices/ynoa.js +116 -0
  1444. package/dist/devices/ynoa.js.map +1 -0
  1445. package/dist/devices/yokis.d.ts +3 -0
  1446. package/dist/devices/yokis.d.ts.map +1 -0
  1447. package/dist/devices/yokis.js +2972 -0
  1448. package/dist/devices/yokis.js.map +1 -0
  1449. package/dist/devices/yookee.d.ts +3 -0
  1450. package/dist/devices/yookee.d.ts.map +1 -0
  1451. package/dist/devices/yookee.js +59 -0
  1452. package/dist/devices/yookee.js.map +1 -0
  1453. package/dist/devices/ysrsai.d.ts +3 -0
  1454. package/dist/devices/ysrsai.d.ts.map +1 -0
  1455. package/dist/devices/ysrsai.js +68 -0
  1456. package/dist/devices/ysrsai.js.map +1 -0
  1457. package/dist/devices/zbeacon.d.ts +3 -0
  1458. package/dist/devices/zbeacon.d.ts.map +1 -0
  1459. package/dist/devices/zbeacon.js +54 -0
  1460. package/dist/devices/zbeacon.js.map +1 -0
  1461. package/dist/devices/zemismart.d.ts +3 -0
  1462. package/dist/devices/zemismart.d.ts.map +1 -0
  1463. package/dist/devices/zemismart.js +1061 -0
  1464. package/dist/devices/zemismart.js.map +1 -0
  1465. package/dist/devices/zen.d.ts +3 -0
  1466. package/dist/devices/zen.d.ts.map +1 -0
  1467. package/dist/devices/zen.js +93 -0
  1468. package/dist/devices/zen.js.map +1 -0
  1469. package/dist/devices/zigbeetlc.d.ts +3 -0
  1470. package/dist/devices/zigbeetlc.d.ts.map +1 -0
  1471. package/dist/devices/zigbeetlc.js +374 -0
  1472. package/dist/devices/zigbeetlc.js.map +1 -0
  1473. package/dist/devices/zipato.d.ts +3 -0
  1474. package/dist/devices/zipato.d.ts.map +1 -0
  1475. package/dist/devices/zipato.js +47 -0
  1476. package/dist/devices/zipato.js.map +1 -0
  1477. package/dist/devices/zunzunbee.d.ts +3 -0
  1478. package/dist/devices/zunzunbee.d.ts.map +1 -0
  1479. package/dist/devices/zunzunbee.js +97 -0
  1480. package/dist/devices/zunzunbee.js.map +1 -0
  1481. package/dist/index.d.ts +19 -0
  1482. package/dist/index.d.ts.map +1 -0
  1483. package/dist/index.js.map +1 -0
  1484. package/dist/indexer.d.ts +5 -0
  1485. package/dist/indexer.d.ts.map +1 -0
  1486. package/dist/indexer.js +135 -0
  1487. package/dist/indexer.js.map +1 -0
  1488. package/dist/lib/adurosmart.d.ts +15 -0
  1489. package/dist/lib/adurosmart.d.ts.map +1 -0
  1490. package/dist/lib/adurosmart.js +669 -0
  1491. package/dist/lib/adurosmart.js.map +1 -0
  1492. package/dist/lib/bosch.d.ts +353 -0
  1493. package/dist/lib/bosch.d.ts.map +1 -0
  1494. package/dist/lib/bosch.js +3163 -0
  1495. package/dist/lib/bosch.js.map +1 -0
  1496. package/dist/lib/color.d.ts +272 -0
  1497. package/dist/lib/color.d.ts.map +1 -0
  1498. package/dist/lib/color.js +766 -0
  1499. package/dist/lib/color.js.map +1 -0
  1500. package/dist/lib/constants.d.ts +78 -0
  1501. package/dist/lib/constants.d.ts.map +1 -0
  1502. package/dist/lib/constants.js +317 -0
  1503. package/dist/lib/constants.js.map +1 -0
  1504. package/dist/lib/develco.d.ts +50 -0
  1505. package/dist/lib/develco.d.ts.map +1 -0
  1506. package/dist/lib/develco.js +433 -0
  1507. package/dist/lib/develco.js.map +1 -0
  1508. package/dist/lib/ewelink.d.ts +30 -0
  1509. package/dist/lib/ewelink.d.ts.map +1 -0
  1510. package/dist/lib/ewelink.js +722 -0
  1511. package/dist/lib/ewelink.js.map +1 -0
  1512. package/dist/lib/exposes.d.ts +376 -0
  1513. package/dist/lib/exposes.d.ts.map +1 -0
  1514. package/dist/lib/exposes.js +1136 -0
  1515. package/dist/lib/exposes.js.map +1 -0
  1516. package/dist/lib/generateDefinition.d.ts +10 -0
  1517. package/dist/lib/generateDefinition.d.ts.map +1 -0
  1518. package/dist/lib/generateDefinition.js +773 -0
  1519. package/dist/lib/generateDefinition.js.map +1 -0
  1520. package/dist/lib/heiman.d.ts +92 -0
  1521. package/dist/lib/heiman.d.ts.map +1 -0
  1522. package/dist/lib/heiman.js +211 -0
  1523. package/dist/lib/heiman.js.map +1 -0
  1524. package/dist/lib/ikea.d.ts +106 -0
  1525. package/dist/lib/ikea.d.ts.map +1 -0
  1526. package/dist/lib/ikea.js +984 -0
  1527. package/dist/lib/ikea.js.map +1 -0
  1528. package/dist/lib/kelvinToXy.d.ts +8 -0
  1529. package/dist/lib/kelvinToXy.d.ts.map +1 -0
  1530. package/dist/lib/kelvinToXy.js +1913 -0
  1531. package/dist/lib/kelvinToXy.js.map +1 -0
  1532. package/dist/lib/ledvance.d.ts +20 -0
  1533. package/dist/lib/ledvance.d.ts.map +1 -0
  1534. package/dist/lib/ledvance.js +100 -0
  1535. package/dist/lib/ledvance.js.map +1 -0
  1536. package/dist/lib/legacy.d.ts +5197 -0
  1537. package/dist/lib/legacy.d.ts.map +1 -0
  1538. package/dist/lib/legacy.js +6865 -0
  1539. package/dist/lib/legacy.js.map +1 -0
  1540. package/dist/lib/legrand.d.ts +132 -0
  1541. package/dist/lib/legrand.d.ts.map +1 -0
  1542. package/dist/lib/legrand.js +404 -0
  1543. package/dist/lib/legrand.js.map +1 -0
  1544. package/dist/lib/light.d.ts +9 -0
  1545. package/dist/lib/light.d.ts.map +1 -0
  1546. package/dist/lib/light.js +144 -0
  1547. package/dist/lib/light.js.map +1 -0
  1548. package/dist/lib/logger.d.ts +4 -0
  1549. package/dist/lib/logger.d.ts.map +1 -0
  1550. package/dist/lib/logger.js +14 -0
  1551. package/dist/lib/logger.js.map +1 -0
  1552. package/dist/lib/lumi.d.ts +1093 -0
  1553. package/dist/lib/lumi.d.ts.map +1 -0
  1554. package/dist/lib/lumi.js +6479 -0
  1555. package/dist/lib/lumi.js.map +1 -0
  1556. package/dist/lib/modernExtend.d.ts +436 -0
  1557. package/dist/lib/modernExtend.d.ts.map +1 -0
  1558. package/dist/lib/modernExtend.js +2702 -0
  1559. package/dist/lib/modernExtend.js.map +1 -0
  1560. package/dist/lib/namron.d.ts +56 -0
  1561. package/dist/lib/namron.d.ts.map +1 -0
  1562. package/dist/lib/namron.js +433 -0
  1563. package/dist/lib/namron.js.map +1 -0
  1564. package/dist/lib/nodon.d.ts +3 -0
  1565. package/dist/lib/nodon.d.ts.map +1 -0
  1566. package/dist/lib/nodon.js +130 -0
  1567. package/dist/lib/nodon.js.map +1 -0
  1568. package/dist/lib/philips.d.ts +321 -0
  1569. package/dist/lib/philips.d.ts.map +1 -0
  1570. package/dist/lib/philips.js +876 -0
  1571. package/dist/lib/philips.js.map +1 -0
  1572. package/dist/lib/reporting.d.ts +57 -0
  1573. package/dist/lib/reporting.d.ts.map +1 -0
  1574. package/dist/lib/reporting.js +294 -0
  1575. package/dist/lib/reporting.js.map +1 -0
  1576. package/dist/lib/sonoff.d.ts +30 -0
  1577. package/dist/lib/sonoff.d.ts.map +1 -0
  1578. package/dist/lib/sonoff.js +91 -0
  1579. package/dist/lib/sonoff.js.map +1 -0
  1580. package/dist/lib/store.d.ts +7 -0
  1581. package/dist/lib/store.d.ts.map +1 -0
  1582. package/dist/lib/store.js +59 -0
  1583. package/dist/lib/store.js.map +1 -0
  1584. package/dist/lib/sunricher.d.ts +29 -0
  1585. package/dist/lib/sunricher.d.ts.map +1 -0
  1586. package/dist/lib/sunricher.js +838 -0
  1587. package/dist/lib/sunricher.js.map +1 -0
  1588. package/dist/lib/tuya.d.ts +998 -0
  1589. package/dist/lib/tuya.d.ts.map +1 -0
  1590. package/dist/lib/tuya.js +3043 -0
  1591. package/dist/lib/tuya.js.map +1 -0
  1592. package/dist/lib/types.d.ts +429 -0
  1593. package/dist/lib/types.d.ts.map +1 -0
  1594. package/dist/lib/types.js +3 -0
  1595. package/dist/lib/types.js.map +1 -0
  1596. package/dist/lib/ubisys.d.ts +107 -0
  1597. package/dist/lib/ubisys.d.ts.map +1 -0
  1598. package/dist/lib/ubisys.js +576 -0
  1599. package/dist/lib/ubisys.js.map +1 -0
  1600. package/dist/lib/utils.d.ts +95 -0
  1601. package/dist/lib/utils.d.ts.map +1 -0
  1602. package/dist/lib/utils.js +736 -0
  1603. package/dist/lib/utils.js.map +1 -0
  1604. package/dist/lib/zosung.d.ts +52 -0
  1605. package/dist/lib/zosung.d.ts.map +1 -0
  1606. package/dist/lib/zosung.js +264 -0
  1607. package/dist/lib/zosung.js.map +1 -0
  1608. package/dist/models-index.json +1 -0
  1609. package/package.json +2 -8
@@ -0,0 +1,4577 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
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
+ 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;
41
+ const zigbee_herdsman_1 = require("@willieee802/zigbee-herdsman");
42
+ const libColor = __importStar(require("../lib/color"));
43
+ const constants = __importStar(require("../lib/constants"));
44
+ const exposes = __importStar(require("../lib/exposes"));
45
+ const legacy = __importStar(require("../lib/legacy"));
46
+ const light = __importStar(require("../lib/light"));
47
+ const logger_1 = require("../lib/logger");
48
+ const globalStore = __importStar(require("../lib/store"));
49
+ const utils = __importStar(require("../lib/utils"));
50
+ const utils_1 = require("../lib/utils");
51
+ const NS = "zhc:tz";
52
+ const manufacturerOptions = {
53
+ sunricher: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.SHENZHEN_SUNRICHER_TECHNOLOGY_LTD },
54
+ 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
+ ikea: { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.IKEA_OF_SWEDEN },
59
+ 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
+ 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
+ };
66
+ exports.on_off = {
67
+ key: ["state", "on_time", "off_wait_time"],
68
+ convertSet: async (entity, key, value, meta) => {
69
+ const state = utils.isString(meta.message.state) ? meta.message.state.toLowerCase() : null;
70
+ utils.validateValue(state, ["toggle", "off", "on"]);
71
+ if (state === "on" && (meta.message.on_time != null || meta.message.off_wait_time != null)) {
72
+ const onTime = meta.message.on_time != null ? meta.message.on_time : 0;
73
+ const offWaitTime = meta.message.off_wait_time != null ? meta.message.off_wait_time : 0;
74
+ if (typeof onTime !== "number") {
75
+ throw new Error("The on_time value must be a number!");
76
+ }
77
+ if (typeof offWaitTime !== "number") {
78
+ throw new Error("The off_wait_time value must be a number!");
79
+ }
80
+ const payload = meta.converterOptions
81
+ ? // TODO: better typing? currently used in a single place??
82
+ meta.converterOptions
83
+ : { ctrlbits: 0, ontime: Math.round(onTime * 10), offwaittime: Math.round(offWaitTime * 10) };
84
+ await entity.command("genOnOff", "onWithTimedOff", payload, utils.getOptions(meta.mapped, entity));
85
+ }
86
+ else {
87
+ await entity.command("genOnOff", state, {}, utils.getOptions(meta.mapped, entity));
88
+ if (state === "toggle") {
89
+ const currentState = meta.state[`state${meta.endpoint_name ? `_${meta.endpoint_name}` : ""}`];
90
+ return currentState ? { state: { state: currentState === "OFF" ? "ON" : "OFF" } } : {};
91
+ }
92
+ return { state: { state: state.toUpperCase() } };
93
+ }
94
+ },
95
+ convertGet: async (entity, key, meta) => {
96
+ await entity.read("genOnOff", ["onOff"]);
97
+ },
98
+ };
99
+ exports.light_color = {
100
+ key: ["color"],
101
+ options: [exposes.options.color_sync(), exposes.options.transition()],
102
+ convertSet: async (entity, key, value, meta) => {
103
+ const newColor = libColor.Color.fromConverterArg(value);
104
+ const newState = {};
105
+ 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()) {
130
+ const hsv = newColor.hsv;
131
+ const hsvCorrected = hsv.colorCorrected(meta);
132
+ newState.color_mode = constants.colorModeLookup[0];
133
+ newState.color = hsv.toObject(false);
134
+ if (hsv.value !== null && utils.isObject(value)) {
135
+ await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: utils.mapNumberRange(hsvCorrected.value, 0, 100, 0, 254), transtime, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
136
+ }
137
+ if (hsv.hue !== null && hsv.saturation !== null) {
138
+ const saturation = utils.mapNumberRange(hsvCorrected.saturation, 0, 100, 0, 254);
139
+ if (supportsEnhancedHue) {
140
+ const enhancehue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 65535);
141
+ await entity.command("lightingColorCtrl", "enhancedMoveToHueAndSaturation", { transtime, enhancehue, saturation, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
142
+ }
143
+ else {
144
+ const hue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 254);
145
+ await entity.command("lightingColorCtrl", "moveToHueAndSaturation", { transtime, hue, saturation, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
146
+ }
147
+ }
148
+ else if (hsv.hue !== null) {
149
+ const direction = value.direction || 0;
150
+ if (supportsEnhancedHue) {
151
+ const enhancehue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 65535);
152
+ await entity.command("lightingColorCtrl", "enhancedMoveToHue", { transtime, enhancehue, direction, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
153
+ }
154
+ else {
155
+ const hue = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 254);
156
+ await entity.command("lightingColorCtrl", "moveToHue", { transtime, hue, direction, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
157
+ }
158
+ }
159
+ else if (hsv.saturation !== null) {
160
+ const saturation = utils.mapNumberRange(hsvCorrected.saturation, 0, 100, 0, 254);
161
+ await entity.command("lightingColorCtrl", "moveToSaturation", { transtime, saturation, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
162
+ }
163
+ }
164
+ else {
165
+ throw new Error("Invalid color");
166
+ }
167
+ return { state: libColor.syncColorState(newState, meta.state, entity, meta.options) };
168
+ },
169
+ convertGet: async (entity, key, meta) => {
170
+ await entity.read("lightingColorCtrl", light.readColorAttributes(entity, meta));
171
+ },
172
+ };
173
+ exports.light_colortemp = {
174
+ key: ["color_temp", "color_temp_percent"],
175
+ options: [exposes.options.color_sync(), exposes.options.transition()],
176
+ convertSet: async (entity, key, value, meta) => {
177
+ const [colorTempMin, colorTempMax] = light.findColorTempRange(entity);
178
+ const preset = { warmest: colorTempMax, warm: 454, neutral: 370, cool: 250, coolest: colorTempMin };
179
+ if (key === "color_temp_percent") {
180
+ utils.assertNumber(value);
181
+ value = utils
182
+ .mapNumberRange(value, 0, 100, colorTempMin != null ? colorTempMin : 154, colorTempMax != null ? colorTempMax : 500)
183
+ .toString();
184
+ }
185
+ if (utils.isString(value) && value in preset) {
186
+ value = utils.getFromLookup(value, preset);
187
+ }
188
+ value = Number(value);
189
+ // ensure value within range
190
+ utils.assertNumber(value);
191
+ value = light.clampColorTemp(value, colorTempMin, colorTempMax);
192
+ await entity.command("lightingColorCtrl", "moveToColorTemp", { colortemp: value, transtime: utils.getTransition(entity, key, meta).time, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
193
+ return {
194
+ state: libColor.syncColorState({ color_mode: constants.colorModeLookup[2], color_temp: value }, meta.state, entity, meta.options),
195
+ };
196
+ },
197
+ convertGet: async (entity, key, meta) => {
198
+ await entity.read("lightingColorCtrl", ["colorMode", "colorTemperature"]);
199
+ },
200
+ };
201
+ // #region Generic converters
202
+ exports.read = {
203
+ key: ["read"],
204
+ convertSet: async (entity, key, value, meta) => {
205
+ utils.assertObject(value, key);
206
+ const result = await entity.read(value.cluster, value.attributes, value.options != null ? value.options : {});
207
+ logger_1.logger.info(`Read result of '${value.cluster}': ${JSON.stringify(result)}`, NS);
208
+ if (value.state_property != null) {
209
+ return { state: { [value.state_property]: result } };
210
+ }
211
+ },
212
+ };
213
+ exports.write = {
214
+ key: ["write"],
215
+ convertSet: async (entity, key, value, meta) => {
216
+ utils.assertObject(value, key);
217
+ const options = utils.getOptions(meta.mapped, entity);
218
+ if (value.options != null) {
219
+ Object.assign(options, value.options);
220
+ }
221
+ await entity.write(value.cluster, value.payload, options);
222
+ logger_1.logger.info(`Wrote '${JSON.stringify(value.payload)}' to '${value.cluster}'`, NS);
223
+ },
224
+ };
225
+ exports.command = {
226
+ key: ["command"],
227
+ convertSet: async (entity, key, value, meta) => {
228
+ utils.assertObject(value, key);
229
+ const options = utils.getOptions(meta.mapped, entity);
230
+ await entity.command(value.cluster, value.command, value.payload != null ? value.payload : {}, options);
231
+ logger_1.logger.info(`Invoked '${value.cluster}.${value.command}' with payload '${JSON.stringify(value.payload)}'`, NS);
232
+ },
233
+ };
234
+ exports.factory_reset = {
235
+ key: ["reset"],
236
+ convertSet: async (entity, key, value, meta) => {
237
+ await entity.command("genBasic", "resetFactDefault", {}, utils.getOptions(meta.mapped, entity));
238
+ },
239
+ };
240
+ exports.identify = {
241
+ key: ["identify"],
242
+ options: [exposes.options.identify_timeout()],
243
+ convertSet: async (entity, key, value, meta) => {
244
+ // External value takes priority over options for compatibility
245
+ const identifyTimeout = value ?? meta.options.identify_timeout ?? 3;
246
+ await entity.command("genIdentify", "identify", { identifytime: identifyTimeout }, utils.getOptions(meta.mapped, entity));
247
+ },
248
+ };
249
+ exports.zcl_command = {
250
+ key: ["zclcommand"],
251
+ convertSet: async (entity, key, value, meta) => {
252
+ utils.assertObject(value, key);
253
+ const payload = value.payload != null ? value.payload : {};
254
+ utils.assertEndpoint(entity);
255
+ await entity.zclCommand(value.cluster, value.command, payload, value.options ?? {}, value.log_payload ?? {}, value.check_status ?? false, value.frametype ?? zigbee_herdsman_1.Zcl.FrameType.SPECIFIC);
256
+ if (value.logging ?? false) {
257
+ logger_1.logger.info(`Invoked ZCL command ${value.cluster}.${value.command} with payload '${JSON.stringify(payload)}'`, NS);
258
+ }
259
+ },
260
+ };
261
+ exports.arm_mode = {
262
+ key: ["arm_mode"],
263
+ convertSet: async (entity, key, value, meta) => {
264
+ utils.assertEndpoint(entity);
265
+ utils.assertObject(value, key);
266
+ if (Array.isArray(meta.mapped))
267
+ throw new Error("Not supported for groups");
268
+ const isNotification = value.transaction != null;
269
+ const modeSrc = isNotification ? constants.armNotification : constants.armMode;
270
+ const mode = utils.getKey(modeSrc, value.mode, undefined, Number);
271
+ if (mode === undefined) {
272
+ throw new Error(`Unsupported mode: '${value.mode}', should be one of: ${Object.values(modeSrc)}`);
273
+ }
274
+ if (isNotification) {
275
+ await entity.commandResponse("ssIasAce", "armRsp", { armnotification: mode }, {}, value.transaction);
276
+ // Do not update PanelStatus after confirming transaction.
277
+ // Instead the server should send an arm_mode command with the necessary state.
278
+ // e.g. exit_delay as a result of arm_all_zones
279
+ return;
280
+ }
281
+ let panelStatus = mode;
282
+ if (meta.mapped.model === "3400-D") {
283
+ panelStatus = mode !== 0 && mode !== 4 ? 0x80 : 0x00;
284
+ }
285
+ let secondsRemain = 0;
286
+ let delayUntil = 0;
287
+ if ((mode === 4 || mode === 5) && value.delay != null) {
288
+ utils.assertNumber(value.delay, "delay");
289
+ if (!utils.isInRange(0, constants.iasMaxSecondsRemain, value.delay)) {
290
+ throw new Error(`Invalid delay value: ${value.delay} (expected ${0} to ${constants.iasMaxSecondsRemain})`);
291
+ }
292
+ secondsRemain = Math.round(value.delay);
293
+ delayUntil = performance.now() + value.delay * 1000;
294
+ }
295
+ globalStore.putValue(entity, "panelStatus", panelStatus);
296
+ globalStore.putValue(entity, "delayUntil", delayUntil);
297
+ const payload = { panelstatus: panelStatus, secondsremain: secondsRemain, audiblenotif: 0, alarmstatus: 0 };
298
+ await entity.commandResponse("ssIasAce", "panelStatusChanged", payload);
299
+ },
300
+ };
301
+ exports.battery_percentage_remaining = {
302
+ key: ["battery"],
303
+ convertGet: async (entity, key, meta) => {
304
+ await entity.read("genPowerCfg", ["batteryPercentageRemaining"]);
305
+ },
306
+ };
307
+ exports.battery_voltage = {
308
+ key: ["battery", "voltage"],
309
+ convertGet: async (entity, key, meta) => {
310
+ await entity.read("genPowerCfg", ["batteryVoltage"]);
311
+ },
312
+ };
313
+ exports.power_on_behavior = {
314
+ key: ["power_on_behavior"],
315
+ convertSet: async (entity, key, value, meta) => {
316
+ utils.assertString(value, key);
317
+ value = value.toLowerCase();
318
+ const lookup = { off: 0, on: 1, toggle: 2, previous: 255 };
319
+ try {
320
+ await entity.write("genOnOff", { startUpOnOff: utils.getFromLookup(value, lookup) }, utils.getOptions(meta.mapped, entity));
321
+ }
322
+ catch (error) {
323
+ if (error.message.includes("UNSUPPORTED_ATTRIBUTE")) {
324
+ throw new Error("Got `UNSUPPORTED_ATTRIBUTE` error, device does not support power on behaviour");
325
+ }
326
+ throw error;
327
+ }
328
+ return { state: { power_on_behavior: value } };
329
+ },
330
+ convertGet: async (entity, key, meta) => {
331
+ await entity.read("genOnOff", ["startUpOnOff"]);
332
+ },
333
+ };
334
+ exports.light_color_mode = {
335
+ key: ["color_mode"],
336
+ convertGet: async (entity, key, meta) => {
337
+ await entity.read("lightingColorCtrl", ["colorMode"]);
338
+ },
339
+ };
340
+ exports.light_color_options = {
341
+ key: ["color_options"],
342
+ convertSet: async (entity, key, value, meta) => {
343
+ utils.assertObject(value, key);
344
+ const options = value.execute_if_off != null && value.execute_if_off ? 1 : 0;
345
+ await entity.write("lightingColorCtrl", { options }, utils.getOptions(meta.mapped, entity));
346
+ return { state: { color_options: value } };
347
+ },
348
+ convertGet: async (entity, key, meta) => {
349
+ await entity.read("lightingColorCtrl", ["options"]);
350
+ },
351
+ };
352
+ exports.lock = {
353
+ key: ["state"],
354
+ convertSet: async (entity, key, value, meta) => {
355
+ // If no pin code is provided, value is a only string. Ex: "UNLOCK"
356
+ let state = utils.isString(value) ? value.toUpperCase() : null;
357
+ let pincode = "";
358
+ // If pin code is provided, value is an object including new state and code. Ex: {state: "UNLOCK", code: "1234"}
359
+ if (utils.isObject(value)) {
360
+ if (value.code) {
361
+ pincode = utils.isString(value.code) ? value.code : "";
362
+ }
363
+ if (value.state) {
364
+ state = utils.isString(value.state) ? value.state.toUpperCase() : null;
365
+ }
366
+ }
367
+ utils.validateValue(state, ["LOCK", "UNLOCK", "TOGGLE"]);
368
+ await entity.command("closuresDoorLock", `${state.toLowerCase()}Door`, { pincodevalue: Buffer.from(pincode, "ascii") }, utils.getOptions(meta.mapped, entity));
369
+ },
370
+ convertGet: async (entity, key, meta) => {
371
+ await entity.read("closuresDoorLock", ["lockState"]);
372
+ },
373
+ };
374
+ exports.lock_auto_relock_time = {
375
+ key: ["auto_relock_time"],
376
+ convertSet: async (entity, key, value, meta) => {
377
+ await entity.write("closuresDoorLock", { autoRelockTime: value }, utils.getOptions(meta.mapped, entity));
378
+ return { state: { auto_relock_time: value } };
379
+ },
380
+ convertGet: async (entity, key, meta) => {
381
+ await entity.read("closuresDoorLock", ["autoRelockTime"]);
382
+ },
383
+ };
384
+ exports.lock_sound_volume = {
385
+ key: ["sound_volume"],
386
+ convertSet: async (entity, key, value, meta) => {
387
+ utils.assertString(value, key);
388
+ utils.validateValue(value, constants.lockSoundVolume);
389
+ await entity.write("closuresDoorLock", { soundVolume: constants.lockSoundVolume.indexOf(value) }, utils.getOptions(meta.mapped, entity));
390
+ return { state: { sound_volume: value } };
391
+ },
392
+ convertGet: async (entity, key, meta) => {
393
+ await entity.read("closuresDoorLock", ["soundVolume"]);
394
+ },
395
+ };
396
+ exports.pincode_lock = {
397
+ key: ["pin_code"],
398
+ convertSet: async (entity, key, value, meta) => {
399
+ utils.assertObject(value, key);
400
+ const user = value.user;
401
+ const userType = value.user_type || "unrestricted";
402
+ const userEnabled = value.user_enabled != null ? value.user_enabled : true;
403
+ const pinCode = value.pin_code;
404
+ if (Number.isNaN(user))
405
+ throw new Error("user must be numbers");
406
+ const pinCodeCount = utils.getMetaValue(entity, meta.mapped, "pinCodeCount");
407
+ if (!utils.isInRange(0, pinCodeCount - 1, user))
408
+ throw new Error("user must be in range for device");
409
+ if (pinCode == null) {
410
+ await entity.command("closuresDoorLock", "clearPinCode", { userid: user }, utils.getOptions(meta.mapped, entity));
411
+ }
412
+ else {
413
+ if (Number.isNaN(pinCode))
414
+ throw new Error("pinCode must be a number");
415
+ const typeLookup = { unrestricted: 0, year_day_schedule: 1, week_day_schedule: 2, master: 3, non_access: 4 };
416
+ const payload = {
417
+ userid: user,
418
+ userstatus: userEnabled ? 1 : 3,
419
+ usertype: utils.getFromLookup(userType, typeLookup),
420
+ pincodevalue: pinCode.toString(),
421
+ };
422
+ await entity.command("closuresDoorLock", "setPinCode", payload, utils.getOptions(meta.mapped, entity));
423
+ }
424
+ },
425
+ convertGet: async (entity, key, meta) => {
426
+ // @ts-expect-error ignore
427
+ const user = meta?.message?.pin_code ? meta.message.pin_code.user : undefined;
428
+ if (user === undefined) {
429
+ const max = utils.getMetaValue(entity, meta.mapped, "pinCodeCount");
430
+ // Get all
431
+ const options = utils.getOptions(meta.mapped, entity);
432
+ for (let i = 0; i < max; i++) {
433
+ await entity.command("closuresDoorLock", "getPinCode", { userid: i }, options);
434
+ }
435
+ }
436
+ else {
437
+ if (Number.isNaN(user)) {
438
+ throw new Error("user must be numbers");
439
+ }
440
+ const pinCodeCount = utils.getMetaValue(entity, meta.mapped, "pinCodeCount");
441
+ if (!utils.isInRange(0, pinCodeCount - 1, user)) {
442
+ throw new Error("userId must be in range for device");
443
+ }
444
+ await entity.command("closuresDoorLock", "getPinCode", { userid: user }, utils.getOptions(meta.mapped, entity));
445
+ }
446
+ },
447
+ };
448
+ exports.lock_userstatus = {
449
+ key: ["user_status"],
450
+ convertSet: async (entity, key, value, meta) => {
451
+ utils.assertObject(value, key);
452
+ const user = value.user;
453
+ if (Number.isNaN(user)) {
454
+ throw new Error("user must be numbers");
455
+ }
456
+ const pinCodeCount = utils.getMetaValue(entity, meta.mapped, "pinCodeCount");
457
+ if (!utils.isInRange(0, pinCodeCount - 1, user)) {
458
+ throw new Error("user must be in range for device");
459
+ }
460
+ const status = utils.getKey(constants.lockUserStatus, value.status, undefined, Number);
461
+ if (status === undefined) {
462
+ throw new Error(`Unsupported status: '${value.status}', should be one of: ${Object.values(constants.lockUserStatus)}`);
463
+ }
464
+ await entity.command("closuresDoorLock", "setUserStatus", {
465
+ userid: user,
466
+ userstatus: status,
467
+ }, utils.getOptions(meta.mapped, entity));
468
+ },
469
+ convertGet: async (entity, key, meta) => {
470
+ // @ts-expect-error ignore
471
+ const user = meta?.message?.user_status ? meta.message.user_status.user : undefined;
472
+ const pinCodeCount = utils.getMetaValue(entity, meta.mapped, "pinCodeCount");
473
+ if (user === undefined) {
474
+ const max = pinCodeCount;
475
+ // Get all
476
+ const options = utils.getOptions(meta.mapped, entity);
477
+ for (let i = 0; i < max; i++) {
478
+ await entity.command("closuresDoorLock", "getUserStatus", { userid: i }, options);
479
+ }
480
+ }
481
+ else {
482
+ if (Number.isNaN(user)) {
483
+ throw new Error("user must be numbers");
484
+ }
485
+ if (!utils.isInRange(0, pinCodeCount - 1, user)) {
486
+ throw new Error("userId must be in range for device");
487
+ }
488
+ await entity.command("closuresDoorLock", "getUserStatus", { userid: user }, utils.getOptions(meta.mapped, entity));
489
+ }
490
+ },
491
+ };
492
+ exports.cover_via_brightness = {
493
+ key: ["position", "state"],
494
+ options: [exposes.options.invert_cover()],
495
+ convertSet: async (entity, key, value, meta) => {
496
+ if (typeof value !== "number") {
497
+ utils.assertString(value, key);
498
+ value = value.toLowerCase();
499
+ if (value === "stop") {
500
+ await entity.command("genLevelCtrl", "stop", { optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
501
+ return;
502
+ }
503
+ const lookup = { open: 100, close: 0 };
504
+ value = utils.getFromLookup(value, lookup);
505
+ }
506
+ const invert = utils.getMetaValue(entity, meta.mapped, "coverInverted", "allEqual", false)
507
+ ? !meta.options.invert_cover
508
+ : meta.options.invert_cover;
509
+ utils.assertNumber(value);
510
+ const position = invert ? 100 - value : value;
511
+ await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: utils.mapNumberRange(Number(position), 0, 100, 0, 255), transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
512
+ return { state: { position: value } };
513
+ },
514
+ convertGet: async (entity, key, meta) => {
515
+ await entity.read("genLevelCtrl", ["currentLevel"]);
516
+ },
517
+ };
518
+ exports.warning = {
519
+ key: ["warning"],
520
+ convertSet: async (entity, key, value, meta) => {
521
+ const mode = { stop: 0, burglar: 1, fire: 2, emergency: 3, police_panic: 4, fire_panic: 5, emergency_panic: 6 };
522
+ const level = { low: 0, medium: 1, high: 2, very_high: 3 };
523
+ const strobeLevel = { low: 0, medium: 1, high: 2, very_high: 3 };
524
+ const values = {
525
+ // @ts-expect-error ignore
526
+ mode: value.mode || "emergency",
527
+ // @ts-expect-error ignore
528
+ level: value.level || "medium",
529
+ // @ts-expect-error ignore
530
+ strobe: value.strobe != null ? value.strobe : true,
531
+ // @ts-expect-error ignore
532
+ duration: value.duration != null ? value.duration : 10,
533
+ // @ts-expect-error ignore
534
+ strobeDutyCycle: value.strobe_duty_cycle != null ? value.strobe_duty_cycle * 10 : 0,
535
+ // @ts-expect-error ignore
536
+ strobeLevel: value.strobe_level != null ? utils.getFromLookup(value.strobe_level, strobeLevel) : 1,
537
+ };
538
+ // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
539
+ let info;
540
+ // https://github.com/Koenkk/zigbee2mqtt/issues/8310 some devices require the info to be reversed.
541
+ if (Array.isArray(meta.mapped))
542
+ throw new Error("Not supported for groups");
543
+ // SIRZB-110/111 require all-zero info byte to reliably stop the siren.
544
+ if (values.mode === "stop" && ["SIRZB-110", "SIRZB-111"].includes(meta.mapped.model)) {
545
+ // @ts-expect-error ignore
546
+ if (value.level == null)
547
+ values.level = "low";
548
+ // @ts-expect-error ignore
549
+ if (value.strobe == null)
550
+ values.strobe = false;
551
+ }
552
+ if (["SIRZB-110", "SRAC-23B-ZBSR", "AV2010/29A", "AV2010/24A"].includes(meta.mapped.model)) {
553
+ info = utils.getFromLookup(values.mode, mode) + ((values.strobe ? 1 : 0) << 4) + (utils.getFromLookup(values.level, level) << 6);
554
+ }
555
+ else {
556
+ info = (utils.getFromLookup(values.mode, mode) << 4) + ((values.strobe ? 1 : 0) << 2) + utils.getFromLookup(values.level, level);
557
+ }
558
+ await entity.command("ssIasWd", "startWarning", { startwarninginfo: info, warningduration: values.duration, strobedutycycle: values.strobeDutyCycle, strobelevel: values.strobeLevel }, utils.getOptions(meta.mapped, entity));
559
+ },
560
+ };
561
+ exports.ias_max_duration = {
562
+ key: ["max_duration"],
563
+ convertSet: async (entity, key, value, meta) => {
564
+ await entity.write("ssIasWd", { maxDuration: value });
565
+ return { state: { max_duration: value } };
566
+ },
567
+ convertGet: async (entity, key, meta) => {
568
+ await entity.read("ssIasWd", ["maxDuration"]);
569
+ },
570
+ };
571
+ exports.warning_simple = {
572
+ key: ["alarm"],
573
+ convertSet: async (entity, key, value, meta) => {
574
+ const alarmState = value === "alarm" || value === "OFF" ? 0 : 1;
575
+ // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
576
+ let info;
577
+ // For Develco SMSZB-120 and HESZB-120, introduced change in fw 4.0.5, tested backward with 4.0.4
578
+ if (Array.isArray(meta.mapped))
579
+ throw new Error("Not supported for groups");
580
+ if (["SMSZB-120", "HESZB-120"].includes(meta.mapped.model)) {
581
+ info = (alarmState << 7) + (alarmState << 6);
582
+ }
583
+ else if (meta.mapped.model === "SIRZB-110") {
584
+ // ZCL-compliant layout: bits 0-3=mode, bit 4=strobe, bits 6-7=level
585
+ // OFF: info=0 (mode=stop, level=low, strobe=off — device requires level=0 to stop)
586
+ // ON: emergency(3) + strobe(1<<4) + very_high(3<<6) = 211
587
+ info = alarmState === 0 ? 0 : 3 + (1 << 4) + (3 << 6);
588
+ }
589
+ else if (meta.mapped.model === "SIRZB-111") {
590
+ // Generic layout: bits 4-7=mode, bit 2=strobe, bits 0-1=level
591
+ // OFF: info=0, ON: (emergency<<4) + (strobe<<2) + very_high = 55
592
+ info = alarmState === 0 ? 0 : (3 << 4) + (1 << 2) + 3;
593
+ }
594
+ else {
595
+ info = (3 << 6) + (alarmState << 2);
596
+ }
597
+ await entity.command("ssIasWd", "startWarning", { startwarninginfo: info, warningduration: 300, strobedutycycle: 0, strobelevel: 0 }, utils.getOptions(meta.mapped, entity));
598
+ },
599
+ };
600
+ exports.squawk = {
601
+ key: ["squawk"],
602
+ convertSet: async (entity, key, value, meta) => {
603
+ utils.assertObject(value, key);
604
+ const state = { system_is_armed: 0, system_is_disarmed: 1 };
605
+ const level = { low: 0, medium: 1, high: 2, very_high: 3 };
606
+ const values = {
607
+ state: value.state,
608
+ level: value.level || "very_high",
609
+ strobe: value.strobe != null ? value.strobe : false,
610
+ };
611
+ const info = utils.getFromLookup(values.state, state) + ((values.strobe ? 1 : 0) << 4) + (utils.getFromLookup(values.level, level) << 6);
612
+ await entity.command("ssIasWd", "squawk", { squawkinfo: info }, utils.getOptions(meta.mapped, entity));
613
+ },
614
+ };
615
+ exports.cover_state = {
616
+ key: ["state"],
617
+ convertSet: async (entity, key, value, meta) => {
618
+ const lookup = {
619
+ open: "upOpen",
620
+ close: "downClose",
621
+ stop: "stop",
622
+ on: "upOpen",
623
+ off: "downClose",
624
+ };
625
+ utils.assertString(value, key);
626
+ await entity.command("closuresWindowCovering", utils.getFromLookup(value.toLowerCase(), lookup), {}, utils.getOptions(meta.mapped, entity));
627
+ },
628
+ };
629
+ exports.cover_position_tilt = {
630
+ key: ["position", "tilt"],
631
+ options: [exposes.options.invert_cover(), exposes.options.cover_position_tilt_disable_report()],
632
+ convertSet: async (entity, key, value, meta) => {
633
+ utils.assertNumber(value, key);
634
+ const isPosition = key === "position";
635
+ const invert = !(utils.getMetaValue(entity, meta.mapped, "coverInverted", "allEqual", false)
636
+ ? !meta.options.invert_cover
637
+ : meta.options.invert_cover);
638
+ const disableReport = utils.getMetaValue(entity, meta.mapped, "coverPositionTiltDisableReport", "allEqual", false)
639
+ ? !meta.options.cover_position_tilt_disable_report
640
+ : meta.options.cover_position_tilt_disable_report;
641
+ const position = invert ? 100 - value : value;
642
+ // Zigbee officially expects 'open' to be 0 and 'closed' to be 100 whereas
643
+ // HomeAssistant etc. work the other way round.
644
+ // For zigbee-herdsman-converters: open = 100, close = 0
645
+ await entity.command("closuresWindowCovering", isPosition ? "goToLiftPercentage" : "goToTiltPercentage", isPosition ? { percentageliftvalue: position } : { percentagetiltvalue: position }, utils.getOptions(meta.mapped, entity));
646
+ if (disableReport) {
647
+ return;
648
+ }
649
+ return { state: { [isPosition ? "position" : "tilt"]: value } };
650
+ },
651
+ convertGet: async (entity, key, meta) => {
652
+ const isPosition = key === "position";
653
+ await entity.read("closuresWindowCovering", [isPosition ? "currentPositionLiftPercentage" : "currentPositionTiltPercentage"]);
654
+ },
655
+ };
656
+ exports.cover_mode = {
657
+ key: ["cover_mode"],
658
+ convertSet: async (entity, key, value, meta) => {
659
+ utils.assertObject(value, key);
660
+ const windowCoveringMode = ((value.reversed ? 1 : 0) << 0) | ((value.calibration ? 1 : 0) << 1) | ((value.maintenance ? 1 : 0) << 2) | ((value.led ? 1 : 0) << 3);
661
+ await entity.write("closuresWindowCovering", { windowCoveringMode }, utils.getOptions(meta.mapped, entity));
662
+ return { state: { cover_mode: value } };
663
+ },
664
+ convertGet: async (entity, key, meta) => {
665
+ await entity.read("closuresWindowCovering", ["windowCoveringMode"]);
666
+ },
667
+ };
668
+ exports.occupancy_timeout = {
669
+ // Sets delay after motion detector changes from occupied to unoccupied
670
+ key: ["occupancy_timeout"],
671
+ convertSet: async (entity, key, value, meta) => {
672
+ utils.assertNumber(value);
673
+ value *= 1;
674
+ await entity.write("msOccupancySensing", { pirOToUDelay: value }, utils.getOptions(meta.mapped, entity));
675
+ return { state: { occupancy_timeout: value } };
676
+ },
677
+ convertGet: async (entity, key, meta) => {
678
+ await entity.read("msOccupancySensing", ["pirOToUDelay"]);
679
+ },
680
+ };
681
+ exports.level_config = {
682
+ key: ["level_config"],
683
+ convertSet: async (entity, key, value, meta) => {
684
+ const state = {};
685
+ // parse payload to grab the keys
686
+ if (typeof value === "string") {
687
+ try {
688
+ value = JSON.parse(value);
689
+ }
690
+ catch {
691
+ throw new Error("Payload is not valid JSON");
692
+ }
693
+ }
694
+ utils.assertObject(value, key);
695
+ // onOffTransitionTime - range 0x0000 to 0xffff - optional
696
+ if (value.on_off_transition_time != null) {
697
+ let onOffTransitionTimeValue = Number(value.on_off_transition_time);
698
+ if (onOffTransitionTimeValue > 65535)
699
+ onOffTransitionTimeValue = 65535;
700
+ if (onOffTransitionTimeValue < 0)
701
+ onOffTransitionTimeValue = 0;
702
+ await entity.write("genLevelCtrl", { onOffTransitionTime: onOffTransitionTimeValue }, utils.getOptions(meta.mapped, entity));
703
+ Object.assign(state, { on_off_transition_time: onOffTransitionTimeValue });
704
+ }
705
+ // onTransitionTime - range 0x0000 to 0xffff - optional
706
+ // 0xffff = use onOffTransitionTime
707
+ if (value.on_transition_time != null) {
708
+ let onTransitionTimeValue = value.on_transition_time;
709
+ if (typeof onTransitionTimeValue === "string" && onTransitionTimeValue.toLowerCase() === "disabled") {
710
+ onTransitionTimeValue = 65535;
711
+ }
712
+ else {
713
+ onTransitionTimeValue = Number(onTransitionTimeValue);
714
+ }
715
+ if (onTransitionTimeValue > 65535)
716
+ onTransitionTimeValue = 65534;
717
+ if (onTransitionTimeValue < 0)
718
+ onTransitionTimeValue = 0;
719
+ await entity.write("genLevelCtrl", { onTransitionTime: onTransitionTimeValue }, utils.getOptions(meta.mapped, entity));
720
+ // reverse translate number -> preset
721
+ if (onTransitionTimeValue === 65535) {
722
+ onTransitionTimeValue = "disabled";
723
+ }
724
+ Object.assign(state, { on_transition_time: onTransitionTimeValue });
725
+ }
726
+ // offTransitionTime - range 0x0000 to 0xffff - optional
727
+ // 0xffff = use onOffTransitionTime
728
+ if (value.off_transition_time != null) {
729
+ let offTransitionTimeValue = value.off_transition_time;
730
+ if (typeof offTransitionTimeValue === "string" && offTransitionTimeValue.toLowerCase() === "disabled") {
731
+ offTransitionTimeValue = 65535;
732
+ }
733
+ else {
734
+ offTransitionTimeValue = Number(offTransitionTimeValue);
735
+ }
736
+ if (offTransitionTimeValue > 65535)
737
+ offTransitionTimeValue = 65534;
738
+ if (offTransitionTimeValue < 0)
739
+ offTransitionTimeValue = 0;
740
+ await entity.write("genLevelCtrl", { offTransitionTime: offTransitionTimeValue }, utils.getOptions(meta.mapped, entity));
741
+ // reverse translate number -> preset
742
+ if (offTransitionTimeValue === 65535) {
743
+ offTransitionTimeValue = "disabled";
744
+ }
745
+ Object.assign(state, { off_transition_time: offTransitionTimeValue });
746
+ }
747
+ // startUpCurrentLevel - range 0x00 to 0xff - optional
748
+ // 0x00 = return to minimum supported level
749
+ // 0xff = return to previous previous
750
+ if (value.current_level_startup != null) {
751
+ let startUpCurrentLevelValue = value.current_level_startup;
752
+ if (typeof startUpCurrentLevelValue === "string" && startUpCurrentLevelValue.toLowerCase() === "previous") {
753
+ startUpCurrentLevelValue = 255;
754
+ }
755
+ else if (typeof startUpCurrentLevelValue === "string" && startUpCurrentLevelValue.toLowerCase() === "minimum") {
756
+ startUpCurrentLevelValue = 0;
757
+ }
758
+ else {
759
+ startUpCurrentLevelValue = Number(startUpCurrentLevelValue);
760
+ }
761
+ if (startUpCurrentLevelValue > 255)
762
+ startUpCurrentLevelValue = 254;
763
+ if (startUpCurrentLevelValue < 0)
764
+ startUpCurrentLevelValue = 1;
765
+ await entity.write("genLevelCtrl", { startUpCurrentLevel: startUpCurrentLevelValue }, utils.getOptions(meta.mapped, entity));
766
+ // reverse translate number -> preset
767
+ if (startUpCurrentLevelValue === 255) {
768
+ startUpCurrentLevelValue = "previous";
769
+ }
770
+ if (startUpCurrentLevelValue === 0) {
771
+ startUpCurrentLevelValue = "minimum";
772
+ }
773
+ Object.assign(state, { current_level_startup: startUpCurrentLevelValue });
774
+ }
775
+ // onLevel - range 0x00 to 0xff - optional
776
+ // Any value outside of MinLevel to MaxLevel, including 0xff and 0x00, is interpreted as "previous".
777
+ if (value.on_level != null) {
778
+ let onLevel = value.on_level;
779
+ if (typeof onLevel === "string" && onLevel.toLowerCase() === "previous") {
780
+ onLevel = 255;
781
+ }
782
+ else {
783
+ onLevel = Number(onLevel);
784
+ }
785
+ if (onLevel > 255)
786
+ onLevel = 254;
787
+ if (onLevel < 1)
788
+ onLevel = 1;
789
+ await entity.write("genLevelCtrl", { onLevel }, utils.getOptions(meta.mapped, entity));
790
+ Object.assign(state, { on_level: onLevel === 255 ? "previous" : onLevel });
791
+ }
792
+ // options - 8-bit map
793
+ // bit 0: ExecuteIfOff - when 0, Move commands are ignored if the device is off;
794
+ // when 1, CurrentLevel can be changed while the device is off.
795
+ // bit 1: CoupleColorTempToLevel - when 1, changes to level also change color temperature.
796
+ // (What this means is not defined, but it's most likely to be "dim to warm".)
797
+ if (value.execute_if_off != null) {
798
+ const executeIfOffValue = !!value.execute_if_off;
799
+ await entity.write("genLevelCtrl", { options: executeIfOffValue ? 1 : 0 }, utils.getOptions(meta.mapped, entity));
800
+ Object.assign(state, { execute_if_off: executeIfOffValue });
801
+ }
802
+ if (Object.keys(state).length > 0) {
803
+ return { state: { level_config: state } };
804
+ }
805
+ },
806
+ convertGet: async (entity, key, meta) => {
807
+ for (const attribute of [
808
+ "onOffTransitionTime",
809
+ "onTransitionTime",
810
+ "offTransitionTime",
811
+ "startUpCurrentLevel",
812
+ "onLevel",
813
+ "options",
814
+ ]) {
815
+ try {
816
+ await entity.read("genLevelCtrl", [attribute]);
817
+ }
818
+ catch {
819
+ // continue regardless of error, all these are optional in ZCL
820
+ }
821
+ }
822
+ },
823
+ };
824
+ exports.ballast_config = {
825
+ key: ["ballast_config", "ballast_minimum_level", "ballast_maximum_level", "ballast_power_on_level"],
826
+ // zcl attribute names are camel case, but we want to use snake case in the outside communication
827
+ convertSet: async (entity, key, value, meta) => {
828
+ if (key === "ballast_config") {
829
+ value = utils.toCamelCase(value);
830
+ for (const [attrName, attrValue] of Object.entries(value)) {
831
+ const attributes = { [attrName]: attrValue };
832
+ await entity.write("lightingBallastCfg", attributes);
833
+ }
834
+ }
835
+ if (key === "ballast_minimum_level") {
836
+ await entity.write("lightingBallastCfg", { minLevel: value });
837
+ }
838
+ if (key === "ballast_maximum_level") {
839
+ await entity.write("lightingBallastCfg", { maxLevel: value });
840
+ }
841
+ if (key === "ballast_power_on_level") {
842
+ await entity.write("lightingBallastCfg", { powerOnLevel: value });
843
+ }
844
+ return { state: { [key]: value } };
845
+ },
846
+ convertGet: async (entity, key, meta) => {
847
+ let result = {};
848
+ for (const attrName of [
849
+ "ballastStatus",
850
+ "minLevel",
851
+ "maxLevel",
852
+ "powerOnLevel",
853
+ "powerOnFadeTime",
854
+ "intrinsicBallastFactor",
855
+ "ballastFactorAdjustment",
856
+ "lampQuantity",
857
+ "lampType",
858
+ "lampManufacturer",
859
+ "lampRatedHours",
860
+ "lampBurnHours",
861
+ "lampAlarmMode",
862
+ "lampBurnHoursTripPoint",
863
+ ]) {
864
+ try {
865
+ result = { ...result, ...(await entity.read("lightingBallastCfg", [attrName])) };
866
+ }
867
+ catch {
868
+ // continue regardless of error
869
+ }
870
+ }
871
+ if (key === "ballast_config") {
872
+ logger_1.logger.debug(`ballast_config attribute results received: ${JSON.stringify(utils.toSnakeCase(result))}`, NS);
873
+ }
874
+ },
875
+ };
876
+ exports.light_brightness_step = {
877
+ key: ["brightness_step", "brightness_step_onoff"],
878
+ options: [exposes.options.transition()],
879
+ convertSet: async (entity, key, value, meta) => {
880
+ const onOff = key.endsWith("_onoff");
881
+ const command = onOff ? "stepWithOnOff" : "step";
882
+ value = Number(value);
883
+ utils.assertNumber(value, key);
884
+ const mode = value > 0 ? 0 : 1;
885
+ const transition = utils.getTransition(entity, key, meta).time;
886
+ await entity.command("genLevelCtrl", command, { stepmode: mode, stepsize: Math.abs(value), transtime: transition, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
887
+ if (meta.state.brightness !== undefined) {
888
+ utils.assertNumber(meta.state.brightness);
889
+ let brightness = onOff || meta.state.state === "ON" ? meta.state.brightness + value : meta.state.brightness;
890
+ if (value === 0) {
891
+ const entityToRead = utils.getEntityOrFirstGroupMember(entity);
892
+ if (entityToRead) {
893
+ brightness = (await entityToRead.read("genLevelCtrl", ["currentLevel"])).currentLevel;
894
+ }
895
+ }
896
+ brightness = Math.min(254, brightness);
897
+ brightness = Math.max(onOff || meta.state.state === "OFF" ? 0 : 1, brightness);
898
+ if (utils.getMetaValue(entity, meta.mapped, "turnsOffAtBrightness1", "allEqual", false)) {
899
+ if (onOff && value < 0 && brightness === 1) {
900
+ brightness = 0;
901
+ }
902
+ else if (onOff && value > 0 && meta.state.brightness === 0) {
903
+ brightness++;
904
+ }
905
+ }
906
+ return { state: { brightness, state: brightness === 0 ? "OFF" : "ON" } };
907
+ }
908
+ },
909
+ };
910
+ exports.light_brightness_move = {
911
+ key: ["brightness_move", "brightness_move_onoff"],
912
+ convertSet: async (entity, key, value, meta) => {
913
+ if (value === "stop" || value === 0) {
914
+ await entity.command("genLevelCtrl", "stop", { optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
915
+ // As we cannot determine the new brightness state, we read it from the device
916
+ await utils.sleep(500);
917
+ const target = utils.getEntityOrFirstGroupMember(entity);
918
+ const onOff = (await target.read("genOnOff", ["onOff"])).onOff;
919
+ const brightness = (await target.read("genLevelCtrl", ["currentLevel"])).currentLevel;
920
+ return { state: { brightness, state: onOff === 1 ? "ON" : "OFF" } };
921
+ }
922
+ value = Number(value);
923
+ utils.assertNumber(value, key);
924
+ const command = key.endsWith("onoff") ? "moveWithOnOff" : "move";
925
+ await entity.command("genLevelCtrl", command, { movemode: value > 0 ? 0 : 1, rate: Math.abs(value), optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
926
+ },
927
+ };
928
+ exports.light_colortemp_step = {
929
+ key: ["color_temp_step"],
930
+ options: [exposes.options.transition()],
931
+ convertSet: async (entity, key, value, meta) => {
932
+ value = Number(value);
933
+ utils.assertNumber(value, key);
934
+ const mode = value > 0 ? 1 : 3;
935
+ const transition = utils.getTransition(entity, key, meta).time;
936
+ await entity.command("lightingColorCtrl", "stepColorTemp", {
937
+ stepmode: mode,
938
+ stepsize: Math.abs(value),
939
+ transtime: transition,
940
+ minimum: 0,
941
+ maximum: 600,
942
+ optionsMask: 0,
943
+ optionsOverride: 0,
944
+ }, utils.getOptions(meta.mapped, entity));
945
+ // We cannot determine the color temperature from the current state so we read it, because
946
+ // - We don't know the max/min values
947
+ // - Color mode could have been switched (x/y or hue/saturation)
948
+ const entityToRead = utils.getEntityOrFirstGroupMember(entity);
949
+ if (entityToRead) {
950
+ await utils.sleep(100 + transition * 100);
951
+ await entityToRead.read("lightingColorCtrl", ["colorTemperature"]);
952
+ }
953
+ },
954
+ };
955
+ exports.light_colortemp_move = {
956
+ key: ["colortemp_move", "color_temp_move"],
957
+ convertSet: async (entity, key, value, meta) => {
958
+ // Initialize payload with default constraints
959
+ let minimum = 0;
960
+ let maximum = 600;
961
+ let rate;
962
+ let movemode;
963
+ // Handle different input formats
964
+ if (utils.isString(value)) {
965
+ // String-based commands
966
+ const stringValue = value.toLowerCase();
967
+ if (stringValue === "stop" || stringValue === "release" || stringValue === "0") {
968
+ rate = 1;
969
+ movemode = 0;
970
+ }
971
+ else if (stringValue === "up" || stringValue === "1") {
972
+ rate = meta.message?.rate != null ? Number(meta.message.rate) : 55;
973
+ movemode = 1; // Move to warmer (higher color temp)
974
+ }
975
+ else if (stringValue === "down") {
976
+ rate = meta.message?.rate != null ? Number(meta.message.rate) : 55;
977
+ movemode = 3; // Move to cooler (lower color temp)
978
+ }
979
+ else {
980
+ throw new Error(`${key}: invalid string value "${value}". Expected "stop", "release", "0", "up", "1", or "down"`);
981
+ }
982
+ // Use legacy constraints for string-based commands
983
+ minimum = 153;
984
+ maximum = 370;
985
+ }
986
+ else if (utils.isNumber(value)) {
987
+ // Simple number input
988
+ const numValue = Number(value);
989
+ if (numValue === 0) {
990
+ // Stop command via 0 rate
991
+ rate = 1;
992
+ movemode = 0;
993
+ }
994
+ else {
995
+ // Normal movement
996
+ rate = Math.abs(numValue);
997
+ movemode = numValue > 0 ? 1 : 3;
998
+ }
999
+ }
1000
+ else if (utils.isObject(value)) {
1001
+ // Object input with rate and optional constraints
1002
+ utils.assertObject(value, key);
1003
+ if (value.rate == null) {
1004
+ throw new Error(`${key}: object must contain 'rate' property`);
1005
+ }
1006
+ const rateValue = Number(value.rate);
1007
+ utils.assertNumber(rateValue, `${key}.rate`);
1008
+ if (rateValue === 0) {
1009
+ // Stop command via 0 rate
1010
+ rate = 1;
1011
+ movemode = 0;
1012
+ }
1013
+ else {
1014
+ // Normal movement
1015
+ rate = Math.abs(rateValue);
1016
+ movemode = rateValue > 0 ? 1 : 3;
1017
+ }
1018
+ // Apply custom constraints if provided
1019
+ if (value.minimum != null) {
1020
+ const minValue = Number(value.minimum);
1021
+ utils.assertNumber(minValue, `${key}.minimum`);
1022
+ minimum = minValue;
1023
+ }
1024
+ if (value.maximum != null) {
1025
+ const maxValue = Number(value.maximum);
1026
+ utils.assertNumber(maxValue, `${key}.maximum`);
1027
+ maximum = maxValue;
1028
+ }
1029
+ // Validate constraints
1030
+ if (minimum >= maximum) {
1031
+ throw new Error(`${key}: minimum (${minimum}) must be less than maximum (${maximum})`);
1032
+ }
1033
+ }
1034
+ else {
1035
+ throw new Error(`${key}: invalid value type. Expected number, string, or object with rate property`);
1036
+ }
1037
+ // Send command
1038
+ await entity.command("lightingColorCtrl", "moveColorTemp", { minimum, maximum, rate, movemode, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
1039
+ // Read current color temperature if stopping
1040
+ if (movemode === 0) {
1041
+ const entityToRead = utils.getEntityOrFirstGroupMember(entity);
1042
+ if (entityToRead) {
1043
+ await utils.sleep(100);
1044
+ await entityToRead.read("lightingColorCtrl", ["colorTemperature", "colorMode"]);
1045
+ }
1046
+ }
1047
+ },
1048
+ };
1049
+ exports.light_color_and_colortemp_via_color = {
1050
+ key: ["color", "color_temp", "color_temp_percent"],
1051
+ options: [exposes.options.color_sync(), exposes.options.transition()],
1052
+ convertSet: async (entity, key, value, meta) => {
1053
+ if (key === "color") {
1054
+ return await exports.light_color.convertSet(entity, key, value, meta);
1055
+ }
1056
+ if (key === "color_temp" || key === "color_temp_percent") {
1057
+ utils.assertNumber(value);
1058
+ const xy = libColor.ColorXY.fromMireds(value);
1059
+ await entity.command("lightingColorCtrl", "moveToColor", {
1060
+ transtime: utils.getTransition(entity, key, meta).time,
1061
+ colorx: utils.mapNumberRange(xy.x, 0, 1, 0, 65535),
1062
+ colory: utils.mapNumberRange(xy.y, 0, 1, 0, 65535),
1063
+ optionsMask: 0,
1064
+ optionsOverride: 0,
1065
+ }, utils.getOptions(meta.mapped, entity));
1066
+ return {
1067
+ state: libColor.syncColorState({ color_mode: constants.colorModeLookup[2], color_temp: value }, meta.state, entity, meta.options),
1068
+ };
1069
+ }
1070
+ },
1071
+ convertGet: async (entity, key, meta) => {
1072
+ await entity.read("lightingColorCtrl", light.readColorAttributes(entity, meta));
1073
+ },
1074
+ };
1075
+ exports.light_hue_saturation_step = {
1076
+ key: ["hue_step", "saturation_step"],
1077
+ options: [exposes.options.transition()],
1078
+ convertSet: async (entity, key, value, meta) => {
1079
+ value = Number(value);
1080
+ utils.assertNumber(value, key);
1081
+ const command = key === "hue_step" ? "stepHue" : "stepSaturation";
1082
+ const attribute = key === "hue_step" ? "currentHue" : "currentSaturation";
1083
+ const mode = value > 0 ? 1 : 3;
1084
+ const transition = utils.getTransition(entity, key, meta).time;
1085
+ await entity.command("lightingColorCtrl", command, { stepmode: mode, stepsize: Math.abs(value), transtime: transition, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
1086
+ // We cannot determine the hue/saturation from the current state so we read it, because
1087
+ // - Color mode could have been switched (x/y or colortemp)
1088
+ const entityToRead = utils.getEntityOrFirstGroupMember(entity);
1089
+ if (entityToRead) {
1090
+ await utils.sleep(100 + transition * 100);
1091
+ await entityToRead.read("lightingColorCtrl", [attribute, "colorMode"]);
1092
+ }
1093
+ },
1094
+ };
1095
+ exports.light_hue_saturation_move = {
1096
+ key: ["hue_move", "saturation_move"],
1097
+ convertSet: async (entity, key, value, meta) => {
1098
+ value = value === "stop" ? value : Number(value);
1099
+ const command = key === "hue_move" ? "moveHue" : "moveSaturation";
1100
+ const attribute = key === "hue_move" ? "currentHue" : "currentSaturation";
1101
+ let rate = 0;
1102
+ let movemode = 0;
1103
+ if (value === "stop" || value === 0) {
1104
+ rate = 1;
1105
+ movemode = 0;
1106
+ }
1107
+ else {
1108
+ utils.assertNumber(value, key);
1109
+ rate = Math.abs(value);
1110
+ movemode = value > 0 ? 1 : 3;
1111
+ }
1112
+ await entity.command("lightingColorCtrl", command, { rate, movemode, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
1113
+ // We cannot determine the hue/saturation from the current state so we read it, because
1114
+ // - Color mode could have been switched (x/y or colortemp)
1115
+ if (value === "stop" || value === 0) {
1116
+ const entityToRead = utils.getEntityOrFirstGroupMember(entity);
1117
+ if (entityToRead) {
1118
+ await utils.sleep(100);
1119
+ await entityToRead.read("lightingColorCtrl", [attribute, "colorMode"]);
1120
+ }
1121
+ }
1122
+ },
1123
+ };
1124
+ exports.light_onoff_brightness = {
1125
+ key: ["state", "brightness", "brightness_percent", "on_time", "off_wait_time"],
1126
+ options: [exposes.options.transition()],
1127
+ convertSet: async (entity, key, value, meta) => {
1128
+ const { message } = meta;
1129
+ const transition = utils.getTransition(entity, "brightness", meta);
1130
+ const turnsOffAtBrightness1 = utils.getMetaValue(entity, meta.mapped, "turnsOffAtBrightness1", "allEqual", false);
1131
+ const moveToLevelWithOnOffDisable = utils.getMetaValue(entity, meta.mapped, "moveToLevelWithOnOffDisable", "allEqual", false);
1132
+ const omitOptionalLevelParams = utils.getMetaValue(entity, meta.mapped, "omitOptionalLevelParams", "allEqual", false);
1133
+ let state = message.state !== undefined ? (typeof message.state === "string" ? message.state.toLowerCase() : null) : undefined;
1134
+ let brightness;
1135
+ if (message.brightness != null) {
1136
+ brightness = Number(message.brightness);
1137
+ }
1138
+ else if (message.brightness_percent != null) {
1139
+ brightness = utils.mapNumberRange(Number(message.brightness_percent), 0, 100, 0, 255);
1140
+ }
1141
+ if (brightness === 255) {
1142
+ // Allow 255 for backwards compatibility.
1143
+ brightness = 254;
1144
+ }
1145
+ if (brightness !== undefined && (Number.isNaN(brightness) || brightness < 0 || brightness > 254)) {
1146
+ throw new Error(`Brightness value of message: '${JSON.stringify(message)}' invalid, must be a number >= 0 and =< 254`);
1147
+ }
1148
+ if (state !== undefined && state !== null && ["on", "off", "toggle"].includes(state) === false) {
1149
+ throw new Error(`State value of message: '${JSON.stringify(message)}' invalid, must be 'ON', 'OFF' or 'TOGGLE'`);
1150
+ }
1151
+ if ((state === undefined || state === null) && brightness === undefined) {
1152
+ throw new Error(`At least one of "brightness" or "state" must have a value: '${JSON.stringify(message)}'`);
1153
+ }
1154
+ // Infer state from desired brightness if unset. Ideally we'd want to keep it as it is, but this code has always
1155
+ // used 'MoveToLevelWithOnOff' so that'd break backwards compatibility. To keep the state, the user
1156
+ // has to explicitly set it to null.
1157
+ if (state === undefined) {
1158
+ if (moveToLevelWithOnOffDisable) {
1159
+ // Although in some cases it can be usefull to use explicit on and off and moveToLevel. In these casese
1160
+ // we just ignore the brightness value and set the state to the current device state.
1161
+ state = meta.state.state.toLowerCase();
1162
+ }
1163
+ else {
1164
+ // Also write to `meta.message.state` in case we delegate to the `on_off` converter.
1165
+ state = meta.message.state = brightness === 0 ? "off" : "on";
1166
+ }
1167
+ }
1168
+ let publishBrightness = brightness !== undefined;
1169
+ const targetState = state === "toggle" ? (meta.state.state === "ON" ? "off" : "on") : state;
1170
+ if (targetState === "off") {
1171
+ // Simulate 'Off' with transition via 'MoveToLevelWithOnOff', otherwise just use 'Off'.
1172
+ // TODO: if this is a group where some members don't support Level Control, turning them off
1173
+ // with transition may have no effect. (Some devices, such as Envilar ZG302-BOX-RELAY, handle
1174
+ // 'MoveToLevelWithOnOff' despite not supporting the cluster; others, like the LEDVANCE SMART+
1175
+ // plug, do not.)
1176
+ brightness = transition.specified || brightness === 0 ? 0 : undefined;
1177
+ if (brightness !== undefined &&
1178
+ meta.state.state === "OFF" &&
1179
+ utils.getMetaValue(entity, meta.mapped, "noOffTransitionWhenOff", { atLeastOnce: true }, false)) {
1180
+ logger_1.logger.debug("Suppressing OFF transition since entity is OFF and has noOffTransitionWhenOff=true", NS);
1181
+ brightness = undefined;
1182
+ }
1183
+ if (meta.state.brightness !== undefined && meta.state.state === "ON") {
1184
+ // The light's current level gets clobbered in two cases:
1185
+ // 1. when 'Off' has a transition, in which case it is really 'MoveToLevelWithOnOff'
1186
+ // https://github.com/Koenkk/zigbee-herdsman-converters/issues/1073
1187
+ // 2. when 'OnLevel' is set: "If OnLevel is not defined, set the CurrentLevel to the stored level."
1188
+ // https://github.com/Koenkk/zigbee2mqtt/issues/2850#issuecomment-580365633
1189
+ // We need to remember current brightness in case the next 'On' does not provide it. `meta` is not reliable
1190
+ // here, as it will get clobbered too if reporting is configured.
1191
+ globalStore.putValue(entity, "brightness", meta.state.brightness);
1192
+ globalStore.putValue(entity, "turnedOffWithTransition", brightness !== undefined);
1193
+ }
1194
+ }
1195
+ else if (targetState === "on" && brightness === undefined) {
1196
+ // Simulate 'On' with transition via 'MoveToLevelWithOnOff', or restore the level from before
1197
+ // it was clobbered by a previous transition to off; otherwise just use 'On'.
1198
+ // TODO: same problem as above.
1199
+ // TODO: if transition is not specified, should use device default (OnTransitionTime), not 0.
1200
+ if (transition.specified || globalStore.getValue(entity, "turnedOffWithTransition") === true) {
1201
+ const levelConfig = utils.getObjectProperty(meta.state, "level_config", {});
1202
+ let onLevel = utils.getObjectProperty(levelConfig, "on_level", 0);
1203
+ if (onLevel === 0 && entity.meta.onLevelSupported !== false) {
1204
+ try {
1205
+ const attributeRead = await entity.read("genLevelCtrl", ["onLevel"]);
1206
+ if (attributeRead !== undefined) {
1207
+ onLevel = attributeRead.onLevel;
1208
+ }
1209
+ }
1210
+ catch {
1211
+ // OnLevel not supported
1212
+ }
1213
+ }
1214
+ if (onLevel === 0) {
1215
+ onLevel = "previous";
1216
+ entity.meta.onLevelSupported = false;
1217
+ entity.save();
1218
+ }
1219
+ if (onLevel === 255 || onLevel === "previous") {
1220
+ const current = utils.getObjectProperty(meta.state, "brightness", 254);
1221
+ brightness = globalStore.getValue(entity, "brightness", current);
1222
+ }
1223
+ else {
1224
+ brightness = onLevel;
1225
+ }
1226
+ // Published state might have gotten clobbered by reporting.
1227
+ publishBrightness = true;
1228
+ }
1229
+ }
1230
+ if (brightness === undefined) {
1231
+ const result = (await exports.on_off.convertSet(entity, "state", state, meta));
1232
+ if (result) {
1233
+ if (result.state && result.state.state === "ON" && meta.state.brightness === 0) {
1234
+ result.state.brightness = 1;
1235
+ }
1236
+ }
1237
+ return result;
1238
+ }
1239
+ if (brightness === 0 && (targetState === "on" || state === null)) {
1240
+ brightness = 1;
1241
+ }
1242
+ if (brightness === 1 && turnsOffAtBrightness1) {
1243
+ brightness = 2;
1244
+ }
1245
+ if (targetState !== "off") {
1246
+ globalStore.putValue(entity, "brightness", brightness);
1247
+ globalStore.clearValue(entity, "turnedOffWithTransition");
1248
+ }
1249
+ if (moveToLevelWithOnOffDisable) {
1250
+ // On some devices "moveToLevelWithOnOff" command seems to be broken, leading to the light
1251
+ // randomly switching off for levels lower than some threshold. Is those cases it's better to
1252
+ // use "moveToLevel" with explicit On and Off when the state changes.
1253
+ if (typeof meta.state.state === "string" && meta.state.state.toLowerCase() !== targetState) {
1254
+ if (targetState === "on") {
1255
+ const payload = { level: Number(brightness), transtime: transition.time };
1256
+ if (!omitOptionalLevelParams) {
1257
+ payload.optionsMask = 0;
1258
+ payload.optionsOverride = 0;
1259
+ }
1260
+ await entity.command("genLevelCtrl", "moveToLevel", payload, utils.getOptions(meta.mapped, entity));
1261
+ }
1262
+ await exports.on_off.convertSet(entity, "state", state, meta);
1263
+ }
1264
+ else {
1265
+ const payload = { level: Number(brightness), transtime: transition.time };
1266
+ if (!omitOptionalLevelParams) {
1267
+ payload.optionsMask = 0;
1268
+ payload.optionsOverride = 0;
1269
+ }
1270
+ await entity.command("genLevelCtrl", "moveToLevel", payload, utils.getOptions(meta.mapped, entity));
1271
+ }
1272
+ }
1273
+ else {
1274
+ const payload = { level: Number(brightness), transtime: transition.time };
1275
+ if (!omitOptionalLevelParams) {
1276
+ payload.optionsMask = 0;
1277
+ payload.optionsOverride = 0;
1278
+ }
1279
+ await entity.command("genLevelCtrl", state === null ? "moveToLevel" : "moveToLevelWithOnOff", payload, utils.getOptions(meta.mapped, entity));
1280
+ }
1281
+ const result = { state: {} };
1282
+ if (publishBrightness) {
1283
+ result.state.brightness = Number(brightness);
1284
+ }
1285
+ if (state !== null && !moveToLevelWithOnOffDisable) {
1286
+ result.state.state = brightness === 0 ? "OFF" : "ON";
1287
+ }
1288
+ return result;
1289
+ },
1290
+ convertGet: async (entity, key, meta) => {
1291
+ if (key === "brightness") {
1292
+ await entity.read("genLevelCtrl", ["currentLevel"]);
1293
+ }
1294
+ else if (key === "state") {
1295
+ await exports.on_off.convertGet(entity, key, meta);
1296
+ }
1297
+ },
1298
+ };
1299
+ exports.light_colortemp_startup = {
1300
+ key: ["color_temp_startup"],
1301
+ convertSet: async (entity, key, value, meta) => {
1302
+ const [colorTempMin, colorTempMax] = light.findColorTempRange(entity);
1303
+ const preset = { warmest: colorTempMax, warm: 454, neutral: 370, cool: 250, coolest: colorTempMin, previous: 65535 };
1304
+ if (utils.isString(value) && value in preset) {
1305
+ value = utils.getFromLookup(value, preset);
1306
+ }
1307
+ value = Number(value);
1308
+ utils.assertNumber(value);
1309
+ // ensure value within range
1310
+ // we do allow one exception for 0xffff, which is to restore the previous value
1311
+ if (value !== 65535) {
1312
+ value = light.clampColorTemp(value, colorTempMin, colorTempMax);
1313
+ }
1314
+ await entity.write("lightingColorCtrl", { startUpColorTemperature: value /* type failure? */ }, utils.getOptions(meta.mapped, entity));
1315
+ return { state: { color_temp_startup: value } };
1316
+ },
1317
+ convertGet: async (entity, key, meta) => {
1318
+ await entity.read("lightingColorCtrl", ["startUpColorTemperature"]);
1319
+ },
1320
+ };
1321
+ exports.light_color_colortemp = {
1322
+ /**
1323
+ * This converter is a combination of light_color and light_colortemp and
1324
+ * can be used instead of the two individual converters . When used to set,
1325
+ * it actually calls out to light_color or light_colortemp to get the
1326
+ * return value. When used to get, it gets both color and colorTemp in
1327
+ * one call.
1328
+ * The reason for the existence of this somewhat peculiar converter is
1329
+ * that some lights don't report their state when changed. To fix this,
1330
+ * we query the state after we set it. We want to query color and colorTemp
1331
+ * both when setting either, because both change when setting one. This
1332
+ * converter is used to do just that.
1333
+ */
1334
+ key: ["color", "color_temp", "color_temp_percent"],
1335
+ options: [exposes.options.color_sync(), exposes.options.transition()],
1336
+ convertSet: async (entity, key, value, meta) => {
1337
+ if (key === "color") {
1338
+ const result = await exports.light_color.convertSet(entity, key, value, meta);
1339
+ return result;
1340
+ }
1341
+ if (key === "color_temp" || key === "color_temp_percent") {
1342
+ const result = await exports.light_colortemp.convertSet(entity, key, value, meta);
1343
+ return result;
1344
+ }
1345
+ },
1346
+ convertGet: async (entity, key, meta) => {
1347
+ await entity.read("lightingColorCtrl", light.readColorAttributes(entity, meta, ["colorTemperature"]));
1348
+ },
1349
+ };
1350
+ exports.effect = {
1351
+ key: ["effect", "alert", "flash"], // alert and flash are deprecated.
1352
+ convertSet: async (entity, key, value, meta) => {
1353
+ if (key === "effect") {
1354
+ utils.assertString(value, key);
1355
+ const lookup = { blink: 0, breathe: 1, okay: 2, channel_change: 11, finish_effect: 254, stop_effect: 255 };
1356
+ value = value.toLowerCase();
1357
+ if (value === "colorloop") {
1358
+ const transition = meta.message.transition ?? 15;
1359
+ utils.assertNumber(transition, "transition");
1360
+ const speed = Math.min(255, Math.max(1, Math.round(255 / transition)));
1361
+ await exports.light_hue_saturation_move.convertSet(entity, "hue_move", speed, meta);
1362
+ }
1363
+ else if (value === "stop_colorloop") {
1364
+ await exports.light_hue_saturation_move.convertSet(entity, "hue_move", "stop", meta);
1365
+ }
1366
+ else {
1367
+ const payload = { effectid: utils.getFromLookup(value, lookup), effectvariant: 0 };
1368
+ await entity.command("genIdentify", "triggerEffect", payload, utils.getOptions(meta.mapped, entity));
1369
+ }
1370
+ }
1371
+ else if (key === "alert" || key === "flash") {
1372
+ // Deprecated
1373
+ let effectid = 0;
1374
+ const lookup = { select: 0x00, lselect: 0x01, none: 0xff };
1375
+ if (key === "flash") {
1376
+ if (value === 2) {
1377
+ value = "select";
1378
+ }
1379
+ else if (value === 10) {
1380
+ value = "lselect";
1381
+ }
1382
+ }
1383
+ effectid = utils.getFromLookup(value, lookup);
1384
+ const payload = { effectid, effectvariant: 0 };
1385
+ await entity.command("genIdentify", "triggerEffect", payload, utils.getOptions(meta.mapped, entity));
1386
+ }
1387
+ },
1388
+ };
1389
+ exports.thermostat_remote_sensing = {
1390
+ key: ["remote_sensing"],
1391
+ convertSet: async (entity, key, value, meta) => {
1392
+ await entity.write("hvacThermostat", { remoteSensing: value });
1393
+ },
1394
+ convertGet: async (entity, key, meta) => {
1395
+ await entity.read("hvacThermostat", ["remoteSensing"]);
1396
+ },
1397
+ };
1398
+ exports.thermostat_weekly_schedule = {
1399
+ key: ["weekly_schedule"],
1400
+ convertSet: async (entity, key, value, meta) => {
1401
+ /*
1402
+ * We want to support a simple human creatable format to send a schedule:
1403
+ {"weekly_schedule": {
1404
+ "dayofweek": ["monday", "tuesday"],
1405
+ "transitions": [
1406
+ {"heatSetpoint": 16, "transitionTime": "0:00"},
1407
+ {"heatSetpoint": 20, "transitionTime": "18:00"},
1408
+ {"heatSetpoint": 16, "transitionTime": "19:30"}
1409
+ ]}}
1410
+
1411
+ * However exposes is not flexible enough to describe something like this. There is a
1412
+ * much more verbose format we also support so that exposes work.
1413
+ {"weekly_schedule": {
1414
+ "dayofweek": [
1415
+ {"day": "monday"},
1416
+ {"day": "tuesday"}
1417
+ ],
1418
+ "transitions": [
1419
+ {"heatSetpoint": 16, "transitionTime": {"hour": 0, "minute": 0}},
1420
+ {"heatSetpoint": 20, "transitionTime": {"hour": 18, "minute": 0}},
1421
+ {"heatSetpoint": 16, "transitionTime": {"hour": 19, "minute": 30}}
1422
+ ]}}
1423
+ */
1424
+ utils.assertObject(value, key);
1425
+ let daysofweek = value.dayofweek;
1426
+ const transitions = value.transitions;
1427
+ let numoftrans = 0;
1428
+ const modes = [];
1429
+ if (Array.isArray(transitions)) {
1430
+ // calculate numoftrans
1431
+ if (typeof value.numoftrans !== "undefined") {
1432
+ logger_1.logger.warning(`weekly_schedule: ignoring provided numoftrans value (${JSON.stringify(value.numoftrans)}), this is now calculated automatically`, NS);
1433
+ }
1434
+ numoftrans = transitions.length;
1435
+ // mode is calculated below
1436
+ if (typeof value.mode !== "undefined") {
1437
+ logger_1.logger.warning(`weekly_schedule: ignoring provided mode value (${JSON.stringify(value.mode)}), this is now calculated automatically`, NS);
1438
+ }
1439
+ // transform transition payload values if needed
1440
+ for (const elem of transitions) {
1441
+ // update mode if needed
1442
+ if (elem.heatSetpoint != null && !modes.includes("heat")) {
1443
+ modes.push("heat");
1444
+ }
1445
+ if (elem.coolSetpoint != null && !modes.includes("cool")) {
1446
+ modes.push("cool");
1447
+ }
1448
+ // transform setpoint values if numeric
1449
+ if (typeof elem.heatSetpoint === "number") {
1450
+ elem.heatSetpoint = Math.round(elem.heatSetpoint * 100);
1451
+ }
1452
+ if (typeof elem.coolSetpoint === "number") {
1453
+ elem.coolSetpoint = Math.round(elem.coolSetpoint * 100);
1454
+ }
1455
+ // accept 24h time notation (e.g. 19:30)
1456
+ if (typeof elem.transitionTime === "string") {
1457
+ const time = elem.transitionTime.split(":");
1458
+ const timeHour = Number.parseInt(time[0], 10) * 60;
1459
+ const timeMinute = Number.parseInt(time[1], 10);
1460
+ if (time.length !== 2 || Number.isNaN(timeHour) || Number.isNaN(timeMinute)) {
1461
+ logger_1.logger.warning(`weekly_schedule: expected 24h time notation (e.g. 19:30) but got '${elem.transitionTime}'!`, NS);
1462
+ }
1463
+ else {
1464
+ elem.transitionTime = timeHour + timeMinute;
1465
+ }
1466
+ }
1467
+ else if (typeof elem.transitionTime === "object") {
1468
+ if (elem.transitionTime.hour == null || elem.transitionTime.minute == null) {
1469
+ throw new Error(`weekly_schedule: expected 24h time object (e.g. {"hour": 19, "minute": 30}), but got '${JSON.stringify(elem.transitionTime)}'!`);
1470
+ }
1471
+ if (Number.isNaN(elem.transitionTime.hour)) {
1472
+ throw new Error(`weekly_schedule: expected time.hour to be a number, but got '${elem.transitionTime.hour}'!`);
1473
+ }
1474
+ if (Number.isNaN(elem.transitionTime.minute)) {
1475
+ throw new Error(`weekly_schedule: expected time.minute to be a number, but got '${elem.transitionTime.minute}'!`);
1476
+ }
1477
+ elem.transitionTime = Number.parseInt(elem.transitionTime.hour, 10) * 60 + Number.parseInt(elem.transitionTime.minute, 10);
1478
+ }
1479
+ }
1480
+ }
1481
+ else {
1482
+ logger_1.logger.error("weekly_schedule: transitions is not an array!", NS);
1483
+ return;
1484
+ }
1485
+ // map array of desired modes to bitmask
1486
+ let mode = 0;
1487
+ for (const m of modes) {
1488
+ // lookup mode bit
1489
+ mode |= 1 << utils.getKey(constants.thermostatScheduleMode, m, 0, Number);
1490
+ }
1491
+ // map array of days to desired dayofweek bitmask
1492
+ if (typeof daysofweek === "string") {
1493
+ daysofweek = [daysofweek];
1494
+ }
1495
+ let dayofweek = 0;
1496
+ if (Array.isArray(daysofweek)) {
1497
+ for (let d of daysofweek) {
1498
+ if (typeof d === "object") {
1499
+ if (d.day == null) {
1500
+ throw new Error(`weekly_schedule: expected dayofweek to be string or {"day": "str"}, but got '${JSON.stringify(d)}'!`);
1501
+ }
1502
+ d = d.day;
1503
+ }
1504
+ // lookup dayofweek bit
1505
+ d = utils.getKey(constants.thermostatDayOfWeek, d.toLowerCase(), d, Number);
1506
+ dayofweek |= 1 << d;
1507
+ }
1508
+ }
1509
+ await entity.command("hvacThermostat", "setWeeklySchedule", { dayofweek, numoftrans, transitions, mode }, utils.getOptions(meta.mapped, entity));
1510
+ },
1511
+ convertGet: async (entity, key, meta) => {
1512
+ const payload = {
1513
+ daystoreturn: 0xff, // Sun-Sat and vacation
1514
+ modetoreturn: 3, // heat + cool
1515
+ };
1516
+ await entity.command("hvacThermostat", "getWeeklySchedule", payload, utils.getOptions(meta.mapped, entity));
1517
+ },
1518
+ };
1519
+ exports.thermostat_system_mode = {
1520
+ key: ["system_mode"],
1521
+ convertSet: async (entity, key, value, meta) => {
1522
+ let systemMode = utils.getKey(constants.thermostatSystemModes, value, undefined, Number);
1523
+ if (systemMode === undefined) {
1524
+ systemMode = utils.getKey(legacy.thermostatSystemModes, value, value, Number);
1525
+ }
1526
+ await entity.write("hvacThermostat", { systemMode });
1527
+ return { state: { system_mode: value } };
1528
+ },
1529
+ convertGet: async (entity, key, meta) => {
1530
+ await entity.read("hvacThermostat", ["systemMode"]);
1531
+ },
1532
+ };
1533
+ exports.acova_thermostat_system_mode = {
1534
+ key: ["system_mode"],
1535
+ convertSet: async (entity, key, value, meta) => {
1536
+ let systemMode = utils.getKey(constants.acovaThermostatSystemModes, value, undefined, Number);
1537
+ if (systemMode === undefined) {
1538
+ systemMode = utils.getKey(legacy.thermostatSystemModes, value, value, Number);
1539
+ }
1540
+ await entity.write("hvacThermostat", { systemMode });
1541
+ return { state: { system_mode: value } };
1542
+ },
1543
+ convertGet: async (entity, key, meta) => {
1544
+ await entity.read("hvacThermostat", ["systemMode"]);
1545
+ },
1546
+ };
1547
+ exports.thermostat_control_sequence_of_operation = {
1548
+ key: ["control_sequence_of_operation"],
1549
+ convertSet: async (entity, key, value, meta) => {
1550
+ utils.assertEndpoint(entity);
1551
+ let val = utils.getKey(constants.thermostatControlSequenceOfOperations, value, undefined, Number);
1552
+ if (val === undefined) {
1553
+ val = utils.getKey(constants.thermostatControlSequenceOfOperations, value, value, Number);
1554
+ }
1555
+ const attributes = { ctrlSeqeOfOper: val };
1556
+ await entity.write("hvacThermostat", attributes);
1557
+ // NOTE: update the cluster attribute we store as this is used by
1558
+ // SMaBiT AV2010/32's dynamic expose function.
1559
+ entity.saveClusterAttributeKeyValue("hvacThermostat", attributes);
1560
+ return { state: { control_sequence_of_operation: value } };
1561
+ },
1562
+ convertGet: async (entity, key, meta) => {
1563
+ await entity.read("hvacThermostat", ["ctrlSeqeOfOper"]);
1564
+ },
1565
+ };
1566
+ exports.thermostat_programming_operation_mode = {
1567
+ key: ["programming_operation_mode"],
1568
+ convertSet: async (entity, key, value, meta) => {
1569
+ const val = utils.getKey(constants.thermostatProgrammingOperationModes, value, undefined, Number);
1570
+ if (val === undefined) {
1571
+ throw new Error(`Programming operation mode invalid, must be one of: ${Object.values(constants.thermostatProgrammingOperationModes).join(", ")}`);
1572
+ }
1573
+ await entity.write("hvacThermostat", { programingOperMode: val });
1574
+ return { state: { programming_operation_mode: value } };
1575
+ },
1576
+ convertGet: async (entity, key, meta) => {
1577
+ await entity.read("hvacThermostat", ["programingOperMode"]);
1578
+ },
1579
+ };
1580
+ exports.thermostat_temperature_display_mode = {
1581
+ key: ["temperature_display_mode"],
1582
+ convertSet: async (entity, key, value, meta) => {
1583
+ const tempDisplayMode = utils.getKey(constants.temperatureDisplayMode, value, value, Number);
1584
+ await entity.write("hvacUserInterfaceCfg", { tempDisplayMode });
1585
+ return { state: { temperature_display_mode: value } };
1586
+ },
1587
+ convertGet: async (entity, key, meta) => {
1588
+ await entity.read("hvacUserInterfaceCfg", ["tempDisplayMode"]);
1589
+ },
1590
+ };
1591
+ exports.thermostat_keypad_lockout = {
1592
+ key: ["keypad_lockout"],
1593
+ convertSet: async (entity, key, value, meta) => {
1594
+ const keypadLockout = utils.getKey(constants.keypadLockoutMode, value, value, Number);
1595
+ await entity.write("hvacUserInterfaceCfg", { keypadLockout });
1596
+ return { state: { keypad_lockout: value } };
1597
+ },
1598
+ convertGet: async (entity, key, meta) => {
1599
+ await entity.read("hvacUserInterfaceCfg", ["keypadLockout"]);
1600
+ },
1601
+ };
1602
+ exports.thermostat_temperature_setpoint_hold = {
1603
+ key: ["temperature_setpoint_hold"],
1604
+ convertSet: async (entity, key, value, meta) => {
1605
+ await entity.write("hvacThermostat", { tempSetpointHold: value });
1606
+ },
1607
+ convertGet: async (entity, key, meta) => {
1608
+ await entity.read("hvacThermostat", ["tempSetpointHold"]);
1609
+ },
1610
+ };
1611
+ exports.thermostat_temperature_setpoint_hold_duration = {
1612
+ key: ["temperature_setpoint_hold_duration"],
1613
+ convertSet: async (entity, key, value, meta) => {
1614
+ await entity.write("hvacThermostat", { tempSetpointHoldDuration: value });
1615
+ },
1616
+ convertGet: async (entity, key, meta) => {
1617
+ await entity.read("hvacThermostat", ["tempSetpointHoldDuration"]);
1618
+ },
1619
+ };
1620
+ exports.fan_mode = {
1621
+ key: ["fan_mode", "fan_state"],
1622
+ convertSet: async (entity, key, value, meta) => {
1623
+ utils.assertString(value, key);
1624
+ const fanMode = utils.getFromLookup(value, constants.fanMode);
1625
+ await entity.write("hvacFanCtrl", { fanMode });
1626
+ return { state: { fan_mode: value.toLowerCase(), fan_state: value.toLowerCase() === "off" ? "OFF" : "ON" } };
1627
+ },
1628
+ convertGet: async (entity, key, meta) => {
1629
+ await entity.read("hvacFanCtrl", ["fanMode"]);
1630
+ },
1631
+ };
1632
+ exports.fan_speed = {
1633
+ key: ["speed"],
1634
+ convertSet: async (entity, key, value, meta) => {
1635
+ utils.assertNumber(value);
1636
+ await entity.command("genLevelCtrl", "moveToLevel", { level: value, transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
1637
+ return { state: { speed: value } };
1638
+ },
1639
+ convertGet: async (entity, key, meta) => {
1640
+ await entity.read("genLevelCtrl", ["currentLevel"]);
1641
+ },
1642
+ };
1643
+ exports.thermostat_local_temperature = {
1644
+ key: ["local_temperature"],
1645
+ convertGet: async (entity, key, meta) => {
1646
+ await entity.read("hvacThermostat", ["localTemp"]);
1647
+ },
1648
+ };
1649
+ exports.thermostat_outdoor_temperature = {
1650
+ key: ["outdoor_temperature"],
1651
+ convertGet: async (entity, key, meta) => {
1652
+ await entity.read("hvacThermostat", ["outdoorTemp"]);
1653
+ },
1654
+ };
1655
+ exports.thermostat_local_temperature_calibration = {
1656
+ key: ["local_temperature_calibration"],
1657
+ convertSet: async (entity, key, value, meta) => {
1658
+ utils.assertNumber(value);
1659
+ await entity.write("hvacThermostat", { localTemperatureCalibration: Math.round(value * 10) });
1660
+ return { state: { local_temperature_calibration: value } };
1661
+ },
1662
+ convertGet: async (entity, key, meta) => {
1663
+ await entity.read("hvacThermostat", ["localTemperatureCalibration"]);
1664
+ },
1665
+ };
1666
+ exports.thermostat_occupancy = {
1667
+ key: ["occupancy"],
1668
+ convertGet: async (entity, key, meta) => {
1669
+ await entity.read("hvacThermostat", ["occupancy"]);
1670
+ },
1671
+ };
1672
+ exports.thermostat_clear_weekly_schedule = {
1673
+ key: ["clear_weekly_schedule"],
1674
+ convertSet: async (entity, key, value, meta) => {
1675
+ await entity.command("hvacThermostat", "clearWeeklySchedule", {}, utils.getOptions(meta.mapped, entity));
1676
+ },
1677
+ };
1678
+ exports.thermostat_pi_heating_demand = {
1679
+ key: ["pi_heating_demand"],
1680
+ convertGet: async (entity, key, meta) => {
1681
+ await entity.read("hvacThermostat", ["pIHeatingDemand"]);
1682
+ },
1683
+ };
1684
+ exports.thermostat_running_state = {
1685
+ key: ["running_state"],
1686
+ convertGet: async (entity, key, meta) => {
1687
+ await entity.read("hvacThermostat", ["runningState"]);
1688
+ },
1689
+ };
1690
+ exports.thermostat_occupied_heating_setpoint = {
1691
+ key: ["occupied_heating_setpoint"],
1692
+ options: [exposes.options.thermostat_unit()],
1693
+ convertSet: async (entity, key, value, meta) => {
1694
+ utils.assertNumber(value, key);
1695
+ let result;
1696
+ if (meta.options.thermostat_unit === "fahrenheit") {
1697
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1698
+ }
1699
+ else {
1700
+ result = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
1701
+ }
1702
+ const occupiedHeatingSetpoint = result;
1703
+ await entity.write("hvacThermostat", { occupiedHeatingSetpoint });
1704
+ return { state: { occupied_heating_setpoint: value } };
1705
+ },
1706
+ convertGet: async (entity, key, meta) => {
1707
+ await entity.read("hvacThermostat", ["occupiedHeatingSetpoint"]);
1708
+ },
1709
+ };
1710
+ exports.thermostat_unoccupied_heating_setpoint = {
1711
+ key: ["unoccupied_heating_setpoint"],
1712
+ options: [exposes.options.thermostat_unit()],
1713
+ convertSet: async (entity, key, value, meta) => {
1714
+ utils.assertNumber(value, key);
1715
+ // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
1716
+ let result;
1717
+ if (meta.options.thermostat_unit === "fahrenheit") {
1718
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1719
+ }
1720
+ else {
1721
+ result = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
1722
+ }
1723
+ const unoccupiedHeatingSetpoint = result;
1724
+ await entity.write("hvacThermostat", { unoccupiedHeatingSetpoint });
1725
+ return { state: { unoccupied_heating_setpoint: value } };
1726
+ },
1727
+ convertGet: async (entity, key, meta) => {
1728
+ await entity.read("hvacThermostat", ["unoccupiedHeatingSetpoint"]);
1729
+ },
1730
+ };
1731
+ exports.thermostat_occupied_cooling_setpoint = {
1732
+ key: ["occupied_cooling_setpoint"],
1733
+ options: [exposes.options.thermostat_unit()],
1734
+ convertSet: async (entity, key, value, meta) => {
1735
+ utils.assertNumber(value, key);
1736
+ // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
1737
+ let result;
1738
+ if (meta.options.thermostat_unit === "fahrenheit") {
1739
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1740
+ }
1741
+ else {
1742
+ result = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
1743
+ }
1744
+ const occupiedCoolingSetpoint = result;
1745
+ await entity.write("hvacThermostat", { occupiedCoolingSetpoint });
1746
+ return { state: { occupied_cooling_setpoint: value } };
1747
+ },
1748
+ convertGet: async (entity, key, meta) => {
1749
+ await entity.read("hvacThermostat", ["occupiedCoolingSetpoint"]);
1750
+ },
1751
+ };
1752
+ exports.thermostat_unoccupied_cooling_setpoint = {
1753
+ key: ["unoccupied_cooling_setpoint"],
1754
+ options: [exposes.options.thermostat_unit()],
1755
+ convertSet: async (entity, key, value, meta) => {
1756
+ utils.assertNumber(value, key);
1757
+ // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
1758
+ let result;
1759
+ if (meta.options.thermostat_unit === "fahrenheit") {
1760
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1761
+ }
1762
+ else {
1763
+ result = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
1764
+ }
1765
+ const unoccupiedCoolingSetpoint = result;
1766
+ await entity.write("hvacThermostat", { unoccupiedCoolingSetpoint });
1767
+ return { state: { unoccupied_cooling_setpoint: value } };
1768
+ },
1769
+ convertGet: async (entity, key, meta) => {
1770
+ await entity.read("hvacThermostat", ["unoccupiedCoolingSetpoint"]);
1771
+ },
1772
+ };
1773
+ exports.thermostat_setpoint_raise_lower = {
1774
+ key: ["setpoint_raise_lower"],
1775
+ convertSet: async (entity, key, value, meta) => {
1776
+ utils.assertObject(value, key);
1777
+ const payload = { mode: value.mode, amount: Math.round(value.amount) * 100 };
1778
+ await entity.command("hvacThermostat", "setpointRaiseLower", payload, utils.getOptions(meta.mapped, entity));
1779
+ },
1780
+ };
1781
+ exports.thermostat_relay_status_log = {
1782
+ key: ["relay_status_log"],
1783
+ convertGet: async (entity, key, meta) => {
1784
+ await entity.command("hvacThermostat", "getRelayStatusLog", {}, utils.getOptions(meta.mapped, entity));
1785
+ },
1786
+ };
1787
+ exports.thermostat_running_mode = {
1788
+ key: ["running_mode"],
1789
+ convertGet: async (entity, key, meta) => {
1790
+ await entity.read("hvacThermostat", ["runningMode"]);
1791
+ },
1792
+ };
1793
+ exports.thermostat_min_heat_setpoint_limit = {
1794
+ key: ["min_heat_setpoint_limit"],
1795
+ convertSet: async (entity, key, value, meta) => {
1796
+ utils.assertNumber(value);
1797
+ // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
1798
+ let result;
1799
+ if (meta.options.thermostat_unit === "fahrenheit") {
1800
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1801
+ }
1802
+ else {
1803
+ result = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
1804
+ }
1805
+ const minHeatSetpointLimit = result;
1806
+ await entity.write("hvacThermostat", { minHeatSetpointLimit });
1807
+ return { state: { min_heat_setpoint_limit: value } };
1808
+ },
1809
+ convertGet: async (entity, key, meta) => {
1810
+ await entity.read("hvacThermostat", ["minHeatSetpointLimit"]);
1811
+ },
1812
+ };
1813
+ exports.thermostat_max_heat_setpoint_limit = {
1814
+ key: ["max_heat_setpoint_limit"],
1815
+ convertSet: async (entity, key, value, meta) => {
1816
+ utils.assertNumber(value, key);
1817
+ // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
1818
+ let result;
1819
+ if (meta.options.thermostat_unit === "fahrenheit") {
1820
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1821
+ }
1822
+ else {
1823
+ result = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
1824
+ }
1825
+ const maxHeatSetpointLimit = result;
1826
+ await entity.write("hvacThermostat", { maxHeatSetpointLimit });
1827
+ return { state: { max_heat_setpoint_limit: value } };
1828
+ },
1829
+ convertGet: async (entity, key, meta) => {
1830
+ await entity.read("hvacThermostat", ["maxHeatSetpointLimit"]);
1831
+ },
1832
+ };
1833
+ exports.thermostat_min_cool_setpoint_limit = {
1834
+ key: ["min_cool_setpoint_limit"],
1835
+ convertSet: async (entity, key, value, meta) => {
1836
+ utils.assertNumber(value, key);
1837
+ // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
1838
+ let result;
1839
+ if (meta.options.thermostat_unit === "fahrenheit") {
1840
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1841
+ }
1842
+ else {
1843
+ result = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
1844
+ }
1845
+ const minCoolSetpointLimit = result;
1846
+ await entity.write("hvacThermostat", { minCoolSetpointLimit });
1847
+ return { state: { min_cool_setpoint_limit: value } };
1848
+ },
1849
+ convertGet: async (entity, key, meta) => {
1850
+ await entity.read("hvacThermostat", ["minCoolSetpointLimit"]);
1851
+ },
1852
+ };
1853
+ exports.thermostat_max_cool_setpoint_limit = {
1854
+ key: ["max_cool_setpoint_limit"],
1855
+ convertSet: async (entity, key, value, meta) => {
1856
+ utils.assertNumber(value, key);
1857
+ // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
1858
+ let result;
1859
+ if (meta.options.thermostat_unit === "fahrenheit") {
1860
+ result = Math.round(utils.normalizeCelsiusVersionOfFahrenheit(value) * 100);
1861
+ }
1862
+ else {
1863
+ result = Number((Math.round(Number((value * 2).toFixed(1))) / 2).toFixed(1)) * 100;
1864
+ }
1865
+ const maxCoolSetpointLimit = result;
1866
+ await entity.write("hvacThermostat", { maxCoolSetpointLimit });
1867
+ return { state: { max_cool_setpoint_limit: value } };
1868
+ },
1869
+ convertGet: async (entity, key, meta) => {
1870
+ await entity.read("hvacThermostat", ["maxCoolSetpointLimit"]);
1871
+ },
1872
+ };
1873
+ exports.thermostat_ac_louver_position = {
1874
+ key: ["ac_louver_position"],
1875
+ convertSet: async (entity, key, value, meta) => {
1876
+ let acLouverPosition = utils.getKey(constants.thermostatAcLouverPositions, value, undefined, Number);
1877
+ if (acLouverPosition === undefined) {
1878
+ acLouverPosition = utils.getKey(constants.thermostatAcLouverPositions, value, value, Number);
1879
+ }
1880
+ await entity.write("hvacThermostat", { acLouverPosition });
1881
+ return { state: { ac_louver_position: value } };
1882
+ },
1883
+ convertGet: async (entity, key, meta) => {
1884
+ await entity.read("hvacThermostat", ["acLouverPosition"]);
1885
+ },
1886
+ };
1887
+ exports.electrical_measurement_power = {
1888
+ key: ["power"],
1889
+ convertGet: async (entity, key, meta) => {
1890
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
1891
+ await ep.read("haElectricalMeasurement", ["activePower"]);
1892
+ },
1893
+ };
1894
+ exports.electrical_measurement_power_phase_b = {
1895
+ key: ["power_phase_b"],
1896
+ convertGet: async (entity, key, meta) => {
1897
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
1898
+ await ep.read("haElectricalMeasurement", ["activePowerPhB"]);
1899
+ },
1900
+ };
1901
+ exports.electrical_measurement_power_phase_c = {
1902
+ key: ["power_phase_c"],
1903
+ convertGet: async (entity, key, meta) => {
1904
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
1905
+ await ep.read("haElectricalMeasurement", ["activePowerPhC"]);
1906
+ },
1907
+ };
1908
+ exports.metering_power = {
1909
+ key: ["power"],
1910
+ convertGet: async (entity, key, meta) => {
1911
+ utils.assertEndpoint(entity);
1912
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "seMetering");
1913
+ await ep.read("seMetering", ["instantaneousDemand"]);
1914
+ },
1915
+ };
1916
+ exports.metering_status = {
1917
+ key: ["status"],
1918
+ convertGet: async (entity, key, meta) => {
1919
+ utils.assertEndpoint(entity);
1920
+ await utils.enforceEndpoint(entity, key, meta).read("seMetering", ["status"]);
1921
+ },
1922
+ };
1923
+ exports.metering_extended_status = {
1924
+ key: ["extended_status"],
1925
+ convertGet: async (entity, key, meta) => {
1926
+ utils.assertEndpoint(entity);
1927
+ await utils.enforceEndpoint(entity, key, meta).read("seMetering", ["extendedStatus"]);
1928
+ },
1929
+ };
1930
+ exports.currentsummdelivered = {
1931
+ key: ["energy"],
1932
+ convertGet: async (entity, key, meta) => {
1933
+ utils.assertEndpoint(entity);
1934
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "seMetering");
1935
+ await ep.read("seMetering", ["currentSummDelivered"]);
1936
+ },
1937
+ };
1938
+ exports.currenttier1summdelivered = {
1939
+ key: ["energy_tier_1"],
1940
+ convertGet: async (entity, key, meta) => {
1941
+ utils.assertEndpoint(entity);
1942
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "seMetering");
1943
+ await ep.read("seMetering", ["currentTier1SummDelivered"]);
1944
+ },
1945
+ };
1946
+ exports.currenttier2summdelivered = {
1947
+ key: ["energy_tier_2"],
1948
+ convertGet: async (entity, key, meta) => {
1949
+ utils.assertEndpoint(entity);
1950
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "seMetering");
1951
+ await ep.read("seMetering", ["currentTier2SummDelivered"]);
1952
+ },
1953
+ };
1954
+ exports.currenttier3summdelivered = {
1955
+ key: ["energy_tier_3"],
1956
+ convertGet: async (entity, key, meta) => {
1957
+ utils.assertEndpoint(entity);
1958
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "seMetering");
1959
+ await ep.read("seMetering", ["currentTier3SummDelivered"]);
1960
+ },
1961
+ };
1962
+ exports.currenttier4summdelivered = {
1963
+ key: ["energy_tier_4"],
1964
+ convertGet: async (entity, key, meta) => {
1965
+ utils.assertEndpoint(entity);
1966
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "seMetering");
1967
+ await ep.read("seMetering", ["currentTier4SummDelivered"]);
1968
+ },
1969
+ };
1970
+ exports.currentsummreceived = {
1971
+ key: ["produced_energy"],
1972
+ convertGet: async (entity, key, meta) => {
1973
+ utils.assertEndpoint(entity);
1974
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "seMetering");
1975
+ await ep.read("seMetering", ["currentSummReceived"]);
1976
+ },
1977
+ };
1978
+ exports.frequency = {
1979
+ key: ["ac_frequency"],
1980
+ convertGet: async (entity, key, meta) => {
1981
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
1982
+ await ep.read("haElectricalMeasurement", ["acFrequency"]);
1983
+ },
1984
+ };
1985
+ exports.electrical_measurement_power_reactive = {
1986
+ key: ["power_reactive"],
1987
+ convertGet: async (entity, key, meta) => {
1988
+ await entity.read("haElectricalMeasurement", ["reactivePower"]);
1989
+ },
1990
+ };
1991
+ exports.powerfactor = {
1992
+ key: ["power_factor"],
1993
+ convertGet: async (entity, key, meta) => {
1994
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
1995
+ await ep.read("haElectricalMeasurement", ["powerFactor"]);
1996
+ },
1997
+ };
1998
+ exports.acvoltage = {
1999
+ key: ["voltage"],
2000
+ convertGet: async (entity, key, meta) => {
2001
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
2002
+ await ep.read("haElectricalMeasurement", ["rmsVoltage"]);
2003
+ },
2004
+ };
2005
+ exports.acvoltage_phase_b = {
2006
+ key: ["voltage_phase_b"],
2007
+ convertGet: async (entity, key, meta) => {
2008
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
2009
+ await ep.read("haElectricalMeasurement", ["rmsVoltagePhB"]);
2010
+ },
2011
+ };
2012
+ exports.acvoltage_phase_c = {
2013
+ key: ["voltage_phase_c"],
2014
+ convertGet: async (entity, key, meta) => {
2015
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
2016
+ await ep.read("haElectricalMeasurement", ["rmsVoltagePhC"]);
2017
+ },
2018
+ };
2019
+ exports.accurrent = {
2020
+ key: ["current"],
2021
+ convertGet: async (entity, key, meta) => {
2022
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
2023
+ await ep.read("haElectricalMeasurement", ["rmsCurrent"]);
2024
+ },
2025
+ };
2026
+ exports.accurrent_phase_b = {
2027
+ key: ["current_phase_b"],
2028
+ convertGet: async (entity, key, meta) => {
2029
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
2030
+ await ep.read("haElectricalMeasurement", ["rmsCurrentPhB"]);
2031
+ },
2032
+ };
2033
+ exports.accurrent_phase_c = {
2034
+ key: ["current_phase_c"],
2035
+ convertGet: async (entity, key, meta) => {
2036
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
2037
+ await ep.read("haElectricalMeasurement", ["rmsCurrentPhC"]);
2038
+ },
2039
+ };
2040
+ exports.accurrent_neutral = {
2041
+ key: ["current_neutral"],
2042
+ convertGet: async (entity, key, meta) => {
2043
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
2044
+ await ep.read("haElectricalMeasurement", ["neutralCurrent"]);
2045
+ },
2046
+ };
2047
+ exports.dccurrent = {
2048
+ key: ["current"],
2049
+ convertGet: async (entity, key, meta) => {
2050
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
2051
+ await ep.read("haElectricalMeasurement", ["dcCurrent"]);
2052
+ },
2053
+ };
2054
+ exports.dcvoltage = {
2055
+ key: ["voltage"],
2056
+ convertGet: async (entity, key, meta) => {
2057
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
2058
+ await ep.read("haElectricalMeasurement", ["dcVoltage"]);
2059
+ },
2060
+ };
2061
+ exports.dcpower = {
2062
+ key: ["power"],
2063
+ convertGet: async (entity, key, meta) => {
2064
+ const ep = (0, utils_1.determineEndpoint)(entity, meta, "haElectricalMeasurement");
2065
+ await ep.read("haElectricalMeasurement", ["dcPower"]);
2066
+ },
2067
+ };
2068
+ exports.temperature = {
2069
+ key: ["temperature"],
2070
+ convertGet: async (entity, key, meta) => {
2071
+ await entity.read("msTemperatureMeasurement", ["measuredValue"]);
2072
+ },
2073
+ };
2074
+ exports.humidity = {
2075
+ key: ["humidity"],
2076
+ convertGet: async (entity, key, meta) => {
2077
+ await entity.read("msRelativeHumidity", ["measuredValue"]);
2078
+ },
2079
+ };
2080
+ // #endregion
2081
+ // #region Non-generic converters
2082
+ exports.livolo_socket_switch_on_off = {
2083
+ key: ["state"],
2084
+ 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 });
2155
+ },
2156
+ };
2157
+ exports.livolo_switch_on_off = {
2158
+ key: ["state"],
2159
+ convertSet: async (entity, key, value, meta) => {
2160
+ 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;
2166
+ }
2167
+ else if (postfix === "right") {
2168
+ channel = 2.0;
2169
+ }
2170
+ else {
2171
+ return;
2172
+ }
2173
+ await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: state, transtime: channel, optionsMask: 0, optionsOverride: 0 });
2174
+ return { state: { state: value.toUpperCase() } };
2175
+ },
2176
+ convertGet: async (entity, key, meta) => {
2177
+ await entity.command("genOnOff", "toggle", {}, { transactionSequenceNumber: 0 });
2178
+ },
2179
+ };
2180
+ exports.livolo_dimmer_level = {
2181
+ key: ["brightness", "brightness_percent", "level"],
2182
+ 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
+ }
2195
+ }
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");
2202
+ }
2203
+ }
2204
+ 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
+ }
2211
+ }
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
+ };
2292
+ },
2293
+ };
2294
+ exports.livolo_cover_options = {
2295
+ key: ["options"],
2296
+ 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')`);
2321
+ }
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)");
2330
+ }
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);
2335
+ }
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");
2392
+ }
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" } };
2396
+ }
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);
2463
+ },
2464
+ };
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"],
3791
+ convertSet: async (entity, key, value, meta) => {
3792
+ utils.assertObject(value);
3793
+ utils.assertNumber(value.ID, "ID");
3794
+ if (value.color_temp != null && value.color != null) {
3795
+ throw new Error(`Don't specify both 'color_temp' and 'color'`);
3796
+ }
3797
+ const isGroup = utils.isGroup(entity);
3798
+ const groupid = isGroup ? entity.groupID : value.group_id != null ? value.group_id : 0;
3799
+ const sceneid = value.ID;
3800
+ const scenename = value.name;
3801
+ const transtime = value.transition != null ? value.transition : 0;
3802
+ if (groupid === 0 && sceneid === 0) {
3803
+ // From Zigbee spec:
3804
+ // "Scene identifier 0x00, along with group identifier 0x0000, is reserved for the global scene used by the OnOff cluster"
3805
+ throw new Error("Scene ID 0 cannot be used with group ID 0 (reserved).");
3806
+ }
3807
+ const state = {};
3808
+ const extensionfieldsets = [];
3809
+ for (const attribute of Object.keys(value)) {
3810
+ let val = value[attribute];
3811
+ if (attribute === "state") {
3812
+ extensionfieldsets.push({ clstId: 6, len: 1, extField: [val.toLowerCase() === "on" ? 1 : 0] });
3813
+ state.state = val.toUpperCase();
3814
+ }
3815
+ else if (attribute === "brightness") {
3816
+ extensionfieldsets.push({ clstId: 8, len: 1, extField: [val] });
3817
+ state.brightness = val;
3818
+ }
3819
+ else if (attribute === "position") {
3820
+ const invert = utils.getMetaValue(entity, meta.mapped, "coverInverted", "allEqual", false)
3821
+ ? !meta.options.invert_cover
3822
+ : meta.options.invert_cover;
3823
+ extensionfieldsets.push({ clstId: 258, len: 1, extField: [invert ? 100 - val : val] });
3824
+ state.position = val;
3825
+ }
3826
+ else if (attribute === "color_temp") {
3827
+ /*
3828
+ * ZCL version 7 added support for ColorTemperatureMireds
3829
+ *
3830
+ * Currently no devices seem to support this, so always fallback to XY conversion. In the future if a device
3831
+ * supports this, or other features get added this the following commit contains an implementation:
3832
+ * https://github.com/Koenkk/zigbee-herdsman-converters/pull/1837/commits/c22175b946b83230ce4e711c2a3796cf2029e78f
3833
+ *
3834
+ * Conversion to XY is allowed according to the ZCL:
3835
+ * `Since there is a direct relation between ColorTemperatureMireds and XY,
3836
+ * color temperature, if supported, is stored as XY in the scenes table.`
3837
+ *
3838
+ * See https://github.com/Koenkk/zigbee2mqtt/issues/4926#issuecomment-735947705
3839
+ */
3840
+ const [colorTempMin, colorTempMax] = light.findColorTempRange(entity);
3841
+ val = light.clampColorTemp(val, colorTempMin, colorTempMax);
3842
+ const xy = libColor.ColorXY.fromMireds(val);
3843
+ const xScaled = utils.mapNumberRange(xy.x, 0, 1, 0, 65535);
3844
+ const yScaled = utils.mapNumberRange(xy.y, 0, 1, 0, 65535);
3845
+ extensionfieldsets.push({ clstId: 768, len: 4, extField: [xScaled, yScaled] });
3846
+ state.color_mode = constants.colorModeLookup[2];
3847
+ state.color_temp = val;
3848
+ }
3849
+ else if (attribute === "color") {
3850
+ try {
3851
+ val = JSON.parse(val);
3852
+ }
3853
+ catch {
3854
+ /* empty */
3855
+ }
3856
+ const newColor = libColor.Color.fromConverterArg(val);
3857
+ if (newColor.isXY()) {
3858
+ const xScaled = utils.mapNumberRange(newColor.xy.x, 0, 1, 0, 65535);
3859
+ const yScaled = utils.mapNumberRange(newColor.xy.y, 0, 1, 0, 65535);
3860
+ extensionfieldsets.push({
3861
+ clstId: 768,
3862
+ len: 4,
3863
+ extField: [xScaled, yScaled],
3864
+ });
3865
+ state.color_mode = constants.colorModeLookup[1];
3866
+ state.color = newColor.xy.toObject();
3867
+ }
3868
+ else if (newColor.isHSV()) {
3869
+ const hsvCorrected = newColor.hsv.colorCorrected(meta);
3870
+ if (utils.getMetaValue(entity, meta.mapped, "supportsEnhancedHue", "allEqual", true)) {
3871
+ const hScaled = utils.mapNumberRange(hsvCorrected.hue, 0, 360, 0, 65535);
3872
+ const sScaled = utils.mapNumberRange(hsvCorrected.saturation, 0, 100, 0, 254);
3873
+ extensionfieldsets.push({
3874
+ clstId: 768,
3875
+ len: 13,
3876
+ extField: [0, 0, hScaled, sScaled, 0, 0, 0, 0],
3877
+ });
3878
+ }
3879
+ else {
3880
+ // The extensionFieldSet is always EnhancedCurrentHue according to ZCL
3881
+ // When the bulb or all bulbs in a group do not support enhanchedHue,
3882
+ const colorXY = hsvCorrected.toXY();
3883
+ 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 });
4264
+ },
4265
+ };
4266
+ exports.schneider_temperature_measured_value = {
4267
+ key: ["temperature_measured_value"],
4268
+ convertSet: async (entity, key, value, meta) => {
4269
+ 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]);
4366
+ },
4367
+ };
4368
+ exports.wiser_vact_calibrate_valve = {
4369
+ key: ["calibrate_valve"],
4370
+ 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 } };
4379
+ },
4380
+ };
4381
+ exports.wiser_sed_occupied_heating_setpoint = {
4382
+ key: ["occupied_heating_setpoint"],
4383
+ 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"]);
4415
+ },
4416
+ };
4417
+ exports.tuya_operation_mode = {
4418
+ key: ["operation_mode"],
4419
+ 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
+ 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 } };
4438
+ },
4439
+ convertGet: async (entity, key, meta) => {
4440
+ await entity.read("ssIasZone", [0x4000], { manufacturerCode: zigbee_herdsman_1.Zcl.ManufacturerCode.DATEK_WIRELESS_AS });
4441
+ },
4442
+ };
4443
+ // #endregion
4444
+ // #region Ignore converters
4445
+ exports.ignore_transition = {
4446
+ key: ["transition"],
4447
+ convertSet: async (entity, key, value, meta) => { },
4448
+ };
4449
+ exports.ignore_rate = {
4450
+ key: ["rate"],
4451
+ convertSet: async (entity, key, value, meta) => { },
4452
+ };
4453
+ // #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
+ //# sourceMappingURL=toZigbee.js.map