zigbee-herdsman-converters 24.13.0 → 25.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (242) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +6 -0
  3. package/dist/converters/fromZigbee.d.ts +1 -0
  4. package/dist/converters/fromZigbee.d.ts.map +1 -1
  5. package/dist/converters/fromZigbee.js +19 -7
  6. package/dist/converters/fromZigbee.js.map +1 -1
  7. package/dist/converters/toZigbee.js +2 -2
  8. package/dist/converters/toZigbee.js.map +1 -1
  9. package/dist/devices/adeo.d.ts.map +1 -1
  10. package/dist/devices/adeo.js +1 -7
  11. package/dist/devices/adeo.js.map +1 -1
  12. package/dist/devices/adurosmart.d.ts.map +1 -1
  13. package/dist/devices/adurosmart.js +7 -0
  14. package/dist/devices/adurosmart.js.map +1 -1
  15. package/dist/devices/amina.d.ts.map +1 -1
  16. package/dist/devices/amina.js +22 -12
  17. package/dist/devices/amina.js.map +1 -1
  18. package/dist/devices/aurora_lighting.js +3 -3
  19. package/dist/devices/aurora_lighting.js.map +1 -1
  20. package/dist/devices/avatto.d.ts.map +1 -1
  21. package/dist/devices/avatto.js +2 -12
  22. package/dist/devices/avatto.js.map +1 -1
  23. package/dist/devices/busch_jaeger.d.ts.map +1 -1
  24. package/dist/devices/busch_jaeger.js +20 -20
  25. package/dist/devices/busch_jaeger.js.map +1 -1
  26. package/dist/devices/centralite.d.ts.map +1 -1
  27. package/dist/devices/centralite.js +1 -15
  28. package/dist/devices/centralite.js.map +1 -1
  29. package/dist/devices/danfoss.d.ts.map +1 -1
  30. package/dist/devices/danfoss.js +14 -21
  31. package/dist/devices/danfoss.js.map +1 -1
  32. package/dist/devices/datek.d.ts.map +1 -1
  33. package/dist/devices/datek.js +10 -11
  34. package/dist/devices/datek.js.map +1 -1
  35. package/dist/devices/develco.d.ts.map +1 -1
  36. package/dist/devices/develco.js +13 -23
  37. package/dist/devices/develco.js.map +1 -1
  38. package/dist/devices/engo.d.ts.map +1 -1
  39. package/dist/devices/engo.js +2 -8
  40. package/dist/devices/engo.js.map +1 -1
  41. package/dist/devices/evanell.d.ts.map +1 -1
  42. package/dist/devices/evanell.js +1 -6
  43. package/dist/devices/evanell.js.map +1 -1
  44. package/dist/devices/ewelink.js +3 -3
  45. package/dist/devices/ewelink.js.map +1 -1
  46. package/dist/devices/fantem.d.ts.map +1 -1
  47. package/dist/devices/fantem.js +1 -7
  48. package/dist/devices/fantem.js.map +1 -1
  49. package/dist/devices/feibit.d.ts.map +1 -1
  50. package/dist/devices/feibit.js +1 -6
  51. package/dist/devices/feibit.js.map +1 -1
  52. package/dist/devices/futurehome.d.ts +1 -1
  53. package/dist/devices/futurehome.d.ts.map +1 -1
  54. package/dist/devices/futurehome.js +1 -4
  55. package/dist/devices/futurehome.js.map +1 -1
  56. package/dist/devices/giex.js +1 -1
  57. package/dist/devices/giex.js.map +1 -1
  58. package/dist/devices/gledopto.d.ts.map +1 -1
  59. package/dist/devices/gledopto.js +9 -17
  60. package/dist/devices/gledopto.js.map +1 -1
  61. package/dist/devices/gmmts.d.ts.map +1 -1
  62. package/dist/devices/gmmts.js +45 -74
  63. package/dist/devices/gmmts.js.map +1 -1
  64. package/dist/devices/heiman.d.ts.map +1 -1
  65. package/dist/devices/heiman.js +2 -9
  66. package/dist/devices/heiman.js.map +1 -1
  67. package/dist/devices/hive.d.ts.map +1 -1
  68. package/dist/devices/hive.js +9 -29
  69. package/dist/devices/hive.js.map +1 -1
  70. package/dist/devices/immax.js +1 -1
  71. package/dist/devices/immax.js.map +1 -1
  72. package/dist/devices/inovelli.d.ts.map +1 -1
  73. package/dist/devices/inovelli.js +2 -1
  74. package/dist/devices/inovelli.js.map +1 -1
  75. package/dist/devices/legrand.d.ts.map +1 -1
  76. package/dist/devices/legrand.js +10 -22
  77. package/dist/devices/legrand.js.map +1 -1
  78. package/dist/devices/lellki.d.ts.map +1 -1
  79. package/dist/devices/lellki.js +9 -8
  80. package/dist/devices/lellki.js.map +1 -1
  81. package/dist/devices/lidl.d.ts.map +1 -1
  82. package/dist/devices/lidl.js +14 -15
  83. package/dist/devices/lidl.js.map +1 -1
  84. package/dist/devices/lifecontrol.d.ts.map +1 -1
  85. package/dist/devices/lifecontrol.js +9 -21
  86. package/dist/devices/lifecontrol.js.map +1 -1
  87. package/dist/devices/lincukoo.d.ts.map +1 -1
  88. package/dist/devices/lincukoo.js +6 -24
  89. package/dist/devices/lincukoo.js.map +1 -1
  90. package/dist/devices/linkind.d.ts.map +1 -1
  91. package/dist/devices/linkind.js +2 -22
  92. package/dist/devices/linkind.js.map +1 -1
  93. package/dist/devices/linptech.js +5 -5
  94. package/dist/devices/linptech.js.map +1 -1
  95. package/dist/devices/livolo.d.ts.map +1 -1
  96. package/dist/devices/livolo.js +94 -249
  97. package/dist/devices/livolo.js.map +1 -1
  98. package/dist/devices/lixee.d.ts.map +1 -1
  99. package/dist/devices/lixee.js +38 -51
  100. package/dist/devices/lixee.js.map +1 -1
  101. package/dist/devices/lumi.d.ts.map +1 -1
  102. package/dist/devices/lumi.js +21 -62
  103. package/dist/devices/lumi.js.map +1 -1
  104. package/dist/devices/mazda.d.ts.map +1 -1
  105. package/dist/devices/mazda.js +1 -4
  106. package/dist/devices/mazda.js.map +1 -1
  107. package/dist/devices/mindy.d.ts.map +1 -1
  108. package/dist/devices/mindy.js +13 -18
  109. package/dist/devices/mindy.js.map +1 -1
  110. package/dist/devices/moes.d.ts.map +1 -1
  111. package/dist/devices/moes.js +24 -60
  112. package/dist/devices/moes.js.map +1 -1
  113. package/dist/devices/namron.d.ts.map +1 -1
  114. package/dist/devices/namron.js +17 -59
  115. package/dist/devices/namron.js.map +1 -1
  116. package/dist/devices/neo.d.ts.map +1 -1
  117. package/dist/devices/neo.js +7 -34
  118. package/dist/devices/neo.js.map +1 -1
  119. package/dist/devices/nous.d.ts.map +1 -1
  120. package/dist/devices/nous.js +2 -6
  121. package/dist/devices/nous.js.map +1 -1
  122. package/dist/devices/onesti.d.ts +1 -1
  123. package/dist/devices/onesti.d.ts.map +1 -1
  124. package/dist/devices/onesti.js.map +1 -1
  125. package/dist/devices/orvibo.d.ts.map +1 -1
  126. package/dist/devices/orvibo.js +5 -4
  127. package/dist/devices/orvibo.js.map +1 -1
  128. package/dist/devices/orztech.d.ts.map +1 -1
  129. package/dist/devices/orztech.js +5 -20
  130. package/dist/devices/orztech.js.map +1 -1
  131. package/dist/devices/osram.d.ts.map +1 -1
  132. package/dist/devices/osram.js +6 -4
  133. package/dist/devices/osram.js.map +1 -1
  134. package/dist/devices/philips.d.ts.map +1 -1
  135. package/dist/devices/philips.js +7 -0
  136. package/dist/devices/philips.js.map +1 -1
  137. package/dist/devices/profalux.d.ts.map +1 -1
  138. package/dist/devices/profalux.js +20 -16
  139. package/dist/devices/profalux.js.map +1 -1
  140. package/dist/devices/rtx.js +1 -1
  141. package/dist/devices/rtx.js.map +1 -1
  142. package/dist/devices/saswell.d.ts.map +1 -1
  143. package/dist/devices/saswell.js +1 -6
  144. package/dist/devices/saswell.js.map +1 -1
  145. package/dist/devices/schneider_electric.d.ts.map +1 -1
  146. package/dist/devices/schneider_electric.js +15 -12
  147. package/dist/devices/schneider_electric.js.map +1 -1
  148. package/dist/devices/senoro.d.ts.map +1 -1
  149. package/dist/devices/senoro.js +1 -4
  150. package/dist/devices/senoro.js.map +1 -1
  151. package/dist/devices/shinasystem.d.ts.map +1 -1
  152. package/dist/devices/shinasystem.js +83 -21
  153. package/dist/devices/shinasystem.js.map +1 -1
  154. package/dist/devices/sinope.d.ts.map +1 -1
  155. package/dist/devices/sinope.js +14 -4
  156. package/dist/devices/sinope.js.map +1 -1
  157. package/dist/devices/smart9.d.ts.map +1 -1
  158. package/dist/devices/smart9.js +2 -7
  159. package/dist/devices/smart9.js.map +1 -1
  160. package/dist/devices/sonoff.d.ts.map +1 -1
  161. package/dist/devices/sonoff.js +1 -0
  162. package/dist/devices/sonoff.js.map +1 -1
  163. package/dist/devices/sunricher.d.ts.map +1 -1
  164. package/dist/devices/sunricher.js +4 -27
  165. package/dist/devices/sunricher.js.map +1 -1
  166. package/dist/devices/tech.d.ts.map +1 -1
  167. package/dist/devices/tech.js +2 -8
  168. package/dist/devices/tech.js.map +1 -1
  169. package/dist/devices/technicolor.d.ts.map +1 -1
  170. package/dist/devices/technicolor.js +2 -15
  171. package/dist/devices/technicolor.js.map +1 -1
  172. package/dist/devices/tuya.d.ts.map +1 -1
  173. package/dist/devices/tuya.js +193 -409
  174. package/dist/devices/tuya.js.map +1 -1
  175. package/dist/devices/ubisys.d.ts.map +1 -1
  176. package/dist/devices/ubisys.js +31 -52
  177. package/dist/devices/ubisys.js.map +1 -1
  178. package/dist/devices/universal_electronics_inc.d.ts.map +1 -1
  179. package/dist/devices/universal_electronics_inc.js +3 -29
  180. package/dist/devices/universal_electronics_inc.js.map +1 -1
  181. package/dist/devices/vesternet.d.ts.map +1 -1
  182. package/dist/devices/vesternet.js +4 -1
  183. package/dist/devices/vesternet.js.map +1 -1
  184. package/dist/devices/weiser.d.ts.map +1 -1
  185. package/dist/devices/weiser.js +3 -48
  186. package/dist/devices/weiser.js.map +1 -1
  187. package/dist/devices/woox.d.ts.map +1 -1
  188. package/dist/devices/woox.js +2 -3
  189. package/dist/devices/woox.js.map +1 -1
  190. package/dist/devices/yale.d.ts +1 -1
  191. package/dist/devices/yale.d.ts.map +1 -1
  192. package/dist/devices/yale.js.map +1 -1
  193. package/dist/devices/yandex.d.ts.map +1 -1
  194. package/dist/devices/yandex.js +4 -4
  195. package/dist/devices/yandex.js.map +1 -1
  196. package/dist/devices/zemismart.d.ts.map +1 -1
  197. package/dist/devices/zemismart.js +8 -23
  198. package/dist/devices/zemismart.js.map +1 -1
  199. package/dist/index.d.ts +4 -4
  200. package/dist/index.d.ts.map +1 -1
  201. package/dist/index.js +14 -7
  202. package/dist/index.js.map +1 -1
  203. package/dist/lib/develco.d.ts.map +1 -1
  204. package/dist/lib/develco.js +0 -2
  205. package/dist/lib/develco.js.map +1 -1
  206. package/dist/lib/ikea.d.ts.map +1 -1
  207. package/dist/lib/ikea.js +3 -2
  208. package/dist/lib/ikea.js.map +1 -1
  209. package/dist/lib/ledvance.js +1 -1
  210. package/dist/lib/ledvance.js.map +1 -1
  211. package/dist/lib/legrand.d.ts +6 -1
  212. package/dist/lib/legrand.d.ts.map +1 -1
  213. package/dist/lib/legrand.js +14 -3
  214. package/dist/lib/legrand.js.map +1 -1
  215. package/dist/lib/lumi.d.ts +1 -0
  216. package/dist/lib/lumi.d.ts.map +1 -1
  217. package/dist/lib/lumi.js +72 -18
  218. package/dist/lib/lumi.js.map +1 -1
  219. package/dist/lib/modernExtend.d.ts +14 -1
  220. package/dist/lib/modernExtend.d.ts.map +1 -1
  221. package/dist/lib/modernExtend.js +108 -14
  222. package/dist/lib/modernExtend.js.map +1 -1
  223. package/dist/lib/store.d.ts +4 -4
  224. package/dist/lib/store.d.ts.map +1 -1
  225. package/dist/lib/store.js +3 -0
  226. package/dist/lib/store.js.map +1 -1
  227. package/dist/lib/tuya.d.ts +18 -18
  228. package/dist/lib/tuya.d.ts.map +1 -1
  229. package/dist/lib/tuya.js +142 -155
  230. package/dist/lib/tuya.js.map +1 -1
  231. package/dist/lib/types.d.ts +31 -15
  232. package/dist/lib/types.d.ts.map +1 -1
  233. package/dist/lib/ubisys.d.ts +2 -1
  234. package/dist/lib/ubisys.d.ts.map +1 -1
  235. package/dist/lib/ubisys.js +46 -0
  236. package/dist/lib/ubisys.js.map +1 -1
  237. package/dist/lib/utils.d.ts +1 -2
  238. package/dist/lib/utils.d.ts.map +1 -1
  239. package/dist/lib/utils.js +0 -30
  240. package/dist/lib/utils.js.map +1 -1
  241. package/dist/models-index.json +1 -1
  242. package/package.json +3 -3
package/dist/lib/tuya.js CHANGED
@@ -33,13 +33,9 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.clusters = exports.modernExtend = exports.fz = exports.tz = exports.valueConverter = exports.valueConverterBasic = exports.Bitmap = exports.enum = exports.Enum = exports.whitelabel = exports.fingerprint = exports.configureMagicPacket = exports.skip = exports.exposes = exports.dataTypes = void 0;
36
+ exports.clusters = exports.modernExtend = exports.fz = exports.tz = exports.valueConverter = exports.valueConverterBasic = exports.Bitmap = exports.enum = exports.Enum = exports.whitelabel = exports.fingerprint = exports.configureBindBasic = exports.configureMcuVersionRequest = exports.configureQuery = exports.configureMagicPacket = exports.skip = exports.exposes = exports.dataTypes = void 0;
37
37
  exports.convertBufferToNumber = convertBufferToNumber;
38
- exports.onEvent = onEvent;
39
38
  exports.convertDecimalValueTo4ByteHexArray = convertDecimalValueTo4ByteHexArray;
40
- exports.onEventMeasurementPoll = onEventMeasurementPoll;
41
- exports.onEventSetTime = onEventSetTime;
42
- exports.onEventSetLocalTime = onEventSetLocalTime;
43
39
  exports.dpValueFromString = dpValueFromString;
44
40
  exports.sendDataPointValue = sendDataPointValue;
45
41
  exports.sendDataPointBool = sendDataPointBool;
@@ -85,66 +81,6 @@ function convertStringToHexArray(value) {
85
81
  }
86
82
  return asciiKeys;
87
83
  }
88
- function onEvent(args) {
89
- return async (type, data, device, settings, state) => {
90
- // biome-ignore lint/style/noParameterAssign: ignored using `--suppress`
91
- args = { queryOnDeviceAnnounce: false, timeStart: "1970", respondToMcuVersionResponse: true, ...args };
92
- const endpoint = device.endpoints[0];
93
- if (type === "message" && data.cluster === "manuSpecificTuya") {
94
- if (args.respondToMcuVersionResponse && data.type === "commandMcuVersionResponse") {
95
- await endpoint.command("manuSpecificTuya", "mcuVersionRequest", { seq: 0x0002 });
96
- }
97
- else if (data.type === "commandMcuGatewayConnectionStatus") {
98
- // "payload" can have the following values:
99
- // 0x00: The gateway is not connected to the internet.
100
- // 0x01: The gateway is connected to the internet.
101
- // 0x02: The request timed out after three seconds.
102
- const payload = { payloadSize: 1, payload: 1 };
103
- await endpoint.command("manuSpecificTuya", "mcuGatewayConnectionStatus", payload, {});
104
- }
105
- }
106
- if (data.type === "commandMcuSyncTime" && data.cluster === "manuSpecificTuya") {
107
- try {
108
- const offset = args.timeStart === "2000" ? constants.OneJanuary2000 : 0;
109
- const utcTime = Math.round((Date.now() - offset) / 1000);
110
- const localTime = utcTime - new Date().getTimezoneOffset() * 60;
111
- const payload = {
112
- payloadSize: 8,
113
- payload: [...convertDecimalValueTo4ByteHexArray(utcTime), ...convertDecimalValueTo4ByteHexArray(localTime)],
114
- };
115
- await endpoint.command("manuSpecificTuya", "mcuSyncTime", payload, {});
116
- }
117
- catch {
118
- /* handle error to prevent crash */
119
- }
120
- }
121
- // Some devices require a dataQuery on deviceAnnounce, otherwise they don't report any data
122
- if (args.queryOnDeviceAnnounce && type === "deviceAnnounce") {
123
- await endpoint.command("manuSpecificTuya", "dataQuery", {});
124
- }
125
- if (args.queryIntervalSeconds) {
126
- if (type === "stop") {
127
- clearTimeout(globalStore.getValue(device, "query_interval"));
128
- globalStore.clearValue(device, "query_interval");
129
- }
130
- else if (!globalStore.hasValue(device, "query_interval")) {
131
- const setTimer = () => {
132
- const timer = setTimeout(async () => {
133
- try {
134
- await endpoint.command("manuSpecificTuya", "dataQuery", {});
135
- }
136
- catch (error) {
137
- logger_1.logger.error(`Failed to query data of '${device.ieeeAddr}' (${error})`, NS);
138
- }
139
- setTimer();
140
- }, args.queryIntervalSeconds * 1000);
141
- globalStore.putValue(device, "query_interval", timer);
142
- };
143
- setTimer();
144
- }
145
- }
146
- };
147
- }
148
84
  function getDataValue(dpValue) {
149
85
  let dataString = "";
150
86
  switch (dpValue.datatype) {
@@ -180,67 +116,6 @@ function convertDecimalValueTo2ByteHexArray(value) {
180
116
  const chunk2 = hexValue.substring(2);
181
117
  return [chunk1, chunk2].map((hexVal) => Number.parseInt(hexVal, 16));
182
118
  }
183
- function onEventMeasurementPoll(type, data, device, options, electricalMeasurement = true, metering = false) {
184
- const endpoint = device.getEndpoint(1);
185
- const poll = async () => {
186
- if (electricalMeasurement) {
187
- await endpoint.read("haElectricalMeasurement", ["rmsVoltage", "rmsCurrent", "activePower"]);
188
- }
189
- if (metering) {
190
- await endpoint.read("seMetering", ["currentSummDelivered"]);
191
- }
192
- };
193
- utils.onEventPoll(type, data, device, options, "measurement", 60, poll);
194
- }
195
- async function onEventSetTime(type, data, device) {
196
- // FIXME: Need to join onEventSetTime/onEventSetLocalTime to one command
197
- if (data.type === "commandMcuSyncTime" && data.cluster === "manuSpecificTuya") {
198
- try {
199
- const utcTime = Math.round((Date.now() - constants.OneJanuary2000) / 1000);
200
- const localTime = utcTime - new Date().getTimezoneOffset() * 60;
201
- const endpoint = device.getEndpoint(1);
202
- const payload = {
203
- payloadSize: 8,
204
- payload: [...convertDecimalValueTo4ByteHexArray(utcTime), ...convertDecimalValueTo4ByteHexArray(localTime)],
205
- };
206
- await endpoint.command("manuSpecificTuya", "mcuSyncTime", payload, {});
207
- }
208
- catch {
209
- // endpoint.command can throw an error which needs to
210
- // be caught or the zigbee-herdsman may crash
211
- // Debug message is handled in the zigbee-herdsman
212
- }
213
- }
214
- }
215
- // set UTC and Local Time as total number of seconds from 00: 00: 00 on January 01, 1970
216
- // force to update every device time every hour due to very poor clock
217
- async function onEventSetLocalTime(type, data, device) {
218
- // FIXME: What actually nextLocalTimeUpdate/forceTimeUpdate do?
219
- // I did not find any timers or something else where it was used.
220
- // Actually, there are two ways to set time on Tuya MCU devices:
221
- // 1. Respond to the `commandMcuSyncTime` event
222
- // 2. Just send `mcuSyncTime` anytime (by 1-hour timer or something else)
223
- const nextLocalTimeUpdate = globalStore.getValue(device, "nextLocalTimeUpdate");
224
- const forceTimeUpdate = nextLocalTimeUpdate == null || nextLocalTimeUpdate < Date.now();
225
- if ((data.type === "commandMcuSyncTime" && data.cluster === "manuSpecificTuya") || forceTimeUpdate) {
226
- globalStore.putValue(device, "nextLocalTimeUpdate", Date.now() + 3600 * 1000);
227
- try {
228
- const utcTime = Math.round(Date.now() / 1000);
229
- const localTime = utcTime - new Date().getTimezoneOffset() * 60;
230
- const endpoint = device.getEndpoint(1);
231
- const payload = {
232
- payloadSize: 8,
233
- payload: [...convertDecimalValueTo4ByteHexArray(utcTime), ...convertDecimalValueTo4ByteHexArray(localTime)],
234
- };
235
- await endpoint.command("manuSpecificTuya", "mcuSyncTime", payload, {});
236
- }
237
- catch {
238
- // endpoint.command can throw an error which needs to
239
- // be caught or the zigbee-herdsman may crash
240
- // Debug message is handled in the zigbee-herdsman
241
- }
242
- }
243
- }
244
119
  // Return `seq` - transaction ID for handling concrete response
245
120
  async function sendDataPoints(entity, dpValues, cmd = "dataRequest", seq) {
246
121
  if (seq === undefined) {
@@ -451,6 +326,19 @@ const configureMagicPacket = async (device, coordinatorEndpoint) => {
451
326
  }
452
327
  };
453
328
  exports.configureMagicPacket = configureMagicPacket;
329
+ const configureQuery = async (device, coordinatorEndpoint) => {
330
+ // Required to get the device to start reporting
331
+ await device.getEndpoint(1).command("manuSpecificTuya", "dataQuery", {});
332
+ };
333
+ exports.configureQuery = configureQuery;
334
+ const configureMcuVersionRequest = async (device, coordinatorEndpoint) => {
335
+ await device.getEndpoint(1).command("manuSpecificTuya", "mcuVersionRequest", { seq: 0x0002 });
336
+ };
337
+ exports.configureMcuVersionRequest = configureMcuVersionRequest;
338
+ const configureBindBasic = async (device, coordinatorEndpoint) => {
339
+ await device.getEndpoint(1).bind("genBasic", coordinatorEndpoint);
340
+ };
341
+ exports.configureBindBasic = configureBindBasic;
454
342
  const fingerprint = (modelID, manufacturerNames) => {
455
343
  return manufacturerNames.map((manufacturerName) => {
456
344
  return { modelID, manufacturerName };
@@ -1457,33 +1345,33 @@ const tuyaTz = {
1457
1345
  key: ["power_on_behavior"],
1458
1346
  convertSet: async (entity, key, value, meta) => {
1459
1347
  const powerOnBehavior = utils.getFromLookup(value, { off: 0, on: 1, previous: 2 });
1460
- await entity.write("manuSpecificTuya_3", { powerOnBehavior });
1348
+ await entity.write("manuSpecificTuya3", { powerOnBehavior });
1461
1349
  return { state: { [key]: value } };
1462
1350
  },
1463
1351
  convertGet: async (entity, key, meta) => {
1464
- await entity.read("manuSpecificTuya_3", ["powerOnBehavior"]);
1352
+ await entity.read("manuSpecificTuya3", ["powerOnBehavior"]);
1465
1353
  },
1466
1354
  },
1467
1355
  switch_type: {
1468
1356
  key: ["switch_type"],
1469
1357
  convertSet: async (entity, key, value, meta) => {
1470
1358
  const switchType = utils.getFromLookup(value, { toggle: 0, state: 1, momentary: 2 });
1471
- await entity.write("manuSpecificTuya_3", { switchType }, { disableDefaultResponse: true });
1359
+ await entity.write("manuSpecificTuya3", { switchType }, { disableDefaultResponse: true });
1472
1360
  return { state: { [key]: value } };
1473
1361
  },
1474
1362
  convertGet: async (entity, key, meta) => {
1475
- await entity.read("manuSpecificTuya_3", ["switchType"]);
1363
+ await entity.read("manuSpecificTuya3", ["switchType"]);
1476
1364
  },
1477
1365
  },
1478
1366
  switch_type_curtain: {
1479
1367
  key: ["switch_type_curtain"],
1480
1368
  convertSet: async (entity, key, value, meta) => {
1481
1369
  const switchType = utils.getFromLookup(value, { "flip-switch": 0, "sync-switch": 1, "button-switch": 2, "button2-switch": 3 });
1482
- await entity.write("manuSpecificTuya_3", { switchType }, { disableDefaultResponse: true });
1370
+ await entity.write("manuSpecificTuya3", { switchType }, { disableDefaultResponse: true });
1483
1371
  return { state: { [key]: value } };
1484
1372
  },
1485
1373
  convertGet: async (entity, key, meta) => {
1486
- await entity.read("manuSpecificTuya_3", ["switchType"]);
1374
+ await entity.read("manuSpecificTuya3", ["switchType"]);
1487
1375
  },
1488
1376
  },
1489
1377
  backlight_indicator_mode_1: {
@@ -1687,7 +1575,7 @@ const tuyaTz = {
1687
1575
  const inching = exports.valueConverter.inchingSwitch.to(value);
1688
1576
  const payload = { payload: inching };
1689
1577
  const endpoint = meta.device.getEndpoint(1);
1690
- await endpoint.command("manuSpecificTuya_4", "setInchingSwitch", payload, utils.getOptions(meta.mapped, endpoint));
1578
+ await endpoint.command("manuSpecificTuya4", "setInchingSwitch", payload, utils.getOptions(meta.mapped, endpoint));
1691
1579
  return { state: { inching_control_set: value } };
1692
1580
  },
1693
1581
  },
@@ -1704,18 +1592,6 @@ const tuyaFz = {
1704
1592
  }
1705
1593
  },
1706
1594
  },
1707
- gateway_connection_status: {
1708
- cluster: "manuSpecificTuya",
1709
- type: ["commandMcuGatewayConnectionStatus"],
1710
- convert: async (model, msg, publish, options, meta) => {
1711
- // "payload" can have the following values:
1712
- // 0x00: The gateway is not connected to the internet.
1713
- // 0x01: The gateway is connected to the internet.
1714
- // 0x02: The request timed out after three seconds.
1715
- const payload = { payloadSize: 1, payload: 1 };
1716
- await msg.endpoint.command("manuSpecificTuya", "mcuGatewayConnectionStatus", payload, {});
1717
- },
1718
- },
1719
1595
  power_on_behavior_1: {
1720
1596
  cluster: "genOnOff",
1721
1597
  type: ["attributeReport", "readResponse"],
@@ -1728,7 +1604,7 @@ const tuyaFz = {
1728
1604
  },
1729
1605
  },
1730
1606
  power_on_behavior_2: {
1731
- cluster: "manuSpecificTuya_3",
1607
+ cluster: "manuSpecificTuya3",
1732
1608
  type: ["attributeReport", "readResponse"],
1733
1609
  convert: (model, msg, publish, options, meta) => {
1734
1610
  const attribute = "powerOnBehavior";
@@ -1751,7 +1627,7 @@ const tuyaFz = {
1751
1627
  },
1752
1628
  },
1753
1629
  switch_type: {
1754
- cluster: "manuSpecificTuya_3",
1630
+ cluster: "manuSpecificTuya3",
1755
1631
  type: ["attributeReport", "readResponse"],
1756
1632
  convert: (model, msg, publish, options, meta) => {
1757
1633
  if (msg.data.switchType !== undefined) {
@@ -1762,7 +1638,7 @@ const tuyaFz = {
1762
1638
  },
1763
1639
  },
1764
1640
  switch_type_curtain: {
1765
- cluster: "manuSpecificTuya_3",
1641
+ cluster: "manuSpecificTuya3",
1766
1642
  type: ["attributeReport", "readResponse"],
1767
1643
  convert: (model, msg, publish, options, meta) => {
1768
1644
  if (msg.data.switchType !== undefined) {
@@ -1899,7 +1775,7 @@ const tuyaFz = {
1899
1775
  },
1900
1776
  },
1901
1777
  inchingSwitch: {
1902
- cluster: "manuSpecificTuya_4",
1778
+ cluster: "manuSpecificTuya4",
1903
1779
  type: ["attributeReport", "readResponse"],
1904
1780
  convert: (model, msg, publish, options, meta) => {
1905
1781
  if (msg.data.inching !== undefined) {
@@ -1983,6 +1859,27 @@ function getHandlersForDP(name, dp, type, converter, readOnly, skip, endpoint, u
1983
1859
  return [fromZigbee, toZigbee];
1984
1860
  }
1985
1861
  const tuyaModernExtend = {
1862
+ electricityMeasurementPoll(args = {}) {
1863
+ const { electricalMeasurement = true, metering = false, optionDescription = undefined } = args;
1864
+ let option = exposes.options.measurement_poll_interval();
1865
+ if (optionDescription !== undefined) {
1866
+ option = option.withDescription(optionDescription);
1867
+ }
1868
+ return modernExtend.poll({
1869
+ key: "measurement",
1870
+ option,
1871
+ defaultIntervalSeconds: 60,
1872
+ poll: async (device) => {
1873
+ const endpoint = device.getEndpoint(1);
1874
+ if (typeof electricalMeasurement === "boolean" ? electricalMeasurement : electricalMeasurement(device)) {
1875
+ await endpoint.read("haElectricalMeasurement", ["rmsVoltage", "rmsCurrent", "activePower"]);
1876
+ }
1877
+ if (typeof metering === "boolean" ? metering : metering(device)) {
1878
+ await endpoint.read("seMetering", ["currentSummDelivered"]);
1879
+ }
1880
+ },
1881
+ });
1882
+ },
1986
1883
  dpTHZBSettings() {
1987
1884
  const exp = e
1988
1885
  .composite("auto_settings", "auto_settings", ea.STATE_SET)
@@ -2038,14 +1935,104 @@ const tuyaModernExtend = {
2038
1935
  };
2039
1936
  },
2040
1937
  tuyaBase(args) {
1938
+ const { dp = false, queryOnDeviceAnnounce = false, queryOnConfigure = false, bindBasicOnConfigure = false, queryIntervalSeconds = undefined, mcuVersionRequestOnConfigure = false,
1939
+ // Allow force updating for device with a very bad clock
1940
+ // Every hour when a message is received the time will be updated.
1941
+ forceTimeUpdates = false, timeStart = "1970", respondToMcuVersionResponse = true, } = args;
1942
+ const fzConverter = {
1943
+ type: [
1944
+ "commandMcuSyncTime",
1945
+ "commandMcuVersionResponse",
1946
+ "commandMcuGatewayConnectionStatus",
1947
+ "commandDataResponse",
1948
+ "commandDataReport",
1949
+ "commandActiveStatusReport",
1950
+ "commandActiveStatusReportAlt",
1951
+ ],
1952
+ cluster: "manuSpecificTuya",
1953
+ convert: (model, msg, publish, options, meta) => {
1954
+ let forceTimeUpdate = false;
1955
+ if (forceTimeUpdates) {
1956
+ const nextLocalTimeUpdate = globalStore.getValue(msg.device, "nextLocalTimeUpdate");
1957
+ forceTimeUpdate = nextLocalTimeUpdate == null || nextLocalTimeUpdate < Date.now();
1958
+ }
1959
+ if (msg.type === "commandMcuSyncTime" || forceTimeUpdate) {
1960
+ globalStore.putValue(msg.device, "nextLocalTimeUpdate", Date.now() + 3600 * 1000);
1961
+ const offset = timeStart === "2000" ? constants.OneJanuary2000 : 0;
1962
+ const utcTime = Math.round((Date.now() - offset) / 1000);
1963
+ const localTime = utcTime - new Date().getTimezoneOffset() * 60;
1964
+ const payload = {
1965
+ payloadSize: 8,
1966
+ payload: [...convertDecimalValueTo4ByteHexArray(utcTime), ...convertDecimalValueTo4ByteHexArray(localTime)],
1967
+ };
1968
+ msg.endpoint
1969
+ .command("manuSpecificTuya", "mcuSyncTime", payload, {})
1970
+ .catch((error) => logger_1.logger.error(`Failed to sync time with '${msg.device.ieeeAddr}' (${error})`, NS));
1971
+ }
1972
+ else if (respondToMcuVersionResponse && msg.type === "commandMcuVersionResponse") {
1973
+ msg.endpoint
1974
+ .command("manuSpecificTuya", "mcuVersionRequest", { seq: 0x0002 })
1975
+ .catch((error) => logger_1.logger.error(`Failed respond to version response '${msg.device.ieeeAddr}' (${error})`, NS));
1976
+ }
1977
+ else if (msg.type === "commandMcuGatewayConnectionStatus") {
1978
+ // "payload" can have the following values:
1979
+ // 0x00: The gateway is not connected to the internet.
1980
+ // 0x01: The gateway is connected to the internet.
1981
+ // 0x02: The request timed out after three seconds.
1982
+ msg.endpoint
1983
+ .command("manuSpecificTuya", "mcuGatewayConnectionStatus", { payloadSize: 1, payload: 1 }, {})
1984
+ .catch((error) => logger_1.logger.error(`Failed respond to gateway connection status '${msg.device.ieeeAddr}' (${error})`, NS));
1985
+ }
1986
+ },
1987
+ };
2041
1988
  const result = {
2042
1989
  configure: [exports.configureMagicPacket],
2043
- onEvent: [onEvent(args.onEvent)],
2044
1990
  isModernExtend: true,
1991
+ fromZigbee: [fzConverter],
1992
+ toZigbee: [],
2045
1993
  };
2046
- if (args?.dp) {
2047
- result.fromZigbee = [tuyaFz.datapoints];
2048
- result.toZigbee = [tuyaTz.datapoints];
1994
+ if (queryOnConfigure) {
1995
+ result.configure.push(exports.configureQuery);
1996
+ }
1997
+ if (mcuVersionRequestOnConfigure) {
1998
+ result.configure.push(exports.configureMcuVersionRequest);
1999
+ }
2000
+ if (bindBasicOnConfigure) {
2001
+ result.configure.push(exports.configureBindBasic);
2002
+ }
2003
+ if (queryOnDeviceAnnounce || queryIntervalSeconds !== undefined) {
2004
+ result.onEvent = [
2005
+ (event) => {
2006
+ // Some devices require a dataQuery on deviceAnnounce, otherwise they don't report any data
2007
+ if (queryOnDeviceAnnounce && event.type === "deviceAnnounce") {
2008
+ event.data.device.endpoints[0]
2009
+ .command("manuSpecificTuya", "dataQuery", {})
2010
+ .catch((error) => logger_1.logger.error(`Failed to query '${event.data.device.ieeeAddr}' on device announce (${error})`, NS));
2011
+ }
2012
+ if (queryIntervalSeconds !== undefined) {
2013
+ if (event.type === "stop") {
2014
+ clearTimeout(globalStore.getValue(event.data.ieeeAddr, "query_interval"));
2015
+ globalStore.clearValue(event.data.ieeeAddr, "query_interval");
2016
+ }
2017
+ else if (event.type === "start") {
2018
+ const setTimer = () => {
2019
+ const timer = setTimeout(() => {
2020
+ event.data.device.endpoints[0]
2021
+ .command("manuSpecificTuya", "dataQuery", {})
2022
+ .catch((error) => logger_1.logger.error(`Failed to query '${event.data.device.ieeeAddr}' on interval (${error})`, NS));
2023
+ setTimer();
2024
+ }, queryIntervalSeconds * 1000);
2025
+ globalStore.putValue(event.data.device.ieeeAddr, "query_interval", timer);
2026
+ };
2027
+ setTimer();
2028
+ }
2029
+ }
2030
+ },
2031
+ ];
2032
+ }
2033
+ if (dp) {
2034
+ result.fromZigbee.push(tuyaFz.datapoints);
2035
+ result.toZigbee.push(tuyaTz.datapoints);
2049
2036
  }
2050
2037
  return result;
2051
2038
  },
@@ -2458,7 +2445,7 @@ const tuyaModernExtend = {
2458
2445
  tuyaSwitchMode: (args) => modernExtend.enumLookup({
2459
2446
  name: "switch_mode",
2460
2447
  lookup: { switch: 0, scene: 1 },
2461
- cluster: "manuSpecificTuya_3",
2448
+ cluster: "manuSpecificTuya3",
2462
2449
  attribute: "switchMode",
2463
2450
  description: "Work mode for switch",
2464
2451
  entityCategory: "config",
@@ -2501,7 +2488,7 @@ const tuyaModernExtend = {
2501
2488
  };
2502
2489
  exports.modernExtend = tuyaModernExtend;
2503
2490
  const tuyaClusters = {
2504
- addTuyaCommonPrivateCluster: () => modernExtend.deviceAddCustomCluster("manuSpecificTuya_4", {
2491
+ addTuyaCommonPrivateCluster: () => modernExtend.deviceAddCustomCluster("manuSpecificTuya4", {
2505
2492
  ID: 0xe000,
2506
2493
  attributes: {
2507
2494
  random_timing: { ID: 0xd001, type: zigbee_herdsman_1.Zcl.DataType.CHAR_STR },