zigbee-herdsman-converters 24.14.0 → 25.1.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 (231) hide show
  1. package/CHANGELOG.md +53 -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/amina.d.ts.map +1 -1
  13. package/dist/devices/amina.js +22 -12
  14. package/dist/devices/amina.js.map +1 -1
  15. package/dist/devices/aurora_lighting.js +3 -3
  16. package/dist/devices/aurora_lighting.js.map +1 -1
  17. package/dist/devices/avatto.d.ts.map +1 -1
  18. package/dist/devices/avatto.js +2 -12
  19. package/dist/devices/avatto.js.map +1 -1
  20. package/dist/devices/busch_jaeger.d.ts.map +1 -1
  21. package/dist/devices/busch_jaeger.js +20 -20
  22. package/dist/devices/busch_jaeger.js.map +1 -1
  23. package/dist/devices/centralite.d.ts.map +1 -1
  24. package/dist/devices/centralite.js +1 -15
  25. package/dist/devices/centralite.js.map +1 -1
  26. package/dist/devices/danfoss.d.ts.map +1 -1
  27. package/dist/devices/danfoss.js +14 -21
  28. package/dist/devices/danfoss.js.map +1 -1
  29. package/dist/devices/datek.d.ts.map +1 -1
  30. package/dist/devices/datek.js +10 -11
  31. package/dist/devices/datek.js.map +1 -1
  32. package/dist/devices/develco.d.ts.map +1 -1
  33. package/dist/devices/develco.js +53 -25
  34. package/dist/devices/develco.js.map +1 -1
  35. package/dist/devices/engo.d.ts.map +1 -1
  36. package/dist/devices/engo.js +2 -8
  37. package/dist/devices/engo.js.map +1 -1
  38. package/dist/devices/evanell.d.ts.map +1 -1
  39. package/dist/devices/evanell.js +1 -6
  40. package/dist/devices/evanell.js.map +1 -1
  41. package/dist/devices/ewelink.js +3 -3
  42. package/dist/devices/ewelink.js.map +1 -1
  43. package/dist/devices/fantem.d.ts.map +1 -1
  44. package/dist/devices/fantem.js +1 -7
  45. package/dist/devices/fantem.js.map +1 -1
  46. package/dist/devices/feibit.d.ts.map +1 -1
  47. package/dist/devices/feibit.js +1 -6
  48. package/dist/devices/feibit.js.map +1 -1
  49. package/dist/devices/futurehome.d.ts +1 -1
  50. package/dist/devices/futurehome.d.ts.map +1 -1
  51. package/dist/devices/futurehome.js +1 -4
  52. package/dist/devices/futurehome.js.map +1 -1
  53. package/dist/devices/giex.js +1 -1
  54. package/dist/devices/giex.js.map +1 -1
  55. package/dist/devices/gledopto.d.ts.map +1 -1
  56. package/dist/devices/gledopto.js +9 -17
  57. package/dist/devices/gledopto.js.map +1 -1
  58. package/dist/devices/gmmts.d.ts.map +1 -1
  59. package/dist/devices/gmmts.js +45 -74
  60. package/dist/devices/gmmts.js.map +1 -1
  61. package/dist/devices/heiman.d.ts.map +1 -1
  62. package/dist/devices/heiman.js +2 -9
  63. package/dist/devices/heiman.js.map +1 -1
  64. package/dist/devices/hive.d.ts.map +1 -1
  65. package/dist/devices/hive.js +9 -29
  66. package/dist/devices/hive.js.map +1 -1
  67. package/dist/devices/immax.js +1 -1
  68. package/dist/devices/immax.js.map +1 -1
  69. package/dist/devices/legrand.d.ts.map +1 -1
  70. package/dist/devices/legrand.js +10 -22
  71. package/dist/devices/legrand.js.map +1 -1
  72. package/dist/devices/lellki.d.ts.map +1 -1
  73. package/dist/devices/lellki.js +9 -8
  74. package/dist/devices/lellki.js.map +1 -1
  75. package/dist/devices/lidl.d.ts.map +1 -1
  76. package/dist/devices/lidl.js +14 -15
  77. package/dist/devices/lidl.js.map +1 -1
  78. package/dist/devices/lifecontrol.d.ts.map +1 -1
  79. package/dist/devices/lifecontrol.js +9 -21
  80. package/dist/devices/lifecontrol.js.map +1 -1
  81. package/dist/devices/lincukoo.d.ts.map +1 -1
  82. package/dist/devices/lincukoo.js +6 -24
  83. package/dist/devices/lincukoo.js.map +1 -1
  84. package/dist/devices/linkind.d.ts.map +1 -1
  85. package/dist/devices/linkind.js +2 -22
  86. package/dist/devices/linkind.js.map +1 -1
  87. package/dist/devices/linptech.js +5 -5
  88. package/dist/devices/linptech.js.map +1 -1
  89. package/dist/devices/livolo.d.ts.map +1 -1
  90. package/dist/devices/livolo.js +94 -249
  91. package/dist/devices/livolo.js.map +1 -1
  92. package/dist/devices/lixee.d.ts.map +1 -1
  93. package/dist/devices/lixee.js +38 -51
  94. package/dist/devices/lixee.js.map +1 -1
  95. package/dist/devices/lumi.d.ts.map +1 -1
  96. package/dist/devices/lumi.js +32 -62
  97. package/dist/devices/lumi.js.map +1 -1
  98. package/dist/devices/mazda.d.ts.map +1 -1
  99. package/dist/devices/mazda.js +1 -4
  100. package/dist/devices/mazda.js.map +1 -1
  101. package/dist/devices/mindy.d.ts.map +1 -1
  102. package/dist/devices/mindy.js +13 -18
  103. package/dist/devices/mindy.js.map +1 -1
  104. package/dist/devices/moes.d.ts.map +1 -1
  105. package/dist/devices/moes.js +23 -59
  106. package/dist/devices/moes.js.map +1 -1
  107. package/dist/devices/namron.d.ts.map +1 -1
  108. package/dist/devices/namron.js +17 -59
  109. package/dist/devices/namron.js.map +1 -1
  110. package/dist/devices/neo.d.ts.map +1 -1
  111. package/dist/devices/neo.js +7 -34
  112. package/dist/devices/neo.js.map +1 -1
  113. package/dist/devices/nous.d.ts.map +1 -1
  114. package/dist/devices/nous.js +2 -6
  115. package/dist/devices/nous.js.map +1 -1
  116. package/dist/devices/onesti.d.ts +1 -1
  117. package/dist/devices/onesti.d.ts.map +1 -1
  118. package/dist/devices/onesti.js.map +1 -1
  119. package/dist/devices/orvibo.d.ts.map +1 -1
  120. package/dist/devices/orvibo.js +5 -4
  121. package/dist/devices/orvibo.js.map +1 -1
  122. package/dist/devices/orztech.d.ts.map +1 -1
  123. package/dist/devices/orztech.js +5 -20
  124. package/dist/devices/orztech.js.map +1 -1
  125. package/dist/devices/osram.d.ts.map +1 -1
  126. package/dist/devices/osram.js +6 -4
  127. package/dist/devices/osram.js.map +1 -1
  128. package/dist/devices/philips.d.ts.map +1 -1
  129. package/dist/devices/philips.js +7 -0
  130. package/dist/devices/philips.js.map +1 -1
  131. package/dist/devices/profalux.d.ts.map +1 -1
  132. package/dist/devices/profalux.js +20 -16
  133. package/dist/devices/profalux.js.map +1 -1
  134. package/dist/devices/qa.js +1 -1
  135. package/dist/devices/qa.js.map +1 -1
  136. package/dist/devices/rtx.js +1 -1
  137. package/dist/devices/rtx.js.map +1 -1
  138. package/dist/devices/saswell.d.ts.map +1 -1
  139. package/dist/devices/saswell.js +1 -6
  140. package/dist/devices/saswell.js.map +1 -1
  141. package/dist/devices/schneider_electric.d.ts.map +1 -1
  142. package/dist/devices/schneider_electric.js +15 -12
  143. package/dist/devices/schneider_electric.js.map +1 -1
  144. package/dist/devices/senoro.d.ts.map +1 -1
  145. package/dist/devices/senoro.js +1 -4
  146. package/dist/devices/senoro.js.map +1 -1
  147. package/dist/devices/shinasystem.d.ts.map +1 -1
  148. package/dist/devices/shinasystem.js +26 -21
  149. package/dist/devices/shinasystem.js.map +1 -1
  150. package/dist/devices/smart9.d.ts.map +1 -1
  151. package/dist/devices/smart9.js +2 -7
  152. package/dist/devices/smart9.js.map +1 -1
  153. package/dist/devices/sonoff.d.ts.map +1 -1
  154. package/dist/devices/sonoff.js +1 -0
  155. package/dist/devices/sonoff.js.map +1 -1
  156. package/dist/devices/sunricher.d.ts.map +1 -1
  157. package/dist/devices/sunricher.js +4 -27
  158. package/dist/devices/sunricher.js.map +1 -1
  159. package/dist/devices/tech.d.ts.map +1 -1
  160. package/dist/devices/tech.js +2 -8
  161. package/dist/devices/tech.js.map +1 -1
  162. package/dist/devices/technicolor.d.ts.map +1 -1
  163. package/dist/devices/technicolor.js +2 -15
  164. package/dist/devices/technicolor.js.map +1 -1
  165. package/dist/devices/tuya.d.ts.map +1 -1
  166. package/dist/devices/tuya.js +189 -427
  167. package/dist/devices/tuya.js.map +1 -1
  168. package/dist/devices/ubisys.d.ts.map +1 -1
  169. package/dist/devices/ubisys.js +31 -52
  170. package/dist/devices/ubisys.js.map +1 -1
  171. package/dist/devices/universal_electronics_inc.d.ts.map +1 -1
  172. package/dist/devices/universal_electronics_inc.js +3 -29
  173. package/dist/devices/universal_electronics_inc.js.map +1 -1
  174. package/dist/devices/vesternet.d.ts.map +1 -1
  175. package/dist/devices/vesternet.js +4 -1
  176. package/dist/devices/vesternet.js.map +1 -1
  177. package/dist/devices/weiser.d.ts.map +1 -1
  178. package/dist/devices/weiser.js +3 -48
  179. package/dist/devices/weiser.js.map +1 -1
  180. package/dist/devices/woox.d.ts.map +1 -1
  181. package/dist/devices/woox.js +2 -3
  182. package/dist/devices/woox.js.map +1 -1
  183. package/dist/devices/yale.d.ts +1 -1
  184. package/dist/devices/yale.d.ts.map +1 -1
  185. package/dist/devices/yale.js.map +1 -1
  186. package/dist/devices/yandex.d.ts.map +1 -1
  187. package/dist/devices/yandex.js +4 -4
  188. package/dist/devices/yandex.js.map +1 -1
  189. package/dist/devices/zemismart.d.ts.map +1 -1
  190. package/dist/devices/zemismart.js +7 -22
  191. package/dist/devices/zemismart.js.map +1 -1
  192. package/dist/index.d.ts +4 -4
  193. package/dist/index.d.ts.map +1 -1
  194. package/dist/index.js +14 -7
  195. package/dist/index.js.map +1 -1
  196. package/dist/lib/ikea.d.ts.map +1 -1
  197. package/dist/lib/ikea.js +3 -2
  198. package/dist/lib/ikea.js.map +1 -1
  199. package/dist/lib/legrand.d.ts +6 -1
  200. package/dist/lib/legrand.d.ts.map +1 -1
  201. package/dist/lib/legrand.js +14 -3
  202. package/dist/lib/legrand.js.map +1 -1
  203. package/dist/lib/lumi.d.ts +1 -0
  204. package/dist/lib/lumi.d.ts.map +1 -1
  205. package/dist/lib/lumi.js +72 -18
  206. package/dist/lib/lumi.js.map +1 -1
  207. package/dist/lib/modernExtend.d.ts +14 -0
  208. package/dist/lib/modernExtend.d.ts.map +1 -1
  209. package/dist/lib/modernExtend.js +107 -11
  210. package/dist/lib/modernExtend.js.map +1 -1
  211. package/dist/lib/philips.js +1 -1
  212. package/dist/lib/store.d.ts +4 -4
  213. package/dist/lib/store.d.ts.map +1 -1
  214. package/dist/lib/store.js +3 -0
  215. package/dist/lib/store.js.map +1 -1
  216. package/dist/lib/tuya.d.ts +18 -18
  217. package/dist/lib/tuya.d.ts.map +1 -1
  218. package/dist/lib/tuya.js +142 -155
  219. package/dist/lib/tuya.js.map +1 -1
  220. package/dist/lib/types.d.ts +31 -15
  221. package/dist/lib/types.d.ts.map +1 -1
  222. package/dist/lib/ubisys.d.ts +2 -1
  223. package/dist/lib/ubisys.d.ts.map +1 -1
  224. package/dist/lib/ubisys.js +46 -0
  225. package/dist/lib/ubisys.js.map +1 -1
  226. package/dist/lib/utils.d.ts +1 -2
  227. package/dist/lib/utils.d.ts.map +1 -1
  228. package/dist/lib/utils.js +0 -30
  229. package/dist/lib/utils.js.map +1 -1
  230. package/dist/models-index.json +1 -1
  231. package/package.json +3 -3
@@ -520,7 +520,7 @@ const tzLocal = {
520
520
  switch (key) {
521
521
  case "temperature_unit": {
522
522
  utils.assertString(value, "temperature_unit");
523
- await entity.write("manuSpecificTuya_2", {
523
+ await entity.write("manuSpecificTuya2", {
524
524
  "57355": { value: { celsius: 0, fahrenheit: 1 }[value], type: 48 },
525
525
  });
526
526
  break;
@@ -550,7 +550,7 @@ const tzLocal = {
550
550
  case "temperature_threshold": {
551
551
  const state = meta.state.temperature_breaker;
552
552
  const buf = Buffer.from([5, utils.getFromLookup(state, onOffLookup), 0, utils.toNumber(value, "temperature_threshold")]);
553
- await entity.command("manuSpecificTuya_3", "setOptions2", {
553
+ await entity.command("manuSpecificTuya3", "setOptions2", {
554
554
  data: buf,
555
555
  });
556
556
  break;
@@ -559,7 +559,7 @@ const tzLocal = {
559
559
  const threshold = meta.state.temperature_threshold;
560
560
  const number = utils.toNumber(threshold, "temperature_threshold");
561
561
  const buf = Buffer.from([5, utils.getFromLookup(value, onOffLookup), 0, number]);
562
- await entity.command("manuSpecificTuya_3", "setOptions2", {
562
+ await entity.command("manuSpecificTuya3", "setOptions2", {
563
563
  data: buf,
564
564
  });
565
565
  break;
@@ -567,7 +567,7 @@ const tzLocal = {
567
567
  case "power_threshold": {
568
568
  const state = meta.state.power_breaker;
569
569
  const buf = Buffer.from([7, utils.getFromLookup(state, onOffLookup), 0, utils.toNumber(value, "power_breaker")]);
570
- await entity.command("manuSpecificTuya_3", "setOptions2", {
570
+ await entity.command("manuSpecificTuya3", "setOptions2", {
571
571
  data: buf,
572
572
  });
573
573
  break;
@@ -576,7 +576,7 @@ const tzLocal = {
576
576
  const threshold = meta.state.power_threshold;
577
577
  const number = utils.toNumber(threshold, "power_breaker");
578
578
  const buf = Buffer.from([7, utils.getFromLookup(value, onOffLookup), 0, number]);
579
- await entity.command("manuSpecificTuya_3", "setOptions2", {
579
+ await entity.command("manuSpecificTuya3", "setOptions2", {
580
580
  data: buf,
581
581
  });
582
582
  break;
@@ -584,7 +584,7 @@ const tzLocal = {
584
584
  case "over_current_threshold": {
585
585
  const state = meta.state.over_current_breaker;
586
586
  const buf = Buffer.from([1, utils.getFromLookup(state, onOffLookup), 0, utils.toNumber(value, "over_current_threshold")]);
587
- await entity.command("manuSpecificTuya_3", "setOptions3", {
587
+ await entity.command("manuSpecificTuya3", "setOptions3", {
588
588
  data: buf,
589
589
  });
590
590
  break;
@@ -593,7 +593,7 @@ const tzLocal = {
593
593
  const threshold = meta.state.over_current_threshold;
594
594
  const number = utils.toNumber(threshold, "over_current_threshold");
595
595
  const buf = Buffer.from([1, utils.getFromLookup(value, onOffLookup), 0, number]);
596
- await entity.command("manuSpecificTuya_3", "setOptions3", {
596
+ await entity.command("manuSpecificTuya3", "setOptions3", {
597
597
  data: buf,
598
598
  });
599
599
  break;
@@ -604,7 +604,7 @@ const tzLocal = {
604
604
  buf.writeUInt8(3, 0);
605
605
  buf.writeUInt8(utils.getFromLookup(state, onOffLookup), 1);
606
606
  buf.writeUInt16BE(utils.toNumber(value, "over_voltage_threshold"), 2);
607
- await entity.command("manuSpecificTuya_3", "setOptions3", {
607
+ await entity.command("manuSpecificTuya3", "setOptions3", {
608
608
  data: buf,
609
609
  });
610
610
  break;
@@ -613,7 +613,7 @@ const tzLocal = {
613
613
  const threshold = meta.state.over_voltage_threshold;
614
614
  const number = utils.toNumber(threshold, "over_voltage_threshold");
615
615
  const buf = Buffer.from([3, utils.getFromLookup(value, onOffLookup), 0, number]);
616
- await entity.command("manuSpecificTuya_3", "setOptions3", {
616
+ await entity.command("manuSpecificTuya3", "setOptions3", {
617
617
  data: buf,
618
618
  });
619
619
  break;
@@ -621,7 +621,7 @@ const tzLocal = {
621
621
  case "under_voltage_threshold": {
622
622
  const state = meta.state.under_voltage_breaker;
623
623
  const buf = Buffer.from([4, utils.getFromLookup(state, onOffLookup), 0, utils.toNumber(value, "under_voltage_threshold")]);
624
- await entity.command("manuSpecificTuya_3", "setOptions3", {
624
+ await entity.command("manuSpecificTuya3", "setOptions3", {
625
625
  data: buf,
626
626
  });
627
627
  break;
@@ -630,7 +630,7 @@ const tzLocal = {
630
630
  const threshold = meta.state.under_voltage_threshold;
631
631
  const number = utils.toNumber(threshold, "under_voltage_breaker");
632
632
  const buf = Buffer.from([4, utils.getFromLookup(value, onOffLookup), 0, number]);
633
- await entity.command("manuSpecificTuya_3", "setOptions3", {
633
+ await entity.command("manuSpecificTuya3", "setOptions3", {
634
634
  data: buf,
635
635
  });
636
636
  break;
@@ -767,7 +767,7 @@ const fzLocal = {
767
767
  },
768
768
  },
769
769
  temperature_unit: {
770
- cluster: "manuSpecificTuya_2",
770
+ cluster: "manuSpecificTuya2",
771
771
  type: ["attributeReport", "readResponse"],
772
772
  convert: (model, msg, publish, options, meta) => {
773
773
  const result = {};
@@ -824,7 +824,7 @@ const fzLocal = {
824
824
  },
825
825
  // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
826
826
  TS011F_threshold: {
827
- cluster: "manuSpecificTuya_3",
827
+ cluster: "manuSpecificTuya3",
828
828
  type: "raw",
829
829
  convert: (model, msg, publish, options, meta) => {
830
830
  const splitToAttributes = (value) => {
@@ -1040,10 +1040,7 @@ exports.definitions = [
1040
1040
  model: "TS0601_water_valve",
1041
1041
  vendor: "Tuya",
1042
1042
  description: "Ultrasonic water meter valve",
1043
- fromZigbee: [tuya.fz.datapoints],
1044
- toZigbee: [tuya.tz.datapoints],
1045
- onEvent: tuya.onEventSetTime,
1046
- configure: tuya.configureMagicPacket,
1043
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
1047
1044
  exposes: [
1048
1045
  // Main valve switch
1049
1046
  e
@@ -1097,10 +1094,8 @@ exports.definitions = [
1097
1094
  model: "TS0203_1",
1098
1095
  vendor: "Tuya",
1099
1096
  description: "Door sensor with scene switch",
1100
- fromZigbee: [tuya.fz.datapoints, fz.ias_contact_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_contact_alarm_1_report],
1101
- toZigbee: [tuya.tz.datapoints],
1102
- onEvent: tuya.onEventSetTime,
1103
- configure: tuya.configureMagicPacket,
1097
+ fromZigbee: [fz.ias_contact_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_contact_alarm_1_report],
1098
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
1104
1099
  exposes: [e.action(["single", "double", "hold"]), e.contact(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
1105
1100
  meta: {
1106
1101
  tuyaDatapoints: [[101, "action", tuya.valueConverterBasic.lookup({ single: 0, double: 1, hold: 2 })]],
@@ -1112,10 +1107,7 @@ exports.definitions = [
1112
1107
  model: "LKWSZ211",
1113
1108
  vendor: "Linkoze",
1114
1109
  description: "Scene remote with 2 keys",
1115
- fromZigbee: [tuya.fz.datapoints, fz.ignore_basic_report],
1116
- toZigbee: [tuya.tz.datapoints],
1117
- onEvent: tuya.onEventSetTime,
1118
- configure: tuya.configureMagicPacket,
1110
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
1119
1111
  exposes: [
1120
1112
  e.battery(),
1121
1113
  e.action(["button_1_single", "button_1_double", "button_1_hold", "button_2_single", "button_2_double", "button_2_hold"]),
@@ -1272,14 +1264,7 @@ exports.definitions = [
1272
1264
  model: "TS0601_temperature_humidity_sensor_2",
1273
1265
  vendor: "Tuya",
1274
1266
  description: "Temperature and humidity sensor",
1275
- fromZigbee: [tuya.fz.datapoints],
1276
- toZigbee: [tuya.tz.datapoints],
1277
- onEvent: tuya.onEvent({ queryOnDeviceAnnounce: true }),
1278
- configure: async (device, coordinatorEndpoint) => {
1279
- await tuya.configureMagicPacket(device, coordinatorEndpoint);
1280
- // Required to get the device to start reporting
1281
- await device.getEndpoint(1).command("manuSpecificTuya", "dataQuery", {});
1282
- },
1267
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, queryOnDeviceAnnounce: true, queryOnConfigure: true })],
1283
1268
  exposes: [e.temperature(), e.humidity(), tuya.exposes.batteryState(), tuya.exposes.temperatureUnit()],
1284
1269
  meta: {
1285
1270
  tuyaDatapoints: [
@@ -1303,14 +1288,7 @@ exports.definitions = [
1303
1288
  model: "TS0601_temperature_humidity_sensor_3",
1304
1289
  vendor: "Tuya",
1305
1290
  description: "Temperature & humidity sensor",
1306
- fromZigbee: [tuya.fz.datapoints],
1307
- configure: async (device, coordinatorEndpoint) => {
1308
- await tuya.configureMagicPacket(device, coordinatorEndpoint);
1309
- // Required to get the device to start reporting (-- Maybe needed? Copied this from another humidity sensor configuration)
1310
- await device.getEndpoint(1).command("manuSpecificTuya", "dataQuery", {});
1311
- },
1312
- toZigbee: [tuya.tz.datapoints],
1313
- onEvent: tuya.onEventSetLocalTime,
1291
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true, queryOnConfigure: true })],
1314
1292
  exposes: [e.temperature(), e.humidity(), e.battery(), tuya.exposes.temperatureUnit()],
1315
1293
  meta: {
1316
1294
  tuyaDatapoints: [
@@ -1327,14 +1305,7 @@ exports.definitions = [
1327
1305
  model: "ZTH05Z",
1328
1306
  vendor: "Tuya",
1329
1307
  description: "Temperature and humidity sensor",
1330
- fromZigbee: [tuya.fz.datapoints],
1331
- toZigbee: [tuya.tz.datapoints],
1332
- onEvent: tuya.onEvent({ queryOnDeviceAnnounce: true }),
1333
- configure: async (device, coordinatorEndpoint) => {
1334
- await tuya.configureMagicPacket(device, coordinatorEndpoint);
1335
- // Required to get the device to start reporting
1336
- await device.getEndpoint(1).command("manuSpecificTuya", "dataQuery", {});
1337
- },
1308
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, queryOnDeviceAnnounce: true, queryOnConfigure: true })],
1338
1309
  exposes: [
1339
1310
  e.temperature(),
1340
1311
  e.humidity(),
@@ -1424,9 +1395,7 @@ exports.definitions = [
1424
1395
  model: "TS0601_contact_temperature_humidity_sensor",
1425
1396
  vendor: "Tuya",
1426
1397
  description: "Contact, temperature and humidity sensor",
1427
- fromZigbee: [tuya.fz.datapoints, tuya.fz.gateway_connection_status],
1428
- toZigbee: [tuya.tz.datapoints],
1429
- configure: tuya.configureMagicPacket,
1398
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
1430
1399
  exposes: [e.contact(), e.temperature(), e.humidity(), e.battery()],
1431
1400
  meta: {
1432
1401
  tuyaDatapoints: [
@@ -1989,10 +1958,8 @@ exports.definitions = [
1989
1958
  description: "Motion detector with illuminance",
1990
1959
  fromZigbee: [fz.ias_occupancy_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_occupancy_alarm_1_report],
1991
1960
  toZigbee: [],
1992
- onEvent: tuya.onEventSetTime,
1993
- configure: tuya.configureMagicPacket,
1961
+ extend: [m.illuminance(), tuya.modernExtend.tuyaBase({ timeStart: "2000" })],
1994
1962
  exposes: [e.occupancy(), e.battery_low(), e.battery(), e.tamper()],
1995
- extend: [m.illuminance()],
1996
1963
  },
1997
1964
  {
1998
1965
  fingerprint: tuya.fingerprint("TS0202", ["_TZ3210_cwamkvua"]),
@@ -2232,7 +2199,7 @@ exports.definitions = [
2232
2199
  },
2233
2200
  },
2234
2201
  {
2235
- fingerprint: tuya.fingerprint("TS0207", ["_TZ3210_tgvtvdoc"]),
2202
+ fingerprint: tuya.fingerprint("TS0207", ["_TZ3210_tgvtvdoc", "_TZ3210_p68kms0l"]),
2236
2203
  model: "RB-SRAIN01",
2237
2204
  vendor: "Tuya",
2238
2205
  description: "Solar rain sensor",
@@ -3719,6 +3686,7 @@ exports.definitions = [
3719
3686
  tuya.whitelabel("Tuya", "TS0044_1", "Zigbee 4 button remote - 12 scene", ["_TZ3000_dziaict4", "_TZ3000_mh9px7cq", "_TZ3000_j61x9rxn"]),
3720
3687
  tuya.whitelabel("Tuya", "TM-YKQ004", "Zigbee 4 button remote - 12 scene", ["_TZ3000_u3nv1jwk"]),
3721
3688
  tuya.whitelabel("HOBEIAN", "ZG-101ZS", "Star Ring 4 Gang Scene Switch", ["_TZ3000_bgtzm4ny"]),
3689
+ tuya.whitelabel("Moes", "XH-SY-04Z", "4 button portable remote control", ["_TZ3000_zgyzgdua"]),
3722
3690
  ],
3723
3691
  fromZigbee: [tuya.fz.on_off_action, fz.battery],
3724
3692
  exposes: [
@@ -3892,10 +3860,7 @@ exports.definitions = [
3892
3860
  model: "BAC-003",
3893
3861
  vendor: "Tuya",
3894
3862
  description: "FCU thermostat temperature controller",
3895
- fromZigbee: [tuya.fz.datapoints],
3896
- toZigbee: [tuya.tz.datapoints],
3897
- onEvent: tuya.onEventSetLocalTime,
3898
- configure: tuya.configureMagicPacket,
3863
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
3899
3864
  options: [
3900
3865
  e
3901
3866
  .enum("control_sequence_of_operation", ea.SET, ["cooling_only", "cooling_and_heating_4-pipes"])
@@ -4073,12 +4038,7 @@ exports.definitions = [
4073
4038
  vendor: "Tuya",
4074
4039
  description: "Water leak sensor",
4075
4040
  fromZigbee: [fz.ignore_basic_report, fz.ignore_tuya_raw, legacy.fromZigbee.wls100z_water_leak],
4076
- toZigbee: [],
4077
- onEvent: tuya.onEventSetTime,
4078
- configure: async (device, coordinatorEndpoint) => {
4079
- const endpoint = device.getEndpoint(1);
4080
- await reporting.bind(endpoint, coordinatorEndpoint, ["genBasic"]);
4081
- },
4041
+ extend: [tuya.modernExtend.tuyaBase({ timeStart: "2000", bindBasicOnConfigure: true })],
4082
4042
  exposes: [e.battery(), e.water_leak()],
4083
4043
  },
4084
4044
  {
@@ -4147,14 +4107,14 @@ exports.definitions = [
4147
4107
  tuya.whitelabel("Nous", "L6Z", "Switch with power monitoring", ["_TZ3000_qaabwu5c", "_TZ3000_1adss9de"]),
4148
4108
  tuya.whitelabel("Tuya", "XSH01A", "1 gang switch", ["_TZ3000_x3ewpzyr"]),
4149
4109
  ],
4150
- onEvent: async (type, data, device, options) => {
4151
- if (["_TZ3000_x3ewpzyr"].includes(device.manufacturerName)) {
4152
- await tuya.onEventMeasurementPoll(type, data, device, options, true, true);
4153
- }
4154
- else if (["_TZ3000_xkap8wtb"].includes(device.manufacturerName) && [162, 100].includes(device.applicationVersion)) {
4155
- await tuya.onEventMeasurementPoll(type, data, device, options, true, true);
4156
- }
4157
- },
4110
+ extend: [
4111
+ tuya.modernExtend.electricityMeasurementPoll({
4112
+ electricalMeasurement: (device) => device.manufacturerName === "_TZ3000_x3ewpzyr" ||
4113
+ (device.manufacturerName === "_TZ3000_xkap8wtb" && [162, 100].includes(device.applicationVersion)),
4114
+ metering: (device) => device.manufacturerName === "_TZ3000_x3ewpzyr" ||
4115
+ (device.manufacturerName === "_TZ3000_xkap8wtb" && [162, 100].includes(device.applicationVersion)),
4116
+ }),
4117
+ ],
4158
4118
  },
4159
4119
  {
4160
4120
  fingerprint: tuya.fingerprint("TS0002", ["_TZ3000_aaifmpuq", "_TZ3000_irrmjcgi", "_TZ3000_huvxrx4i"]),
@@ -4680,6 +4640,7 @@ exports.definitions = [
4680
4640
  "_TZE200_2odrmqwq",
4681
4641
  "_TZE204_lh3arisb",
4682
4642
  "_TZE284_udank5zs",
4643
+ "_TZE284_b7kbnl6q",
4683
4644
  "_TZE200_7shyddj3",
4684
4645
  "_TZE204_a2jcoyuk",
4685
4646
  "_TZE204_zuq5xxib",
@@ -4838,10 +4799,7 @@ exports.definitions = [
4838
4799
  model: "TS0601_cover_7",
4839
4800
  vendor: "Tuya",
4840
4801
  description: "Cover motor",
4841
- onEvent: tuya.onEvent(),
4842
- configure: tuya.configureMagicPacket,
4843
- fromZigbee: [tuya.fz.datapoints],
4844
- toZigbee: [tuya.tz.datapoints],
4802
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
4845
4803
  exposes: [e.cover_position().setAccess("position", ea.STATE_SET), e.battery()],
4846
4804
  meta: {
4847
4805
  tuyaDatapoints: [
@@ -4912,10 +4870,7 @@ exports.definitions = [
4912
4870
  vendor: "Tuya",
4913
4871
  description: "Window opener",
4914
4872
  options: [exposes.options.invert_cover()],
4915
- fromZigbee: [tuya.fz.datapoints],
4916
- toZigbee: [tuya.tz.datapoints],
4917
- onEvent: tuya.onEventSetTime,
4918
- configure: tuya.configureMagicPacket,
4873
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
4919
4874
  exposes: [e.cover_position().setAccess("position", ea.STATE_SET)],
4920
4875
  meta: {
4921
4876
  tuyaDatapoints: [
@@ -4938,10 +4893,7 @@ exports.definitions = [
4938
4893
  model: "TS0601_cover_9",
4939
4894
  vendor: "Tuya",
4940
4895
  description: "Cover motor",
4941
- onEvent: tuya.onEvent(),
4942
- configure: tuya.configureMagicPacket,
4943
- fromZigbee: [tuya.fz.datapoints],
4944
- toZigbee: [tuya.tz.datapoints],
4896
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
4945
4897
  exposes: [e.cover_position().setAccess("position", ea.STATE_SET), e.battery()],
4946
4898
  meta: {
4947
4899
  tuyaDatapoints: [
@@ -4973,10 +4925,7 @@ exports.definitions = [
4973
4925
  model: "_TZE284_debczeci",
4974
4926
  vendor: "iHseno",
4975
4927
  description: "Human presence sensor",
4976
- fromZigbee: [tuya.fz.datapoints],
4977
- toZigbee: [tuya.tz.datapoints],
4978
- onEvent: tuya.onEventSetLocalTime,
4979
- configure: tuya.configureMagicPacket,
4928
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
4980
4929
  exposes: [
4981
4930
  e.presence().withDescription("Human presence detected"),
4982
4931
  e.battery().withDescription("Battery percentage"),
@@ -4997,10 +4946,7 @@ exports.definitions = [
4997
4946
  model: "TS0601_cover_10",
4998
4947
  vendor: "Tuya",
4999
4948
  description: "Cover motor",
5000
- onEvent: tuya.onEvent(),
5001
- configure: tuya.configureMagicPacket,
5002
- fromZigbee: [tuya.fz.datapoints],
5003
- toZigbee: [tuya.tz.datapoints],
4949
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
5004
4950
  exposes: [
5005
4951
  e.cover_position().setAccess("position", ea.STATE_SET),
5006
4952
  e.enum("motor_direction", ea.STATE_SET, ["normal", "reversed"]).withDescription("Set the motor direction"),
@@ -5097,10 +5043,7 @@ exports.definitions = [
5097
5043
  model: "BX82-TYZ1",
5098
5044
  vendor: "Manhot",
5099
5045
  description: "Cover motor",
5100
- onEvent: tuya.onEvent(),
5101
- configure: tuya.configureMagicPacket,
5102
- fromZigbee: [tuya.fz.datapoints],
5103
- toZigbee: [tuya.tz.datapoints],
5046
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
5104
5047
  exposes: [
5105
5048
  e.cover_position().setAccess("position", ea.STATE_SET),
5106
5049
  e.enum("motor_direction", ea.STATE_SET, ["normal", "reversed"]).withDescription("Set the motor direction"),
@@ -5134,10 +5077,7 @@ exports.definitions = [
5134
5077
  model: "MB60L-ZG-ZT-TY",
5135
5078
  vendor: "Manhot",
5136
5079
  description: "Smart blinds motor",
5137
- onEvent: tuya.onEvent(),
5138
- configure: tuya.configureMagicPacket,
5139
- fromZigbee: [tuya.fz.datapoints],
5140
- toZigbee: [tuya.tz.datapoints],
5080
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
5141
5081
  exposes: [
5142
5082
  e.battery(),
5143
5083
  e.cover_position().setAccess("position", ea.STATE_SET),
@@ -5223,7 +5163,7 @@ exports.definitions = [
5223
5163
  tuyaThermostatSystemMode: legacy.thermostatSystemModes3,
5224
5164
  },
5225
5165
  ota: true,
5226
- onEvent: tuya.onEventSetLocalTime,
5166
+ extend: [tuya.modernExtend.tuyaBase({ forceTimeUpdates: true })],
5227
5167
  fromZigbee: [legacy.fromZigbee.tuya_thermostat, fz.ignore_basic_report, fz.ignore_tuya_set_time],
5228
5168
  toZigbee: [
5229
5169
  legacy.toZigbee.tuya_thermostat_child_lock,
@@ -5288,10 +5228,7 @@ exports.definitions = [
5288
5228
  model: "BAB-1413_Pro",
5289
5229
  vendor: "Tuya",
5290
5230
  description: "Thermostat radiator valve",
5291
- fromZigbee: [tuya.fz.datapoints],
5292
- toZigbee: [tuya.tz.datapoints],
5293
- onEvent: tuya.onEventSetTime,
5294
- configure: tuya.configureMagicPacket,
5231
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
5295
5232
  ota: true,
5296
5233
  exposes: [
5297
5234
  e.battery(),
@@ -5408,10 +5345,7 @@ exports.definitions = [
5408
5345
  model: "PO-THCO-EAU",
5409
5346
  vendor: "Powernity",
5410
5347
  description: "Thermostat radiator valve",
5411
- fromZigbee: [tuya.fz.datapoints],
5412
- toZigbee: [tuya.tz.datapoints],
5413
- onEvent: tuya.onEventSetTime,
5414
- configure: tuya.configureMagicPacket,
5348
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
5415
5349
  exposes: [
5416
5350
  e.battery().withUnit("%"),
5417
5351
  e.child_lock(),
@@ -5491,11 +5425,8 @@ exports.definitions = [
5491
5425
  model: "TS0601_cover_3",
5492
5426
  vendor: "Tuya",
5493
5427
  description: "Cover motor",
5494
- fromZigbee: [tuya.fz.datapoints],
5495
- toZigbee: [tuya.tz.datapoints],
5496
- onEvent: tuya.onEventSetTime,
5428
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
5497
5429
  options: [exposes.options.invert_cover()],
5498
- configure: tuya.configureMagicPacket,
5499
5430
  exposes: [
5500
5431
  e.battery(),
5501
5432
  e.cover_position().setAccess("position", ea.STATE_SET),
@@ -5637,10 +5568,7 @@ exports.definitions = [
5637
5568
  tuya.whitelabel("GIEX", "TV06", "Thermostat radiator valve", ["_TZE200_py4cm3he"]),
5638
5569
  ],
5639
5570
  ota: true,
5640
- fromZigbee: [tuya.fz.datapoints],
5641
- toZigbee: [tuya.tz.datapoints],
5642
- onEvent: tuya.onEventSetLocalTime,
5643
- configure: tuya.configureMagicPacket,
5571
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
5644
5572
  exposes: [
5645
5573
  e.battery_low(),
5646
5574
  e.child_lock(),
@@ -5749,10 +5677,7 @@ exports.definitions = [
5749
5677
  vendor: "Tuya",
5750
5678
  description: "Thermostat radiator valve",
5751
5679
  whiteLabel: [{ vendor: "S366", model: "Cloud Even" }],
5752
- fromZigbee: [tuya.fz.datapoints],
5753
- toZigbee: [tuya.tz.datapoints],
5754
- onEvent: tuya.onEventSetLocalTime,
5755
- configure: tuya.configureMagicPacket,
5680
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
5756
5681
  meta: {
5757
5682
  tuyaDatapoints: [
5758
5683
  [1, "system_mode", tuya.valueConverterBasic.lookup({ heat: true, off: false })],
@@ -5824,8 +5749,6 @@ exports.definitions = [
5824
5749
  model: "TS0601_thermostat_3",
5825
5750
  vendor: "Tuya",
5826
5751
  description: "Thermostatic radiator valve",
5827
- fromZigbee: [tuya.fz.datapoints],
5828
- toZigbee: [tuya.tz.datapoints],
5829
5752
  whiteLabel: [
5830
5753
  tuya.whitelabel("AVATTO", "ME167", "Thermostatic radiator valve", [
5831
5754
  "_TZE200_p3dbf6qs",
@@ -5845,8 +5768,7 @@ exports.definitions = [
5845
5768
  "_TZE200_suxywabt",
5846
5769
  ]),
5847
5770
  ],
5848
- onEvent: tuya.onEventSetTime,
5849
- configure: tuya.configureMagicPacket,
5771
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
5850
5772
  exposes: [
5851
5773
  e.child_lock(),
5852
5774
  e.battery_low(),
@@ -5913,10 +5835,7 @@ exports.definitions = [
5913
5835
  model: "TS0601_thermostat_4",
5914
5836
  vendor: "Tuya",
5915
5837
  description: "Thermostatic radiator valve",
5916
- fromZigbee: [tuya.fz.datapoints],
5917
- toZigbee: [tuya.tz.datapoints],
5918
- onEvent: tuya.onEventSetLocalTime,
5919
- configure: tuya.configureMagicPacket,
5838
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
5920
5839
  exposes: [
5921
5840
  e.child_lock(),
5922
5841
  e.battery(),
@@ -6006,7 +5925,7 @@ exports.definitions = [
6006
5925
  legacy.toZigbee.tuya_thermostat_current_heating_setpoint,
6007
5926
  legacy.toZigbee.tuya_thermostat_weekly_schedule,
6008
5927
  ],
6009
- onEvent: tuya.onEventSetTime,
5928
+ extend: [tuya.modernExtend.tuyaBase({ timeStart: "2000" })],
6010
5929
  meta: {
6011
5930
  thermostat: {
6012
5931
  weeklyScheduleMaxTransitions: 4,
@@ -6043,7 +5962,7 @@ exports.definitions = [
6043
5962
  legacy.toZigbee.tuya_thermostat_current_heating_setpoint,
6044
5963
  legacy.toZigbee.tuya_thermostat_weekly_schedule,
6045
5964
  ],
6046
- onEvent: tuya.onEventSetTime,
5965
+ extend: [tuya.modernExtend.tuyaBase({ timeStart: "2000" })],
6047
5966
  meta: {
6048
5967
  timeout: 20000, // TRV wakes up every 10sec
6049
5968
  thermostat: {
@@ -6073,10 +5992,7 @@ exports.definitions = [
6073
5992
  tuya.whitelabel("id3", "GTZ06", "Thermostatic radiator valve", ["_TZE200_z1tyspqw"]),
6074
5993
  tuya.whitelabel("AVATTO", "TRV07", "Thermostatic radiator valve", ["_TZE200_bvrlmajk"]),
6075
5994
  ],
6076
- onEvent: tuya.onEventSetLocalTime,
6077
- fromZigbee: [tuya.fz.datapoints],
6078
- toZigbee: [tuya.tz.datapoints],
6079
- configure: tuya.configureMagicPacket,
5995
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
6080
5996
  exposes: [
6081
5997
  e.battery(),
6082
5998
  e.child_lock(),
@@ -6160,10 +6076,7 @@ exports.definitions = [
6160
6076
  vendor: "Tuya",
6161
6077
  whiteLabel: [tuya.whitelabel("Sber", "SBDV-00185", "Thermostatic radiator valve", ["_TZE204_cvcu2p6e"])],
6162
6078
  description: "Thermostatic radiator valve",
6163
- onEvent: tuya.onEventSetLocalTime,
6164
- fromZigbee: [tuya.fz.datapoints],
6165
- toZigbee: [tuya.tz.datapoints],
6166
- configure: tuya.configureMagicPacket,
6079
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
6167
6080
  exposes: [
6168
6081
  e.battery(),
6169
6082
  e.child_lock(),
@@ -6239,10 +6152,7 @@ exports.definitions = [
6239
6152
  vendor: "Tuya",
6240
6153
  description: "Thermostatic radiator valve.",
6241
6154
  whiteLabel: [tuya.whitelabel("Moes", "TRV801", "Thermostatic radiator valve", ["_TZE204_9mjy74mp", "_TZE200_9mjy74mp"])],
6242
- onEvent: tuya.onEventSetLocalTime,
6243
- fromZigbee: [tuya.fz.datapoints],
6244
- toZigbee: [tuya.tz.datapoints],
6245
- configure: tuya.configureMagicPacket,
6155
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
6246
6156
  exposes: [
6247
6157
  e.battery(),
6248
6158
  e.child_lock(),
@@ -6471,10 +6381,7 @@ exports.definitions = [
6471
6381
  model: "ZHT-002",
6472
6382
  vendor: "Moes",
6473
6383
  description: "ZHT series thermostat",
6474
- fromZigbee: [tuya.fz.datapoints],
6475
- toZigbee: [tuya.tz.datapoints],
6476
- onEvent: tuya.onEventSetTime,
6477
- configure: tuya.configureMagicPacket,
6384
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
6478
6385
  exposes: [
6479
6386
  e.binary("state", ea.STATE_SET, "ON", "OFF").withDescription("Turn the thermostat ON/OFF"),
6480
6387
  e.child_lock(),
@@ -6573,10 +6480,7 @@ exports.definitions = [
6573
6480
  model: "TRV603-WZ",
6574
6481
  vendor: "Tuya",
6575
6482
  description: "Thermostatic radiator valve.",
6576
- fromZigbee: [tuya.fz.datapoints],
6577
- toZigbee: [tuya.tz.datapoints],
6578
- onEvent: tuya.onEventSetLocalTime,
6579
- configure: tuya.configureMagicPacket,
6483
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
6580
6484
  exposes: [
6581
6485
  e.battery(),
6582
6486
  e.child_lock(),
@@ -6703,7 +6607,6 @@ exports.definitions = [
6703
6607
  }
6704
6608
  await endpoint.read("genOnOff", ["onOff", "moesStartUpOnOff", "tuyaBacklightMode"]);
6705
6609
  },
6706
- options: [exposes.options.measurement_poll_interval()],
6707
6610
  // This device doesn't support reporting correctly.
6708
6611
  // https://github.com/Koenkk/zigbee-herdsman-converters/pull/1270
6709
6612
  exposes: [
@@ -6715,7 +6618,7 @@ exports.definitions = [
6715
6618
  e.enum("power_outage_memory", ea.ALL, ["on", "off", "restore"]).withDescription("Recover state after power outage"),
6716
6619
  e.enum("indicator_mode", ea.ALL, ["off", "off/on", "on/off"]).withDescription("LED indicator mode"),
6717
6620
  ],
6718
- onEvent: (type, data, device, options) => tuya.onEventMeasurementPoll(type, data, device, options, true, false),
6621
+ extend: [tuya.modernExtend.electricityMeasurementPoll()],
6719
6622
  },
6720
6623
  {
6721
6624
  fingerprint: tuya.fingerprint("TS0111", ["_TYZB01_ymcdbl3u"]),
@@ -6742,9 +6645,9 @@ exports.definitions = [
6742
6645
  { vendor: "MODEMIX", model: "MOD048" },
6743
6646
  { vendor: "Coswall", model: "CS-AJ-DE2U-ZG-11" },
6744
6647
  { vendor: "Aubess", model: "TS011F_plug_1" },
6745
- tuya.whitelabel("BSEED", "FK86ZEUSK1W", "Wall-mounted electrical socket", ["_TZ3000_4ux0ondb"]),
6648
+ tuya.whitelabel("BSEED", "FK86ZEUSK1W", "Wall-mounted electrical socket", ["_TZ3000_4ux0ondb", "_TZ3000_b28wrpvx"]),
6746
6649
  tuya.whitelabel("Nous", "A1Z", "Smart plug (with power monitoring)", ["_TZ3000_2putqrmw", "_TZ3000_ksw8qtmt"]),
6747
- tuya.whitelabel("Moes", "MOES_plug", "Smart plug (with power monitoring)", ["_TZ3000_yujkchbz"]),
6650
+ tuya.whitelabel("Moes", "Moes_plug", "Smart plug (with power monitoring)", ["_TZ3000_yujkchbz"]),
6748
6651
  tuya.whitelabel("Moes", "ZK-EU", "Smart wallsocket (with power monitoring)", ["_TZ3000_ss98ec5d"]),
6749
6652
  tuya.whitelabel("Elivco", "LSPA9", "Smart plug (with power monitoring)", ["_TZ3000_okaz9tjs"]),
6750
6653
  tuya.whitelabel("PSMART", "T440", "Smart wallsocket (with power monitoring)", ["_TZ3000_y4ona9me"]),
@@ -6842,6 +6745,9 @@ exports.definitions = [
6842
6745
  indicatorMode: true,
6843
6746
  childLock: true,
6844
6747
  }),
6748
+ tuya.modernExtend.electricityMeasurementPoll({
6749
+ metering: (device) => [100, 160].includes(device.applicationVersion) || ["1.0.5\u0000"].includes(device.softwareBuildID), // polling for energy
6750
+ }),
6845
6751
  ],
6846
6752
  configure: async (device, coordinatorEndpoint) => {
6847
6753
  await tuya.configureMagicPacket(device, coordinatorEndpoint);
@@ -6857,9 +6763,6 @@ exports.definitions = [
6857
6763
  utils.attachOutputCluster(device, "genOta");
6858
6764
  device.save();
6859
6765
  },
6860
- options: [exposes.options.measurement_poll_interval()],
6861
- onEvent: (type, data, device, options) => tuya.onEventMeasurementPoll(type, data, device, options, true, // polling for voltage, current and power
6862
- [100, 160].includes(device.applicationVersion) || ["1.0.5\u0000"].includes(device.softwareBuildID)),
6863
6766
  },
6864
6767
  {
6865
6768
  fingerprint: tuya.fingerprint("TS011F", ["_TZ3000_in5s3wn1", "_TZ3000_wbloefbf"]),
@@ -6945,15 +6848,35 @@ exports.definitions = [
6945
6848
  ],
6946
6849
  },
6947
6850
  },
6851
+ {
6852
+ fingerprint: tuya.fingerprint("TS0601", ["_TZE284_ai4rqhky"]),
6853
+ model: "HS2SA-1",
6854
+ vendor: "Heiman",
6855
+ description: "Photoelectric Smoke Alarm",
6856
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
6857
+ exposes: [
6858
+ e.smoke(),
6859
+ e.battery(),
6860
+ tuya.exposes.batteryState(),
6861
+ e.binary("silence", ea.STATE_SET, "ON", "OFF"),
6862
+ e.enum("self_test", ea.STATE, ["checking", "check_success", "check_failure"]),
6863
+ ],
6864
+ meta: {
6865
+ tuyaDatapoints: [
6866
+ [1, "smoke", tuya.valueConverter.trueFalse0],
6867
+ [9, "self_test", tuya.valueConverterBasic.lookup({ checking: 0, check_success: 1, check_failure: 2 })],
6868
+ [14, "battery_state", tuya.valueConverter.batteryState],
6869
+ [15, "battery", tuya.valueConverter.raw],
6870
+ [16, "silence", tuya.valueConverter.onOff],
6871
+ ],
6872
+ },
6873
+ },
6948
6874
  {
6949
6875
  fingerprint: tuya.fingerprint("TS0601", ["_TZE200_m9skfctm", "_TZE200_rccxox8p", "_TZE284_rccxox8p"]),
6950
6876
  model: "PA-44Z",
6951
6877
  vendor: "Tuya",
6952
6878
  description: "Photoelectric smoke detector",
6953
- fromZigbee: [tuya.fz.datapoints],
6954
- toZigbee: [tuya.tz.datapoints],
6955
- onEvent: tuya.onEventSetTime,
6956
- configure: tuya.configureMagicPacket,
6879
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
6957
6880
  exposes: [
6958
6881
  e.smoke(),
6959
6882
  e.battery(),
@@ -7048,10 +6971,7 @@ exports.definitions = [
7048
6971
  model: "ZS-301Z",
7049
6972
  vendor: "Arteco",
7050
6973
  description: "Soil moisture sensor",
7051
- fromZigbee: [tuya.fz.datapoints],
7052
- toZigbee: [tuya.tz.datapoints],
7053
- onEvent: tuya.onEventSetTime,
7054
- configure: tuya.configureMagicPacket,
6974
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
7055
6975
  exposes: [
7056
6976
  e.enum("battery_state", ea.STATE, ["low", "middle", "high"]).withDescription("low: 1-25%, middle: 26-50%, high: 51-100%"),
7057
6977
  e.temperature(),
@@ -7089,10 +7009,7 @@ exports.definitions = [
7089
7009
  model: "ZSS-QY-SSD-A-EN",
7090
7010
  vendor: "Tuya",
7091
7011
  description: "Smart smoke alarm",
7092
- fromZigbee: [tuya.fz.datapoints],
7093
- toZigbee: [tuya.tz.datapoints],
7094
- onEvent: tuya.onEventSetTime,
7095
- configure: tuya.configureMagicPacket,
7012
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
7096
7013
  exposes: [
7097
7014
  e.smoke(),
7098
7015
  tuya.exposes.faultAlarm(),
@@ -7129,16 +7046,14 @@ exports.definitions = [
7129
7046
  e.binary("alarm", ea.STATE_SET, true, false).withDescription("Enable the alarm"),
7130
7047
  e.binary("silence_siren", ea.STATE_SET, true, false).withDescription("Silence the siren"),
7131
7048
  ],
7132
- onEvent: tuya.onEventSetTime,
7049
+ extend: [tuya.modernExtend.tuyaBase({ timeStart: "2000" })],
7133
7050
  },
7134
7051
  {
7135
7052
  fingerprint: tuya.fingerprint("TS0601", ["_TZE204_cjbofhxw", "_TZE284_cjbofhxw"]),
7136
7053
  model: "PJ-MGW1203",
7137
7054
  vendor: "Tuya",
7138
7055
  description: "Clamp meter",
7139
- fromZigbee: [tuya.fz.datapoints, tuya.fz.gateway_connection_status],
7140
- toZigbee: [tuya.tz.datapoints],
7141
- configure: tuya.configureMagicPacket,
7056
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
7142
7057
  exposes: [e.current(), e.power(), e.voltage(), e.energy()],
7143
7058
  meta: {
7144
7059
  tuyaDatapoints: [
@@ -8374,7 +8289,7 @@ exports.definitions = [
8374
8289
  description: "Wall-mount thermostat",
8375
8290
  fromZigbee: [legacy.fromZigbee.hy_thermostat, fz.ignore_basic_report],
8376
8291
  toZigbee: [legacy.toZigbee.hy_thermostat],
8377
- onEvent: tuya.onEventSetTime,
8292
+ extend: [tuya.modernExtend.tuyaBase({ timeStart: "2000" })],
8378
8293
  exposes: [
8379
8294
  e
8380
8295
  .climate()
@@ -8389,10 +8304,7 @@ exports.definitions = [
8389
8304
  model: "ZWT07",
8390
8305
  vendor: "Tuya",
8391
8306
  description: "Wall-mount thermostat",
8392
- fromZigbee: [tuya.fz.datapoints],
8393
- toZigbee: [tuya.tz.datapoints],
8394
- onEvent: tuya.onEvent({ timeStart: "1970" }),
8395
- configure: tuya.configureMagicPacket,
8307
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
8396
8308
  exposes: [
8397
8309
  e
8398
8310
  .climate()
@@ -8479,7 +8391,7 @@ exports.definitions = [
8479
8391
  .withValueStep(1)
8480
8392
  .withPreset("default", 60, "Default value"),
8481
8393
  ],
8482
- onEvent: tuya.onEventSetTime,
8394
+ extend: [tuya.modernExtend.tuyaBase({ timeStart: "2000" })],
8483
8395
  },
8484
8396
  {
8485
8397
  fingerprint: tuya.fingerprint("TS0601", [
@@ -8493,13 +8405,7 @@ exports.definitions = [
8493
8405
  model: "ZWT198/ZWT100-BH",
8494
8406
  vendor: "Tuya",
8495
8407
  description: "Wall thermostat",
8496
- onEvent: tuya.onEvent({
8497
- timeStart: "1970",
8498
- respondToMcuVersionResponse: false,
8499
- }),
8500
- fromZigbee: [tuya.fz.datapoints],
8501
- toZigbee: [tuya.tz.datapoints],
8502
- configure: tuya.configureMagicPacket,
8408
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, respondToMcuVersionResponse: false })],
8503
8409
  exposes: [
8504
8410
  e.binary("factory_reset", ea.STATE_SET, "ON", "OFF").withDescription("Full factory reset, use with caution!"),
8505
8411
  e.child_lock(),
@@ -8649,10 +8555,7 @@ exports.definitions = [
8649
8555
  model: "TGM50-ZB",
8650
8556
  vendor: "Tuya",
8651
8557
  description: "Beok wall thermostat",
8652
- onEvent: tuya.onEvent({ timeStart: "1970" }),
8653
- fromZigbee: [tuya.fz.datapoints],
8654
- toZigbee: [tuya.tz.datapoints],
8655
- configure: tuya.configureMagicPacket,
8558
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
8656
8559
  exposes: [
8657
8560
  e.child_lock(),
8658
8561
  e.temperature_sensor_select(["internal", "external", "both"]),
@@ -8779,6 +8682,14 @@ exports.definitions = [
8779
8682
  configure: tuya.configureMagicPacket,
8780
8683
  extend: [m.illuminance()],
8781
8684
  },
8685
+ {
8686
+ fingerprint: tuya.fingerprint("TS0222", ["_TZ3000_j6adk9id"]),
8687
+ model: "TS0222_solar_light",
8688
+ vendor: "Tuya",
8689
+ description: "Solar light sensor",
8690
+ configure: tuya.configureMagicPacket,
8691
+ extend: [m.illuminance(), m.battery()],
8692
+ },
8782
8693
  {
8783
8694
  zigbeeModel: ["TS0210"],
8784
8695
  model: "TS0210",
@@ -8917,8 +8828,7 @@ exports.definitions = [
8917
8828
  e.enum("power_outage_memory", ea.ALL, ["on", "off", "restore"]).withDescription("Recover state after power outage"),
8918
8829
  e.enum("indicator_mode", ea.STATE_SET, ["off", "on_off", "off_on"]).withDescription("Relay LED indicator mode"),
8919
8830
  ],
8920
- options: [exposes.options.measurement_poll_interval()],
8921
- onEvent: (type, data, device, options) => tuya.onEventMeasurementPoll(type, data, device, options, true, false),
8831
+ extend: [tuya.modernExtend.electricityMeasurementPoll()],
8922
8832
  },
8923
8833
  {
8924
8834
  fingerprint: [...tuya.fingerprint("TS011F", ["_TZ3000_7issjl2q"]), ...tuya.fingerprint("TS0011", ["_TZ3000_gzvniqjb"])],
@@ -9025,7 +8935,7 @@ exports.definitions = [
9025
8935
  ],
9026
8936
  },
9027
8937
  {
9028
- fingerprint: tuya.fingerprint("TS0603", ["_TZE608_c75zqghm", "_TZE608_fmemczv1", "_TZE608_xkr8gep3"]),
8938
+ fingerprint: tuya.fingerprint("TS0603", ["_TZE608_c75zqghm", "_TZE608_fmemczv1", "_TZE608_xkr8gep3", "_TZE608_lapuuoke"]),
9029
8939
  model: "TS0603",
9030
8940
  vendor: "Tuya",
9031
8941
  meta: {
@@ -9066,7 +8976,7 @@ exports.definitions = [
9066
8976
  "genPowerCfg",
9067
8977
  "msTemperatureMeasurement",
9068
8978
  "msRelativeHumidity",
9069
- "manuSpecificTuya_2",
8979
+ "manuSpecificTuya2",
9070
8980
  ]);
9071
8981
  },
9072
8982
  exposes: [
@@ -9283,10 +9193,9 @@ exports.definitions = [
9283
9193
  fz.tuya_operation_mode,
9284
9194
  ],
9285
9195
  toZigbee: [tz.tuya_operation_mode],
9286
- onEvent: tuya.onEventSetLocalTime,
9196
+ extend: [tuya.modernExtend.tuyaBase({ forceTimeUpdates: true })],
9287
9197
  configure: async (device, coordinatorEndpoint) => {
9288
9198
  const endpoint = device.getEndpoint(1);
9289
- await endpoint.read("genBasic", [0x0004, 0x000, 0x0001, 0x0005, 0x0007, 0xfffe]);
9290
9199
  await endpoint.write("genOnOff", { tuyaOperationMode: 1 });
9291
9200
  await endpoint.read("genOnOff", ["tuyaOperationMode"]);
9292
9201
  try {
@@ -9638,10 +9547,7 @@ exports.definitions = [
9638
9547
  model: "Y1_IN",
9639
9548
  vendor: "Tuya",
9640
9549
  description: "Smart human presence sensor 24G",
9641
- fromZigbee: [tuya.fz.datapoints],
9642
- toZigbee: [tuya.tz.datapoints],
9643
- onEvent: tuya.onEventSetTime,
9644
- configure: tuya.configureMagicPacket,
9550
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
9645
9551
  exposes: [
9646
9552
  e.presence(),
9647
9553
  e.illuminance(),
@@ -9783,10 +9689,7 @@ exports.definitions = [
9783
9689
  model: "WZ-M100",
9784
9690
  vendor: "Wenzhi",
9785
9691
  description: "Human presence sensor",
9786
- fromZigbee: [tuya.fz.datapoints],
9787
- toZigbee: [tuya.tz.datapoints],
9788
- onEvent: tuya.onEventSetTime,
9789
- configure: tuya.configureMagicPacket,
9692
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
9790
9693
  exposes: [
9791
9694
  e.illuminance(),
9792
9695
  e.presence(),
@@ -9973,11 +9876,7 @@ exports.definitions = [
9973
9876
  description: "Temperature & humidity sensor with clock",
9974
9877
  fromZigbee: [legacy.fromZigbee.nous_lcd_temperature_humidity_sensor, fz.ignore_tuya_set_time],
9975
9878
  toZigbee: [legacy.toZigbee.nous_lcd_temperature_humidity_sensor],
9976
- onEvent: tuya.onEventSetLocalTime,
9977
- configure: async (device, coordinatorEndpoint) => {
9978
- const endpoint = device.getEndpoint(1);
9979
- await reporting.bind(endpoint, coordinatorEndpoint, ["genBasic"]);
9980
- },
9879
+ extend: [tuya.modernExtend.tuyaBase({ forceTimeUpdates: true, bindBasicOnConfigure: true })],
9981
9880
  exposes: [
9982
9881
  e.temperature(),
9983
9882
  e.humidity(),
@@ -10005,7 +9904,7 @@ exports.definitions = [
10005
9904
  description: "Tubular motor",
10006
9905
  fromZigbee: [legacy.fromZigbee.zb_sm_cover, fz.ignore_basic_report],
10007
9906
  toZigbee: [legacy.toZigbee.zb_sm_cover],
10008
- onEvent: tuya.onEventSetTime,
9907
+ extend: [tuya.modernExtend.tuyaBase({ timeStart: "2000" })],
10009
9908
  exposes: [
10010
9909
  e.cover_position().setAccess("position", ea.STATE_SET),
10011
9910
  e.enum("goto_positon", ea.SET, ["25", "50", "75", "FAVORITE"]),
@@ -10055,7 +9954,7 @@ exports.definitions = [
10055
9954
  description: "Temperature & humidity sensor with LCD",
10056
9955
  fromZigbee: [fz.temperature, fzLocal.humidity10, fzLocal.temperature_unit, fz.battery, fz.ignore_tuya_set_time],
10057
9956
  toZigbee: [tzLocal.temperature_unit],
10058
- onEvent: tuya.onEventSetLocalTime,
9957
+ extend: [tuya.modernExtend.tuyaBase({ forceTimeUpdates: true })],
10059
9958
  exposes: [
10060
9959
  e.temperature(),
10061
9960
  e.humidity(),
@@ -10077,7 +9976,7 @@ exports.definitions = [
10077
9976
  description: "Human presence sensor Zigbee",
10078
9977
  fromZigbee: [legacy.fromZigbee.hpsz],
10079
9978
  toZigbee: [legacy.toZigbee.hpsz],
10080
- onEvent: tuya.onEventSetLocalTime,
9979
+ extend: [tuya.modernExtend.tuyaBase({ forceTimeUpdates: true })],
10081
9980
  exposes: [
10082
9981
  e.presence(),
10083
9982
  e.numeric("duration_of_attendance", ea.STATE).withUnit("min").withDescription("Shows the presence duration in minutes"),
@@ -10283,13 +10182,7 @@ exports.definitions = [
10283
10182
  model: "RSH-HS06",
10284
10183
  vendor: "Tuya",
10285
10184
  description: "Temperature and humidity sensor",
10286
- fromZigbee: [tuya.fz.datapoints],
10287
- toZigbee: [tuya.tz.datapoints],
10288
- onEvent: tuya.onEvent({ queryOnDeviceAnnounce: true }),
10289
- configure: async (device, coordinatorEndpoint) => {
10290
- await tuya.configureMagicPacket(device, coordinatorEndpoint);
10291
- await device.getEndpoint(1).command("manuSpecificTuya", "dataQuery", {});
10292
- },
10185
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, queryOnDeviceAnnounce: true, queryOnConfigure: true })],
10293
10186
  exposes: [
10294
10187
  e.temperature(),
10295
10188
  e.humidity(),
@@ -10363,10 +10256,7 @@ exports.definitions = [
10363
10256
  model: "TS0601_pir",
10364
10257
  vendor: "Tuya",
10365
10258
  description: "Haozee PIR sensor",
10366
- fromZigbee: [tuya.fz.datapoints],
10367
- toZigbee: [tuya.tz.datapoints],
10368
- onEvent: tuya.onEvent(),
10369
- configure: tuya.configureMagicPacket,
10259
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
10370
10260
  exposes: (device, options) => {
10371
10261
  const exposes = [e.occupancy(), e.illuminance()];
10372
10262
  // https://github.com/Koenkk/zigbee2mqtt.io/pull/4018
@@ -10693,7 +10583,7 @@ exports.definitions = [
10693
10583
  model: "TS110E_1gang_1",
10694
10584
  vendor: "Tuya",
10695
10585
  description: "1 channel dimmer",
10696
- extend: [m.light({ powerOnBehavior: false, configureReporting: true })],
10586
+ extend: [m.light({ powerOnBehavior: false, configureReporting: true, effect: false }), tuya.modernExtend.tuyaMagicPacket()],
10697
10587
  fromZigbee: [tuya.fz.power_on_behavior_1, fz.TS110E_switch_type, fz.TS110E, fz.on_off],
10698
10588
  toZigbee: [tz.TS110E_light_onoff_brightness, tuya.tz.power_on_behavior_1, tz.TS110E_options],
10699
10589
  exposes: [e.power_on_behavior(), tuya.exposes.switchType(), e.min_brightness(), e.max_brightness()],
@@ -10793,11 +10683,9 @@ exports.definitions = [
10793
10683
  toZigbee: [tz.TS110E_onoff_brightness, tz.TS110E_options, tuya.tz.power_on_behavior_1, tz.light_brightness_move],
10794
10684
  meta: { multiEndpoint: true },
10795
10685
  exposes: [
10686
+ e.power_on_behavior(),
10796
10687
  e.light_brightness().withMinBrightness().withMaxBrightness().withEndpoint("l1"),
10797
10688
  e.light_brightness().withMinBrightness().withMaxBrightness().withEndpoint("l2"),
10798
- e.power_on_behavior().withEndpoint("l1"),
10799
- e.power_on_behavior().withEndpoint("l2"),
10800
- tuya.exposes.lightType().withAccess(ea.ALL),
10801
10689
  tuya.exposes.switchType().withEndpoint("l1"),
10802
10690
  tuya.exposes.switchType().withEndpoint("l2"),
10803
10691
  ],
@@ -10907,10 +10795,7 @@ exports.definitions = [
10907
10795
  model: "TS0049",
10908
10796
  vendor: "Tuya",
10909
10797
  description: "Water valve",
10910
- fromZigbee: [tuya.fz.datapoints],
10911
- toZigbee: [tuya.tz.datapoints],
10912
- onEvent: tuya.onEventSetLocalTime,
10913
- configure: tuya.configureMagicPacket,
10798
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
10914
10799
  exposes: [
10915
10800
  tuya.exposes.errorStatus(),
10916
10801
  tuya.exposes.switch(),
@@ -10932,10 +10817,8 @@ exports.definitions = [
10932
10817
  model: "TS0601_water_switch",
10933
10818
  vendor: "Tuya",
10934
10819
  description: "Dual water valve",
10935
- fromZigbee: [tuya.fz.datapoints, fz.battery],
10936
- toZigbee: [tuya.tz.datapoints],
10937
- onEvent: tuya.onEventSetTime,
10938
- configure: tuya.configureMagicPacket,
10820
+ fromZigbee: [fz.battery],
10821
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
10939
10822
  exposes: [
10940
10823
  e.enum("valve_status", ea.STATE, ["manual", "auto", "idle"]).withDescription("Valve 1 status (manual, auto, idle)").withEndpoint("l1"),
10941
10824
  e.enum("valve_status", ea.STATE, ["manual", "auto", "idle"]).withDescription("Valve 2 status (manual, auto, idle)").withEndpoint("l2"),
@@ -12258,10 +12141,7 @@ exports.definitions = [
12258
12141
  model: "TS0601_bidirectional_energy meter",
12259
12142
  vendor: "Tuya",
12260
12143
  description: "Bidirectional energy meter with 150A Current Clamp",
12261
- fromZigbee: [tuya.fz.datapoints],
12262
- toZigbee: [tuya.tz.datapoints],
12263
- onEvent: tuya.onEventSetTime,
12264
- configure: tuya.configureMagicPacket,
12144
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
12265
12145
  exposes: [
12266
12146
  e.energy(),
12267
12147
  e.produced_energy(),
@@ -12283,6 +12163,7 @@ exports.definitions = [
12283
12163
  fingerprint: tuya.fingerprint("TS0601", [
12284
12164
  "_TZE200_vmcgja59",
12285
12165
  "_TZE204_dvosyycn",
12166
+ "_TZE284_dvosyycn",
12286
12167
  "_TZE200_wktrysab",
12287
12168
  "_TZE204_wktrysab",
12288
12169
  "_TZE204_nvxorhcj",
@@ -12486,6 +12367,7 @@ exports.definitions = [
12486
12367
  childLock: true,
12487
12368
  endpoints: ["l1", "l2"],
12488
12369
  }),
12370
+ tuya.modernExtend.electricityMeasurementPoll(),
12489
12371
  ],
12490
12372
  endpoint: (device) => {
12491
12373
  return { l1: 1, l2: 2 };
@@ -12507,8 +12389,6 @@ exports.definitions = [
12507
12389
  });
12508
12390
  device.save();
12509
12391
  },
12510
- options: [exposes.options.measurement_poll_interval()],
12511
- onEvent: (type, data, device, options) => tuya.onEventMeasurementPoll(type, data, device, options, true, false),
12512
12392
  whiteLabel: [tuya.whitelabel("Nous", "A4Z", "2 gang outdoor plug", ["_TZ3000_rqbjepe8", "_TZ3000_uwkja6z1"])],
12513
12393
  },
12514
12394
  {
@@ -12651,9 +12531,7 @@ exports.definitions = [
12651
12531
  model: "ZS-TYG3-SM-61Z",
12652
12532
  vendor: "Tuya",
12653
12533
  description: "Smart switch (4 gang + 2 scene) with backlight and neutral wire",
12654
- fromZigbee: [tuya.fz.datapoints],
12655
- toZigbee: [tuya.tz.datapoints],
12656
- configure: tuya.configureMagicPacket,
12534
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
12657
12535
  exposes: [
12658
12536
  tuya.exposes.switch().withDescription("All Switches"),
12659
12537
  tuya.exposes.switch().withEndpoint("l1"),
@@ -12671,7 +12549,6 @@ exports.definitions = [
12671
12549
  tuya.exposes.countdown().withEndpoint("l6"),
12672
12550
  e.power_on_behavior().withAccess(ea.STATE_SET),
12673
12551
  ],
12674
- onEvent: tuya.onEventSetTime,
12675
12552
  endpoint: (device) => {
12676
12553
  return {
12677
12554
  l1: 1,
@@ -12710,9 +12587,7 @@ exports.definitions = [
12710
12587
  model: "ZS-TYG3-SM-21Z",
12711
12588
  vendor: "Tuya",
12712
12589
  description: "2 gang smart switch with backlight and neutral wire",
12713
- fromZigbee: [tuya.fz.datapoints],
12714
- toZigbee: [tuya.tz.datapoints],
12715
- configure: tuya.configureMagicPacket,
12590
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
12716
12591
  exposes: [
12717
12592
  tuya.exposes.switch().withDescription("All Switches"),
12718
12593
  tuya.exposes.switch().withEndpoint("l1"),
@@ -12722,7 +12597,6 @@ exports.definitions = [
12722
12597
  tuya.exposes.countdown().withEndpoint("l2"),
12723
12598
  e.power_on_behavior().withAccess(ea.STATE_SET),
12724
12599
  ],
12725
- onEvent: tuya.onEventSetTime,
12726
12600
  endpoint: (device) => {
12727
12601
  return { l1: 1, l2: 1, state: 1, backlight: 1 };
12728
12602
  },
@@ -12744,9 +12618,6 @@ exports.definitions = [
12744
12618
  model: "ZS-TYG3-SM-31Z",
12745
12619
  vendor: "Tuya",
12746
12620
  description: "3 gang smart switch with backlight and neutral wire",
12747
- fromZigbee: [tuya.fz.datapoints],
12748
- toZigbee: [tuya.tz.datapoints],
12749
- configure: tuya.configureMagicPacket,
12750
12621
  exposes: [
12751
12622
  tuya.exposes.switch().withDescription("All Switches"),
12752
12623
  tuya.exposes.switch().withEndpoint("l1"),
@@ -12758,7 +12629,7 @@ exports.definitions = [
12758
12629
  tuya.exposes.countdown().withEndpoint("l3"),
12759
12630
  e.power_on_behavior(["off", "on", "previous"]).withAccess(ea.STATE_SET),
12760
12631
  ],
12761
- onEvent: tuya.onEventSetTime,
12632
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
12762
12633
  endpoint: (device) => {
12763
12634
  return { l1: 1, l2: 1, l3: 1, state: 1, backlight: 1 };
12764
12635
  },
@@ -12782,9 +12653,7 @@ exports.definitions = [
12782
12653
  model: "ZS-TYG3-SM-41Z",
12783
12654
  vendor: "Tuya",
12784
12655
  description: "4 gang smart switch with backlight and neutral wire",
12785
- fromZigbee: [tuya.fz.datapoints],
12786
- toZigbee: [tuya.tz.datapoints],
12787
- configure: tuya.configureMagicPacket,
12656
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
12788
12657
  exposes: [
12789
12658
  tuya.exposes.switch().withDescription("All Switches"),
12790
12659
  tuya.exposes.switch().withEndpoint("l1"),
@@ -12798,7 +12667,6 @@ exports.definitions = [
12798
12667
  tuya.exposes.countdown().withEndpoint("l4"),
12799
12668
  e.power_on_behavior(["off", "on", "previous"]).withAccess(ea.STATE_SET),
12800
12669
  ],
12801
- onEvent: tuya.onEventSetTime,
12802
12670
  endpoint: (device) => {
12803
12671
  return { l1: 1, l2: 1, l3: 1, l4: 1, state: 1, backlight: 1 };
12804
12672
  },
@@ -13630,8 +13498,7 @@ exports.definitions = [
13630
13498
  description: "Bidirectional energy meter with 80A current clamp",
13631
13499
  fromZigbee: [fzLocal.PJ1203A_strict_fz_datapoints, fzLocal.PJ1203A_sync_time_increase_seq],
13632
13500
  toZigbee: [tuya.tz.datapoints],
13633
- onEvent: tuya.onEventSetTime,
13634
- configure: tuya.configureMagicPacket,
13501
+ extend: [tuya.modernExtend.tuyaBase({ timeStart: "2000" })],
13635
13502
  options: [
13636
13503
  e
13637
13504
  .binary("late_energy_flow_a", ea.SET, true, false)
@@ -13705,10 +13572,7 @@ exports.definitions = [
13705
13572
  model: "PC311-Z-TY",
13706
13573
  vendor: "Tuya",
13707
13574
  description: "Bidirectional energy meter with 80A current clamp",
13708
- fromZigbee: [tuya.fz.datapoints],
13709
- toZigbee: [tuya.tz.datapoints],
13710
- onEvent: tuya.onEventSetTime,
13711
- configure: tuya.configureMagicPacket,
13575
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
13712
13576
  exposes: [
13713
13577
  e.ac_frequency(),
13714
13578
  e.voltage(),
@@ -13754,10 +13618,7 @@ exports.definitions = [
13754
13618
  model: "TYBAC-006",
13755
13619
  vendor: "Tuya",
13756
13620
  description: "Wall-mount thermostat for 2-pipe fan-coil unit",
13757
- fromZigbee: [tuya.fz.datapoints],
13758
- toZigbee: [tuya.tz.datapoints],
13759
- onEvent: tuya.onEventSetLocalTime,
13760
- configure: tuya.configureMagicPacket,
13621
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
13761
13622
  options: [
13762
13623
  e
13763
13624
  .enum("control_sequence_of_operation", ea.SET, ["cooling_only", "cooling_and_heating_4-pipes"])
@@ -13883,10 +13744,7 @@ exports.definitions = [
13883
13744
  model: "rtsc11r",
13884
13745
  vendor: "Tuya",
13885
13746
  description: "5.8G human presence sensor with relay",
13886
- configure: tuya.configureMagicPacket,
13887
- fromZigbee: [tuya.fz.datapoints],
13888
- toZigbee: [tuya.tz.datapoints],
13889
- onEvent: tuya.onEventSetTime,
13747
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
13890
13748
  exposes: [
13891
13749
  e.presence(),
13892
13750
  e.illuminance().withUnit("lx"),
@@ -14004,21 +13862,27 @@ exports.definitions = [
14004
13862
  vendor: "Tuya",
14005
13863
  description: "Smart WiFi Zigbee chlorine meter",
14006
13864
  whiteLabel: [tuya.whitelabel("Tuya", "YK-S03", "Smart pH and Chlorine Tester for Swimming Pool", ["_TZE200_d9mzkhoq"])],
14007
- fromZigbee: [tuya.fz.datapoints],
14008
- toZigbee: [tuya.tz.datapoints],
14009
13865
  // Don't query too often. Values are not always updated. https://github.com/Koenkk/zigbee2mqtt/issues/18704
14010
- onEvent: tuya.onEvent({
14011
- queryOnDeviceAnnounce: true,
14012
- // https://github.com/Koenkk/zigbee2mqtt/issues/23946#issuecomment-2941182834
14013
- queryIntervalSeconds: 20 * 60,
14014
- }),
14015
- configure: async (device, coordinatorEndpoint) => {
14016
- await tuya.configureMagicPacket(device, coordinatorEndpoint);
14017
- const endpoint = device.endpoints[0];
14018
- // Needed to make the device report reliable
14019
- // https://github.com/Koenkk/zigbee2mqtt/issues/18704#issuecomment-3109695384
14020
- await endpoint.write("genBasic", { 65502: { value: 0x13, type: zigbee_herdsman_1.Zcl.DataType.UINT8 } });
14021
- },
13866
+ extend: [
13867
+ tuya.modernExtend.tuyaBase({
13868
+ dp: true,
13869
+ queryOnDeviceAnnounce: true,
13870
+ // https://github.com/Koenkk/zigbee2mqtt/issues/23946#issuecomment-2941182834
13871
+ queryIntervalSeconds: 10 * 60,
13872
+ }),
13873
+ m.poll({
13874
+ key: "backlight",
13875
+ defaultIntervalSeconds: 30 * 60,
13876
+ poll: async (device) => {
13877
+ // Set backlight ever 30 mins, otherwise device stops updating.
13878
+ // https://github.com/Koenkk/zigbee2mqtt/issues/23946#issuecomment-3176121660
13879
+ const ep = device.getEndpoint(1);
13880
+ await tuya.sendDataPointValue(ep, 105, 0, "dataRequest", 1);
13881
+ await utils.sleep(2000);
13882
+ await tuya.sendDataPointValue(ep, 105, 0, "dataRequest", 0);
13883
+ },
13884
+ }),
13885
+ ],
14022
13886
  exposes: [
14023
13887
  e.numeric("tds", ea.STATE).withUnit("ppm").withDescription("Total Dissolved Solids"),
14024
13888
  e.temperature(),
@@ -14079,11 +13943,8 @@ exports.definitions = [
14079
13943
  .withDescription("Free Chlorine minimal value")
14080
13944
  .withValueMin(0)
14081
13945
  .withValueMax(15),
14082
- e
14083
- .numeric("salinity", ea.STATE)
14084
- .withUnit("ppm")
14085
- .withDescription("Salt value"),
14086
- // e.numeric('backlightvalue', ea.STATE).withUnit('gg').withDescription('Backlight Value'),
13946
+ e.numeric("salinity", ea.STATE).withUnit("ppm").withDescription("Salt value"),
13947
+ e.numeric("backlightvalue", ea.STATE_SET).withUnit("gg").withDescription("Backlight Value").withValueMin(0).withValueMax(1),
14087
13948
  ],
14088
13949
  meta: {
14089
13950
  // All datapoints go in here
@@ -14091,19 +13952,19 @@ exports.definitions = [
14091
13952
  [1, "tds", tuya.valueConverter.raw],
14092
13953
  [2, "temperature", tuya.valueConverter.divideBy10],
14093
13954
  [7, "battery", tuya.valueConverter.raw],
14094
- [10, "ph", tuya.valueConverter.divideBy100],
13955
+ [10, "ph", tuya.valueConverter.divideBy10],
14095
13956
  [11, "ec", tuya.valueConverter.raw],
14096
13957
  [101, "orp", tuya.valueConverter.raw],
14097
- [102, "free_chlorine", tuya.valueConverter.divideBy10],
14098
- // [105, 'backlightvalue', tuya.valueConverter.raw],
13958
+ [102, "free_chlorine", tuya.valueConverter.raw],
13959
+ [105, "backlightvalue", tuya.valueConverter.raw],
14099
13960
  [106, "ph_max", tuya.valueConverter.divideBy10],
14100
13961
  [107, "ph_min", tuya.valueConverter.divideBy10],
14101
13962
  [108, "ec_max", tuya.valueConverter.raw],
14102
13963
  [109, "ec_min", tuya.valueConverter.raw],
14103
13964
  [110, "orp_max", tuya.valueConverter.raw],
14104
13965
  [111, "orp_min", tuya.valueConverter.raw],
14105
- [112, "free_chlorine_max", tuya.valueConverter.divideBy10],
14106
- [113, "free_chlorine_min", tuya.valueConverter.divideBy10],
13966
+ [112, "free_chlorine_max", tuya.valueConverter.raw],
13967
+ [113, "free_chlorine_min", tuya.valueConverter.raw],
14107
13968
  [117, "salinity", tuya.valueConverter.raw],
14108
13969
  ],
14109
13970
  },
@@ -14113,10 +13974,7 @@ exports.definitions = [
14113
13974
  model: "SP02-ZB001",
14114
13975
  vendor: "iAlarm",
14115
13976
  description: "Infrared motion sensor",
14116
- fromZigbee: [tuya.fz.datapoints],
14117
- toZigbee: [tuya.tz.datapoints],
14118
- onEvent: tuya.onEventSetTime,
14119
- configure: tuya.configureMagicPacket,
13977
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
14120
13978
  exposes: [e.tamper(), e.battery(), e.occupancy()],
14121
13979
  meta: {
14122
13980
  tuyaDatapoints: [
@@ -14148,10 +14006,7 @@ exports.definitions = [
14148
14006
  model: "DCR-RQJ",
14149
14007
  vendor: "Tuya",
14150
14008
  description: "Carbon monoxide sensor gas leak detector",
14151
- fromZigbee: [tuya.fz.datapoints],
14152
- toZigbee: [tuya.tz.datapoints],
14153
- onEvent: tuya.onEventSetTime,
14154
- configure: tuya.configureMagicPacket,
14009
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
14155
14010
  exposes: [e.gas(), tuya.exposes.gasValue().withUnit("LEL %"), e.carbon_monoxide(), e.co()],
14156
14011
  meta: {
14157
14012
  tuyaDatapoints: [
@@ -14181,10 +14036,7 @@ exports.definitions = [
14181
14036
  model: "SZR07U",
14182
14037
  vendor: "Tuya",
14183
14038
  description: "24GHz millimeter wave radar",
14184
- configure: tuya.configureMagicPacket,
14185
- fromZigbee: [tuya.fz.datapoints],
14186
- toZigbee: [tuya.tz.datapoints],
14187
- onEvent: tuya.onEventSetTime,
14039
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
14188
14040
  exposes: [
14189
14041
  e.presence(),
14190
14042
  e
@@ -14275,13 +14127,7 @@ exports.definitions = [
14275
14127
  model: "TOWSMR1",
14276
14128
  vendor: "Tongou",
14277
14129
  description: "Single-phase multifunction RCBO (DIN Module)",
14278
- fromZigbee: [tuya.fz.datapoints, tuya.fz.gateway_connection_status],
14279
- toZigbee: [tuya.tz.datapoints],
14280
- configure: async (device, coordinatorEndpoint) => {
14281
- await tuya.configureMagicPacket(device, coordinatorEndpoint);
14282
- // Required to get the device to start reporting
14283
- await device.getEndpoint(1).command("manuSpecificTuya", "dataQuery", {});
14284
- },
14130
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, queryOnConfigure: true, queryIntervalSeconds: 10, respondToMcuVersionResponse: false })],
14285
14131
  whiteLabel: [tuya.whitelabel("Tongou", "TOSA1", "Single-phase multifunction RCBO (DIN Module)", ["_TZE284_432zhuwe"])],
14286
14132
  exposes: [
14287
14133
  tuya.exposes.switch(),
@@ -14483,27 +14329,13 @@ exports.definitions = [
14483
14329
  [145, "overpower_recloser", tuya.valueConverter.onOff],
14484
14330
  ],
14485
14331
  },
14486
- onEvent: tuya.onEvent({
14487
- respondToMcuVersionResponse: false,
14488
- queryIntervalSeconds: 10,
14489
- }),
14490
14332
  },
14491
14333
  {
14492
14334
  fingerprint: [{ modelID: "TS0601", manufacturerName: "_TZE284_6ocnqlhn" }],
14493
14335
  model: "TO-Q-SYS-JZT",
14494
14336
  vendor: "Tongou",
14495
14337
  description: "Din rail smart meter",
14496
- fromZigbee: [tuya.fz.datapoints, tuya.fz.gateway_connection_status],
14497
- toZigbee: [tuya.tz.datapoints],
14498
- onEvent: tuya.onEvent({
14499
- respondToMcuVersionResponse: false,
14500
- queryIntervalSeconds: 10,
14501
- }),
14502
- configure: async (device, coordinatorEndpoint) => {
14503
- await tuya.configureMagicPacket(device, coordinatorEndpoint);
14504
- // Required to get the device to start reporting
14505
- await device.getEndpoint(1).command("manuSpecificTuya", "dataQuery", {});
14506
- },
14338
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, queryOnConfigure: true, queryIntervalSeconds: 10, respondToMcuVersionResponse: false })],
14507
14339
  exposes: [
14508
14340
  tuya.exposes.switch(),
14509
14341
  e.power(),
@@ -14685,9 +14517,7 @@ exports.definitions = [
14685
14517
  model: "EA4161C-BI",
14686
14518
  vendor: "Tuya",
14687
14519
  description: "Single-phase multifunction energy meter (DIN Module)",
14688
- fromZigbee: [tuya.fz.datapoints, tuya.fz.gateway_connection_status],
14689
- toZigbee: [tuya.tz.datapoints],
14690
- configure: tuya.configureMagicPacket,
14520
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
14691
14521
  exposes: [e.current(), e.power(), e.voltage(), e.energy(), e.text("meter_id", ea.STATE).withDescription("Meter ID (ID of device)")],
14692
14522
  meta: {
14693
14523
  tuyaDatapoints: [
@@ -14729,12 +14559,9 @@ exports.definitions = [
14729
14559
  fingerprint: tuya.fingerprint("TS0601", ["_TZE200_pl31aqf5", "_TZE200_xpvamyfz", "_TZE284_xpvamyfz"]),
14730
14560
  model: "ZR360CDB",
14731
14561
  vendor: "Zorro Alert",
14732
- fromZigbee: [tuya.fz.datapoints],
14733
- toZigbee: [tuya.tz.datapoints],
14734
14562
  description: "Multifunctional CO2 detector",
14563
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
14735
14564
  whiteLabel: [tuya.whitelabel("Nous", "E10", "Multifunctional CO2 detector", ["_TZE200_xpvamyfz", "_TZE284_xpvamyfz"])],
14736
- onEvent: tuya.onEventSetTime,
14737
- configure: tuya.configureMagicPacket,
14738
14565
  exposes: [
14739
14566
  e.humidity(),
14740
14567
  e.temperature(),
@@ -14793,10 +14620,7 @@ exports.definitions = [
14793
14620
  model: "TS0601_floor_thermostat",
14794
14621
  vendor: "Tuya",
14795
14622
  description: "Zigbee thermostat for electric floors",
14796
- fromZigbee: [tuya.fz.datapoints],
14797
- toZigbee: [tuya.tz.datapoints],
14798
- onEvent: tuya.onEventSetTime, // Add this if you are getting no converter for 'commandMcuSyncTime'
14799
- configure: tuya.configureMagicPacket,
14623
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
14800
14624
  exposes: [
14801
14625
  e
14802
14626
  .climate()
@@ -14846,10 +14670,7 @@ exports.definitions = [
14846
14670
  model: "TE-1Z",
14847
14671
  vendor: "Tuya",
14848
14672
  description: "Floor heating thermostat",
14849
- fromZigbee: [tuya.fz.datapoints],
14850
- toZigbee: [tuya.tz.datapoints],
14851
- onEvent: tuya.onEventSetTime,
14852
- configure: tuya.configureMagicPacket,
14673
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
14853
14674
  exposes: [
14854
14675
  // e.binary('system_mode', ea.STATE_SET, 'ON', 'OFF')
14855
14676
  // .withDescription('Turn system on or standby mode'),
@@ -14958,10 +14779,7 @@ exports.definitions = [
14958
14779
  model: "PRO-900Z",
14959
14780
  vendor: "ElectSmart",
14960
14781
  description: "Thermostat for electric floor",
14961
- fromZigbee: [tuya.fz.datapoints],
14962
- toZigbee: [tuya.tz.datapoints],
14963
- onEvent: tuya.onEventSetTime,
14964
- configure: tuya.configureMagicPacket,
14782
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
14965
14783
  exposes: [
14966
14784
  e.binary("child_lock", ea.STATE_SET, "ON", "OFF").withLabel("Child lock"),
14967
14785
  e.binary("eco_mode", ea.STATE_SET, "OFF", "ON").withLabel("ECO mode").withDescription("Default: Off"),
@@ -15120,10 +14938,7 @@ exports.definitions = [
15120
14938
  model: "ZPV-01",
15121
14939
  vendor: "Novato",
15122
14940
  description: "Battery powered smart valve",
15123
- fromZigbee: [tuya.fz.datapoints],
15124
- toZigbee: [tuya.tz.datapoints],
15125
- onEvent: tuya.onEventSetTime,
15126
- configure: tuya.configureMagicPacket,
14941
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
15127
14942
  exposes: [
15128
14943
  e.switch().setAccess("state", ea.STATE_SET),
15129
14944
  e.enum("valve_state", ea.STATE, ["Closed", "Unknown", "Open"]).withDescription("Valve Status"),
@@ -15286,15 +15101,9 @@ exports.definitions = [
15286
15101
  model: "TOQCB2-80",
15287
15102
  vendor: "Tongou",
15288
15103
  description: "Smart circuit breaker",
15289
- fromZigbee: [tuya.fz.datapoints],
15290
- toZigbee: [tuya.tz.datapoints],
15291
15104
  // Important: respondToMcuVersionResponse should be false otherwise there is an avalanche of commandMcuVersionResponse messages every second.
15292
15105
  // queryIntervalSeconds: is doing a pooling to update the device's parameters, now defined to update data every 3 minutes.
15293
- onEvent: tuya.onEvent({
15294
- respondToMcuVersionResponse: false,
15295
- queryIntervalSeconds: 3 * 60,
15296
- }),
15297
- configure: tuya.configureMagicPacket,
15106
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, queryIntervalSeconds: 3 * 60, respondToMcuVersionResponse: false })],
15298
15107
  exposes: [
15299
15108
  tuya.exposes.switch(),
15300
15109
  e.energy(),
@@ -15473,10 +15282,7 @@ exports.definitions = [
15473
15282
  model: "ZY-M100-S_3",
15474
15283
  vendor: "Tuya",
15475
15284
  description: "Human presence detector",
15476
- fromZigbee: [tuya.fz.datapoints],
15477
- toZigbee: [tuya.tz.datapoints],
15478
- onEvent: tuya.onEventSetTime,
15479
- configure: tuya.configureMagicPacket,
15285
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
15480
15286
  exposes: [
15481
15287
  e.presence(),
15482
15288
  e.illuminance(),
@@ -15515,9 +15321,7 @@ exports.definitions = [
15515
15321
  model: "ZG-205Z",
15516
15322
  vendor: "Tuya",
15517
15323
  description: "5.8 GHz human presence sensor",
15518
- fromZigbee: [tuya.fz.datapoints],
15519
- toZigbee: [tuya.tz.datapoints],
15520
- onEvent: tuya.onEventSetTime,
15324
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
15521
15325
  exposes: [
15522
15326
  e.presence(),
15523
15327
  e
@@ -15597,18 +15401,10 @@ exports.definitions = [
15597
15401
  null,
15598
15402
  {
15599
15403
  from: (v) => {
15600
- const lookup = {
15601
- none: tuya.enum(0),
15602
- presence: tuya.enum(1),
15603
- peaceful: tuya.enum(2),
15604
- small_movement: tuya.enum(3),
15605
- large_movement: tuya.enum(4),
15606
- };
15607
- const presenceState = Object.entries(lookup).find((i) => i[1].valueOf() === v)[0];
15608
- return {
15609
- presence: presenceState !== "none",
15610
- presence_state: presenceState,
15611
- };
15404
+ if (v > 99) {
15405
+ return v / 10;
15406
+ }
15407
+ return v / 100;
15612
15408
  },
15613
15409
  },
15614
15410
  ],
@@ -15683,7 +15479,7 @@ exports.definitions = [
15683
15479
  },
15684
15480
  },
15685
15481
  {
15686
- fingerprint: tuya.fingerprint("TS0601", ["_TZE204_zqq3cipq"]),
15482
+ fingerprint: tuya.fingerprint("TS0601", ["_TZE204_zqq3cipq", "_TZE284_zqq3cipq"]),
15687
15483
  model: "PN16",
15688
15484
  vendor: "ZSVIOT",
15689
15485
  description: "16-way controller",
@@ -16347,10 +16143,7 @@ exports.definitions = [
16347
16143
  model: "TS0601_GTZ10",
16348
16144
  vendor: "Tuya",
16349
16145
  description: "Thermostat radiator valve",
16350
- fromZigbee: [tuya.fz.datapoints],
16351
- toZigbee: [tuya.tz.datapoints],
16352
- onEvent: tuya.onEventSetLocalTime,
16353
- configure: tuya.configureMagicPacket,
16146
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
16354
16147
  ota: true,
16355
16148
  exposes: [
16356
16149
  e.battery(),
@@ -16517,10 +16310,7 @@ exports.definitions = [
16517
16310
  model: "ME201WZ",
16518
16311
  vendor: "Tuya",
16519
16312
  description: "Water level sensor",
16520
- fromZigbee: [tuya.fz.datapoints],
16521
- toZigbee: [tuya.tz.datapoints],
16522
- onEvent: tuya.onEventSetLocalTime,
16523
- configure: tuya.configureMagicPacket,
16313
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
16524
16314
  exposes: [
16525
16315
  e.numeric("liquid_level_percent", ea.STATE).withUnit("%").withDescription("Liquid level ratio"),
16526
16316
  e.numeric("liquid_depth", ea.STATE).withUnit("m").withDescription("Liquid Depth"),
@@ -16579,11 +16369,7 @@ exports.definitions = [
16579
16369
  model: "TLC2206",
16580
16370
  vendor: "Tuya",
16581
16371
  description: "Water level sensor",
16582
- extend: [m.forcePowerSource({ powerSource: "Mains (single phase)" })],
16583
- fromZigbee: [tuya.fz.datapoints],
16584
- toZigbee: [tuya.tz.datapoints],
16585
- onEvent: tuya.onEventSetLocalTime,
16586
- configure: tuya.configureMagicPacket,
16372
+ extend: [m.forcePowerSource({ powerSource: "Mains (single phase)" }), tuya.modernExtend.tuyaBase({ dp: true, forceTimeUpdates: true })],
16587
16373
  exposes: [
16588
16374
  e.numeric("liquid_level_percent", ea.STATE).withUnit("%").withDescription("Liquid level ratio"),
16589
16375
  e.numeric("liquid_depth", ea.STATE).withUnit("cm").withDescription("Liquid depth"),
@@ -16642,10 +16428,7 @@ exports.definitions = [
16642
16428
  model: "HHST001",
16643
16429
  vendor: "HeatHUB",
16644
16430
  description: "Fan coil thermostat",
16645
- fromZigbee: [tuya.fz.datapoints],
16646
- toZigbee: [tuya.tz.datapoints],
16647
- onEvent: tuya.onEventSetTime,
16648
- configure: tuya.configureMagicPacket,
16431
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
16649
16432
  exposes: [
16650
16433
  e.binary("state", ea.STATE_SET, "ON", "OFF").withDescription("Turn the thermostat ON/OFF"),
16651
16434
  e
@@ -17414,10 +17197,7 @@ exports.definitions = [
17414
17197
  model: "AE-940K",
17415
17198
  vendor: "ACMELEC",
17416
17199
  description: "Compatible with Daikin vrv system",
17417
- fromZigbee: [tuya.fz.datapoints],
17418
- toZigbee: [tuya.tz.datapoints],
17419
- onEvent: tuya.onEventSetTime,
17420
- configure: tuya.configureMagicPacket,
17200
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
17421
17201
  exposes: [
17422
17202
  e.binary("state", ea.STATE_SET, "ON", "OFF").withDescription("Turn the thermostat ON/OFF"),
17423
17203
  e
@@ -17461,10 +17241,7 @@ exports.definitions = [
17461
17241
  model: "AE-669K",
17462
17242
  vendor: "ACMELEC",
17463
17243
  description: "Compatible with Mitsubishi Electric vrf system",
17464
- fromZigbee: [tuya.fz.datapoints],
17465
- toZigbee: [tuya.tz.datapoints],
17466
- onEvent: tuya.onEventSetTime,
17467
- configure: tuya.configureMagicPacket,
17244
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
17468
17245
  exposes: [
17469
17246
  e.binary("state", ea.STATE_SET, "ON", "OFF").withDescription("Turn the thermostat ON/OFF"),
17470
17247
  e
@@ -17738,10 +17515,7 @@ exports.definitions = [
17738
17515
  model: "HY-SZLUMPIR",
17739
17516
  vendor: "Homcloud",
17740
17517
  description: "PIR sensor",
17741
- fromZigbee: [tuya.fz.datapoints],
17742
- toZigbee: [tuya.tz.datapoints],
17743
- onEvent: tuya.onEvent(),
17744
- configure: tuya.configureMagicPacket,
17518
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
17745
17519
  exposes: [e.occupancy(), e.illuminance(), e.battery()],
17746
17520
  meta: {
17747
17521
  tuyaDatapoints: [
@@ -17756,10 +17530,7 @@ exports.definitions = [
17756
17530
  model: "XZ-AKT101",
17757
17531
  vendor: "Tuya",
17758
17532
  description: "Intelligent air conditioning wall switch",
17759
- fromZigbee: [tuya.fz.datapoints],
17760
- toZigbee: [tuya.tz.datapoints],
17761
- onEvent: tuya.onEventSetTime,
17762
- configure: tuya.configureMagicPacket,
17533
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
17763
17534
  ota: true,
17764
17535
  exposes: [
17765
17536
  e.binary("air_switch", ea.STATE_SET, true, false),
@@ -17904,10 +17675,7 @@ exports.definitions = [
17904
17675
  model: "EPJ-ZB",
17905
17676
  vendor: "Nova Digital",
17906
17677
  description: "Smart sliding window pusher",
17907
- fromZigbee: [tuya.fz.datapoints],
17908
- toZigbee: [tuya.tz.datapoints],
17909
- onEvent: tuya.onEventSetTime,
17910
- configure: tuya.configureMagicPacket,
17678
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
17911
17679
  exposes: [
17912
17680
  e.battery(),
17913
17681
  e.cover_position(),
@@ -18074,10 +17842,7 @@ exports.definitions = [
18074
17842
  model: "RD24G01",
18075
17843
  vendor: "Tuya",
18076
17844
  description: "24GHz human presence sensor",
18077
- fromZigbee: [tuya.fz.datapoints],
18078
- toZigbee: [tuya.tz.datapoints],
18079
- onEvent: tuya.onEventSetTime,
18080
- configure: tuya.configureMagicPacket,
17845
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
18081
17846
  exposes: [
18082
17847
  exposes
18083
17848
  .enum("presence_state", exposes.access.STATE, ["none", "motion", "stationary"])
@@ -18126,10 +17891,7 @@ exports.definitions = [
18126
17891
  model: "M515EGBZTN",
18127
17892
  vendor: "Quoya",
18128
17893
  description: "Zigbee roller blind",
18129
- fromZigbee: [tuya.fz.datapoints],
18130
- toZigbee: [tuya.tz.datapoints],
18131
- onEvent: tuya.onEventSetTime,
18132
- configure: tuya.configureMagicPacket,
17894
+ extend: [tuya.modernExtend.tuyaBase({ dp: true, timeStart: "2000" })],
18133
17895
  options: [exposes.options.invert_cover()],
18134
17896
  exposes: [
18135
17897
  e.cover_position().setAccess("position", ea.STATE_SET),