@willieee802/zigbee-herdsman-converters 19.44.4 → 19.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (591) hide show
  1. package/CHANGELOG.md +1101 -0
  2. package/dist/converters/actions.d.ts.map +1 -1
  3. package/dist/converters/actions.js +2 -0
  4. package/dist/converters/actions.js.map +1 -1
  5. package/dist/converters/fromZigbee.d.ts +1 -150
  6. package/dist/converters/fromZigbee.d.ts.map +1 -1
  7. package/dist/converters/fromZigbee.js +183 -3044
  8. package/dist/converters/fromZigbee.js.map +1 -1
  9. package/dist/converters/toZigbee.d.ts +0 -121
  10. package/dist/converters/toZigbee.d.ts.map +1 -1
  11. package/dist/converters/toZigbee.js +289 -2386
  12. package/dist/converters/toZigbee.js.map +1 -1
  13. package/dist/devices/ITCommander.d.ts.map +1 -1
  14. package/dist/devices/ITCommander.js +2 -1
  15. package/dist/devices/ITCommander.js.map +1 -1
  16. package/dist/devices/acova.d.ts.map +1 -1
  17. package/dist/devices/acova.js +69 -2
  18. package/dist/devices/acova.js.map +1 -1
  19. package/dist/devices/adeo.d.ts.map +1 -1
  20. package/dist/devices/adeo.js +35 -3
  21. package/dist/devices/adeo.js.map +1 -1
  22. package/dist/devices/adurosmart.js +1 -1
  23. package/dist/devices/adurosmart.js.map +1 -1
  24. package/dist/devices/amina.d.ts.map +1 -1
  25. package/dist/devices/amina.js +47 -10
  26. package/dist/devices/amina.js.map +1 -1
  27. package/dist/devices/aurora_lighting.d.ts.map +1 -1
  28. package/dist/devices/aurora_lighting.js +15 -0
  29. package/dist/devices/aurora_lighting.js.map +1 -1
  30. package/dist/devices/automaton.d.ts.map +1 -1
  31. package/dist/devices/automaton.js +1 -0
  32. package/dist/devices/automaton.js.map +1 -1
  33. package/dist/devices/avatto.d.ts.map +1 -1
  34. package/dist/devices/avatto.js +29 -24
  35. package/dist/devices/avatto.js.map +1 -1
  36. package/dist/devices/awox.d.ts.map +1 -1
  37. package/dist/devices/awox.js +41 -3
  38. package/dist/devices/awox.js.map +1 -1
  39. package/dist/devices/bacchus.d.ts.map +1 -1
  40. package/dist/devices/bacchus.js +75 -0
  41. package/dist/devices/bacchus.js.map +1 -1
  42. package/dist/devices/bitron.d.ts.map +1 -1
  43. package/dist/devices/bitron.js +29 -2
  44. package/dist/devices/bitron.js.map +1 -1
  45. package/dist/devices/bosch.d.ts.map +1 -1
  46. package/dist/devices/bosch.js +70 -50
  47. package/dist/devices/bosch.js.map +1 -1
  48. package/dist/devices/bticino.d.ts.map +1 -1
  49. package/dist/devices/bticino.js +11 -1
  50. package/dist/devices/bticino.js.map +1 -1
  51. package/dist/devices/byun.d.ts.map +1 -1
  52. package/dist/devices/byun.js +40 -3
  53. package/dist/devices/byun.js.map +1 -1
  54. package/dist/devices/candeo.d.ts.map +1 -1
  55. package/dist/devices/candeo.js +262 -9
  56. package/dist/devices/candeo.js.map +1 -1
  57. package/dist/devices/centralite.d.ts +9 -0
  58. package/dist/devices/centralite.d.ts.map +1 -1
  59. package/dist/devices/centralite.js +44 -5
  60. package/dist/devices/centralite.js.map +1 -1
  61. package/dist/devices/{aubess.d.ts → cigol.d.ts} +1 -1
  62. package/dist/devices/cigol.d.ts.map +1 -0
  63. package/dist/devices/cigol.js +260 -0
  64. package/dist/devices/cigol.js.map +1 -0
  65. package/dist/devices/cleverio.js +2 -2
  66. package/dist/devices/cleverio.js.map +1 -1
  67. package/dist/devices/climax.d.ts.map +1 -1
  68. package/dist/devices/climax.js +15 -1
  69. package/dist/devices/climax.js.map +1 -1
  70. package/dist/devices/ctm.d.ts.map +1 -1
  71. package/dist/devices/ctm.js +845 -496
  72. package/dist/devices/ctm.js.map +1 -1
  73. package/dist/devices/custom_devices_diy.d.ts +183 -1
  74. package/dist/devices/custom_devices_diy.d.ts.map +1 -1
  75. package/dist/devices/custom_devices_diy.js +390 -33
  76. package/dist/devices/custom_devices_diy.js.map +1 -1
  77. package/dist/devices/daewoo.d.ts +3 -0
  78. package/dist/devices/daewoo.d.ts.map +1 -0
  79. package/dist/devices/daewoo.js +198 -0
  80. package/dist/devices/daewoo.js.map +1 -0
  81. package/dist/devices/danfoss.d.ts.map +1 -1
  82. package/dist/devices/danfoss.js +1270 -296
  83. package/dist/devices/danfoss.js.map +1 -1
  84. package/dist/devices/databyte.d.ts.map +1 -1
  85. package/dist/devices/databyte.js +47 -3
  86. package/dist/devices/databyte.js.map +1 -1
  87. package/dist/devices/datek.d.ts.map +1 -1
  88. package/dist/devices/datek.js +202 -41
  89. package/dist/devices/datek.js.map +1 -1
  90. package/dist/devices/dawon_dns.d.ts.map +1 -1
  91. package/dist/devices/dawon_dns.js +14 -1
  92. package/dist/devices/dawon_dns.js.map +1 -1
  93. package/dist/devices/develco.d.ts.map +1 -1
  94. package/dist/devices/develco.js +145 -64
  95. package/dist/devices/develco.js.map +1 -1
  96. package/dist/devices/diyruz.d.ts.map +1 -1
  97. package/dist/devices/diyruz.js +444 -20
  98. package/dist/devices/diyruz.js.map +1 -1
  99. package/dist/devices/domraem.d.ts.map +1 -1
  100. package/dist/devices/domraem.js +7 -0
  101. package/dist/devices/domraem.js.map +1 -1
  102. package/dist/devices/easyaccess.d.ts.map +1 -1
  103. package/dist/devices/easyaccess.js +22 -2
  104. package/dist/devices/easyaccess.js.map +1 -1
  105. package/dist/devices/easyiot.d.ts.map +1 -1
  106. package/dist/devices/easyiot.js +767 -5
  107. package/dist/devices/easyiot.js.map +1 -1
  108. package/dist/devices/echostar.d.ts.map +1 -1
  109. package/dist/devices/echostar.js +25 -1
  110. package/dist/devices/echostar.js.map +1 -1
  111. package/dist/devices/ecodim.d.ts.map +1 -1
  112. package/dist/devices/ecodim.js +8 -0
  113. package/dist/devices/ecodim.js.map +1 -1
  114. package/dist/devices/ecolink.d.ts.map +1 -1
  115. package/dist/devices/ecolink.js +12 -0
  116. package/dist/devices/ecolink.js.map +1 -1
  117. package/dist/devices/efekta.d.ts.map +1 -1
  118. package/dist/devices/efekta.js +1615 -60
  119. package/dist/devices/efekta.js.map +1 -1
  120. package/dist/devices/eglo.d.ts.map +1 -1
  121. package/dist/devices/eglo.js +203 -17
  122. package/dist/devices/eglo.js.map +1 -1
  123. package/dist/devices/elko.d.ts.map +1 -1
  124. package/dist/devices/elko.js +20 -22
  125. package/dist/devices/elko.js.map +1 -1
  126. package/dist/devices/engo.d.ts.map +1 -1
  127. package/dist/devices/engo.js +201 -0
  128. package/dist/devices/engo.js.map +1 -1
  129. package/dist/devices/enocean.d.ts.map +1 -1
  130. package/dist/devices/enocean.js +132 -4
  131. package/dist/devices/enocean.js.map +1 -1
  132. package/dist/devices/ensystec.d.ts +3 -0
  133. package/dist/devices/ensystec.d.ts.map +1 -0
  134. package/dist/devices/ensystec.js +1200 -0
  135. package/dist/devices/ensystec.js.map +1 -0
  136. package/dist/devices/eurotronic.d.ts +78 -1
  137. package/dist/devices/eurotronic.d.ts.map +1 -1
  138. package/dist/devices/eurotronic.js +244 -40
  139. package/dist/devices/eurotronic.js.map +1 -1
  140. package/dist/devices/ewelink.d.ts.map +1 -1
  141. package/dist/devices/ewelink.js +154 -2
  142. package/dist/devices/ewelink.js.map +1 -1
  143. package/dist/devices/fantem.js +1 -1
  144. package/dist/devices/fantem.js.map +1 -1
  145. package/dist/devices/fireangel.d.ts.map +1 -1
  146. package/dist/devices/fireangel.js +12 -1
  147. package/dist/devices/fireangel.js.map +1 -1
  148. package/dist/devices/frankever.d.ts.map +1 -1
  149. package/dist/devices/frankever.js +96 -0
  150. package/dist/devices/frankever.js.map +1 -1
  151. package/dist/devices/frient.d.ts.map +1 -1
  152. package/dist/devices/frient.js +15 -0
  153. package/dist/devices/frient.js.map +1 -1
  154. package/dist/devices/girier.js +1 -1
  155. package/dist/devices/girier.js.map +1 -1
  156. package/dist/devices/gledopto.js +1 -1
  157. package/dist/devices/gledopto.js.map +1 -1
  158. package/dist/devices/gmmts.d.ts.map +1 -1
  159. package/dist/devices/gmmts.js +59 -55
  160. package/dist/devices/gmmts.js.map +1 -1
  161. package/dist/devices/halo_smart_labs.d.ts +3 -0
  162. package/dist/devices/halo_smart_labs.d.ts.map +1 -0
  163. package/dist/devices/halo_smart_labs.js +918 -0
  164. package/dist/devices/halo_smart_labs.js.map +1 -0
  165. package/dist/devices/handshake_finland.d.ts +3 -0
  166. package/dist/devices/handshake_finland.d.ts.map +1 -0
  167. package/dist/devices/handshake_finland.js +15 -0
  168. package/dist/devices/handshake_finland.js.map +1 -0
  169. package/dist/devices/heiman.d.ts.map +1 -1
  170. package/dist/devices/heiman.js +1361 -147
  171. package/dist/devices/heiman.js.map +1 -1
  172. package/dist/devices/heimgard_technologies.d.ts.map +1 -1
  173. package/dist/devices/heimgard_technologies.js +13 -0
  174. package/dist/devices/heimgard_technologies.js.map +1 -1
  175. package/dist/devices/hive.d.ts.map +1 -1
  176. package/dist/devices/hive.js +11 -0
  177. package/dist/devices/hive.js.map +1 -1
  178. package/dist/devices/ikea.d.ts.map +1 -1
  179. package/dist/devices/ikea.js +185 -135
  180. package/dist/devices/ikea.js.map +1 -1
  181. package/dist/devices/iluminize.d.ts.map +1 -1
  182. package/dist/devices/iluminize.js +8 -7
  183. package/dist/devices/iluminize.js.map +1 -1
  184. package/dist/devices/immax.d.ts.map +1 -1
  185. package/dist/devices/immax.js +3 -1
  186. package/dist/devices/immax.js.map +1 -1
  187. package/dist/devices/index.d.ts.map +1 -1
  188. package/dist/devices/index.js +20 -2
  189. package/dist/devices/index.js.map +1 -1
  190. package/dist/devices/innr.d.ts.map +1 -1
  191. package/dist/devices/innr.js +34 -2
  192. package/dist/devices/innr.js.map +1 -1
  193. package/dist/devices/inovelli.d.ts.map +1 -1
  194. package/dist/devices/inovelli.js +41 -2348
  195. package/dist/devices/inovelli.js.map +1 -1
  196. package/dist/devices/iris.d.ts.map +1 -1
  197. package/dist/devices/iris.js +13 -1
  198. package/dist/devices/iris.js.map +1 -1
  199. package/dist/devices/javis.d.ts.map +1 -1
  200. package/dist/devices/javis.js +39 -1
  201. package/dist/devices/javis.js.map +1 -1
  202. package/dist/devices/jxuan.d.ts.map +1 -1
  203. package/dist/devices/jxuan.js +37 -2
  204. package/dist/devices/jxuan.js.map +1 -1
  205. package/dist/devices/kami.d.ts.map +1 -1
  206. package/dist/devices/kami.js +21 -2
  207. package/dist/devices/kami.js.map +1 -1
  208. package/dist/devices/keen_home.d.ts.map +1 -1
  209. package/dist/devices/keen_home.js +13 -3
  210. package/dist/devices/keen_home.js.map +1 -1
  211. package/dist/devices/klikaanklikuit.d.ts.map +1 -1
  212. package/dist/devices/klikaanklikuit.js +7 -0
  213. package/dist/devices/klikaanklikuit.js.map +1 -1
  214. package/dist/devices/kmpcil.d.ts.map +1 -1
  215. package/dist/devices/kmpcil.js +44 -5
  216. package/dist/devices/kmpcil.js.map +1 -1
  217. package/dist/devices/konke.d.ts.map +1 -1
  218. package/dist/devices/konke.js +10 -1
  219. package/dist/devices/konke.js.map +1 -1
  220. package/dist/devices/lds.d.ts.map +1 -1
  221. package/dist/devices/lds.js +7 -0
  222. package/dist/devices/lds.js.map +1 -1
  223. package/dist/devices/led_trading.d.ts.map +1 -1
  224. package/dist/devices/led_trading.js +13 -13
  225. package/dist/devices/led_trading.js.map +1 -1
  226. package/dist/devices/leedarson.d.ts.map +1 -1
  227. package/dist/devices/leedarson.js +140 -1
  228. package/dist/devices/leedarson.js.map +1 -1
  229. package/dist/devices/legrand.d.ts.map +1 -1
  230. package/dist/devices/legrand.js +73 -42
  231. package/dist/devices/legrand.js.map +1 -1
  232. package/dist/devices/lellki.d.ts.map +1 -1
  233. package/dist/devices/lellki.js +3 -1
  234. package/dist/devices/lellki.js.map +1 -1
  235. package/dist/devices/letv.d.ts.map +1 -1
  236. package/dist/devices/letv.js +16 -2
  237. package/dist/devices/letv.js.map +1 -1
  238. package/dist/devices/lidl.d.ts.map +1 -1
  239. package/dist/devices/lidl.js +26 -6
  240. package/dist/devices/lidl.js.map +1 -1
  241. package/dist/devices/lincukoo.d.ts.map +1 -1
  242. package/dist/devices/lincukoo.js +92 -31
  243. package/dist/devices/lincukoo.js.map +1 -1
  244. package/dist/devices/linkind.d.ts.map +1 -1
  245. package/dist/devices/linkind.js +14 -1
  246. package/dist/devices/linkind.js.map +1 -1
  247. package/dist/devices/linptech.d.ts.map +1 -1
  248. package/dist/devices/linptech.js +3 -1
  249. package/dist/devices/linptech.js.map +1 -1
  250. package/dist/devices/livingwise.d.ts.map +1 -1
  251. package/dist/devices/livingwise.js +2 -1
  252. package/dist/devices/livingwise.js.map +1 -1
  253. package/dist/devices/livolo.d.ts.map +1 -1
  254. package/dist/devices/livolo.js +612 -20
  255. package/dist/devices/livolo.js.map +1 -1
  256. package/dist/devices/lixee.d.ts.map +1 -1
  257. package/dist/devices/lixee.js +46 -44
  258. package/dist/devices/lixee.js.map +1 -1
  259. package/dist/devices/lonsonho.d.ts.map +1 -1
  260. package/dist/devices/lonsonho.js +18 -11
  261. package/dist/devices/lonsonho.js.map +1 -1
  262. package/dist/devices/lumi.d.ts.map +1 -1
  263. package/dist/devices/lumi.js +877 -155
  264. package/dist/devices/lumi.js.map +1 -1
  265. package/dist/devices/lytko.d.ts.map +1 -1
  266. package/dist/devices/lytko.js +205 -556
  267. package/dist/devices/lytko.js.map +1 -1
  268. package/dist/devices/makegood.d.ts.map +1 -1
  269. package/dist/devices/makegood.js +5 -1
  270. package/dist/devices/makegood.js.map +1 -1
  271. package/dist/devices/mazda.js +7 -7
  272. package/dist/devices/mazda.js.map +1 -1
  273. package/dist/devices/meazon.d.ts.map +1 -1
  274. package/dist/devices/meazon.js +82 -20
  275. package/dist/devices/meazon.js.map +1 -1
  276. package/dist/devices/megaman.d.ts +4 -0
  277. package/dist/devices/megaman.d.ts.map +1 -0
  278. package/dist/devices/megaman.js +48 -0
  279. package/dist/devices/megaman.js.map +1 -0
  280. package/dist/devices/mercator.d.ts.map +1 -1
  281. package/dist/devices/mercator.js +20 -5
  282. package/dist/devices/mercator.js.map +1 -1
  283. package/dist/devices/miboxer.d.ts.map +1 -1
  284. package/dist/devices/miboxer.js +3 -1
  285. package/dist/devices/miboxer.js.map +1 -1
  286. package/dist/devices/mill.d.ts.map +1 -1
  287. package/dist/devices/mill.js +33 -7
  288. package/dist/devices/mill.js.map +1 -1
  289. package/dist/devices/moes.d.ts.map +1 -1
  290. package/dist/devices/moes.js +89 -15
  291. package/dist/devices/moes.js.map +1 -1
  292. package/dist/devices/msh.d.ts +3 -0
  293. package/dist/devices/msh.d.ts.map +1 -0
  294. package/dist/devices/msh.js +93 -0
  295. package/dist/devices/msh.js.map +1 -0
  296. package/dist/devices/muller_licht.d.ts.map +1 -1
  297. package/dist/devices/muller_licht.js +11 -0
  298. package/dist/devices/muller_licht.js.map +1 -1
  299. package/dist/devices/multir.d.ts.map +1 -1
  300. package/dist/devices/multir.js +12 -1
  301. package/dist/devices/multir.js.map +1 -1
  302. package/dist/devices/multiterm.js +2 -2
  303. package/dist/devices/multiterm.js.map +1 -1
  304. package/dist/devices/namron.d.ts.map +1 -1
  305. package/dist/devices/namron.js +488 -128
  306. package/dist/devices/namron.js.map +1 -1
  307. package/dist/devices/neo.d.ts.map +1 -1
  308. package/dist/devices/neo.js +151 -192
  309. package/dist/devices/neo.js.map +1 -1
  310. package/dist/devices/netica.d.ts +3 -0
  311. package/dist/devices/netica.d.ts.map +1 -0
  312. package/dist/devices/netica.js +153 -0
  313. package/dist/devices/netica.js.map +1 -0
  314. package/dist/devices/niko.d.ts.map +1 -1
  315. package/dist/devices/niko.js +10 -8
  316. package/dist/devices/niko.js.map +1 -1
  317. package/dist/devices/nodon.d.ts.map +1 -1
  318. package/dist/devices/nodon.js +6 -4
  319. package/dist/devices/nodon.js.map +1 -1
  320. package/dist/devices/nous.d.ts.map +1 -1
  321. package/dist/devices/nous.js +160 -61
  322. package/dist/devices/nous.js.map +1 -1
  323. package/dist/devices/nue_3a.d.ts.map +1 -1
  324. package/dist/devices/nue_3a.js +2 -0
  325. package/dist/devices/nue_3a.js.map +1 -1
  326. package/dist/devices/onesti.d.ts +11 -1
  327. package/dist/devices/onesti.d.ts.map +1 -1
  328. package/dist/devices/onesti.js +30 -6
  329. package/dist/devices/onesti.js.map +1 -1
  330. package/dist/devices/onokom.d.ts.map +1 -1
  331. package/dist/devices/onokom.js +1152 -2309
  332. package/dist/devices/onokom.js.map +1 -1
  333. package/dist/devices/orvibo.d.ts +17 -1
  334. package/dist/devices/orvibo.d.ts.map +1 -1
  335. package/dist/devices/orvibo.js +71 -4
  336. package/dist/devices/orvibo.js.map +1 -1
  337. package/dist/devices/owon.d.ts.map +1 -1
  338. package/dist/devices/owon.js +382 -62
  339. package/dist/devices/owon.js.map +1 -1
  340. package/dist/devices/paul_neuhaus.d.ts.map +1 -1
  341. package/dist/devices/paul_neuhaus.js +9 -0
  342. package/dist/devices/paul_neuhaus.js.map +1 -1
  343. package/dist/devices/paulmann.js +2 -2
  344. package/dist/devices/paulmann.js.map +1 -1
  345. package/dist/devices/perenio.d.ts.map +1 -1
  346. package/dist/devices/perenio.js +57 -39
  347. package/dist/devices/perenio.js.map +1 -1
  348. package/dist/devices/philips.d.ts.map +1 -1
  349. package/dist/devices/philips.js +194 -53
  350. package/dist/devices/philips.js.map +1 -1
  351. package/dist/devices/plaid.d.ts.map +1 -1
  352. package/dist/devices/plaid.js +18 -1
  353. package/dist/devices/plaid.js.map +1 -1
  354. package/dist/devices/plugwise.d.ts.map +1 -1
  355. package/dist/devices/plugwise.js +307 -26
  356. package/dist/devices/plugwise.js.map +1 -1
  357. package/dist/devices/profalux.d.ts.map +1 -1
  358. package/dist/devices/profalux.js +25 -1
  359. package/dist/devices/profalux.js.map +1 -1
  360. package/dist/devices/pushok.d.ts.map +1 -1
  361. package/dist/devices/pushok.js +44 -0
  362. package/dist/devices/pushok.js.map +1 -1
  363. package/dist/devices/qa.d.ts.map +1 -1
  364. package/dist/devices/qa.js +80 -32
  365. package/dist/devices/qa.js.map +1 -1
  366. package/dist/devices/repenic_ltd.d.ts +3 -0
  367. package/dist/devices/repenic_ltd.d.ts.map +1 -0
  368. package/dist/devices/repenic_ltd.js +97 -0
  369. package/dist/devices/repenic_ltd.js.map +1 -0
  370. package/dist/devices/robb.d.ts.map +1 -1
  371. package/dist/devices/robb.js +13 -1
  372. package/dist/devices/robb.js.map +1 -1
  373. package/dist/devices/rtx.js +1 -1
  374. package/dist/devices/rtx.js.map +1 -1
  375. package/dist/devices/salus_controls.d.ts.map +1 -1
  376. package/dist/devices/salus_controls.js +44 -17
  377. package/dist/devices/salus_controls.js.map +1 -1
  378. package/dist/devices/samotech.js +2 -2
  379. package/dist/devices/samotech.js.map +1 -1
  380. package/dist/devices/sber.d.ts.map +1 -1
  381. package/dist/devices/sber.js +435 -26
  382. package/dist/devices/sber.js.map +1 -1
  383. package/dist/devices/schneider_electric.d.ts.map +1 -1
  384. package/dist/devices/schneider_electric.js +808 -252
  385. package/dist/devices/schneider_electric.js.map +1 -1
  386. package/dist/devices/securifi.d.ts.map +1 -1
  387. package/dist/devices/securifi.js +24 -1
  388. package/dist/devices/securifi.js.map +1 -1
  389. package/dist/devices/sengled.d.ts.map +1 -1
  390. package/dist/devices/sengled.js +5 -4
  391. package/dist/devices/sengled.js.map +1 -1
  392. package/dist/devices/shada.d.ts +3 -0
  393. package/dist/devices/shada.d.ts.map +1 -0
  394. package/dist/devices/{aubess.js → shada.js} +7 -20
  395. package/dist/devices/shada.js.map +1 -0
  396. package/dist/devices/shelly.d.ts.map +1 -1
  397. package/dist/devices/shelly.js +646 -61
  398. package/dist/devices/shelly.js.map +1 -1
  399. package/dist/devices/shinasystem.d.ts.map +1 -1
  400. package/dist/devices/shinasystem.js +75 -16
  401. package/dist/devices/shinasystem.js.map +1 -1
  402. package/dist/devices/siglis.d.ts.map +1 -1
  403. package/dist/devices/siglis.js +26 -0
  404. package/dist/devices/siglis.js.map +1 -1
  405. package/dist/devices/sinope.d.ts.map +1 -1
  406. package/dist/devices/sinope.js +163 -83
  407. package/dist/devices/sinope.js.map +1 -1
  408. package/dist/devices/slacky_diy.d.ts.map +1 -1
  409. package/dist/devices/slacky_diy.js +3007 -69
  410. package/dist/devices/slacky_diy.js.map +1 -1
  411. package/dist/devices/smarli.d.ts.map +1 -1
  412. package/dist/devices/smarli.js +4 -5
  413. package/dist/devices/smarli.js.map +1 -1
  414. package/dist/devices/smartthings.d.ts +25 -0
  415. package/dist/devices/smartthings.d.ts.map +1 -1
  416. package/dist/devices/smartthings.js +62 -11
  417. package/dist/devices/smartthings.js.map +1 -1
  418. package/dist/devices/somfy.d.ts.map +1 -1
  419. package/dist/devices/somfy.js +14 -1
  420. package/dist/devices/somfy.js.map +1 -1
  421. package/dist/devices/sonoff.d.ts +42 -1
  422. package/dist/devices/sonoff.d.ts.map +1 -1
  423. package/dist/devices/sonoff.js +5161 -2007
  424. package/dist/devices/sonoff.js.map +1 -1
  425. package/dist/devices/sprut.d.ts.map +1 -1
  426. package/dist/devices/sprut.js +5 -4
  427. package/dist/devices/sprut.js.map +1 -1
  428. package/dist/devices/stello.d.ts.map +1 -1
  429. package/dist/devices/stello.js +6 -24
  430. package/dist/devices/stello.js.map +1 -1
  431. package/dist/devices/stelpro.d.ts +51 -1
  432. package/dist/devices/stelpro.d.ts.map +1 -1
  433. package/dist/devices/stelpro.js +86 -23
  434. package/dist/devices/stelpro.js.map +1 -1
  435. package/dist/devices/sunricher.d.ts.map +1 -1
  436. package/dist/devices/sunricher.js +215 -29
  437. package/dist/devices/sunricher.js.map +1 -1
  438. package/dist/devices/tech.d.ts.map +1 -1
  439. package/dist/devices/tech.js +35 -35
  440. package/dist/devices/tech.js.map +1 -1
  441. package/dist/devices/terncy.d.ts.map +1 -1
  442. package/dist/devices/terncy.js +398 -2
  443. package/dist/devices/terncy.js.map +1 -1
  444. package/dist/devices/third_reality.d.ts +42 -1
  445. package/dist/devices/third_reality.d.ts.map +1 -1
  446. package/dist/devices/third_reality.js +521 -110
  447. package/dist/devices/third_reality.js.map +1 -1
  448. package/dist/devices/tuya.d.ts.map +1 -1
  449. package/dist/devices/tuya.js +3139 -814
  450. package/dist/devices/tuya.js.map +1 -1
  451. package/dist/devices/ubisys.d.ts.map +1 -1
  452. package/dist/devices/ubisys.js +11 -8
  453. package/dist/devices/ubisys.js.map +1 -1
  454. package/dist/devices/vesternet.d.ts.map +1 -1
  455. package/dist/devices/vesternet.js +7 -0
  456. package/dist/devices/vesternet.js.map +1 -1
  457. package/dist/devices/viessmann.d.ts.map +1 -1
  458. package/dist/devices/viessmann.js +107 -4
  459. package/dist/devices/viessmann.js.map +1 -1
  460. package/dist/devices/vsmart.d.ts.map +1 -1
  461. package/dist/devices/vsmart.js +11 -0
  462. package/dist/devices/vsmart.js.map +1 -1
  463. package/dist/devices/weiser.d.ts.map +1 -1
  464. package/dist/devices/weiser.js +6 -0
  465. package/dist/devices/weiser.js.map +1 -1
  466. package/dist/devices/wirenboard.d.ts.map +1 -1
  467. package/dist/devices/wirenboard.js +124 -21
  468. package/dist/devices/wirenboard.js.map +1 -1
  469. package/dist/devices/wmun.d.ts.map +1 -1
  470. package/dist/devices/wmun.js +3 -2
  471. package/dist/devices/wmun.js.map +1 -1
  472. package/dist/devices/woolley.d.ts.map +1 -1
  473. package/dist/devices/woolley.js +6 -9
  474. package/dist/devices/woolley.js.map +1 -1
  475. package/dist/devices/woox.js +2 -2
  476. package/dist/devices/woox.js.map +1 -1
  477. package/dist/devices/xyzroe.d.ts.map +1 -1
  478. package/dist/devices/xyzroe.js +16 -4
  479. package/dist/devices/xyzroe.js.map +1 -1
  480. package/dist/devices/yale.d.ts.map +1 -1
  481. package/dist/devices/yale.js +138 -40
  482. package/dist/devices/yale.js.map +1 -1
  483. package/dist/devices/yandex.d.ts.map +1 -1
  484. package/dist/devices/yandex.js +93 -11
  485. package/dist/devices/yandex.js.map +1 -1
  486. package/dist/devices/yokis.d.ts.map +1 -1
  487. package/dist/devices/yokis.js +122 -85
  488. package/dist/devices/yokis.js.map +1 -1
  489. package/dist/devices/zbeacon.d.ts.map +1 -1
  490. package/dist/devices/zbeacon.js +0 -7
  491. package/dist/devices/zbeacon.js.map +1 -1
  492. package/dist/devices/zemismart.d.ts.map +1 -1
  493. package/dist/devices/zemismart.js +148 -11
  494. package/dist/devices/zemismart.js.map +1 -1
  495. package/dist/devices/zigbeetlc.js +1 -1
  496. package/dist/devices/zigbeetlc.js.map +1 -1
  497. package/dist/index.d.ts +1 -1
  498. package/dist/index.d.ts.map +1 -1
  499. package/dist/index.js +40 -35
  500. package/dist/index.js.map +1 -1
  501. package/dist/lib/bosch.d.ts.map +1 -1
  502. package/dist/lib/bosch.js +212 -42
  503. package/dist/lib/bosch.js.map +1 -1
  504. package/dist/lib/constants.d.ts +99 -17
  505. package/dist/lib/constants.d.ts.map +1 -1
  506. package/dist/lib/constants.js +15 -2
  507. package/dist/lib/constants.js.map +1 -1
  508. package/dist/lib/develco.d.ts +11 -0
  509. package/dist/lib/develco.d.ts.map +1 -1
  510. package/dist/lib/develco.js +78 -9
  511. package/dist/lib/develco.js.map +1 -1
  512. package/dist/lib/exposes.d.ts +11 -10
  513. package/dist/lib/exposes.d.ts.map +1 -1
  514. package/dist/lib/exposes.js +7 -48
  515. package/dist/lib/exposes.js.map +1 -1
  516. package/dist/lib/heiman.d.ts.map +1 -1
  517. package/dist/lib/heiman.js +34 -14
  518. package/dist/lib/heiman.js.map +1 -1
  519. package/dist/lib/ikea.d.ts +17 -0
  520. package/dist/lib/ikea.d.ts.map +1 -1
  521. package/dist/lib/ikea.js +46 -20
  522. package/dist/lib/ikea.js.map +1 -1
  523. package/dist/lib/inovelli.d.ts +86 -0
  524. package/dist/lib/inovelli.d.ts.map +1 -0
  525. package/dist/lib/inovelli.js +2580 -0
  526. package/dist/lib/inovelli.js.map +1 -0
  527. package/dist/lib/ledvance.d.ts +4 -4
  528. package/dist/lib/ledvance.d.ts.map +1 -1
  529. package/dist/lib/ledvance.js +23 -7
  530. package/dist/lib/ledvance.js.map +1 -1
  531. package/dist/lib/legacy.d.ts +21 -2
  532. package/dist/lib/legacy.d.ts.map +1 -1
  533. package/dist/lib/legacy.js +29 -2
  534. package/dist/lib/legacy.js.map +1 -1
  535. package/dist/lib/legrand.d.ts +65 -6
  536. package/dist/lib/legrand.d.ts.map +1 -1
  537. package/dist/lib/legrand.js +188 -9
  538. package/dist/lib/legrand.js.map +1 -1
  539. package/dist/lib/light.d.ts +1 -1
  540. package/dist/lib/light.d.ts.map +1 -1
  541. package/dist/lib/light.js +2 -2
  542. package/dist/lib/light.js.map +1 -1
  543. package/dist/lib/lumi.d.ts +88 -44
  544. package/dist/lib/lumi.d.ts.map +1 -1
  545. package/dist/lib/lumi.js +1813 -59
  546. package/dist/lib/lumi.js.map +1 -1
  547. package/dist/lib/modernExtend.d.ts +19 -14
  548. package/dist/lib/modernExtend.d.ts.map +1 -1
  549. package/dist/lib/modernExtend.js +37 -35
  550. package/dist/lib/modernExtend.js.map +1 -1
  551. package/dist/lib/namron.d.ts +131 -28
  552. package/dist/lib/namron.d.ts.map +1 -1
  553. package/dist/lib/namron.js +723 -42
  554. package/dist/lib/namron.js.map +1 -1
  555. package/dist/lib/nodon.d.ts.map +1 -1
  556. package/dist/lib/nodon.js +3 -1
  557. package/dist/lib/nodon.js.map +1 -1
  558. package/dist/lib/philips.d.ts +106 -2
  559. package/dist/lib/philips.d.ts.map +1 -1
  560. package/dist/lib/philips.js +945 -44
  561. package/dist/lib/philips.js.map +1 -1
  562. package/dist/lib/sonoff.d.ts +77 -10
  563. package/dist/lib/sonoff.d.ts.map +1 -1
  564. package/dist/lib/sonoff.js +165 -34
  565. package/dist/lib/sonoff.js.map +1 -1
  566. package/dist/lib/sunricher.d.ts +1 -1
  567. package/dist/lib/sunricher.d.ts.map +1 -1
  568. package/dist/lib/sunricher.js +6 -8
  569. package/dist/lib/sunricher.js.map +1 -1
  570. package/dist/lib/tuya.d.ts +558 -13
  571. package/dist/lib/tuya.d.ts.map +1 -1
  572. package/dist/lib/tuya.js +1518 -10
  573. package/dist/lib/tuya.js.map +1 -1
  574. package/dist/lib/types.d.ts +9 -6
  575. package/dist/lib/types.d.ts.map +1 -1
  576. package/dist/lib/ubisys.d.ts +1 -1
  577. package/dist/lib/ubisys.d.ts.map +1 -1
  578. package/dist/lib/ubisys.js +60 -5
  579. package/dist/lib/ubisys.js.map +1 -1
  580. package/dist/lib/utils.d.ts +5 -8
  581. package/dist/lib/utils.d.ts.map +1 -1
  582. package/dist/lib/utils.js +30 -17
  583. package/dist/lib/utils.js.map +1 -1
  584. package/dist/lib/zosung.d.ts +69 -6
  585. package/dist/lib/zosung.d.ts.map +1 -1
  586. package/dist/lib/zosung.js +113 -1
  587. package/dist/lib/zosung.js.map +1 -1
  588. package/dist/models-index.json +1 -1
  589. package/package.json +2 -2
  590. package/dist/devices/aubess.d.ts.map +0 -1
  591. package/dist/devices/aubess.js.map +0 -1
@@ -32,17 +32,10 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
35
  Object.defineProperty(exports, "__esModule", { value: true });
39
36
  exports.ias_sos_alarm_2 = exports.ias_carbon_monoxide_alarm_1_gas_alarm_2 = exports.ias_carbon_monoxide_alarm_1 = exports.ias_contact_alarm_1_report = exports.ias_contact_alarm_1 = exports.ias_smoke_alarm_1 = exports.ias_gas_alarm_2 = exports.ias_gas_alarm_1 = exports.ias_vibration_alarm_1_with_timeout = exports.ias_vibration_alarm_1 = exports.ias_water_leak_alarm_1_report = exports.ias_water_leak_alarm_1 = exports.ias_siren = exports.ias_no_alarm = exports.power_on_behavior = exports.on_off_skip_duplicate_transaction = exports.on_off_force_multiendpoint = exports.on_off = exports.gas_metering = exports.electrical_measurement = exports.metering = exports.meter_identification = exports.color_colortemp = exports.level_config = exports.brightness = exports.occupancy_timeout = exports.occupancy_with_timeout = exports.occupancy = exports.co2 = exports.pressure = exports.soil_moisture = exports.flow = exports.pm25 = exports.humidity = exports.device_temperature = exports.temperature = exports.battery = exports.linkquality_from_basic = exports.lock_user_status_response = exports.lock_pin_code_response = exports.lock_set_pin_code_response = exports.lock = exports.lock_programming_event_read_pincode = exports.lock_programming_event = exports.lock_operation_event = exports.hvac_user_interface = exports.thermostat_weekly_schedule = exports.thermostat = exports.fan_speed = exports.fan = void 0;
40
- exports.ias_smoke_alarm_1_develco = exports.namron_hvac_user_interface = exports.namron_thermostat = exports.power_source = exports.ias_wd = exports.ias_enroll = exports.checkin_presence = exports.lighting_ballast_configuration = exports.curtain_position_analog_output = exports.cover_state_via_onoff = exports.cover_position_via_brightness = exports.cover_position_tilt = exports.identify = exports.command_off_state = exports.command_on_state = exports.command_emergency = exports.command_move_to_hue = exports.command_move_to_saturation = exports.command_move_hue = exports.command_move_to_color = exports.command_move_to_color_temp = exports.command_color_loop_set = exports.command_step_saturation = exports.command_step_hue = exports.command_move_to_hue_and_saturation = exports.command_enhanced_move_to_hue_and_saturation = exports.command_step_color_temperature = exports.command_stop_move_step = exports.command_move_color_temperature = exports.command_stop = exports.command_step = exports.command_move = exports.command_move_to_level = exports.command_toggle = exports.command_off_with_effect = exports.command_off = exports.command_on = exports.command_cover_close = exports.command_cover_open = exports.command_cover_stop = exports.command_arm = exports.command_panic = exports.command_recall = exports.command_store = exports.ias_occupancy_alarm_1_with_timeout = exports.ias_occupancy_only_alarm_2 = exports.ias_alarm_only_alarm_1 = exports.ias_occupancy_alarm_2 = exports.ias_occupancy_alarm_1_report = exports.ias_occupancy_alarm_1 = void 0;
41
- exports.enocean_ptm216z = exports.enocean_ptm215ze = exports.enocean_ptm215z = exports.K4003C_binary_input = exports.diyruz_rspm = exports.diyruz_contact = exports.ewelink_action = exports.restorable_brightness = exports.tint404011_move_to_color_temp = exports.tint_scene = exports.orvibo_raw_2 = exports.orvibo_raw_1 = exports.danfoss_icon_hvac_user_interface = exports.danfoss_icon_regulator = exports.danfoss_icon_battery = exports.danfoss_icon_floor_sensor = exports.danfoss_thermostat_setpoint_scheduled = exports.danfoss_hvac_ui = exports.danfoss_thermostat = exports.meazon_meter = exports.heiman_ir_remote = exports.plaid_battery = exports.keypad20_battery = exports.keypad20states = exports.ptvo_switch_analog_input = exports.ptvo_switch_uart = exports.livolo_switch_state_raw = exports.easycodetouch_action = exports.easycode_action = exports.livolo_pir_state = exports.livolo_illuminance_state = exports.livolo_hygrometer_state = exports.livolo_cover_state = exports.livolo_dimmer_state = exports.livolo_curtain_switch_state = exports.livolo_new_switch_state_4gang = exports.livolo_new_switch_state_2gang = exports.livolo_new_switch_state = exports.livolo_socket_state = exports.livolo_switch_state = exports.tuya_switch_scene = exports.WSZ01_on_off_action = exports.tuya_cover_options = exports.tuya_cover_options_2 = exports.ts0216_siren = exports.ZigUP = exports.DTB190502A1 = exports.tuya_doorbell_button = exports.tuya_led_controller = exports.ts0201_temperature_humidity_alarm = void 0;
42
- exports.CCTSwitch_D0001_levelctrl = exports.hue_wall_switch_device_mode = exports.hue_motion_led_indication = exports.hue_motion_sensitivity = exports.DNCKAT_S00X_buttons = exports.KAMI_occupancy = exports.KAMI_contact = exports.CC2530ROUTER_meta = exports.CC2530ROUTER_led = exports.diyruz_zintercom_config = exports.diyruz_airsense_config_hum = exports.diyruz_airsense_config_pres = exports.diyruz_airsense_config_temp = exports.diyruz_airsense_config_co2 = exports.diyruz_geiger_config = exports.diyruz_geiger = exports.diyruz_freepad_config = exports.javis_lock_report = exports.heiman_scenes = exports.STS_PRS_251_presence = exports.PGC410EU_presence = exports.ZMCSW032D_cover_position = exports.SAGE206612_state = exports.almond_click = exports.color_stop_raw = exports.adeo_button_65024 = exports.scenes_recall_scene_65024 = exports.heiman_air_quality = exports.heiman_hcho = exports.U02I007C01_water_leak = exports.U02I007C01_contact = exports.keen_home_smart_vent_pressure = exports.qlwz_letv8key_switch = exports.konke_action = exports.ptvo_multistate_action = exports.command_status_change_notification_action = exports.W2_module_carbon_monoxide = exports.legrand_greenpower = exports.legrand_power_alarm = exports.legrand_scenes = exports.bticino_4027C_binary_input_moving = exports.legrand_binary_input_on_off = exports.legrand_binary_input_moving = exports.byun_gas_true = exports.byun_gas_false = exports.byun_smoke_true = exports.byun_smoke_false = exports.kmpcil_res005_on_off = exports.kmpcil_res005_occupancy = exports.diyruz_freepad_clicks = void 0;
43
- exports.ignore_command_off_with_effect = exports.ignore_command_off = exports.ignore_command_on = exports.ignore_genIdentify = exports.ignore_iasace_commandgetpanelstatus = exports.ignore_iaszone_report = exports.ignore_iaszone_statuschange = exports.ignore_iaszone_attreport = exports.ignore_thermostat_report = exports.ignore_closuresWindowCovering_report = exports.ignore_light_color_colortemp_report = exports.ignore_light_brightness_report = exports.ignore_power_report = exports.ignore_multistate_report = exports.ignore_analog_report = exports.ignore_pressure_report = exports.ignore_humidity_report = exports.ignore_temperature_report = exports.ignore_occupancy_report = exports.ignore_illuminance_report = exports.ignore_onoff_report = exports.awox_refresh = exports.awox_refreshColored = exports.awox_colors = exports.SNZB02_humidity = exports.SNZB02_temperature = exports.hw_version = exports.led_on_motion = exports.tuya_multi_action = exports.command_stop_move_raw = exports.sunricher_switch2801K4 = exports.sunricher_switch2801K2 = exports.tuya_operation_mode = exports.sihas_action = exports.sihas_people_cnt = exports.heiman_doorbell_button = exports.rc_110_level_to_scene = exports.wiser_smart_setpoint_command_client = exports.wiser_smart_thermostat_client = exports.schneider_temperature = exports.schneider_ui_action = exports.idlock_fw = exports.idlock = exports.ZB003X_occupancy = exports.ZB003X_attr = exports.itcmdr_clicks = exports.ias_keypad = exports.tuya_relay_din_led_indicator = exports.hue_tap = exports.CCTSwitch_D0001_lighting = void 0;
44
- exports.TS110E_switch_type = exports.TS110E_light_type = exports.TS110E = exports.wiser_smart_thermostat = exports.wiser_lighting_ballast_configuration = exports.schneider_lighting_ballast_configuration = exports.ZM35HQ_attr = exports.eurotronic_thermostat = exports.viessmann_thermostat = exports.stelpro_thermostat = exports.SP600_power = exports.ias_ace_occupancy_with_timeout = exports.command_on_presence = exports.EKO09738_metering = exports.metering_datek = exports.command_arm_with_transaction = exports.ignore_electrical_measurement = exports.ignore_metering = exports.ignore_tuya_raw = exports.ignore_tuya_set_time = exports.ignore_haDiagnostic = exports.ignore_genLevelCtrl_report = exports.ignore_command_stop = exports.ignore_command_step = void 0;
45
- const node_assert_1 = __importDefault(require("node:assert"));
37
+ exports.tint404011_move_to_color_temp = exports.tint_scene = exports.hw_version = exports.power_source = exports.ias_wd = exports.ias_enroll = exports.checkin_presence = exports.lighting_ballast_configuration = exports.curtain_position_analog_output = exports.cover_state_via_onoff = exports.cover_position_via_brightness = exports.cover_position_tilt = exports.identify = exports.command_off_state = exports.command_on_state = exports.command_emergency = exports.command_move_to_hue = exports.command_move_to_saturation = exports.command_move_hue = exports.command_move_to_color = exports.command_move_to_color_temp = exports.command_color_loop_set = exports.command_step_saturation = exports.command_step_hue = exports.command_move_to_hue_and_saturation = exports.command_enhanced_move_to_hue_and_saturation = exports.command_step_color_temperature = exports.command_stop_move_step = exports.command_move_color_temperature = exports.command_stop = exports.command_step = exports.command_move = exports.command_move_to_level = exports.command_toggle = exports.command_off_with_effect = exports.command_off = exports.command_on = exports.command_cover_close = exports.command_cover_open = exports.command_cover_stop = exports.command_arm = exports.command_panic = exports.command_recall = exports.command_store = exports.ias_occupancy_alarm_1_with_timeout = exports.ias_occupancy_only_alarm_2 = exports.ias_alarm_only_alarm_1 = exports.ias_occupancy_alarm_2 = exports.ias_occupancy_alarm_1_report = exports.ias_occupancy_alarm_1 = void 0;
38
+ exports.ias_ace_occupancy_with_timeout = exports.command_arm_with_transaction = exports.ignore_electrical_measurement = exports.ignore_metering = exports.ignore_tuya_raw = exports.ignore_tuya_set_time = exports.ignore_haDiagnostic = exports.ignore_genLevelCtrl_report = exports.ignore_command_stop = exports.ignore_command_step = exports.ignore_command_off_with_effect = exports.ignore_command_off = exports.ignore_command_on = exports.ignore_genIdentify = exports.ignore_iasace_commandgetpanelstatus = exports.ignore_iaszone_report = exports.ignore_iaszone_statuschange = exports.ignore_iaszone_attreport = exports.ignore_thermostat_report = exports.ignore_closuresWindowCovering_report = exports.ignore_light_color_colortemp_report = exports.ignore_light_brightness_report = exports.ignore_power_report = exports.ignore_multistate_report = exports.ignore_analog_report = exports.ignore_pressure_report = exports.ignore_humidity_report = exports.ignore_temperature_report = exports.ignore_occupancy_report = exports.ignore_illuminance_report = exports.ignore_onoff_report = exports.awox_refresh = exports.awox_refreshColored = exports.awox_colors = exports.SNZB02_humidity = exports.SNZB02_temperature = exports.sunricher_switch2801K4 = exports.sunricher_switch2801K2 = exports.U02I007C01_water_leak = exports.U02I007C01_contact = exports.command_status_change_notification_action = exports.ewelink_action = void 0;
46
39
  const libColor = __importStar(require("../lib/color"));
47
40
  const constants = __importStar(require("../lib/constants"));
48
41
  const exposes = __importStar(require("../lib/exposes"));
@@ -52,8 +45,6 @@ const utils = __importStar(require("../lib/utils"));
52
45
  const utils_1 = require("../lib/utils");
53
46
  const NS = "zhc:fz";
54
47
  const defaultSimulatedBrightness = 255;
55
- const e = exposes.presets;
56
- const ea = exposes.access;
57
48
  // #region Generic/recommended converters
58
49
  exports.fan = {
59
50
  cluster: "hvacFanCtrl",
@@ -123,8 +114,7 @@ exports.thermostat = {
123
114
  result[(0, utils_1.postfixWithEndpointName)("setpoint_change_amount", msg, model, meta)] = msg.data.setpointChangeAmount / 100;
124
115
  }
125
116
  if (msg.data.setpointChangeSource !== undefined) {
126
- result[(0, utils_1.postfixWithEndpointName)("setpoint_change_source", msg, model, meta)] =
127
- constants.thermostatSetpointChangeSource[msg.data.setpointChangeSource];
117
+ result[(0, utils_1.postfixWithEndpointName)("setpoint_change_source", msg, model, meta)] = utils.getFromLookup(msg.data.setpointChangeSource, constants.thermostatSetpointChangeSource);
128
118
  }
129
119
  if (msg.data.setpointChangeSourceTimeStamp !== undefined) {
130
120
  const date = new Date(2000, 0, 1);
@@ -141,21 +131,19 @@ exports.thermostat = {
141
131
  };
142
132
  }
143
133
  if (msg.data.ctrlSeqeOfOper !== undefined) {
144
- result[(0, utils_1.postfixWithEndpointName)("control_sequence_of_operation", msg, model, meta)] =
145
- constants.thermostatControlSequenceOfOperations[msg.data.ctrlSeqeOfOper];
134
+ result[(0, utils_1.postfixWithEndpointName)("control_sequence_of_operation", msg, model, meta)] = utils.getFromLookup(msg.data.ctrlSeqeOfOper, constants.thermostatControlSequenceOfOperations);
146
135
  }
147
136
  if (msg.data.programingOperMode !== undefined) {
148
- result[(0, utils_1.postfixWithEndpointName)("programming_operation_mode", msg, model, meta)] =
149
- constants.thermostatProgrammingOperationModes[msg.data.programingOperMode];
137
+ result[(0, utils_1.postfixWithEndpointName)("programming_operation_mode", msg, model, meta)] = utils.getFromLookup(msg.data.programingOperMode, constants.thermostatProgrammingOperationModes);
150
138
  }
151
139
  if (msg.data.systemMode !== undefined) {
152
- result[(0, utils_1.postfixWithEndpointName)("system_mode", msg, model, meta)] = constants.thermostatSystemModes[msg.data.systemMode];
140
+ result[(0, utils_1.postfixWithEndpointName)("system_mode", msg, model, meta)] = utils.getFromLookup(msg.data.systemMode, constants.thermostatSystemModes);
153
141
  }
154
142
  if (msg.data.runningMode !== undefined) {
155
- result[(0, utils_1.postfixWithEndpointName)("running_mode", msg, model, meta)] = constants.thermostatRunningMode[msg.data.runningMode];
143
+ result[(0, utils_1.postfixWithEndpointName)("running_mode", msg, model, meta)] = utils.getFromLookup(msg.data.runningMode, constants.thermostatRunningMode);
156
144
  }
157
145
  if (msg.data.runningState !== undefined) {
158
- result[(0, utils_1.postfixWithEndpointName)("running_state", msg, model, meta)] = constants.thermostatRunningStates[msg.data.runningState];
146
+ result[(0, utils_1.postfixWithEndpointName)("running_state", msg, model, meta)] = utils.getFromLookup(msg.data.runningState, constants.thermostatRunningStates);
159
147
  }
160
148
  if (msg.data.pIHeatingDemand !== undefined) {
161
149
  result[(0, utils_1.postfixWithEndpointName)("pi_heating_demand", msg, model, meta)] = (0, utils_1.mapNumberRange)(msg.data.pIHeatingDemand, 0, dontMapPIHeatingDemand ? 100 : 255, 0, 100);
@@ -213,8 +201,7 @@ exports.thermostat = {
213
201
  }
214
202
  }
215
203
  if (msg.data.acLouverPosition !== undefined) {
216
- result[(0, utils_1.postfixWithEndpointName)("ac_louver_position", msg, model, meta)] =
217
- constants.thermostatAcLouverPositions[msg.data.acLouverPosition];
204
+ result[(0, utils_1.postfixWithEndpointName)("ac_louver_position", msg, model, meta)] = utils.getFromLookup(msg.data.acLouverPosition, constants.thermostatAcLouverPositions);
218
205
  }
219
206
  return result;
220
207
  },
@@ -226,7 +213,7 @@ exports.thermostat_weekly_schedule = {
226
213
  const days = [];
227
214
  for (let i = 0; i < 8; i++) {
228
215
  if ((msg.data.dayofweek & (1 << i)) > 0) {
229
- days.push(constants.thermostatDayOfWeek[i]);
216
+ days.push(utils.getFromLookup(i, constants.thermostatDayOfWeek));
230
217
  }
231
218
  }
232
219
  const transitions = [];
@@ -388,7 +375,7 @@ exports.lock_pin_code_response = {
388
375
  const result = { users: {} };
389
376
  result.users[userId] = { status: status };
390
377
  if (options?.expose_pin && data.pincodevalue) {
391
- result.users[userId].pin_code = data.pincodevalue;
378
+ result.users[userId].pin_code = data.pincodevalue.toString();
392
379
  }
393
380
  return result;
394
381
  },
@@ -613,23 +600,25 @@ exports.level_config = {
613
600
  result[level_config] = {};
614
601
  // onOffTransitionTime - range 0x0000 to 0xffff - optional
615
602
  if (msg.data.onOffTransitionTime !== undefined && msg.data.onOffTransitionTime !== undefined) {
616
- result[level_config].on_off_transition_time = Number(msg.data.onOffTransitionTime);
603
+ result[level_config].on_off_transition_time = Number(msg.data.onOffTransitionTime) / 10;
617
604
  }
618
605
  // onTransitionTime - range 0x0000 to 0xffff - optional
619
606
  // 0xffff = use onOffTransitionTime
620
607
  if (msg.data.onTransitionTime !== undefined && msg.data.onTransitionTime !== undefined) {
621
- result[level_config].on_transition_time = Number(msg.data.onTransitionTime);
622
- if (result[level_config].on_transition_time === 65535) {
608
+ if (Number(msg.data.onTransitionTime) === 65535) {
623
609
  result[level_config].on_transition_time = "disabled";
624
610
  }
611
+ else
612
+ result[level_config].on_transition_time = Number(msg.data.onTransitionTime) / 10;
625
613
  }
626
614
  // offTransitionTime - range 0x0000 to 0xffff - optional
627
615
  // 0xffff = use onOffTransitionTime
628
616
  if (msg.data.offTransitionTime !== undefined && msg.data.offTransitionTime !== undefined) {
629
- result[level_config].off_transition_time = Number(msg.data.offTransitionTime);
630
- if (result[level_config].off_transition_time === 65535) {
617
+ if (Number(msg.data.offTransitionTime) === 65535) {
631
618
  result[level_config].off_transition_time = "disabled";
632
619
  }
620
+ else
621
+ result[level_config].off_transition_time = Number(msg.data.offTransitionTime) / 10;
633
622
  }
634
623
  // startUpCurrentLevel - range 0x00 to 0xff - optional
635
624
  // 0x00 = return to minimum supported level
@@ -1514,6 +1503,7 @@ exports.command_step_color_temperature = {
1514
1503
  const payload = {
1515
1504
  action: (0, utils_1.postfixWithEndpointName)(`color_temperature_step_${direction}`, msg, model, meta),
1516
1505
  action_step_size: msg.data.stepsize,
1506
+ action_color_temperature_delta: direction === "up" ? msg.data.stepsize : -1 * msg.data.stepsize,
1517
1507
  };
1518
1508
  if (msg.data.transtime !== undefined) {
1519
1509
  payload.action_transition_time = msg.data.transtime / 100;
@@ -1930,2774 +1920,239 @@ exports.power_source = {
1930
1920
  return payload;
1931
1921
  },
1932
1922
  };
1933
- // #endregion
1934
- // #region Non-generic converters
1935
- exports.namron_thermostat = {
1936
- cluster: "hvacThermostat",
1937
- type: ["attributeReport", "readResponse"],
1938
- convert: (model, msg, publish, options, meta) => {
1939
- const result = {};
1940
- const data = msg.data;
1941
- if (data[0x1000] !== undefined) {
1942
- // Display brightness
1943
- const lookup = { 0: "low", 1: "mid", 2: "high" };
1944
- result.lcd_brightness = lookup[data[0x1000]];
1945
- }
1946
- if (data[0x1001] !== undefined) {
1947
- // Button vibration level
1948
- const lookup = { 0: "off", 1: "low", 2: "high" };
1949
- result.button_vibration_level = lookup[data[0x1001]];
1950
- }
1951
- if (data[0x1002] !== undefined) {
1952
- // Floor sensor type
1953
- const lookup = { 1: "10k", 2: "15k", 3: "50k", 4: "100k", 5: "12k" };
1954
- result.floor_sensor_type = lookup[data[0x1002]];
1955
- }
1956
- if (data[0x1003] !== undefined) {
1957
- // Sensor
1958
- const lookup = { 0: "air", 1: "floor", 2: "both" };
1959
- result.sensor = lookup[data[0x1003]];
1960
- }
1961
- if (data[0x1004] !== undefined) {
1962
- // PowerUpStatus
1963
- const lookup = { 0: "default", 1: "last_status" };
1964
- result.powerup_status = lookup[data[0x1004]];
1965
- }
1966
- if (data[0x1005] !== undefined) {
1967
- // FloorSensorCalibration
1968
- result.floor_sensor_calibration = (0, utils_1.precisionRound)(data[0x1005], 2) / 10;
1969
- }
1970
- if (data[0x1006] !== undefined) {
1971
- // DryTime
1972
- result.dry_time = data[0x1006];
1973
- }
1974
- if (data[0x1007] !== undefined) {
1975
- // ModeAfterDry
1976
- const lookup = { 0: "off", 1: "manual", 2: "auto", 3: "away" };
1977
- result.mode_after_dry = lookup[data[0x1007]];
1978
- }
1979
- if (data[0x1008] !== undefined) {
1980
- // TemperatureDisplay
1981
- const lookup = { 0: "room", 1: "floor" };
1982
- result.temperature_display = lookup[data[0x1008]];
1983
- }
1984
- if (data[0x1009] !== undefined) {
1985
- // WindowOpenCheck
1986
- result.window_open_check = data[0x1009] / 2;
1987
- }
1988
- if (data[0x100a] !== undefined) {
1989
- // Hysterersis
1990
- result.hysterersis = (0, utils_1.precisionRound)(data[0x100a], 2) / 10;
1991
- }
1992
- if (data[0x100b] !== undefined) {
1993
- // DisplayAutoOffEnable
1994
- result.display_auto_off_enabled = data[0x100b] ? "enabled" : "disabled";
1995
- }
1996
- if (data[0x2001] !== undefined) {
1997
- // AlarmAirTempOverValue
1998
- result.alarm_airtemp_overvalue = data[0x2001];
1999
- }
2000
- if (data[0x2002] !== undefined) {
2001
- // Away Mode Set
2002
- result.away_mode = data[0x2002] ? "ON" : "OFF";
2003
- }
2004
- return result;
2005
- },
2006
- };
2007
- exports.namron_hvac_user_interface = {
2008
- cluster: "hvacUserInterfaceCfg",
1923
+ exports.hw_version = {
1924
+ cluster: "genBasic",
2009
1925
  type: ["attributeReport", "readResponse"],
2010
1926
  convert: (model, msg, publish, options, meta) => {
2011
1927
  const result = {};
2012
- if (msg.data.keypadLockout !== undefined) {
2013
- // Set as child lock instead as keypadlockout
2014
- result.child_lock = msg.data.keypadLockout === 0 ? "UNLOCK" : "LOCK";
2015
- }
1928
+ if (msg.data.hwVersion !== undefined)
1929
+ result.hw_version = msg.data.hwVersion;
2016
1930
  return result;
2017
1931
  },
2018
1932
  };
2019
- exports.ias_smoke_alarm_1_develco = {
2020
- cluster: "ssIasZone",
2021
- type: "commandStatusChangeNotification",
1933
+ // #endregion
1934
+ // #region Non-generic converters
1935
+ exports.tint_scene = {
1936
+ cluster: "genBasic",
1937
+ type: "write",
2022
1938
  convert: (model, msg, publish, options, meta) => {
2023
- const zoneStatus = msg.data.zonestatus;
2024
- return {
2025
- smoke: (zoneStatus & 1) > 0,
2026
- battery_low: (zoneStatus & (1 << 3)) > 0,
2027
- supervision_reports: (zoneStatus & (1 << 4)) > 0,
2028
- restore_reports: (zoneStatus & (1 << 5)) > 0,
2029
- test: (zoneStatus & (1 << 8)) > 0,
2030
- };
1939
+ const payload = { action: `scene_${msg.data["16389"]}` };
1940
+ (0, utils_1.addActionGroup)(payload, msg, model);
1941
+ return payload;
2031
1942
  },
2032
1943
  };
2033
- exports.ts0201_temperature_humidity_alarm = {
2034
- cluster: "manuSpecificTuya2",
2035
- type: ["attributeReport", "readResponse"],
1944
+ exports.tint404011_move_to_color_temp = {
1945
+ cluster: "lightingColorCtrl",
1946
+ type: "commandMoveToColorTemp",
2036
1947
  convert: (model, msg, publish, options, meta) => {
2037
- const result = {};
2038
- if (msg.data.alarm_temperature_max !== undefined) {
2039
- result.alarm_temperature_max = msg.data.alarm_temperature_max;
2040
- }
2041
- if (msg.data.alarm_temperature_min !== undefined) {
2042
- result.alarm_temperature_min = msg.data.alarm_temperature_min;
1948
+ // The remote has an internal state so store the last action in order to
1949
+ // determine the direction of the color temperature change.
1950
+ if (!globalStore.hasValue(msg.endpoint, "last_color_temp")) {
1951
+ globalStore.putValue(msg.endpoint, "last_color_temp", msg.data.colortemp);
2043
1952
  }
2044
- if (msg.data.alarm_humidity_max !== undefined) {
2045
- result.alarm_humidity_max = msg.data.alarm_humidity_max;
1953
+ const lastTemp = globalStore.getValue(msg.endpoint, "last_color_temp");
1954
+ globalStore.putValue(msg.endpoint, "last_color_temp", msg.data.colortemp);
1955
+ let direction = "down";
1956
+ if (lastTemp > msg.data.colortemp) {
1957
+ direction = "up";
2046
1958
  }
2047
- if (msg.data.alarm_humidity_min !== undefined) {
2048
- result.alarm_humidity_min = msg.data.alarm_humidity_min;
1959
+ else if (lastTemp < msg.data.colortemp) {
1960
+ direction = "down";
2049
1961
  }
2050
- if (msg.data.alarm_humidity !== undefined) {
2051
- const sensorAlarmLookup = { "0": "below_min_humdity", "1": "over_humidity", "2": "off" };
2052
- result.alarm_humidity = sensorAlarmLookup[msg.data.alarm_humidity];
1962
+ else if (msg.data.colortemp === 370 || msg.data.colortemp === 555) {
1963
+ // The remote goes up to 370 in steps and emits 555 on down button hold.
1964
+ direction = "down";
2053
1965
  }
2054
- if (msg.data.alarm_temperature !== undefined) {
2055
- const sensorAlarmLookup = { "0": "below_min_temperature", "1": "over_temperature", "2": "off" };
2056
- result.alarm_temperature = sensorAlarmLookup[msg.data.alarm_temperature];
1966
+ else if (msg.data.colortemp === 153) {
1967
+ direction = "up";
2057
1968
  }
2058
- return result;
1969
+ const payload = {
1970
+ action: (0, utils_1.postfixWithEndpointName)("color_temperature_move", msg, model, meta),
1971
+ action_color_temperature: msg.data.colortemp,
1972
+ action_transition_time: msg.data.transtime,
1973
+ action_color_temperature_direction: direction,
1974
+ };
1975
+ (0, utils_1.addActionGroup)(payload, msg, model);
1976
+ return payload;
2059
1977
  },
2060
1978
  };
2061
- exports.tuya_led_controller = {
2062
- cluster: "lightingColorCtrl",
2063
- type: ["attributeReport", "readResponse"],
2064
- options: [exposes.options.color_sync()],
1979
+ exports.ewelink_action = {
1980
+ cluster: "genOnOff",
1981
+ type: ["commandOn", "commandOff", "commandToggle"],
2065
1982
  convert: (model, msg, publish, options, meta) => {
2066
- const result = {};
2067
- if (msg.data.colorTemperature !== undefined) {
2068
- const value = Number(msg.data.colorTemperature);
2069
- const color_temp = (0, utils_1.postfixWithEndpointName)("color_temp", msg, model, meta);
2070
- result[color_temp] = value;
2071
- }
2072
- if (msg.data.tuyaBrightness !== undefined) {
2073
- const brightness = (0, utils_1.postfixWithEndpointName)("brightness", msg, model, meta);
2074
- result[brightness] = msg.data.tuyaBrightness;
2075
- }
2076
- if (msg.data.tuyaRgbMode !== undefined) {
2077
- const color_mode = (0, utils_1.postfixWithEndpointName)("color_mode", msg, model, meta);
2078
- if (msg.data.tuyaRgbMode === 1) {
2079
- result[color_mode] = constants.colorModeLookup[0];
2080
- }
2081
- else {
2082
- result[color_mode] = constants.colorModeLookup[2];
2083
- }
2084
- }
2085
- const color = (0, utils_1.postfixWithEndpointName)("color", msg, model, meta);
2086
- result[color] = {};
2087
- if (msg.data.currentHue !== undefined) {
2088
- result[color].hue = (0, utils_1.mapNumberRange)(msg.data.currentHue, 0, 254, 0, 360);
2089
- result[color].h = result[color].hue;
2090
- }
2091
- if (msg.data.currentSaturation !== undefined) {
2092
- result[color].saturation = (0, utils_1.mapNumberRange)(msg.data.currentSaturation, 0, 254, 0, 100);
2093
- result[color].s = result[color].saturation;
2094
- }
2095
- // Use postfixWithEndpointName with an empty value to get just the postfix that
2096
- // can be added to the result keys.
2097
- const epPostfix = (0, utils_1.postfixWithEndpointName)("", msg, model, meta);
2098
- return Object.assign(result, libColor.syncColorState(result, meta.state, msg.endpoint, options, epPostfix));
1983
+ const lookup = { commandToggle: "single", commandOn: "double", commandOff: "long" };
1984
+ return { action: lookup[msg.type] };
2099
1985
  },
2100
1986
  };
2101
- exports.tuya_doorbell_button = {
1987
+ // export const _8840100H_water_leak_alarm: Fz.Converter = {
1988
+ // cluster: "haApplianceEventsAlerts",
1989
+ // type: "commandAlertsNotification",
1990
+ // convert: (model, msg, publish, options, meta) => {
1991
+ // const alertStatus = msg.data.aalert;
1992
+ // return {
1993
+ // water_leak: (alertStatus & (1 << 12)) > 0,
1994
+ // };
1995
+ // },
1996
+ // };
1997
+ exports.command_status_change_notification_action = {
2102
1998
  cluster: "ssIasZone",
2103
1999
  type: "commandStatusChangeNotification",
2104
2000
  convert: (model, msg, publish, options, meta) => {
2105
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model))
2106
- return;
2107
- const lookup = { 1: "pressed" };
2108
- const zoneStatus = msg.data.zonestatus;
2109
- return {
2110
- action: lookup[zoneStatus & 1],
2111
- tamper: (zoneStatus & (1 << 2)) > 0,
2112
- battery_low: (zoneStatus & (1 << 3)) > 0,
2113
- };
2001
+ const lookup = { 0: "off", 1: "single", 2: "double", 3: "hold" };
2002
+ return { action: lookup[msg.data.zonestatus] };
2114
2003
  },
2115
2004
  };
2116
- exports.DTB190502A1 = {
2117
- cluster: "genOnOff",
2118
- type: ["attributeReport", "readResponse"],
2005
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2006
+ exports.U02I007C01_contact = {
2007
+ cluster: "ssIasZone",
2008
+ type: "commandStatusChangeNotification",
2119
2009
  convert: (model, msg, publish, options, meta) => {
2120
- const lookupKEY = {
2121
- "0": "KEY_SYS",
2122
- "1": "KEY_UP",
2123
- "2": "KEY_DOWN",
2124
- "3": "KEY_NONE",
2125
- };
2126
- const lookupLED = { "0": "OFF", "1": "ON" };
2010
+ const zoneStatus = msg.data.zonestatus;
2011
+ if (msg.endpoint.ID !== 1)
2012
+ return;
2127
2013
  return {
2128
- cpu_temperature: (0, utils_1.precisionRound)(msg.data["41361"], 2),
2129
- key_state: lookupKEY[msg.data["41362"]],
2130
- led_state: lookupLED[msg.data["41363"]],
2014
+ contact: !((zoneStatus & 1) > 0),
2131
2015
  };
2132
2016
  },
2133
2017
  };
2134
- exports.ZigUP = {
2135
- cluster: "genOnOff",
2136
- type: ["attributeReport", "readResponse"],
2018
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2019
+ exports.U02I007C01_water_leak = {
2020
+ cluster: "ssIasZone",
2021
+ type: "commandStatusChangeNotification",
2137
2022
  convert: (model, msg, publish, options, meta) => {
2138
- const lookup = {
2139
- "0": "timer",
2140
- "1": "key",
2141
- "2": "dig-in",
2142
- };
2143
- let ds18b20Id = null;
2144
- let ds18b20Value = null;
2145
- if (msg.data["41368"]) {
2146
- ds18b20Id = msg.data["41368"].split(":")[0];
2147
- ds18b20Value = (0, utils_1.precisionRound)(Number.parseFloat(msg.data["41368"].split(":")[1]), 2);
2148
- }
2023
+ const zoneStatus = msg.data.zonestatus;
2024
+ if (msg.endpoint.ID !== 2)
2025
+ return;
2149
2026
  return {
2150
- state: msg.data.onOff === 1 ? "ON" : "OFF",
2151
- cpu_temperature: (0, utils_1.precisionRound)(msg.data["41361"], 2),
2152
- external_temperature: (0, utils_1.precisionRound)(msg.data["41362"], 1),
2153
- external_humidity: (0, utils_1.precisionRound)(msg.data["41363"], 1),
2154
- s0_counts: msg.data["41364"],
2155
- adc_volt: (0, utils_1.precisionRound)(msg.data["41365"], 3),
2156
- dig_input: msg.data["41366"],
2157
- reason: lookup[msg.data["41367"]],
2158
- [`${ds18b20Id}`]: ds18b20Value,
2027
+ water_leak: (zoneStatus & 1) > 0,
2159
2028
  };
2160
2029
  },
2161
2030
  };
2162
- exports.ts0216_siren = {
2163
- cluster: "ssIasWd",
2164
- type: ["attributeReport", "readResponse"],
2031
+ const SUNRICHER_SWITCH2801K2_LOOKUP = {
2032
+ 33: "press_on",
2033
+ 32: "press_off",
2034
+ 52: "release",
2035
+ 53: "hold_on",
2036
+ 54: "hold_off",
2037
+ };
2038
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2039
+ exports.sunricher_switch2801K2 = {
2040
+ cluster: "greenPower",
2041
+ type: ["commandNotification", "commandCommissioningNotification"],
2165
2042
  convert: (model, msg, publish, options, meta) => {
2166
- const result = {};
2167
- if (msg.data.maxDuration !== undefined)
2168
- result.duration = msg.data.maxDuration;
2169
- if (msg.data["2"] !== undefined) {
2170
- result.volume = (0, utils_1.mapNumberRange)(msg.data["2"], 100, 10, 0, 100);
2171
- }
2172
- if (["_TYZB01_sbpc1zrb"].includes(meta.device.manufacturerName) && typeof msg.data["2"] === "number") {
2173
- const volData = msg.data["2"];
2174
- result.volume = volData === 0 ? 0 : (0, utils_1.mapNumberRange)(volData, 100, 33, 1, 100);
2043
+ const commandID = msg.data.commandID;
2044
+ if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model, msg.data.frameCounter, `${msg.device.ieeeAddr}_${commandID}`))
2045
+ return;
2046
+ if (commandID >= 0xe0)
2047
+ return; // Skip op commands
2048
+ if (SUNRICHER_SWITCH2801K2_LOOKUP[commandID] === undefined) {
2049
+ logger_1.logger.error(`Sunricher: missing command '${commandID}'`, NS);
2175
2050
  }
2176
- if (msg.data["61440"] !== undefined) {
2177
- result.alarm = msg.data["61440"] !== 0;
2051
+ else {
2052
+ return { action: SUNRICHER_SWITCH2801K2_LOOKUP[commandID] };
2178
2053
  }
2179
- return result;
2180
2054
  },
2181
2055
  };
2182
- exports.tuya_cover_options_2 = {
2183
- cluster: "closuresWindowCovering",
2184
- type: ["attributeReport", "readResponse"],
2056
+ const SUNRICHER_SWITCH2801K4_LOOKUP = {
2057
+ 33: "press_on",
2058
+ 32: "press_off",
2059
+ 55: "press_high",
2060
+ 56: "press_low",
2061
+ 53: "hold_high",
2062
+ 54: "hold_low",
2063
+ 52: "release",
2064
+ };
2065
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2066
+ exports.sunricher_switch2801K4 = {
2067
+ cluster: "greenPower",
2068
+ type: ["commandNotification", "commandCommissioningNotification"],
2185
2069
  convert: (model, msg, publish, options, meta) => {
2186
- const result = {};
2187
- if (msg.data.moesCalibrationTime !== undefined) {
2188
- const value = msg.data.moesCalibrationTime / 100;
2189
- result[(0, utils_1.postfixWithEndpointName)("calibration_time", msg, model, meta)] = value;
2070
+ const commandID = msg.data.commandID;
2071
+ if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model, msg.data.frameCounter, `${msg.device.ieeeAddr}_${commandID}`))
2072
+ return;
2073
+ if (commandID >= 0xe0)
2074
+ return; // Skip op commands
2075
+ if (SUNRICHER_SWITCH2801K4_LOOKUP[commandID] === undefined) {
2076
+ logger_1.logger.error(`Sunricher: missing command '${commandID}'`, NS);
2190
2077
  }
2191
- if (msg.data.tuyaMotorReversal !== undefined) {
2192
- const value = msg.data.tuyaMotorReversal;
2193
- const reversalLookup = { 0: "OFF", 1: "ON" };
2194
- result[(0, utils_1.postfixWithEndpointName)("motor_reversal", msg, model, meta)] = reversalLookup[value];
2078
+ else {
2079
+ return { action: SUNRICHER_SWITCH2801K4_LOOKUP[commandID] };
2195
2080
  }
2196
- return result;
2197
2081
  },
2198
2082
  };
2199
- exports.tuya_cover_options = {
2200
- cluster: "closuresWindowCovering",
2083
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2084
+ exports.SNZB02_temperature = {
2085
+ cluster: "msTemperatureMeasurement",
2201
2086
  type: ["attributeReport", "readResponse"],
2202
2087
  convert: (model, msg, publish, options, meta) => {
2203
- const result = {};
2204
- if (msg.data.tuyaMovingState !== undefined) {
2205
- const value = msg.data.tuyaMovingState;
2206
- const movingLookup = { 0: "UP", 1: "STOP", 2: "DOWN" };
2207
- result[(0, utils_1.postfixWithEndpointName)("moving", msg, model, meta)] = movingLookup[value];
2208
- }
2209
- if (msg.data.tuyaCalibration !== undefined) {
2210
- const value = msg.data.tuyaCalibration;
2211
- const calibrationLookup = { 0: "ON", 1: "OFF" };
2212
- result[(0, utils_1.postfixWithEndpointName)("calibration", msg, model, meta)] = calibrationLookup[value];
2213
- }
2214
- if (msg.data.tuyaMotorReversal !== undefined) {
2215
- const value = msg.data.tuyaMotorReversal;
2216
- const reversalLookup = { 0: "OFF", 1: "ON" };
2217
- result[(0, utils_1.postfixWithEndpointName)("motor_reversal", msg, model, meta)] = reversalLookup[value];
2218
- }
2219
- if (msg.data.moesCalibrationTime !== undefined) {
2220
- const value = msg.data.moesCalibrationTime / 10.0;
2221
- if (["_TZ3000_cet6ch1r", "_TZ3000_5iixzdo7"].includes(meta.device.manufacturerName)) {
2222
- const endpoint = msg.endpoint.ID;
2223
- const calibrationLookup = { 1: "to_open", 2: "to_close" };
2224
- result[(0, utils_1.postfixWithEndpointName)(`calibration_time_${calibrationLookup[endpoint]}`, msg, model, meta)] = value;
2225
- }
2226
- else {
2227
- result[(0, utils_1.postfixWithEndpointName)("calibration_time", msg, model, meta)] = value;
2228
- }
2088
+ const temperature = msg.data.measuredValue / 100.0;
2089
+ // https://github.com/Koenkk/zigbee2mqtt/issues/13640
2090
+ // SNZB-02 reports stranges values sometimes
2091
+ if (temperature > -33 && temperature < 100) {
2092
+ const property = (0, utils_1.postfixWithEndpointName)("temperature", msg, model, meta);
2093
+ return { [property]: temperature };
2229
2094
  }
2230
- return result;
2231
2095
  },
2232
2096
  };
2233
2097
  // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2234
- exports.WSZ01_on_off_action = {
2235
- cluster: 65029,
2236
- type: "attributeReport",
2237
- convert: (model, msg, publish, options, meta) => {
2238
- const clickMapping = { 0: "release", 1: "single", 2: "double", 3: "hold" };
2239
- return { action: `${clickMapping[msg.data["1"]]}` };
2240
- },
2241
- };
2242
- exports.tuya_switch_scene = {
2243
- cluster: "genOnOff",
2244
- type: "commandTuyaAction",
2245
- convert: (model, msg, publish, options, meta) => {
2246
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model))
2247
- return;
2248
- // Since it is a non standard ZCL command, no default response is send from zigbee-herdsman
2249
- // Send the defaultResponse here, otherwise the second button click delays.
2250
- // https://github.com/Koenkk/zigbee2mqtt/issues/8149
2251
- return { action: "switch_scene", action_scene: msg.data.value };
2252
- },
2253
- };
2254
- exports.livolo_switch_state = {
2255
- cluster: "genOnOff",
2098
+ exports.SNZB02_humidity = {
2099
+ cluster: "msRelativeHumidity",
2256
2100
  type: ["attributeReport", "readResponse"],
2257
2101
  convert: (model, msg, publish, options, meta) => {
2258
- const status = msg.data.onOff;
2259
- return {
2260
- state_left: status & 1 ? "ON" : "OFF",
2261
- state_right: status & 2 ? "ON" : "OFF",
2262
- };
2263
- },
2264
- };
2265
- exports.livolo_socket_state = {
2266
- cluster: "genPowerCfg",
2267
- type: ["raw"],
2268
- convert: (model, msg, publish, options, meta) => {
2269
- const stateHeader = Buffer.from([122, 209]);
2270
- if (msg.data.indexOf(stateHeader) === 0) {
2271
- const status = msg.data[14];
2272
- return { state: status & 1 ? "ON" : "OFF" };
2102
+ const humidity = msg.data.measuredValue / 100.0;
2103
+ // https://github.com/Koenkk/zigbee2mqtt/issues/13640
2104
+ // SNZB-02 reports stranges values sometimes
2105
+ if (humidity >= 0 && humidity <= 99.75) {
2106
+ return { humidity };
2273
2107
  }
2274
2108
  },
2275
2109
  };
2276
- exports.livolo_new_switch_state = {
2277
- cluster: "genPowerCfg",
2110
+ exports.awox_colors = {
2111
+ cluster: "lightingColorCtrl",
2278
2112
  type: ["raw"],
2279
2113
  convert: (model, msg, publish, options, meta) => {
2280
- const stateHeader = Buffer.from([122, 209]);
2281
- if (msg.data.indexOf(stateHeader) === 0) {
2282
- const status = msg.data[14];
2283
- return { state: status & 1 ? "ON" : "OFF" };
2114
+ const buffer = msg.data;
2115
+ const commonForColors = buffer[0] === 17 && buffer[2] === 48 && buffer[3] === 0 && buffer[5] === 8 && buffer[6] === 0;
2116
+ let color = null;
2117
+ if (commonForColors && [255, 254].includes(buffer[4])) {
2118
+ color = "red";
2284
2119
  }
2285
- },
2286
- };
2287
- exports.livolo_new_switch_state_2gang = {
2288
- cluster: "genPowerCfg",
2289
- type: ["raw"],
2290
- convert: (model, msg, publish, options, meta) => {
2291
- const stateHeader = Buffer.from([122, 209]);
2292
- if (msg.data.indexOf(stateHeader) === 0) {
2293
- if (msg.data[10] === 7) {
2294
- const status = msg.data[14];
2295
- return {
2296
- state_left: status & 1 ? "ON" : "OFF",
2297
- state_right: status & 2 ? "ON" : "OFF",
2298
- };
2299
- }
2120
+ else if (commonForColors && [42, 41].includes(buffer[4])) {
2121
+ color = "yellow";
2300
2122
  }
2301
- },
2302
- };
2303
- exports.livolo_new_switch_state_4gang = {
2304
- cluster: "genPowerCfg",
2305
- type: ["raw"],
2306
- convert: (model, msg, publish, options, meta) => {
2307
- const stateHeader = Buffer.from([122, 209]);
2308
- if (msg.data.indexOf(stateHeader) === 0) {
2309
- if (msg.data[10] === 7) {
2310
- const status = msg.data[14];
2311
- return {
2312
- state_left: status & 1 ? "ON" : "OFF",
2313
- state_right: status & 2 ? "ON" : "OFF",
2314
- state_bottom_left: status & 4 ? "ON" : "OFF",
2315
- state_bottom_right: status & 8 ? "ON" : "OFF",
2316
- };
2317
- }
2318
- if (msg.data[10] === 13) {
2319
- const status = msg.data[13];
2320
- return {
2321
- state_left: status & 1 ? "ON" : "OFF",
2322
- state_right: status & 2 ? "ON" : "OFF",
2323
- state_bottom_left: status & 4 ? "ON" : "OFF",
2324
- state_bottom_right: status & 8 ? "ON" : "OFF",
2325
- };
2326
- }
2123
+ else if (commonForColors && [85, 84].includes(buffer[4])) {
2124
+ color = "green";
2125
+ }
2126
+ else if (commonForColors && [170, 169].includes(buffer[4])) {
2127
+ color = "blue";
2128
+ }
2129
+ if (color != null) {
2130
+ return { action: color, action_group: msg.groupID };
2327
2131
  }
2328
2132
  },
2329
2133
  };
2330
- exports.livolo_curtain_switch_state = {
2331
- cluster: "genPowerCfg",
2332
- type: ["raw"],
2134
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2135
+ exports.awox_refreshColored = {
2136
+ cluster: "lightingColorCtrl",
2137
+ type: ["commandMoveHue"],
2333
2138
  convert: (model, msg, publish, options, meta) => {
2334
- const stateHeader = Buffer.from([122, 209]);
2335
- if (msg.data.indexOf(stateHeader) === 0) {
2336
- if (msg.data[10] === 5 || msg.data[10] === 2) {
2337
- const status = msg.data[14];
2338
- return {
2339
- state_left: status === 1 ? "ON" : "OFF",
2340
- state_right: status === 0 ? "ON" : "OFF",
2341
- };
2342
- }
2139
+ if (msg.data.movemode === 1 && msg.data.rate === 12) {
2140
+ return { action: "refresh_colored", action_group: msg.groupID };
2343
2141
  }
2344
2142
  },
2345
2143
  };
2346
- exports.livolo_dimmer_state = {
2347
- cluster: "genPowerCfg",
2144
+ exports.awox_refresh = {
2145
+ cluster: "genLevelCtrl",
2348
2146
  type: ["raw"],
2349
2147
  convert: (model, msg, publish, options, meta) => {
2350
- const stateHeader = Buffer.from([122, 209]);
2351
- if (msg.data.indexOf(stateHeader) === 0) {
2352
- if (msg.data[10] === 7) {
2353
- const status = msg.data[14];
2354
- return { state: status & 1 ? "ON" : "OFF" };
2355
- }
2356
- if (msg.data[10] === 13) {
2357
- const status = msg.data[13];
2358
- return { state: status & 1 ? "ON" : "OFF" };
2359
- }
2360
- if (msg.data[10] === 5) {
2361
- // TODO: Unknown dp, assumed value type
2362
- const value = msg.data[14] * 10;
2363
- return {
2364
- brightness: (0, utils_1.mapNumberRange)(value, 0, 1000, 0, 255),
2365
- brightness_percent: (0, utils_1.mapNumberRange)(value, 0, 1000, 0, 100),
2366
- level: value,
2367
- };
2368
- }
2369
- }
2370
- },
2371
- };
2372
- exports.livolo_cover_state = {
2373
- cluster: "genPowerCfg",
2374
- type: ["raw"],
2375
- convert: (model, msg, publish, options, meta) => {
2376
- const dp = msg.data[10];
2377
- const defaults = { motor_direction: "FORWARD", motor_speed: 40 };
2378
- if (msg.data[0] === 0x7a && msg.data[1] === 0xd1) {
2379
- const reportType = msg.data[12];
2380
- switch (dp) {
2381
- case 0x0c:
2382
- case 0x0f:
2383
- if (reportType === 0x04) {
2384
- // Position report
2385
- const position = 100 - msg.data[13];
2386
- const state = position > 0 ? "OPEN" : "CLOSE";
2387
- const moving = dp === 0x0f;
2388
- return { ...defaults, ...meta.state, position, state, moving };
2389
- }
2390
- if (reportType === 0x12) {
2391
- // Speed report
2392
- const motorSpeed = msg.data[13];
2393
- return { ...defaults, ...meta.state, motor_speed: motorSpeed };
2394
- }
2395
- if (reportType === 0x13) {
2396
- // Direction report
2397
- const direction = msg.data[13];
2398
- if (direction < 0x80) {
2399
- return { ...defaults, ...meta.state, motor_direction: "FORWARD" };
2400
- }
2401
- return { ...defaults, ...meta.state, motor_direction: "REVERSE" };
2402
- }
2403
- break;
2404
- case 0x02:
2405
- case 0x03:
2406
- // Ignore special commands used only when pairing, as these will rather be handled by `onEvent`
2407
- return null;
2408
- case 0x08:
2409
- // Ignore general command acknowledgements, as they provide no useful information.
2410
- return null;
2411
- default:
2412
- // Unknown dps
2413
- logger_1.logger.debug(`Unhandled DP ${dp} for ${meta.device.manufacturerName}: ${msg.data.toString("hex")}`, NS);
2414
- }
2415
- }
2416
- },
2417
- };
2418
- exports.livolo_hygrometer_state = {
2419
- cluster: "genPowerCfg",
2420
- type: ["raw"],
2421
- convert: (model, msg, publish, options, meta) => {
2422
- const dp = msg.data[10];
2423
- switch (dp) {
2424
- case 14:
2425
- return {
2426
- temperature: Number(msg.data[13]),
2427
- };
2428
- case 12:
2429
- return {
2430
- humidity: Number(msg.data[13]),
2431
- };
2432
- }
2433
- },
2434
- };
2435
- exports.livolo_illuminance_state = {
2436
- cluster: "genPowerCfg",
2437
- type: ["raw"],
2438
- convert: (model, msg, publish, options, meta) => {
2439
- const dp = msg.data[12];
2440
- const noiseLookup = { 1: "silent", 2: "normal", 3: "lively", 4: "noisy" };
2441
- switch (dp) {
2442
- case 13:
2443
- return {
2444
- illuminance: Number(msg.data[13]),
2445
- };
2446
- case 14:
2447
- return {
2448
- noise_detected: msg.data[13] > 2,
2449
- noise_level: noiseLookup[msg.data[13]],
2450
- };
2451
- }
2452
- },
2453
- };
2454
- exports.livolo_pir_state = {
2455
- cluster: "genPowerCfg",
2456
- type: ["raw"],
2457
- convert: (model, msg, publish, options, meta) => {
2458
- const stateHeader = Buffer.from([122, 209]);
2459
- if (msg.data.indexOf(stateHeader) === 0) {
2460
- if (msg.data[10] === 7) {
2461
- const status = msg.data[14];
2462
- return {
2463
- occupancy: !!(status & 1),
2464
- };
2465
- }
2466
- }
2467
- },
2468
- };
2469
- exports.easycode_action = {
2470
- cluster: "closuresDoorLock",
2471
- type: "raw",
2472
- convert: (model, msg, publish, options, meta) => {
2473
- const lookup = {
2474
- 13: "lock",
2475
- 14: "zigbee_unlock",
2476
- 3: "rfid_unlock",
2477
- 0: "keypad_unlock",
2478
- };
2479
- const value = lookup[msg.data[4]];
2480
- if (value === "lock" || value === "zigbee_unlock") {
2481
- return { action: value };
2482
- }
2483
- return { action: lookup[msg.data[3]] };
2484
- },
2485
- };
2486
- exports.easycodetouch_action = {
2487
- cluster: "closuresDoorLock",
2488
- type: "raw",
2489
- convert: (model, msg, publish, options, meta) => {
2490
- const value = constants.easyCodeTouchActions[(msg.data[3] << 8) | msg.data[4]];
2491
- if (value) {
2492
- return { action: value };
2493
- }
2494
- logger_1.logger.warning(`Unknown lock status with source ${msg.data[3]} and event code ${msg.data[4]}`, NS);
2495
- },
2496
- };
2497
- exports.livolo_switch_state_raw = {
2498
- cluster: "genPowerCfg",
2499
- type: ["raw"],
2500
- convert: (model, msg, publish, options, meta) => {
2501
- /*
2502
- header ieee address info data
2503
- new socket
2504
- [124,210,21,216,128, 199,147,3,24,0,75,18,0, 19,7,0] after interview
2505
- [122,209, 199,147,3,24,0,75,18,0, 7,1,6,1,0,11] off
2506
- [122,209, 199,147,3,24,0,75,18,0, 7,1,6,1,1,11] on
2507
-
2508
- new switch
2509
- [124,210,21,216,128, 228,41,3,24,0,75,18,0, 19,1,0] after interview
2510
- [122,209, 228,41,3,24,0,75,18,0, 7,1,0,1,0,11] off
2511
- [122,209, 228,41,3,24,0,75,18,0, 7,1,0,1,1,11] on
2512
-
2513
- old switch
2514
- [124,210,21,216,128, 170, 10,2,24,0,75,18,0, 17,0,1] after interview
2515
- [124,210,21,216,0, 18, 15,5,24,0,75,18,0, 34,0,0] left: 0, right: 0
2516
- [124,210,21,216,0, 18, 15,5,24,0,75,18,0, 34,0,1] left: 1, right: 0
2517
- [124,210,21,216,0, 18, 15,5,24,0,75,18,0, 34,0,2] left: 0, right: 1
2518
- [124,210,21,216,0, 18, 15,5,24,0,75,18,0, 34,0,3] left: 1, right: 1
2519
-
2520
- curtain switch
2521
- [124,210,21,216,128, 110,74,116,33,0,75,18,0, 19,5,0] after interview
2522
- [122,209, 110,74,116,33,0,75,18,0, 5,1,5,0,2,11] left: 0, right: 0 (off)
2523
- [122,209, 110,74,116,33,0,75,18,0, 5,1,5,0,1,11] left: 1, right: 0 (left on)
2524
- [122,209, 110,74,116,33,0,75,18,0, 5,1,5,0,0,11] left: 0, right: 1 (right on)
2525
-
2526
- pir sensor
2527
- [124,210,21,216,128, 225,52,225,34,0,75,18,0, 19,13,0] after interview
2528
- [122,209, 245,94,225,34,0,75,18,0, 7,1,7,1,1,11] occupancy: true
2529
- [122,209, 245,94,225,34,0,75,18,0, 7,1,7,1,0,11] occupancy: false
2530
-
2531
- hygrometer
2532
- [122,209, 191,22,3,24,0,75,18,0, 14,1,8,21,14,11] temperature: 21 degrees Celsius
2533
- [122,209, 191,22,3,24,0,75,18,0, 12,1,9,73,12,11] humidity: 73%
2534
-
2535
- illuminance
2536
- [124,210,21,216,128, 221,0,115,33,0,75,18,0, 19,12,0] after interview
2537
- [122,209, 221,0,115,33,0,75,18,0, 12,1,14,4,12,11] noise: 4 (noisy)
2538
- [122,209, 221,0,115,33,0,75,18,0, 12,1,14,3,12,11] noise: 3 (lively)
2539
- [122,209, 221,0,115,33,0,75,18,0, 12,1,14,2,12,11] noise: 2 (normal)
2540
- [122,209, 221,0,115,33,0,75,18,0, 12,1,14,1,12,11] noise: 1 (silent)
2541
- [122,209, 221,0,115,33,0,75,18,0, 12,1,13,20,12,11] lux: 20
2542
- [122,209, 221,0,115,33,0,75,18,0, 2,0,12,199,1,11] ??
2543
- */
2544
- const malformedHeader = Buffer.from([0x7c, 0xd2, 0x15, 0xd8, 0x00]);
2545
- const infoHeader = Buffer.from([0x7c, 0xd2, 0x15, 0xd8, 0x80]);
2546
- // status of old devices
2547
- if (msg.data.indexOf(malformedHeader) === 0) {
2548
- const status = msg.data[15];
2549
- return {
2550
- state_left: status & 1 ? "ON" : "OFF",
2551
- state_right: status & 2 ? "ON" : "OFF",
2552
- };
2553
- }
2554
- // info about device
2555
- if (msg.data.indexOf(infoHeader) === 0) {
2556
- if (msg.data.includes(Buffer.from([19, 7, 0]), 13)) {
2557
- // new socket, hack
2558
- meta.device.modelID = "TI0001-socket";
2559
- meta.device.save();
2560
- }
2561
- // No need to detect this switches, will be done by universal procedure
2562
- /* if (msg.data.includes(Buffer.from([19, 1, 0]), 13)) {
2563
- // new switch, hack
2564
- meta.device.modelID = 'TI0001-switch';
2565
- meta.device.save();
2566
- }
2567
- if (msg.data.includes(Buffer.from([19, 2, 0]), 13)) {
2568
- // new switch, hack
2569
- meta.device.modelID = 'TI0001-switch-2gang';
2570
- meta.device.save();
2571
- }*/
2572
- if (msg.data.includes(Buffer.from([19, 5, 0]), 13)) {
2573
- logger_1.logger.debug("Detected Livolo Curtain Switch", NS);
2574
- // curtain switch, hack
2575
- meta.device.modelID = "TI0001-curtain-switch";
2576
- meta.device.save();
2577
- }
2578
- if (msg.data.includes(Buffer.from([19, 20, 0]), 13)) {
2579
- // new dimmer, hack
2580
- meta.device.modelID = "TI0001-dimmer";
2581
- meta.device.save();
2582
- }
2583
- if (msg.data.includes(Buffer.from([19, 21, 0]), 13)) {
2584
- meta.device.modelID = "TI0001-cover";
2585
- meta.device.save();
2586
- }
2587
- if (msg.data.includes(Buffer.from([19, 13, 0]), 13)) {
2588
- logger_1.logger.debug("Detected Livolo Pir Sensor", NS);
2589
- meta.device.modelID = "TI0001-pir";
2590
- meta.device.save();
2591
- }
2592
- if (msg.data.includes(Buffer.from([19, 15, 0]), 13)) {
2593
- logger_1.logger.debug("Detected Livolo Digital Hygrometer", NS);
2594
- meta.device.modelID = "TI0001-hygrometer";
2595
- meta.device.save();
2596
- }
2597
- if (msg.data.includes(Buffer.from([19, 12, 0]), 13)) {
2598
- logger_1.logger.debug("Detected Livolo Digital Illuminance and Sound Sensor", NS);
2599
- meta.device.modelID = "TI0001-illuminance";
2600
- meta.device.save();
2601
- }
2602
- }
2603
- },
2604
- };
2605
- exports.ptvo_switch_uart = {
2606
- cluster: "genMultistateValue",
2607
- type: ["attributeReport", "readResponse"],
2608
- convert: (model, msg, publish, options, meta) => {
2609
- let data = msg.data.stateText; // ZclArray is only for write
2610
- if (Array.isArray(data)) {
2611
- let bHex = false;
2612
- let code;
2613
- let index;
2614
- for (index = 0; index < data.length; index += 1) {
2615
- code = data[index];
2616
- if (code < 32 || code > 127) {
2617
- bHex = true;
2618
- break;
2619
- }
2620
- }
2621
- if (!bHex) {
2622
- data = data.toString();
2623
- }
2624
- else {
2625
- data = [...data];
2626
- }
2627
- }
2628
- return { action: data };
2629
- },
2630
- };
2631
- exports.ptvo_switch_analog_input = {
2632
- cluster: "genAnalogInput",
2633
- type: ["attributeReport", "readResponse"],
2634
- convert: (model, msg, publish, options, meta) => {
2635
- const payload = {};
2636
- const channel = msg.endpoint.ID;
2637
- const name = `l${channel}`;
2638
- const endpoint = msg.endpoint;
2639
- payload[name] = (0, utils_1.precisionRound)(msg.data.presentValue, 3);
2640
- const cluster = "genLevelCtrl";
2641
- if (endpoint && (endpoint.supportsInputCluster(cluster) || endpoint.supportsOutputCluster(cluster))) {
2642
- payload[`brightness_${name}`] = msg.data.presentValue;
2643
- }
2644
- else if (msg.data.description !== undefined) {
2645
- const data1 = msg.data.description;
2646
- if (data1) {
2647
- const data2 = data1.split(",");
2648
- const devid = data2[1];
2649
- const unit = data2[0];
2650
- if (devid) {
2651
- payload[`device_${name}`] = devid;
2652
- }
2653
- const valRaw = msg.data.presentValue;
2654
- if (unit) {
2655
- let val = (0, utils_1.precisionRound)(valRaw, 1);
2656
- const nameLookup = {
2657
- C: "temperature",
2658
- "%": "humidity",
2659
- m: "altitude",
2660
- Pa: "pressure",
2661
- ppm: "quality",
2662
- psize: "particle_size",
2663
- V: "voltage",
2664
- A: "current",
2665
- Wh: "energy",
2666
- W: "power",
2667
- Hz: "frequency",
2668
- pf: "power_factor",
2669
- lx: "illuminance",
2670
- };
2671
- let nameAlt = "";
2672
- if (unit === "A" || unit === "pf") {
2673
- if (valRaw < 1) {
2674
- val = (0, utils_1.precisionRound)(valRaw, 3);
2675
- }
2676
- }
2677
- if (unit.startsWith("mcpm") || unit.startsWith("ncpm")) {
2678
- const num = unit.substr(4, 1);
2679
- nameAlt = num === "A" ? `${unit.substr(0, 4)}10` : unit;
2680
- val = (0, utils_1.precisionRound)(valRaw, 2);
2681
- }
2682
- else {
2683
- nameAlt = nameLookup[unit];
2684
- }
2685
- if (nameAlt === undefined) {
2686
- const valueIndex = Number.parseInt(unit, 10);
2687
- if (!Number.isNaN(valueIndex)) {
2688
- nameAlt = `val${unit}`;
2689
- }
2690
- }
2691
- if (nameAlt !== undefined) {
2692
- payload[`${nameAlt}_${name}`] = val;
2693
- }
2694
- }
2695
- }
2696
- }
2697
- return payload;
2698
- },
2699
- };
2700
- exports.keypad20states = {
2701
- cluster: "genOnOff",
2702
- type: ["readResponse", "attributeReport"],
2703
- convert: (model, msg, publish, options, meta) => {
2704
- const button = (0, utils_1.getKey)(model.endpoint(msg.device), msg.endpoint.ID);
2705
- const state = msg.data.onOff === 1;
2706
- if (button) {
2707
- return { [button]: state };
2708
- }
2709
- },
2710
- };
2711
- exports.keypad20_battery = {
2712
- cluster: "genPowerCfg",
2713
- type: ["readResponse", "attributeReport"],
2714
- convert: (model, msg, publish, options, meta) => {
2715
- const voltage = msg.data.mainsVoltage / 10;
2716
- return {
2717
- battery: (0, utils_1.batteryVoltageToPercentage)(voltage, "3V_2100"),
2718
- voltage: voltage, // @deprecated
2719
- // voltage: voltage / 1000.0,
2720
- };
2721
- },
2722
- };
2723
- exports.plaid_battery = {
2724
- cluster: "genPowerCfg",
2725
- type: ["readResponse", "attributeReport"],
2726
- convert: (model, msg, publish, options, meta) => {
2727
- const payload = {};
2728
- if (msg.data.mainsVoltage !== undefined) {
2729
- payload.voltage = msg.data.mainsVoltage;
2730
- if (model.meta?.battery?.voltageToPercentage) {
2731
- payload.battery = (0, utils_1.batteryVoltageToPercentage)(payload.voltage, model.meta.battery.voltageToPercentage);
2732
- }
2733
- }
2734
- return payload;
2735
- },
2736
- };
2737
- exports.heiman_ir_remote = {
2738
- cluster: "heimanSpecificInfraRedRemote",
2739
- type: ["commandStudyKeyRsp", "commandCreateIdRsp", "commandGetIdAndKeyCodeListRsp"],
2740
- convert: (model, msg, publish, options, meta) => {
2741
- // TODO: split converter for each cmd?
2742
- switch (msg.type) {
2743
- case "commandStudyKeyRsp":
2744
- (0, node_assert_1.default)("keyCode" in msg.data);
2745
- return {
2746
- action: "learn",
2747
- action_result: msg.data.result === 1 ? "success" : "error",
2748
- action_key_code: msg.data.keyCode,
2749
- action_id: msg.data.result === 1 ? msg.data.id : undefined,
2750
- };
2751
- case "commandCreateIdRsp":
2752
- (0, node_assert_1.default)("id" in msg.data);
2753
- (0, node_assert_1.default)("modelType" in msg.data);
2754
- return {
2755
- action: "create",
2756
- action_result: msg.data.id === 0xff ? "error" : "success",
2757
- action_model_type: msg.data.modelType,
2758
- action_id: msg.data.id !== 0xff ? msg.data.id : undefined,
2759
- };
2760
- case "commandGetIdAndKeyCodeListRsp": {
2761
- (0, node_assert_1.default)("packetNumber" in msg.data);
2762
- // See cluster.js with data format description
2763
- if (msg.data.packetNumber === 1) {
2764
- // start to collect and merge list
2765
- // so, we use store instance for temp storage during merging
2766
- globalStore.putValue(msg.endpoint, "db", []);
2767
- }
2768
- const buffer = msg.data.learnedDevicesList;
2769
- for (let i = 0; i < msg.data.packetLength;) {
2770
- const modelDescription = {
2771
- id: buffer[i],
2772
- model_type: buffer[i + 1],
2773
- key_codes: [],
2774
- };
2775
- const numberOfKeys = buffer[i + 2];
2776
- for (let j = i + 3; j < i + 3 + numberOfKeys; j++) {
2777
- modelDescription.key_codes.push(buffer[j]);
2778
- }
2779
- i = i + 3 + numberOfKeys;
2780
- globalStore.getValue(msg.endpoint, "db").push(modelDescription);
2781
- }
2782
- if (msg.data.packetNumber === msg.data.packetsTotal) {
2783
- // last packet, all data collected, can publish
2784
- const result = {
2785
- devices: globalStore.getValue(msg.endpoint, "db"),
2786
- };
2787
- globalStore.clearValue(msg.endpoint, "db");
2788
- return result;
2789
- }
2790
- break;
2791
- }
2792
- }
2793
- },
2794
- };
2795
- exports.meazon_meter = {
2796
- cluster: "seMetering",
2797
- type: ["attributeReport", "readResponse"],
2798
- convert: (model, msg, publish, options, meta) => {
2799
- const result = {};
2800
- // typo on property name to stick with zcl definition
2801
- if (msg.data.inletTempreature !== undefined) {
2802
- result.inlet_temperature = (0, utils_1.precisionRound)(msg.data.inletTempreature, 2);
2803
- result.inletTemperature = result.inlet_temperature; // deprecated
2804
- }
2805
- if (msg.data.status !== undefined) {
2806
- result.status = (0, utils_1.precisionRound)(msg.data.status, 2);
2807
- }
2808
- if (msg.data["8192"] !== undefined) {
2809
- result.line_frequency = (0, utils_1.precisionRound)(Number.parseFloat(msg.data["8192"]) / 100.0, 2);
2810
- result.linefrequency = result.line_frequency; // deprecated
2811
- }
2812
- if (msg.data["8193"] !== undefined) {
2813
- result.power = (0, utils_1.precisionRound)(msg.data["8193"], 2);
2814
- }
2815
- if (msg.data["8196"] !== undefined) {
2816
- result.voltage = (0, utils_1.precisionRound)(msg.data["8196"], 2);
2817
- }
2818
- if (msg.data["8213"] !== undefined) {
2819
- result.voltage = (0, utils_1.precisionRound)(msg.data["8213"], 2);
2820
- }
2821
- if (msg.data["8199"] !== undefined) {
2822
- result.current = (0, utils_1.precisionRound)(msg.data["8199"], 2);
2823
- }
2824
- if (msg.data["8216"] !== undefined) {
2825
- result.current = (0, utils_1.precisionRound)(msg.data["8216"], 2);
2826
- }
2827
- if (msg.data["8202"] !== undefined) {
2828
- result.reactive_power = (0, utils_1.precisionRound)(msg.data["8202"], 2);
2829
- result.reactivepower = result.reactive_power; // deprecated
2830
- }
2831
- if (msg.data["12288"] !== undefined) {
2832
- result.energy_consumed = (0, utils_1.precisionRound)(msg.data["12288"], 2); // deprecated
2833
- result.energyconsumed = result.energy_consumed; // deprecated
2834
- result.energy = result.energy_consumed;
2835
- }
2836
- if (msg.data["12291"] !== undefined) {
2837
- result.energy_produced = (0, utils_1.precisionRound)(msg.data["12291"], 2);
2838
- result.energyproduced = result.energy_produced; // deprecated
2839
- }
2840
- if (msg.data["12294"] !== undefined) {
2841
- result.reactive_summation = (0, utils_1.precisionRound)(msg.data["12294"], 2);
2842
- result.reactivesummation = result.reactive_summation; // deprecated
2843
- }
2844
- if (msg.data["16408"] !== undefined) {
2845
- result.measure_serial = (0, utils_1.precisionRound)(msg.data["16408"], 2);
2846
- result.measureserial = result.measure_serial; // deprecated
2847
- }
2848
- return result;
2849
- },
2850
- };
2851
- exports.danfoss_thermostat = {
2852
- cluster: "hvacThermostat",
2853
- type: ["attributeReport", "readResponse"],
2854
- convert: (model, msg, publish, options, meta) => {
2855
- const result = {};
2856
- if (msg.data.danfossWindowOpenFeatureEnable !== undefined) {
2857
- result[(0, utils_1.postfixWithEndpointName)("window_open_feature", msg, model, meta)] = msg.data.danfossWindowOpenFeatureEnable === 1;
2858
- }
2859
- if (msg.data.danfossWindowOpenInternal !== undefined) {
2860
- result[(0, utils_1.postfixWithEndpointName)("window_open_internal", msg, model, meta)] =
2861
- constants.danfossWindowOpen[msg.data.danfossWindowOpenInternal] !== undefined
2862
- ? constants.danfossWindowOpen[msg.data.danfossWindowOpenInternal]
2863
- : msg.data.danfossWindowOpenInternal;
2864
- }
2865
- if (msg.data.danfossWindowOpenExternal !== undefined) {
2866
- result[(0, utils_1.postfixWithEndpointName)("window_open_external", msg, model, meta)] = msg.data.danfossWindowOpenExternal === 1;
2867
- }
2868
- if (msg.data.danfossDayOfWeek !== undefined) {
2869
- result[(0, utils_1.postfixWithEndpointName)("day_of_week", msg, model, meta)] =
2870
- constants.thermostatDayOfWeek[msg.data.danfossDayOfWeek] !== undefined
2871
- ? constants.thermostatDayOfWeek[msg.data.danfossDayOfWeek]
2872
- : msg.data.danfossDayOfWeek;
2873
- }
2874
- if (msg.data.danfossTriggerTime !== undefined) {
2875
- result[(0, utils_1.postfixWithEndpointName)("trigger_time", msg, model, meta)] = msg.data.danfossTriggerTime;
2876
- }
2877
- if (msg.data.danfossMountedModeActive !== undefined) {
2878
- result[(0, utils_1.postfixWithEndpointName)("mounted_mode_active", msg, model, meta)] = msg.data.danfossMountedModeActive === 1;
2879
- }
2880
- if (msg.data.danfossMountedModeControl !== undefined) {
2881
- result[(0, utils_1.postfixWithEndpointName)("mounted_mode_control", msg, model, meta)] = msg.data.danfossMountedModeControl === 1;
2882
- }
2883
- if (msg.data.danfossThermostatOrientation !== undefined) {
2884
- result[(0, utils_1.postfixWithEndpointName)("thermostat_vertical_orientation", msg, model, meta)] = msg.data.danfossThermostatOrientation === 1;
2885
- }
2886
- if (msg.data.danfossExternalMeasuredRoomSensor !== undefined) {
2887
- result[(0, utils_1.postfixWithEndpointName)("external_measured_room_sensor", msg, model, meta)] = msg.data.danfossExternalMeasuredRoomSensor;
2888
- }
2889
- if (msg.data.danfossRadiatorCovered !== undefined) {
2890
- result[(0, utils_1.postfixWithEndpointName)("radiator_covered", msg, model, meta)] = msg.data.danfossRadiatorCovered === 1;
2891
- }
2892
- if (msg.data.danfossAlgorithmScaleFactor !== undefined) {
2893
- result[(0, utils_1.postfixWithEndpointName)("algorithm_scale_factor", msg, model, meta)] = msg.data.danfossAlgorithmScaleFactor;
2894
- }
2895
- if (msg.data.danfossHeatAvailable !== undefined) {
2896
- result[(0, utils_1.postfixWithEndpointName)("heat_available", msg, model, meta)] = msg.data.danfossHeatAvailable === 1;
2897
- }
2898
- if (msg.data.danfossHeatRequired !== undefined) {
2899
- if (msg.data.danfossHeatRequired === 1) {
2900
- result[(0, utils_1.postfixWithEndpointName)("heat_required", msg, model, meta)] = true;
2901
- result[(0, utils_1.postfixWithEndpointName)("running_state", msg, model, meta)] = "heat";
2902
- }
2903
- else {
2904
- result[(0, utils_1.postfixWithEndpointName)("heat_required", msg, model, meta)] = false;
2905
- result[(0, utils_1.postfixWithEndpointName)("running_state", msg, model, meta)] = "idle";
2906
- }
2907
- }
2908
- if (msg.data.danfossLoadBalancingEnable !== undefined) {
2909
- result[(0, utils_1.postfixWithEndpointName)("load_balancing_enable", msg, model, meta)] = msg.data.danfossLoadBalancingEnable === 1;
2910
- }
2911
- if (msg.data.danfossLoadRoomMean !== undefined) {
2912
- result[(0, utils_1.postfixWithEndpointName)("load_room_mean", msg, model, meta)] = msg.data.danfossLoadRoomMean;
2913
- }
2914
- if (msg.data.danfossLoadEstimate !== undefined) {
2915
- result[(0, utils_1.postfixWithEndpointName)("load_estimate", msg, model, meta)] = msg.data.danfossLoadEstimate;
2916
- }
2917
- if (msg.data.danfossPreheatStatus !== undefined) {
2918
- result[(0, utils_1.postfixWithEndpointName)("preheat_status", msg, model, meta)] = msg.data.danfossPreheatStatus === 1;
2919
- }
2920
- if (msg.data.danfossAdaptionRunStatus !== undefined) {
2921
- result[(0, utils_1.postfixWithEndpointName)("adaptation_run_status", msg, model, meta)] =
2922
- constants.danfossAdaptionRunStatus[msg.data.danfossAdaptionRunStatus];
2923
- }
2924
- if (msg.data.danfossAdaptionRunSettings !== undefined) {
2925
- result[(0, utils_1.postfixWithEndpointName)("adaptation_run_settings", msg, model, meta)] = msg.data.danfossAdaptionRunSettings === 1;
2926
- }
2927
- if (msg.data.danfossAdaptionRunControl !== undefined) {
2928
- result[(0, utils_1.postfixWithEndpointName)("adaptation_run_control", msg, model, meta)] =
2929
- constants.danfossAdaptionRunControl[msg.data.danfossAdaptionRunControl];
2930
- }
2931
- if (msg.data.danfossRegulationSetpointOffset !== undefined) {
2932
- result[(0, utils_1.postfixWithEndpointName)("regulation_setpoint_offset", msg, model, meta)] = msg.data.danfossRegulationSetpointOffset;
2933
- }
2934
- // Danfoss Icon Converters
2935
- if (msg.data.danfossRoomStatusCode !== undefined) {
2936
- result[(0, utils_1.postfixWithEndpointName)("room_status_code", msg, model, meta)] =
2937
- constants.danfossRoomStatusCode[msg.data.danfossRoomStatusCode] !== undefined
2938
- ? constants.danfossRoomStatusCode[msg.data.danfossRoomStatusCode]
2939
- : msg.data.danfossRoomStatusCode;
2940
- }
2941
- if (msg.data.danfossOutputStatus !== undefined) {
2942
- if (msg.data.danfossOutputStatus === 1) {
2943
- result[(0, utils_1.postfixWithEndpointName)("output_status", msg, model, meta)] = "active";
2944
- result[(0, utils_1.postfixWithEndpointName)("running_state", msg, model, meta)] = "heat";
2945
- }
2946
- else {
2947
- result[(0, utils_1.postfixWithEndpointName)("output_status", msg, model, meta)] = "inactive";
2948
- result[(0, utils_1.postfixWithEndpointName)("running_state", msg, model, meta)] = "idle";
2949
- }
2950
- }
2951
- return result;
2952
- },
2953
- };
2954
- exports.danfoss_hvac_ui = {
2955
- cluster: "hvacUserInterfaceCfg",
2956
- type: ["attributeReport", "readResponse"],
2957
- convert: (model, msg, publish, options, meta) => {
2958
- const result = {};
2959
- if (msg.data.danfossViewingDirection !== undefined) {
2960
- result[(0, utils_1.postfixWithEndpointName)("viewing_direction", msg, model, meta)] = msg.data.danfossViewingDirection === 1;
2961
- }
2962
- return result;
2963
- },
2964
- };
2965
- exports.danfoss_thermostat_setpoint_scheduled = {
2966
- cluster: "hvacThermostat",
2967
- type: ["attributeReport", "readResponse"],
2968
- convert: (model, msg, publish, options, meta) => {
2969
- const result = {};
2970
- if (msg.data.occupiedHeatingSetpoint !== undefined) {
2971
- result[(0, utils_1.postfixWithEndpointName)("occupied_heating_setpoint_scheduled", msg, model, meta)] =
2972
- (0, utils_1.precisionRound)(msg.data.occupiedHeatingSetpoint, 2) / 100;
2973
- }
2974
- return result;
2975
- },
2976
- };
2977
- exports.danfoss_icon_floor_sensor = {
2978
- cluster: "hvacThermostat",
2979
- type: ["attributeReport", "readResponse"],
2980
- convert: (model, msg, publish, options, meta) => {
2981
- const result = {};
2982
- if (msg.data.danfossRoomFloorSensorMode !== undefined) {
2983
- result[(0, utils_1.postfixWithEndpointName)("room_floor_sensor_mode", msg, model, meta)] =
2984
- constants.danfossRoomFloorSensorMode[msg.data.danfossRoomFloorSensorMode] !== undefined
2985
- ? constants.danfossRoomFloorSensorMode[msg.data.danfossRoomFloorSensorMode]
2986
- : msg.data.danfossRoomFloorSensorMode;
2987
- }
2988
- if (msg.data.danfossFloorMinSetpoint !== undefined) {
2989
- const value = (0, utils_1.precisionRound)(msg.data.danfossFloorMinSetpoint, 2) / 100;
2990
- if (value >= -273.15) {
2991
- result[(0, utils_1.postfixWithEndpointName)("floor_min_setpoint", msg, model, meta)] = value;
2992
- }
2993
- }
2994
- if (msg.data.danfossFloorMaxSetpoint !== undefined) {
2995
- const value = (0, utils_1.precisionRound)(msg.data.danfossFloorMaxSetpoint, 2) / 100;
2996
- if (value >= -273.15) {
2997
- result[(0, utils_1.postfixWithEndpointName)("floor_max_setpoint", msg, model, meta)] = value;
2998
- }
2999
- }
3000
- if (msg.data.danfossScheduleTypeUsed !== undefined) {
3001
- result[(0, utils_1.postfixWithEndpointName)("schedule_type_used", msg, model, meta)] =
3002
- constants.danfossScheduleTypeUsed[msg.data.danfossScheduleTypeUsed] !== undefined
3003
- ? constants.danfossScheduleTypeUsed[msg.data.danfossScheduleTypeUsed]
3004
- : msg.data.danfossScheduleTypeUsed;
3005
- }
3006
- if (msg.data.danfossIcon2PreHeat !== undefined) {
3007
- result[(0, utils_1.postfixWithEndpointName)("icon2_pre_heat", msg, model, meta)] =
3008
- constants.danfossIcon2PreHeat[msg.data.danfossIcon2PreHeat] !== undefined
3009
- ? constants.danfossIcon2PreHeat[msg.data.danfossIcon2PreHeat]
3010
- : msg.data.danfossIcon2PreHeat;
3011
- }
3012
- if (msg.data.danfossIcon2PreHeatStatus !== undefined) {
3013
- result[(0, utils_1.postfixWithEndpointName)("icon2_pre_heat_status", msg, model, meta)] =
3014
- constants.danfossIcon2PreHeatStatus[msg.data.danfossIcon2PreHeatStatus] !== undefined
3015
- ? constants.danfossIcon2PreHeatStatus[msg.data.danfossIcon2PreHeatStatus]
3016
- : msg.data.danfossIcon2PreHeatStatus;
3017
- }
3018
- return result;
3019
- },
3020
- };
3021
- exports.danfoss_icon_battery = {
3022
- cluster: "genPowerCfg",
3023
- type: ["attributeReport", "readResponse"],
3024
- convert: (model, msg, publish, options, meta) => {
3025
- const result = {};
3026
- if (msg.data.batteryPercentageRemaining !== undefined) {
3027
- // Some devices do not comply to the ZCL and report a
3028
- // batteryPercentageRemaining of 100 when the battery is full (should be 200).
3029
- const dontDividePercentage = model.meta?.battery?.dontDividePercentage;
3030
- let percentage = msg.data.batteryPercentageRemaining;
3031
- percentage = dontDividePercentage ? percentage : percentage / 2;
3032
- result[(0, utils_1.postfixWithEndpointName)("battery", msg, model, meta)] = (0, utils_1.precisionRound)(percentage, 2);
3033
- }
3034
- return result;
3035
- },
3036
- };
3037
- exports.danfoss_icon_regulator = {
3038
- cluster: "haDiagnostic",
3039
- type: ["attributeReport", "readResponse"],
3040
- convert: (model, msg, publish, options, meta) => {
3041
- const result = {};
3042
- if (msg.data.danfossSystemStatusCode !== undefined) {
3043
- result[(0, utils_1.postfixWithEndpointName)("system_status_code", msg, model, meta)] =
3044
- constants.danfossSystemStatusCode[msg.data.danfossSystemStatusCode] !== undefined
3045
- ? constants.danfossSystemStatusCode[msg.data.danfossSystemStatusCode]
3046
- : msg.data.danfossSystemStatusCode;
3047
- }
3048
- if (msg.data.danfossHeatSupplyRequest !== undefined) {
3049
- result[(0, utils_1.postfixWithEndpointName)("heat_supply_request", msg, model, meta)] =
3050
- constants.danfossHeatsupplyRequest[msg.data.danfossHeatSupplyRequest] !== undefined
3051
- ? constants.danfossHeatsupplyRequest[msg.data.danfossHeatSupplyRequest]
3052
- : msg.data.danfossHeatSupplyRequest;
3053
- }
3054
- if (msg.data.danfossSystemStatusWater !== undefined) {
3055
- result[(0, utils_1.postfixWithEndpointName)("system_status_water", msg, model, meta)] =
3056
- constants.danfossSystemStatusWater[msg.data.danfossSystemStatusWater] !== undefined
3057
- ? constants.danfossSystemStatusWater[msg.data.danfossSystemStatusWater]
3058
- : msg.data.danfossSystemStatusWater;
3059
- }
3060
- if (msg.data.danfossMultimasterRole !== undefined) {
3061
- result[(0, utils_1.postfixWithEndpointName)("multimaster_role", msg, model, meta)] =
3062
- constants.danfossMultimasterRole[msg.data.danfossMultimasterRole] !== undefined
3063
- ? constants.danfossMultimasterRole[msg.data.danfossMultimasterRole]
3064
- : msg.data.danfossMultimasterRole;
3065
- }
3066
- if (msg.data.danfossIconApplication !== undefined) {
3067
- result[(0, utils_1.postfixWithEndpointName)("icon_application", msg, model, meta)] =
3068
- constants.danfossIconApplication[msg.data.danfossIconApplication] !== undefined
3069
- ? constants.danfossIconApplication[msg.data.danfossIconApplication]
3070
- : msg.data.danfossIconApplication;
3071
- }
3072
- if (msg.data.danfossIconForcedHeatingCooling !== undefined) {
3073
- result[(0, utils_1.postfixWithEndpointName)("icon_forced_heating_cooling", msg, model, meta)] =
3074
- constants.danfossIconForcedHeatingCooling[msg.data.danfossIconForcedHeatingCooling] !== undefined
3075
- ? constants.danfossIconForcedHeatingCooling[msg.data.danfossIconForcedHeatingCooling]
3076
- : msg.data.danfossIconForcedHeatingCooling;
3077
- }
3078
- return result;
3079
- },
3080
- };
3081
- exports.danfoss_icon_hvac_user_interface = {
3082
- cluster: "hvacUserInterfaceCfg",
3083
- type: ["attributeReport", "readResponse"],
3084
- convert: (model, msg, publish, options, meta) => {
3085
- const result = {};
3086
- if (msg.data.keypadLockout !== undefined) {
3087
- result[(0, utils_1.postfixWithEndpointName)("keypad_lockout", msg, model, meta)] =
3088
- constants.keypadLockoutMode[msg.data.keypadLockout] !== undefined
3089
- ? constants.keypadLockoutMode[msg.data.keypadLockout]
3090
- : msg.data.keypadLockout;
3091
- }
3092
- if (msg.data.tempDisplayMode !== undefined) {
3093
- result[(0, utils_1.postfixWithEndpointName)("temperature_display_mode", msg, model, meta)] =
3094
- constants.temperatureDisplayMode[msg.data.tempDisplayMode] !== undefined
3095
- ? constants.temperatureDisplayMode[msg.data.tempDisplayMode]
3096
- : msg.data.tempDisplayMode;
3097
- }
3098
- return result;
3099
- },
3100
- };
3101
- exports.orvibo_raw_1 = {
3102
- cluster: 23,
3103
- type: "raw",
3104
- convert: (model, msg, publish, options, meta) => {
3105
- // 25,0,8,3,0,0 - click btn 1
3106
- // 25,0,8,3,0,2 - hold btn 1
3107
- // 25,0,8,3,0,3 - release btn 1
3108
- // 25,0,8,11,0,0 - click btn 2
3109
- // 25,0,8,11,0,2 - hold btn 2
3110
- // 25,0,8,11,0,3 - release btn 2
3111
- // 25,0,8,7,0,0 - click btn 3
3112
- // 25,0,8,7,0,2 - hold btn 3
3113
- // 25,0,8,7,0,3 - release btn 3
3114
- // 25,0,8,15,0,0 - click btn 4
3115
- // 25,0,8,15,0,2 - hold btn 4
3116
- // 25,0,8,15,0,3 - release btn 4
3117
- // TODO: do not know how to get to use 5,6,7,8 buttons
3118
- const buttonLookup = {
3119
- 3: "button_1",
3120
- 11: "button_2",
3121
- 7: "button_3",
3122
- 15: "button_4",
3123
- };
3124
- const actionLookup = {
3125
- 0: "click",
3126
- 2: "hold",
3127
- 3: "release",
3128
- };
3129
- const button = buttonLookup[msg.data[3]];
3130
- const action = actionLookup[msg.data[5]];
3131
- if (button) {
3132
- return { action: `${button}_${action}` };
3133
- }
3134
- },
3135
- };
3136
- exports.orvibo_raw_2 = {
3137
- cluster: 23,
3138
- type: "raw",
3139
- convert: (model, msg, publish, options, meta) => {
3140
- const buttonLookup = {
3141
- 1: "button_1",
3142
- 2: "button_2",
3143
- 3: "button_3",
3144
- 4: "button_4",
3145
- 5: "button_5",
3146
- 6: "button_6",
3147
- 7: "button_7",
3148
- };
3149
- const actionLookup = {
3150
- 0: "click",
3151
- 2: "hold",
3152
- 3: "release",
3153
- };
3154
- const button = buttonLookup[msg.data[3]];
3155
- const action = actionLookup[msg.data[5]];
3156
- if (button) {
3157
- return { action: `${button}_${action}` };
3158
- }
3159
- },
3160
- };
3161
- exports.tint_scene = {
3162
- cluster: "genBasic",
3163
- type: "write",
3164
- convert: (model, msg, publish, options, meta) => {
3165
- const payload = { action: `scene_${msg.data["16389"]}` };
3166
- (0, utils_1.addActionGroup)(payload, msg, model);
3167
- return payload;
3168
- },
3169
- };
3170
- exports.tint404011_move_to_color_temp = {
3171
- cluster: "lightingColorCtrl",
3172
- type: "commandMoveToColorTemp",
3173
- convert: (model, msg, publish, options, meta) => {
3174
- // The remote has an internal state so store the last action in order to
3175
- // determine the direction of the color temperature change.
3176
- if (!globalStore.hasValue(msg.endpoint, "last_color_temp")) {
3177
- globalStore.putValue(msg.endpoint, "last_color_temp", msg.data.colortemp);
3178
- }
3179
- const lastTemp = globalStore.getValue(msg.endpoint, "last_color_temp");
3180
- globalStore.putValue(msg.endpoint, "last_color_temp", msg.data.colortemp);
3181
- let direction = "down";
3182
- if (lastTemp > msg.data.colortemp) {
3183
- direction = "up";
3184
- }
3185
- else if (lastTemp < msg.data.colortemp) {
3186
- direction = "down";
3187
- }
3188
- else if (msg.data.colortemp === 370 || msg.data.colortemp === 555) {
3189
- // The remote goes up to 370 in steps and emits 555 on down button hold.
3190
- direction = "down";
3191
- }
3192
- else if (msg.data.colortemp === 153) {
3193
- direction = "up";
3194
- }
3195
- const payload = {
3196
- action: (0, utils_1.postfixWithEndpointName)("color_temperature_move", msg, model, meta),
3197
- action_color_temperature: msg.data.colortemp,
3198
- action_transition_time: msg.data.transtime,
3199
- action_color_temperature_direction: direction,
3200
- };
3201
- (0, utils_1.addActionGroup)(payload, msg, model);
3202
- return payload;
3203
- },
3204
- };
3205
- exports.restorable_brightness = {
3206
- cluster: "genLevelCtrl",
3207
- type: ["attributeReport", "readResponse"],
3208
- convert: (model, msg, publish, options, meta) => {
3209
- if (msg.data.currentLevel !== undefined) {
3210
- // Ignore brightness = 0, which only happens when state is OFF
3211
- if (Number(msg.data.currentLevel) > 0) {
3212
- return { brightness: msg.data.currentLevel };
3213
- }
3214
- return {};
3215
- }
3216
- },
3217
- };
3218
- exports.ewelink_action = {
3219
- cluster: "genOnOff",
3220
- type: ["commandOn", "commandOff", "commandToggle"],
3221
- convert: (model, msg, publish, options, meta) => {
3222
- const lookup = { commandToggle: "single", commandOn: "double", commandOff: "long" };
3223
- return { action: lookup[msg.type] };
3224
- },
3225
- };
3226
- exports.diyruz_contact = {
3227
- cluster: "genOnOff",
3228
- type: ["attributeReport", "readResponse"],
3229
- convert: (model, msg, publish, options, meta) => {
3230
- return { contact: msg.data.onOff !== 0 };
3231
- },
3232
- };
3233
- exports.diyruz_rspm = {
3234
- cluster: "genOnOff",
3235
- type: ["attributeReport", "readResponse"],
3236
- convert: (model, msg, publish, options, meta) => {
3237
- const power = (0, utils_1.precisionRound)(msg.data["41364"], 2);
3238
- return {
3239
- state: msg.data.onOff === 1 ? "ON" : "OFF",
3240
- cpu_temperature: (0, utils_1.precisionRound)(msg.data["41361"], 2),
3241
- power: power,
3242
- current: (0, utils_1.precisionRound)(power / 230, 2),
3243
- action: msg.data["41367"] === 1 ? "hold" : "release",
3244
- };
3245
- },
3246
- };
3247
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3248
- exports.K4003C_binary_input = {
3249
- cluster: "genBinaryInput",
3250
- type: "attributeReport",
3251
- convert: (model, msg, publish, options, meta) => {
3252
- return { action: msg.data.presentValue === 1 ? "off" : "on" };
3253
- },
3254
- };
3255
- exports.enocean_ptm215z = {
3256
- cluster: "greenPower",
3257
- type: ["commandNotification", "commandCommissioningNotification"],
3258
- convert: (model, msg, publish, options, meta) => {
3259
- const commandID = msg.data.commandID;
3260
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model, msg.data.frameCounter, `${msg.device.ieeeAddr}_${commandID}`))
3261
- return;
3262
- if (commandID === 224)
3263
- return; // Skip commissioning command.
3264
- // Button 1: A0 (top left)
3265
- // Button 2: A1 (bottom left)
3266
- // Button 3: B0 (top right)
3267
- // Button 4: B1 (bottom right)
3268
- const lookup = {
3269
- 16: "press_1",
3270
- 20: "release_1",
3271
- 17: "press_2",
3272
- 21: "release_2",
3273
- 19: "press_3",
3274
- 23: "release_3",
3275
- 18: "press_4",
3276
- 22: "release_4",
3277
- 100: "press_1_and_3",
3278
- 101: "release_1_and_3",
3279
- 98: "press_2_and_4",
3280
- 99: "release_2_and_4",
3281
- 34: "press_energy_bar",
3282
- };
3283
- const action = lookup[commandID] !== undefined ? lookup[commandID] : `unknown_${commandID}`;
3284
- return { action };
3285
- },
3286
- };
3287
- exports.enocean_ptm215ze = {
3288
- cluster: "greenPower",
3289
- type: ["commandNotification", "commandCommissioningNotification"],
3290
- convert: (model, msg, publish, options, meta) => {
3291
- const commandID = msg.data.commandID;
3292
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model, msg.data.frameCounter, `${msg.device.ieeeAddr}_${commandID}`))
3293
- return;
3294
- if (commandID === 224)
3295
- return;
3296
- // Button 1: A0 (top left)
3297
- // Button 2: A1 (bottom left)
3298
- // Button 3: B0 (top right)
3299
- // Button 4: B1 (bottom right)
3300
- const lookup = {
3301
- 34: "press_1",
3302
- 35: "release_1",
3303
- 24: "press_2",
3304
- 25: "release_2",
3305
- 20: "press_3",
3306
- 21: "release_3",
3307
- 18: "press_4",
3308
- 19: "release_4",
3309
- 100: "press_1_and_2",
3310
- 101: "release_1_and_2",
3311
- 98: "press_1_and_3",
3312
- 99: "release_1_and_3",
3313
- 30: "press_1_and_4",
3314
- 31: "release_1_and_4",
3315
- 28: "press_2_and_3",
3316
- 29: "release_2_and_3",
3317
- 26: "press_2_and_4",
3318
- 27: "release_2_and_4",
3319
- 22: "press_3_and_4",
3320
- 23: "release_3_and_4",
3321
- 16: "press_energy_bar",
3322
- 17: "release_energy_bar",
3323
- 0: "press_or_release_all",
3324
- 80: "lock",
3325
- 81: "unlock",
3326
- 82: "half_open",
3327
- 83: "tilt",
3328
- };
3329
- if (lookup[commandID] === undefined) {
3330
- logger_1.logger.error(`PTM 215ZE: missing command '${commandID}'`, NS);
3331
- }
3332
- else {
3333
- return { action: lookup[commandID] };
3334
- }
3335
- },
3336
- };
3337
- exports.enocean_ptm216z = {
3338
- cluster: "greenPower",
3339
- type: ["commandNotification", "commandCommissioningNotification"],
3340
- convert: (model, msg, publish, options, meta) => {
3341
- const commandID = msg.data.commandID;
3342
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model, msg.data.frameCounter, `${msg.device.ieeeAddr}_${commandID}`))
3343
- return;
3344
- if (commandID === 224)
3345
- return;
3346
- // Button 1: A0 (top left)
3347
- // Button 2: A1 (bottom left)
3348
- // Button 3: B0 (top right)
3349
- // Button 4: B1 (bottom right)
3350
- const lookup = {
3351
- "105_1": "press_1",
3352
- "105_2": "press_2",
3353
- "105_3": "press_1_and_2",
3354
- "105_4": "press_3",
3355
- "105_5": "press_1_and_3",
3356
- "105_6": "press_2_and_3",
3357
- "105_7": "press_1_and_2_and_3",
3358
- "105_8": "press_4",
3359
- "105_9": "press_1_and_4",
3360
- "105_10": "press_2_and_4",
3361
- "105_11": "press_1_and_2_and_4",
3362
- "105_12": "press_3_and_4",
3363
- "105_13": "press_1_and_3_and_4",
3364
- "105_14": "press_2_and_3_and_4",
3365
- "105_15": "press_all",
3366
- "105_16": "press_energy_bar",
3367
- "106_0": "release",
3368
- "104_": "short_press_2_of_2",
3369
- };
3370
- const ID = `${commandID}_${("raw" in msg.data.commandFrame && msg.data.commandFrame.raw?.slice(0, 1).join("_")) ?? ""}`;
3371
- if (lookup[ID] === undefined) {
3372
- logger_1.logger.error(`PTM 216Z: missing command '${ID}'`, NS);
3373
- }
3374
- else {
3375
- return { action: lookup[ID] };
3376
- }
3377
- },
3378
- };
3379
- // export const _8840100H_water_leak_alarm: Fz.Converter = {
3380
- // cluster: "haApplianceEventsAlerts",
3381
- // type: "commandAlertsNotification",
3382
- // convert: (model, msg, publish, options, meta) => {
3383
- // const alertStatus = msg.data.aalert;
3384
- // return {
3385
- // water_leak: (alertStatus & (1 << 12)) > 0,
3386
- // };
3387
- // },
3388
- // };
3389
- exports.diyruz_freepad_clicks = {
3390
- cluster: "genMultistateInput",
3391
- type: ["readResponse", "attributeReport"],
3392
- convert: (model, msg, publish, options, meta) => {
3393
- const button = (0, utils_1.getKey)(model.endpoint(msg.device), msg.endpoint.ID);
3394
- const lookup = { 0: "hold", 1: "single", 2: "double", 3: "triple", 4: "quadruple", 255: "release" };
3395
- const clicks = msg.data.presentValue;
3396
- const action = lookup[clicks] ? lookup[clicks] : `many_${clicks}`;
3397
- return { action: `${button}_${action}` };
3398
- },
3399
- };
3400
- exports.kmpcil_res005_occupancy = {
3401
- cluster: "genBinaryInput",
3402
- type: ["attributeReport", "readResponse"],
3403
- convert: (model, msg, publish, options, meta) => {
3404
- return { occupancy: msg.data.presentValue === 1 };
3405
- },
3406
- };
3407
- exports.kmpcil_res005_on_off = {
3408
- cluster: "genBinaryOutput",
3409
- type: ["attributeReport", "readResponse"],
3410
- convert: (model, msg, publish, options, meta) => {
3411
- return { state: msg.data.presentValue === 0 ? "OFF" : "ON" };
3412
- },
3413
- };
3414
- exports.byun_smoke_false = {
3415
- cluster: "pHMeasurement",
3416
- type: ["attributeReport"],
3417
- convert: (model, msg, publish, options, meta) => {
3418
- if (msg.endpoint.ID === 1 && msg.data.measuredValue === 0) {
3419
- return { smoke: false };
3420
- }
3421
- },
3422
- };
3423
- exports.byun_smoke_true = {
3424
- cluster: "ssIasZone",
3425
- type: ["commandStatusChangeNotification"],
3426
- convert: (model, msg, publish, options, meta) => {
3427
- if (msg.endpoint.ID === 1 && msg.data.zonestatus === 33) {
3428
- return { smoke: true };
3429
- }
3430
- },
3431
- };
3432
- exports.byun_gas_false = {
3433
- cluster: 1034,
3434
- type: ["raw"],
3435
- convert: (model, msg, publish, options, meta) => {
3436
- if (msg.endpoint.ID === 1 && msg.data[0] === 24) {
3437
- return { gas: false };
3438
- }
3439
- },
3440
- };
3441
- exports.byun_gas_true = {
3442
- cluster: "ssIasZone",
3443
- type: ["commandStatusChangeNotification"],
3444
- convert: (model, msg, publish, options, meta) => {
3445
- if (msg.endpoint.ID === 1 && msg.data.zonestatus === 33) {
3446
- return { gas: true };
3447
- }
3448
- },
3449
- };
3450
- exports.legrand_binary_input_moving = {
3451
- cluster: "genBinaryInput",
3452
- type: ["attributeReport", "readResponse"],
3453
- convert: (model, msg, publish, options, meta) => {
3454
- return { action: msg.data.presentValue ? "moving" : "stopped" };
3455
- },
3456
- };
3457
- exports.legrand_binary_input_on_off = {
3458
- cluster: "genBinaryInput",
3459
- type: ["attributeReport", "readResponse"],
3460
- convert: (model, msg, publish, options, meta) => {
3461
- const multiEndpoint = model.meta?.multiEndpoint;
3462
- const property = multiEndpoint ? (0, utils_1.postfixWithEndpointName)("state", msg, model, meta) : "state";
3463
- return { [property]: msg.data.presentValue ? "ON" : "OFF" };
3464
- },
3465
- };
3466
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3467
- exports.bticino_4027C_binary_input_moving = {
3468
- cluster: "genBinaryInput",
3469
- type: ["attributeReport", "readResponse"],
3470
- options: [exposes.options.no_position_support()],
3471
- convert: (model, msg, publish, options, meta) => {
3472
- return options.no_position_support
3473
- ? { action: msg.data.presentValue ? "stopped" : "moving", position: 50 }
3474
- : { action: msg.data.presentValue ? "stopped" : "moving" };
3475
- },
3476
- };
3477
- exports.legrand_scenes = {
3478
- cluster: "genScenes",
3479
- type: "commandRecall",
3480
- convert: (model, msg, publish, options, meta) => {
3481
- const lookup = {
3482
- 65527: "enter",
3483
- 65526: "leave",
3484
- 65524: "sleep",
3485
- 65525: "wakeup",
3486
- 65518: "ambiance_I",
3487
- 65519: "ambiance_II",
3488
- 65520: "ambiance_III",
3489
- };
3490
- return { action: lookup[msg.data.groupid] ? lookup[msg.data.groupid] : "default" };
3491
- },
3492
- };
3493
- exports.legrand_power_alarm = {
3494
- cluster: "haElectricalMeasurement",
3495
- type: ["attributeReport", "readResponse"],
3496
- convert: (model, msg, publish, options, meta) => {
3497
- const payload = {};
3498
- // 0xf000 = 61440
3499
- // This attribute returns usually 2 when power is over the defined threshold.
3500
- if (msg.data["61440"] !== undefined) {
3501
- payload.power_alarm_active_value = msg.data["61440"];
3502
- payload.power_alarm_active = payload.power_alarm_active_value > 0;
3503
- }
3504
- // 0xf001 = 61441
3505
- if (msg.data["61441"] !== undefined) {
3506
- payload.power_alarm_enabled = msg.data["61441"];
3507
- }
3508
- // 0xf002 = 61442, wh = watt hour
3509
- if (msg.data["61442"] !== undefined) {
3510
- payload.power_alarm_wh_threshold = msg.data["61442"];
3511
- }
3512
- return payload;
3513
- },
3514
- };
3515
- exports.legrand_greenpower = {
3516
- cluster: "greenPower",
3517
- type: ["commandNotification", "commandCommissioningNotification"],
3518
- convert: (model, msg, publish, options, meta) => {
3519
- const commandID = msg.data.commandID;
3520
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model, msg.data.frameCounter, `${msg.device.ieeeAddr}_${commandID}`))
3521
- return;
3522
- if (commandID === 224)
3523
- return;
3524
- const lookup = {
3525
- 16: "home_arrival",
3526
- 17: "home_departure", // ZLGP14
3527
- 18: "daytime_day",
3528
- 19: "daytime_night", // ZLGP16, yes these commandIDs are lower than ZLGP15s'
3529
- 20: "press_1",
3530
- 21: "press_2",
3531
- 22: "press_3",
3532
- 23: "press_4", // ZLGP15
3533
- 34: "press_once",
3534
- 32: "press_twice", // ZLGP17, ZLGP18
3535
- 51: "down_hold", // ZLGP17, ZLGP18
3536
- 52: "stop",
3537
- 53: "up",
3538
- 54: "down", // 600087l
3539
- 55: "up_hold", // ZLGP17, ZLGP18
3540
- };
3541
- if (lookup[commandID] === undefined) {
3542
- logger_1.logger.error(`Legrand GreenPower: missing command '${commandID}'`, NS);
3543
- }
3544
- else {
3545
- return { action: lookup[commandID] };
3546
- }
3547
- },
3548
- };
3549
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3550
- exports.W2_module_carbon_monoxide = {
3551
- cluster: "ssIasZone",
3552
- type: "commandStatusChangeNotification",
3553
- convert: (model, msg, publish, options, meta) => {
3554
- const zoneStatus = msg.data.zonestatus;
3555
- return {
3556
- carbon_monoxide: (zoneStatus & (1 << 8)) > 8,
3557
- };
3558
- },
3559
- };
3560
- exports.command_status_change_notification_action = {
3561
- cluster: "ssIasZone",
3562
- type: "commandStatusChangeNotification",
3563
- convert: (model, msg, publish, options, meta) => {
3564
- const lookup = { 0: "off", 1: "single", 2: "double", 3: "hold" };
3565
- return { action: lookup[msg.data.zonestatus] };
3566
- },
3567
- };
3568
- exports.ptvo_multistate_action = {
3569
- cluster: "genMultistateInput",
3570
- type: ["attributeReport", "readResponse"],
3571
- convert: (model, msg, publish, options, meta) => {
3572
- const actionLookup = { 0: "release", 1: "single", 2: "double", 3: "tripple", 4: "hold" };
3573
- const value = msg.data.presentValue;
3574
- const action = actionLookup[value];
3575
- return { action: (0, utils_1.postfixWithEndpointName)(action, msg, model, meta) };
3576
- },
3577
- };
3578
- exports.konke_action = {
3579
- cluster: "genOnOff",
3580
- type: ["attributeReport", "readResponse"],
3581
- convert: (model, msg, publish, options, meta) => {
3582
- const value = msg.data.onOff;
3583
- const lookup = { 128: "single", 129: "double", 130: "hold" };
3584
- return lookup[value] ? { action: lookup[value] } : null;
3585
- },
3586
- };
3587
- exports.qlwz_letv8key_switch = {
3588
- cluster: "genMultistateInput",
3589
- type: ["attributeReport", "readResponse"],
3590
- convert: (model, msg, publish, options, meta) => {
3591
- const buttonLookup = { 4: "up", 2: "down", 5: "left", 3: "right", 8: "center", 1: "back", 7: "play", 6: "voice" };
3592
- const actionLookup = { 0: "hold", 1: "single", 2: "double", 3: "tripple" };
3593
- const button = buttonLookup[msg.endpoint.ID];
3594
- const action = actionLookup[msg.data.presentValue] || msg.data.presentValue;
3595
- if (button) {
3596
- return { action: `${action}_${button}` };
3597
- }
3598
- },
3599
- };
3600
- exports.keen_home_smart_vent_pressure = {
3601
- cluster: "msPressureMeasurement",
3602
- type: ["attributeReport", "readResponse"],
3603
- convert: (model, msg, publish, options, meta) => {
3604
- const pressure = msg.data.measuredValue !== undefined ? msg.data.measuredValue : Number.parseFloat(msg.data["32"]) / 1000.0;
3605
- return { pressure };
3606
- },
3607
- };
3608
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3609
- exports.U02I007C01_contact = {
3610
- cluster: "ssIasZone",
3611
- type: "commandStatusChangeNotification",
3612
- convert: (model, msg, publish, options, meta) => {
3613
- const zoneStatus = msg.data.zonestatus;
3614
- if (msg.endpoint.ID !== 1)
3615
- return;
3616
- return {
3617
- contact: !((zoneStatus & 1) > 0),
3618
- };
3619
- },
3620
- };
3621
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3622
- exports.U02I007C01_water_leak = {
3623
- cluster: "ssIasZone",
3624
- type: "commandStatusChangeNotification",
3625
- convert: (model, msg, publish, options, meta) => {
3626
- const zoneStatus = msg.data.zonestatus;
3627
- if (msg.endpoint.ID !== 2)
3628
- return;
3629
- return {
3630
- water_leak: (zoneStatus & 1) > 0,
3631
- };
3632
- },
3633
- };
3634
- exports.heiman_hcho = {
3635
- cluster: "msFormaldehyde",
3636
- type: ["attributeReport", "readResponse"],
3637
- convert: (model, msg, publish, options, meta) => {
3638
- if (msg.data.measuredValue) {
3639
- return { hcho: msg.data.measuredValue / 1000.0 };
3640
- }
3641
- },
3642
- };
3643
- exports.heiman_air_quality = {
3644
- cluster: "heimanSpecificAirQuality",
3645
- type: ["attributeReport", "readResponse"],
3646
- convert: (model, msg, publish, options, meta) => {
3647
- const result = {};
3648
- if (msg.data.batteryState) {
3649
- const lookup = {
3650
- 0: "not_charging",
3651
- 1: "charging",
3652
- 2: "charged",
3653
- };
3654
- result.battery_state = lookup[msg.data.batteryState];
3655
- }
3656
- if (msg.data.tvocMeasuredValue)
3657
- result.voc = msg.data.tvocMeasuredValue;
3658
- if (msg.data.aqiMeasuredValue)
3659
- result.aqi = msg.data.aqiMeasuredValue;
3660
- if (msg.data.pm10measuredValue)
3661
- result.pm10 = msg.data.pm10measuredValue;
3662
- return result;
3663
- },
3664
- };
3665
- exports.scenes_recall_scene_65024 = {
3666
- cluster: 65024,
3667
- type: ["raw"],
3668
- convert: (model, msg, publish, options, meta) => {
3669
- return { action: `scene_${msg.data[msg.data.length - 2] - 9}` };
3670
- },
3671
- };
3672
- exports.adeo_button_65024 = {
3673
- cluster: 65024,
3674
- type: ["raw"],
3675
- convert: (model, msg, publish, options, meta) => {
3676
- const clickMapping = { 1: "single", 2: "double", 3: "hold" };
3677
- return { action: `${clickMapping[msg.data[6]]}` };
3678
- },
3679
- };
3680
- exports.color_stop_raw = {
3681
- cluster: "lightingColorCtrl",
3682
- type: ["raw"],
3683
- convert: (model, msg, publish, options, meta) => {
3684
- const payload = { action: (0, utils_1.postfixWithEndpointName)("color_stop", msg, model, meta) };
3685
- (0, utils_1.addActionGroup)(payload, msg, model);
3686
- return payload;
3687
- },
3688
- };
3689
- exports.almond_click = {
3690
- cluster: "ssIasAce",
3691
- type: ["commandArm"],
3692
- convert: (model, msg, publish, options, meta) => {
3693
- const action = msg.data.armmode;
3694
- const lookup = { 3: "single", 0: "double", 2: "long" };
3695
- // Workaround to ignore duplicated (false) presses that
3696
- // are 100ms apart, since the button often generates
3697
- // multiple duplicated messages for a single click event.
3698
- if (!globalStore.hasValue(msg.endpoint, "since")) {
3699
- globalStore.putValue(msg.endpoint, "since", 0);
3700
- }
3701
- const now = Date.now();
3702
- const since = globalStore.getValue(msg.endpoint, "since");
3703
- if (now - since > 100 && lookup[action]) {
3704
- globalStore.putValue(msg.endpoint, "since", now);
3705
- return { action: lookup[action] };
3706
- }
3707
- },
3708
- };
3709
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3710
- exports.SAGE206612_state = {
3711
- cluster: "genOnOff",
3712
- type: ["commandOn", "commandOff"],
3713
- convert: (model, msg, publish, options, meta) => {
3714
- const timeout = 28;
3715
- if (!globalStore.hasValue(msg.endpoint, "action")) {
3716
- globalStore.putValue(msg.endpoint, "action", []);
3717
- }
3718
- const lookup = { commandOn: "bell1", commandOff: "bell2" };
3719
- const timer = setTimeout(() => globalStore.getValue(msg.endpoint, "action").pop(), timeout * 1000);
3720
- const list = globalStore.getValue(msg.endpoint, "action");
3721
- if (list.length === 0 || list.length > 4) {
3722
- list.push(timer);
3723
- return { action: lookup[msg.type] };
3724
- }
3725
- if (timeout > 0) {
3726
- list.push(timer);
3727
- }
3728
- },
3729
- };
3730
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3731
- exports.ZMCSW032D_cover_position = {
3732
- cluster: "closuresWindowCovering",
3733
- type: ["attributeReport", "readResponse"],
3734
- options: [
3735
- exposes.options.invert_cover(),
3736
- e.numeric("time_close", ea.SET).withDescription("Set the full closing time of the roller shutter (e.g. set it to 20) (value is in s)."),
3737
- e.numeric("time_open", ea.SET).withDescription("Set the full opening time of the roller shutter (e.g. set it to 21) (value is in s)."),
3738
- ],
3739
- convert: (model, msg, publish, options, meta) => {
3740
- const result = {};
3741
- const timeCoverSetMiddle = 60;
3742
- // https://github.com/Koenkk/zigbee-herdsman-converters/pull/1336
3743
- // Need to add time_close and time_open in your configuration.yaml after friendly_name (and set your time)
3744
- if (options.time_close != null && options.time_open != null) {
3745
- if (!globalStore.hasValue(msg.endpoint, "position")) {
3746
- globalStore.putValue(msg.endpoint, "position", { lastPreviousAction: -1, CurrentPosition: -1, since: false });
3747
- }
3748
- const entry = globalStore.getValue(msg.endpoint, "position");
3749
- // ignore if first action is middle and ignore action middle if previous action is middle
3750
- if (msg.data.currentPositionLiftPercentage !== undefined && msg.data.currentPositionLiftPercentage === 50) {
3751
- if ((entry.CurrentPosition === -1 && entry.lastPreviousAction === -1) || entry.lastPreviousAction === 50) {
3752
- logger_1.logger.warning("ZMCSW032D ignore action", NS);
3753
- return;
3754
- }
3755
- }
3756
- let currentPosition = entry.CurrentPosition;
3757
- const lastPreviousAction = entry.lastPreviousAction;
3758
- const deltaTimeSec = Math.floor((Date.now() - entry.since) / 1000); // convert to sec
3759
- entry.since = Date.now();
3760
- entry.lastPreviousAction = msg.data.currentPositionLiftPercentage;
3761
- if (msg.data.currentPositionLiftPercentage !== undefined && msg.data.currentPositionLiftPercentage === 50) {
3762
- if (deltaTimeSec < timeCoverSetMiddle || deltaTimeSec > timeCoverSetMiddle) {
3763
- if (lastPreviousAction === 100) {
3764
- // Open
3765
- currentPosition = currentPosition === -1 ? 0 : currentPosition;
3766
- currentPosition = currentPosition + (deltaTimeSec * 100) / Number(options.time_open);
3767
- }
3768
- else if (lastPreviousAction === 0) {
3769
- // Close
3770
- currentPosition = currentPosition === -1 ? 100 : currentPosition;
3771
- currentPosition = currentPosition - (deltaTimeSec * 100) / Number(options.time_close);
3772
- }
3773
- currentPosition = currentPosition > 100 ? 100 : currentPosition;
3774
- currentPosition = currentPosition < 0 ? 0 : currentPosition;
3775
- }
3776
- }
3777
- entry.CurrentPosition = currentPosition;
3778
- if (msg.data.currentPositionLiftPercentage !== undefined && msg.data.currentPositionLiftPercentage !== 50) {
3779
- // position cast float to int
3780
- result.position = currentPosition | 0;
3781
- }
3782
- else {
3783
- if (deltaTimeSec < timeCoverSetMiddle || deltaTimeSec > timeCoverSetMiddle) {
3784
- // position cast float to int
3785
- result.position = currentPosition | 0;
3786
- }
3787
- else {
3788
- entry.CurrentPosition = lastPreviousAction;
3789
- result.position = lastPreviousAction;
3790
- }
3791
- }
3792
- result.position = options.invert_cover ? 100 - result.position : result.position;
3793
- }
3794
- else {
3795
- // Previous solution without time_close and time_open
3796
- if (msg.data.currentPositionLiftPercentage !== undefined && msg.data.currentPositionLiftPercentage !== 50) {
3797
- const liftPercentage = msg.data.currentPositionLiftPercentage;
3798
- result.position = liftPercentage;
3799
- result.position = options.invert_cover ? 100 - result.position : result.position;
3800
- }
3801
- }
3802
- // Add the state
3803
- if ("position" in result) {
3804
- result.state = result.position === 0 ? "CLOSE" : "OPEN";
3805
- }
3806
- return result;
3807
- },
3808
- };
3809
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3810
- exports.PGC410EU_presence = {
3811
- cluster: "manuSpecificSmartThingsArrivalSensor",
3812
- type: "commandArrivalSensorNotify",
3813
- options: [exposes.options.presence_timeout()],
3814
- convert: (model, msg, publish, options, meta) => {
3815
- const useOptionsTimeout = options?.presence_timeout != null;
3816
- const timeout = useOptionsTimeout ? Number(options.presence_timeout) : 100; // 100 seconds by default
3817
- // Stop existing timer because motion is detected and set a new one.
3818
- clearTimeout(globalStore.getValue(msg.endpoint, "timer"));
3819
- const timer = setTimeout(() => publish({ presence: false }), timeout * 1000);
3820
- globalStore.putValue(msg.endpoint, "timer", timer);
3821
- return { presence: true };
3822
- },
3823
- };
3824
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3825
- exports.STS_PRS_251_presence = {
3826
- cluster: "genBinaryInput",
3827
- type: ["attributeReport", "readResponse"],
3828
- options: [exposes.options.presence_timeout()],
3829
- convert: (model, msg, publish, options, meta) => {
3830
- const useOptionsTimeout = options?.presence_timeout != null;
3831
- const timeout = useOptionsTimeout ? Number(options.presence_timeout) : 100; // 100 seconds by default
3832
- // Stop existing timer because motion is detected and set a new one.
3833
- clearTimeout(globalStore.getValue(msg.endpoint, "timer"));
3834
- const timer = setTimeout(() => publish({ presence: false }), timeout * 1000);
3835
- globalStore.putValue(msg.endpoint, "timer", timer);
3836
- return { presence: true };
3837
- },
3838
- };
3839
- exports.heiman_scenes = {
3840
- cluster: "heimanSpecificScenes",
3841
- type: ["commandAtHome", "commandGoOut", "commandCinema", "commandRepast", "commandSleep"],
3842
- convert: (model, msg, publish, options, meta) => {
3843
- const lookup = {
3844
- commandCinema: "cinema",
3845
- commandAtHome: "at_home",
3846
- commandSleep: "sleep",
3847
- commandGoOut: "go_out",
3848
- commandRepast: "repast",
3849
- };
3850
- if (lookup[msg.type] !== undefined)
3851
- return { action: lookup[msg.type] };
3852
- },
3853
- };
3854
- exports.javis_lock_report = {
3855
- cluster: "genBasic",
3856
- type: "attributeReport",
3857
- convert: (model, msg, publish, options, meta) => {
3858
- const lookup = {
3859
- 0: "pairing",
3860
- 1: "keypad",
3861
- 2: "rfid_card_unlock",
3862
- 3: "touch_unlock",
3863
- };
3864
- const utf8FromStr = (s) => {
3865
- const a = [];
3866
- for (let i = 0, enc = encodeURIComponent(s); i < enc.length;) {
3867
- if (enc[i] === "%") {
3868
- a.push(Number.parseInt(enc.substr(i + 1, 2), 16));
3869
- i += 3;
3870
- }
3871
- else {
3872
- a.push(enc.charCodeAt(i++));
3873
- }
3874
- }
3875
- return a;
3876
- };
3877
- const data = utf8FromStr(msg.data["16896"]);
3878
- clearTimeout(globalStore.getValue(msg.endpoint, "timer"));
3879
- const timer = setTimeout(() => publish({ action: "lock", state: "LOCK" }), 2 * 1000);
3880
- globalStore.putValue(msg.endpoint, "timer", timer);
3881
- return {
3882
- action: "unlock",
3883
- action_user: data[3],
3884
- action_source: data[5],
3885
- action_source_name: lookup[data[5]],
3886
- };
3887
- },
3888
- };
3889
- exports.diyruz_freepad_config = {
3890
- cluster: "genOnOffSwitchCfg",
3891
- type: ["readResponse"],
3892
- convert: (model, msg, publish, options, meta) => {
3893
- const button = (0, utils_1.getKey)(model.endpoint(msg.device), msg.endpoint.ID);
3894
- const { switchActions, switchType } = msg.data;
3895
- const switchTypesLookup = ["toggle", "momentary", "multifunction"];
3896
- const switchActionsLookup = ["on", "off", "toggle"];
3897
- return {
3898
- [`switch_type_${button}`]: switchTypesLookup[switchType],
3899
- [`switch_actions_${button}`]: switchActionsLookup[switchActions],
3900
- };
3901
- },
3902
- };
3903
- exports.diyruz_geiger = {
3904
- cluster: "msIlluminanceMeasurement",
3905
- type: ["attributeReport", "readResponse"],
3906
- convert: (model, msg, publish, options, meta) => {
3907
- return {
3908
- radioactive_events_per_minute: msg.data["61441"],
3909
- radiation_dose_per_hour: msg.data["61442"],
3910
- };
3911
- },
3912
- };
3913
- exports.diyruz_geiger_config = {
3914
- cluster: "msIlluminanceLevelSensing",
3915
- type: "readResponse",
3916
- convert: (model, msg, publish, options, meta) => {
3917
- const result = {};
3918
- if (msg.data[0xf001] !== undefined) {
3919
- result.led_feedback = ["OFF", "ON"][msg.data[0xf001]];
3920
- }
3921
- if (msg.data[0xf002] !== undefined) {
3922
- result.buzzer_feedback = ["OFF", "ON"][msg.data[0xf002]];
3923
- }
3924
- if (msg.data[0xf000] !== undefined) {
3925
- result.sensitivity = msg.data[0xf000];
3926
- }
3927
- if (msg.data[0xf003] !== undefined) {
3928
- result.sensors_count = msg.data[0xf003];
3929
- }
3930
- if (msg.data[0xf004] !== undefined) {
3931
- result.sensors_type = ["СБМ-20/СТС-5/BOI-33", "СБМ-19/СТС-6", "Others"][msg.data[0xf004]];
3932
- }
3933
- if (msg.data[0xf005] !== undefined) {
3934
- result.alert_threshold = msg.data[0xf005];
3935
- }
3936
- return result;
3937
- },
3938
- };
3939
- exports.diyruz_airsense_config_co2 = {
3940
- cluster: "msCO2",
3941
- type: "readResponse",
3942
- convert: (model, msg, publish, options, meta) => {
3943
- const result = {};
3944
- if (msg.data[0x0203] !== undefined) {
3945
- result.led_feedback = ["OFF", "ON"][msg.data[0x0203]];
3946
- }
3947
- if (msg.data[0x0202] !== undefined) {
3948
- result.enable_abc = ["OFF", "ON"][msg.data[0x0202]];
3949
- }
3950
- if (msg.data[0x0204] !== undefined) {
3951
- result.threshold1 = msg.data[0x0204];
3952
- }
3953
- if (msg.data[0x0205] !== undefined) {
3954
- result.threshold2 = msg.data[0x0205];
3955
- }
3956
- return result;
3957
- },
3958
- };
3959
- exports.diyruz_airsense_config_temp = {
3960
- cluster: "msTemperatureMeasurement",
3961
- type: "readResponse",
3962
- convert: (model, msg, publish, options, meta) => {
3963
- const result = {};
3964
- if (msg.data[0x0210] !== undefined) {
3965
- result.temperature_offset = msg.data[0x0210];
3966
- }
3967
- return result;
3968
- },
3969
- };
3970
- exports.diyruz_airsense_config_pres = {
3971
- cluster: "msPressureMeasurement",
3972
- type: "readResponse",
3973
- convert: (model, msg, publish, options, meta) => {
3974
- const result = {};
3975
- if (msg.data[0x0210] !== undefined) {
3976
- result.pressure_offset = msg.data[0x0210];
3977
- }
3978
- return result;
3979
- },
3980
- };
3981
- exports.diyruz_airsense_config_hum = {
3982
- cluster: "msRelativeHumidity",
3983
- type: "readResponse",
3984
- convert: (model, msg, publish, options, meta) => {
3985
- const result = {};
3986
- if (msg.data[0x0210] !== undefined) {
3987
- result.humidity_offset = msg.data[0x0210];
3988
- }
3989
- return result;
3990
- },
3991
- };
3992
- exports.diyruz_zintercom_config = {
3993
- cluster: "closuresDoorLock",
3994
- type: ["attributeReport", "readResponse"],
3995
- convert: (model, msg, publish, options, meta) => {
3996
- const result = {};
3997
- if (msg.data[0x0050] !== undefined) {
3998
- result.state = ["idle", "ring", "talk", "open", "drop"][msg.data[0x0050]];
3999
- }
4000
- if (msg.data[0x0051] !== undefined) {
4001
- result.mode = ["never", "once", "always", "drop"][msg.data[0x0051]];
4002
- }
4003
- if (msg.data[0x0052] !== undefined) {
4004
- result.sound = ["OFF", "ON"][msg.data[0x0052]];
4005
- }
4006
- if (msg.data[0x0053] !== undefined) {
4007
- result.time_ring = msg.data[0x0053];
4008
- }
4009
- if (msg.data[0x0054] !== undefined) {
4010
- result.time_talk = msg.data[0x0054];
4011
- }
4012
- if (msg.data[0x0055] !== undefined) {
4013
- result.time_open = msg.data[0x0055];
4014
- }
4015
- if (msg.data[0x0057] !== undefined) {
4016
- result.time_bell = msg.data[0x0057];
4017
- }
4018
- if (msg.data[0x0056] !== undefined) {
4019
- result.time_report = msg.data[0x0056];
4020
- }
4021
- return result;
4022
- },
4023
- };
4024
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4025
- exports.CC2530ROUTER_led = {
4026
- cluster: "genOnOff",
4027
- type: ["attributeReport", "readResponse"],
4028
- convert: (model, msg, publish, options, meta) => {
4029
- return { led: msg.data.onOff === 1 };
4030
- },
4031
- };
4032
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4033
- exports.CC2530ROUTER_meta = {
4034
- cluster: "genBinaryValue",
4035
- type: ["attributeReport", "readResponse"],
4036
- convert: (model, msg, publish, options, meta) => {
4037
- const data = msg.data;
4038
- return {
4039
- description: data.description,
4040
- type: data.inactiveText,
4041
- rssi: data.presentValue,
4042
- };
4043
- },
4044
- };
4045
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4046
- exports.KAMI_contact = {
4047
- cluster: "ssIasZone",
4048
- type: ["raw"],
4049
- convert: (model, msg, publish, options, meta) => {
4050
- return { contact: msg.data[7] === 0 };
4051
- },
4052
- };
4053
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4054
- exports.KAMI_occupancy = {
4055
- cluster: "msOccupancySensing",
4056
- type: ["raw"],
4057
- convert: (model, msg, publish, options, meta) => {
4058
- if (msg.data[7] === 1) {
4059
- return { action: "motion" };
4060
- }
4061
- },
4062
- };
4063
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4064
- exports.DNCKAT_S00X_buttons = {
4065
- cluster: "genOnOff",
4066
- type: ["attributeReport", "readResponse"],
4067
- convert: (model, msg, publish, options, meta) => {
4068
- const action = msg.data.onOff === 1 ? "release" : "hold";
4069
- return { action: (0, utils_1.postfixWithEndpointName)(action, msg, model, meta) };
4070
- },
4071
- };
4072
- exports.hue_motion_sensitivity = {
4073
- cluster: "msOccupancySensing",
4074
- type: ["attributeReport", "readResponse"],
4075
- convert: (model, msg, publish, options, meta) => {
4076
- if (msg.data["48"] !== undefined) {
4077
- const lookup = ["low", "medium", "high", "very_high", "max"];
4078
- return { motion_sensitivity: lookup[msg.data["48"]] };
4079
- }
4080
- },
4081
- };
4082
- exports.hue_motion_led_indication = {
4083
- cluster: "genBasic",
4084
- type: ["attributeReport", "readResponse"],
4085
- convert: (model, msg, publish, options, meta) => {
4086
- if (msg.data["51"] !== undefined) {
4087
- return { led_indication: msg.data["51"] === 1 };
4088
- }
4089
- },
4090
- };
4091
- exports.hue_wall_switch_device_mode = {
4092
- cluster: "genBasic",
4093
- type: ["attributeReport", "readResponse"],
4094
- convert: (model, msg, publish, options, meta) => {
4095
- if (msg.data["52"] !== undefined) {
4096
- const values = ["single_rocker", "single_push_button", "dual_rocker", "dual_push_button"];
4097
- return { device_mode: values[msg.data["52"]] };
4098
- }
4099
- },
4100
- };
4101
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4102
- exports.CCTSwitch_D0001_levelctrl = {
4103
- cluster: "genLevelCtrl",
4104
- type: ["commandMoveToLevel", "commandMoveToLevelWithOnOff", "commandMove", "commandStop"],
4105
- convert: (model, msg, publish, options, meta) => {
4106
- const payload = {};
4107
- if (msg.type === "commandMove") {
4108
- (0, node_assert_1.default)("movemode" in msg.data);
4109
- const direction = msg.data.movemode === 1 ? "down" : "up";
4110
- payload.action = `brightness_${direction}_hold`;
4111
- globalStore.putValue(msg.endpoint, "direction", direction);
4112
- globalStore.putValue(msg.endpoint, "start", Date.now());
4113
- payload.rate = msg.data.rate;
4114
- payload.action_rate = msg.data.rate;
4115
- }
4116
- else if (msg.type === "commandStop") {
4117
- const direction = globalStore.getValue(msg.endpoint, "direction");
4118
- const duration = Date.now() - globalStore.getValue(msg.endpoint, "start");
4119
- payload.action = `brightness_${direction}_release`;
4120
- payload.duration = duration;
4121
- payload.action_duration = duration;
4122
- }
4123
- else {
4124
- // wrap the messages from button2 and button4 into a single function
4125
- // button2 always sends "commandMoveToLevel"
4126
- // button4 sends two messages, with "commandMoveToLevelWithOnOff" coming first in the sequence
4127
- // so that's the one we key off of to indicate "button4". we will NOT print it in that case,
4128
- // instead it will be returned as part of the second sequence with
4129
- // CCTSwitch_D0001_move_to_colortemp_recall below.
4130
- let clk = "brightness";
4131
- let cmd = null;
4132
- (0, node_assert_1.default)("level" in msg.data);
4133
- payload.action_brightness = msg.data.level;
4134
- payload.action_transition = msg.data.transtime / 10.0;
4135
- payload.brightness = msg.data.level;
4136
- payload.transition = msg.data.transtime / 10.0;
4137
- if (msg.type === "commandMoveToLevel") {
4138
- // pressing the brightness button increments/decrements from 13-254.
4139
- // when it reaches the end (254) it will start decrementing by a step,
4140
- // and vice versa.
4141
- const direction = msg.data.level > globalStore.getValue(msg.endpoint, "last_brightness") ? "up" : "down";
4142
- cmd = `${clk}_${direction}`;
4143
- globalStore.putValue(msg.endpoint, "last_brightness", msg.data.level);
4144
- }
4145
- else if (msg.type === "commandMoveToLevelWithOnOff") {
4146
- // This is the 'start' of the 4th button sequence.
4147
- clk = "memory";
4148
- globalStore.putValue(msg.endpoint, "last_move_level", msg.data.level);
4149
- globalStore.putValue(msg.endpoint, "last_clk", clk);
4150
- }
4151
- if (clk !== "memory") {
4152
- globalStore.putValue(msg.endpoint, "last_seq", msg.meta.zclTransactionSequenceNumber);
4153
- globalStore.putValue(msg.endpoint, "last_clk", clk);
4154
- payload.action = cmd;
4155
- }
4156
- }
4157
- return payload;
4158
- },
4159
- };
4160
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4161
- exports.CCTSwitch_D0001_lighting = {
4162
- cluster: "lightingColorCtrl",
4163
- type: ["commandMoveToColorTemp", "commandMoveColorTemp"],
4164
- convert: (model, msg, publish, options, meta) => {
4165
- const payload = {};
4166
- if (msg.type === "commandMoveColorTemp") {
4167
- (0, node_assert_1.default)("movemode" in msg.data);
4168
- const clk = "colortemp";
4169
- payload.rate = msg.data.rate;
4170
- payload.action_rate = msg.data.rate;
4171
- if (msg.data.movemode === 0) {
4172
- const direction = globalStore.getValue(msg.endpoint, "direction");
4173
- const duration = Date.now() - globalStore.getValue(msg.endpoint, "start");
4174
- payload.action = `${clk}_${direction}_release`;
4175
- payload.duration = duration;
4176
- payload.action_duration = duration;
4177
- }
4178
- else {
4179
- const direction = msg.data.movemode === 3 ? "down" : "up";
4180
- payload.action = `${clk}_${direction}_hold`;
4181
- payload.rate = msg.data.rate;
4182
- payload.action_rate = msg.data.rate;
4183
- // store button and start moment
4184
- globalStore.putValue(msg.endpoint, "direction", direction);
4185
- globalStore.putValue(msg.endpoint, "start", Date.now());
4186
- }
4187
- }
4188
- else {
4189
- // both button3 and button4 send the command "commandMoveToColorTemp"
4190
- // in order to distinguish between the buttons, use the sequence number and the previous command
4191
- // to determine if this message was immediately preceded by "commandMoveToLevelWithOnOff"
4192
- // if this command follows a "commandMoveToLevelWithOnOff", then it's actually button4's second message
4193
- // and we can ignore it entirely
4194
- const lastClk = globalStore.getValue(msg.endpoint, "last_clk");
4195
- const lastSeq = globalStore.getValue(msg.endpoint, "last_seq");
4196
- const seq = msg.meta.zclTransactionSequenceNumber;
4197
- let clk = "colortemp";
4198
- (0, node_assert_1.default)("colortemp" in msg.data);
4199
- payload.color_temp = msg.data.colortemp;
4200
- payload.transition = msg.data.transtime / 10.0;
4201
- payload.action_color_temp = msg.data.colortemp;
4202
- payload.action_transition = msg.data.transtime / 10.0;
4203
- // because the remote sends two commands for button4, we need to look at the previous command and
4204
- // see if it was the recognized start command for button4 - if so, ignore this second command,
4205
- // because it's not really button3, it's actually button4
4206
- if (lastClk === "memory") {
4207
- payload.action = "recall";
4208
- payload.brightness = globalStore.getValue(msg.endpoint, "last_move_level");
4209
- payload.action_brightness = globalStore.getValue(msg.endpoint, "last_move_level");
4210
- // ensure the "last" message was really the message prior to this one
4211
- // accounts for missed messages (gap >1) and for the remote's rollover from 127 to 0
4212
- if ((seq === 0 && lastSeq === 127) || seq - lastSeq === 1) {
4213
- clk = null;
4214
- }
4215
- }
4216
- else {
4217
- // pressing the color temp button increments/decrements from 153-370K.
4218
- // when it reaches the end (370) it will start decrementing by a step,
4219
- // and vice versa.
4220
- const direction = msg.data.colortemp > globalStore.getValue(msg.endpoint, "last_color_temp") ? "up" : "down";
4221
- const cmd = `${clk}_${direction}`;
4222
- payload.action = cmd;
4223
- globalStore.putValue(msg.endpoint, "last_color_temp", msg.data.colortemp);
4224
- }
4225
- if (clk != null) {
4226
- globalStore.putValue(msg.endpoint, "last_seq", msg.meta.zclTransactionSequenceNumber);
4227
- globalStore.putValue(msg.endpoint, "last_clk", clk);
4228
- }
4229
- }
4230
- return payload;
4231
- },
4232
- };
4233
- exports.hue_tap = {
4234
- cluster: "greenPower",
4235
- type: ["commandNotification", "commandCommissioningNotification"],
4236
- convert: (model, msg, publish, options, meta) => {
4237
- const commandID = msg.data.commandID;
4238
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model, msg.data.frameCounter, `${msg.device.ieeeAddr}_${commandID}`))
4239
- return;
4240
- if (commandID === 224)
4241
- return;
4242
- const lookup = {
4243
- 34: "press_1",
4244
- 16: "press_2",
4245
- 17: "press_3",
4246
- 18: "press_4",
4247
- // Actions below are never generated by a Hue Tap but by a PMT 215Z
4248
- // https://github.com/Koenkk/zigbee2mqtt/issues/18088
4249
- 98: "press_3_and_4",
4250
- 99: "release_3_and_4",
4251
- 100: "press_1_and_2",
4252
- 101: "release_1_and_2",
4253
- };
4254
- if (lookup[commandID] === undefined) {
4255
- logger_1.logger.error(`Hue Tap: missing command '${commandID}'`, NS);
4256
- }
4257
- else {
4258
- return { action: lookup[commandID] };
4259
- }
4260
- },
4261
- };
4262
- exports.tuya_relay_din_led_indicator = {
4263
- cluster: "genOnOff",
4264
- type: ["attributeReport", "readResponse"],
4265
- convert: (model, msg, publish, options, meta) => {
4266
- const property = 0x8001;
4267
- if (msg.data[property] !== undefined) {
4268
- const dict = { 0: "off", 1: "on_off", 2: "off_on" };
4269
- const value = msg.data[property];
4270
- if (dict[value] !== undefined) {
4271
- return { [(0, utils_1.postfixWithEndpointName)("indicator_mode", msg, model, meta)]: dict[value] };
4272
- }
4273
- }
4274
- },
4275
- };
4276
- exports.ias_keypad = {
4277
- cluster: "ssIasZone",
4278
- type: "commandStatusChangeNotification",
4279
- convert: (model, msg, publish, options, meta) => {
4280
- const zoneStatus = msg.data.zonestatus;
4281
- return {
4282
- tamper: (zoneStatus & (1 << 2)) > 0,
4283
- battery_low: (zoneStatus & (1 << 3)) > 0,
4284
- restore_reports: (zoneStatus & (1 << 5)) > 0,
4285
- };
4286
- },
4287
- };
4288
- exports.itcmdr_clicks = {
4289
- cluster: "genMultistateInput",
4290
- type: ["readResponse", "attributeReport"],
4291
- convert: (model, msg, publish, options, meta) => {
4292
- const lookup = { 0: "hold", 1: "single", 2: "double", 3: "triple", 4: "quadruple", 255: "release" };
4293
- const clicks = msg.data.presentValue;
4294
- const action = lookup[clicks] ? lookup[clicks] : "many";
4295
- return { action };
4296
- },
4297
- };
4298
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4299
- exports.ZB003X_attr = {
4300
- cluster: "ssIasZone",
4301
- type: ["attributeReport", "readResponse"],
4302
- convert: (model, msg, publish, options, meta) => {
4303
- const data = msg.data;
4304
- const senslookup = { 0: "low", 1: "medium", 2: "high" };
4305
- const keeptimelookup = { 0: 0, 1: 30, 2: 60, 3: 120, 4: 240, 5: 480 };
4306
- if (data && data.currentZoneSensitivityLevel !== undefined) {
4307
- const value = data.currentZoneSensitivityLevel;
4308
- return { sensitivity: senslookup[value] };
4309
- }
4310
- if (data && data["61441"] !== undefined) {
4311
- const value = data["61441"];
4312
- return { keep_time: keeptimelookup[value] };
4313
- }
4314
- },
4315
- };
4316
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4317
- exports.ZB003X_occupancy = {
4318
- cluster: "ssIasZone",
4319
- type: "commandStatusChangeNotification",
4320
- convert: (model, msg, publish, options, meta) => {
4321
- const zoneStatus = msg.data.zonestatus;
4322
- return { occupancy: (zoneStatus & 1) > 0, tamper: (zoneStatus & 4) > 0 };
4323
- },
4324
- };
4325
- exports.idlock = {
4326
- cluster: "closuresDoorLock",
4327
- type: ["attributeReport", "readResponse"],
4328
- convert: (model, msg, publish, options, meta) => {
4329
- const result = {};
4330
- if (0x4000 in msg.data) {
4331
- result.master_pin_mode = msg.data[0x4000] === 1;
4332
- }
4333
- if (0x4001 in msg.data) {
4334
- result.rfid_enable = msg.data[0x4001] === 1;
4335
- }
4336
- if (0x4003 in msg.data) {
4337
- const lookup = {
4338
- 0: "deactivated",
4339
- 1: "random_pin_1x_use",
4340
- 5: "random_pin_1x_use",
4341
- 6: "random_pin_24_hours",
4342
- 9: "random_pin_24_hours",
4343
- };
4344
- result.service_mode = lookup[msg.data[0x4003]];
4345
- }
4346
- if (0x4004 in msg.data) {
4347
- const lookup = { 0: "auto_off_away_off", 1: "auto_on_away_off", 2: "auto_off_away_on", 3: "auto_on_away_on" };
4348
- result.lock_mode = lookup[msg.data[0x4004]];
4349
- }
4350
- if (0x4005 in msg.data) {
4351
- result.relock_enabled = msg.data[0x4005] === 1;
4352
- }
4353
- return result;
4354
- },
4355
- };
4356
- exports.idlock_fw = {
4357
- cluster: "genBasic",
4358
- type: ["attributeReport", "readResponse"],
4359
- convert: (model, msg, publish, options, meta) => {
4360
- const result = {};
4361
- if (0x5000 in msg.data) {
4362
- result.idlock_lock_fw = msg.data[0x5000];
4363
- }
4364
- return result;
4365
- },
4366
- };
4367
- exports.schneider_ui_action = {
4368
- cluster: "wiserDeviceInfo",
4369
- type: "attributeReport",
4370
- convert: (model, msg, publish, options, meta) => {
4371
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model))
4372
- return;
4373
- const data = msg.data.deviceInfo.split(",");
4374
- if (data[0] === "UI" && data[1]) {
4375
- const result = { action: utils.toSnakeCase(data[1]) };
4376
- let screenAwake = globalStore.getValue(msg.endpoint, "screenAwake");
4377
- screenAwake = screenAwake !== undefined ? screenAwake : false;
4378
- const keypadLockedNumber = Number(msg.endpoint.getClusterAttributeValue("hvacUserInterfaceCfg", "keypadLockout"));
4379
- const keypadLocked = keypadLockedNumber !== undefined ? keypadLockedNumber !== 0 : false;
4380
- // Emulate UI temperature update
4381
- if (data[1] === "ScreenWake") {
4382
- globalStore.putValue(msg.endpoint, "screenAwake", true);
4383
- }
4384
- else if (data[1] === "ScreenSleep") {
4385
- globalStore.putValue(msg.endpoint, "screenAwake", false);
4386
- }
4387
- else if (screenAwake && !keypadLocked) {
4388
- let occupiedHeatingSetpoint = Number(msg.endpoint.getClusterAttributeValue("hvacThermostat", "occupiedHeatingSetpoint"));
4389
- occupiedHeatingSetpoint = occupiedHeatingSetpoint != null ? occupiedHeatingSetpoint : 400;
4390
- if (data[1] === "ButtonPressMinusDown") {
4391
- occupiedHeatingSetpoint -= 50;
4392
- }
4393
- else if (data[1] === "ButtonPressPlusDown") {
4394
- occupiedHeatingSetpoint += 50;
4395
- }
4396
- msg.endpoint.saveClusterAttributeKeyValue("hvacThermostat", { occupiedHeatingSetpoint: occupiedHeatingSetpoint });
4397
- result.occupied_heating_setpoint = occupiedHeatingSetpoint / 100;
4398
- }
4399
- return result;
4400
- }
4401
- },
4402
- };
4403
- exports.schneider_temperature = {
4404
- cluster: "msTemperatureMeasurement",
4405
- type: ["attributeReport", "readResponse"],
4406
- convert: (model, msg, publish, options, meta) => {
4407
- const temperature = msg.data.measuredValue / 100.0;
4408
- const property = (0, utils_1.postfixWithEndpointName)("local_temperature", msg, model, meta);
4409
- return { [property]: temperature };
4410
- },
4411
- };
4412
- exports.wiser_smart_thermostat_client = {
4413
- cluster: "hvacThermostat",
4414
- type: "read",
4415
- convert: async (model, msg, publish, options, meta) => {
4416
- const response = {};
4417
- if (msg.data[0] === 0xe010) {
4418
- // Zone Mode
4419
- const lookup = { manual: 1, schedule: 2, energy_saver: 3, holiday: 6 };
4420
- const zonemodeNum = meta.state.zone_mode ? lookup[meta.state.zone_mode] : 1;
4421
- response[0xe010] = { value: zonemodeNum, type: 0x30 };
4422
- await msg.endpoint.readResponse(msg.cluster, msg.meta.zclTransactionSequenceNumber, response, { srcEndpoint: 11 });
4423
- }
4424
- },
4425
- };
4426
- exports.wiser_smart_setpoint_command_client = {
4427
- cluster: "hvacThermostat",
4428
- type: ["commandWiserSmartSetSetpoint"],
4429
- convert: (model, msg, publish, options, meta) => {
4430
- const attribute = {};
4431
- const result = {};
4432
- // The UI client on the thermostat also updates the server, so no need to readback/send again on next sync.
4433
- // This also ensures the next client read of setpoint is in sync with the latest commanded value.
4434
- attribute.occupiedHeatingSetpoint = msg.data.setpoint;
4435
- msg.endpoint.saveClusterAttributeKeyValue("hvacThermostat", attribute);
4436
- result.occupied_heating_setpoint = msg.data.setpoint / 100.0;
4437
- logger_1.logger.debug(`received wiser setpoint command with value: '${msg.data.setpoint}'`, NS);
4438
- return result;
4439
- },
4440
- };
4441
- exports.rc_110_level_to_scene = {
4442
- cluster: "genLevelCtrl",
4443
- type: ["commandMoveToLevel", "commandMoveToLevelWithOnOff"],
4444
- convert: (model, msg, publish, options, meta) => {
4445
- const scenes = { 2: "1", 52: "2", 102: "3", 153: "4", 194: "5", 254: "6" };
4446
- return { action: `scene_${scenes[msg.data.level]}` };
4447
- },
4448
- };
4449
- exports.heiman_doorbell_button = {
4450
- cluster: "ssIasZone",
4451
- type: "commandStatusChangeNotification",
4452
- convert: (model, msg, publish, options, meta) => {
4453
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model))
4454
- return;
4455
- const lookup = {
4456
- 32768: "pressed",
4457
- 32772: "pressed",
4458
- };
4459
- const zoneStatus = msg.data.zonestatus;
4460
- return {
4461
- action: lookup[zoneStatus],
4462
- tamper: (zoneStatus & (1 << 2)) > 0,
4463
- battery_low: (zoneStatus & (1 << 3)) > 0,
4464
- };
4465
- },
4466
- };
4467
- exports.sihas_people_cnt = {
4468
- cluster: "genAnalogInput",
4469
- type: ["attributeReport", "readResponse"],
4470
- convert: (model, msg, publish, options, meta) => {
4471
- const lookup = { "0": "idle", "1": "in", "2": "out" };
4472
- const value = (0, utils_1.precisionRound)(msg.data.presentValue, 1);
4473
- const people = (0, utils_1.precisionRound)(msg.data.presentValue, 0);
4474
- let result = null;
4475
- if (value <= 80) {
4476
- result = { people: people, status: lookup[(value * 10) % 10] };
4477
- return result;
4478
- }
4479
- },
4480
- };
4481
- exports.sihas_action = {
4482
- cluster: "genOnOff",
4483
- type: ["commandOn", "commandOff", "commandToggle"],
4484
- convert: (model, msg, publish, options, meta) => {
4485
- const lookup = { commandToggle: "long", commandOn: "double", commandOff: "single" };
4486
- let buttonMapping = null;
4487
- if (model.model === "SBM300ZB2") {
4488
- buttonMapping = { 1: "1", 2: "2" };
4489
- }
4490
- else if (model.model === "SBM300ZB3") {
4491
- buttonMapping = { 1: "1", 2: "2", 3: "3" };
4492
- }
4493
- else if (model.model === "SBM300ZB4") {
4494
- buttonMapping = { 1: "1", 2: "2", 3: "3", 4: "4" };
4495
- }
4496
- else if (model.model === "SBM300ZC2") {
4497
- buttonMapping = { 1: "1", 2: "2" };
4498
- }
4499
- else if (model.model === "SBM300ZC3") {
4500
- buttonMapping = { 1: "1", 2: "2", 3: "3" };
4501
- }
4502
- else if (model.model === "SBM300ZC4") {
4503
- buttonMapping = { 1: "1", 2: "2", 3: "3", 4: "4" };
4504
- }
4505
- else if (model.model === "MSM-300ZB") {
4506
- buttonMapping = { 1: "1", 2: "2", 3: "3", 4: "4" };
4507
- }
4508
- else if (model.model === "SQM300ZC4") {
4509
- buttonMapping = { 1: "1", 2: "2", 3: "3", 4: "4" };
4510
- }
4511
- const button = buttonMapping ? `${buttonMapping[msg.endpoint.ID]}_` : "";
4512
- return { action: `${button}${lookup[msg.type]}` };
4513
- },
4514
- };
4515
- exports.tuya_operation_mode = {
4516
- cluster: "genOnOff",
4517
- type: ["attributeReport", "readResponse"],
4518
- convert: (model, msg, publish, options, meta) => {
4519
- if (msg.data.tuyaOperationMode !== undefined) {
4520
- const value = msg.data.tuyaOperationMode;
4521
- const lookup = { 0: "command", 1: "event" };
4522
- return { operation_mode: lookup[value] };
4523
- }
4524
- },
4525
- };
4526
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4527
- exports.sunricher_switch2801K2 = {
4528
- cluster: "greenPower",
4529
- type: ["commandNotification", "commandCommissioningNotification"],
4530
- convert: (model, msg, publish, options, meta) => {
4531
- const commandID = msg.data.commandID;
4532
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model, msg.data.frameCounter, `${msg.device.ieeeAddr}_${commandID}`))
4533
- return;
4534
- if (commandID === 224)
4535
- return;
4536
- const lookup = { 33: "press_on", 32: "press_off", 52: "release", 53: "hold_on", 54: "hold_off" };
4537
- if (lookup[commandID] === undefined) {
4538
- logger_1.logger.error(`Sunricher: missing command '${commandID}'`, NS);
4539
- }
4540
- else {
4541
- return { action: lookup[commandID] };
4542
- }
4543
- },
4544
- };
4545
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4546
- exports.sunricher_switch2801K4 = {
4547
- cluster: "greenPower",
4548
- type: ["commandNotification", "commandCommissioningNotification"],
4549
- convert: (model, msg, publish, options, meta) => {
4550
- const commandID = msg.data.commandID;
4551
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model, msg.data.frameCounter, `${msg.device.ieeeAddr}_${commandID}`))
4552
- return;
4553
- if (commandID === 224)
4554
- return;
4555
- const lookup = {
4556
- 33: "press_on",
4557
- 32: "press_off",
4558
- 55: "press_high",
4559
- 56: "press_low",
4560
- 53: "hold_high",
4561
- 54: "hold_low",
4562
- 52: "release",
4563
- };
4564
- if (lookup[commandID] === undefined) {
4565
- logger_1.logger.error(`Sunricher: missing command '${commandID}'`, NS);
4566
- }
4567
- else {
4568
- return { action: lookup[commandID] };
4569
- }
4570
- },
4571
- };
4572
- exports.command_stop_move_raw = {
4573
- cluster: "lightingColorCtrl",
4574
- type: "raw",
4575
- convert: (model, msg, publish, options, meta) => {
4576
- // commandStopMove without params
4577
- if (msg.data[2] !== 71)
4578
- return;
4579
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model))
4580
- return;
4581
- const movestop = "stop";
4582
- const action = (0, utils_1.postfixWithEndpointName)(`hue_${movestop}`, msg, model, meta);
4583
- const payload = { action };
4584
- (0, utils_1.addActionGroup)(payload, msg, model);
4585
- return payload;
4586
- },
4587
- };
4588
- exports.tuya_multi_action = {
4589
- cluster: "genOnOff",
4590
- type: ["commandTuyaAction", "commandTuyaAction2"],
4591
- convert: (model, msg, publish, options, meta) => {
4592
- if ((0, utils_1.hasAlreadyProcessedMessage)(msg, model))
4593
- return;
4594
- // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
4595
- let action;
4596
- if (msg.type === "commandTuyaAction") {
4597
- const lookup = { 0: "single", 1: "double", 2: "hold" };
4598
- action = lookup[msg.data.value];
4599
- }
4600
- else if (msg.type === "commandTuyaAction2") {
4601
- const lookup = { 0: "rotate_right", 1: "rotate_left" };
4602
- action = lookup[msg.data.value];
4603
- }
4604
- return { action };
4605
- },
4606
- };
4607
- exports.led_on_motion = {
4608
- cluster: "ssIasZone",
4609
- type: ["attributeReport", "readResponse"],
4610
- convert: (model, msg, publish, options, meta) => {
4611
- const result = {};
4612
- if (0x4000 in msg.data) {
4613
- result.led_on_motion = msg.data[0x4000] === 1;
4614
- }
4615
- return result;
4616
- },
4617
- };
4618
- exports.hw_version = {
4619
- cluster: "genBasic",
4620
- type: ["attributeReport", "readResponse"],
4621
- convert: (model, msg, publish, options, meta) => {
4622
- const result = {};
4623
- if (msg.data.hwVersion !== undefined)
4624
- result.hw_version = msg.data.hwVersion;
4625
- return result;
4626
- },
4627
- };
4628
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4629
- exports.SNZB02_temperature = {
4630
- cluster: "msTemperatureMeasurement",
4631
- type: ["attributeReport", "readResponse"],
4632
- convert: (model, msg, publish, options, meta) => {
4633
- const temperature = msg.data.measuredValue / 100.0;
4634
- // https://github.com/Koenkk/zigbee2mqtt/issues/13640
4635
- // SNZB-02 reports stranges values sometimes
4636
- if (temperature > -33 && temperature < 100) {
4637
- const property = (0, utils_1.postfixWithEndpointName)("temperature", msg, model, meta);
4638
- return { [property]: temperature };
4639
- }
4640
- },
4641
- };
4642
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4643
- exports.SNZB02_humidity = {
4644
- cluster: "msRelativeHumidity",
4645
- type: ["attributeReport", "readResponse"],
4646
- convert: (model, msg, publish, options, meta) => {
4647
- const humidity = msg.data.measuredValue / 100.0;
4648
- // https://github.com/Koenkk/zigbee2mqtt/issues/13640
4649
- // SNZB-02 reports stranges values sometimes
4650
- if (humidity >= 0 && humidity <= 99.75) {
4651
- return { humidity };
4652
- }
4653
- },
4654
- };
4655
- exports.awox_colors = {
4656
- cluster: "lightingColorCtrl",
4657
- type: ["raw"],
4658
- convert: (model, msg, publish, options, meta) => {
4659
- const buffer = msg.data;
4660
- const commonForColors = buffer[0] === 17 && buffer[2] === 48 && buffer[3] === 0 && buffer[5] === 8 && buffer[6] === 0;
4661
- let color = null;
4662
- if (commonForColors && [255, 254].includes(buffer[4])) {
4663
- color = "red";
4664
- }
4665
- else if (commonForColors && [42, 41].includes(buffer[4])) {
4666
- color = "yellow";
4667
- }
4668
- else if (commonForColors && [85, 84].includes(buffer[4])) {
4669
- color = "green";
4670
- }
4671
- else if (commonForColors && [170, 169].includes(buffer[4])) {
4672
- color = "blue";
4673
- }
4674
- if (color != null) {
4675
- return { action: color, action_group: msg.groupID };
4676
- }
4677
- },
4678
- };
4679
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4680
- exports.awox_refreshColored = {
4681
- cluster: "lightingColorCtrl",
4682
- type: ["commandMoveHue"],
4683
- convert: (model, msg, publish, options, meta) => {
4684
- if (msg.data.movemode === 1 && msg.data.rate === 12) {
4685
- return { action: "refresh_colored", action_group: msg.groupID };
4686
- }
4687
- },
4688
- };
4689
- exports.awox_refresh = {
4690
- cluster: "genLevelCtrl",
4691
- type: ["raw"],
4692
- convert: (model, msg, publish, options, meta) => {
4693
- const buffer = msg.data;
4694
- const isRefresh = buffer[0] === 17 && buffer[2] === 16 && (buffer[3] === 1 || buffer[3] === 0) && buffer[4] === 1;
4695
- const isRefreshLong = buffer[0] === 17 && buffer[2] === 16 && buffer[3] === 1 && buffer[4] === 2;
4696
- if (isRefresh) {
4697
- return { action: "refresh", action_group: msg.groupID };
4698
- }
4699
- if (isRefreshLong) {
4700
- return { action: "refresh_long", action_group: msg.groupID };
2148
+ const buffer = msg.data;
2149
+ const isRefresh = buffer[0] === 17 && buffer[2] === 16 && (buffer[3] === 1 || buffer[3] === 0) && buffer[4] === 1;
2150
+ const isRefreshLong = buffer[0] === 17 && buffer[2] === 16 && buffer[3] === 1 && buffer[4] === 2;
2151
+ if (isRefresh) {
2152
+ return { action: "refresh", action_group: msg.groupID };
2153
+ }
2154
+ if (isRefreshLong) {
2155
+ return { action: "refresh_long", action_group: msg.groupID };
4701
2156
  }
4702
2157
  },
4703
2158
  };
@@ -4864,44 +2319,6 @@ exports.command_arm_with_transaction = {
4864
2319
  return payload;
4865
2320
  },
4866
2321
  };
4867
- exports.metering_datek = {
4868
- cluster: "seMetering",
4869
- type: ["attributeReport", "readResponse"],
4870
- convert: (model, msg, publish, options, meta) => {
4871
- const result = exports.metering.convert(model, msg, publish, options, meta);
4872
- // Filter incorrect 0 energy values reported by the device:
4873
- // https://github.com/Koenkk/zigbee2mqtt/issues/7852
4874
- if (result && result.energy === 0) {
4875
- delete result.energy;
4876
- }
4877
- return result;
4878
- },
4879
- };
4880
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4881
- exports.EKO09738_metering = {
4882
- /**
4883
- * Elko EKO09738 and EKO09716 reports power in mW, scale to W
4884
- */
4885
- cluster: "seMetering",
4886
- type: ["attributeReport", "readResponse"],
4887
- convert: (model, msg, publish, options, meta) => {
4888
- const result = exports.metering.convert(model, msg, publish, options, meta);
4889
- if (result && result.power !== undefined) {
4890
- result.power /= 1000;
4891
- }
4892
- return result;
4893
- },
4894
- };
4895
- exports.command_on_presence = {
4896
- cluster: "genOnOff",
4897
- type: "commandOn",
4898
- convert: (model, msg, publish, options, meta) => {
4899
- const newMsg = { ...msg, type: "commandCheckin", data: {} };
4900
- const payload1 = exports.checkin_presence.convert(model, newMsg, publish, options, meta);
4901
- const payload2 = exports.command_on.convert(model, msg, publish, options, meta);
4902
- return { ...payload1, ...payload2 };
4903
- },
4904
- };
4905
2322
  exports.ias_ace_occupancy_with_timeout = {
4906
2323
  cluster: "ssIasAce",
4907
2324
  type: "commandGetPanelStatus",
@@ -4911,282 +2328,4 @@ exports.ias_ace_occupancy_with_timeout = {
4911
2328
  return exports.occupancy_with_timeout.convert(model, newMsg, publish, options, meta);
4912
2329
  },
4913
2330
  };
4914
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
4915
- exports.SP600_power = {
4916
- cluster: "seMetering",
4917
- type: ["attributeReport", "readResponse"],
4918
- convert: (model, msg, publish, options, meta) => {
4919
- if (meta.device.dateCode === "20160120") {
4920
- // Cannot use metering, divisor/multiplier is not according to ZCL.
4921
- // https://github.com/Koenkk/zigbee2mqtt/issues/2233
4922
- // https://github.com/Koenkk/zigbee-herdsman-converters/issues/915
4923
- const result = {};
4924
- if (msg.data.instantaneousDemand !== undefined) {
4925
- result.power = msg.data.instantaneousDemand;
4926
- }
4927
- // Summation is reported in Watthours
4928
- if (msg.data.currentSummDelivered !== undefined) {
4929
- const value = msg.data.currentSummDelivered;
4930
- result.energy = value / 1000.0;
4931
- }
4932
- return result;
4933
- }
4934
- return exports.metering.convert(model, msg, publish, options, meta);
4935
- },
4936
- };
4937
- exports.stelpro_thermostat = {
4938
- cluster: "hvacThermostat",
4939
- type: ["attributeReport", "readResponse"],
4940
- convert: (model, msg, publish, options, meta) => {
4941
- const result = exports.thermostat.convert(model, msg, publish, options, meta);
4942
- if (result && msg.data.StelproSystemMode === 5) {
4943
- // 'Eco' mode is translated into 'auto' here
4944
- result.system_mode = constants.thermostatSystemModes[1];
4945
- }
4946
- if (result && msg.data.pIHeatingDemand !== undefined) {
4947
- result.running_state = msg.data.pIHeatingDemand >= 10 ? "heat" : "idle";
4948
- }
4949
- return result;
4950
- },
4951
- };
4952
- exports.viessmann_thermostat = {
4953
- cluster: "hvacThermostat",
4954
- type: ["attributeReport", "readResponse"],
4955
- convert: (model, msg, publish, options, meta) => {
4956
- const result = exports.thermostat.convert(model, msg, publish, options, meta);
4957
- if (result) {
4958
- // ViessMann TRVs report piHeatingDemand from 0-5
4959
- // NOTE: remove the result for now, but leave it configure for reporting
4960
- // it will show up in the debug log still to help try and figure out
4961
- // what this value potentially means.
4962
- delete result.pi_heating_demand;
4963
- // viessmannWindowOpenInternal
4964
- // 0-2, 5: unknown
4965
- // 3: window open (OO on display, no heating)
4966
- // 4: window open (OO on display, heating)
4967
- if (msg.data.viessmannWindowOpenInternal !== undefined) {
4968
- result.window_open = msg.data.viessmannWindowOpenInternal === 3 || msg.data.viessmannWindowOpenInternal === 4;
4969
- }
4970
- // viessmannWindowOpenForce (rw, bool)
4971
- if (msg.data.viessmannWindowOpenForce !== undefined) {
4972
- result.window_open_force = msg.data.viessmannWindowOpenForce === 1;
4973
- }
4974
- // viessmannAssemblyMode (ro, bool)
4975
- // 0: TRV installed
4976
- // 1: TRV ready to install (-- on display)
4977
- if (msg.data.viessmannAssemblyMode !== undefined) {
4978
- result.assembly_mode = msg.data.viessmannAssemblyMode === 1;
4979
- }
4980
- }
4981
- return result;
4982
- },
4983
- };
4984
- exports.eurotronic_thermostat = {
4985
- cluster: "hvacThermostat",
4986
- type: ["attributeReport", "readResponse"],
4987
- convert: (model, msg, publish, options, meta) => {
4988
- const result = exports.thermostat.convert(model, msg, publish, options, meta);
4989
- if (result) {
4990
- if (typeof msg.data[0x4003] === "number") {
4991
- result.current_heating_setpoint = (0, utils_1.precisionRound)(msg.data[0x4003], 2) / 100;
4992
- }
4993
- if (typeof msg.data[0x4008] === "number") {
4994
- result.child_lock = (msg.data[0x4008] & 0x80) !== 0 ? "LOCK" : "UNLOCK";
4995
- result.mirror_display = (msg.data[0x4008] & 0x02) !== 0 ? "ON" : "OFF";
4996
- // This seems broken... We need to write 0x20 to turn it off and 0x10 to set
4997
- // it to auto mode. However, when it reports the flag, it will report 0x10
4998
- // when it's off, and nothing at all when it's in auto mode
4999
- // the new Comet valve reports the off status on bit 5
5000
- // if either bit 4 or 5 is set, off mode is active
5001
- if ((msg.data[0x4008] & 0x30) !== 0) {
5002
- // reports auto -> setting to force_off
5003
- result.system_mode = constants.thermostatSystemModes[0];
5004
- }
5005
- else if ((msg.data[0x4008] & 0x04) !== 0) {
5006
- // always_on
5007
- result.system_mode = constants.thermostatSystemModes[4];
5008
- }
5009
- else {
5010
- // auto
5011
- result.system_mode = constants.thermostatSystemModes[1];
5012
- }
5013
- }
5014
- if (typeof msg.data[0x4002] === "number") {
5015
- result.error_status = msg.data[0x4002];
5016
- }
5017
- if (typeof msg.data[0x4000] === "number") {
5018
- result.trv_mode = msg.data[0x4000];
5019
- }
5020
- if (typeof msg.data[0x4001] === "number") {
5021
- result.valve_position = msg.data[0x4001];
5022
- }
5023
- if (msg.data.pIHeatingDemand !== undefined) {
5024
- result.running_state = msg.data.pIHeatingDemand >= 10 ? "heat" : "idle";
5025
- }
5026
- }
5027
- return result;
5028
- },
5029
- };
5030
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
5031
- exports.ZM35HQ_attr = {
5032
- cluster: "ssIasZone",
5033
- type: ["attributeReport", "readResponse"],
5034
- convert: (model, msg, publish, options, meta) => {
5035
- let result = {};
5036
- const data = msg.data;
5037
- if (data && data.zoneStatus !== undefined) {
5038
- const result1 = exports.ias_occupancy_alarm_1_report.convert(model, msg, publish, options, meta);
5039
- result = { ...result1 };
5040
- }
5041
- if (data && data.currentZoneSensitivityLevel !== undefined) {
5042
- const senslookup = { 0: "low", 1: "medium", 2: "high" };
5043
- result.sensitivity = senslookup[data.currentZoneSensitivityLevel];
5044
- }
5045
- if (data && data["61441"] !== undefined) {
5046
- const keeptimelookup = { 0: 30, 1: 60, 2: 120 };
5047
- result.keep_time = keeptimelookup[data["61441"]];
5048
- }
5049
- return result;
5050
- },
5051
- };
5052
- exports.schneider_lighting_ballast_configuration = {
5053
- cluster: "lightingBallastCfg",
5054
- type: ["attributeReport", "readResponse"],
5055
- convert: (model, msg, publish, options, meta) => {
5056
- const result = exports.lighting_ballast_configuration.convert(model, msg, publish, options, meta);
5057
- const lookup = { 1: "RC", 2: "RL" };
5058
- if (result && msg.data[0xe000] !== undefined) {
5059
- result.dimmer_mode = lookup[msg.data[0xe000]];
5060
- }
5061
- return result;
5062
- },
5063
- };
5064
- exports.wiser_lighting_ballast_configuration = {
5065
- cluster: "lightingBallastCfg",
5066
- type: ["attributeReport", "readResponse"],
5067
- convert: (model, msg, publish, options, meta) => {
5068
- const result = exports.lighting_ballast_configuration.convert(model, msg, publish, options, meta);
5069
- if (result && msg.data.wiserControlMode !== undefined) {
5070
- result.dimmer_mode = constants.wiserDimmerControlMode[msg.data.wiserControlMode];
5071
- }
5072
- return result;
5073
- },
5074
- };
5075
- exports.wiser_smart_thermostat = {
5076
- cluster: "hvacThermostat",
5077
- type: ["attributeReport", "readResponse"],
5078
- convert: async (model, msg, publish, options, meta) => {
5079
- const result = exports.thermostat.convert(model, msg, publish, options, meta);
5080
- if (result) {
5081
- if (msg.data[0xe010] !== undefined) {
5082
- // wiserSmartZoneMode
5083
- const lookup = { 1: "manual", 2: "schedule", 3: "energy_saver", 6: "holiday" };
5084
- result.zone_mode = lookup[msg.data[0xe010]];
5085
- }
5086
- if (msg.data[0xe011] !== undefined) {
5087
- // wiserSmartHactConfig
5088
- const lookup = { 0: "unconfigured", 128: "setpoint_switch", 130: "setpoint_fip", 131: "fip_fip" };
5089
- result.hact_config = lookup[msg.data[0xe011]];
5090
- }
5091
- if (msg.data[0xe020] !== undefined) {
5092
- // wiserSmartCurrentFilPiloteMode
5093
- const lookup = {
5094
- 0: "comfort",
5095
- 1: "comfort_-1",
5096
- 2: "comfort_-2",
5097
- 3: "energy_saving",
5098
- 4: "frost_protection",
5099
- 5: "off",
5100
- };
5101
- result.fip_setting = lookup[msg.data[0xe020]];
5102
- }
5103
- if (msg.data[0xe030] !== undefined) {
5104
- // wiserSmartValvePosition
5105
- result.pi_heating_demand = msg.data[0xe030];
5106
- }
5107
- if (msg.data[0xe031] !== undefined) {
5108
- // wiserSmartValveCalibrationStatus
5109
- const lookup = {
5110
- 0: "ongoing",
5111
- 1: "successful",
5112
- 2: "uncalibrated",
5113
- 3: "failed_e1",
5114
- 4: "failed_e2",
5115
- 5: "failed_e3",
5116
- };
5117
- result.valve_calibration_status = lookup[msg.data[0xe031]];
5118
- }
5119
- // Radiator thermostats command changes from UI, but report value periodically for sync,
5120
- // force an update of the value if it doesn't match the current existing value
5121
- if (meta.device.modelID === "EH-ZB-VACT" &&
5122
- msg.data.occupiedHeatingSetpoint !== undefined &&
5123
- meta.state.occupied_heating_setpoint !== undefined) {
5124
- if (result.occupied_heating_setpoint !== meta.state.occupied_heating_setpoint) {
5125
- const lookup = { manual: 1, schedule: 2, energy_saver: 3, holiday: 6 };
5126
- const zonemodeNum = lookup[Number(meta.state.zone_mode)];
5127
- const setpoint = Number((Math.round(Number((Number(meta.state.occupied_heating_setpoint) * 2).toFixed(1))) / 2).toFixed(1)) * 100;
5128
- const payload = {
5129
- operatingmode: 0,
5130
- zonemode: zonemodeNum,
5131
- setpoint: setpoint,
5132
- reserved: 0xff,
5133
- };
5134
- await msg.endpoint.command("hvacThermostat", "wiserSmartSetSetpoint", payload, {
5135
- srcEndpoint: 11,
5136
- disableDefaultResponse: true,
5137
- });
5138
- logger_1.logger.debug(`syncing vact setpoint was: '${result.occupied_heating_setpoint}' now: '${meta.state.occupied_heating_setpoint}'`, NS);
5139
- }
5140
- }
5141
- else {
5142
- publish(result);
5143
- }
5144
- }
5145
- },
5146
- };
5147
- exports.TS110E = {
5148
- cluster: "genLevelCtrl",
5149
- type: ["attributeReport", "readResponse"],
5150
- convert: (model, msg, publish, options, meta) => {
5151
- const result = {};
5152
- if (msg.data["64515"] !== undefined) {
5153
- result.min_brightness = utils.mapNumberRange(msg.data["64515"], 0, 1000, 1, 255);
5154
- }
5155
- if (msg.data["64516"] !== undefined) {
5156
- result.max_brightness = utils.mapNumberRange(msg.data["64516"], 0, 1000, 1, 255);
5157
- }
5158
- if (msg.data["61440"] !== undefined) {
5159
- const propertyName = utils.postfixWithEndpointName("brightness", msg, model, meta);
5160
- result[propertyName] = utils.mapNumberRange(msg.data["61440"], 0, 1000, 0, 255);
5161
- }
5162
- return result;
5163
- },
5164
- };
5165
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
5166
- exports.TS110E_light_type = {
5167
- cluster: "genLevelCtrl",
5168
- type: ["attributeReport", "readResponse"],
5169
- convert: (model, msg, publish, options, meta) => {
5170
- const result = {};
5171
- if (msg.data["64514"] !== undefined) {
5172
- const lookup = { 0: "led", 1: "incandescent", 2: "halogen" };
5173
- result.light_type = lookup[msg.data["64514"]];
5174
- }
5175
- return result;
5176
- },
5177
- };
5178
- // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
5179
- exports.TS110E_switch_type = {
5180
- cluster: "genLevelCtrl",
5181
- type: ["attributeReport", "readResponse"],
5182
- convert: (model, msg, publish, options, meta) => {
5183
- const result = {};
5184
- if (msg.data["64514"] !== undefined) {
5185
- const lookup = { 0: "momentary", 1: "toggle", 2: "state" };
5186
- const propertyName = utils.postfixWithEndpointName("switch_type", msg, model, meta);
5187
- result[propertyName] = lookup[msg.data["64514"]];
5188
- }
5189
- return result;
5190
- },
5191
- };
5192
2331
  //# sourceMappingURL=fromZigbee.js.map