zigbee-herdsman-converters 15.0.45 → 15.0.47

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.
package/devices/bosch.js CHANGED
@@ -522,6 +522,22 @@ const definition = [
522
522
  exposes.enum('heartbeat', ea.ALL, Object.keys(stateOffOn)).withDescription('Enable/disable heartbeat'),
523
523
  ],
524
524
  },
525
+ {
526
+ zigbeeModel: ['RFPR-ZB-SH-EU'],
527
+ model: 'RFPR-ZB-SH-EU',
528
+ vendor: 'Bosch',
529
+ description: 'Wireless motion detector',
530
+ fromZigbee: [fz.temperature, fz.battery, fz.ias_occupancy_alarm_1],
531
+ toZigbee: [],
532
+ meta: {battery: {voltageToPercentage: '3V_2500'}},
533
+ configure: async (device, coordinatorEndpoint, logger) => {
534
+ const endpoint = device.getEndpoint(1);
535
+ await reporting.bind(endpoint, coordinatorEndpoint, ['msTemperatureMeasurement', 'genPowerCfg']);
536
+ await reporting.temperature(endpoint);
537
+ await reporting.batteryVoltage(endpoint);
538
+ },
539
+ exposes: [e.temperature(), e.battery(), e.occupancy(), e.battery_low(), e.tamper()],
540
+ },
525
541
  {
526
542
  zigbeeModel: ['RBSH-SP-ZB-EU'],
527
543
  model: 'BSP-FZ2',
package/devices/candeo.js CHANGED
@@ -6,7 +6,7 @@ const e = exposes.presets;
6
6
 
7
7
  module.exports = [
8
8
  {
9
- zigbeeModel: ['HK-DIM-A'],
9
+ zigbeeModel: ['HK-DIM-A', 'Candeo Zigbee Dimmer'],
10
10
  model: 'HK-DIM-A',
11
11
  vendor: 'Candeo',
12
12
  description: 'Zigbee LED dimmer smart switch',
@@ -129,7 +129,7 @@ module.exports = [
129
129
  // For some this fails so set manually
130
130
  // https://github.com/Koenkk/zigbee2mqtt/issues/3575
131
131
  endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {
132
- acCurrentDivisor: 1000, acCurrentMultiplier: 1, powerMultiplier: 1, powerDivisor: 10});
132
+ acCurrentDivisor: 1000, acCurrentMultiplier: 1, acPowerMultiplier: 1, acPowerDivisor: 10});
133
133
  }
134
134
  await reporting.rmsVoltage(endpoint, {change: 2}); // Voltage reports in V
135
135
  await reporting.rmsCurrent(endpoint, {change: 10}); // Current reports in mA
@@ -2,6 +2,7 @@ const exposes = require('../lib/exposes');
2
2
  const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
3
  const tz = require('../converters/toZigbee');
4
4
  const reporting = require('../lib/reporting');
5
+ const ota = require('../lib/ota');
5
6
  const e = exposes.presets;
6
7
 
7
8
  module.exports = [
@@ -13,6 +14,7 @@ module.exports = [
13
14
  fromZigbee: [fz.lock, fz.lock_operation_event, fz.battery, fz.lock_programming_event, fz.lock_pin_code_response],
14
15
  toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus],
15
16
  meta: {pinCodeCount: 20},
17
+ ota: ota.zigbeeOTA,
16
18
  configure: async (device, coordinatorEndpoint, logger) => {
17
19
  const endpoint = device.getEndpoint(1);
18
20
  await reporting.bind(endpoint, coordinatorEndpoint, ['closuresDoorLock', 'genPowerCfg']);
package/devices/ikea.js CHANGED
@@ -12,7 +12,7 @@ const e = exposes.presets;
12
12
  const ea = exposes.access;
13
13
  const herdsman = require('zigbee-herdsman');
14
14
  const {
15
- calibrateAndPrecisionRoundOptions, postfixWithEndpointName, getMetaValue,
15
+ calibrateAndPrecisionRoundOptions, postfixWithEndpointName, getMetaValue, precisionRound,
16
16
  } = require('../lib/utils');
17
17
 
18
18
  const bulbOnEvent = async (type, data, device, options, state) => {
@@ -72,39 +72,6 @@ const configureRemote = async (device, coordinatorEndpoint, logger) => {
72
72
  await reporting.batteryPercentageRemaining(endpoint);
73
73
  };
74
74
 
75
- const fzLocal = {
76
- // The STYRBAR sends an on +- 500ms after the arrow release. We don't want to send the ON action in this case.
77
- // https://github.com/Koenkk/zigbee2mqtt/issues/13335
78
- STYRBAR_on: {
79
- cluster: 'genOnOff',
80
- type: 'commandOn',
81
- convert: (model, msg, publish, options, meta) => {
82
- if (utils.hasAlreadyProcessedMessage(msg, model)) return;
83
- const arrowReleaseAgo = Date.now() - globalStore.getValue(msg.endpoint, 'arrow_release', 0);
84
- if (arrowReleaseAgo > 700) {
85
- return {action: 'on'};
86
- }
87
- },
88
- },
89
- STYRBAR_arrow_release: {
90
- cluster: 'genScenes',
91
- type: 'commandTradfriArrowRelease',
92
- options: [exposes.options.legacy()],
93
- convert: (model, msg, publish, options, meta) => {
94
- if (utils.hasAlreadyProcessedMessage(msg, model)) return;
95
- globalStore.putValue(msg.endpoint, 'arrow_release', Date.now());
96
- const direction = globalStore.getValue(msg.endpoint, 'direction');
97
- if (direction) {
98
- globalStore.clearValue(msg.endpoint, 'direction');
99
- const duration = msg.data.value / 1000;
100
- const result = {action: `arrow_${direction}_release`, duration, action_duration: duration};
101
- if (!utils.isLegacyEnabled(options)) delete result.duration;
102
- return result;
103
- }
104
- },
105
- },
106
- };
107
-
108
75
  const tradfriExtend = {
109
76
  light_onoff_brightness: (options = {}) => ({
110
77
  ...extend.light_onoff_brightness(options),
@@ -214,6 +181,61 @@ const ikea = {
214
181
  return state;
215
182
  },
216
183
  },
184
+ remote_battery: {
185
+ cluster: 'genPowerCfg',
186
+ type: ['attributeReport', 'readResponse'],
187
+ convert: (model, msg, publish, options, meta) => {
188
+ const payload = {};
189
+ if (msg.data.hasOwnProperty('batteryPercentageRemaining')) {
190
+ // Some devices do not comply to the ZCL and report a
191
+ // batteryPercentageRemaining of 100 when the battery is full (should be 200).
192
+ //
193
+ // IKEA corrected this on newer remote fw version, but many people are still
194
+ // 2.2.010 which is the last version supporting group bindings. We try to be
195
+ // smart and pick the correct one for IKEA remotes.
196
+ let dontDividePercentage = false;
197
+ let percentage = msg.data['batteryPercentageRemaining'];
198
+ const fwVer = meta.device.softwareBuildID.split('.');
199
+ if ((fwVer[0] < 2) || (fwVer[0] == 2 && fwVer[1] <= 3)) {
200
+ dontDividePercentage = true;
201
+ }
202
+ percentage = dontDividePercentage ? percentage : percentage / 2;
203
+ payload.battery = precisionRound(percentage, 2);
204
+ }
205
+
206
+ return payload;
207
+ },
208
+ },
209
+ // The STYRBAR sends an on +- 500ms after the arrow release. We don't want to send the ON action in this case.
210
+ // https://github.com/Koenkk/zigbee2mqtt/issues/13335
211
+ styrbar_on: {
212
+ cluster: 'genOnOff',
213
+ type: 'commandOn',
214
+ convert: (model, msg, publish, options, meta) => {
215
+ if (utils.hasAlreadyProcessedMessage(msg, model)) return;
216
+ const arrowReleaseAgo = Date.now() - globalStore.getValue(msg.endpoint, 'arrow_release', 0);
217
+ if (arrowReleaseAgo > 700) {
218
+ return {action: 'on'};
219
+ }
220
+ },
221
+ },
222
+ styrbar_arrow_release: {
223
+ cluster: 'genScenes',
224
+ type: 'commandTradfriArrowRelease',
225
+ options: [exposes.options.legacy()],
226
+ convert: (model, msg, publish, options, meta) => {
227
+ if (utils.hasAlreadyProcessedMessage(msg, model)) return;
228
+ globalStore.putValue(msg.endpoint, 'arrow_release', Date.now());
229
+ const direction = globalStore.getValue(msg.endpoint, 'direction');
230
+ if (direction) {
231
+ globalStore.clearValue(msg.endpoint, 'direction');
232
+ const duration = msg.data.value / 1000;
233
+ const result = {action: `arrow_${direction}_release`, duration, action_duration: duration};
234
+ if (!utils.isLegacyEnabled(options)) delete result.duration;
235
+ return result;
236
+ }
237
+ },
238
+ },
217
239
  },
218
240
  tz: {
219
241
  air_purifier_fan_mode: {
@@ -623,12 +645,12 @@ module.exports = [
623
645
  model: 'E1524/E1810',
624
646
  description: 'TRADFRI remote control',
625
647
  vendor: 'IKEA',
626
- fromZigbee: [fz.battery, fz.E1524_E1810_toggle, fz.E1524_E1810_levelctrl, fz.ikea_arrow_click, fz.ikea_arrow_hold,
648
+ fromZigbee: [ikea.fz.remote_battery, fz.E1524_E1810_toggle, fz.E1524_E1810_levelctrl, fz.ikea_arrow_click, fz.ikea_arrow_hold,
627
649
  fz.ikea_arrow_release],
628
- exposes: [e.battery(), e.action(['arrow_left_click', 'arrow_left_hold', 'arrow_left_release', 'arrow_right_click',
629
- 'arrow_right_hold', 'arrow_right_release', 'brightness_down_click', 'brightness_down_hold', 'brightness_down_release',
630
- 'brightness_up_click', 'brightness_up_hold', 'brightness_up_release', 'toggle'])],
631
- toZigbee: [],
650
+ exposes: [e.battery().withAccess(ea.STATE_GET), e.action(['arrow_left_click', 'arrow_left_hold', 'arrow_left_release',
651
+ 'arrow_right_click', 'arrow_right_hold', 'arrow_right_release', 'brightness_down_click', 'brightness_down_hold',
652
+ 'brightness_down_release', 'brightness_up_click', 'brightness_up_hold', 'brightness_up_release', 'toggle'])],
653
+ toZigbee: [tz.battery_percentage_remaining],
632
654
  ota: ota.tradfri,
633
655
  // dontDividePercentage: true not needed with latest firmware
634
656
  // https://github.com/Koenkk/zigbee2mqtt/issues/16412
@@ -639,14 +661,13 @@ module.exports = [
639
661
  model: 'E2001/E2002',
640
662
  vendor: 'IKEA',
641
663
  description: 'STYRBAR remote control',
642
- fromZigbee: [fz.battery, fzLocal.STYRBAR_on, fz.command_off, fz.command_move, fz.command_stop, fz.ikea_arrow_click,
643
- fz.ikea_arrow_hold, fzLocal.STYRBAR_arrow_release],
644
- exposes: [e.battery(), e.action(['on', 'off', 'brightness_move_up', 'brightness_move_down',
664
+ fromZigbee: [ikea.fz.remote_battery, ikea.fz.styrbar_on, fz.command_off, fz.command_move, fz.command_stop, fz.ikea_arrow_click,
665
+ fz.ikea_arrow_hold, ikea.fz.styrbar_arrow_release],
666
+ exposes: [e.battery().withAccess(ea.STATE_GET), e.action(['on', 'off', 'brightness_move_up', 'brightness_move_down',
645
667
  'brightness_stop', 'arrow_left_click', 'arrow_right_click', 'arrow_left_hold',
646
668
  'arrow_right_hold', 'arrow_left_release', 'arrow_right_release'])],
647
- toZigbee: [],
669
+ toZigbee: [tz.battery_percentage_remaining],
648
670
  ota: ota.tradfri,
649
- meta: {battery: {dontDividePercentage: true}},
650
671
  configure: async (device, coordinatorEndpoint, logger) => {
651
672
  // Binding genOnOff is not required to make device send events.
652
673
  const endpoint = device.getEndpoint(1);
@@ -659,12 +680,16 @@ module.exports = [
659
680
  model: 'E1743',
660
681
  vendor: 'IKEA',
661
682
  description: 'TRADFRI ON/OFF switch',
662
- fromZigbee: [fz.command_on, fz.legacy.genOnOff_cmdOn, fz.command_off, fz.legacy.genOnOff_cmdOff, fz.command_move, fz.battery,
663
- fz.legacy.E1743_brightness_up, fz.legacy.E1743_brightness_down, fz.command_stop, fz.legacy.E1743_brightness_stop],
664
- exposes: [e.battery(), e.action(['on', 'off', 'brightness_move_down', 'brightness_move_up', 'brightness_stop'])],
665
- toZigbee: [],
683
+ fromZigbee: [fz.command_on, fz.legacy.genOnOff_cmdOn, fz.command_off, fz.legacy.genOnOff_cmdOff, fz.command_move,
684
+ ikea.fz.remote_battery, fz.legacy.E1743_brightness_up, fz.legacy.E1743_brightness_down, fz.command_stop,
685
+ fz.legacy.E1743_brightness_stop],
686
+ exposes: [
687
+ e.battery().withAccess(ea.STATE_GET),
688
+ e.action(['on', 'off', 'brightness_move_down', 'brightness_move_up', 'brightness_stop']),
689
+ ],
690
+ toZigbee: [tz.battery_percentage_remaining],
666
691
  ota: ota.tradfri,
667
- meta: {disableActionGroup: true, battery: {dontDividePercentage: true}},
692
+ meta: {disableActionGroup: true},
668
693
  configure: configureRemote,
669
694
  },
670
695
  {
@@ -672,11 +697,11 @@ module.exports = [
672
697
  model: 'E1841',
673
698
  vendor: 'IKEA',
674
699
  description: 'KNYCKLAN open/close remote water valve',
675
- fromZigbee: [fz.command_on, fz.command_off, fz.battery],
676
- exposes: [e.battery(), e.action(['on', 'off'])],
677
- toZigbee: [],
700
+ fromZigbee: [fz.command_on, fz.command_off, ikea.fz.remote_battery],
701
+ exposes: [e.battery().withAccess(ea.STATE_GET), e.action(['on', 'off'])],
702
+ toZigbee: [tz.battery_percentage_remaining],
678
703
  ota: ota.tradfri,
679
- meta: {disableActionGroup: true, battery: {dontDividePercentage: true}},
704
+ meta: {disableActionGroup: true},
680
705
  configure: configureRemote,
681
706
  },
682
707
  {
@@ -699,11 +724,11 @@ module.exports = [
699
724
  model: 'E1812',
700
725
  vendor: 'IKEA',
701
726
  description: 'TRADFRI shortcut button',
702
- fromZigbee: [fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.battery],
703
- exposes: [e.battery(), e.action(['on', 'off', 'brightness_move_up', 'brightness_stop'])],
704
- toZigbee: [],
727
+ fromZigbee: [fz.command_on, fz.command_off, fz.command_move, fz.command_stop, ikea.fz.remote_battery],
728
+ exposes: [e.battery().withAccess(ea.STATE_GET), e.action(['on', 'off', 'brightness_move_up', 'brightness_stop'])],
729
+ toZigbee: [tz.battery_percentage_remaining],
705
730
  ota: ota.tradfri,
706
- meta: {disableActionGroup: true, battery: {dontDividePercentage: true}},
731
+ meta: {disableActionGroup: true},
707
732
  configure: async (device, coordinatorEndpoint, logger) => {
708
733
  // Binding genOnOff is not required to make device send events.
709
734
  const endpoint = device.getEndpoint(1);
@@ -838,11 +863,10 @@ module.exports = [
838
863
  model: 'E1766',
839
864
  vendor: 'IKEA',
840
865
  description: 'TRADFRI open/close remote',
841
- fromZigbee: [fz.battery, fz.command_cover_close, fz.legacy.cover_close, fz.command_cover_open, fz.legacy.cover_open,
866
+ fromZigbee: [ikea.fz.remote_battery, fz.command_cover_close, fz.legacy.cover_close, fz.command_cover_open, fz.legacy.cover_open,
842
867
  fz.command_cover_stop, fz.legacy.cover_stop],
843
- exposes: [e.battery(), e.action(['close', 'open', 'stop'])],
844
- toZigbee: [],
845
- meta: {battery: {dontDividePercentage: true}},
868
+ exposes: [e.battery().withAccess(ea.STATE_GET), e.action(['close', 'open', 'stop'])],
869
+ toZigbee: [tz.battery_percentage_remaining],
846
870
  ota: ota.tradfri,
847
871
  configure: configureRemote,
848
872
  },
@@ -979,6 +1003,13 @@ module.exports = [
979
1003
  description: 'STOFTMOLN ceiling/wall lamp 24 warm light dimmable',
980
1004
  extend: tradfriExtend.light_onoff_brightness(),
981
1005
  },
1006
+ {
1007
+ zigbeeModel: ['STOFTMOLN ceiling/wall lamp WW10'],
1008
+ model: 'T2105',
1009
+ vendor: 'IKEA',
1010
+ description: 'STOFTMOLN ceiling/wall lamp 10 warm light dimmable',
1011
+ extend: tradfriExtend.light_onoff_brightness(),
1012
+ },
982
1013
  {
983
1014
  zigbeeModel: ['TRADFRIbulbPAR38WS900lm'],
984
1015
  model: 'LED2006R9',
@@ -28,6 +28,22 @@ const tzLocal = {
28
28
  };
29
29
 
30
30
  module.exports = [
31
+ {
32
+ zigbeeModel: [' Pocket remote\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'+
33
+ '\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'],
34
+ model: '067755',
35
+ vendor: 'Legrand',
36
+ description: 'Wireless and batteryless 4 scenes control',
37
+ fromZigbee: [fz.identify, fz.battery, fz.command_recall],
38
+ exposes: [e.battery(), e.action(['identify', 'recall_1_1'])],
39
+ toZigbee: [],
40
+ meta: {multiEndpoint: true, battery: {voltageToPercentage: '3V_2500'}, publishDuplicateTransaction: true},
41
+ onEvent: readInitialBatteryState,
42
+ configure: async (device, coordinatorEndpoint, logger) => {
43
+ const endpoint = device.getEndpoint(1);
44
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'genOnOff', 'genLevelCtrl']);
45
+ },
46
+ },
31
47
  {
32
48
  zigbeeModel: [' Dry contact\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'+
33
49
  '\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'],
@@ -3044,4 +3044,11 @@ module.exports = [
3044
3044
  description: 'Hue Gradient light tube compact',
3045
3045
  extend: philips.extend.light_onoff_brightness_colortemp_color_gradient({colorTempRange: [153, 500]}),
3046
3046
  },
3047
+ {
3048
+ zigbeeModel: ['929003055701'],
3049
+ model: '929003055701',
3050
+ vendor: 'Philips',
3051
+ description: 'Hue White Ambiance Devote',
3052
+ extend: philips.extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
3053
+ },
3047
3054
  ];
@@ -43,6 +43,24 @@ module.exports = [
43
43
  },
44
44
  ota: ota.salus,
45
45
  },
46
+ {
47
+ zigbeeModel: ['SX885ZB'],
48
+ model: 'SX885ZB',
49
+ vendor: 'Salus Controls',
50
+ description: 'miniSmartPlug',
51
+ fromZigbee: [fz.on_off, fz.metering],
52
+ toZigbee: [tz.on_off],
53
+ configure: async (device, coordinatorEndpoint, logger) => {
54
+ const endpoint = device.getEndpoint(9);
55
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'seMetering']);
56
+ await reporting.onOff(endpoint);
57
+ await reporting.instantaneousDemand(endpoint, {min: 5, change: 10});
58
+ await reporting.currentSummDelivered(endpoint, {min: 5, change: [0, 10]});
59
+ await endpoint.read('seMetering', ['multiplier', 'divisor']);
60
+ },
61
+ ota: ota.salus,
62
+ exposes: [e.switch(), e.power(), e.energy()],
63
+ },
46
64
  {
47
65
  zigbeeModel: ['SR600'],
48
66
  model: 'SR600',
package/devices/tuya.js CHANGED
@@ -899,7 +899,7 @@ module.exports = [
899
899
  ],
900
900
  meta: {
901
901
  tuyaDatapoints: [
902
- [1, 'gas', tuya.valueConverterBasic.lookup({true: tuya.enum(0), false: tuya.enum(1)})],
902
+ [1, 'gas', tuya.valueConverter.trueFalseEnum0],
903
903
  [2, 'gas_value', tuya.valueConverter.divideBy10],
904
904
  [6, 'alarm_ringtone', tuya.valueConverterBasic.lookup({'1': 0, '2': 1, '3': 2, '4': 3, '5': 4})],
905
905
  [7, 'alarm_time', tuya.valueConverter.raw],
@@ -2177,7 +2177,6 @@ module.exports = [
2177
2177
  {modelID: 'TS0601', manufacturerName: '_TZE200_8whxpsiw'}, // EVOLVEO
2178
2178
  {modelID: 'TS0601', manufacturerName: '_TZE200_xby0s3ta'}, // Sandy Beach HY367
2179
2179
  {modelID: 'TS0601', manufacturerName: '_TZE200_7fqkphoq'}, // AFINTEK
2180
- {modelID: 'TS0601', manufacturerName: '_TZE200_gd4rvykv'}, // Sanico
2181
2180
  ],
2182
2181
  model: 'TS0601_thermostat',
2183
2182
  vendor: 'TuYa',
@@ -2372,6 +2371,7 @@ module.exports = [
2372
2371
  fingerprint: tuya.fingerprint('TS0601', [
2373
2372
  '_TZE200_bvu2wnxz', /* model: 'ME167', vendor: 'Avatto' */
2374
2373
  '_TZE200_6rdj8dzm', /* model: 'ME167', vendor: 'Avatto' */
2374
+ '_TZE200_gd4rvykv', // Sanico
2375
2375
  ]),
2376
2376
  model: 'TS0601_thermostat_3',
2377
2377
  vendor: 'TuYa',
@@ -2541,7 +2541,13 @@ module.exports = [
2541
2541
  zigbeeModel: ['TS0121'],
2542
2542
  model: 'TS0121_plug',
2543
2543
  description: '10A UK or 16A EU smart plug',
2544
- whiteLabel: [{vendor: 'BlitzWolf', model: 'BW-SHP13'}],
2544
+ whiteLabel: [
2545
+ {vendor: 'BlitzWolf', model: 'BW-SHP13'},
2546
+ {vendor: 'Connecte', model: '4500990'},
2547
+ {vendor: 'Connecte', model: '4500991'},
2548
+ {vendor: 'Connecte', model: '4500992'},
2549
+ {vendor: 'Connecte', model: '4500993'},
2550
+ ],
2545
2551
  vendor: 'TuYa',
2546
2552
  fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, tuya.fz.power_outage_memory,
2547
2553
  tuya.fz.indicator_mode],
@@ -2558,6 +2564,9 @@ module.exports = [
2558
2564
  await reporting.currentSummDelivered(endpoint);
2559
2565
  } catch (error) {/* fails for some https://github.com/Koenkk/zigbee2mqtt/issues/11179 */}
2560
2566
  await endpoint.read('genOnOff', ['onOff', 'moesStartUpOnOff', 'tuyaBacklightMode']);
2567
+ await reporting.rmsVoltage(endpoint, {change: 5});
2568
+ await reporting.rmsCurrent(endpoint, {change: 50});
2569
+ await reporting.activePower(endpoint, {change: 10});
2561
2570
  },
2562
2571
  options: [exposes.options.measurement_poll_interval()],
2563
2572
  // This device doesn't support reporting correctly.
@@ -2809,6 +2818,55 @@ module.exports = [
2809
2818
  ],
2810
2819
  },
2811
2820
  },
2821
+ {
2822
+ fingerprint: tuya.fingerprint('TS0601', ['_TZE200_rhblgy0z']),
2823
+ model: 'TS0601_din_3',
2824
+ vendor: 'TuYa',
2825
+ description: 'Zigbee DIN energy meter',
2826
+ fromZigbee: [tuya.fz.datapoints],
2827
+ toZigbee: [tuya.tz.datapoints],
2828
+ configure: tuya.configureMagicPacket,
2829
+ whiteLabel: [{vendor: 'XOCA', model: 'DAC2161C'}],
2830
+ exposes: [tuya.exposes.switch(), e.energy(), e.produced_energy(), e.power(), e.voltage(), e.current(),
2831
+ exposes.enum('fault', ea.STATE, ['clear', 'over_current_threshold', 'over_power_threshold',
2832
+ 'over_voltage threshold', 'wrong_frequency_threshold']).withDescription('Fault status of the device (clear = nothing)'),
2833
+ exposes.enum('threshold_1', ea.STATE, ['not_set', 'over_current_threshold', 'over_voltage_threshold'])
2834
+ .withDescription('State of threshold_1'),
2835
+ exposes.binary('threshold_1_protection', ea.STATE, 'ON', 'OFF')
2836
+ .withDescription('OFF - alarm only, ON - relay will be off when threshold reached'),
2837
+ exposes.numeric('threshold_1_value', ea.STATE)
2838
+ .withDescription('Can be in Volt or Ampere depending on threshold setting. Setup the value on the device'),
2839
+ exposes.enum('threshold_2', ea.STATE, ['not_set', 'over_current_threshold', 'over_voltage_threshold'])
2840
+ .withDescription('State of threshold_2'),
2841
+ exposes.binary('threshold_2_protection', ea.STATE, 'ON', 'OFF')
2842
+ .withDescription('OFF - alarm only, ON - relay will be off when threshold reached'),
2843
+ exposes.numeric('threshold_2_value', ea.STATE)
2844
+ .withDescription('Setup value on the device'),
2845
+ exposes.binary('clear_fault', ea.STATE_SET, 'ON', 'OFF')
2846
+ .withDescription('Turn ON to clear last the fault'),
2847
+ exposes.text('meter_id', ea.STATE).withDescription('Meter ID (ID of device)'),
2848
+ ],
2849
+ meta: {
2850
+ tuyaDatapoints: [
2851
+ [1, 'energy', tuya.valueConverter.divideBy100],
2852
+ [2, 'produced_energy', tuya.valueConverter.divideBy100],
2853
+ [3, null, null], // Monthly, but sends data only after request
2854
+ [4, null, null], // Dayly, but sends data only after request
2855
+ [6, null, tuya.valueConverter.phaseVariant2], // voltage and current
2856
+ [10, 'fault', tuya.valueConverterBasic.lookup({'clear': 0, 'over_current_threshold': 1,
2857
+ 'over_power_threshold': 2, 'over_voltage_threshold': 4, 'wrong_frequency_threshold': 8})],
2858
+ [11, null, null], // Frozen - strange function, in native app - nothing is clear
2859
+ [16, 'state', tuya.valueConverter.onOff],
2860
+ [17, null, tuya.valueConverter.threshold], // It's settable, but can't write converter
2861
+ [18, 'meter_id', tuya.valueConverter.raw],
2862
+ [20, 'clear_fault', tuya.valueConverter.onOff], // Clear fault
2863
+ [21, null, null], // Forward Energy T1 - don't know what this
2864
+ [22, null, null], // Forward Energy T2 - don't know what this
2865
+ [23, null, null], // Forward Energy T3 - don't know what this
2866
+ [24, null, null], // Forward Energy T4 - don't know what this
2867
+ ],
2868
+ },
2869
+ },
2812
2870
  {
2813
2871
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_byzdayie'},
2814
2872
  {modelID: 'TS0601', manufacturerName: '_TZE200_fsb6zw01'},
@@ -77,7 +77,7 @@ module.exports = [
77
77
  },
78
78
  },
79
79
  {
80
- fingerprint: [{modelID: 'TS0003', manufacturerName: '_TZ3000_vjhcenzo'}],
80
+ fingerprint: [{modelID: 'TS0003', manufacturerName: '_TZ3000_vjhcenzo'}, {modelID: 'TS0003', manufacturerName: '_TZ3000_f09j9qjb'}],
81
81
  model: 'TB25',
82
82
  vendor: 'Zemismart',
83
83
  description: 'Smart light switch and socket - 2 gang with neutral wire',
package/lib/tuya.js CHANGED
@@ -1233,6 +1233,7 @@ const valueConverter = {
1233
1233
  trueFalse0: valueConverterBasic.trueFalse(0),
1234
1234
  trueFalse1: valueConverterBasic.trueFalse(1),
1235
1235
  trueFalse2: valueConverterBasic.trueFalse(2),
1236
+ trueFalseEnum0: valueConverterBasic.trueFalse(new Enum(0)),
1236
1237
  onOff: valueConverterBasic.lookup({'ON': true, 'OFF': false}),
1237
1238
  powerOnBehavior: valueConverterBasic.lookup({'off': 0, 'on': 1, 'previous': 2}),
1238
1239
  lightType: valueConverterBasic.lookup({'led': 0, 'incandescent': 1, 'halogen': 2}),
@@ -1614,7 +1615,7 @@ const tuyaTz = {
1614
1615
  'week_schedule_programming', 'online', 'holiday_mode_date', 'schedule', 'schedule_monday', 'schedule_tuesday',
1615
1616
  'schedule_wednesday', 'schedule_thursday', 'schedule_friday', 'schedule_saturday', 'schedule_sunday', 'clear_fault',
1616
1617
  'scale_protection', 'error', 'radar_scene', 'radar_sensitivity', 'tumble_alarm_time', 'tumble_switch', 'fall_sensitivity',
1617
- 'min_temperature', 'max_temperature', 'window_detection', 'boost_heating',
1618
+ 'min_temperature', 'max_temperature', 'window_detection', 'boost_heating', 'alarm_ringtone', 'alarm_time',
1618
1619
  ],
1619
1620
  convertSet: async (entity, key, value, meta) => {
1620
1621
  // A set converter is only called once; therefore we need to loop
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "15.0.45",
3
+ "version": "15.0.47",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -38,7 +38,7 @@
38
38
  "buffer-crc32": "^0.2.13",
39
39
  "https-proxy-agent": "^5.0.1",
40
40
  "tar-stream": "^3.0.0",
41
- "zigbee-herdsman": "^0.14.90"
41
+ "zigbee-herdsman": "^0.14.92"
42
42
  },
43
43
  "devDependencies": {
44
44
  "eslint": "*",