zigbee-herdsman-converters 20.44.0 → 21.0.0-pre.1

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 (349) hide show
  1. package/converters/fromZigbee.d.ts +4 -6
  2. package/converters/fromZigbee.d.ts.map +1 -1
  3. package/converters/fromZigbee.js +3 -32
  4. package/converters/fromZigbee.js.map +1 -1
  5. package/converters/toZigbee.d.ts +1 -49
  6. package/converters/toZigbee.d.ts.map +1 -1
  7. package/converters/toZigbee.js +38 -46
  8. package/converters/toZigbee.js.map +1 -1
  9. package/devices/adeo.d.ts.map +1 -1
  10. package/devices/adeo.js +1 -2
  11. package/devices/adeo.js.map +1 -1
  12. package/devices/adurosmart.d.ts.map +1 -1
  13. package/devices/adurosmart.js +1 -2
  14. package/devices/adurosmart.js.map +1 -1
  15. package/devices/aeotec.js +1 -1
  16. package/devices/aeotec.js.map +1 -1
  17. package/devices/airam.d.ts.map +1 -1
  18. package/devices/airam.js +1 -13
  19. package/devices/airam.js.map +1 -1
  20. package/devices/amina.d.ts.map +1 -1
  21. package/devices/amina.js +1 -2
  22. package/devices/amina.js.map +1 -1
  23. package/devices/aurora_lighting.d.ts.map +1 -1
  24. package/devices/aurora_lighting.js +2 -3
  25. package/devices/aurora_lighting.js.map +1 -1
  26. package/devices/bitron.d.ts.map +1 -1
  27. package/devices/bitron.js +1 -2
  28. package/devices/bitron.js.map +1 -1
  29. package/devices/bosch.d.ts.map +1 -1
  30. package/devices/bosch.js +10 -9
  31. package/devices/bosch.js.map +1 -1
  32. package/devices/bticino.d.ts.map +1 -1
  33. package/devices/bticino.js +2 -3
  34. package/devices/bticino.js.map +1 -1
  35. package/devices/busch_jaeger.d.ts.map +1 -1
  36. package/devices/busch_jaeger.js +1 -11
  37. package/devices/busch_jaeger.js.map +1 -1
  38. package/devices/chacon.js +1 -1
  39. package/devices/chacon.js.map +1 -1
  40. package/devices/ctm.d.ts.map +1 -1
  41. package/devices/ctm.js +5 -8
  42. package/devices/ctm.js.map +1 -1
  43. package/devices/custom_devices_diy.d.ts.map +1 -1
  44. package/devices/custom_devices_diy.js +6 -10
  45. package/devices/custom_devices_diy.js.map +1 -1
  46. package/devices/danalock.d.ts.map +1 -1
  47. package/devices/danalock.js +1 -2
  48. package/devices/danalock.js.map +1 -1
  49. package/devices/danfoss.d.ts.map +1 -1
  50. package/devices/danfoss.js +1 -2
  51. package/devices/danfoss.js.map +1 -1
  52. package/devices/datek.d.ts.map +1 -1
  53. package/devices/datek.js +2 -5
  54. package/devices/datek.js.map +1 -1
  55. package/devices/develco.d.ts.map +1 -1
  56. package/devices/develco.js +19 -20
  57. package/devices/develco.js.map +1 -1
  58. package/devices/diyruz.d.ts.map +1 -1
  59. package/devices/diyruz.js +1 -2
  60. package/devices/diyruz.js.map +1 -1
  61. package/devices/dresden_elektronik.d.ts.map +1 -1
  62. package/devices/dresden_elektronik.js +3 -27
  63. package/devices/dresden_elektronik.js.map +1 -1
  64. package/devices/ecodim.d.ts.map +1 -1
  65. package/devices/ecodim.js +1 -2
  66. package/devices/ecodim.js.map +1 -1
  67. package/devices/ecozy.d.ts.map +1 -1
  68. package/devices/ecozy.js +1 -2
  69. package/devices/ecozy.js.map +1 -1
  70. package/devices/eurotronic.d.ts.map +1 -1
  71. package/devices/eurotronic.js +1 -2
  72. package/devices/eurotronic.js.map +1 -1
  73. package/devices/fantem.d.ts.map +1 -1
  74. package/devices/fantem.js +0 -1
  75. package/devices/fantem.js.map +1 -1
  76. package/devices/frient.js +1 -1
  77. package/devices/frient.js.map +1 -1
  78. package/devices/futurehome.d.ts.map +1 -1
  79. package/devices/futurehome.js +1 -2
  80. package/devices/futurehome.js.map +1 -1
  81. package/devices/gledopto.d.ts.map +1 -1
  82. package/devices/gledopto.js +30 -31
  83. package/devices/gledopto.js.map +1 -1
  84. package/devices/gmmts.d.ts.map +1 -1
  85. package/devices/gmmts.js +1 -2
  86. package/devices/gmmts.js.map +1 -1
  87. package/devices/heiman.d.ts.map +1 -1
  88. package/devices/heiman.js +3 -4
  89. package/devices/heiman.js.map +1 -1
  90. package/devices/heimgard_technologies.d.ts.map +1 -1
  91. package/devices/heimgard_technologies.js +5 -6
  92. package/devices/heimgard_technologies.js.map +1 -1
  93. package/devices/icasa.d.ts.map +1 -1
  94. package/devices/icasa.js +2 -25
  95. package/devices/icasa.js.map +1 -1
  96. package/devices/ikea.d.ts.map +1 -1
  97. package/devices/ikea.js +37 -51
  98. package/devices/ikea.js.map +1 -1
  99. package/devices/iluminize.d.ts.map +1 -1
  100. package/devices/iluminize.js +1 -2
  101. package/devices/iluminize.js.map +1 -1
  102. package/devices/immax.d.ts.map +1 -1
  103. package/devices/immax.js +3 -4
  104. package/devices/immax.js.map +1 -1
  105. package/devices/index.d.ts +1 -0
  106. package/devices/index.d.ts.map +1 -1
  107. package/devices/innr.d.ts.map +1 -1
  108. package/devices/innr.js +34 -35
  109. package/devices/innr.js.map +1 -1
  110. package/devices/inovelli.d.ts.map +1 -1
  111. package/devices/inovelli.js +3 -11
  112. package/devices/inovelli.js.map +1 -1
  113. package/devices/insta.d.ts.map +1 -1
  114. package/devices/insta.js +3 -12
  115. package/devices/insta.js.map +1 -1
  116. package/devices/javis.js +1 -1
  117. package/devices/javis.js.map +1 -1
  118. package/devices/jethome.d.ts.map +1 -1
  119. package/devices/jethome.js +1 -2
  120. package/devices/jethome.js.map +1 -1
  121. package/devices/kmpcil.d.ts.map +1 -1
  122. package/devices/kmpcil.js +1 -10
  123. package/devices/kmpcil.js.map +1 -1
  124. package/devices/konke.d.ts.map +1 -1
  125. package/devices/konke.js +2 -3
  126. package/devices/konke.js.map +1 -1
  127. package/devices/leedarson.d.ts.map +1 -1
  128. package/devices/leedarson.js +3 -11
  129. package/devices/leedarson.js.map +1 -1
  130. package/devices/legrand.d.ts.map +1 -1
  131. package/devices/legrand.js +30 -32
  132. package/devices/legrand.js.map +1 -1
  133. package/devices/leviton.d.ts.map +1 -1
  134. package/devices/leviton.js +1 -2
  135. package/devices/leviton.js.map +1 -1
  136. package/devices/lidl.d.ts.map +1 -1
  137. package/devices/lidl.js +1 -2
  138. package/devices/lidl.js.map +1 -1
  139. package/devices/lixee.d.ts.map +1 -1
  140. package/devices/lixee.js +1 -2
  141. package/devices/lixee.js.map +1 -1
  142. package/devices/lumi.d.ts.map +1 -1
  143. package/devices/lumi.js +19 -82
  144. package/devices/lumi.js.map +1 -1
  145. package/devices/lupus.d.ts.map +1 -1
  146. package/devices/lupus.js +3 -4
  147. package/devices/lupus.js.map +1 -1
  148. package/devices/lutron.d.ts.map +1 -1
  149. package/devices/lutron.js +7 -5
  150. package/devices/lutron.js.map +1 -1
  151. package/devices/lytko.d.ts.map +1 -1
  152. package/devices/lytko.js +6 -7
  153. package/devices/lytko.js.map +1 -1
  154. package/devices/meazon.d.ts.map +1 -1
  155. package/devices/meazon.js +2 -3
  156. package/devices/meazon.js.map +1 -1
  157. package/devices/moes.js +2 -2
  158. package/devices/moes.js.map +1 -1
  159. package/devices/muller_licht.d.ts.map +1 -1
  160. package/devices/muller_licht.js +5 -6
  161. package/devices/muller_licht.js.map +1 -1
  162. package/devices/namron.d.ts.map +1 -1
  163. package/devices/namron.js +17 -18
  164. package/devices/namron.js.map +1 -1
  165. package/devices/net2grid.d.ts.map +1 -1
  166. package/devices/net2grid.js +1 -2
  167. package/devices/net2grid.js.map +1 -1
  168. package/devices/nodon.d.ts.map +1 -1
  169. package/devices/nodon.js +13 -14
  170. package/devices/nodon.js.map +1 -1
  171. package/devices/nue_3a.d.ts.map +1 -1
  172. package/devices/nue_3a.js +3 -4
  173. package/devices/nue_3a.js.map +1 -1
  174. package/devices/osram.d.ts.map +1 -1
  175. package/devices/osram.js +20 -27
  176. package/devices/osram.js.map +1 -1
  177. package/devices/owon.d.ts.map +1 -1
  178. package/devices/owon.js +2 -3
  179. package/devices/owon.js.map +1 -1
  180. package/devices/perenio.d.ts.map +1 -1
  181. package/devices/perenio.js +3 -4
  182. package/devices/perenio.js.map +1 -1
  183. package/devices/philips.d.ts.map +1 -1
  184. package/devices/philips.js +10 -16
  185. package/devices/philips.js.map +1 -1
  186. package/devices/pushok.d.ts.map +1 -1
  187. package/devices/pushok.js +13 -11
  188. package/devices/pushok.js.map +1 -1
  189. package/devices/salus_controls.d.ts.map +1 -1
  190. package/devices/salus_controls.js +9 -10
  191. package/devices/salus_controls.js.map +1 -1
  192. package/devices/saswell.js +1 -1
  193. package/devices/schneider_electric.d.ts.map +1 -1
  194. package/devices/schneider_electric.js +14 -17
  195. package/devices/schneider_electric.js.map +1 -1
  196. package/devices/securifi.d.ts.map +1 -1
  197. package/devices/securifi.js +1 -2
  198. package/devices/securifi.js.map +1 -1
  199. package/devices/sengled.d.ts.map +1 -1
  200. package/devices/sengled.js +46 -27
  201. package/devices/sengled.js.map +1 -1
  202. package/devices/shinasystem.d.ts.map +1 -1
  203. package/devices/shinasystem.js +22 -23
  204. package/devices/shinasystem.js.map +1 -1
  205. package/devices/sinope.d.ts.map +1 -1
  206. package/devices/sinope.js +17 -19
  207. package/devices/sinope.js.map +1 -1
  208. package/devices/smartthings.d.ts.map +1 -1
  209. package/devices/smartthings.js +3 -10
  210. package/devices/smartthings.js.map +1 -1
  211. package/devices/sonoff.d.ts.map +1 -1
  212. package/devices/sonoff.js +14 -11
  213. package/devices/sonoff.js.map +1 -1
  214. package/devices/stelpro.d.ts.map +1 -1
  215. package/devices/stelpro.js +4 -5
  216. package/devices/stelpro.js.map +1 -1
  217. package/devices/sunricher.d.ts.map +1 -1
  218. package/devices/sunricher.js +1 -14
  219. package/devices/sunricher.js.map +1 -1
  220. package/devices/swann.d.ts.map +1 -1
  221. package/devices/swann.js +1 -2
  222. package/devices/swann.js.map +1 -1
  223. package/devices/sylvania.d.ts.map +1 -1
  224. package/devices/sylvania.js +2 -11
  225. package/devices/sylvania.js.map +1 -1
  226. package/devices/terncy.d.ts.map +1 -1
  227. package/devices/terncy.js +5 -7
  228. package/devices/terncy.js.map +1 -1
  229. package/devices/third_reality.d.ts.map +1 -1
  230. package/devices/third_reality.js +18 -19
  231. package/devices/third_reality.js.map +1 -1
  232. package/devices/tplink.js +1 -1
  233. package/devices/tplink.js.map +1 -1
  234. package/devices/trust.d.ts.map +1 -1
  235. package/devices/trust.js +1 -2
  236. package/devices/trust.js.map +1 -1
  237. package/devices/tuya.d.ts.map +1 -1
  238. package/devices/tuya.js +61 -63
  239. package/devices/tuya.js.map +1 -1
  240. package/devices/ubisys.d.ts.map +1 -1
  241. package/devices/ubisys.js +8 -9
  242. package/devices/ubisys.js.map +1 -1
  243. package/devices/uhome.d.ts.map +1 -1
  244. package/devices/uhome.js +1 -2
  245. package/devices/uhome.js.map +1 -1
  246. package/devices/viessmann.d.ts.map +1 -1
  247. package/devices/viessmann.js +1 -2
  248. package/devices/viessmann.js.map +1 -1
  249. package/devices/weiser.d.ts.map +1 -1
  250. package/devices/weiser.js +0 -2
  251. package/devices/weiser.js.map +1 -1
  252. package/devices/wirenboard.d.ts.map +1 -1
  253. package/devices/wirenboard.js +3 -4
  254. package/devices/wirenboard.js.map +1 -1
  255. package/devices/xyzroe.d.ts.map +1 -1
  256. package/devices/xyzroe.js +1 -4
  257. package/devices/xyzroe.js.map +1 -1
  258. package/devices/zen.d.ts.map +1 -1
  259. package/devices/zen.js +2 -4
  260. package/devices/zen.js.map +1 -1
  261. package/devices/zigbeetlc.d.ts +1 -0
  262. package/devices/zigbeetlc.d.ts.map +1 -1
  263. package/devices/zigbeetlc.js +3 -3
  264. package/devices/zigbeetlc.js.map +1 -1
  265. package/index.d.ts +4 -3
  266. package/index.d.ts.map +1 -1
  267. package/index.js +15 -13
  268. package/index.js.map +1 -1
  269. package/lib/exposes.d.ts +2 -5
  270. package/lib/exposes.d.ts.map +1 -1
  271. package/lib/exposes.js +4 -9
  272. package/lib/exposes.js.map +1 -1
  273. package/lib/ikea.d.ts +1 -49
  274. package/lib/ikea.d.ts.map +1 -1
  275. package/lib/ikea.js +3 -72
  276. package/lib/ikea.js.map +1 -1
  277. package/lib/ledvance.d.ts.map +1 -1
  278. package/lib/ledvance.js +5 -3
  279. package/lib/ledvance.js.map +1 -1
  280. package/lib/legacy.d.ts +182 -915
  281. package/lib/legacy.d.ts.map +1 -1
  282. package/lib/legacy.js +177 -1924
  283. package/lib/legacy.js.map +1 -1
  284. package/lib/lumi.d.ts +0 -142
  285. package/lib/lumi.d.ts.map +1 -1
  286. package/lib/lumi.js +7 -293
  287. package/lib/lumi.js.map +1 -1
  288. package/lib/modernExtend.d.ts +3 -7
  289. package/lib/modernExtend.d.ts.map +1 -1
  290. package/lib/modernExtend.js +4 -73
  291. package/lib/modernExtend.js.map +1 -1
  292. package/lib/ota.d.ts +71 -0
  293. package/lib/ota.d.ts.map +1 -0
  294. package/lib/ota.js +663 -0
  295. package/lib/ota.js.map +1 -0
  296. package/lib/philips.d.ts.map +1 -1
  297. package/lib/philips.js +2 -3
  298. package/lib/philips.js.map +1 -1
  299. package/lib/types.d.ts +41 -30
  300. package/lib/types.d.ts.map +1 -1
  301. package/lib/utils.d.ts +0 -1
  302. package/lib/utils.d.ts.map +1 -1
  303. package/lib/utils.js +1 -7
  304. package/lib/utils.js.map +1 -1
  305. package/package.json +23 -9
  306. package/lib/ota/common.d.ts +0 -31
  307. package/lib/ota/common.d.ts.map +0 -1
  308. package/lib/ota/common.js +0 -630
  309. package/lib/ota/common.js.map +0 -1
  310. package/lib/ota/gmmts.d.ts +0 -8
  311. package/lib/ota/gmmts.d.ts.map +0 -1
  312. package/lib/ota/gmmts.js +0 -62
  313. package/lib/ota/gmmts.js.map +0 -1
  314. package/lib/ota/index.d.ts +0 -15
  315. package/lib/ota/index.d.ts.map +0 -1
  316. package/lib/ota/index.js +0 -48
  317. package/lib/ota/index.js.map +0 -1
  318. package/lib/ota/inovelli.d.ts +0 -8
  319. package/lib/ota/inovelli.d.ts.map +0 -1
  320. package/lib/ota/inovelli.js +0 -91
  321. package/lib/ota/inovelli.js.map +0 -1
  322. package/lib/ota/jethome.d.ts +0 -9
  323. package/lib/ota/jethome.d.ts.map +0 -1
  324. package/lib/ota/jethome.js +0 -92
  325. package/lib/ota/jethome.js.map +0 -1
  326. package/lib/ota/ledvance.d.ts +0 -11
  327. package/lib/ota/ledvance.d.ts.map +0 -1
  328. package/lib/ota/ledvance.js +0 -75
  329. package/lib/ota/ledvance.js.map +0 -1
  330. package/lib/ota/salus.d.ts +0 -11
  331. package/lib/ota/salus.d.ts.map +0 -1
  332. package/lib/ota/salus.js +0 -99
  333. package/lib/ota/salus.js.map +0 -1
  334. package/lib/ota/securifi.d.ts +0 -4
  335. package/lib/ota/securifi.d.ts.map +0 -1
  336. package/lib/ota/securifi.js +0 -48
  337. package/lib/ota/securifi.js.map +0 -1
  338. package/lib/ota/tradfri.d.ts +0 -13
  339. package/lib/ota/tradfri.d.ts.map +0 -1
  340. package/lib/ota/tradfri.js +0 -72
  341. package/lib/ota/tradfri.js.map +0 -1
  342. package/lib/ota/ubisys.d.ts +0 -20
  343. package/lib/ota/ubisys.d.ts.map +0 -1
  344. package/lib/ota/ubisys.js +0 -93
  345. package/lib/ota/ubisys.js.map +0 -1
  346. package/lib/ota/zigbeeOTA.d.ts +0 -12
  347. package/lib/ota/zigbeeOTA.d.ts.map +0 -1
  348. package/lib/ota/zigbeeOTA.js +0 -143
  349. package/lib/ota/zigbeeOTA.js.map +0 -1
package/lib/legacy.js CHANGED
@@ -27,7 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  return (mod && mod.__esModule) ? mod : { "default": mod };
28
28
  };
29
29
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.ictcg1 = exports.tuyaGetDataValue = exports.moesSwitch = exports.dataPoints = exports.ZMLookups = exports.msLookups = exports.giexWaterValve = exports.thermostatPresets = exports.thermostatSystemModes4 = exports.thermostatSystemModes3 = exports.thermostatSystemModes2 = exports.tuyaHPSCheckingResult = exports.thermostatSystemModes = exports.thermostatControlSequenceOfOperations = exports.toZigbee = exports.tz = exports.fromZigbee = exports.fz = void 0;
30
+ exports.tuyaGetDataValue = exports.moesSwitch = exports.dataPoints = exports.ZMLookups = exports.msLookups = exports.giexWaterValve = exports.thermostatPresets = exports.thermostatSystemModes4 = exports.thermostatSystemModes3 = exports.thermostatSystemModes2 = exports.tuyaHPSCheckingResult = exports.thermostatSystemModes = exports.thermostatControlSequenceOfOperations = exports.toZigbee = exports.tz = exports.fromZigbee = exports.fz = void 0;
31
31
  exports.firstDpValue = firstDpValue;
32
32
  exports.dpValueFromEnum = dpValueFromEnum;
33
33
  exports.dpValueFromBool = dpValueFromBool;
@@ -68,14 +68,6 @@ const light = __importStar(require("./light"));
68
68
  const logger_1 = require("./logger");
69
69
  const globalStore = __importStar(require("./store"));
70
70
  const utils = __importStar(require("./utils"));
71
- const fromZigbeeStore = {};
72
- // get object property name (key) by it's value
73
- const getKey = (object, value) => {
74
- for (const key in object) {
75
- if (object[key] == value)
76
- return key;
77
- }
78
- };
79
71
  const dataTypes = {
80
72
  raw: 0, // [ bytes ]
81
73
  bool: 1, // [0/1]
@@ -1046,25 +1038,6 @@ function firstDpValue(msg, meta, converterName) {
1046
1038
  }
1047
1039
  return dpValues[0];
1048
1040
  }
1049
- const numberWithinRange = (number, min, max) => {
1050
- if (number > max) {
1051
- return max;
1052
- }
1053
- else if (number < min) {
1054
- return min;
1055
- }
1056
- else {
1057
- return number;
1058
- }
1059
- };
1060
- const holdUpdateBrightness324131092621 = (deviceID) => {
1061
- if (fromZigbeeStore[deviceID] && fromZigbeeStore[deviceID].brightnessSince && fromZigbeeStore[deviceID].brightnessDirection) {
1062
- const duration = Date.now() - fromZigbeeStore[deviceID].brightnessSince;
1063
- const delta = (duration / 10) * (fromZigbeeStore[deviceID].brightnessDirection === 'up' ? 1 : -1);
1064
- const newValue = fromZigbeeStore[deviceID].brightnessValue + delta;
1065
- fromZigbeeStore[deviceID].brightnessValue = numberWithinRange(newValue, 1, 255);
1066
- }
1067
- };
1068
1041
  function getMetaValue(entity, definition, key, groupStrategy = 'first') {
1069
1042
  if (entity.constructor.name === 'Group' && entity.members.length > 0) {
1070
1043
  const values = [];
@@ -1110,117 +1083,6 @@ const tuyaGetDataValue = (dataType, data) => {
1110
1083
  }
1111
1084
  };
1112
1085
  exports.tuyaGetDataValue = tuyaGetDataValue;
1113
- const toPercentage = (value, min, max) => {
1114
- if (value > max) {
1115
- value = max;
1116
- }
1117
- else if (value < min) {
1118
- value = min;
1119
- }
1120
- const normalised = (value - min) / (max - min);
1121
- return Math.round(normalised * 100);
1122
- };
1123
- const postfixWithEndpointName = (name, msg, definition) => {
1124
- if (definition.meta && definition.meta.multiEndpoint) {
1125
- const endpointName = definition.endpoint !== undefined ? getKey(definition.endpoint(msg.device), msg.endpoint.ID) : msg.endpoint.ID;
1126
- return `${name}_${endpointName}`;
1127
- }
1128
- else {
1129
- return name;
1130
- }
1131
- };
1132
- const transactionStore = {};
1133
- const hasAlreadyProcessedMessage = (msg, model, transaction = null, key = null) => {
1134
- if (model.meta && model.meta.publishDuplicateTransaction)
1135
- return false;
1136
- const current = transaction !== null ? transaction : msg.meta.zclTransactionSequenceNumber;
1137
- key = key || msg.device.ieeeAddr;
1138
- if (transactionStore[key] === current)
1139
- return true;
1140
- transactionStore[key] = current;
1141
- return false;
1142
- };
1143
- const addActionGroup = (payload, msg, definition) => {
1144
- const disableActionGroup = definition.meta && definition.meta.disableActionGroup;
1145
- if (!disableActionGroup && msg.groupID) {
1146
- payload.action_group = msg.groupID;
1147
- }
1148
- };
1149
- const ratelimitedDimmer = (model, msg, publish, options, meta) => {
1150
- const deviceID = msg.device.ieeeAddr;
1151
- const payload = {};
1152
- let duration = 0;
1153
- if (!fromZigbeeStore[deviceID]) {
1154
- fromZigbeeStore[deviceID] = { lastmsg: false };
1155
- }
1156
- const s = fromZigbeeStore[deviceID];
1157
- if (s.lastmsg) {
1158
- duration = Date.now() - s.lastmsg;
1159
- }
1160
- else {
1161
- s.lastmsg = Date.now();
1162
- }
1163
- if (duration > 500) {
1164
- s.lastmsg = Date.now();
1165
- payload.action = 'brightness';
1166
- payload.brightness = msg.data.level;
1167
- publish(payload);
1168
- }
1169
- };
1170
- const ictcg1 = (model, msg, publish, options, action) => {
1171
- const deviceID = msg.device.ieeeAddr;
1172
- const payload = {};
1173
- if (!fromZigbeeStore[deviceID]) {
1174
- fromZigbeeStore[deviceID] = { since: false, direction: false, value: 255, publish: publish };
1175
- }
1176
- const s = fromZigbeeStore[deviceID];
1177
- // if rate == 70 so we rotate slowly
1178
- const rate = msg.data.rate == 70 ? 0.3 : 1;
1179
- if (action === 'move') {
1180
- s.since = Date.now();
1181
- const direction = msg.data.movemode === 1 ? 'left' : 'right';
1182
- s.direction = direction;
1183
- payload.action = `rotate_${direction}`;
1184
- }
1185
- else if (action === 'level') {
1186
- s.value = msg.data.level;
1187
- const direction = s.value === 0 ? 'left' : 'right';
1188
- payload.action = `rotate_${direction}_quick`;
1189
- payload.brightness = s.value;
1190
- }
1191
- else if (action === 'stop') {
1192
- if (s.direction) {
1193
- const duration = Date.now() - s.since;
1194
- const delta = Math.round(rate * (duration / 10) * (s.direction === 'left' ? -1 : 1));
1195
- const newValue = s.value + delta;
1196
- if (newValue >= 0 && newValue <= 255) {
1197
- s.value = newValue;
1198
- }
1199
- }
1200
- payload.action = 'rotate_stop';
1201
- payload.brightness = s.value;
1202
- s.direction = false;
1203
- }
1204
- if (s.timerId) {
1205
- clearInterval(s.timerId);
1206
- s.timerId = false;
1207
- }
1208
- if (action === 'move') {
1209
- s.timerId = setInterval(() => {
1210
- const duration = Date.now() - s.since;
1211
- const delta = Math.round(rate * (duration / 10) * (s.direction === 'left' ? -1 : 1));
1212
- const newValue = s.value + delta;
1213
- if (newValue >= 0 && newValue <= 255) {
1214
- s.value = newValue;
1215
- }
1216
- payload.brightness = s.value;
1217
- s.since = Date.now();
1218
- s.publish(payload);
1219
- }, 200);
1220
- }
1221
- return payload.brightness;
1222
- };
1223
- exports.ictcg1 = ictcg1;
1224
1086
  const SAFETY_MIN_SECS = 10;
1225
1087
  const CAPACITY = 'capacity';
1226
1088
  const DURATION = 'duration';
@@ -1259,7 +1121,7 @@ const giexWaterValve = {
1259
1121
  waterConsumed: 'water_consumed',
1260
1122
  };
1261
1123
  exports.giexWaterValve = giexWaterValve;
1262
- const fromZigbee1 = {
1124
+ const fromZigbee = {
1263
1125
  TS0222: {
1264
1126
  cluster: 'manuSpecificTuya',
1265
1127
  type: ['commandDataResponse', 'commandDataReport'],
@@ -1271,7 +1133,6 @@ const fromZigbee1 = {
1271
1133
  switch (dp) {
1272
1134
  case 2:
1273
1135
  result.illuminance = value;
1274
- result.illuminance_lux = value;
1275
1136
  break;
1276
1137
  case 4:
1277
1138
  result.battery = value;
@@ -1633,1742 +1494,192 @@ const fromZigbee1 = {
1633
1494
  case dataPoints.x5hSetTempCeiling: {
1634
1495
  return { upper_temp: value };
1635
1496
  }
1636
- case dataPoints.x5hCurrentTemp: {
1637
- const temperature = value & (1 << 15) ? value - (1 << 16) + 1 : value;
1638
- return { local_temperature: parseFloat((temperature / 10).toFixed(1)) };
1639
- }
1640
- case dataPoints.x5hTempCorrection: {
1641
- return { local_temperature_calibration: parseFloat((value / 10).toFixed(1)) };
1642
- }
1643
- case dataPoints.x5hMode: {
1644
- const lookup = { 0: 'manual', 1: 'program' };
1645
- return { preset: lookup[value] };
1646
- }
1647
- case dataPoints.x5hSensorSelection: {
1648
- const lookup = { 0: 'internal', 1: 'external', 2: 'both' };
1649
- return { sensor: lookup[value] };
1650
- }
1651
- case dataPoints.x5hOutputReverse: {
1652
- return { output_reverse: value };
1653
- }
1654
- default: {
1655
- logger_1.logger.debug(`Unrecognized DP #${dp} with data ${JSON.stringify(dpValue)}`, 'zhc:legacy:fz:x5h_thermostat');
1656
- }
1657
- }
1658
- },
1659
- },
1660
- zs_thermostat: {
1661
- cluster: 'manuSpecificTuya',
1662
- type: ['commandDataResponse', 'commandDataReport'],
1663
- convert: (model, msg, publish, options, meta) => {
1664
- const dpValue = firstDpValue(msg, meta, 'zs_thermostat');
1665
- const dp = dpValue.dp;
1666
- const value = getDataValue(dpValue);
1667
- const ret = {};
1668
- const daysMap = { 1: 'monday', 2: 'tuesday', 3: 'wednesday', 4: 'thursday', 5: 'friday', 6: 'saturday', 7: 'sunday' };
1669
- const day = daysMap[value[0]];
1670
- switch (dp) {
1671
- case dataPoints.zsChildLock:
1672
- return { child_lock: value ? 'LOCK' : 'UNLOCK' };
1673
- case dataPoints.zsHeatingSetpoint:
1674
- if (value == 0)
1675
- ret.system_mode = 'off';
1676
- if (value == 60) {
1677
- ret.system_mode = 'heat';
1678
- ret.preset = 'boost';
1679
- }
1680
- ret.current_heating_setpoint = (value / 2).toFixed(1);
1681
- if (value > 0 && value < 60)
1682
- globalStore.putValue(msg.endpoint, 'current_heating_setpoint', ret.current_heating_setpoint);
1683
- return ret;
1684
- case dataPoints.zsHeatingSetpointAuto:
1685
- return { current_heating_setpoint_auto: (value / 2).toFixed(1) };
1686
- case dataPoints.zsOpenwindowTemp:
1687
- return { detectwindow_temperature: (value / 2).toFixed(1) };
1688
- case dataPoints.zsOpenwindowTime:
1689
- return { detectwindow_timeminute: value };
1690
- case dataPoints.zsLocalTemp:
1691
- return { local_temperature: (value / 10).toFixed(1) };
1692
- case dataPoints.zsBatteryVoltage:
1693
- return { voltage: Math.round(value * 10) };
1694
- case dataPoints.zsTempCalibration:
1695
- return { local_temperature_calibration: value > 55 ? ((value - 0x100000000) / 10).toFixed(1) : (value / 10).toFixed(1) };
1696
- case dataPoints.zsBinaryOne:
1697
- return { binary_one: value ? 'ON' : 'OFF' };
1698
- case dataPoints.zsBinaryTwo:
1699
- return { binary_two: value ? 'ON' : 'OFF' };
1700
- case dataPoints.zsComfortTemp:
1701
- return { comfort_temperature: (value / 2).toFixed(1) };
1702
- case dataPoints.zsEcoTemp:
1703
- return { eco_temperature: (value / 2).toFixed(1) };
1704
- // case dataPoints.zsAwayTemp:
1705
- // return {away_preset_temperature: (value / 2).toFixed(1)};
1706
- case dataPoints.zsMode:
1707
- switch (value) {
1708
- case 1: // manual
1709
- return { system_mode: 'heat', away_mode: 'OFF', preset: 'manual' };
1710
- case 2: // away
1711
- return { system_mode: 'auto', away_mode: 'ON', preset: 'holiday' };
1712
- case 0: // auto
1713
- return { system_mode: 'auto', away_mode: 'OFF', preset: 'schedule' };
1714
- default:
1715
- logger_1.logger.warning(`Preset ${value} is not recognized.`, 'zhc:legacy:fz:zs_thermostat');
1716
- break;
1717
- }
1718
- break;
1719
- case dataPoints.zsScheduleMonday:
1720
- case dataPoints.zsScheduleTuesday:
1721
- case dataPoints.zsScheduleWednesday:
1722
- case dataPoints.zsScheduleThursday:
1723
- case dataPoints.zsScheduleFriday:
1724
- case dataPoints.zsScheduleSaturday:
1725
- case dataPoints.zsScheduleSunday:
1726
- for (let i = 1; i <= 9; i++) {
1727
- const tempId = (i - 1) * 2 + 1;
1728
- const timeId = (i - 1) * 2 + 2;
1729
- ret[`${day}_temp_${i}`] = (value[tempId] / 2).toFixed(1);
1730
- if (i != 9) {
1731
- ret[`${day}_hour_${i}`] = Math.floor(value[timeId] / 4)
1732
- .toString()
1733
- .padStart(2, '0');
1734
- ret[`${day}_minute_${i}`] = ((value[timeId] % 4) * 15).toString().padStart(2, '0');
1735
- }
1736
- }
1737
- return ret;
1738
- case dataPoints.zsAwaySetting:
1739
- ret.away_preset_year = value[0];
1740
- ret.away_preset_month = value[1];
1741
- ret.away_preset_day = value[2];
1742
- ret.away_preset_hour = value[3];
1743
- ret.away_preset_minute = value[4];
1744
- ret.away_preset_temperature = (value[5] / 2).toFixed(1);
1745
- ret.away_preset_days = (value[6] << 8) + value[7];
1746
- return ret;
1747
- default:
1748
- logger_1.logger.debug(`Unrecognized DP #${dp} with data ${JSON.stringify(dpValue)}`, 'zhc:legacy:fz:zs_thermostat');
1749
- }
1750
- },
1751
- },
1752
- giexWaterValve: {
1753
- cluster: 'manuSpecificTuya',
1754
- type: ['commandDataResponse', 'commandDataReport'],
1755
- convert: (model, msg, publish, options, meta) => {
1756
- // @ts-expect-error ignore
1757
- const modelConverters = giexFzModelConverters[model.model] || {};
1758
- for (const dpValue of msg.data.dpValues) {
1759
- const value = getDataValue(dpValue);
1760
- const { dp } = dpValue;
1761
- switch (dp) {
1762
- case dataPoints.giexWaterValve.state:
1763
- return { [giexWaterValve.state]: value ? ON : OFF };
1764
- case dataPoints.giexWaterValve.mode:
1765
- return { [giexWaterValve.mode]: value ? CAPACITY : DURATION };
1766
- case dataPoints.giexWaterValve.irrigationTarget:
1767
- return { [giexWaterValve.irrigationTarget]: value };
1768
- case dataPoints.giexWaterValve.cycleIrrigationNumTimes:
1769
- return { [giexWaterValve.cycleIrrigationNumTimes]: value };
1770
- case dataPoints.giexWaterValve.cycleIrrigationInterval:
1771
- return { [giexWaterValve.cycleIrrigationInterval]: value };
1772
- case dataPoints.giexWaterValve.waterConsumed:
1773
- return { [giexWaterValve.waterConsumed]: value };
1774
- case dataPoints.giexWaterValve.irrigationStartTime:
1775
- return { [giexWaterValve.irrigationStartTime]: modelConverters.time?.(value) || value };
1776
- case dataPoints.giexWaterValve.irrigationEndTime:
1777
- return { [giexWaterValve.irrigationEndTime]: modelConverters.time?.(value) || value };
1778
- case dataPoints.giexWaterValve.lastIrrigationDuration:
1779
- return { [giexWaterValve.lastIrrigationDuration]: value.split(',').shift() }; // Remove meaningless ,0 suffix
1780
- case dataPoints.giexWaterValve.battery:
1781
- return { [giexWaterValve.battery]: value };
1782
- case dataPoints.giexWaterValve.currentTemperature:
1783
- return; // Do Nothing - value ignored because it isn't a valid temperature reading (misdocumented and usage unclear)
1784
- default: // Unknown data point warning
1785
- logger_1.logger.debug(`Unrecognized DP #${dp} with VALUE = ${value}`, 'legacy:fz:giex_water_valve');
1786
- }
1787
- }
1788
- },
1789
- },
1790
- tuya_alecto_smoke: {
1791
- cluster: 'manuSpecificTuya',
1792
- type: ['commandDataResponse', 'commandDataReport'],
1793
- convert: (model, msg, publish, options, meta) => {
1794
- const dpValue = firstDpValue(msg, meta, 'tuya_alecto_smoke');
1795
- const dp = dpValue.dp;
1796
- const value = getDataValue(dpValue);
1797
- switch (dp) {
1798
- case dataPoints.alectoSmokeState:
1799
- // @ts-expect-error ignore
1800
- return { smoke_state: { 0: 'alarm', 1: 'normal' }[value] };
1801
- case dataPoints.alectoSmokeValue:
1802
- return { smoke_value: value };
1803
- case dataPoints.alectoSelfChecking:
1804
- return { self_checking: value };
1805
- case dataPoints.alectoCheckingResult:
1806
- // @ts-expect-error ignore
1807
- return { checking_result: { 0: 'checking', 1: 'check_success', 2: 'check_failure', 3: 'others' }[value] };
1808
- case dataPoints.alectoSmokeTest:
1809
- return { smoke_test: value };
1810
- case dataPoints.alectoLifecycle:
1811
- return { lifecycle: value };
1812
- case dataPoints.alectoBatteryPercentage:
1813
- return { battery: value };
1814
- case dataPoints.alectoBatteryState:
1815
- // @ts-expect-error ignore
1816
- return { battery_state: { 0: 'low', 1: 'middle', 2: 'high' }[value] };
1817
- case dataPoints.alectoSilence:
1818
- return { silence: value };
1819
- default:
1820
- logger_1.logger.debug(`Unrecognized DP #${dp} with data ${JSON.stringify(msg.data)}`, 'zhc:legacy:fz:tuya_alecto_smoke');
1821
- }
1822
- },
1823
- },
1824
- SmartButton_skip: {
1825
- cluster: 'genLevelCtrl',
1826
- type: 'commandStep',
1827
- options: [exposes.options.legacy()],
1828
- convert: (model, msg, publish, options, meta) => {
1829
- if (utils.isLegacyEnabled(options)) {
1830
- const direction = msg.data.stepmode === 1 ? 'backward' : 'forward';
1831
- return {
1832
- action: `skip_${direction}`,
1833
- step_size: msg.data.stepsize,
1834
- transition_time: msg.data.transtime,
1835
- };
1836
- }
1837
- else {
1838
- return fromZigbee_1.default.command_step.convert(model, msg, publish, options, meta);
1839
- }
1840
- },
1841
- },
1842
- konke_click: {
1843
- cluster: 'genOnOff',
1844
- type: ['attributeReport', 'readResponse'],
1845
- options: [exposes.options.legacy()],
1846
- convert: (model, msg, publish, options, meta) => {
1847
- if (utils.isLegacyEnabled(options)) {
1848
- const value = msg.data['onOff'];
1849
- const lookup = {
1850
- 128: { click: 'single' }, // single click
1851
- 129: { click: 'double' }, // double and many click
1852
- 130: { click: 'long' }, // hold
1853
- };
1854
- return lookup[value] ? lookup[value] : null;
1855
- }
1856
- },
1857
- },
1858
- terncy_raw: {
1859
- cluster: 'manuSpecificClusterAduroSmart',
1860
- type: 'raw',
1861
- options: [exposes.options.legacy()],
1862
- convert: (model, msg, publish, options, meta) => {
1863
- if (utils.isLegacyEnabled(options)) {
1864
- // 13,40,18,104, 0,8,1 - click
1865
- // 13,40,18,22, 0,17,1
1866
- // 13,40,18,32, 0,18,1
1867
- // 13,40,18,6, 0,16,1
1868
- // 13,40,18,111, 0,4,2 - double click
1869
- // 13,40,18,58, 0,7,2
1870
- // 13,40,18,6, 0,2,3 - triple click
1871
- // motion messages:
1872
- // 13,40,18,105, 4,167,0,7 - motion on right side
1873
- // 13,40,18,96, 4,27,0,5
1874
- // 13,40,18,101, 4,27,0,7
1875
- // 13,40,18,125, 4,28,0,5
1876
- // 13,40,18,85, 4,28,0,7
1877
- // 13,40,18,3, 4,24,0,5
1878
- // 13,40,18,81, 4,10,1,7
1879
- // 13,40,18,72, 4,30,1,5
1880
- // 13,40,18,24, 4,25,0,40 - motion on left side
1881
- // 13,40,18,47, 4,28,0,56
1882
- // 13,40,18,8, 4,32,0,40
1883
- let value = {};
1884
- if (msg.data[4] == 0) {
1885
- value = msg.data[6];
1886
- if (1 <= value && value <= 3) {
1887
- const actionLookup = { 1: 'single', 2: 'double', 3: 'triple', 4: 'quadruple' };
1888
- return { click: actionLookup[value] };
1889
- }
1890
- }
1891
- }
1892
- },
1893
- },
1894
- CCTSwitch_D0001_on_off: {
1895
- cluster: 'genOnOff',
1896
- type: ['commandOn', 'commandOff'],
1897
- options: [exposes.options.legacy()],
1898
- convert: (model, msg, publish, options, meta) => {
1899
- if (utils.isLegacyEnabled(options)) {
1900
- return { click: 'power' };
1901
- }
1902
- },
1903
- },
1904
- ptvo_switch_buttons: {
1905
- cluster: 'genMultistateInput',
1906
- type: ['attributeReport', 'readResponse'],
1907
- options: [exposes.options.legacy()],
1908
- convert: (model, msg, publish, options, meta) => {
1909
- if (utils.isLegacyEnabled(options)) {
1910
- const button = getKey(model.endpoint(msg.device), msg.endpoint.ID);
1911
- const value = msg.data['presentValue'];
1912
- const actionLookup = {
1913
- 0: 'release',
1914
- 1: 'single',
1915
- 2: 'double',
1916
- 3: 'tripple',
1917
- 4: 'hold',
1918
- };
1919
- const action = actionLookup[value];
1920
- if (button) {
1921
- return { click: button + (action ? `_${action}` : '') };
1922
- }
1923
- }
1924
- },
1925
- },
1926
- ZGRC013_brightness_onoff: {
1927
- cluster: 'genLevelCtrl',
1928
- type: 'commandMoveWithOnOff',
1929
- options: [exposes.options.legacy()],
1930
- convert: (model, msg, publish, options, meta) => {
1931
- if (utils.isLegacyEnabled(options)) {
1932
- const button = msg.endpoint.ID;
1933
- const direction = msg.data.movemode == 0 ? 'up' : 'down';
1934
- if (button) {
1935
- return { click: `${button}_${direction}` };
1936
- }
1937
- }
1938
- },
1939
- },
1940
- ZGRC013_brightness_stop: {
1941
- cluster: 'genLevelCtrl',
1942
- type: 'commandStopWithOnOff',
1943
- options: [exposes.options.legacy()],
1944
- convert: (model, msg, publish, options, meta) => {
1945
- if (utils.isLegacyEnabled(options)) {
1946
- const button = msg.endpoint.ID;
1947
- if (button) {
1948
- return { click: `${button}_stop` };
1949
- }
1950
- }
1951
- },
1952
- },
1953
- ZGRC013_scene: {
1954
- cluster: 'genScenes',
1955
- type: 'commandRecall',
1956
- options: [exposes.options.legacy()],
1957
- convert: (model, msg, publish, options, meta) => {
1958
- if (utils.isLegacyEnabled(options)) {
1959
- return { click: `scene_${msg.data.groupid}_${msg.data.sceneid}` };
1960
- }
1961
- },
1962
- },
1963
- ZGRC013_cmdOn: {
1964
- cluster: 'genOnOff',
1965
- type: 'commandOn',
1966
- options: [exposes.options.legacy()],
1967
- convert: (model, msg, publish, options, meta) => {
1968
- if (utils.isLegacyEnabled(options)) {
1969
- const button = msg.endpoint.ID;
1970
- if (button) {
1971
- return { click: `${button}_on` };
1972
- }
1973
- }
1974
- },
1975
- },
1976
- ZGRC013_cmdOff: {
1977
- cluster: 'genOnOff',
1978
- type: 'commandOff',
1979
- options: [exposes.options.legacy()],
1980
- convert: (model, msg, publish, options, meta) => {
1981
- if (utils.isLegacyEnabled(options)) {
1982
- const button = msg.endpoint.ID;
1983
- if (button) {
1984
- return { click: `${button}_off` };
1985
- }
1986
- }
1987
- },
1988
- },
1989
- ZGRC013_brightness: {
1990
- cluster: 'genLevelCtrl',
1991
- type: 'commandMove',
1992
- options: [exposes.options.legacy()],
1993
- convert: (model, msg, publish, options, meta) => {
1994
- if (utils.isLegacyEnabled(options)) {
1995
- const button = msg.endpoint.ID;
1996
- const direction = msg.data.movemode == 0 ? 'up' : 'down';
1997
- if (button) {
1998
- return { click: `${button}_${direction}` };
1999
- }
2000
- }
2001
- },
2002
- },
2003
- CTR_U_scene: {
2004
- cluster: 'genScenes',
2005
- type: 'commandRecall',
2006
- options: [exposes.options.legacy()],
2007
- convert: (model, msg, publish, options, meta) => {
2008
- if (utils.isLegacyEnabled(options)) {
2009
- return { click: `scene_${msg.data.groupid}_${msg.data.sceneid}` };
2010
- }
2011
- },
2012
- },
2013
- st_button_state: {
2014
- cluster: 'ssIasZone',
2015
- type: 'commandStatusChangeNotification',
2016
- options: [exposes.options.legacy()],
2017
- convert: (model, msg, publish, options, meta) => {
2018
- if (utils.isLegacyEnabled(options)) {
2019
- const buttonStates = {
2020
- 0: 'off',
2021
- 1: 'single',
2022
- 2: 'double',
2023
- 3: 'hold',
2024
- };
2025
- if (msg.data.data !== undefined) {
2026
- const zoneStatus = msg.data.zonestatus;
2027
- return { click: buttonStates[zoneStatus] };
2028
- }
2029
- else {
2030
- const zoneStatus = msg.data.zonestatus;
2031
- return { click: buttonStates[zoneStatus] };
2032
- }
2033
- }
2034
- },
2035
- },
2036
- cover_stop: {
2037
- cluster: 'closuresWindowCovering',
2038
- type: 'commandStop',
2039
- options: [exposes.options.legacy()],
2040
- convert: (model, msg, publish, options, meta) => {
2041
- if (utils.isLegacyEnabled(options)) {
2042
- return { click: 'release' };
2043
- }
2044
- },
2045
- },
2046
- cover_open: {
2047
- cluster: 'closuresWindowCovering',
2048
- type: 'commandUpOpen',
2049
- options: [exposes.options.legacy()],
2050
- convert: (model, msg, publish, options, meta) => {
2051
- if (utils.isLegacyEnabled(options)) {
2052
- return { click: 'open' };
2053
- }
2054
- },
2055
- },
2056
- cover_close: {
2057
- cluster: 'closuresWindowCovering',
2058
- type: 'commandDownClose',
2059
- options: [exposes.options.legacy()],
2060
- convert: (model, msg, publish, options, meta) => {
2061
- if (utils.isLegacyEnabled(options)) {
2062
- return { click: 'close' };
2063
- }
2064
- },
2065
- },
2066
- TS0218_click: {
2067
- cluster: 'ssIasAce',
2068
- type: 'commandEmergency',
2069
- options: [exposes.options.legacy()],
2070
- convert: (model, msg, publish, options, meta) => {
2071
- if (utils.isLegacyEnabled(options)) {
2072
- return { action: 'click' };
2073
- }
2074
- else {
2075
- return fromZigbee_1.default.command_emergency.convert(model, msg, publish, options, meta);
2076
- }
2077
- },
2078
- },
2079
- scenes_recall_click: {
2080
- cluster: 'genScenes',
2081
- type: 'commandRecall',
2082
- options: [exposes.options.legacy()],
2083
- convert: (model, msg, publish, options, meta) => {
2084
- if (utils.isLegacyEnabled(options)) {
2085
- return { click: msg.data.sceneid };
2086
- }
2087
- },
2088
- },
2089
- AV2010_34_click: {
2090
- cluster: 'genScenes',
2091
- type: 'commandRecall',
2092
- options: [exposes.options.legacy()],
2093
- convert: (model, msg, publish, options, meta) => {
2094
- if (utils.isLegacyEnabled(options)) {
2095
- return { click: msg.data.groupid };
2096
- }
2097
- },
2098
- },
2099
- genOnOff_cmdOn: {
2100
- cluster: 'genOnOff',
2101
- type: 'commandOn',
2102
- options: [exposes.options.legacy()],
2103
- convert: (model, msg, publish, options, meta) => {
2104
- if (utils.isLegacyEnabled(options)) {
2105
- return { click: 'on' };
2106
- }
2107
- },
2108
- },
2109
- genOnOff_cmdOff: {
2110
- cluster: 'genOnOff',
2111
- type: 'commandOff',
2112
- options: [exposes.options.legacy()],
2113
- convert: (model, msg, publish, options, meta) => {
2114
- if (utils.isLegacyEnabled(options)) {
2115
- return { click: 'off' };
2116
- }
2117
- },
2118
- },
2119
- RM01_on_click: {
2120
- cluster: 'genOnOff',
2121
- type: 'commandOn',
2122
- options: [exposes.options.legacy()],
2123
- convert: (model, msg, publish, options, meta) => {
2124
- if (utils.isLegacyEnabled(options)) {
2125
- const button = getKey(model.endpoint(msg.device), msg.endpoint.ID);
2126
- return { action: `${button}_on` };
2127
- }
2128
- else {
2129
- return fromZigbee_1.default.command_on.convert(model, msg, publish, options, meta);
2130
- }
2131
- },
2132
- },
2133
- RM01_off_click: {
2134
- cluster: 'genOnOff',
2135
- type: 'commandOff',
2136
- options: [exposes.options.legacy()],
2137
- convert: (model, msg, publish, options, meta) => {
2138
- if (utils.isLegacyEnabled(options)) {
2139
- const button = getKey(model.endpoint(msg.device), msg.endpoint.ID);
2140
- return { action: `${button}_off` };
2141
- }
2142
- else {
2143
- return fromZigbee_1.default.command_off.convert(model, msg, publish, options, meta);
2144
- }
2145
- },
2146
- },
2147
- RM01_down_hold: {
2148
- cluster: 'genLevelCtrl',
2149
- type: 'commandStep',
2150
- options: [exposes.options.legacy()],
2151
- convert: (model, msg, publish, options, meta) => {
2152
- if (utils.isLegacyEnabled(options)) {
2153
- const button = getKey(model.endpoint(msg.device), msg.endpoint.ID);
2154
- return {
2155
- action: `${button}_down`,
2156
- step_mode: msg.data.stepmode,
2157
- step_size: msg.data.stepsize,
2158
- transition_time: msg.data.transtime,
2159
- };
2160
- }
2161
- else {
2162
- return fromZigbee_1.default.command_step.convert(model, msg, publish, options, meta);
2163
- }
2164
- },
2165
- },
2166
- RM01_up_hold: {
2167
- cluster: 'genLevelCtrl',
2168
- type: 'commandStepWithOnOff',
2169
- options: [exposes.options.legacy()],
2170
- convert: (model, msg, publish, options, meta) => {
2171
- if (utils.isLegacyEnabled(options)) {
2172
- const button = getKey(model.endpoint(msg.device), msg.endpoint.ID);
2173
- return {
2174
- action: `${button}_up`,
2175
- step_mode: msg.data.stepmode,
2176
- step_size: msg.data.stepsize,
2177
- transition_time: msg.data.transtime,
2178
- };
2179
- }
2180
- else {
2181
- return fromZigbee_1.default.command_step.convert(model, msg, publish, options, meta);
2182
- }
2183
- },
2184
- },
2185
- RM01_stop: {
2186
- cluster: 'genLevelCtrl',
2187
- type: 'commandStop',
2188
- options: [exposes.options.legacy()],
2189
- convert: (model, msg, publish, options, meta) => {
2190
- if (utils.isLegacyEnabled(options)) {
2191
- const button = getKey(model.endpoint(msg.device), msg.endpoint.ID);
2192
- return { action: `${button}_stop` };
2193
- }
2194
- else {
2195
- return fromZigbee_1.default.command_stop.convert(model, msg, publish, options, meta);
2196
- }
2197
- },
2198
- },
2199
- cmd_move: {
2200
- cluster: 'genLevelCtrl',
2201
- type: 'commandMove',
2202
- options: [exposes.options.legacy(), exposes.options.simulated_brightness(' Note: will only work when legacy: false is set.')],
2203
- convert: (model, msg, publish, options, meta) => {
2204
- if (hasAlreadyProcessedMessage(msg, model))
2205
- return;
2206
- if (utils.isLegacyEnabled(options)) {
2207
- ictcg1(model, msg, publish, options, 'move');
2208
- const direction = msg.data.movemode === 1 ? 'left' : 'right';
2209
- return { action: `rotate_${direction}`, rate: msg.data.rate };
2210
- }
2211
- else {
2212
- return fromZigbee_1.default.command_move.convert(model, msg, publish, options, meta);
2213
- }
2214
- },
2215
- },
2216
- cmd_move_with_onoff: {
2217
- cluster: 'genLevelCtrl',
2218
- type: 'commandMoveWithOnOff',
2219
- options: [exposes.options.legacy(), exposes.options.simulated_brightness(' Note: will only work when legacy: false is set.')],
2220
- convert: (model, msg, publish, options, meta) => {
2221
- if (utils.isLegacyEnabled(options)) {
2222
- ictcg1(model, msg, publish, options, 'move');
2223
- const direction = msg.data.movemode === 1 ? 'left' : 'right';
2224
- return { action: `rotate_${direction}`, rate: msg.data.rate };
2225
- }
2226
- else {
2227
- return fromZigbee_1.default.command_move.convert(model, msg, publish, options, meta);
2228
- }
2229
- },
2230
- },
2231
- cmd_stop: {
2232
- cluster: 'genLevelCtrl',
2233
- type: 'commandStop',
2234
- options: [exposes.options.legacy()],
2235
- convert: (model, msg, publish, options, meta) => {
2236
- if (hasAlreadyProcessedMessage(msg, model))
2237
- return;
2238
- if (utils.isLegacyEnabled(options)) {
2239
- const value = ictcg1(model, msg, publish, options, 'stop');
2240
- return { action: `rotate_stop`, brightness: value };
2241
- }
2242
- else {
2243
- return fromZigbee_1.default.command_stop.convert(model, msg, publish, options, meta);
2244
- }
2245
- },
2246
- },
2247
- cmd_stop_with_onoff: {
2248
- cluster: 'genLevelCtrl',
2249
- type: 'commandStopWithOnOff',
2250
- options: [exposes.options.legacy()],
2251
- convert: (model, msg, publish, options, meta) => {
2252
- if (utils.isLegacyEnabled(options)) {
2253
- const value = ictcg1(model, msg, publish, options, 'stop');
2254
- return { action: `rotate_stop`, brightness: value };
2255
- }
2256
- else {
2257
- return fromZigbee_1.default.command_stop.convert(model, msg, publish, options, meta);
2258
- }
2259
- },
2260
- },
2261
- cmd_move_to_level_with_onoff: {
2262
- cluster: 'genLevelCtrl',
2263
- type: 'commandMoveToLevelWithOnOff',
2264
- options: [exposes.options.legacy()],
2265
- convert: (model, msg, publish, options, meta) => {
2266
- if (utils.isLegacyEnabled(options)) {
2267
- const value = ictcg1(model, msg, publish, options, 'level');
2268
- const direction = msg.data.level === 0 ? 'left' : 'right';
2269
- return { action: `rotate_${direction}_quick`, level: msg.data.level, brightness: value };
2270
- }
2271
- else {
2272
- return fromZigbee_1.default.command_move_to_level.convert(model, msg, publish, options, meta);
2273
- }
2274
- },
2275
- },
2276
- immax_07046L_arm: {
2277
- cluster: 'ssIasAce',
2278
- type: 'commandArm',
2279
- options: [exposes.options.legacy()],
2280
- convert: (model, msg, publish, options, meta) => {
2281
- if (utils.isLegacyEnabled(options)) {
2282
- const action = msg.data['armmode'];
2283
- delete msg.data['armmode'];
2284
- const modeLookup = {
2285
- 0: 'disarm',
2286
- 1: 'arm_stay',
2287
- 3: 'arm_away',
2288
- };
2289
- return { action: modeLookup[action] };
2290
- }
2291
- else {
2292
- return fromZigbee_1.default.command_arm.convert(model, msg, publish, options, meta);
2293
- }
2294
- },
2295
- },
2296
- KEF1PA_arm: {
2297
- cluster: 'ssIasAce',
2298
- type: 'commandArm',
2299
- options: [exposes.options.legacy()],
2300
- convert: (model, msg, publish, options, meta) => {
2301
- if (utils.isLegacyEnabled(options)) {
2302
- const action = msg.data['armmode'];
2303
- delete msg.data['armmode'];
2304
- const modeLookup = {
2305
- 0: 'home',
2306
- 2: 'sleep',
2307
- 3: 'away',
2308
- };
2309
- return { action: modeLookup[action] };
2310
- }
2311
- else {
2312
- return fromZigbee_1.default.command_arm.convert(model, msg, publish, options, meta);
2313
- }
2314
- },
2315
- },
2316
- CTR_U_brightness_updown_click: {
2317
- cluster: 'genLevelCtrl',
2318
- type: 'commandStep',
2319
- options: [exposes.options.legacy()],
2320
- convert: (model, msg, publish, options, meta) => {
2321
- if (utils.isLegacyEnabled(options)) {
2322
- const deviceID = msg.device.ieeeAddr;
2323
- const direction = msg.data.stepmode === 1 ? 'down' : 'up';
2324
- // Save last direction for release event
2325
- if (!fromZigbeeStore[deviceID]) {
2326
- fromZigbeeStore[deviceID] = {};
2327
- }
2328
- fromZigbeeStore[deviceID].direction = direction;
2329
- return {
2330
- action: `brightness_${direction}_click`,
2331
- step_size: msg.data.stepsize,
2332
- transition_time: msg.data.transtime,
2333
- };
2334
- }
2335
- else {
2336
- return fromZigbee_1.default.command_step.convert(model, msg, publish, options, meta);
2337
- }
2338
- },
2339
- },
2340
- CTR_U_brightness_updown_hold: {
2341
- cluster: 'genLevelCtrl',
2342
- type: 'commandMove',
2343
- options: [exposes.options.legacy()],
2344
- convert: (model, msg, publish, options, meta) => {
2345
- if (utils.isLegacyEnabled(options)) {
2346
- const deviceID = msg.device.ieeeAddr;
2347
- const direction = msg.data.movemode === 1 ? 'down' : 'up';
2348
- // Save last direction for release event
2349
- if (!fromZigbeeStore[deviceID]) {
2350
- fromZigbeeStore[deviceID] = {};
2351
- }
2352
- fromZigbeeStore[deviceID].direction = direction;
2353
- return {
2354
- action: `brightness_${direction}_hold`,
2355
- rate: msg.data.rate,
2356
- };
2357
- }
2358
- else {
2359
- return fromZigbee_1.default.command_move.convert(model, msg, publish, options, meta);
2360
- }
2361
- },
2362
- },
2363
- CTR_U_brightness_updown_release: {
2364
- cluster: 'genLevelCtrl',
2365
- type: 'commandStop',
2366
- options: [exposes.options.legacy()],
2367
- convert: (model, msg, publish, options, meta) => {
2368
- if (utils.isLegacyEnabled(options)) {
2369
- const deviceID = msg.device.ieeeAddr;
2370
- if (!fromZigbeeStore[deviceID]) {
2371
- return null;
2372
- }
2373
- const direction = fromZigbeeStore[deviceID].direction;
2374
- return {
2375
- action: `brightness_${direction}_release`,
2376
- };
2377
- }
2378
- else {
2379
- return fromZigbee_1.default.command_stop.convert(model, msg, publish, options, meta);
2380
- }
2381
- },
2382
- },
2383
- osram_lightify_switch_cmdOn: {
2384
- cluster: 'genOnOff',
2385
- type: 'commandOn',
2386
- options: [exposes.options.legacy()],
2387
- convert: (model, msg, publish, options, meta) => {
2388
- if (utils.isLegacyEnabled(options)) {
2389
- return { action: 'up' };
2390
- }
2391
- else {
2392
- return fromZigbee_1.default.command_on.convert(model, msg, publish, options, meta);
2393
- }
2394
- },
2395
- },
2396
- osram_lightify_switch_cmdOff: {
2397
- cluster: 'genOnOff',
2398
- type: 'commandOff',
2399
- options: [exposes.options.legacy()],
2400
- convert: (model, msg, publish, options, meta) => {
2401
- if (utils.isLegacyEnabled(options)) {
2402
- return { action: 'down' };
2403
- }
2404
- else {
2405
- return fromZigbee_1.default.command_off.convert(model, msg, publish, options, meta);
2406
- }
2407
- },
2408
- },
2409
- osram_lightify_switch_cmdMoveWithOnOff: {
2410
- cluster: 'genLevelCtrl',
2411
- type: 'commandMoveWithOnOff',
2412
- options: [exposes.options.legacy()],
2413
- convert: (model, msg, publish, options, meta) => {
2414
- if (utils.isLegacyEnabled(options)) {
2415
- const deviceID = msg.device.ieeeAddr;
2416
- if (!fromZigbeeStore[deviceID]) {
2417
- fromZigbeeStore[deviceID] = { direction: null };
2418
- }
2419
- fromZigbeeStore[deviceID].direction = 'up';
2420
- return { action: 'up_hold' };
2421
- }
2422
- else {
2423
- return fromZigbee_1.default.command_move.convert(model, msg, publish, options, meta);
2424
- }
2425
- },
2426
- },
2427
- osram_lightify_switch_AC0251100NJ_cmdStop: {
2428
- cluster: 'genLevelCtrl',
2429
- type: 'commandStop',
2430
- options: [exposes.options.legacy()],
2431
- convert: (model, msg, publish, options, meta) => {
2432
- if (utils.isLegacyEnabled(options)) {
2433
- const map = {
2434
- 1: 'up_release',
2435
- 2: 'down_release',
2436
- };
2437
- return { action: map[msg.endpoint.ID] };
2438
- }
2439
- else {
2440
- return fromZigbee_1.default.command_stop.convert(model, msg, publish, options, meta);
2441
- }
2442
- },
2443
- },
2444
- osram_lightify_switch_cmdMove: {
2445
- cluster: 'genLevelCtrl',
2446
- type: 'commandMove',
2447
- options: [exposes.options.legacy()],
2448
- convert: (model, msg, publish, options, meta) => {
2449
- if (utils.isLegacyEnabled(options)) {
2450
- const deviceID = msg.device.ieeeAddr;
2451
- if (!fromZigbeeStore[deviceID]) {
2452
- fromZigbeeStore[deviceID] = { direction: null };
2453
- }
2454
- fromZigbeeStore[deviceID].direction = 'down';
2455
- return { action: 'down_hold' };
2456
- }
2457
- else {
2458
- return fromZigbee_1.default.command_move.convert(model, msg, publish, options, meta);
2459
- }
2460
- },
2461
- },
2462
- osram_lightify_switch_cmdMoveHue: {
2463
- cluster: 'lightingColorCtrl',
2464
- type: 'commandMoveHue',
2465
- options: [exposes.options.legacy()],
2466
- convert: (model, msg, publish, options, meta) => {
2467
- if (utils.isLegacyEnabled(options)) {
2468
- if (msg.data.movemode === 0) {
2469
- return { action: 'circle_release' };
2470
- }
2471
- }
2472
- else {
2473
- return fromZigbee_1.default.command_move_hue.convert(model, msg, publish, options, meta);
2474
- }
2475
- },
2476
- },
2477
- osram_lightify_switch_cmdMoveToSaturation: {
2478
- cluster: 'lightingColorCtrl',
2479
- type: 'commandMoveToSaturation',
2480
- options: [exposes.options.legacy()],
2481
- convert: (model, msg, publish, options, meta) => {
2482
- if (utils.isLegacyEnabled(options)) {
2483
- return { action: 'circle_hold' };
2484
- }
2485
- else {
2486
- return fromZigbee_1.default.command_move_to_saturation.convert(model, msg, publish, options, meta);
2487
- }
2488
- },
2489
- },
2490
- osram_lightify_switch_cmdMoveToLevelWithOnOff: {
2491
- cluster: 'genLevelCtrl',
2492
- type: 'commandMoveToLevelWithOnOff',
2493
- options: [exposes.options.legacy()],
2494
- convert: (model, msg, publish, options, meta) => {
2495
- if (utils.isLegacyEnabled(options)) {
2496
- return { action: 'circle_click' };
2497
- }
2498
- else {
2499
- return fromZigbee_1.default.command_move_to_level.convert(model, msg, publish, options, meta);
2500
- }
2501
- },
2502
- },
2503
- osram_lightify_switch_cmdMoveToColorTemp: {
2504
- cluster: 'lightingColorCtrl',
2505
- type: 'commandMoveToColorTemp',
2506
- options: [exposes.options.legacy()],
2507
- convert: (model, msg, publish, options, meta) => {
2508
- if (utils.isLegacyEnabled(options)) {
2509
- return null;
2510
- }
2511
- else {
2512
- return fromZigbee_1.default.command_move_to_color_temp.convert(model, msg, publish, options, meta);
2513
- }
2514
- },
2515
- },
2516
- osram_lightify_switch_73743_cmdStop: {
2517
- cluster: 'genLevelCtrl',
2518
- type: 'commandStop',
2519
- options: [exposes.options.legacy()],
2520
- convert: (model, msg, publish, options, meta) => {
2521
- if (utils.isLegacyEnabled(options)) {
2522
- const deviceID = msg.device.ieeeAddr;
2523
- if (!fromZigbeeStore[deviceID]) {
2524
- fromZigbeeStore[deviceID] = { direction: null };
2525
- }
2526
- let direction;
2527
- if (fromZigbeeStore[deviceID].direction) {
2528
- direction = `${fromZigbeeStore[deviceID].direction}_`;
2529
- }
2530
- return { action: `${direction}release` };
2531
- }
2532
- else {
2533
- return fromZigbee_1.default.command_stop.convert(model, msg, publish, options, meta);
2534
- }
2535
- },
2536
- },
2537
- osram_lightify_switch_AB371860355_cmdOn: {
2538
- cluster: 'genOnOff',
2539
- type: 'commandOn',
2540
- options: [exposes.options.legacy()],
2541
- convert: (model, msg, publish, options, meta) => {
2542
- if (utils.isLegacyEnabled(options)) {
2543
- return { action: 'left_top_click' };
2544
- }
2545
- else {
2546
- return fromZigbee_1.default.command_on.convert(model, msg, publish, options, meta);
2547
- }
2548
- },
2549
- },
2550
- osram_lightify_switch_AB371860355_cmdOff: {
2551
- cluster: 'genOnOff',
2552
- type: 'commandOff',
2553
- options: [exposes.options.legacy()],
2554
- convert: (model, msg, publish, options, meta) => {
2555
- if (utils.isLegacyEnabled(options)) {
2556
- return { action: 'left_bottom_click' };
2557
- }
2558
- else {
2559
- return fromZigbee_1.default.command_off.convert(model, msg, publish, options, meta);
2560
- }
2561
- },
2562
- },
2563
- osram_lightify_switch_AB371860355_cmdStepColorTemp: {
2564
- cluster: 'lightingColorCtrl',
2565
- type: 'commandStepColorTemp',
2566
- options: [exposes.options.legacy()],
2567
- convert: (model, msg, publish, options, meta) => {
2568
- if (utils.isLegacyEnabled(options)) {
2569
- const pos = msg.data.stepmode === 1 ? 'top' : 'bottom';
2570
- return { action: `right_${pos}_click` };
2571
- }
2572
- else {
2573
- return fromZigbee_1.default.command_step_color_temperature.convert(model, msg, publish, options, meta);
2574
- }
2575
- },
2576
- },
2577
- osram_lightify_switch_AB371860355_cmdMoveWithOnOff: {
2578
- cluster: 'genLevelCtrl',
2579
- type: 'commandMoveWithOnOff',
2580
- options: [exposes.options.legacy()],
2581
- convert: (model, msg, publish, options, meta) => {
2582
- if (utils.isLegacyEnabled(options)) {
2583
- return { action: 'left_top_hold' };
2584
- }
2585
- else {
2586
- return fromZigbee_1.default.command_move.convert(model, msg, publish, options, meta);
2587
- }
2588
- },
2589
- },
2590
- osram_lightify_switch_AB371860355_cmdMove: {
2591
- cluster: 'genLevelCtrl',
2592
- type: 'commandMove',
2593
- options: [exposes.options.legacy()],
2594
- convert: (model, msg, publish, options, meta) => {
2595
- if (utils.isLegacyEnabled(options)) {
2596
- return { action: 'left_bottom_hold' };
2597
- }
2598
- else {
2599
- return fromZigbee_1.default.command_move.convert(model, msg, publish, options, meta);
2600
- }
2601
- },
2602
- },
2603
- osram_lightify_switch_AB371860355_cmdStop: {
2604
- cluster: 'genLevelCtrl',
2605
- type: 'commandStop',
2606
- options: [exposes.options.legacy()],
2607
- convert: (model, msg, publish, options, meta) => {
2608
- if (utils.isLegacyEnabled(options)) {
2609
- const pos = msg.endpoint.ID === 1 ? 'top' : 'bottom';
2610
- return { action: `left_${pos}_release` };
2611
- }
2612
- else {
2613
- return fromZigbee_1.default.command_stop.convert(model, msg, publish, options, meta);
2614
- }
2615
- },
2616
- },
2617
- osram_lightify_switch_AB371860355_cmdMoveHue: {
2618
- cluster: 'lightingColorCtrl',
2619
- type: 'commandMoveHue',
2620
- options: [exposes.options.legacy()],
2621
- convert: (model, msg, publish, options, meta) => {
2622
- if (utils.isLegacyEnabled(options)) {
2623
- const pos = msg.endpoint.ID === 2 ? 'top' : 'bottom';
2624
- const action = msg.data.movemode === 0 ? 'release' : 'hold';
2625
- return { action: `right_${pos}_${action}` };
2626
- }
2627
- else {
2628
- return fromZigbee_1.default.command_move_hue.convert(model, msg, publish, options, meta);
2629
- }
2630
- },
2631
- },
2632
- osram_lightify_switch_AB371860355_cmdMoveSat: {
2633
- cluster: 'lightingColorCtrl',
2634
- type: 'commandMoveToSaturation',
2635
- options: [exposes.options.legacy()],
2636
- convert: (model, msg, publish, options, meta) => {
2637
- if (utils.isLegacyEnabled(options)) {
2638
- const pos = msg.endpoint.ID === 2 ? 'top' : 'bottom';
2639
- return { action: `right_${pos}_hold` };
2640
- }
2641
- else {
2642
- return fromZigbee_1.default.command_move_to_saturation.convert(model, msg, publish, options, meta);
2643
- }
2644
- },
2645
- },
2646
- insta_scene_click: {
2647
- cluster: 'genScenes',
2648
- type: 'commandRecall',
2649
- options: [exposes.options.legacy()],
2650
- convert: (model, msg, publish, options, meta) => {
2651
- if (utils.isLegacyEnabled(options)) {
2652
- return {
2653
- action: `select_${msg.data.sceneid}`,
2654
- };
2655
- }
2656
- else {
2657
- return fromZigbee_1.default.command_recall.convert(model, msg, publish, options, meta);
2658
- }
2659
- },
2660
- },
2661
- insta_down_hold: {
2662
- cluster: 'genLevelCtrl',
2663
- type: 'commandStep',
2664
- options: [exposes.options.legacy()],
2665
- convert: (model, msg, publish, options, meta) => {
2666
- if (utils.isLegacyEnabled(options)) {
2667
- return {
2668
- action: 'down',
2669
- step_mode: msg.data.stepmode,
2670
- step_size: msg.data.stepsize,
2671
- transition_time: msg.data.transtime,
2672
- };
2673
- }
2674
- else {
2675
- return fromZigbee_1.default.command_step.convert(model, msg, publish, options, meta);
2676
- }
2677
- },
2678
- },
2679
- insta_up_hold: {
2680
- cluster: 'genLevelCtrl',
2681
- type: 'commandStepWithOnOff',
2682
- options: [exposes.options.legacy()],
2683
- convert: (model, msg, publish, options, meta) => {
2684
- if (utils.isLegacyEnabled(options)) {
2685
- return {
2686
- action: 'up',
2687
- step_mode: msg.data.stepmode,
2688
- step_size: msg.data.stepsize,
2689
- transition_time: msg.data.transtime,
2690
- };
2691
- }
2692
- else {
2693
- return fromZigbee_1.default.command_step.convert(model, msg, publish, options, meta);
2694
- }
2695
- },
2696
- },
2697
- insta_stop: {
2698
- cluster: 'genLevelCtrl',
2699
- type: 'commandStop',
2700
- options: [exposes.options.legacy()],
2701
- convert: (model, msg, publish, options, meta) => {
2702
- if (utils.isLegacyEnabled(options)) {
2703
- return {
2704
- action: 'stop',
2705
- };
2706
- }
2707
- else {
2708
- return fromZigbee_1.default.command_stop.convert(model, msg, publish, options, meta);
2709
- }
2710
- },
2711
- },
2712
- tint404011_brightness_updown_click: {
2713
- cluster: 'genLevelCtrl',
2714
- type: 'commandStep',
2715
- options: [exposes.options.legacy()],
2716
- convert: (model, msg, publish, options, meta) => {
2717
- if (utils.isLegacyEnabled(options)) {
2718
- const direction = msg.data.stepmode === 1 ? 'down' : 'up';
2719
- const payload = {
2720
- action: `brightness_${direction}_click`,
2721
- step_size: msg.data.stepsize,
2722
- transition_time: msg.data.transtime,
2723
- };
2724
- addActionGroup(payload, msg, model);
2725
- return payload;
2726
- }
2727
- else {
2728
- return fromZigbee_1.default.command_step.convert(model, msg, publish, options, meta);
2729
- }
2730
- },
2731
- },
2732
- tint404011_brightness_updown_hold: {
2733
- cluster: 'genLevelCtrl',
2734
- type: 'commandMove',
2735
- options: [exposes.options.legacy()],
2736
- convert: (model, msg, publish, options, meta) => {
2737
- if (utils.isLegacyEnabled(options)) {
2738
- const deviceID = msg.device.ieeeAddr;
2739
- const direction = msg.data.movemode === 1 ? 'down' : 'up';
2740
- // Save last direction for release event
2741
- if (!fromZigbeeStore[deviceID]) {
2742
- fromZigbeeStore[deviceID] = {};
2743
- }
2744
- fromZigbeeStore[deviceID].movemode = direction;
2745
- const payload = {
2746
- action: `brightness_${direction}_hold`,
2747
- rate: msg.data.rate,
2748
- };
2749
- addActionGroup(payload, msg, model);
2750
- return payload;
2751
- }
2752
- else {
2753
- return fromZigbee_1.default.command_move.convert(model, msg, publish, options, meta);
2754
- }
2755
- },
2756
- },
2757
- tint404011_brightness_updown_release: {
2758
- cluster: 'genLevelCtrl',
2759
- type: 'commandStop',
2760
- options: [exposes.options.legacy()],
2761
- convert: (model, msg, publish, options, meta) => {
2762
- if (utils.isLegacyEnabled(options)) {
2763
- const deviceID = msg.device.ieeeAddr;
2764
- if (!fromZigbeeStore[deviceID]) {
2765
- return null;
2766
- }
2767
- const direction = fromZigbeeStore[deviceID].movemode;
2768
- const payload = { action: `brightness_${direction}_release` };
2769
- addActionGroup(payload, msg, model);
2770
- return payload;
2771
- }
2772
- else {
2773
- return fromZigbee_1.default.command_stop.convert(model, msg, publish, options, meta);
2774
- }
2775
- },
2776
- },
2777
- tint404011_move_to_color_temp: {
2778
- cluster: 'lightingColorCtrl',
2779
- type: 'commandMoveToColorTemp',
2780
- options: [exposes.options.legacy()],
2781
- convert: (model, msg, publish, options, meta) => {
2782
- if (utils.isLegacyEnabled(options)) {
2783
- const payload = {
2784
- action: `color_temp`,
2785
- action_color_temperature: msg.data.colortemp,
2786
- transition_time: msg.data.transtime,
2787
- };
2788
- addActionGroup(payload, msg, model);
2789
- return payload;
2790
- }
2791
- else {
2792
- return fromZigbee_1.default.tint404011_move_to_color_temp.convert(model, msg, publish, options, meta);
2793
- }
2794
- },
2795
- },
2796
- tint404011_move_to_color: {
2797
- cluster: 'lightingColorCtrl',
2798
- type: 'commandMoveToColor',
2799
- options: [exposes.options.legacy()],
2800
- convert: (model, msg, publish, options, meta) => {
2801
- if (utils.isLegacyEnabled(options)) {
2802
- const payload = {
2803
- action_color: {
2804
- x: utils.precisionRound(msg.data.colorx / 65535, 3),
2805
- y: utils.precisionRound(msg.data.colory / 65535, 3),
2806
- },
2807
- action: 'color_wheel',
2808
- transition_time: msg.data.transtime,
2809
- };
2810
- addActionGroup(payload, msg, model);
2811
- return payload;
2812
- }
2813
- else {
2814
- return fromZigbee_1.default.command_move_to_color.convert(model, msg, publish, options, meta);
2815
- }
2816
- },
2817
- },
2818
- heiman_smart_controller_armmode: {
2819
- cluster: 'ssIasAce',
2820
- type: 'commandArm',
2821
- options: [exposes.options.legacy()],
2822
- convert: (model, msg, publish, options, meta) => {
2823
- if (utils.isLegacyEnabled(options)) {
2824
- if (msg.data.armmode != null) {
2825
- const lookup = {
2826
- 0: 'disarm',
2827
- 1: 'arm_partial_zones',
2828
- 3: 'arm_all_zones',
2829
- };
2830
- const value = msg.data.armmode;
2831
- return { action: lookup[value] || `armmode_${value}` };
2832
- }
2833
- }
2834
- else {
2835
- return fromZigbee_1.default.command_arm.convert(model, msg, publish, options, meta);
2836
- }
2837
- },
2838
- },
2839
- LZL4B_onoff: {
2840
- cluster: 'genLevelCtrl',
2841
- type: 'commandMoveToLevelWithOnOff',
2842
- options: [exposes.options.legacy()],
2843
- convert: (model, msg, publish, options, meta) => {
2844
- if (utils.isLegacyEnabled(options)) {
2845
- return {
2846
- action: msg.data.level,
2847
- transition_time: msg.data.transtime,
2848
- };
2849
- }
2850
- else {
2851
- return fromZigbee_1.default.command_move_to_level.convert(model, msg, publish, options, meta);
2852
- }
2853
- },
2854
- },
2855
- eria_81825_updown: {
2856
- cluster: 'genLevelCtrl',
2857
- type: 'commandStep',
2858
- options: [exposes.options.legacy()],
2859
- convert: (model, msg, publish, options, meta) => {
2860
- if (utils.isLegacyEnabled(options)) {
2861
- const direction = msg.data.stepmode === 0 ? 'up' : 'down';
2862
- return { action: `${direction}` };
2863
- }
2864
- else {
2865
- return fromZigbee_1.default.command_step.convert(model, msg, publish, options, meta);
2866
- }
2867
- },
2868
- },
2869
- ZYCT202_stop: {
2870
- cluster: 'genLevelCtrl',
2871
- type: 'commandStop',
2872
- options: [exposes.options.legacy()],
2873
- convert: (model, msg, publish, options, meta) => {
2874
- if (utils.isLegacyEnabled(options)) {
2875
- return { action: 'stop', action_group: msg.groupID };
2876
- }
2877
- else {
2878
- return fromZigbee_1.default.command_stop.convert(model, msg, publish, options, meta);
2879
- }
2880
- },
2881
- },
2882
- ZYCT202_up_down: {
2883
- cluster: 'genLevelCtrl',
2884
- type: 'commandMove',
2885
- options: [exposes.options.legacy()],
2886
- convert: (model, msg, publish, options, meta) => {
2887
- if (utils.isLegacyEnabled(options)) {
2888
- const value = msg.data['movemode'];
2889
- let action = null;
2890
- if (value === 0)
2891
- action = { action: 'up-press', action_group: msg.groupID };
2892
- else if (value === 1)
2893
- action = { action: 'down-press', action_group: msg.groupID };
2894
- return action ? action : null;
2895
- }
2896
- else {
2897
- return fromZigbee_1.default.command_move.convert(model, msg, publish, options, meta);
2898
- }
2899
- },
2900
- },
2901
- STS_PRS_251_beeping: {
2902
- cluster: 'genIdentify',
2903
- type: ['attributeReport', 'readResponse'],
2904
- options: [exposes.options.legacy()],
2905
- convert: (model, msg, publish, options, meta) => {
2906
- if (utils.isLegacyEnabled(options)) {
2907
- return { action: 'beeping' };
2908
- }
2909
- else {
2910
- return fromZigbee_1.default.identify.convert(model, msg, publish, options, meta);
2911
- }
2912
- },
2913
- },
2914
- dimmer_passthru_brightness: {
2915
- cluster: 'genLevelCtrl',
2916
- type: 'commandMoveToLevelWithOnOff',
2917
- options: [exposes.options.legacy()],
2918
- convert: (model, msg, publish, options, meta) => {
2919
- if (utils.isLegacyEnabled(options)) {
2920
- ratelimitedDimmer(model, msg, publish, options, meta);
2921
- }
2922
- else {
2923
- return fromZigbee_1.default.command_move_to_level.convert(model, msg, publish, options, meta);
2924
- }
2925
- },
2926
- },
2927
- bitron_thermostat_att_report: {
2928
- cluster: 'hvacThermostat',
2929
- type: ['attributeReport', 'readResponse'],
2930
- options: [exposes.options.legacy()],
2931
- convert: (model, msg, publish, options, meta) => {
2932
- if (!utils.isLegacyEnabled(options)) {
2933
- return fromZigbee_1.default.thermostat.convert(model, msg, publish, options, meta);
2934
- }
2935
- const result = {};
2936
- if (typeof msg.data['localTemp'] == 'number') {
2937
- result.local_temperature = utils.precisionRound(msg.data['localTemp'], 2) / 100;
2938
- }
2939
- if (typeof msg.data['localTemperatureCalibration'] == 'number') {
2940
- result.local_temperature_calibration = utils.precisionRound(msg.data['localTemperatureCalibration'], 2) / 10;
2941
- }
2942
- if (typeof msg.data['occupiedHeatingSetpoint'] == 'number') {
2943
- result.occupied_heating_setpoint = utils.precisionRound(msg.data['occupiedHeatingSetpoint'], 2) / 100;
2944
- }
2945
- if (typeof msg.data['runningState'] == 'number') {
2946
- result.running_state = msg.data['runningState'];
2947
- }
2948
- if (typeof msg.data['batteryAlarmState'] == 'number') {
2949
- result.battery_alarm_state = msg.data['batteryAlarmState'];
2950
- }
2951
- return result;
2952
- },
2953
- },
2954
- thermostat_att_report: {
2955
- cluster: 'hvacThermostat',
2956
- type: ['attributeReport', 'readResponse'],
2957
- options: [exposes.options.legacy()],
2958
- convert: (model, msg, publish, options, meta) => {
2959
- if (!utils.isLegacyEnabled(options)) {
2960
- return fromZigbee_1.default.thermostat.convert(model, msg, publish, options, meta);
2961
- }
2962
- const result = {};
2963
- if (typeof msg.data['localTemp'] == 'number') {
2964
- result[postfixWithEndpointName('local_temperature', msg, model)] = utils.precisionRound(msg.data['localTemp'], 2) / 100;
2965
- }
2966
- if (typeof msg.data['localTemperatureCalibration'] == 'number') {
2967
- result[postfixWithEndpointName('local_temperature_calibration', msg, model)] =
2968
- utils.precisionRound(msg.data['localTemperatureCalibration'], 2) / 10;
2969
- }
2970
- if (typeof msg.data['occupancy'] == 'number') {
2971
- result[postfixWithEndpointName('occupancy', msg, model)] = msg.data['occupancy'];
2972
- }
2973
- if (typeof msg.data['occupiedHeatingSetpoint'] == 'number') {
2974
- let ohs = utils.precisionRound(msg.data['occupiedHeatingSetpoint'], 2) / 100;
2975
- // Stelpro will return -325.65 when set to off
2976
- ohs = ohs < -250 ? 0 : ohs;
2977
- result[postfixWithEndpointName('occupied_heating_setpoint', msg, model)] = ohs;
2978
- }
2979
- if (typeof msg.data['unoccupiedHeatingSetpoint'] == 'number') {
2980
- result[postfixWithEndpointName('unoccupied_heating_setpoint', msg, model)] =
2981
- utils.precisionRound(msg.data['unoccupiedHeatingSetpoint'], 2) / 100;
2982
- }
2983
- if (typeof msg.data['occupiedCoolingSetpoint'] == 'number') {
2984
- result[postfixWithEndpointName('occupied_cooling_setpoint', msg, model)] =
2985
- utils.precisionRound(msg.data['occupiedCoolingSetpoint'], 2) / 100;
2986
- }
2987
- if (typeof msg.data['unoccupiedCoolingSetpoint'] == 'number') {
2988
- result[postfixWithEndpointName('unoccupied_cooling_setpoint', msg, model)] =
2989
- utils.precisionRound(msg.data['unoccupiedCoolingSetpoint'], 2) / 100;
2990
- }
2991
- if (typeof msg.data['weeklySchedule'] == 'number') {
2992
- result[postfixWithEndpointName('weekly_schedule', msg, model)] = msg.data['weeklySchedule'];
2993
- }
2994
- if (typeof msg.data['setpointChangeAmount'] == 'number') {
2995
- result[postfixWithEndpointName('setpoint_change_amount', msg, model)] = msg.data['setpointChangeAmount'] / 100;
2996
- }
2997
- if (typeof msg.data['setpointChangeSource'] == 'number') {
2998
- result[postfixWithEndpointName('setpoint_change_source', msg, model)] = msg.data['setpointChangeSource'];
2999
- }
3000
- if (typeof msg.data['setpointChangeSourceTimeStamp'] == 'number') {
3001
- result[postfixWithEndpointName('setpoint_change_source_timestamp', msg, model)] = msg.data['setpointChangeSourceTimeStamp'];
3002
- }
3003
- if (typeof msg.data['remoteSensing'] == 'number') {
3004
- result[postfixWithEndpointName('remote_sensing', msg, model)] = msg.data['remoteSensing'];
3005
- }
3006
- const ctrl = msg.data['ctrlSeqeOfOper'];
3007
- if (typeof ctrl == 'number' && thermostatControlSequenceOfOperations[ctrl] !== undefined) {
3008
- result[postfixWithEndpointName('control_sequence_of_operation', msg, model)] = thermostatControlSequenceOfOperations[ctrl];
3009
- }
3010
- const smode = msg.data['systemMode'];
3011
- if (typeof smode == 'number' && thermostatSystemModes[smode] !== undefined) {
3012
- result[postfixWithEndpointName('system_mode', msg, model)] = thermostatSystemModes[smode];
3013
- }
3014
- const rmode = msg.data['runningMode'];
3015
- if (typeof rmode == 'number' && thermostatSystemModes[rmode] !== undefined) {
3016
- result[postfixWithEndpointName('running_mode', msg, model)] = thermostatSystemModes[rmode];
3017
- }
3018
- const state = msg.data['runningState'];
3019
- if (typeof state == 'number' && constants.thermostatRunningStates[state] !== undefined) {
3020
- result[postfixWithEndpointName('running_state', msg, model)] = constants.thermostatRunningStates[state];
3021
- }
3022
- if (typeof msg.data['pIHeatingDemand'] == 'number') {
3023
- result[postfixWithEndpointName('pi_heating_demand', msg, model)] = utils.precisionRound((msg.data['pIHeatingDemand'] / 255.0) * 100.0, 0);
3024
- }
3025
- if (typeof msg.data['tempSetpointHold'] == 'number') {
3026
- result[postfixWithEndpointName('temperature_setpoint_hold', msg, model)] = msg.data['tempSetpointHold'];
3027
- }
3028
- if (typeof msg.data['tempSetpointHoldDuration'] == 'number') {
3029
- result[postfixWithEndpointName('temperature_setpoint_hold_duration', msg, model)] = msg.data['tempSetpointHoldDuration'];
3030
- }
3031
- return result;
3032
- },
3033
- },
3034
- stelpro_thermostat: {
3035
- cluster: 'hvacThermostat',
3036
- type: ['attributeReport', 'readResponse'],
3037
- options: [exposes.options.legacy()],
3038
- convert: (model, msg, publish, options, meta) => {
3039
- if (!utils.isLegacyEnabled(options)) {
3040
- return fromZigbee_1.default.stelpro_thermostat.convert(model, msg, publish, options, meta);
3041
- }
3042
- const result = fromZigbee.thermostat_att_report.convert(model, msg, publish, options, meta);
3043
- const mode = msg.data['StelproSystemMode'];
3044
- if (mode == 'number') {
3045
- result.stelpro_mode = mode;
3046
- switch (mode) {
3047
- case 5:
3048
- // 'Eco' mode is translated into 'auto' here
3049
- result.system_mode = thermostatSystemModes[1];
3050
- break;
3051
- }
3052
- }
3053
- const piHeatingDemand = msg.data['pIHeatingDemand'];
3054
- if (typeof piHeatingDemand == 'number') {
3055
- // DEPRECATED: only return running_state here (change operation -> running_state)
3056
- result.operation = piHeatingDemand >= 10 ? 'heating' : 'idle';
3057
- result.running_state = piHeatingDemand >= 10 ? 'heat' : 'idle';
3058
- }
3059
- return result;
3060
- },
3061
- },
3062
- viessmann_thermostat_att_report: {
3063
- cluster: 'hvacThermostat',
3064
- type: ['attributeReport', 'readResponse'],
3065
- options: [exposes.options.legacy()],
3066
- convert: (model, msg, publish, options, meta) => {
3067
- if (!utils.isLegacyEnabled(options)) {
3068
- return fromZigbee_1.default.viessmann_thermostat.convert(model, msg, publish, options, meta);
3069
- }
3070
- const result = fromZigbee.thermostat_att_report.convert(model, msg, publish, options, meta);
3071
- // ViessMann TRVs report piHeatingDemand from 0-5
3072
- // NOTE: remove the result for now, but leave it configure for reporting
3073
- // it will show up in the debug log still to help try and figure out
3074
- // what this value potentially means.
3075
- if (typeof msg.data['pIHeatingDemand'] == 'number') {
3076
- delete result.pi_heating_demand;
3077
- }
3078
- return result;
3079
- },
3080
- },
3081
- wiser_thermostat: {
3082
- cluster: 'hvacThermostat',
3083
- type: ['attributeReport', 'readResponse'],
3084
- options: [exposes.options.legacy()],
3085
- convert: (model, msg, publish, options, meta) => {
3086
- if (!utils.isLegacyEnabled(options)) {
3087
- return fromZigbee_1.default.thermostat.convert(model, msg, publish, options, meta);
3088
- }
3089
- const result = {};
3090
- if (typeof msg.data['localTemp'] == 'number') {
3091
- result.local_temperature = utils.precisionRound(msg.data['localTemp'], 2) / 100;
3092
- }
3093
- if (typeof msg.data['occupiedHeatingSetpoint'] == 'number') {
3094
- result.occupied_heating_setpoint = utils.precisionRound(msg.data['occupiedHeatingSetpoint'], 2) / 100;
3095
- }
3096
- if (typeof msg.data['pIHeatingDemand'] == 'number') {
3097
- result.pi_heating_demand = utils.precisionRound(msg.data['pIHeatingDemand'], 2);
3098
- }
3099
- return result;
3100
- },
3101
- },
3102
- hvac_user_interface: {
3103
- cluster: 'hvacUserInterfaceCfg',
3104
- type: ['attributeReport', 'readResponse'],
3105
- options: [exposes.options.legacy()],
3106
- convert: (model, msg, publish, options, meta) => {
3107
- if (!utils.isLegacyEnabled(options)) {
3108
- return fromZigbee_1.default.hvac_user_interface.convert(model, msg, publish, options, meta);
3109
- }
3110
- const result = {};
3111
- const lockoutMode = msg.data['keypadLockout'];
3112
- if (typeof lockoutMode == 'number') {
3113
- result.keypad_lockout = lockoutMode;
3114
- }
3115
- return result;
3116
- },
3117
- },
3118
- thermostat_weekly_schedule_rsp: {
3119
- cluster: 'hvacThermostat',
3120
- type: ['commandGetWeeklyScheduleRsp'],
3121
- options: [exposes.options.legacy()],
3122
- convert: (model, msg, publish, options, meta) => {
3123
- if (!utils.isLegacyEnabled(options)) {
3124
- return fromZigbee_1.default.thermostat_weekly_schedule.convert(model, msg, publish, options, meta);
3125
- }
3126
- const result = {};
3127
- const key = postfixWithEndpointName('weekly_schedule', msg, model);
3128
- result[key] = {};
3129
- if (typeof msg.data['dayofweek'] == 'number') {
3130
- result[key][msg.data['dayofweek']] = msg.data;
3131
- for (const elem of result[key][msg.data['dayofweek']]['transitions']) {
3132
- if (typeof elem['heatSetpoint'] == 'number') {
3133
- elem['heatSetpoint'] /= 100;
3134
- }
3135
- if (typeof elem['coolSetpoint'] == 'number') {
3136
- elem['coolSetpoint'] /= 100;
3137
- }
3138
- }
3139
- }
3140
- return result;
3141
- },
3142
- },
3143
- terncy_knob: {
3144
- cluster: 'manuSpecificClusterAduroSmart',
3145
- type: ['attributeReport', 'readResponse'],
3146
- options: [exposes.options.legacy()],
3147
- convert: (model, msg, publish, options, meta) => {
3148
- if (!utils.isLegacyEnabled(options)) {
3149
- return fromZigbee_1.default.terncy_knob.convert(model, msg, publish, options, meta);
3150
- }
3151
- if (typeof msg.data['27'] === 'number') {
3152
- return {
3153
- action: 'rotate',
3154
- direction: msg.data['27'] > 0 ? 'clockwise' : 'counterclockwise',
3155
- number: Math.abs(msg.data['27']) / 12,
3156
- };
3157
- }
3158
- },
3159
- },
3160
- wiser_itrv_battery: {
3161
- cluster: 'genPowerCfg',
3162
- type: ['attributeReport', 'readResponse'],
3163
- options: [exposes.options.legacy()],
3164
- convert: (model, msg, publish, options, meta) => {
3165
- if (!utils.isLegacyEnabled(options)) {
3166
- return fromZigbee_1.default.battery.convert(model, msg, publish, options, meta);
3167
- }
3168
- const result = {};
3169
- if (typeof msg.data['batteryVoltage'] == 'number') {
3170
- const battery = { max: 30, min: 22 };
3171
- const voltage = msg.data['batteryVoltage'];
3172
- result.battery = toPercentage(voltage, battery.min, battery.max);
3173
- result.voltage = voltage / 10;
3174
- }
3175
- if (typeof msg.data['batteryAlarmState'] == 'number') {
3176
- const battLow = msg.data['batteryAlarmState'];
3177
- if (battLow) {
3178
- result['battery_low'] = true;
1497
+ case dataPoints.x5hCurrentTemp: {
1498
+ const temperature = value & (1 << 15) ? value - (1 << 16) + 1 : value;
1499
+ return { local_temperature: parseFloat((temperature / 10).toFixed(1)) };
3179
1500
  }
3180
- else {
3181
- result['battery_low'] = false;
1501
+ case dataPoints.x5hTempCorrection: {
1502
+ return { local_temperature_calibration: parseFloat((value / 10).toFixed(1)) };
3182
1503
  }
3183
- }
3184
- return result;
3185
- },
3186
- },
3187
- ubisys_c4_scenes: {
3188
- cluster: 'genScenes',
3189
- type: 'commandRecall',
3190
- options: [exposes.options.legacy()],
3191
- convert: (model, msg, publish, options, meta) => {
3192
- if (!utils.isLegacyEnabled(options)) {
3193
- return fromZigbee_1.default.command_recall.convert(model, msg, publish, options, meta);
3194
- }
3195
- return { action: `${msg.endpoint.ID}_scene_${msg.data.groupid}_${msg.data.sceneid}` };
3196
- },
3197
- },
3198
- ubisys_c4_onoff: {
3199
- cluster: 'genOnOff',
3200
- type: ['commandOn', 'commandOff', 'commandToggle'],
3201
- options: [exposes.options.legacy()],
3202
- convert: (model, msg, publish, options, meta) => {
3203
- if (!utils.isLegacyEnabled(options)) {
3204
- if (msg.type === 'commandOn') {
3205
- return fromZigbee_1.default.command_on.convert(model, msg, publish, options, meta);
1504
+ case dataPoints.x5hMode: {
1505
+ const lookup = { 0: 'manual', 1: 'program' };
1506
+ return { preset: lookup[value] };
1507
+ }
1508
+ case dataPoints.x5hSensorSelection: {
1509
+ const lookup = { 0: 'internal', 1: 'external', 2: 'both' };
1510
+ return { sensor: lookup[value] };
3206
1511
  }
3207
- else if (msg.type === 'commandOff') {
3208
- return fromZigbee_1.default.command_off.convert(model, msg, publish, options, meta);
1512
+ case dataPoints.x5hOutputReverse: {
1513
+ return { output_reverse: value };
3209
1514
  }
3210
- else if (msg.type === 'commandToggle') {
3211
- return fromZigbee_1.default.command_toggle.convert(model, msg, publish, options, meta);
1515
+ default: {
1516
+ logger_1.logger.debug(`Unrecognized DP #${dp} with data ${JSON.stringify(dpValue)}`, 'zhc:legacy:fz:x5h_thermostat');
3212
1517
  }
3213
1518
  }
3214
- return { action: `${msg.endpoint.ID}_${msg.type.substr(7).toLowerCase()}` };
3215
1519
  },
3216
1520
  },
3217
- ubisys_c4_level: {
3218
- cluster: 'genLevelCtrl',
3219
- type: ['commandMoveWithOnOff', 'commandStopWithOnOff'],
3220
- options: [exposes.options.legacy()],
1521
+ zs_thermostat: {
1522
+ cluster: 'manuSpecificTuya',
1523
+ type: ['commandDataResponse', 'commandDataReport'],
3221
1524
  convert: (model, msg, publish, options, meta) => {
3222
- if (!utils.isLegacyEnabled(options)) {
3223
- if (msg.type === 'commandMoveWithOnOff') {
3224
- return fromZigbee_1.default.command_move.convert(model, msg, publish, options, meta);
3225
- }
3226
- else if (msg.type === 'commandStopWithOnOff') {
3227
- return fromZigbee_1.default.command_stop.convert(model, msg, publish, options, meta);
3228
- }
3229
- }
3230
- switch (msg.type) {
3231
- case 'commandMoveWithOnOff':
3232
- return { action: `${msg.endpoint.ID}_level_move_${msg.data.movemode ? 'down' : 'up'}` };
3233
- case 'commandStopWithOnOff':
3234
- return { action: `${msg.endpoint.ID}_level_stop` };
1525
+ const dpValue = firstDpValue(msg, meta, 'zs_thermostat');
1526
+ const dp = dpValue.dp;
1527
+ const value = getDataValue(dpValue);
1528
+ const ret = {};
1529
+ const daysMap = { 1: 'monday', 2: 'tuesday', 3: 'wednesday', 4: 'thursday', 5: 'friday', 6: 'saturday', 7: 'sunday' };
1530
+ const day = daysMap[value[0]];
1531
+ switch (dp) {
1532
+ case dataPoints.zsChildLock:
1533
+ return { child_lock: value ? 'LOCK' : 'UNLOCK' };
1534
+ case dataPoints.zsHeatingSetpoint:
1535
+ if (value == 0)
1536
+ ret.system_mode = 'off';
1537
+ if (value == 60) {
1538
+ ret.system_mode = 'heat';
1539
+ ret.preset = 'boost';
1540
+ }
1541
+ ret.current_heating_setpoint = (value / 2).toFixed(1);
1542
+ if (value > 0 && value < 60)
1543
+ globalStore.putValue(msg.endpoint, 'current_heating_setpoint', ret.current_heating_setpoint);
1544
+ return ret;
1545
+ case dataPoints.zsHeatingSetpointAuto:
1546
+ return { current_heating_setpoint_auto: (value / 2).toFixed(1) };
1547
+ case dataPoints.zsOpenwindowTemp:
1548
+ return { detectwindow_temperature: (value / 2).toFixed(1) };
1549
+ case dataPoints.zsOpenwindowTime:
1550
+ return { detectwindow_timeminute: value };
1551
+ case dataPoints.zsLocalTemp:
1552
+ return { local_temperature: (value / 10).toFixed(1) };
1553
+ case dataPoints.zsBatteryVoltage:
1554
+ return { voltage: Math.round(value * 10) };
1555
+ case dataPoints.zsTempCalibration:
1556
+ return { local_temperature_calibration: value > 55 ? ((value - 0x100000000) / 10).toFixed(1) : (value / 10).toFixed(1) };
1557
+ case dataPoints.zsBinaryOne:
1558
+ return { binary_one: value ? 'ON' : 'OFF' };
1559
+ case dataPoints.zsBinaryTwo:
1560
+ return { binary_two: value ? 'ON' : 'OFF' };
1561
+ case dataPoints.zsComfortTemp:
1562
+ return { comfort_temperature: (value / 2).toFixed(1) };
1563
+ case dataPoints.zsEcoTemp:
1564
+ return { eco_temperature: (value / 2).toFixed(1) };
1565
+ // case dataPoints.zsAwayTemp:
1566
+ // return {away_preset_temperature: (value / 2).toFixed(1)};
1567
+ case dataPoints.zsMode:
1568
+ switch (value) {
1569
+ case 1: // manual
1570
+ return { system_mode: 'heat', away_mode: 'OFF', preset: 'manual' };
1571
+ case 2: // away
1572
+ return { system_mode: 'auto', away_mode: 'ON', preset: 'holiday' };
1573
+ case 0: // auto
1574
+ return { system_mode: 'auto', away_mode: 'OFF', preset: 'schedule' };
1575
+ default:
1576
+ logger_1.logger.warning(`Preset ${value} is not recognized.`, 'zhc:legacy:fz:zs_thermostat');
1577
+ break;
1578
+ }
1579
+ break;
1580
+ case dataPoints.zsScheduleMonday:
1581
+ case dataPoints.zsScheduleTuesday:
1582
+ case dataPoints.zsScheduleWednesday:
1583
+ case dataPoints.zsScheduleThursday:
1584
+ case dataPoints.zsScheduleFriday:
1585
+ case dataPoints.zsScheduleSaturday:
1586
+ case dataPoints.zsScheduleSunday:
1587
+ for (let i = 1; i <= 9; i++) {
1588
+ const tempId = (i - 1) * 2 + 1;
1589
+ const timeId = (i - 1) * 2 + 2;
1590
+ ret[`${day}_temp_${i}`] = (value[tempId] / 2).toFixed(1);
1591
+ if (i != 9) {
1592
+ ret[`${day}_hour_${i}`] = Math.floor(value[timeId] / 4)
1593
+ .toString()
1594
+ .padStart(2, '0');
1595
+ ret[`${day}_minute_${i}`] = ((value[timeId] % 4) * 15).toString().padStart(2, '0');
1596
+ }
1597
+ }
1598
+ return ret;
1599
+ case dataPoints.zsAwaySetting:
1600
+ ret.away_preset_year = value[0];
1601
+ ret.away_preset_month = value[1];
1602
+ ret.away_preset_day = value[2];
1603
+ ret.away_preset_hour = value[3];
1604
+ ret.away_preset_minute = value[4];
1605
+ ret.away_preset_temperature = (value[5] / 2).toFixed(1);
1606
+ ret.away_preset_days = (value[6] << 8) + value[7];
1607
+ return ret;
1608
+ default:
1609
+ logger_1.logger.debug(`Unrecognized DP #${dp} with data ${JSON.stringify(dpValue)}`, 'zhc:legacy:fz:zs_thermostat');
3235
1610
  }
3236
1611
  },
3237
1612
  },
3238
- ubisys_c4_cover: {
3239
- cluster: 'closuresWindowCovering',
3240
- type: ['commandUpOpen', 'commandDownClose', 'commandStop'],
3241
- options: [exposes.options.legacy()],
1613
+ giexWaterValve: {
1614
+ cluster: 'manuSpecificTuya',
1615
+ type: ['commandDataResponse', 'commandDataReport'],
3242
1616
  convert: (model, msg, publish, options, meta) => {
3243
- if (!utils.isLegacyEnabled(options)) {
3244
- if (msg.type === 'commandUpOpen') {
3245
- return fromZigbee_1.default.command_cover_open.convert(model, msg, publish, options, meta);
3246
- }
3247
- else if (msg.type === 'commandDownClose') {
3248
- return fromZigbee_1.default.command_cover_close.convert(model, msg, publish, options, meta);
3249
- }
3250
- else if (msg.type === 'commandStop') {
3251
- return fromZigbee_1.default.command_cover_stop.convert(model, msg, publish, options, meta);
1617
+ // @ts-expect-error ignore
1618
+ const modelConverters = giexFzModelConverters[model.model] || {};
1619
+ for (const dpValue of msg.data.dpValues) {
1620
+ const value = getDataValue(dpValue);
1621
+ const { dp } = dpValue;
1622
+ switch (dp) {
1623
+ case dataPoints.giexWaterValve.state:
1624
+ return { [giexWaterValve.state]: value ? ON : OFF };
1625
+ case dataPoints.giexWaterValve.mode:
1626
+ return { [giexWaterValve.mode]: value ? CAPACITY : DURATION };
1627
+ case dataPoints.giexWaterValve.irrigationTarget:
1628
+ return { [giexWaterValve.irrigationTarget]: value };
1629
+ case dataPoints.giexWaterValve.cycleIrrigationNumTimes:
1630
+ return { [giexWaterValve.cycleIrrigationNumTimes]: value };
1631
+ case dataPoints.giexWaterValve.cycleIrrigationInterval:
1632
+ return { [giexWaterValve.cycleIrrigationInterval]: value };
1633
+ case dataPoints.giexWaterValve.waterConsumed:
1634
+ return { [giexWaterValve.waterConsumed]: value };
1635
+ case dataPoints.giexWaterValve.irrigationStartTime:
1636
+ return { [giexWaterValve.irrigationStartTime]: modelConverters.time?.(value) || value };
1637
+ case dataPoints.giexWaterValve.irrigationEndTime:
1638
+ return { [giexWaterValve.irrigationEndTime]: modelConverters.time?.(value) || value };
1639
+ case dataPoints.giexWaterValve.lastIrrigationDuration:
1640
+ return { [giexWaterValve.lastIrrigationDuration]: value.split(',').shift() }; // Remove meaningless ,0 suffix
1641
+ case dataPoints.giexWaterValve.battery:
1642
+ return { [giexWaterValve.battery]: value };
1643
+ case dataPoints.giexWaterValve.currentTemperature:
1644
+ return; // Do Nothing - value ignored because it isn't a valid temperature reading (misdocumented and usage unclear)
1645
+ default: // Unknown data point warning
1646
+ logger_1.logger.debug(`Unrecognized DP #${dp} with VALUE = ${value}`, 'legacy:fz:giex_water_valve');
3252
1647
  }
3253
1648
  }
3254
- const lookup = {
3255
- commandUpOpen: 'open',
3256
- commandDownClose: 'close',
3257
- commandStop: 'stop',
3258
- };
3259
- return { action: `${msg.endpoint.ID}_cover_${lookup[msg.type]}` };
3260
1649
  },
3261
1650
  },
3262
- hue_dimmer_switch: {
3263
- cluster: 'manuSpecificPhilips',
3264
- type: 'commandHueNotification',
3265
- options: [exposes.options.legacy(), exposes.options.simulated_brightness('Only works when legacy is false.')],
1651
+ tuya_alecto_smoke: {
1652
+ cluster: 'manuSpecificTuya',
1653
+ type: ['commandDataResponse', 'commandDataReport'],
3266
1654
  convert: (model, msg, publish, options, meta) => {
3267
- if (!utils.isLegacyEnabled(options)) {
3268
- return fromZigbee_1.default.hue_dimmer_switch.convert(model, msg, publish, options, meta);
3269
- }
3270
- const multiplePressTimeout = options && options.multiple_press_timeout !== undefined ? options.multiple_press_timeout : 0.25;
3271
- const getPayload = function (button, pressType, pressDuration, pressCounter, brightnessSend, brightnessValue) {
3272
- const payLoad = {};
3273
- payLoad['action'] = `${button}-${pressType}`;
3274
- payLoad['duration'] = pressDuration / 1000;
3275
- if (pressCounter) {
3276
- payLoad['counter'] = pressCounter;
3277
- }
3278
- if (brightnessSend) {
3279
- payLoad['brightness'] = fromZigbeeStore[deviceID].brightnessValue;
3280
- }
3281
- return payLoad;
3282
- };
3283
- const deviceID = msg.device.ieeeAddr;
3284
- const buttonLookup = { 1: 'on', 2: 'up', 3: 'down', 4: 'off' };
3285
- const button = buttonLookup[msg.data['button']];
3286
- const typeLookup = { 0: 'press', 1: 'hold', 2: 'release', 3: 'release' };
3287
- const type = typeLookup[msg.data['type']];
3288
- const brightnessEnabled = options && options.send_brightess !== undefined ? options.send_brightess : true;
3289
- const brightnessSend = brightnessEnabled && button && (button == 'up' || button == 'down');
3290
- // Initialize store
3291
- if (!fromZigbeeStore[deviceID]) {
3292
- fromZigbeeStore[deviceID] = {
3293
- pressStart: null,
3294
- pressType: null,
3295
- delayedButton: null,
3296
- delayedBrightnessSend: null,
3297
- delayedType: null,
3298
- delayedCounter: 0,
3299
- delayedTimerStart: null,
3300
- delayedTimer: null,
3301
- };
3302
- if (brightnessEnabled) {
3303
- fromZigbeeStore[deviceID].brightnessValue = 255;
3304
- fromZigbeeStore[deviceID].brightnessSince = null;
3305
- fromZigbeeStore[deviceID].brightnessDirection = null;
3306
- }
3307
- }
3308
- if (button && type) {
3309
- if (type == 'press') {
3310
- fromZigbeeStore[deviceID].pressStart = Date.now();
3311
- fromZigbeeStore[deviceID].pressType = 'press';
3312
- if (brightnessSend) {
3313
- const newValue = fromZigbeeStore[deviceID].brightnessValue + (button === 'up' ? 32 : -32);
3314
- fromZigbeeStore[deviceID].brightnessValue = numberWithinRange(newValue, 1, 255);
3315
- }
3316
- }
3317
- else if (type == 'hold') {
3318
- fromZigbeeStore[deviceID].pressType = 'hold';
3319
- if (brightnessSend) {
3320
- holdUpdateBrightness324131092621(deviceID);
3321
- fromZigbeeStore[deviceID].brightnessSince = Date.now();
3322
- fromZigbeeStore[deviceID].brightnessDirection = button;
3323
- }
3324
- }
3325
- else if (type == 'release') {
3326
- if (brightnessSend) {
3327
- fromZigbeeStore[deviceID].brightnessSince = null;
3328
- fromZigbeeStore[deviceID].brightnessDirection = null;
3329
- }
3330
- if (fromZigbeeStore[deviceID].pressType == 'hold') {
3331
- fromZigbeeStore[deviceID].pressType += '-release';
3332
- }
3333
- }
3334
- if (type == 'press') {
3335
- // pressed different button
3336
- if (fromZigbeeStore[deviceID].delayedTimer && fromZigbeeStore[deviceID].delayedButton != button) {
3337
- clearTimeout(fromZigbeeStore[deviceID].delayedTimer);
3338
- fromZigbeeStore[deviceID].delayedTimer = null;
3339
- publish(getPayload(fromZigbeeStore[deviceID].delayedButton, fromZigbeeStore[deviceID].delayedType, 0, fromZigbeeStore[deviceID].delayedCounter, fromZigbeeStore[deviceID].delayedBrightnessSend, fromZigbeeStore[deviceID].brightnessValue));
3340
- }
3341
- }
3342
- else {
3343
- // released after press: start timer
3344
- if (fromZigbeeStore[deviceID].pressType == 'press') {
3345
- if (fromZigbeeStore[deviceID].delayedTimer) {
3346
- clearTimeout(fromZigbeeStore[deviceID].delayedTimer);
3347
- fromZigbeeStore[deviceID].delayedTimer = null;
3348
- }
3349
- else {
3350
- fromZigbeeStore[deviceID].delayedCounter = 0;
3351
- }
3352
- fromZigbeeStore[deviceID].delayedButton = button;
3353
- fromZigbeeStore[deviceID].delayedBrightnessSend = brightnessSend;
3354
- fromZigbeeStore[deviceID].delayedType = fromZigbeeStore[deviceID].pressType;
3355
- fromZigbeeStore[deviceID].delayedCounter++;
3356
- fromZigbeeStore[deviceID].delayedTimerStart = Date.now();
3357
- fromZigbeeStore[deviceID].delayedTimer = setTimeout(() => {
3358
- publish(getPayload(fromZigbeeStore[deviceID].delayedButton, fromZigbeeStore[deviceID].delayedType, 0, fromZigbeeStore[deviceID].delayedCounter, fromZigbeeStore[deviceID].delayedBrightnessSend, fromZigbeeStore[deviceID].brightnessValue));
3359
- fromZigbeeStore[deviceID].delayedTimer = null;
3360
- // @ts-expect-error ignore
3361
- }, multiplePressTimeout * 1000);
3362
- }
3363
- else {
3364
- const pressDuration = fromZigbeeStore[deviceID].pressType == 'hold' || fromZigbeeStore[deviceID].pressType == 'hold-release'
3365
- ? Date.now() - fromZigbeeStore[deviceID].pressStart
3366
- : 0;
3367
- return getPayload(button, fromZigbeeStore[deviceID].pressType, pressDuration, null, brightnessSend, fromZigbeeStore[deviceID].brightnessValue);
3368
- }
3369
- }
1655
+ const dpValue = firstDpValue(msg, meta, 'tuya_alecto_smoke');
1656
+ const dp = dpValue.dp;
1657
+ const value = getDataValue(dpValue);
1658
+ switch (dp) {
1659
+ case dataPoints.alectoSmokeState:
1660
+ // @ts-expect-error ignore
1661
+ return { smoke_state: { 0: 'alarm', 1: 'normal' }[value] };
1662
+ case dataPoints.alectoSmokeValue:
1663
+ return { smoke_value: value };
1664
+ case dataPoints.alectoSelfChecking:
1665
+ return { self_checking: value };
1666
+ case dataPoints.alectoCheckingResult:
1667
+ // @ts-expect-error ignore
1668
+ return { checking_result: { 0: 'checking', 1: 'check_success', 2: 'check_failure', 3: 'others' }[value] };
1669
+ case dataPoints.alectoSmokeTest:
1670
+ return { smoke_test: value };
1671
+ case dataPoints.alectoLifecycle:
1672
+ return { lifecycle: value };
1673
+ case dataPoints.alectoBatteryPercentage:
1674
+ return { battery: value };
1675
+ case dataPoints.alectoBatteryState:
1676
+ // @ts-expect-error ignore
1677
+ return { battery_state: { 0: 'low', 1: 'middle', 2: 'high' }[value] };
1678
+ case dataPoints.alectoSilence:
1679
+ return { silence: value };
1680
+ default:
1681
+ logger_1.logger.debug(`Unrecognized DP #${dp} with data ${JSON.stringify(msg.data)}`, 'zhc:legacy:fz:tuya_alecto_smoke');
3370
1682
  }
3371
- return {};
3372
1683
  },
3373
1684
  },
3374
1685
  blitzwolf_occupancy_with_timeout: {
@@ -4575,7 +2886,7 @@ const fromZigbee1 = {
4575
2886
  result = { fading_time: value / 10 };
4576
2887
  break;
4577
2888
  case dataPoints.tshpsIlluminanceLux:
4578
- result = { illuminance_lux: value };
2889
+ result = { illuminance: value };
4579
2890
  break;
4580
2891
  case dataPoints.tshpsCLI: // not recognize
4581
2892
  result = { cli: value };
@@ -4760,7 +3071,7 @@ const fromZigbee1 = {
4760
3071
  case dataPoints.thitBatteryPercentage:
4761
3072
  return { battery: value };
4762
3073
  case dataPoints.thitIlluminanceLux:
4763
- return { illuminance_lux: value };
3074
+ return { illuminance: value };
4764
3075
  default:
4765
3076
  logger_1.logger.debug(`Unrecognized DP #${dp} with data ${JSON.stringify(dpValue)}`, 'zhc:legacy:fz:tuya_illuminance_temperature_humidity_sensor');
4766
3077
  }
@@ -4784,7 +3095,7 @@ const fromZigbee1 = {
4784
3095
  case dataPoints.state:
4785
3096
  return { brightness_state: brightnessState[value] };
4786
3097
  case dataPoints.tIlluminanceLux:
4787
- return { illuminance_lux: value };
3098
+ return { illuminance: value };
4788
3099
  default:
4789
3100
  logger_1.logger.debug(`Unrecognized DP #${dp} with data ${JSON.stringify(dpValue)}`, 'zhc:legacy:fz:tuya_illuminance_sensor');
4790
3101
  }
@@ -5540,7 +3851,7 @@ const fromZigbee1 = {
5540
3851
  };
5541
3852
  case 101:
5542
3853
  return {
5543
- illuminance_lux: value,
3854
+ illuminance: value,
5544
3855
  };
5545
3856
  case 102:
5546
3857
  if (meta.device.manufacturerName === '_TZE200_kagkgk0i') {
@@ -5558,7 +3869,7 @@ const fromZigbee1 = {
5558
3869
  led_enable: value == 1 ? true : false,
5559
3870
  };
5560
3871
  case 104:
5561
- return { illuminance_lux: value };
3872
+ return { illuminance: value };
5562
3873
  case 105:
5563
3874
  return {
5564
3875
  illuminance_calibration: value,
@@ -5596,7 +3907,7 @@ const fromZigbee1 = {
5596
3907
  const brightnesStateLookup = { '0': 'low', '1': 'middle', '2': 'high' };
5597
3908
  switch (dp) {
5598
3909
  case 2:
5599
- return { illuminance_lux: value };
3910
+ return { illuminance: value };
5600
3911
  case 4:
5601
3912
  return { battery: value };
5602
3913
  case 1:
@@ -5607,63 +3918,8 @@ const fromZigbee1 = {
5607
3918
  },
5608
3919
  },
5609
3920
  };
5610
- const fromZigbee2 = {
5611
- tuya_thermostat_weekly_schedule_1: {
5612
- cluster: 'manuSpecificTuya',
5613
- type: ['commandDataResponse', 'commandDataReport'],
5614
- options: [exposes.options.legacy()],
5615
- convert: (model, msg, publish, options, meta) => {
5616
- if (!utils.isLegacyEnabled(options)) {
5617
- return fromZigbee1.tuya_thermostat_weekly_schedule_2.convert(model, msg, publish, options, meta);
5618
- }
5619
- const dpValue = firstDpValue(msg, meta, 'tuya_thermostat_weekly_schedule');
5620
- const dp = dpValue.dp;
5621
- const value = tuyaGetDataValue(dpValue.datatype, dpValue.data);
5622
- const thermostatMeta = getMetaValue(msg.endpoint, model, 'thermostat');
5623
- const firstDayDpId = thermostatMeta.weeklyScheduleFirstDayDpId;
5624
- const maxTransitions = thermostatMeta.weeklyScheduleMaxTransitions;
5625
- let dataOffset = 0;
5626
- let conversion = 'generic';
5627
- function dataToTransitions(data, maxTransitions, offset) {
5628
- // Later it is possible to move converter to meta or to other place outside if other type of converter
5629
- // will be needed for other device. Currently this converter is based on ETOP HT-08 thermostat.
5630
- // see also toZigbee.tuya_thermostat_weekly_schedule()
5631
- function dataToTransition(data, index) {
5632
- return {
5633
- transitionTime: (data[index + 0] << 8) + data[index + 1],
5634
- heatSetpoint: (parseFloat((data[index + 2] << 8) + data[index + 3]) / 10.0).toFixed(1),
5635
- };
5636
- }
5637
- const result = [];
5638
- for (let i = 0; i < maxTransitions; i++) {
5639
- result.push(dataToTransition(data, i * 4 + offset));
5640
- }
5641
- return result;
5642
- }
5643
- if (thermostatMeta.weeklyScheduleConversion !== undefined) {
5644
- conversion = thermostatMeta.weeklyScheduleConversion;
5645
- }
5646
- if (conversion == 'saswell') {
5647
- // Saswell has scheduling mode in the first byte
5648
- dataOffset = 1;
5649
- }
5650
- if (dp >= firstDayDpId && dp < firstDayDpId + 7) {
5651
- const dayOfWeek = dp - firstDayDpId + 1;
5652
- return {
5653
- // Same as in hvacThermostat:getWeeklyScheduleRsp hvacThermostat:setWeeklySchedule cluster format
5654
- weekly_schedule: {
5655
- [dayOfWeek]: {
5656
- dayofweek: dayOfWeek,
5657
- numoftrans: maxTransitions,
5658
- mode: 1, // bits: 0-heat present, 1-cool present (dec: 1-heat,2-cool,3-heat+cool)
5659
- transitions: dataToTransitions(value, maxTransitions, dataOffset),
5660
- },
5661
- },
5662
- };
5663
- }
5664
- },
5665
- },
5666
- };
3921
+ exports.fz = fromZigbee;
3922
+ exports.fromZigbee = fromZigbee;
5667
3923
  const toZigbee1 = {
5668
3924
  SA12IZL_silence_siren: {
5669
3925
  key: ['silence_siren'],
@@ -8331,9 +6587,6 @@ const thermostatSystemModes = {
8331
6587
  9: 'Sleep',
8332
6588
  };
8333
6589
  exports.thermostatSystemModes = thermostatSystemModes;
8334
- const fromZigbee = { ...fromZigbee1, ...fromZigbee2 };
8335
- exports.fz = fromZigbee;
8336
- exports.fromZigbee = fromZigbee;
8337
6590
  const toZigbee = { ...toZigbee1, ...toZigbee2 };
8338
6591
  exports.tz = toZigbee;
8339
6592
  exports.toZigbee = toZigbee;