@willieee802/zigbee-herdsman-converters 19.44.3 → 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 +3143 -815
  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
package/dist/lib/tuya.js CHANGED
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.clusters = exports.modernExtend = exports.fz = exports.tz = exports.valueConverter = exports.valueConverterBasic = exports.Bitmap = exports.BacklightColorEnum = exports.enum = exports.Enum = exports.whitelabel = exports.fingerprint = exports.configureBindBasic = exports.configureMcuVersionRequest = exports.configureQuery = exports.configureMagicPacket = exports.skip = exports.exposes = exports.TuyaWeatherID = exports.F3ProTuyaWeatherCondition = exports.M8ProTuyaWeatherCondition = exports.dataTypes = void 0;
36
+ exports.clusters = exports.modernExtend = exports.fz = exports.tz = exports.valueConverter = exports.valueConverterBasic = exports.Bitmap = exports.BacklightColorEnum = exports.enum = exports.Enum = exports.whitelabel = exports.fingerprint = exports.configureBindBasic = exports.configureMcuVersionRequest = exports.configureQuery = exports.configureMagicPacket = exports.skip = exports.exposes = exports.TuyaWeatherID = exports.F3ProTuyaWeatherCondition = exports.M8ProTuyaWeatherCondition = exports.dataTypes = exports.circuitBreakerFaultList = void 0;
37
37
  exports.convertBufferToNumber = convertBufferToNumber;
38
38
  exports.convertDecimalValueTo4ByteHexArray = convertDecimalValueTo4ByteHexArray;
39
39
  exports.dpValueFromString = dpValueFromString;
@@ -47,6 +47,7 @@ exports.getHandlersForDP = getHandlersForDP;
47
47
  const zigbee_herdsman_1 = require("@willieee802/zigbee-herdsman");
48
48
  const fz = __importStar(require("../converters/fromZigbee"));
49
49
  const tz = __importStar(require("../converters/toZigbee"));
50
+ const libColor = __importStar(require("../lib/color"));
50
51
  const constants = __importStar(require("./constants"));
51
52
  const exposes = __importStar(require("./exposes"));
52
53
  const logger_1 = require("./logger");
@@ -58,6 +59,25 @@ const utils_1 = require("./utils");
58
59
  const NS = "zhc:tuya";
59
60
  const e = exposes.presets;
60
61
  const ea = exposes.access;
62
+ exports.circuitBreakerFaultList = [
63
+ "short_circuit",
64
+ "surge",
65
+ "overload",
66
+ "leakage_current",
67
+ "temperature",
68
+ "fire",
69
+ "high_power",
70
+ "self_test",
71
+ "over_current",
72
+ "unbalance",
73
+ "over_voltage",
74
+ "under_voltage",
75
+ "miss_phase",
76
+ "outage",
77
+ "magnetism", // or negative_power
78
+ "credit",
79
+ "no_balance",
80
+ ];
61
81
  exports.dataTypes = {
62
82
  raw: 0, // [ bytes ]
63
83
  bool: 1, // [0/1]
@@ -234,6 +254,15 @@ async function sendDataPointStringBuffer(entity, dp, value, cmd, seq) {
234
254
  return await sendDataPoints(entity, [dpValueFromString(dp, value)], cmd, seq);
235
255
  }
236
256
  const tuyaExposes = {
257
+ alarmTime: () => e
258
+ .numeric("alarm_time", ea.STATE_SET)
259
+ .withUnit("s")
260
+ .withValueMin(1)
261
+ .withValueMax(180)
262
+ .withValueStep(1)
263
+ .withDescription("Alarm time")
264
+ .withCategory("config"),
265
+ alarmMode: () => e.enum("alarm_mode", ea.STATE_SET, ["arm", "silent", "disarm"]).withDescription("Alarm work mode").withCategory("config"),
237
266
  lightType: () => e.enum("light_type", ea.STATE_SET, ["led", "incandescent", "halogen"]).withDescription("Type of light attached to the device"),
238
267
  lightBrightnessWithMinMax: () => e
239
268
  .light_brightness()
@@ -250,10 +279,50 @@ const tuyaExposes = {
250
279
  .withValueMax(43200)
251
280
  .withValueStep(1)
252
281
  .withUnit("s")
253
- .withDescription("Countdown to turn device off after a certain time"),
282
+ .withDescription("Toggle the device after a set duration (one time action)"),
283
+ countdown_min: () => e
284
+ .numeric("countdown", ea.STATE_SET)
285
+ .withValueMin(1)
286
+ .withValueMax(240)
287
+ .withValueStep(1)
288
+ .withUnit("min")
289
+ .withDescription("Turn off the sprinkler after set duration (one time action)"),
290
+ on_with_countdown: () => e
291
+ .numeric("on_with_countdown", ea.STATE_SET)
292
+ .withValueMin(1)
293
+ .withValueMax(240)
294
+ .withValueStep(1)
295
+ .withUnit("min")
296
+ .withDescription("Turn on the sprinkler and start countdown"),
297
+ countdown_left: () => e
298
+ .numeric("countdown_left", ea.STATE)
299
+ .withValueMin(0)
300
+ .withValueMax(240)
301
+ .withValueStep(1)
302
+ .withUnit("min")
303
+ .withDescription("Time left in the countdown"),
304
+ single_watering_duration: () => e.numeric("single_watering_duration", ea.STATE).withDescription("Duration of last watering").withUnit("s"),
305
+ flow_switch: () => e
306
+ .binary("flow_switch", ea.STATE_SET, "ON", "OFF")
307
+ .withDescription("Enables water flow measurement, and automatically turn off the sprinkler when flow is 0 for ~30s"),
308
+ quantitative_watering: () => e
309
+ .numeric("quantitative_watering", ea.STATE_SET)
310
+ .withValueMin(1)
311
+ .withValueMax(10000)
312
+ .withValueStep(1)
313
+ .withUnit("L")
314
+ .withDescription("Turn on the sprinkler with a set amount of water"),
315
+ single_watering_amount: () => e.numeric("single_watering_amount", ea.STATE).withUnit("L").withDescription("Quantity of last watering"),
316
+ surplus_flow: () => e.numeric("surplus_flow", ea.STATE).withUnit("L").withDescription("Remaining amount"),
317
+ water_total: () => e.numeric("water_total", ea.STATE).withUnit("L").withValueMin(0).withValueStep(0.001).withDescription("Total watering amount"),
318
+ water_current: () => e.numeric("water_current", ea.STATE).withUnit("L/min").withValueMin(0).withValueStep(0.001).withDescription("Current water flow"),
319
+ water_total_reset: () => e.enum("water_total_reset", ea.STATE_SET, ["reset"]).withDescription("Reset the stored watering amount to 0").withCategory("config"),
320
+ refresh: () => e.enum("refresh", ea.STATE_SET, ["refresh"]).withDescription("Refresh the device status").withCategory("config"),
321
+ status_sprinkler: () => e.enum("status", ea.STATE, ["off", "on_auto", "button_locked", "on_manual_app", "on_manual_button"]).withDescription("Status"),
254
322
  switch: () => e.switch().setAccess("state", ea.STATE_SET),
255
323
  selfTest: () => e.binary("self_test", ea.STATE_SET, true, false).withDescription("Indicates whether the device is being self-tested"),
256
324
  selfTestResult: () => e.enum("self_test_result", ea.STATE, ["checking", "success", "failure", "others"]).withDescription("Result of the self-test"),
325
+ fault: () => e.binary("fault", ea.STATE, true, false).withDescription("Indicates whether a fault was detected").withCategory("diagnostic"),
257
326
  faultAlarm: () => e.binary("fault_alarm", ea.STATE, true, false).withDescription("Indicates whether a fault was detected"),
258
327
  silence: () => e.binary("silence", ea.STATE_SET, true, false).withDescription("Silence the alarm"),
259
328
  frostProtection: (extraNote = "") => e
@@ -335,7 +404,7 @@ const tuyaExposes = {
335
404
  batteryState: () => e.enum("battery_state", ea.STATE, ["low", "medium", "high"]).withDescription("State of the battery"),
336
405
  doNotDisturb: () => e
337
406
  .binary("do_not_disturb", ea.STATE_SET, true, false)
338
- .withDescription("Do not disturb mode, when enabled this function will keep the light OFF after a power outage")
407
+ .withDescription("Controls state after power outage: false = on, true = restore previous state")
339
408
  .withCategory("config"),
340
409
  colorPowerOnBehavior: () => e
341
410
  .enum("color_power_on_behavior", ea.STATE_SET, ["initial", "previous", "customized"])
@@ -378,6 +447,266 @@ const tuyaExposes = {
378
447
  }
379
448
  return x;
380
449
  },
450
+ inchingSwitch2: () => e
451
+ .composite("inching", "inching", ea.STATE_SET)
452
+ .withDescription("Inching configuration")
453
+ .withFeature(e
454
+ .binary("state", ea.STATE_SET, "ON", "OFF")
455
+ .withDescription("Whenever the device is switched ON, switch it OFF automatically after the configured delay"))
456
+ .withFeature(e
457
+ .numeric("minutes", ea.STATE_SET)
458
+ .withUnit("m")
459
+ .withValueMin(0)
460
+ .withValueMax(1440)
461
+ .withDescription("Minutes component of the delay duration"))
462
+ .withFeature(e
463
+ .numeric("seconds", ea.STATE_SET)
464
+ .withUnit("s")
465
+ .withValueMin(0)
466
+ .withValueMax(59)
467
+ .withDescription("Seconds component of the delay duration"))
468
+ .withCategory("config"),
469
+ circuitBreakerFaults: () => e
470
+ .list("faults", ea.STATE, e.enum("fault", ea.STATE, exports.circuitBreakerFaultList))
471
+ .withDescription("List of current faults")
472
+ .withCategory("diagnostic"),
473
+ circuitBreakerStatus: () => e.enum("status", ea.STATE, ["off", "consumption", "production"]).withDescription("Current operating status").withCategory("diagnostic"),
474
+ leakageCurrent: () => e
475
+ .numeric("leakage_current", ea.STATE)
476
+ .withUnit("mA")
477
+ .withDescription("Measured current difference between live and neutral wires")
478
+ .withCategory("diagnostic"),
479
+ reclosing: () => e
480
+ .binary("reclosing", ea.STATE_SET, "ON", "OFF")
481
+ .withCategory("config")
482
+ .withDescription("Automatically attempt switching ON the circuit after it was turned OFF by a detected fault"),
483
+ reclosing_delay: () => e
484
+ .numeric("reclosing_delay", ea.STATE_SET)
485
+ .withUnit("s")
486
+ .withValueMin(1)
487
+ .withValueMax(99)
488
+ .withValueStep(1)
489
+ .withCategory("config")
490
+ .withDescription("Time to wait after the fault is cleared, before attempting reclose"),
491
+ reclosing_count: () => e
492
+ .numeric("reclosing_count", ea.STATE_SET)
493
+ .withValueMin(0)
494
+ .withValueMax(30)
495
+ .withValueStep(1)
496
+ .withCategory("config")
497
+ .withDescription("Number of allowed reclosing attempts per fault"),
498
+ energyPrepayment: () => e
499
+ .binary("prepayment", ea.STATE_SET, "ON", "OFF")
500
+ .withDescription("Automatically switch OFF the circuit when the energy balance reaches zero")
501
+ .withCategory("config"),
502
+ energyBalance: () => e
503
+ .numeric("energy_balance", ea.STATE)
504
+ .withUnit("kWh")
505
+ .withDescription("Amount of energy allowed for consumption (Decreases when Prepayment is enabled)")
506
+ .withCategory("diagnostic"),
507
+ energyBalanceAdd: () => e
508
+ .numeric("energy_balance_add", ea.STATE_SET)
509
+ .withUnit("kWh")
510
+ .withValueMin(0)
511
+ .withValueMax(999999)
512
+ .withValueStep(0.01)
513
+ .withDescription("Add an amount of energy to the balance")
514
+ .withCategory("config"),
515
+ energyBalanceReset: () => e.enum("energy_balance_reset", ea.STATE_SET, ["RESET"]).withDescription("Set the energy balance to zero").withCategory("config"),
516
+ energyReset: () => e.enum("energy_reset", ea.STATE_SET, ["RESET"]).withDescription("Set the energy measurements to zero").withCategory("config"),
517
+ leakageCurrentAndTemperatureAlarm: () => e
518
+ .composite("alarm_set_1", "alarm_set_1", ea.STATE_SET)
519
+ .withDescription("Leakage current and temperature alarms configuration")
520
+ .withFeature(e
521
+ .binary("leakage_current_alarm", ea.STATE_SET, "ON", "OFF")
522
+ .withDescription("Automatically switch OFF the circuit when the leakage current is above the limit (Default ON)"))
523
+ .withFeature(e
524
+ .numeric("leakage_current_threshold", ea.STATE_SET)
525
+ .withUnit("mA")
526
+ .withValueMin(1)
527
+ .withValueMax(99)
528
+ .withValueStep(1)
529
+ .withDescription("Leakage current limit (Default 50mA)"))
530
+ .withFeature(e
531
+ .binary("device_temperature_alarm", ea.STATE_SET, "ON", "OFF")
532
+ .withDescription("Automatically switch OFF the circuit when the measured temperature exceeds the limit (Default ON)"))
533
+ .withFeature(e
534
+ .numeric("device_temperature_threshold", ea.STATE_SET)
535
+ .withUnit("°C")
536
+ .withValueMin(10)
537
+ .withValueMax(85)
538
+ .withValueStep(1)
539
+ .withDescription("Temperature limit (Default 80°C)"))
540
+ .withCategory("config"),
541
+ rs485ConfigAndHighPowerAlarm: () => e
542
+ .composite("alarm_set_1", "alarm_set_1", ea.STATE_SET)
543
+ .withDescription("Configuration for RS485 wired communication (if supported by device) and high power alarm")
544
+ .withFeature(e.binary("rs485_baud_rate_enabled", ea.STATE_SET, "ON", "OFF").withLabel("RS485 baud rate"))
545
+ .withFeature(e.enum("rs485_baud_rate", ea.STATE_SET, [2400, 4800, 9600, 19200, 38400]).withLabel("RS485 baud rate"))
546
+ .withFeature(e.binary("rs485_address_enabled", ea.STATE_SET, "ON", "OFF").withLabel("RS485 address"))
547
+ .withFeature(e.numeric("rs485_address", ea.STATE_SET).withValueMin(1).withValueMax(100).withValueStep(1).withLabel("RS485 address"))
548
+ .withFeature(e.binary("rs485_data_format_enabled", ea.STATE_SET, "ON", "OFF").withLabel("RS485 data format"))
549
+ .withFeature(e.enum("rs485_data_format", ea.STATE_SET, ["N81", "E81", "O81", "N82"]).withLabel("RS485 data format"))
550
+ .withFeature(e
551
+ .binary("high_power_alarm", ea.STATE_SET, "ON", "OFF")
552
+ .withDescription("Trigger alarm when power draw exceeds the limit (Default OFF)"))
553
+ .withFeature(e
554
+ .numeric("high_power_threshold", ea.STATE_SET)
555
+ .withValueMin(0)
556
+ .withValueMax(65535)
557
+ .withValueStep(1)
558
+ .withUnit("kW")
559
+ .withDescription("Power limit (Default 25 kW)"))
560
+ .withCategory("config"),
561
+ currentAndVoltageAlarm: () => e
562
+ .composite("alarm_set_2", "alarm_set_2", ea.STATE_SET)
563
+ .withDescription("Current and voltage alarms configuration")
564
+ .withFeature(e
565
+ .binary("over_current_alarm", ea.STATE_SET, "ON", "OFF")
566
+ .withDescription("Automatically switch OFF the circuit when the circuit draws more current than the limit (Default ON)"))
567
+ .withFeature(e
568
+ .numeric("over_current_threshold", ea.STATE_SET)
569
+ .withUnit("A")
570
+ .withValueMin(1.0)
571
+ .withValueMax(80.0)
572
+ .withValueStep(0.1)
573
+ .withDescription("Current upper limit (Default 63A)"))
574
+ .withFeature(e
575
+ .binary("over_voltage_alarm", ea.STATE_SET, "ON", "OFF")
576
+ .withDescription("Automatically switch OFF the circuit when the voltage is above the limit (Default ON)"))
577
+ .withFeature(e
578
+ .numeric("over_voltage_threshold", ea.STATE_SET)
579
+ .withUnit("V")
580
+ .withValueMin(120)
581
+ .withValueMax(300)
582
+ .withValueStep(1)
583
+ .withDescription("Voltage upper limit (Default 275V)"))
584
+ .withFeature(e
585
+ .binary("under_voltage_alarm", ea.STATE_SET, "ON", "OFF")
586
+ .withDescription("Automatically switch OFF the circuit when the voltage is below the limit (Default ON)"))
587
+ .withFeature(e
588
+ .numeric("under_voltage_threshold", ea.STATE_SET)
589
+ .withUnit("V")
590
+ .withValueMin(80)
591
+ .withValueMax(210)
592
+ .withValueStep(1)
593
+ .withDescription("Voltage lower limit (Default 175V)"))
594
+ .withCategory("config"),
595
+ alarmSet2: () => e
596
+ .composite("alarm_set_2", "alarm_set_2", ea.STATE_SET)
597
+ .withDescription("Configuration for alarms and reporting frequency")
598
+ .withFeature(e
599
+ .binary("over_current_alarm", ea.STATE_SET, "ON", "OFF")
600
+ .withDescription("Trigger alarm when current is higher than the limit (Default OFF)"))
601
+ .withFeature(e
602
+ .numeric("over_current_threshold", ea.STATE_SET)
603
+ .withUnit("A")
604
+ .withValueMin(0)
605
+ .withValueMax(65535)
606
+ .withValueStep(1)
607
+ .withDescription("Current upper limit (Default 100A)"))
608
+ .withFeature(e
609
+ .binary("over_voltage_alarm", ea.STATE_SET, "ON", "OFF")
610
+ .withDescription("Trigger alarm when the voltage is above the limit (Default ON)"))
611
+ .withFeature(e
612
+ .numeric("over_voltage_threshold", ea.STATE_SET)
613
+ .withUnit("V")
614
+ .withValueMin(0)
615
+ .withValueMax(65535)
616
+ .withValueStep(1)
617
+ .withDescription("Voltage upper limit (Default 253V)"))
618
+ .withFeature(e
619
+ .binary("under_voltage_alarm", ea.STATE_SET, "ON", "OFF")
620
+ .withDescription("Trigger alarm when the voltage is below the limit (Default OFF)"))
621
+ .withFeature(e
622
+ .numeric("under_voltage_threshold", ea.STATE_SET)
623
+ .withUnit("V")
624
+ .withValueMin(0)
625
+ .withValueMax(65535)
626
+ .withValueStep(1)
627
+ .withDescription("Voltage lower limit (Default 180V)"))
628
+ .withFeature(e
629
+ .binary("unbalanced_load_alarm", ea.STATE_SET, "ON", "OFF")
630
+ .withDescription("Trigger alarm when power factor is below the limit (Default 15%)"))
631
+ .withFeature(e
632
+ .numeric("unbalanced_load_threshold", ea.STATE_SET)
633
+ .withUnit("%")
634
+ .withValueMin(0)
635
+ .withValueMax(100)
636
+ .withValueStep(1)
637
+ .withDescription("Power factor lower limit (Default 15%)"))
638
+ .withFeature(e.binary("phase_loss_alarm", ea.STATE_SET, "ON", "OFF").withDescription("Trigger alarm when one phase is unavailable (Default OFF)"))
639
+ .withFeature(e
640
+ .binary("negative_active_power_alarm", ea.STATE_SET, "ON", "OFF")
641
+ .withDescription("Trigger alarm when the active power is negative (Default ON)"))
642
+ .withFeature(e.binary("custom_data_reporting_interval", ea.STATE_SET, "ON", "OFF"))
643
+ .withFeature(e
644
+ .numeric("data_reporting_interval", ea.STATE_SET)
645
+ .withUnit("s")
646
+ .withValueMin(5)
647
+ .withValueMax(600)
648
+ .withValueStep(0.5)
649
+ .withDescription("How often the device should report measurements (Default 5s)"))
650
+ .withCategory("config"),
651
+ overCurrentThresholdTime: () => e
652
+ .numeric("over_current_threshold_time", ea.STATE_SET)
653
+ .withUnit("s")
654
+ .withValueMin(0)
655
+ .withValueMax(999)
656
+ .withValueStep(1)
657
+ .withDescription("Time overcurrent is allowed before the circuit is switched OFF (Default 0s)")
658
+ .withCategory("config"),
659
+ lostFlowAlarm: () => e
660
+ .composite("alarm_set_3", "alarm_set_3", ea.STATE_SET)
661
+ .withDescription("Lost flow alarm configuration")
662
+ .withFeature(e.binary("lost_flow_alarm", ea.STATE_SET, "ON", "OFF").withDescription("Unknown"))
663
+ .withFeature(e
664
+ .numeric("lost_flow_threshold", ea.STATE_SET)
665
+ .withUnit("A")
666
+ .withValueMin(1.0)
667
+ .withValueMax(100.0)
668
+ .withValueStep(0.1)
669
+ .withDescription("Unknown"))
670
+ .withCategory("config"),
671
+ lostFlowThresholdTime: () => e
672
+ .numeric("lost_flow_threshold_time", ea.STATE_SET)
673
+ .withUnit("s")
674
+ .withValueMin(0)
675
+ .withValueMax(999)
676
+ .withValueStep(1)
677
+ .withDescription("Unknown (Default 0s)")
678
+ .withCategory("config"),
679
+ liquidLevelPercent: () => e.numeric("liquid_level_percent", ea.STATE).withUnit("%").withDescription("Liquid level ratio"),
680
+ liquidDepth: () => e.numeric("liquid_depth", ea.STATE).withUnit("cm").withDescription("Liquid depth"),
681
+ liquidDepthMax: () => e
682
+ .numeric("liquid_depth_max", ea.STATE_SET)
683
+ .withUnit("mm")
684
+ .withDescription("Height from sensor to liquid level")
685
+ .withValueMin(10)
686
+ .withValueMax(4000)
687
+ .withValueStep(5),
688
+ liquidInstallationHeight: () => e
689
+ .numeric("installation_height", ea.STATE_SET)
690
+ .withUnit("mm")
691
+ .withDescription("Height from sensor to tank bottom")
692
+ .withValueMin(10)
693
+ .withValueMax(4000)
694
+ .withValueStep(5),
695
+ liquidMinimalPercent: () => e
696
+ .numeric("min_set", ea.STATE_SET)
697
+ .withUnit("%")
698
+ .withDescription("Liquid minimal percentage")
699
+ .withValueMin(0)
700
+ .withValueMax(100)
701
+ .withValueStep(1),
702
+ liquidMaximalPercent: () => e
703
+ .numeric("max_set", ea.STATE_SET)
704
+ .withUnit("%")
705
+ .withDescription("Liquid maximum percentage")
706
+ .withValueMin(0)
707
+ .withValueMax(100)
708
+ .withValueStep(1),
709
+ liquidState: () => e.enum("liquid_state", ea.STATE, ["low", "normal", "high"]).withDescription("Liquid level status"),
381
710
  };
382
711
  exports.exposes = tuyaExposes;
383
712
  exports.skip = {
@@ -423,6 +752,104 @@ const whitelabel = (vendor, model, description, manufacturerNames) => {
423
752
  return { vendor, model, description, fingerprint };
424
753
  };
425
754
  exports.whitelabel = whitelabel;
755
+ function parseThresholds(buffer, definitions) {
756
+ const onOffLookup = { 0: "OFF", 1: "ON" };
757
+ const result = {};
758
+ for (let i = 0; i < buffer.length; i += 4) {
759
+ const id = buffer[i];
760
+ const definition = definitions[id];
761
+ if (!definition) {
762
+ continue;
763
+ }
764
+ result[definition.enabled] = onOffLookup[buffer[i + 1]];
765
+ if (definition.value)
766
+ result[definition.value] = buffer.readUInt16BE(i + 2);
767
+ }
768
+ return result;
769
+ }
770
+ function encodeThresholds(values, currentState, definitions) {
771
+ const onOffLookup = { OFF: 0, ON: 1 };
772
+ const result = [];
773
+ for (const [id, definition] of Object.entries(definitions)) {
774
+ const enabled = values[definition.enabled] ?? currentState[definition.enabled];
775
+ const value = !definition.value ? 0 : (values[definition.value] ?? currentState[definition.value]);
776
+ if (enabled === undefined || value === undefined) {
777
+ continue;
778
+ }
779
+ const buf = Buffer.alloc(4);
780
+ buf.writeUInt8(Number(id), 0);
781
+ buf.writeUInt8(utils.getFromLookup(enabled, onOffLookup), 1);
782
+ buf.writeUInt16BE(Number(value), 2);
783
+ result.push(...buf);
784
+ }
785
+ return result;
786
+ }
787
+ const alarmSet1ThresholdDefinitions = {
788
+ 4: {
789
+ enabled: "leakage_current_alarm",
790
+ value: "leakage_current_threshold",
791
+ },
792
+ 5: {
793
+ enabled: "device_temperature_alarm",
794
+ value: "device_temperature_threshold",
795
+ },
796
+ };
797
+ const alarmSet1BThresholdDefinitions = {
798
+ 3: {
799
+ enabled: "rs485_baud_rate_enabled",
800
+ value: "rs485_baud_rate",
801
+ },
802
+ 4: {
803
+ enabled: "rs485_address_enabled",
804
+ value: "rs485_address",
805
+ },
806
+ 5: {
807
+ enabled: "rs485_data_format_enabled",
808
+ value: "rs485_data_format",
809
+ },
810
+ 7: {
811
+ enabled: "high_power_alarm",
812
+ value: "high_power_threshold",
813
+ },
814
+ };
815
+ const alarmSet2ThresholdDefinitions = {
816
+ 1: {
817
+ enabled: "over_current_alarm",
818
+ value: "over_current_threshold",
819
+ },
820
+ 2: {
821
+ enabled: "unbalanced_load_alarm",
822
+ value: "unbalanced_load_threshold",
823
+ },
824
+ 3: {
825
+ enabled: "over_voltage_alarm",
826
+ value: "over_voltage_threshold",
827
+ },
828
+ 4: {
829
+ enabled: "under_voltage_alarm",
830
+ value: "under_voltage_threshold",
831
+ },
832
+ 5: {
833
+ enabled: "phase_loss_alarm",
834
+ },
835
+ 7: {
836
+ enabled: "negative_active_power_alarm",
837
+ },
838
+ 8: {
839
+ enabled: "custom_data_reporting_interval",
840
+ value: "data_reporting_interval",
841
+ },
842
+ 9: {
843
+ enabled: "device_locating",
844
+ value: "device_locating_threshold",
845
+ },
846
+ };
847
+ const alarmSet3ThresholdDefinitions = {
848
+ 3: {
849
+ enabled: "lost_flow_alarm",
850
+ value: "lost_flow_threshold",
851
+ },
852
+ };
426
853
  class Base {
427
854
  value;
428
855
  constructor(value) {
@@ -478,6 +905,9 @@ exports.valueConverterBasic = {
478
905
  divideBy: (value) => {
479
906
  return { to: (v) => v * value, from: (v) => v / value };
480
907
  },
908
+ multiplyBy: (value) => {
909
+ return { to: (v) => v / value, from: (v) => v * value };
910
+ },
481
911
  divideByFromOnly: (value) => {
482
912
  return { to: (v) => v, from: (v) => v / value };
483
913
  },
@@ -501,6 +931,8 @@ exports.valueConverter = {
501
931
  trueFalseEnum0: exports.valueConverterBasic.trueFalse(new Enum(0)),
502
932
  trueFalseEnum1: exports.valueConverterBasic.trueFalse(new Enum(1)),
503
933
  onOff: exports.valueConverterBasic.lookup({ ON: true, OFF: false }),
934
+ onOffEnumOn1: exports.valueConverterBasic.lookup({ ON: new Enum(1), OFF: new Enum(0) }),
935
+ onOffEnumOn0: exports.valueConverterBasic.lookup({ ON: new Enum(0), OFF: new Enum(1) }),
504
936
  powerOnBehavior: exports.valueConverterBasic.lookup({ off: 0, on: 1, previous: 2 }),
505
937
  powerOnBehaviorEnum: exports.valueConverterBasic.lookup({ off: new Enum(0), on: new Enum(1), previous: new Enum(2) }),
506
938
  switchType: exports.valueConverterBasic.lookup({ momentary: new Enum(0), toggle: new Enum(1), state: new Enum(2) }),
@@ -528,11 +960,14 @@ exports.valueConverter = {
528
960
  divideBy10: exports.valueConverterBasic.divideBy(10),
529
961
  divideBy100: exports.valueConverterBasic.divideBy(100),
530
962
  divideBy1000: exports.valueConverterBasic.divideBy(1000),
963
+ multiplyBy10: exports.valueConverterBasic.multiplyBy(10),
531
964
  divideBy10FromOnly: exports.valueConverterBasic.divideByFromOnly(10),
532
965
  switchMode: exports.valueConverterBasic.lookup({ switch: new Enum(0), scene: new Enum(1) }),
533
966
  switchMode2: exports.valueConverterBasic.lookup({ switch: new Enum(0), curtain: new Enum(1) }),
534
967
  lightMode: exports.valueConverterBasic.lookup({ normal: new Enum(0), on: new Enum(1), off: new Enum(2), flash: new Enum(3) }),
535
968
  raw: exports.valueConverterBasic.raw(),
969
+ fault: { from: (v) => !!v },
970
+ alarmMode: exports.valueConverterBasic.lookup({ arm: new Enum(0), silent: new Enum(1), disarm: new Enum(2) }),
536
971
  localTemperatureCalibration: {
537
972
  from: (value) => (value > 4000 ? value - 4096 : value),
538
973
  to: (value) => (value < 0 ? 4096 + value : value),
@@ -542,6 +977,14 @@ exports.valueConverter = {
542
977
  from: (value) => (value > 200 ? value - 256 : value),
543
978
  to: (value) => (value < 0 ? 256 + value : value),
544
979
  },
980
+ refresh: {
981
+ to: (v) => {
982
+ return v === "refresh";
983
+ },
984
+ from: () => {
985
+ return "idle";
986
+ },
987
+ },
545
988
  waterConsumption: {
546
989
  from: (v) => {
547
990
  const buf = Buffer.isBuffer(v) ? v : Buffer.from(v || []);
@@ -552,6 +995,19 @@ exports.valueConverter = {
552
995
  return 0;
553
996
  },
554
997
  },
998
+ fertility: exports.valueConverterBasic.lookup({
999
+ normal: new Enum(0),
1000
+ lower: new Enum(1),
1001
+ low: new Enum(2),
1002
+ middle: new Enum(3),
1003
+ high: new Enum(4),
1004
+ higher: new Enum(5),
1005
+ }),
1006
+ temperature_humidity_alarm: exports.valueConverterBasic.lookup({
1007
+ lower_alarm: new Enum(0),
1008
+ upper_alarm: new Enum(1),
1009
+ cancel: new Enum(2),
1010
+ }),
555
1011
  setLimit: {
556
1012
  to: (v) => {
557
1013
  if (!v)
@@ -632,6 +1088,49 @@ exports.valueConverter = {
632
1088
  };
633
1089
  },
634
1090
  },
1091
+ phaseVariant4: {
1092
+ from: (v) => {
1093
+ return {
1094
+ voltage: v.readUint16BE(0) / 10,
1095
+ current: ((v.readUint8(2) << 16) + (v.readUint8(3) << 8) + v.readUint8(4)) / 1000,
1096
+ power: (v.readUint8(5) << 16) + (v.readUint8(6) << 8) + v.readUint8(7),
1097
+ };
1098
+ },
1099
+ },
1100
+ onOffWithZeros: {
1101
+ to: (v) => {
1102
+ if (v === "OFF")
1103
+ return false;
1104
+ if (v === "ON")
1105
+ return true;
1106
+ },
1107
+ from: (v, meta, options, publish) => {
1108
+ let result = "ON";
1109
+ if (!v) {
1110
+ // device is slow to report, we can assume zero values when off
1111
+ publish({ status: "off", current: 0, power: 0 });
1112
+ result = "OFF";
1113
+ }
1114
+ // setting/changing the state resets the countdown, but device doesn't report it
1115
+ if (meta.state.state !== result)
1116
+ publish({ countdown: 0 });
1117
+ return result;
1118
+ },
1119
+ },
1120
+ onOffFingerbot: {
1121
+ to: (v) => {
1122
+ if (v === "OFF")
1123
+ return false;
1124
+ if (v === "ON")
1125
+ return true;
1126
+ },
1127
+ from: (v, meta, options, publish) => {
1128
+ publish({ switch_states: "idle" });
1129
+ if (v)
1130
+ return "ON";
1131
+ return "OFF";
1132
+ },
1133
+ },
635
1134
  power: {
636
1135
  from: (v) => {
637
1136
  // Support negative readings
@@ -826,6 +1325,80 @@ exports.valueConverter = {
826
1325
  return result;
827
1326
  },
828
1327
  },
1328
+ threshold_4: {
1329
+ from: (v) => parseThresholds(v, alarmSet1ThresholdDefinitions),
1330
+ to: (v, meta) => encodeThresholds(v, meta.state.alarm_set_1 || {}, alarmSet1ThresholdDefinitions),
1331
+ },
1332
+ threshold_5: {
1333
+ from: (v) => {
1334
+ const result = parseThresholds(v, alarmSet2ThresholdDefinitions);
1335
+ if (result["over_current_threshold"]) {
1336
+ result["over_current_threshold"] = Number(result["over_current_threshold"]) / 10;
1337
+ }
1338
+ return result;
1339
+ },
1340
+ to: (v, meta) => {
1341
+ const vEncoded = { ...v };
1342
+ if (v["over_current_threshold"]) {
1343
+ vEncoded["over_current_threshold"] = Number(v["over_current_threshold"] * 10);
1344
+ }
1345
+ return encodeThresholds(vEncoded, meta.state.alarm_set_2 || {}, alarmSet2ThresholdDefinitions);
1346
+ },
1347
+ },
1348
+ threshold_6: {
1349
+ from: (v) => {
1350
+ const result = parseThresholds(v, alarmSet3ThresholdDefinitions);
1351
+ if (result["lost_flow_threshold"]) {
1352
+ result["lost_flow_threshold"] = Number(result["lost_flow_threshold"]) / 10;
1353
+ }
1354
+ return result;
1355
+ },
1356
+ to: (v, meta) => {
1357
+ const vEncoded = { ...v };
1358
+ if (v["lost_flow_threshold"]) {
1359
+ vEncoded["lost_flow_threshold"] = Number(v["lost_flow_threshold"] * 10);
1360
+ }
1361
+ return encodeThresholds(vEncoded, meta.state.alarm_set_3 || {}, alarmSet3ThresholdDefinitions);
1362
+ },
1363
+ },
1364
+ threshold_7: {
1365
+ from: (v) => {
1366
+ const result = parseThresholds(v, alarmSet1BThresholdDefinitions);
1367
+ if (result["rs485_baud_rate"]) {
1368
+ result["rs485_baud_rate"] = 1200 * 2 ** Number(result["rs485_baud_rate"]);
1369
+ }
1370
+ if (result["rs485_data_format"]) {
1371
+ result["rs485_data_format"] = utils.getFromLookup(result["rs485_data_format"], { 81: "N81", 82: "E81", 83: "O81", 84: "N82" });
1372
+ }
1373
+ return result;
1374
+ },
1375
+ to: (v, meta) => {
1376
+ const vEncoded = { ...v };
1377
+ if (v["rs485_baud_rate"]) {
1378
+ vEncoded["rs485_baud_rate"] = Math.log2(Number(v["rs485_baud_rate"]) / 1200);
1379
+ }
1380
+ if (v["rs485_data_format"]) {
1381
+ vEncoded["rs485_data_format"] = utils.getFromLookup(v["rs485_data_format"], { N81: 81, E81: 82, O81: 83, N82: 84 });
1382
+ }
1383
+ return encodeThresholds(vEncoded, meta.state.alarm_set_1 || {}, alarmSet1BThresholdDefinitions);
1384
+ },
1385
+ },
1386
+ threshold_8: {
1387
+ from: (v) => {
1388
+ const result = parseThresholds(v, alarmSet2ThresholdDefinitions);
1389
+ if (result["data_reporting_interval"]) {
1390
+ result["data_reporting_interval"] = Number(result["data_reporting_interval"]) / 2;
1391
+ }
1392
+ return result;
1393
+ },
1394
+ to: (v, meta) => {
1395
+ const vEncoded = { ...v };
1396
+ if (v["data_reporting_interval"]) {
1397
+ vEncoded["data_reporting_interval"] = Number(v["data_reporting_interval"] * 2);
1398
+ }
1399
+ return encodeThresholds(vEncoded, meta.state.alarm_set_2 || {}, alarmSet2ThresholdDefinitions);
1400
+ },
1401
+ },
829
1402
  selfTestResult: exports.valueConverterBasic.lookup({ checking: 0, success: 1, failure: 2, others: 3 }),
830
1403
  lockUnlock: exports.valueConverterBasic.lookup({ LOCK: true, UNLOCK: false }),
831
1404
  localTempCalibration1: {
@@ -864,6 +1437,34 @@ exports.valueConverter = {
864
1437
  return v;
865
1438
  },
866
1439
  },
1440
+ localTempCalibration4: {
1441
+ from: (v) => {
1442
+ if (v > 0x7fffffff)
1443
+ v -= 0x100000000;
1444
+ return v / 100;
1445
+ },
1446
+ to: (v) => {
1447
+ if (v > 0)
1448
+ return v * 100;
1449
+ if (v < 0)
1450
+ return v * 100 + 0x100000000;
1451
+ return v;
1452
+ },
1453
+ },
1454
+ localTempCalibration5: {
1455
+ from: (v) => {
1456
+ if (v > 0x7fffffff)
1457
+ v -= 0x100000000;
1458
+ return v;
1459
+ },
1460
+ to: (v) => {
1461
+ if (v > 0)
1462
+ return v;
1463
+ if (v < 0)
1464
+ return v + 0x100000000;
1465
+ return v;
1466
+ },
1467
+ },
867
1468
  thermostatHolidayStartStop: {
868
1469
  from: (v) => {
869
1470
  const start = {
@@ -893,7 +1494,7 @@ exports.valueConverter = {
893
1494
  thermostatHolidayStartStopUnixTS: {
894
1495
  // converts 8-byte big-endian 2 times Unix timestamps array to "YYYY/MM/DD HH:MM | YYYY/MM/DD HH:MM" string
895
1496
  from: (v) => {
896
- if (!v || v.length !== 8)
1497
+ if (v?.length !== 8)
897
1498
  return "";
898
1499
  // Convert first 4 bytes → start Unix timestamp
899
1500
  const startUnixTS = (v[0] << 24) | (v[1] << 16) | (v[2] << 8) | v[3];
@@ -1609,6 +2210,148 @@ exports.valueConverter = {
1609
2210
  return Buffer.from(s, "hex").swap16().toString("utf16le").trim();
1610
2211
  },
1611
2212
  },
2213
+ inchingSwitch2: {
2214
+ to: (value, meta) => {
2215
+ const currentState = meta.state.inching || { state: "OFF", minutes: 1, seconds: 0 };
2216
+ const state = value.state !== undefined ? value.state : currentState.state;
2217
+ const minutes = value.minutes !== undefined ? value.minutes : currentState.minutes;
2218
+ const seconds = value.seconds !== undefined ? value.seconds : currentState.seconds;
2219
+ let totalSeconds = Math.max(1, minutes * 60 + seconds);
2220
+ if (totalSeconds > 65535)
2221
+ totalSeconds = 65535;
2222
+ const buf = Buffer.alloc(3);
2223
+ buf.writeUInt8(state === "ON" ? 1 : 0, 0);
2224
+ buf.writeUInt16BE(totalSeconds, 1);
2225
+ return buf.toString("base64");
2226
+ },
2227
+ from: (value) => {
2228
+ const buf = typeof value === "string" ? Buffer.from(value, "base64") : Buffer.from(value);
2229
+ const state = buf.readUInt8(0) === 1 ? "ON" : "OFF";
2230
+ const totalSeconds = buf.readUInt16BE(1);
2231
+ const minutes = Math.floor(totalSeconds / 60);
2232
+ const seconds = totalSeconds % 60;
2233
+ return { state, minutes, seconds };
2234
+ },
2235
+ },
2236
+ circuitBreakerFaults: {
2237
+ from: (value) => {
2238
+ // value is a bitmap where each bit represents a fault flag
2239
+ const faults = [];
2240
+ for (let i = 0; i < exports.circuitBreakerFaultList.length; i++) {
2241
+ const bit = 1 << i;
2242
+ if ((value & bit) === bit) {
2243
+ faults.push(exports.circuitBreakerFaultList[i]);
2244
+ }
2245
+ }
2246
+ return faults;
2247
+ },
2248
+ },
2249
+ circuitBreakerFaults1: {
2250
+ from: (value) => {
2251
+ // value is a bitmap where each bit represents a fault flag
2252
+ const faults = [];
2253
+ for (let i = 0; i < exports.circuitBreakerFaultList.length; i++) {
2254
+ const bit = 1 << i;
2255
+ if ((value & bit) === bit) {
2256
+ if (exports.circuitBreakerFaultList[i] === "magnetism")
2257
+ faults.push("negative_power");
2258
+ else
2259
+ faults.push(exports.circuitBreakerFaultList[i]);
2260
+ }
2261
+ }
2262
+ return faults;
2263
+ },
2264
+ },
2265
+ reset: {
2266
+ to: (v) => {
2267
+ if (v === "RESET")
2268
+ return false;
2269
+ },
2270
+ from: (v) => {
2271
+ return "idle";
2272
+ },
2273
+ },
2274
+ energyBalanceAdd: {
2275
+ to: (v) => {
2276
+ return v * 100;
2277
+ },
2278
+ from: (v) => {
2279
+ return 0;
2280
+ },
2281
+ },
2282
+ circuitBreakerStatus: exports.valueConverterBasic.lookup({ off: new Enum(0), consumption: new Enum(1), production: new Enum(2) }), // only 0-1 is confirmed
2283
+ cycleSchedule: {
2284
+ // https://developer.tuya.com/en/docs/iot/cycle_timing?id=Kb4vhzu0ryfwm
2285
+ // Configure device with schedules of alternating on/off cycles.
2286
+ // Between start and end (time of day), on selected days, repeat:
2287
+ // ON for onDuration, then OFF for offDuration.
2288
+ from: (v) => {
2289
+ const buf = Buffer.from(v, "base64");
2290
+ const schedules = [];
2291
+ for (let offset = 10; offset + 9 < buf.length; offset += 10) {
2292
+ schedules.push({
2293
+ enabled: buf.readUInt8(offset) === 1,
2294
+ daysMask: buf.readUInt8(offset + 1),
2295
+ startTime: buf.readUInt16BE(offset + 2),
2296
+ endTime: buf.readUInt16BE(offset + 4),
2297
+ onDuration: buf.readUInt16BE(offset + 6),
2298
+ offDuration: buf.readUInt16BE(offset + 8),
2299
+ // unit is minutes
2300
+ });
2301
+ }
2302
+ return schedules;
2303
+ },
2304
+ },
2305
+ GX03ValveState: (zoneNum) => {
2306
+ const lookup = { 0: "Manual", 1: "Auto", 2: "Closed" };
2307
+ return {
2308
+ from: (value, meta, options, publish) => {
2309
+ // Set initial value to both timers to unlock UI
2310
+ if (meta.state?.timer_1 === undefined) {
2311
+ publish({
2312
+ timer_1: 5,
2313
+ timer_2: 5,
2314
+ });
2315
+ const endpoint = meta.device.getEndpoint(1);
2316
+ void (async () => {
2317
+ await sendDataPointValue(endpoint, 13, 5);
2318
+ await sendDataPointValue(endpoint, 14, 5);
2319
+ })();
2320
+ }
2321
+ // Reset the related countdown on valve closing
2322
+ if (value === 2) {
2323
+ publish({ [`countdown_${zoneNum}`]: 0 });
2324
+ }
2325
+ if (typeof value === "number" && value in lookup) {
2326
+ return lookup[value];
2327
+ }
2328
+ return `Unknown (${value})`;
2329
+ },
2330
+ };
2331
+ },
2332
+ autoAdjustment: {
2333
+ to: (v) => {
2334
+ return v === "START";
2335
+ },
2336
+ from: (v) => {
2337
+ return "idle";
2338
+ },
2339
+ },
2340
+ switchStates: {
2341
+ to: (v, meta) => {
2342
+ if (v === "SWITCH") {
2343
+ switch (meta.state.state) {
2344
+ case "ON":
2345
+ return false;
2346
+ case "OFF":
2347
+ return true;
2348
+ }
2349
+ }
2350
+ },
2351
+ from: (v) => {
2352
+ return "idle";
2353
+ },
2354
+ },
1612
2355
  };
1613
2356
  const tuyaTz = {
1614
2357
  power_on_behavior_1: {
@@ -1749,7 +2492,10 @@ const tuyaTz = {
1749
2492
  key: ["color_power_on_behavior"],
1750
2493
  convertSet: async (entity, key, value, meta) => {
1751
2494
  const v = utils.getFromLookup(value, { initial: 0, previous: 1, customized: 2 });
1752
- await entity.command("lightingColorCtrl", "tuyaOnStartUp", { mode: v * 256, data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] });
2495
+ await entity.command("lightingColorCtrl", "tuyaOnStartUp", {
2496
+ mode: v * 256,
2497
+ data: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
2498
+ });
1753
2499
  return { state: { color_power_on_behavior: value } };
1754
2500
  },
1755
2501
  },
@@ -1807,7 +2553,9 @@ const tuyaTz = {
1807
2553
  do_not_disturb: {
1808
2554
  key: ["do_not_disturb"],
1809
2555
  convertSet: async (entity, key, value, meta) => {
1810
- await entity.command("lightingColorCtrl", "tuyaDoNotDisturb", { enable: value ? 1 : 0 });
2556
+ await entity.command("lightingColorCtrl", "tuyaDoNotDisturb", {
2557
+ enable: value ? 1 : 0,
2558
+ });
1811
2559
  return { state: { do_not_disturb: value } };
1812
2560
  },
1813
2561
  },
@@ -1874,6 +2622,363 @@ const tuyaTz = {
1874
2622
  return { state: { inching_control_set: value } };
1875
2623
  },
1876
2624
  },
2625
+ cover_calibration: {
2626
+ key: [
2627
+ "calibration",
2628
+ "calibration_to_open",
2629
+ "calibration_to_close",
2630
+ "calibration_time",
2631
+ "calibration_time_to_open",
2632
+ "calibration_time_to_close",
2633
+ ],
2634
+ convertSet: async (entity, key, value, meta) => {
2635
+ if (key.startsWith("calibration_time")) {
2636
+ utils.assertNumber(value, key);
2637
+ const calibration_time = value * 10;
2638
+ if (key === "calibration_time" || key === "calibration_time_to_open") {
2639
+ await entity.write("closuresWindowCovering", {
2640
+ moesCalibrationTime: calibration_time,
2641
+ });
2642
+ }
2643
+ else if (key === "calibration_time_to_close") {
2644
+ await meta.device.getEndpoint(2).write("closuresWindowCovering", {
2645
+ moesCalibrationTime: calibration_time,
2646
+ });
2647
+ }
2648
+ return { state: { [key]: value } };
2649
+ }
2650
+ utils.assertString(value, key);
2651
+ const lookup = { ON: 0, OFF: 1 };
2652
+ value = value.toUpperCase();
2653
+ const calibration = utils.getFromLookup(value, lookup);
2654
+ if (key === "calibration" || key === "calibration_to_open") {
2655
+ await entity.write("closuresWindowCovering", { tuyaCalibration: calibration });
2656
+ }
2657
+ else if (key === "calibration_to_close") {
2658
+ await meta.device
2659
+ .getEndpoint(2)
2660
+ .write("closuresWindowCovering", { tuyaCalibration: calibration });
2661
+ }
2662
+ return { state: { [key]: value } };
2663
+ },
2664
+ convertGet: async (entity, key, meta) => {
2665
+ if (key === "calibration" || key === "calibration_to_open") {
2666
+ await entity.read("closuresWindowCovering", ["tuyaCalibration"]);
2667
+ }
2668
+ else if (key === "calibration_to_close") {
2669
+ await meta.device
2670
+ .getEndpoint(2)
2671
+ .read("closuresWindowCovering", ["tuyaCalibration"]);
2672
+ }
2673
+ else if (key === "calibration_time" || key === "calibration_time_to_open") {
2674
+ await entity.read("closuresWindowCovering", ["moesCalibrationTime"]);
2675
+ }
2676
+ else if (key === "calibration_time_to_close") {
2677
+ await meta.device
2678
+ .getEndpoint(2)
2679
+ .read("closuresWindowCovering", ["moesCalibrationTime"]);
2680
+ }
2681
+ },
2682
+ },
2683
+ operation_mode: {
2684
+ key: ["operation_mode"],
2685
+ convertSet: async (entity, key, value, meta) => {
2686
+ // modes:
2687
+ // 0 - 'command' mode. keys send commands. useful for group control
2688
+ // 1 - 'event' mode. keys send events. useful for handling
2689
+ utils.assertString(value, key);
2690
+ const endpoint = meta.device.getEndpoint(1);
2691
+ await endpoint.write("genOnOff", { tuyaOperationMode: utils.getFromLookup(value, { command: 0, event: 1 }) });
2692
+ return { state: { operation_mode: value.toLowerCase() } };
2693
+ },
2694
+ convertGet: async (entity, key, meta) => {
2695
+ const endpoint = meta.device.getEndpoint(1);
2696
+ await endpoint.read("genOnOff", ["tuyaOperationMode"]);
2697
+ },
2698
+ },
2699
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2700
+ TS110E_onoff_brightness: {
2701
+ key: ["state", "brightness"],
2702
+ convertSet: async (entity, key, value, meta) => {
2703
+ const { message, state } = meta;
2704
+ if (message.state === "OFF" || (message.state != null && message.brightness == null)) {
2705
+ return await tz.on_off.convertSet(entity, key, value, meta);
2706
+ }
2707
+ if (message.brightness != null) {
2708
+ // set brightness
2709
+ if (state.state === "OFF") {
2710
+ await entity.command("genOnOff", "on", {}, utils.getOptions(meta.mapped, entity));
2711
+ }
2712
+ const brightness = utils.toNumber(message.brightness, "brightness");
2713
+ const level = utils.mapNumberRange(brightness, 0, 254, 0, 1000);
2714
+ await entity.command("genLevelCtrl", "moveToLevelTuya", { level, transtime: 100 }, utils.getOptions(meta.mapped, entity));
2715
+ return { state: { state: "ON", brightness } };
2716
+ }
2717
+ },
2718
+ convertGet: async (entity, key, meta) => {
2719
+ if (key === "state")
2720
+ await tz.on_off.convertGet(entity, key, meta);
2721
+ if (key === "brightness")
2722
+ await entity.read("genLevelCtrl", [61440]);
2723
+ },
2724
+ },
2725
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2726
+ TS110E_options: {
2727
+ key: ["min_brightness", "max_brightness", "light_type", "switch_type"],
2728
+ convertSet: async (entity, key, value, meta) => {
2729
+ let payload = null;
2730
+ if (key === "min_brightness" || key === "max_brightness") {
2731
+ const id = key === "min_brightness" ? 64515 : 64516;
2732
+ payload = { [id]: { value: utils.mapNumberRange(utils.toNumber(value, key), 1, 255, 0, 1000), type: 0x21 } };
2733
+ }
2734
+ else if (key === "light_type" || key === "switch_type") {
2735
+ utils.assertString(value, "light_type/switch_type");
2736
+ const lookup = key === "light_type" ? { led: 0, incandescent: 1, halogen: 2 } : { momentary: 0, toggle: 1, state: 2 };
2737
+ payload = { 64514: { value: lookup[value], type: 0x20 } };
2738
+ }
2739
+ await entity.write("genLevelCtrl", payload, utils.getOptions(meta.mapped, entity));
2740
+ return { state: { [key]: value } };
2741
+ },
2742
+ convertGet: async (entity, key, meta) => {
2743
+ let id = null;
2744
+ if (key === "min_brightness")
2745
+ id = 64515;
2746
+ if (key === "max_brightness")
2747
+ id = 64516;
2748
+ if (key === "light_type" || key === "switch_type")
2749
+ id = 64514;
2750
+ await entity.read("genLevelCtrl", [id]);
2751
+ },
2752
+ },
2753
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
2754
+ TS110E_light_onoff_brightness: {
2755
+ ...tz.light_onoff_brightness,
2756
+ convertSet: async (entity, key, value, meta) => {
2757
+ const { message } = meta;
2758
+ if (message.state === "ON" || (typeof message.brightness === "number" && message.brightness > 1)) {
2759
+ // Does not turn off with physical press when turned on with just moveToLevelWithOnOff, required on before.
2760
+ // https://github.com/Koenkk/zigbee2mqtt/issues/15902#issuecomment-1382848150
2761
+ await entity.command("genOnOff", "on", {}, utils.getOptions(meta.mapped, entity));
2762
+ }
2763
+ return await tz.light_onoff_brightness.convertSet(entity, key, value, meta);
2764
+ },
2765
+ },
2766
+ cover_reversal: {
2767
+ key: ["motor_reversal"],
2768
+ convertSet: async (entity, key, value, meta) => {
2769
+ utils.assertString(value, key);
2770
+ const lookup = { ON: 1, OFF: 0 };
2771
+ value = value.toUpperCase();
2772
+ const reversal = utils.getFromLookup(value, lookup);
2773
+ await entity.write("closuresWindowCovering", { tuyaMotorReversal: reversal });
2774
+ return { state: { motor_reversal: value } };
2775
+ },
2776
+ convertGet: async (entity, key, meta) => {
2777
+ await entity.read("closuresWindowCovering", ["tuyaMotorReversal"]);
2778
+ },
2779
+ },
2780
+ moes_cover_calibration: {
2781
+ key: ["calibration_time"],
2782
+ convertSet: async (entity, key, value, meta) => {
2783
+ utils.assertNumber(value);
2784
+ const calibration = value * 10;
2785
+ await entity.write("closuresWindowCovering", { moesCalibrationTime: calibration });
2786
+ return { state: { calibration_time: value } };
2787
+ },
2788
+ convertGet: async (entity, key, meta) => {
2789
+ await entity.read("closuresWindowCovering", ["moesCalibrationTime"]);
2790
+ },
2791
+ },
2792
+ led_control: {
2793
+ key: ["brightness", "color", "color_temp"],
2794
+ options: [exposes.options.color_sync()],
2795
+ convertSet: async (entity, key, value, meta) => {
2796
+ if (key === "brightness" &&
2797
+ meta.state.color_mode === constants.colorModeLookup[2] &&
2798
+ meta.message.color == null &&
2799
+ meta.message.color_temp == null) {
2800
+ const level = Number(value);
2801
+ await entity.command("genLevelCtrl", "moveToLevel", { level, transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
2802
+ globalStore.putValue(entity, "brightness", level);
2803
+ return { state: { brightness: level } };
2804
+ }
2805
+ if (key === "brightness" && utils.isNumber(meta.message.color_temp)) {
2806
+ const level = Number(value);
2807
+ await entity.command("lightingColorCtrl", "tuyaRgbMode", { enable: 0 });
2808
+ await entity.command("lightingColorCtrl", "moveToColorTemp", {
2809
+ colortemp: utils.mapNumberRange(meta.message.color_temp, 500, 154, 0, 254),
2810
+ transtime: 0,
2811
+ optionsMask: 0,
2812
+ optionsOverride: 0,
2813
+ }, utils.getOptions(meta.mapped, entity));
2814
+ await entity.command("genLevelCtrl", "moveToLevel", { level, transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
2815
+ globalStore.putValue(entity, "brightness", level);
2816
+ const newState = {
2817
+ brightness: level,
2818
+ color_mode: constants.colorModeLookup[2],
2819
+ color_temp: meta.message.color_temp,
2820
+ };
2821
+ return { state: libColor.syncColorState(newState, meta.state, entity, meta.options) };
2822
+ }
2823
+ if (key === "color_temp") {
2824
+ utils.assertNumber(value, key);
2825
+ const level = globalStore.getValue(entity, "brightness") || 100;
2826
+ await entity.command("lightingColorCtrl", "tuyaRgbMode", { enable: 0 });
2827
+ await entity.command("lightingColorCtrl", "moveToColorTemp", { colortemp: utils.mapNumberRange(value, 500, 154, 0, 254), transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
2828
+ await entity.command("genLevelCtrl", "moveToLevel", { level, transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
2829
+ const newState = {
2830
+ brightness: level,
2831
+ color_mode: constants.colorModeLookup[2],
2832
+ color_temp: value,
2833
+ };
2834
+ return { state: libColor.syncColorState(newState, meta.state, entity, meta.options) };
2835
+ }
2836
+ const zclData = {
2837
+ brightness: globalStore.getValue(entity, "brightness") || 100,
2838
+ // @ts-expect-error ignore
2839
+ hue: utils.mapNumberRange(meta.state.color.h, 0, 360, 0, 254) || 100,
2840
+ // @ts-expect-error ignore
2841
+ saturation: utils.mapNumberRange(meta.state.color.s, 0, 100, 0, 254) || 100,
2842
+ transtime: 0,
2843
+ };
2844
+ if (utils.isObject(value)) {
2845
+ if (value.h) {
2846
+ zclData.hue = utils.mapNumberRange(value.h, 0, 360, 0, 254);
2847
+ }
2848
+ if (value.hue) {
2849
+ zclData.hue = utils.mapNumberRange(value.hue, 0, 360, 0, 254);
2850
+ }
2851
+ if (value.s) {
2852
+ zclData.saturation = utils.mapNumberRange(value.s, 0, 100, 0, 254);
2853
+ }
2854
+ if (value.saturation) {
2855
+ zclData.saturation = utils.mapNumberRange(value.saturation, 0, 100, 0, 254);
2856
+ }
2857
+ if (value.b) {
2858
+ zclData.brightness = Number(value.b);
2859
+ }
2860
+ if (value.brightness) {
2861
+ zclData.brightness = Number(value.brightness);
2862
+ }
2863
+ if (typeof value === "number") {
2864
+ zclData.brightness = value;
2865
+ }
2866
+ }
2867
+ if (meta.message.color != null) {
2868
+ if (utils.isObject(meta.message.color)) {
2869
+ if (meta.message.color.h) {
2870
+ zclData.hue = utils.mapNumberRange(meta.message.color.h, 0, 360, 0, 254);
2871
+ }
2872
+ if (meta.message.color.s) {
2873
+ zclData.saturation = utils.mapNumberRange(meta.message.color.s, 0, 100, 0, 254);
2874
+ }
2875
+ if (meta.message.color.b) {
2876
+ zclData.brightness = Number(meta.message.color.b);
2877
+ }
2878
+ if (meta.message.color.brightness) {
2879
+ zclData.brightness = Number(meta.message.color.brightness);
2880
+ }
2881
+ }
2882
+ }
2883
+ await entity.command("lightingColorCtrl", "tuyaRgbMode", { enable: 1 });
2884
+ await entity.command("lightingColorCtrl", "tuyaMoveToHueAndSaturationBrightness", zclData, utils.getOptions(meta.mapped, entity));
2885
+ globalStore.putValue(entity, "brightness", zclData.brightness);
2886
+ const newState = {
2887
+ brightness: zclData.brightness,
2888
+ color: {
2889
+ h: utils.mapNumberRange(zclData.hue, 0, 254, 0, 360),
2890
+ hue: utils.mapNumberRange(zclData.hue, 0, 254, 0, 360),
2891
+ s: utils.mapNumberRange(zclData.saturation, 0, 254, 0, 100),
2892
+ saturation: utils.mapNumberRange(zclData.saturation, 0, 254, 0, 100),
2893
+ },
2894
+ color_mode: constants.colorModeLookup[0],
2895
+ };
2896
+ return { state: libColor.syncColorState(newState, meta.state, entity, meta.options) };
2897
+ },
2898
+ convertGet: async (entity, key, meta) => {
2899
+ await entity.read("lightingColorCtrl", [
2900
+ "currentHue",
2901
+ "currentSaturation",
2902
+ "tuyaBrightness",
2903
+ "tuyaRgbMode",
2904
+ "colorTemperature",
2905
+ ]);
2906
+ },
2907
+ },
2908
+ relay_din_led_indicator: {
2909
+ key: ["indicator_mode"],
2910
+ convertSet: async (entity, key, value, meta) => {
2911
+ utils.assertString(value, key);
2912
+ value = value.toLowerCase();
2913
+ const lookup = { off: 0x00, on_off: 0x01, off_on: 0x02 };
2914
+ const payload = utils.getFromLookup(value, lookup);
2915
+ await entity.write("genOnOff", { 32769: { value: payload, type: 0x30 } });
2916
+ return { state: { indicator_mode: value } };
2917
+ },
2918
+ },
2919
+ led_controller: {
2920
+ key: ["state", "color"],
2921
+ convertSet: async (entity, key, value, meta) => {
2922
+ if (key === "state") {
2923
+ utils.assertString(value, key);
2924
+ if (value.toLowerCase() === "off") {
2925
+ await entity.command("genOnOff", "offWithEffect", { effectid: 0x01, effectvariant: 0x01 }, utils.getOptions(meta.mapped, entity));
2926
+ }
2927
+ else {
2928
+ await entity.command("genLevelCtrl", "moveToLevelWithOnOff", { level: 255, transtime: 0, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
2929
+ }
2930
+ return { state: { state: value.toUpperCase() } };
2931
+ }
2932
+ if (key === "color") {
2933
+ utils.assertObject(value);
2934
+ const hue = utils.mapNumberRange(value.h, 0, 360, 0, 254);
2935
+ const saturation = utils.mapNumberRange(value.s, 0, 100, 0, 254);
2936
+ const transtime = 0;
2937
+ const direction = 0;
2938
+ await entity.command("lightingColorCtrl", "moveToHue", { hue, transtime, direction, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
2939
+ await entity.command("lightingColorCtrl", "moveToSaturation", { saturation, transtime, optionsMask: 0, optionsOverride: 0 }, utils.getOptions(meta.mapped, entity));
2940
+ }
2941
+ },
2942
+ convertGet: async (entity, key, meta) => {
2943
+ if (key === "state") {
2944
+ await entity.read("genOnOff", ["onOff"]);
2945
+ }
2946
+ else if (key === "color") {
2947
+ await entity.read("lightingColorCtrl", ["currentHue", "currentSaturation"]);
2948
+ }
2949
+ },
2950
+ },
2951
+ ts0216_duration: {
2952
+ key: ["duration"],
2953
+ convertSet: async (entity, key, value, meta) => {
2954
+ await entity.write("ssIasWd", { maxDuration: value });
2955
+ },
2956
+ convertGet: async (entity, key, meta) => {
2957
+ await entity.read("ssIasWd", ["maxDuration"]);
2958
+ },
2959
+ },
2960
+ ts0216_volume: {
2961
+ key: ["volume"],
2962
+ convertSet: async (entity, key, value, meta) => {
2963
+ utils.assertNumber(value);
2964
+ if (["_TYZB01_sbpc1zrb"].includes(meta.device.manufacturerName)) {
2965
+ const volume = value === 0 ? 0 : utils.mapNumberRange(value, 1, 100, 100, 33);
2966
+ await entity.write("ssIasWd", { 2: { value: volume, type: 0x20 } });
2967
+ return;
2968
+ }
2969
+ await entity.write("ssIasWd", { 2: { value: utils.mapNumberRange(value, 0, 100, 100, 10), type: 0x20 } });
2970
+ },
2971
+ convertGet: async (entity, key, meta) => {
2972
+ await entity.read("ssIasWd", [0x0002]);
2973
+ },
2974
+ },
2975
+ ts0216_alarm: {
2976
+ key: ["alarm"],
2977
+ convertSet: async (entity, key, value, meta) => {
2978
+ const info = value ? (2 << 4) + (1 << 2) + 0 : 0;
2979
+ await entity.command("ssIasWd", "startWarning", { startwarninginfo: info, warningduration: 0, strobedutycycle: 0, strobelevel: 3 }, utils.getOptions(meta.mapped, entity));
2980
+ },
2981
+ },
1877
2982
  };
1878
2983
  exports.tz = tuyaTz;
1879
2984
  const tuyaFz = {
@@ -2029,7 +3134,7 @@ const tuyaFz = {
2029
3134
  if (utils.hasAlreadyProcessedMessage(msg, model))
2030
3135
  return;
2031
3136
  const result = {};
2032
- if (!model.meta || !model.meta.tuyaDatapoints)
3137
+ if (!model.meta?.tuyaDatapoints)
2033
3138
  throw new Error("No datapoints map defined");
2034
3139
  const datapoints = model.meta.tuyaDatapoints;
2035
3140
  for (const dpValue of msg.data.dpValues) {
@@ -2134,6 +3239,218 @@ const tuyaFz = {
2134
3239
  return result;
2135
3240
  },
2136
3241
  },
3242
+ cover_options: {
3243
+ cluster: "closuresWindowCovering",
3244
+ type: ["attributeReport", "readResponse"],
3245
+ convert: (model, msg, publish, options, meta) => {
3246
+ const result = {};
3247
+ if (msg.data.tuyaMovingState !== undefined) {
3248
+ const value = msg.data.tuyaMovingState;
3249
+ const movingLookup = { 0: "UP", 1: "STOP", 2: "DOWN" };
3250
+ result[utils.postfixWithEndpointName("moving", msg, model, meta)] = movingLookup[value];
3251
+ }
3252
+ if (msg.data.tuyaCalibration !== undefined) {
3253
+ const value = msg.data.tuyaCalibration;
3254
+ const calibrationLookup = { 0: "ON", 1: "OFF" };
3255
+ result[utils.postfixWithEndpointName("calibration", msg, model, meta)] = calibrationLookup[value];
3256
+ }
3257
+ if (msg.data.tuyaMotorReversal !== undefined) {
3258
+ const value = msg.data.tuyaMotorReversal;
3259
+ const reversalLookup = { 0: "OFF", 1: "ON" };
3260
+ result[utils.postfixWithEndpointName("motor_reversal", msg, model, meta)] = reversalLookup[value];
3261
+ }
3262
+ if (msg.data.moesCalibrationTime !== undefined) {
3263
+ const value = msg.data.moesCalibrationTime / 10.0;
3264
+ if (["_TZ3000_cet6ch1r", "_TZ3000_5iixzdo7"].includes(meta.device.manufacturerName)) {
3265
+ const endpoint = msg.endpoint.ID;
3266
+ const calibrationLookup = { 1: "to_open", 2: "to_close" };
3267
+ result[utils.postfixWithEndpointName(`calibration_time_${calibrationLookup[endpoint]}`, msg, model, meta)] = value;
3268
+ }
3269
+ else {
3270
+ result[utils.postfixWithEndpointName("calibration_time", msg, model, meta)] = value;
3271
+ }
3272
+ }
3273
+ return result;
3274
+ },
3275
+ },
3276
+ cover_options_2: {
3277
+ cluster: "closuresWindowCovering",
3278
+ type: ["attributeReport", "readResponse"],
3279
+ convert: (model, msg, publish, options, meta) => {
3280
+ const result = {};
3281
+ if (msg.data.moesCalibrationTime !== undefined) {
3282
+ const value = msg.data.moesCalibrationTime / 100;
3283
+ result[utils.postfixWithEndpointName("calibration_time", msg, model, meta)] = value;
3284
+ }
3285
+ if (msg.data.tuyaMotorReversal !== undefined) {
3286
+ const value = msg.data.tuyaMotorReversal;
3287
+ const reversalLookup = { 0: "OFF", 1: "ON" };
3288
+ result[utils.postfixWithEndpointName("motor_reversal", msg, model, meta)] = reversalLookup[value];
3289
+ }
3290
+ return result;
3291
+ },
3292
+ },
3293
+ operation_mode: {
3294
+ cluster: "genOnOff",
3295
+ type: ["attributeReport", "readResponse"],
3296
+ convert: (model, msg, publish, options, meta) => {
3297
+ if (msg.data.tuyaOperationMode !== undefined) {
3298
+ const value = msg.data.tuyaOperationMode;
3299
+ const lookup = { 0: "command", 1: "event" };
3300
+ return { operation_mode: lookup[value] };
3301
+ }
3302
+ },
3303
+ },
3304
+ switch_scene: {
3305
+ cluster: "genOnOff",
3306
+ type: "commandTuyaAction",
3307
+ convert: (model, msg, publish, options, meta) => {
3308
+ if (utils.hasAlreadyProcessedMessage(msg, model))
3309
+ return;
3310
+ // Since it is a non standard ZCL command, no default response is send from zigbee-herdsman
3311
+ // Send the defaultResponse here, otherwise the second button click delays.
3312
+ // https://github.com/Koenkk/zigbee2mqtt/issues/8149
3313
+ return { action: "switch_scene", action_scene: msg.data.value };
3314
+ },
3315
+ },
3316
+ multi_action: {
3317
+ cluster: "genOnOff",
3318
+ type: ["commandTuyaAction", "commandTuyaAction2"],
3319
+ convert: (model, msg, publish, options, meta) => {
3320
+ if (utils.hasAlreadyProcessedMessage(msg, model))
3321
+ return;
3322
+ // biome-ignore lint/suspicious/noImplicitAnyLet: ignored using `--suppress`
3323
+ let action;
3324
+ if (msg.type === "commandTuyaAction") {
3325
+ const lookup = { 0: "single", 1: "double", 2: "hold" };
3326
+ action = lookup[msg.data.value];
3327
+ }
3328
+ else if (msg.type === "commandTuyaAction2") {
3329
+ const lookup = { 0: "rotate_right", 1: "rotate_left" };
3330
+ action = lookup[msg.data.value];
3331
+ }
3332
+ return { action };
3333
+ },
3334
+ },
3335
+ led_controller: {
3336
+ cluster: "lightingColorCtrl",
3337
+ type: ["attributeReport", "readResponse"],
3338
+ options: [exposes.options.color_sync()],
3339
+ convert: (model, msg, publish, options, meta) => {
3340
+ const result = {};
3341
+ if (msg.data.colorTemperature !== undefined) {
3342
+ const value = Number(msg.data.colorTemperature);
3343
+ const color_temp = utils.postfixWithEndpointName("color_temp", msg, model, meta);
3344
+ result[color_temp] = value;
3345
+ }
3346
+ if (msg.data.tuyaBrightness !== undefined) {
3347
+ const brightness = utils.postfixWithEndpointName("brightness", msg, model, meta);
3348
+ result[brightness] = msg.data.tuyaBrightness;
3349
+ }
3350
+ if (msg.data.tuyaRgbMode !== undefined) {
3351
+ const color_mode = utils.postfixWithEndpointName("color_mode", msg, model, meta);
3352
+ if (msg.data.tuyaRgbMode === 1) {
3353
+ result[color_mode] = constants.colorModeLookup[0];
3354
+ }
3355
+ else {
3356
+ result[color_mode] = constants.colorModeLookup[2];
3357
+ }
3358
+ }
3359
+ const color = utils.postfixWithEndpointName("color", msg, model, meta);
3360
+ result[color] = {};
3361
+ if (msg.data.currentHue !== undefined) {
3362
+ result[color].hue = utils.mapNumberRange(msg.data.currentHue, 0, 254, 0, 360);
3363
+ result[color].h = result[color].hue;
3364
+ }
3365
+ if (msg.data.currentSaturation !== undefined) {
3366
+ result[color].saturation = utils.mapNumberRange(msg.data.currentSaturation, 0, 254, 0, 100);
3367
+ result[color].s = result[color].saturation;
3368
+ }
3369
+ // Use postfixWithEndpointName with an empty value to get just the postfix that
3370
+ // can be added to the result keys.
3371
+ const epPostfix = utils.postfixWithEndpointName("", msg, model, meta);
3372
+ return Object.assign(result, libColor.syncColorState(result, meta.state, msg.endpoint, options, epPostfix));
3373
+ },
3374
+ },
3375
+ relay_din_led_indicator: {
3376
+ cluster: "genOnOff",
3377
+ type: ["attributeReport", "readResponse"],
3378
+ convert: (model, msg, publish, options, meta) => {
3379
+ const property = 0x8001;
3380
+ if (msg.data[property] !== undefined) {
3381
+ const dict = { 0: "off", 1: "on_off", 2: "off_on" };
3382
+ const value = msg.data[property];
3383
+ if (dict[value] !== undefined) {
3384
+ return { [utils.postfixWithEndpointName("indicator_mode", msg, model, meta)]: dict[value] };
3385
+ }
3386
+ }
3387
+ },
3388
+ },
3389
+ TS110E: {
3390
+ cluster: "genLevelCtrl",
3391
+ type: ["attributeReport", "readResponse"],
3392
+ convert: (model, msg, publish, options, meta) => {
3393
+ const result = {};
3394
+ if (msg.data["64515"] !== undefined) {
3395
+ result.min_brightness = utils.mapNumberRange(msg.data["64515"], 0, 1000, 1, 255);
3396
+ }
3397
+ if (msg.data["64516"] !== undefined) {
3398
+ result.max_brightness = utils.mapNumberRange(msg.data["64516"], 0, 1000, 1, 255);
3399
+ }
3400
+ if (msg.data["61440"] !== undefined) {
3401
+ const propertyName = utils.postfixWithEndpointName("brightness", msg, model, meta);
3402
+ result[propertyName] = utils.mapNumberRange(msg.data["61440"], 0, 1000, 0, 255);
3403
+ }
3404
+ return result;
3405
+ },
3406
+ },
3407
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3408
+ TS110E_light_type: {
3409
+ cluster: "genLevelCtrl",
3410
+ type: ["attributeReport", "readResponse"],
3411
+ convert: (model, msg, publish, options, meta) => {
3412
+ const result = {};
3413
+ if (msg.data["64514"] !== undefined) {
3414
+ const lookup = { 0: "led", 1: "incandescent", 2: "halogen" };
3415
+ result.light_type = lookup[msg.data["64514"]];
3416
+ }
3417
+ return result;
3418
+ },
3419
+ },
3420
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
3421
+ TS110E_switch_type: {
3422
+ cluster: "genLevelCtrl",
3423
+ type: ["attributeReport", "readResponse"],
3424
+ convert: (model, msg, publish, options, meta) => {
3425
+ const result = {};
3426
+ if (msg.data["64514"] !== undefined) {
3427
+ const lookup = { 0: "momentary", 1: "toggle", 2: "state" };
3428
+ const propertyName = utils.postfixWithEndpointName("switch_type", msg, model, meta);
3429
+ result[propertyName] = lookup[msg.data["64514"]];
3430
+ }
3431
+ return result;
3432
+ },
3433
+ },
3434
+ ts0216_siren: {
3435
+ cluster: "ssIasWd",
3436
+ type: ["attributeReport", "readResponse"],
3437
+ convert: (model, msg, publish, options, meta) => {
3438
+ const result = {};
3439
+ if (msg.data.maxDuration !== undefined)
3440
+ result.duration = msg.data.maxDuration;
3441
+ if (msg.data["2"] !== undefined) {
3442
+ result.volume = utils.mapNumberRange(msg.data["2"], 100, 10, 0, 100);
3443
+ }
3444
+ if (["_TYZB01_sbpc1zrb"].includes(meta.device.manufacturerName) && typeof msg.data["2"] === "number") {
3445
+ const volData = msg.data["2"];
3446
+ result.volume = volData === 0 ? 0 : utils.mapNumberRange(volData, 100, 33, 1, 100);
3447
+ }
3448
+ if (msg.data["61440"] !== undefined) {
3449
+ result.alarm = msg.data["61440"] !== 0;
3450
+ }
3451
+ return result;
3452
+ },
3453
+ },
2137
3454
  };
2138
3455
  exports.fz = tuyaFz;
2139
3456
  function getHandlersForDP(name, dp, type, converter, readOnly, skip, endpoint, useGlobalSequence) {
@@ -2383,6 +3700,30 @@ const tuyaModernExtend = {
2383
3700
  },
2384
3701
  ];
2385
3702
  }
3703
+ const tuyaGenBasic = tuyaClusters.addTuyaGenBasicCluster();
3704
+ const tuyaGenGroups = tuyaClusters.addTuyaGenGroupsCluster();
3705
+ const tuyaGenOnOff = tuyaClusters.addTuyaGenOnOffCluster();
3706
+ const tuyaGenLevelCtrl = tuyaClusters.addTuyaGenLevelCtrlCluster();
3707
+ const customCluster2 = tuyaClusters.addManuSpecificTuya2Cluster();
3708
+ const customCluster3 = tuyaClusters.addManuSpecificTuya3Cluster();
3709
+ result.onEvent = [
3710
+ ...(tuyaGenBasic.onEvent ?? []),
3711
+ ...(tuyaGenGroups.onEvent ?? []),
3712
+ ...(tuyaGenOnOff.onEvent ?? []),
3713
+ ...(tuyaGenLevelCtrl.onEvent ?? []),
3714
+ ...(customCluster2.onEvent ?? []),
3715
+ ...(customCluster3.onEvent ?? []),
3716
+ ...(result.onEvent ?? []),
3717
+ ];
3718
+ result.configure = [
3719
+ ...(tuyaGenBasic.configure ?? []),
3720
+ ...(tuyaGenGroups.configure ?? []),
3721
+ ...(tuyaGenOnOff.configure ?? []),
3722
+ ...(tuyaGenLevelCtrl.configure ?? []),
3723
+ ...(customCluster2.configure ?? []),
3724
+ ...(customCluster3.configure ?? []),
3725
+ ...(result.configure ?? []),
3726
+ ];
2386
3727
  if (dp) {
2387
3728
  result.fromZigbee.push(tuyaFz.datapoints);
2388
3729
  result.toZigbee.push(tuyaTz.datapoints);
@@ -2652,6 +3993,12 @@ const tuyaModernExtend = {
2652
3993
  result.toZigbee.push(tuyaTz.color_power_on_behavior);
2653
3994
  result.exposes.push(tuyaExposes.colorPowerOnBehavior());
2654
3995
  }
3996
+ const tuyaLightingColorCtrl = tuyaClusters.addTuyaLightingColorCtrlCluster();
3997
+ result.onEvent = [...(tuyaLightingColorCtrl.onEvent ?? []), ...(result.onEvent ?? [])];
3998
+ result.configure = [...(tuyaLightingColorCtrl.configure ?? []), ...(result.configure ?? [])];
3999
+ const customCluster3 = tuyaClusters.addManuSpecificTuya3Cluster();
4000
+ result.onEvent = [...(customCluster3.onEvent ?? []), ...(result.onEvent ?? [])];
4001
+ result.configure = [...(customCluster3.configure ?? []), ...(result.configure ?? [])];
2655
4002
  result.configure.push((0, utils_1.configureSetPowerSourceWhenUnknown)("Mains (single phase)"));
2656
4003
  return result;
2657
4004
  },
@@ -3015,23 +4362,184 @@ const tuyaModernExtend = {
3015
4362
  };
3016
4363
  exports.modernExtend = tuyaModernExtend;
3017
4364
  const tuyaClusters = {
4365
+ addTuyaClosuresWindowCoveringCluster: () => modernExtend.deviceAddCustomCluster("closuresWindowCovering", {
4366
+ name: "closuresWindowCovering",
4367
+ ID: zigbee_herdsman_1.Zcl.Clusters.closuresWindowCovering.ID,
4368
+ attributes: {
4369
+ tuyaMovingState: { name: "tuyaMovingState", ID: 0xf000, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4370
+ tuyaCalibration: { name: "tuyaCalibration", ID: 0xf001, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4371
+ tuyaMotorReversal: { name: "tuyaMotorReversal", ID: 0xf002, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4372
+ moesCalibrationTime: { name: "moesCalibrationTime", ID: 0xf003, type: zigbee_herdsman_1.Zcl.DataType.UINT16, write: true, max: 0xffff },
4373
+ },
4374
+ commands: {},
4375
+ commandsResponse: {},
4376
+ }),
4377
+ addTuyaGenBasicCluster: () => modernExtend.deviceAddCustomCluster("genBasic", {
4378
+ name: "genBasic",
4379
+ ID: zigbee_herdsman_1.Zcl.Clusters.genBasic.ID,
4380
+ attributes: {},
4381
+ commands: {
4382
+ tuyaSetup: { name: "tuyaSetup", ID: 0xf0, parameters: [] },
4383
+ },
4384
+ commandsResponse: {},
4385
+ }),
4386
+ addTuyaGenGroupsCluster: () => modernExtend.deviceAddCustomCluster("genGroups", {
4387
+ name: "genGroups",
4388
+ ID: zigbee_herdsman_1.Zcl.Clusters.genGroups.ID,
4389
+ attributes: {},
4390
+ commands: {
4391
+ miboxerSetZones: { name: "miboxerSetZones", ID: 0xf0, parameters: [{ name: "zones", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_MIBOXER_ZONES }] },
4392
+ },
4393
+ commandsResponse: {},
4394
+ }),
4395
+ addTuyaGenOnOffCluster: () => modernExtend.deviceAddCustomCluster("genOnOff", {
4396
+ name: "genOnOff",
4397
+ ID: zigbee_herdsman_1.Zcl.Clusters.genOnOff.ID,
4398
+ attributes: {
4399
+ tuyaBacklightSwitch: { name: "tuyaBacklightSwitch", ID: 0x5000, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4400
+ tuyaBacklightMode: { name: "tuyaBacklightMode", ID: 0x8001, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4401
+ moesStartUpOnOff: { name: "moesStartUpOnOff", ID: 0x8002, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4402
+ tuyaOperationMode: { name: "tuyaOperationMode", ID: 0x8004, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4403
+ },
4404
+ commands: {
4405
+ tuyaCountdown: {
4406
+ name: "tuyaCountdown",
4407
+ ID: 0xf0,
4408
+ parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.BUFFER }],
4409
+ },
4410
+ tuyaAction2: { name: "tuyaAction2", ID: 0xfc, parameters: [{ name: "value", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }] },
4411
+ tuyaAction: {
4412
+ name: "tuyaAction",
4413
+ ID: 0xfd,
4414
+ parameters: [
4415
+ { name: "value", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff },
4416
+ { name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.BUFFER },
4417
+ ],
4418
+ },
4419
+ },
4420
+ commandsResponse: {},
4421
+ }),
4422
+ addTuyaGenLevelCtrlCluster: () => modernExtend.deviceAddCustomCluster("genLevelCtrl", {
4423
+ name: "genLevelCtrl",
4424
+ ID: zigbee_herdsman_1.Zcl.Clusters.genLevelCtrl.ID,
4425
+ attributes: {},
4426
+ commands: {
4427
+ moveToLevelTuya: {
4428
+ name: "moveToLevelTuya",
4429
+ ID: 0xf0,
4430
+ parameters: [
4431
+ { name: "level", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff },
4432
+ { name: "transtime", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff },
4433
+ ],
4434
+ },
4435
+ },
4436
+ commandsResponse: {},
4437
+ }),
4438
+ addTuyaLightingColorCtrlCluster: () => modernExtend.deviceAddCustomCluster("lightingColorCtrl", {
4439
+ name: "lightingColorCtrl",
4440
+ ID: zigbee_herdsman_1.Zcl.Clusters.lightingColorCtrl.ID,
4441
+ attributes: {
4442
+ tuyaRgbMode: { name: "tuyaRgbMode", ID: 0xf000, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
4443
+ tuyaBrightness: { name: "tuyaBrightness", ID: 0xf001, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
4444
+ },
4445
+ commands: {
4446
+ tuyaMoveToHueAndSaturationBrightness: {
4447
+ name: "tuyaMoveToHueAndSaturationBrightness",
4448
+ ID: 0x06,
4449
+ parameters: [
4450
+ { name: "hue", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff },
4451
+ { name: "saturation", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff },
4452
+ { name: "transtime", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff },
4453
+ { name: "brightness", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff },
4454
+ ],
4455
+ },
4456
+ tuyaSetMinimumBrightness: {
4457
+ name: "tuyaSetMinimumBrightness",
4458
+ ID: 0xe0,
4459
+ parameters: [{ name: "minimum", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff }],
4460
+ },
4461
+ tuyaMoveToHueAndSaturationBrightness2: {
4462
+ name: "tuyaMoveToHueAndSaturationBrightness2",
4463
+ ID: 0xe1,
4464
+ parameters: [
4465
+ { name: "hue", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff },
4466
+ { name: "saturation", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff },
4467
+ { name: "brightness", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff },
4468
+ ],
4469
+ },
4470
+ tuyaRgbMode: { name: "tuyaRgbMode", ID: 0xf0, parameters: [{ name: "enable", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }] },
4471
+ tuyaOnStartUp: {
4472
+ name: "tuyaOnStartUp",
4473
+ ID: 0xf9,
4474
+ parameters: [
4475
+ { name: "mode", type: zigbee_herdsman_1.Zcl.DataType.UINT16, max: 0xffff },
4476
+ { name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.LIST_UINT8 },
4477
+ ],
4478
+ },
4479
+ tuyaDoNotDisturb: { name: "tuyaDoNotDisturb", ID: 0xfa, parameters: [{ name: "enable", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff }] },
4480
+ tuyaOnOffTransitionTime: {
4481
+ name: "tuyaOnOffTransitionTime",
4482
+ ID: 0xfb,
4483
+ parameters: [
4484
+ { name: "unknown", type: zigbee_herdsman_1.Zcl.DataType.UINT8, max: 0xff },
4485
+ { name: "onTransitionTime", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.BIG_ENDIAN_UINT24 },
4486
+ { name: "offTransitionTime", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.BIG_ENDIAN_UINT24 },
4487
+ ],
4488
+ },
4489
+ },
4490
+ commandsResponse: {},
4491
+ }),
4492
+ addManuSpecificTuya2Cluster: () => modernExtend.deviceAddCustomCluster("manuSpecificTuya2", {
4493
+ name: "manuSpecificTuya2",
4494
+ ID: 0xe002,
4495
+ attributes: {
4496
+ alarmTemperatureMax: { name: "alarmTemperatureMax", ID: 0xd00a, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, min: -32768, max: 32767 },
4497
+ alarmTemperatureMin: { name: "alarmTemperatureMin", ID: 0xd00b, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, min: -32768, max: 32767 },
4498
+ alarmHumidityMax: { name: "alarmHumidityMax", ID: 0xd00d, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, min: -32768, max: 32767 },
4499
+ alarmHumidityMin: { name: "alarmHumidityMin", ID: 0xd00e, type: zigbee_herdsman_1.Zcl.DataType.INT16, write: true, min: -32768, max: 32767 },
4500
+ alarmHumidity: { name: "alarmHumidity", ID: 0xd00f, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4501
+ alarmTemperature: { name: "alarmTemperature", ID: 0xd006, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4502
+ unknown: { name: "unknown", ID: 0xd010, type: zigbee_herdsman_1.Zcl.DataType.UINT8, write: true, max: 0xff },
4503
+ },
4504
+ commands: {},
4505
+ commandsResponse: {},
4506
+ }),
4507
+ addManuSpecificTuya3Cluster: () => modernExtend.deviceAddCustomCluster("manuSpecificTuya3", {
4508
+ name: "manuSpecificTuya3",
4509
+ ID: 0xe001,
4510
+ attributes: {
4511
+ powerOnBehavior: { name: "powerOnBehavior", ID: 0xd010, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4512
+ switchMode: { name: "switchMode", ID: 0xd020, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4513
+ switchType: { name: "switchType", ID: 0xd030, type: zigbee_herdsman_1.Zcl.DataType.ENUM8, write: true, max: 0xff },
4514
+ },
4515
+ commands: {
4516
+ setOptions1: { name: "setOptions1", ID: 0xe5, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.BUFFER }] },
4517
+ setOptions2: { name: "setOptions2", ID: 0xe6, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.BUFFER }] },
4518
+ setOptions3: { name: "setOptions3", ID: 0xe7, parameters: [{ name: "data", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.BUFFER }] },
4519
+ },
4520
+ commandsResponse: {},
4521
+ }),
3018
4522
  addTuyaCommonPrivateCluster: () => modernExtend.deviceAddCustomCluster("manuSpecificTuya4", {
4523
+ name: "manuSpecificTuya4",
3019
4524
  ID: 0xe000,
3020
4525
  attributes: {
3021
- random_timing: { ID: 0xd001, type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR, write: true },
3022
- cycle_timing: { ID: 0xd002, type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR, write: true },
3023
- inching: { ID: 0xd003, type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR, write: true },
4526
+ random_timing: { name: "random_timing", ID: 0xd001, type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR, write: true },
4527
+ cycle_timing: { name: "cycle_timing", ID: 0xd002, type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR, write: true },
4528
+ inching: { name: "inching", ID: 0xd003, type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR, write: true },
3024
4529
  },
3025
4530
  commands: {
3026
4531
  setRandomTiming: {
4532
+ name: "setRandomTiming",
3027
4533
  ID: 0xf7,
3028
4534
  parameters: [{ name: "payload", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.BUFFER }],
3029
4535
  },
3030
4536
  setCycleTiming: {
4537
+ name: "setCycleTiming",
3031
4538
  ID: 0xf8,
3032
4539
  parameters: [{ name: "payload", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.BUFFER }],
3033
4540
  },
3034
4541
  setInchingSwitch: {
4542
+ name: "setInchingSwitch",
3035
4543
  ID: 0xfb,
3036
4544
  parameters: [{ name: "payload", type: zigbee_herdsman_1.Zcl.BuffaloZclDataType.BUFFER }],
3037
4545
  },