zigbee-herdsman-converters 25.91.0 → 25.93.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 (56) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/converters/fromZigbee.js +2 -2
  3. package/dist/converters/fromZigbee.js.map +1 -1
  4. package/dist/devices/dresden_elektronik.d.ts.map +1 -1
  5. package/dist/devices/dresden_elektronik.js +16 -6
  6. package/dist/devices/dresden_elektronik.js.map +1 -1
  7. package/dist/devices/ezviz.d.ts +3 -0
  8. package/dist/devices/ezviz.d.ts.map +1 -0
  9. package/dist/devices/ezviz.js +47 -0
  10. package/dist/devices/ezviz.js.map +1 -0
  11. package/dist/devices/gewiss.d.ts.map +1 -1
  12. package/dist/devices/gewiss.js +2 -1
  13. package/dist/devices/gewiss.js.map +1 -1
  14. package/dist/devices/gledopto.js +1 -1
  15. package/dist/devices/gledopto.js.map +1 -1
  16. package/dist/devices/heiman.d.ts.map +1 -1
  17. package/dist/devices/heiman.js +948 -256
  18. package/dist/devices/heiman.js.map +1 -1
  19. package/dist/devices/index.d.ts.map +1 -1
  20. package/dist/devices/index.js +2 -0
  21. package/dist/devices/index.js.map +1 -1
  22. package/dist/devices/inovelli.js +1 -1
  23. package/dist/devices/inovelli.js.map +1 -1
  24. package/dist/devices/ledvance.d.ts.map +1 -1
  25. package/dist/devices/ledvance.js +14 -20
  26. package/dist/devices/ledvance.js.map +1 -1
  27. package/dist/devices/lightsolutions.d.ts.map +1 -1
  28. package/dist/devices/lightsolutions.js +7 -0
  29. package/dist/devices/lightsolutions.js.map +1 -1
  30. package/dist/devices/lumi.d.ts.map +1 -1
  31. package/dist/devices/lumi.js +28 -34
  32. package/dist/devices/lumi.js.map +1 -1
  33. package/dist/devices/moes.d.ts.map +1 -1
  34. package/dist/devices/moes.js +98 -0
  35. package/dist/devices/moes.js.map +1 -1
  36. package/dist/devices/muller_licht.d.ts.map +1 -1
  37. package/dist/devices/muller_licht.js +7 -0
  38. package/dist/devices/muller_licht.js.map +1 -1
  39. package/dist/devices/philips.d.ts.map +1 -1
  40. package/dist/devices/philips.js +31 -13
  41. package/dist/devices/philips.js.map +1 -1
  42. package/dist/devices/sonoff.d.ts.map +1 -1
  43. package/dist/devices/sonoff.js +45 -53
  44. package/dist/devices/sonoff.js.map +1 -1
  45. package/dist/devices/tuya.d.ts.map +1 -1
  46. package/dist/devices/tuya.js +479 -17
  47. package/dist/devices/tuya.js.map +1 -1
  48. package/dist/lib/lumi.d.ts +2 -0
  49. package/dist/lib/lumi.d.ts.map +1 -1
  50. package/dist/lib/lumi.js +137 -0
  51. package/dist/lib/lumi.js.map +1 -1
  52. package/dist/lib/modernExtend.d.ts.map +1 -1
  53. package/dist/lib/modernExtend.js +3 -3
  54. package/dist/lib/modernExtend.js.map +1 -1
  55. package/dist/models-index.json +1 -1
  56. package/package.json +3 -3
@@ -412,6 +412,40 @@ const convLocal = {
412
412
  },
413
413
  },
414
414
  };
415
+ // TS0601_smart_scene_knob constants and helpers //
416
+ // 4 physical buttons with knob rotation, 3 modes: Scene (DP 1-4), Light (ZCL), Curtain (DP broadcast)
417
+ // Mode switch: hold button 2 or 4 for 5 seconds (only cycles through bound modes)
418
+ // Group ID pattern: base + (button-1) * 20, detected from first button press
419
+ const modeScene = 0x01;
420
+ const modeLight = 0x03;
421
+ const modeCurtain = 0x04;
422
+ const groupIdOffset = 20;
423
+ const statusUnassigned = "unassigned";
424
+ const statusWaiting = "waiting_button_1";
425
+ const statusReady = "ready";
426
+ const getButtonFromGroupId = (groupId, baseGroupId) => {
427
+ if (!baseGroupId || !groupId)
428
+ return null;
429
+ const offset = groupId - baseGroupId;
430
+ if (offset >= 0 && offset % groupIdOffset === 0) {
431
+ const button = Math.floor(offset / groupIdOffset) + 1;
432
+ if (button >= 1 && button <= 4)
433
+ return button;
434
+ }
435
+ return null;
436
+ };
437
+ // DP 102 payload: [0x01, 0x01, mode, ...name(12 bytes), ...suffix(4 bytes)]
438
+ // Suffix: slot number at position (slot-1), rest 0xff
439
+ const bindSlotTS0601SmartSceneKnob = async (entity, slot, mode) => {
440
+ const modeNames = { [modeScene]: "Scene", [modeLight]: "Light", [modeCurtain]: "Curtain" };
441
+ const slotName = `${modeNames[mode] || "Scene"} ${slot}`;
442
+ const nameBuffer = Buffer.alloc(12, 0);
443
+ nameBuffer.write(slotName, "utf8");
444
+ const suffix = Buffer.from([0xff, 0xff, 0xff, 0xff]);
445
+ suffix[slot - 1] = slot;
446
+ const payload = Buffer.concat([Buffer.from([0x01, 0x01, mode]), nameBuffer, suffix]);
447
+ await tuya.sendDataPointRaw(entity, 102, payload, "dataRequest", 0x10 + (slot - 1));
448
+ };
415
449
  const tzLocal = {
416
450
  ts0049_countdown: {
417
451
  key: ["water_countdown"],
@@ -797,6 +831,56 @@ const tzLocal = {
797
831
  return { state: { backlight_mode: value } };
798
832
  },
799
833
  },
834
+ // TS0601_smart_scene_knob //
835
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
836
+ TS0601_smart_scene_knob_bind_all: {
837
+ key: ["bind_all_scene", "bind_all_light", "bind_all_curtain"],
838
+ convertSet: async (entity, key, value, meta) => {
839
+ const modes = {
840
+ bind_all_scene: modeScene,
841
+ bind_all_light: modeLight,
842
+ bind_all_curtain: modeCurtain,
843
+ };
844
+ const mode = modes[key];
845
+ for (let slot = 1; slot <= 4; slot++) {
846
+ await bindSlotTS0601SmartSceneKnob(entity, slot, mode);
847
+ if (slot < 4)
848
+ await new Promise((resolve) => setTimeout(resolve, 500));
849
+ }
850
+ // Scene mode doesn't use Group ID
851
+ if (key === "bind_all_scene") {
852
+ return {};
853
+ }
854
+ const currentStatus = meta.state?.assignment_status;
855
+ const baseGroupId = meta.state?.base_group_id;
856
+ if (currentStatus !== statusReady || !baseGroupId) {
857
+ return { state: { assignment_status: statusWaiting } };
858
+ }
859
+ return {};
860
+ },
861
+ },
862
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
863
+ TS0601_smart_scene_knob_assign_button_1: {
864
+ key: ["assign_button_1"],
865
+ convertSet: (entity, key, value, meta) => {
866
+ return { state: { assignment_status: statusWaiting } };
867
+ },
868
+ },
869
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
870
+ TS0601_smart_scene_knob_set_base_group_id: {
871
+ key: ["set_base_group_id"],
872
+ convertSet: (entity, key, value, meta) => {
873
+ const baseGroupId = Number.parseInt(value, 10);
874
+ if (Number.isNaN(baseGroupId) || baseGroupId < 1 || baseGroupId > 65000)
875
+ return {};
876
+ return {
877
+ state: {
878
+ base_group_id: baseGroupId,
879
+ assignment_status: statusReady,
880
+ },
881
+ };
882
+ },
883
+ },
800
884
  };
801
885
  const fzLocal = {
802
886
  TLSR82xxAction: {
@@ -1048,6 +1132,208 @@ const fzLocal = {
1048
1132
  }
1049
1133
  },
1050
1134
  },
1135
+ // TS0601_smart_scene_knob //
1136
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
1137
+ TS0601_smart_scene_knob_light_onoff: {
1138
+ cluster: "genOnOff",
1139
+ type: ["commandOn", "commandOff"],
1140
+ convert: (model, msg, publish, options, meta) => {
1141
+ const groupId = msg.groupID;
1142
+ if (!groupId)
1143
+ return;
1144
+ const baseGroupId = meta.state?.base_group_id;
1145
+ const status = meta.state?.assignment_status || statusUnassigned;
1146
+ const command = msg.type === "commandOn" ? "on" : "off";
1147
+ if (status === statusWaiting) {
1148
+ return {
1149
+ base_group_id: groupId,
1150
+ assignment_status: statusReady,
1151
+ action: `light_1_${command}`,
1152
+ action_group: groupId,
1153
+ action_button: 1,
1154
+ };
1155
+ }
1156
+ if (status === statusReady && baseGroupId) {
1157
+ const button = getButtonFromGroupId(groupId, baseGroupId);
1158
+ if (!button)
1159
+ return;
1160
+ return {
1161
+ action: `light_${button}_${command}`,
1162
+ action_group: groupId,
1163
+ action_button: button,
1164
+ };
1165
+ }
1166
+ return { action_group: groupId, assignment_status: statusUnassigned };
1167
+ },
1168
+ },
1169
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
1170
+ TS0601_smart_scene_knob_light_brightness: {
1171
+ cluster: "genLevelCtrl",
1172
+ type: ["commandMoveToLevelWithOnOff", "commandMoveToLevel"],
1173
+ convert: (model, msg, publish, options, meta) => {
1174
+ const groupId = msg.groupID;
1175
+ if (!groupId)
1176
+ return;
1177
+ const baseGroupId = meta.state?.base_group_id;
1178
+ const status = meta.state?.assignment_status || statusUnassigned;
1179
+ const level = msg.data.level;
1180
+ const prevBrightness = meta.state?.brightness;
1181
+ const prevDirection = meta.state?.brightness_direction;
1182
+ let direction = "";
1183
+ if (prevBrightness !== undefined) {
1184
+ if (level > prevBrightness)
1185
+ direction = "_up";
1186
+ else if (level < prevBrightness)
1187
+ direction = "_down";
1188
+ else
1189
+ direction = prevDirection || "";
1190
+ }
1191
+ if (status === statusWaiting) {
1192
+ return {
1193
+ base_group_id: groupId,
1194
+ assignment_status: statusReady,
1195
+ action: `light_1_brightness${direction}`,
1196
+ action_group: groupId,
1197
+ action_button: 1,
1198
+ brightness: level,
1199
+ brightness_direction: direction,
1200
+ };
1201
+ }
1202
+ if (status === statusReady && baseGroupId) {
1203
+ const button = getButtonFromGroupId(groupId, baseGroupId);
1204
+ if (!button)
1205
+ return;
1206
+ return {
1207
+ action: `light_${button}_brightness${direction}`,
1208
+ action_group: groupId,
1209
+ action_button: button,
1210
+ brightness: level,
1211
+ brightness_direction: direction,
1212
+ };
1213
+ }
1214
+ return { action_group: groupId, brightness: level };
1215
+ },
1216
+ },
1217
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
1218
+ TS0601_smart_scene_knob_light_colortemp: {
1219
+ // Direction: higher mired = warmer = down, lower mired = cooler = up
1220
+ cluster: "lightingColorCtrl",
1221
+ type: ["commandMoveToColorTemp"],
1222
+ convert: (model, msg, publish, options, meta) => {
1223
+ const groupId = msg.groupID;
1224
+ if (!groupId)
1225
+ return;
1226
+ const baseGroupId = meta.state?.base_group_id;
1227
+ const status = meta.state?.assignment_status || statusUnassigned;
1228
+ const colortemp = msg.data.colortemp;
1229
+ const prevColortemp = meta.state?.color_temp;
1230
+ const prevDirection = meta.state?.color_temp_direction;
1231
+ let direction = "";
1232
+ if (prevColortemp !== undefined) {
1233
+ if (colortemp > prevColortemp)
1234
+ direction = "_down";
1235
+ else if (colortemp < prevColortemp)
1236
+ direction = "_up";
1237
+ else
1238
+ direction = prevDirection || "";
1239
+ }
1240
+ if (status === statusWaiting) {
1241
+ return {
1242
+ base_group_id: groupId,
1243
+ assignment_status: statusReady,
1244
+ action: `light_1_colortemp${direction}`,
1245
+ action_group: groupId,
1246
+ action_button: 1,
1247
+ color_temp: colortemp,
1248
+ color_temp_direction: direction,
1249
+ };
1250
+ }
1251
+ if (status === statusReady && baseGroupId) {
1252
+ const button = getButtonFromGroupId(groupId, baseGroupId);
1253
+ if (!button)
1254
+ return;
1255
+ return {
1256
+ action: `light_${button}_colortemp${direction}`,
1257
+ action_group: groupId,
1258
+ action_button: button,
1259
+ color_temp: colortemp,
1260
+ color_temp_direction: direction,
1261
+ };
1262
+ }
1263
+ return { action_group: groupId, color_temp: colortemp };
1264
+ },
1265
+ },
1266
+ // biome-ignore lint/style/useNamingConvention: ignored using `--suppress`
1267
+ TS0601_smart_scene_knob_curtain_command: {
1268
+ // DP 1: 0=start, 2=stop (1=init rotation, ignored)
1269
+ // DP 2: 4-byte big-endian position 0-100%
1270
+ cluster: "manuSpecificTuya",
1271
+ type: ["commandDataRequest"],
1272
+ convert: (model, msg, publish, options, meta) => {
1273
+ const groupId = msg.groupID;
1274
+ if (!groupId)
1275
+ return;
1276
+ const baseGroupId = meta.state?.base_group_id;
1277
+ const status = meta.state?.assignment_status || statusUnassigned;
1278
+ const dpValues = msg.data.dpValues;
1279
+ if (!dpValues || dpValues.length === 0)
1280
+ return;
1281
+ const dp = dpValues[0].dp;
1282
+ const data = dpValues[0].data;
1283
+ let action = null;
1284
+ let position = null;
1285
+ if (dp === 1) {
1286
+ const commands = { 0: "start", 2: "stop" };
1287
+ action = commands[data[0]] || null;
1288
+ }
1289
+ else if (dp === 2) {
1290
+ position = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
1291
+ const prevPosition = meta.state?.curtain_position;
1292
+ const prevDirection = meta.state?.curtain_position_direction;
1293
+ if (prevPosition !== undefined) {
1294
+ if (position > prevPosition)
1295
+ action = "position_open";
1296
+ else if (position < prevPosition)
1297
+ action = "position_close";
1298
+ else
1299
+ action = prevDirection ? `position${prevDirection}` : "position";
1300
+ }
1301
+ else {
1302
+ action = "position";
1303
+ }
1304
+ }
1305
+ if (!action)
1306
+ return;
1307
+ const result = { action_group: groupId };
1308
+ if (position !== null) {
1309
+ result.curtain_position = position;
1310
+ if (action.includes("_open"))
1311
+ result.curtain_position_direction = "_open";
1312
+ else if (action.includes("_close"))
1313
+ result.curtain_position_direction = "_close";
1314
+ }
1315
+ if (status === statusWaiting) {
1316
+ return {
1317
+ ...result,
1318
+ base_group_id: groupId,
1319
+ assignment_status: statusReady,
1320
+ action: `curtain_1_${action}`,
1321
+ action_button: 1,
1322
+ };
1323
+ }
1324
+ if (status === statusReady && baseGroupId) {
1325
+ const button = getButtonFromGroupId(groupId, baseGroupId);
1326
+ if (!button)
1327
+ return;
1328
+ return {
1329
+ ...result,
1330
+ action: `curtain_${button}_${action}`,
1331
+ action_button: button,
1332
+ };
1333
+ }
1334
+ return result;
1335
+ },
1336
+ },
1051
1337
  };
1052
1338
  exports.definitions = [
1053
1339
  {
@@ -2672,6 +2958,7 @@ exports.definitions = [
2672
2958
  "_TZ3210_wbsgmojq",
2673
2959
  ]),
2674
2960
  tuya.whitelabel("Moes", "ZB-TDC6-RCW-E14", "RGB+CCT 5W E14 LED bulb", ["_TZ3210_ifga63rg"]),
2961
+ tuya.whitelabel("Moes", "ZB-TDD6-RCW-4", "RGB+CCT 6W Smart Downlight", ["_TZ3210_b8jdosxo"]),
2675
2962
  tuya.whitelabel("MiBoxer", "E3-ZR", "3 in 1 LED Controller", ["_TZB210_wy1pyu1q", "_TZB210_yatkpuha"]),
2676
2963
  tuya.whitelabel("MiBoxer", "SZ5", "5 in 1 LED Controller", ["_TZB210_w9hcix2r"]),
2677
2964
  tuya.whitelabel("MiBoxer", "FUT037Z+", "RGB led controller", ["_TZB210_417ikxay", "_TZB210_wxazcmsh"]),
@@ -4125,7 +4412,7 @@ exports.definitions = [
4125
4412
  },
4126
4413
  },
4127
4414
  {
4128
- fingerprint: tuya.fingerprint("TS0601", ["_TZE200_gbagoilo"]),
4415
+ fingerprint: tuya.fingerprint("TS0601", ["_TZE200_gbagoilo", "_TZE284_xnwxmj8z"]),
4129
4416
  model: "MG-ZG01W",
4130
4417
  vendor: "Tuya",
4131
4418
  description: "1 gang switch with power meter",
@@ -4290,6 +4577,7 @@ exports.definitions = [
4290
4577
  "_TZ3000_ssp0maqm",
4291
4578
  "_TZ3000_p3fph1go",
4292
4579
  "_TZ3000_9r5jaajv",
4580
+ "_TZ3000_nxdziqzc",
4293
4581
  ]),
4294
4582
  model: "TS0215A_sos",
4295
4583
  vendor: "Tuya",
@@ -5388,6 +5676,7 @@ Ensure all 12 segments are defined and separated by spaces.`),
5388
5676
  "_TZ3000_66fekqhh",
5389
5677
  "_TZ3000_ok0ggpk7",
5390
5678
  "_TZ3000_aknpkt02",
5679
+ "_TZ3000_pfc7i3kt",
5391
5680
  ]),
5392
5681
  model: "TS0003_switch_3_gang_with_backlight",
5393
5682
  vendor: "Tuya",
@@ -5396,12 +5685,14 @@ Ensure all 12 segments are defined and separated by spaces.`),
5396
5685
  tuya.modernExtend.tuyaMagicPacket(),
5397
5686
  m.deviceEndpoints({ endpoints: { l1: 1, l2: 2, l3: 3 } }),
5398
5687
  tuya.modernExtend.tuyaOnOff({
5688
+ onOffCountdown: (m) => m !== "_TZ3000_pfc7i3kt",
5399
5689
  powerOnBehavior2: (m) => m !== "_TZ3000_nwidmc4n",
5400
- indicatorMode: (m) => m !== "_TZ3000_nwidmc4n",
5401
- backlightModeOffOn: true,
5690
+ indicatorMode: (m) => m !== "_TZ3000_nwidmc4n" && m !== "_TZ3000_pfc7i3kt",
5691
+ inchingSwitch: (m) => m !== "_TZ3000_pfc7i3kt",
5692
+ backlightModeOffOn: (m) => m !== "_TZ3000_pfc7i3kt",
5402
5693
  endpoints: ["l1", "l2", "l3"],
5403
5694
  powerOutageMemory: (m) => m === "_TZ3000_nwidmc4n",
5404
- switchType: (m) => m === "_TZ3000_nwidmc4n",
5695
+ switchType: (m) => m === "_TZ3000_nwidmc4n" || m === "_TZ3000_pfc7i3kt",
5405
5696
  }),
5406
5697
  ],
5407
5698
  configure: async (device, coordinatorEndpoint) => {
@@ -5411,6 +5702,7 @@ Ensure all 12 segments are defined and separated by spaces.`),
5411
5702
  await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ["genOnOff"]);
5412
5703
  },
5413
5704
  whiteLabel: [
5705
+ tuya.whitelabel("Moes", "MS-104CZ", "3 gang switch module", ["_TZ3000_pfc7i3kt"]),
5414
5706
  tuya.whitelabel("Lonsonho", "X703A", "3 Gang switch with backlight", ["_TZ3000_rhkfbfcv"]),
5415
5707
  tuya.whitelabel("Zemismart", "ZM-L03E-Z", "3 gang switch with neutral", ["_TZ3000_empogkya", "_TZ3000_lsunm46z"]),
5416
5708
  tuya.whitelabel("Zemismart", "KES-606US-L3", "3 gang switch with neutral", ["_TZ3000_uilitwsy"]),
@@ -6539,6 +6831,7 @@ Ensure all 12 segments are defined and separated by spaces.`),
6539
6831
  "_TZE200_ba69l9ol",
6540
6832
  "_TZE200_68nvbi09",
6541
6833
  "_TZE200_vexa5o82",
6834
+ "_TZE200_sfqyhvpv",
6542
6835
  ]),
6543
6836
  model: "TS0601_cover_3",
6544
6837
  vendor: "Tuya",
@@ -6559,6 +6852,7 @@ Ensure all 12 segments are defined and separated by spaces.`),
6559
6852
  tuya.whitelabel("Zemismart", "ZM85EL-2Z", "Roman Rod I type U curtains track", ["_TZE200_cf1sl3tj", "_TZE200_nw1r9hp6"]),
6560
6853
  tuya.whitelabel("Hiladuo", "B09M3R35GC", "Motorized roller shade", ["_TZE200_9p5xmj5r"]),
6561
6854
  tuya.whitelabel("Tuya", "MYQ-RM25-1.3/25-BZ", "Tubular roller blind motor", ["_TZE200_vexa5o82"]),
6855
+ tuya.whitelabel("Shaman", "25EB-1/30-TYZ", "Motorized roller shade", ["_TZE200_sfqyhvpv"]),
6562
6856
  ],
6563
6857
  meta: {
6564
6858
  // All datapoints go in here
@@ -9257,7 +9551,20 @@ Ensure all 12 segments are defined and separated by spaces.`),
9257
9551
  },
9258
9552
  },
9259
9553
  {
9260
- fingerprint: tuya.fingerprint("TS0726", ["_TZ3002_1s0vfmtv", "_TZ3002_gdwja9a7"]),
9554
+ fingerprint: tuya.fingerprint("TS0726", ["_TZ3002_l8bfzlcd"]),
9555
+ model: "TS0726_1_gang",
9556
+ vendor: "Tuya",
9557
+ description: "1 gang switch with neutral wire",
9558
+ fromZigbee: [fz.on_off, tuya.fz.power_on_behavior_2, fzLocal.TS0726_action],
9559
+ toZigbee: [tz.on_off, tuya.tz.power_on_behavior_2, tzLocal.TS0726_switch_mode],
9560
+ exposes: [e.switch(), e.power_on_behavior(), e.enum("switch_mode", ea.STATE_SET, ["switch", "scene"]), e.action(["scene_1"])],
9561
+ configure: async (device, coordinatorEndpoint) => {
9562
+ await tuya.configureMagicPacket(device, coordinatorEndpoint);
9563
+ await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ["genOnOff"]);
9564
+ },
9565
+ },
9566
+ {
9567
+ fingerprint: tuya.fingerprint("TS0726", ["_TZ3002_1s0vfmtv", "_TZ3002_gdwja9a7", "_TZ3002_u7d3nes3"]),
9261
9568
  model: "TS0726_2_gang",
9262
9569
  vendor: "Tuya",
9263
9570
  description: "2 gang switch with neutral wire",
@@ -9377,7 +9684,7 @@ Ensure all 12 segments are defined and separated by spaces.`),
9377
9684
  },
9378
9685
  },
9379
9686
  {
9380
- fingerprint: tuya.fingerprint("TS0726", ["_TZ3002_iedhxgyi", "_TZ3000_lcjsewlo"]),
9687
+ fingerprint: tuya.fingerprint("TS0726", ["_TZ3002_iedhxgyi", "_TZ3000_lcjsewlo", "_TZ3000_kfkqkjqe"]),
9381
9688
  model: "TS0726_3_gang",
9382
9689
  vendor: "Tuya",
9383
9690
  description: "3 gang switch with neutral wire",
@@ -9401,7 +9708,14 @@ Ensure all 12 segments are defined and separated by spaces.`),
9401
9708
  },
9402
9709
  },
9403
9710
  {
9404
- fingerprint: tuya.fingerprint("TS0726", ["_TZ3000_wsspgtcd", "_TZ3000_s678wazd", "_TZ3002_pzao9ls1", "_TZ3000_kfkqkjqe"]),
9711
+ fingerprint: tuya.fingerprint("TS0726", [
9712
+ "_TZ3000_wsspgtcd",
9713
+ "_TZ3000_s678wazd",
9714
+ "_TZ3002_pzao9ls1",
9715
+ "_TZ3002_uu4uircb",
9716
+ "_TZ3002_yptomml1",
9717
+ "_TZ3002_pw4ad2xa",
9718
+ ]),
9405
9719
  model: "TS0726_4_gang",
9406
9720
  vendor: "Tuya",
9407
9721
  description: "4 gang switch with neutral wire",
@@ -12139,6 +12453,22 @@ Ensure all 12 segments are defined and separated by spaces.`),
12139
12453
  await reporting.onOff(endpoint);
12140
12454
  },
12141
12455
  },
12456
+ {
12457
+ fingerprint: tuya.fingerprint("TS110E", ["_TZE200_ubgdwsnr"]),
12458
+ model: "EKAC-T3096Z",
12459
+ vendor: "Ekaza",
12460
+ description: "2 channel dimmer",
12461
+ extend: [tuya.modernExtend.tuyaBase({ dp: true }), m.deviceEndpoints({ endpoints: { l1: 1, l2: 2 } })],
12462
+ exposes: [e.light_brightness().withEndpoint("l1"), e.light_brightness().withEndpoint("l2")],
12463
+ meta: {
12464
+ tuyaDatapoints: [
12465
+ [1, "state_l1", tuya.valueConverter.onOff],
12466
+ [2, "brightness_l1", tuya.valueConverter.scale0_254to0_1000],
12467
+ [7, "state_l2", tuya.valueConverter.onOff],
12468
+ [8, "brightness_l2", tuya.valueConverter.scale0_254to0_1000],
12469
+ ],
12470
+ },
12471
+ },
12142
12472
  {
12143
12473
  fingerprint: tuya.fingerprint("TS110E", ["_TZ3210_wdexaypg"]),
12144
12474
  model: "TS110E_2gang_1",
@@ -20016,6 +20346,117 @@ Ensure all 12 segments are defined and separated by spaces.`),
20016
20346
  l2: 1,
20017
20347
  }),
20018
20348
  },
20349
+ {
20350
+ fingerprint: tuya.fingerprint("TS0601", ["_TZE284_nj7sfid2"]),
20351
+ model: "TS0601_smart_scene_knob",
20352
+ vendor: "Tuya",
20353
+ description: "Smart scene knob controller with 4 buttons",
20354
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
20355
+ fromZigbee: [
20356
+ fzLocal.TS0601_smart_scene_knob_light_onoff,
20357
+ fzLocal.TS0601_smart_scene_knob_light_brightness,
20358
+ fzLocal.TS0601_smart_scene_knob_light_colortemp,
20359
+ fzLocal.TS0601_smart_scene_knob_curtain_command,
20360
+ ],
20361
+ toZigbee: [
20362
+ tzLocal.TS0601_smart_scene_knob_bind_all,
20363
+ tzLocal.TS0601_smart_scene_knob_assign_button_1,
20364
+ tzLocal.TS0601_smart_scene_knob_set_base_group_id,
20365
+ ],
20366
+ exposes: [
20367
+ e
20368
+ .action([
20369
+ "scene_1",
20370
+ "scene_2",
20371
+ "scene_3",
20372
+ "scene_4",
20373
+ "light_1_on",
20374
+ "light_1_off",
20375
+ "light_1_brightness_up",
20376
+ "light_1_brightness_down",
20377
+ "light_1_colortemp_up",
20378
+ "light_1_colortemp_down",
20379
+ "light_2_on",
20380
+ "light_2_off",
20381
+ "light_2_brightness_up",
20382
+ "light_2_brightness_down",
20383
+ "light_2_colortemp_up",
20384
+ "light_2_colortemp_down",
20385
+ "light_3_on",
20386
+ "light_3_off",
20387
+ "light_3_brightness_up",
20388
+ "light_3_brightness_down",
20389
+ "light_3_colortemp_up",
20390
+ "light_3_colortemp_down",
20391
+ "light_4_on",
20392
+ "light_4_off",
20393
+ "light_4_brightness_up",
20394
+ "light_4_brightness_down",
20395
+ "light_4_colortemp_up",
20396
+ "light_4_colortemp_down",
20397
+ "curtain_1_start",
20398
+ "curtain_1_stop",
20399
+ "curtain_1_position_open",
20400
+ "curtain_1_position_close",
20401
+ "curtain_2_start",
20402
+ "curtain_2_stop",
20403
+ "curtain_2_position_open",
20404
+ "curtain_2_position_close",
20405
+ "curtain_3_start",
20406
+ "curtain_3_stop",
20407
+ "curtain_3_position_open",
20408
+ "curtain_3_position_close",
20409
+ "curtain_4_start",
20410
+ "curtain_4_stop",
20411
+ "curtain_4_position_open",
20412
+ "curtain_4_position_close",
20413
+ ])
20414
+ .withDescription("Triggered action from scene button, light knob, or curtain control"),
20415
+ e.numeric("brightness", ea.STATE).withValueMin(0).withValueMax(254).withDescription("Brightness level from light mode (0-254)"),
20416
+ e.numeric("color_temp", ea.STATE).withValueMin(150).withValueMax(500).withDescription("Color temperature from light mode (mired)"),
20417
+ e
20418
+ .numeric("curtain_position", ea.STATE)
20419
+ .withValueMin(0)
20420
+ .withValueMax(100)
20421
+ .withUnit("%")
20422
+ .withDescription("Curtain position from curtain mode (0-100%)"),
20423
+ e
20424
+ .enum("assignment_status", ea.STATE, [statusUnassigned, statusWaiting, statusReady])
20425
+ .withCategory("diagnostic")
20426
+ .withDescription("Button assignment status"),
20427
+ e
20428
+ .numeric("base_group_id", ea.STATE)
20429
+ .withCategory("diagnostic")
20430
+ .withDescription("Base Group ID for button 1 (buttons 2-4 are +20, +40, +60)"),
20431
+ e
20432
+ .numeric("action_button", ea.STATE)
20433
+ .withValueMin(1)
20434
+ .withValueMax(4)
20435
+ .withCategory("diagnostic")
20436
+ .withDescription("Button number from last action"),
20437
+ e.numeric("action_group", ea.STATE).withCategory("diagnostic").withDescription("Group ID from last action"),
20438
+ e.enum("bind_all_scene", ea.SET, ["bind"]).withCategory("config").withDescription("Bind all buttons to Scene mode (red LED)"),
20439
+ e.enum("bind_all_light", ea.SET, ["bind"]).withCategory("config").withDescription("Bind all buttons to Light mode (green LED)"),
20440
+ e.enum("bind_all_curtain", ea.SET, ["bind"]).withCategory("config").withDescription("Bind all buttons to Curtain mode (blue LED)"),
20441
+ e.enum("assign_button_1", ea.SET, ["assign"]).withCategory("config").withDescription("Start assignment: press button 1 after clicking"),
20442
+ e
20443
+ .numeric("set_base_group_id", ea.SET)
20444
+ .withValueMin(1)
20445
+ .withValueMax(65000)
20446
+ .withCategory("config")
20447
+ .withDescription("Manually set base Group ID (advanced)"),
20448
+ ],
20449
+ meta: {
20450
+ tuyaDatapoints: [
20451
+ [1, "action", tuya.valueConverter.static("scene_1")],
20452
+ [2, "action", tuya.valueConverter.static("scene_2")],
20453
+ [3, "action", tuya.valueConverter.static("scene_3")],
20454
+ [4, "action", tuya.valueConverter.static("scene_4")],
20455
+ [52, "binding_confirmation", tuya.valueConverter.raw],
20456
+ [102, "binding_config", tuya.valueConverter.raw],
20457
+ ],
20458
+ },
20459
+ },
20019
20460
  {
20020
20461
  fingerprint: [{ modelID: "TS0601", manufacturerName: "_TZE200_khah2lkr" }],
20021
20462
  model: "HY607W-3A",
@@ -20536,7 +20977,7 @@ Ensure all 12 segments are defined and separated by spaces.`),
20536
20977
  manual: tuya.enum(7),
20537
20978
  }),
20538
20979
  ],
20539
- [11, "power", tuya.valueConverter.raw],
20980
+ [11, "power", tuya.valueConverter.divideBy10],
20540
20981
  [16, "local_temperature", tuya.valueConverter.divideBy10],
20541
20982
  [
20542
20983
  17,
@@ -20554,8 +20995,8 @@ Ensure all 12 segments are defined and separated by spaces.`),
20554
20995
  [101, "voltage", tuya.valueConverter.divideBy10],
20555
20996
  [102, "current", tuya.valueConverter.divideBy1000],
20556
20997
  [103, "temperature_sensibility", tuya.valueConverter.divideBy10],
20557
- [104, "energy_today", tuya.valueConverter.raw],
20558
- [105, "energy_yesterday", tuya.valueConverter.raw],
20998
+ [104, "energy_today", tuya.valueConverter.divideBy10],
20999
+ [105, "energy_yesterday", tuya.valueConverter.divideBy10],
20559
21000
  [
20560
21001
  106,
20561
21002
  "device_mode_type",
@@ -20565,7 +21006,7 @@ Ensure all 12 segments are defined and separated by spaces.`),
20565
21006
  switch: tuya.enum(2),
20566
21007
  }),
20567
21008
  ],
20568
- [107, "energy", tuya.valueConverter.raw],
21009
+ [107, "energy", tuya.valueConverter.divideBy10],
20569
21010
  [108, "week_program_1", tuya.valueConverter.raw],
20570
21011
  [109, "week_program_2", tuya.valueConverter.raw],
20571
21012
  [110, "week_program_3", tuya.valueConverter.raw],
@@ -20608,7 +21049,7 @@ Ensure all 12 segments are defined and separated by spaces.`),
20608
21049
  e.energy(),
20609
21050
  e.numeric("energy_today", ea.STATE).withUnit("kWh").withDescription("Energy consumed today"),
20610
21051
  e.numeric("energy_yesterday", ea.STATE).withUnit("kWh").withDescription("Energy consumed yesterday"),
20611
- e.binary("device_mode_type", ea.STATE_SET, "ON", "OFF").withDescription("Set pilot wire mode to 6 (includes comfort 1 & 2)."),
21052
+ e.binary("device_mode_type", ea.STATE_SET, "ON", "OFF").withDescription("Set pilot wire mode to 6 modes (includes comfort 1 & 2)."),
20612
21053
  ],
20613
21054
  meta: {
20614
21055
  tuyaDatapoints: [
@@ -20624,7 +21065,7 @@ Ensure all 12 segments are defined and separated by spaces.`),
20624
21065
  comfort_2: tuya.enum(5),
20625
21066
  }),
20626
21067
  ],
20627
- [11, "power", tuya.valueConverter.raw],
21068
+ [11, "power", tuya.valueConverter.divideBy10],
20628
21069
  [16, "local_temperature", tuya.valueConverter.divideBy10],
20629
21070
  [19, "local_temperature_calibration", tuya.valueConverter.localTempCalibration2],
20630
21071
  [20, "fault", tuya.valueConverter.raw],
@@ -20644,10 +21085,10 @@ Ensure all 12 segments are defined and separated by spaces.`),
20644
21085
  [113, "window_timeout", tuya.valueConverter.raw],
20645
21086
  [114, "device_mode_type", tuya.valueConverter.onOff],
20646
21087
  [115, "voltage", tuya.valueConverter.divideBy10],
20647
- [116, "current", tuya.valueConverter.divideBy1000],
20648
- [117, "energy", tuya.valueConverter.raw],
20649
- [119, "energy_today", tuya.valueConverter.raw],
20650
- [120, "energy_yesterday", tuya.valueConverter.raw],
21088
+ [116, "current", tuya.valueConverter.divideBy10],
21089
+ [117, "energy", tuya.valueConverter.divideBy10],
21090
+ [119, "energy_today", tuya.valueConverter.divideBy10],
21091
+ [120, "energy_yesterday", tuya.valueConverter.divideBy10],
20651
21092
  ],
20652
21093
  },
20653
21094
  },
@@ -22067,5 +22508,26 @@ Ensure all 12 segments are defined and separated by spaces.`),
22067
22508
  ],
22068
22509
  },
22069
22510
  },
22511
+ {
22512
+ fingerprint: [{ modelID: "TS0601", manufacturerName: "_TZE284_8se38w3c" }],
22513
+ model: "TZ-ZT01_GA4",
22514
+ vendor: "Tuya",
22515
+ description: "Temperature & humidity Sensor with external probe",
22516
+ extend: [tuya.modernExtend.tuyaBase({ dp: true })],
22517
+ exposes: [
22518
+ e.temperature(),
22519
+ e.numeric("temperature_probe", ea.STATE).withUnit("°C").withDescription("Probe temperature"),
22520
+ e.humidity(),
22521
+ tuya.exposes.batteryState(),
22522
+ ],
22523
+ meta: {
22524
+ tuyaDatapoints: [
22525
+ [1, "temperature", tuya.valueConverter.divideBy10],
22526
+ [2, "humidity", tuya.valueConverter.raw],
22527
+ [3, "battery_state", tuya.valueConverter.batteryState],
22528
+ [38, "temperature_probe", tuya.valueConverter.divideBy10],
22529
+ ],
22530
+ },
22531
+ },
22070
22532
  ];
22071
22533
  //# sourceMappingURL=tuya.js.map