zigbee-herdsman-converters 14.0.635 → 14.0.636

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/hive.js CHANGED
@@ -344,7 +344,7 @@ module.exports = [
344
344
  },
345
345
  exposes: [
346
346
  exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 32, 0.5).withLocalTemperature()
347
- .withSystemMode(['off', 'auto', 'heat']).withRunningState(['idle', 'heat']).withEndpoint('heat'),
347
+ .withSystemMode(['off', 'auto', 'heat', 'emergency_heating']).withRunningState(['idle', 'heat']).withEndpoint('heat'),
348
348
  exposes.binary('temperature_setpoint_hold', ea.ALL, true, false)
349
349
  .withDescription('Prevent changes. `false` = run normally. `true` = prevent from making changes.' +
350
350
  ' Must be set to `false` when system_mode = off or `true` for heat').withEndpoint('heat'),
@@ -396,7 +396,7 @@ module.exports = [
396
396
  },
397
397
  exposes: [
398
398
  exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 32, 0.5).withLocalTemperature()
399
- .withSystemMode(['off', 'auto', 'heat']).withRunningState(['idle', 'heat']).withEndpoint('heat'),
399
+ .withSystemMode(['off', 'auto', 'heat', 'emergency_heating']).withRunningState(['idle', 'heat']).withEndpoint('heat'),
400
400
  exposes.binary('temperature_setpoint_hold', ea.ALL, true, false)
401
401
  .withDescription('Prevent changes. `false` = run normally. `true` = prevent from making changes.' +
402
402
  ' Must be set to `false` when system_mode = off or `true` for heat').withEndpoint('heat'),
package/devices/namron.js CHANGED
@@ -1,5 +1,6 @@
1
+ const herdsman = require('zigbee-herdsman');
1
2
  const exposes = require('../lib/exposes');
2
- const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
+ const fz = require('../converters/fromZigbee');
3
4
  const tz = require('../converters/toZigbee');
4
5
  const constants = require('../lib/constants');
5
6
  const reporting = require('../lib/reporting');
@@ -8,6 +9,90 @@ const extend = require('../lib/extend');
8
9
  const ea = exposes.access;
9
10
  const e = exposes.presets;
10
11
 
12
+ const sunricherManufacturer = {manufacturerCode: herdsman.Zcl.ManufacturerCode.SHENZHEN_SUNRICH};
13
+
14
+ const fzLocal = {
15
+ namron_panelheater: {
16
+ cluster: 'hvacThermostat',
17
+ type: ['attributeReport', 'readResponse'],
18
+ convert: (model, msg, publish, options, meta) => {
19
+ const result = {};
20
+ const data = msg.data;
21
+ if (data.hasOwnProperty(0x1000)) { // OperateDisplayBrightnesss
22
+ result.display_brightnesss = data[0x1000];
23
+ }
24
+ if (data.hasOwnProperty(0x1001)) { // DisplayAutoOffActivation
25
+ const lookup = {0: 'deactivated', 1: 'activated'};
26
+ result.display_auto_off = lookup[data[0x1001]];
27
+ }
28
+ if (data.hasOwnProperty(0x1004)) { // PowerUpStatus
29
+ const lookup = {0: 'manual', 1: 'last_state'};
30
+ result.power_up_status = lookup[data[0x1004]];
31
+ }
32
+ if (data.hasOwnProperty(0x1009)) { // WindowOpenCheck
33
+ const lookup = {0: 'enable', 1: 'disable'};
34
+ result.window_open_check = lookup[data[0x1009]];
35
+ }
36
+ if (data.hasOwnProperty(0x100A)) { // Hysterersis
37
+ result.hysterersis = data[0x100A];
38
+ }
39
+ return result;
40
+ },
41
+ },
42
+ };
43
+
44
+ const tzLocal = {
45
+ namron_panelheater: {
46
+ key: [
47
+ 'display_brightnesss', 'display_auto_off',
48
+ 'power_up_status', 'window_open_check', 'hysterersis',
49
+ ],
50
+ convertSet: async (entity, key, value, meta) => {
51
+ if (key === 'display_brightnesss') {
52
+ const payload = {0x1000: {value: value, type: herdsman.Zcl.DataType.enum8}};
53
+ await entity.write('hvacThermostat', payload, sunricherManufacturer);
54
+ } else if (key === 'display_auto_off') {
55
+ const lookup = {'deactivated': 0, 'activated': 1};
56
+ const payload = {0x1001: {value: lookup[value], type: herdsman.Zcl.DataType.enum8}};
57
+ await entity.write('hvacThermostat', payload, sunricherManufacturer);
58
+ } else if (key === 'power_up_status') {
59
+ const lookup = {'manual': 0, 'last_state': 1};
60
+ const payload = {0x1004: {value: lookup[value], type: herdsman.Zcl.DataType.enum8}};
61
+ await entity.write('hvacThermostat', payload, sunricherManufacturer);
62
+ } else if (key==='window_open_check') {
63
+ const lookup = {'enable': 0, 'disable': 1};
64
+ const payload = {0x1009: {value: lookup[value], type: herdsman.Zcl.DataType.enum8}};
65
+ await entity.write('hvacThermostat', payload, sunricherManufacturer);
66
+ } else if (key==='hysterersis') {
67
+ const payload = {0x100A: {value: value, type: 0x20}};
68
+ await entity.write('hvacThermostat', payload, sunricherManufacturer);
69
+ }
70
+ },
71
+ convertGet: async (entity, key, meta) => {
72
+ switch (key) {
73
+ case 'display_brightnesss':
74
+ await entity.read('hvacThermostat', [0x1000], sunricherManufacturer);
75
+ break;
76
+ case 'display_auto_off':
77
+ await entity.read('hvacThermostat', [0x1001], sunricherManufacturer);
78
+ break;
79
+ case 'power_up_status':
80
+ await entity.read('hvacThermostat', [0x1004], sunricherManufacturer);
81
+ break;
82
+ case 'window_open_check':
83
+ await entity.read('hvacThermostat', [0x1009], sunricherManufacturer);
84
+ break;
85
+ case 'hysterersis':
86
+ await entity.read('hvacThermostat', [0x100A], sunricherManufacturer);
87
+ break;
88
+
89
+ default: // Unknown key
90
+ throw new Error(`Unhandled key toZigbee.namron_panelheater.convertGet ${key}`);
91
+ }
92
+ },
93
+ },
94
+ };
95
+
11
96
  module.exports = [
12
97
  {
13
98
  zigbeeModel: ['3308431'],
@@ -502,4 +587,109 @@ module.exports = [
502
587
  await endpoint.read('hvacThermostat', [0x2001, 0x2002], options);
503
588
  },
504
589
  },
590
+ {
591
+ zigbeeModel: ['5401392', '5401396', '5401393', '5401397', '5401394', '5401398', '5401395', '5401399'],
592
+ model: '540139X',
593
+ vendor: 'Namron',
594
+ description: 'Panel heater 400/600/800/1000 W',
595
+ fromZigbee: [fz.thermostat, fz.metering, fz.electrical_measurement, fzLocal.namron_panelheater, fz.namron_hvac_user_interface],
596
+ toZigbee: [tz.thermostat_occupied_heating_setpoint, tz.thermostat_local_temperature_calibration, tz.thermostat_system_mode,
597
+ tz.thermostat_running_state, tz.thermostat_local_temperature, tzLocal.namron_panelheater, tz.namron_thermostat_child_lock],
598
+ exposes: [e.power(), e.current(), e.voltage(), e.energy(),
599
+ exposes.climate()
600
+ .withSetpoint('occupied_heating_setpoint', 5, 35, 0.5)
601
+ .withLocalTemperature()
602
+ // Unit also supports Auto, but i havent added support the scheduler yet
603
+ // so the function is not listed for now, as this doesn´t allow you the set the temperature
604
+ .withSystemMode(['off', 'heat'])
605
+ .withLocalTemperatureCalibration(-3, 3, 0.1)
606
+ .withRunningState(['idle', 'heat']),
607
+ // Namron proprietary stuff
608
+ exposes.binary('child_lock', ea.ALL, 'LOCK', 'UNLOCK')
609
+ .withDescription('Enables/disables physical input on the device'),
610
+ exposes.numeric('hysterersis', ea.ALL)
611
+ .withUnit('°C')
612
+ .withValueMin(5).withValueMax(50).withValueStep(0.1)
613
+ .withDescription('Hysterersis setting, range is 5-50, unit is 0.1oC, Default: 5.'),
614
+ exposes.numeric('display_brightnesss', ea.ALL)
615
+ .withValueMin(1).withValueMax(7).withValueStep(1)
616
+ .withDescription('Adjust brightness of display values 1(Low)-7(High)'),
617
+ exposes.enum('display_auto_off', ea.ALL, ['deactivated', 'activated'])
618
+ .withDescription('Enable / Disable display auto off'),
619
+ exposes.enum('power_up_status', ea.ALL, ['manual', 'last_state'])
620
+ .withDescription('The mode after a power reset. Default: Previous Mode. See instructions for information about manual'),
621
+ exposes.enum('window_open_check', ea.ALL, ['enable', 'disable'])
622
+ .withDescription('Turn on/off window check mode'),
623
+ ],
624
+ configure: async (device, coordinatorEndpoint, logger) => {
625
+ const endpoint = device.getEndpoint(1);
626
+ const binds = [
627
+ 'genBasic', 'genIdentify', 'hvacThermostat', 'seMetering', 'haElectricalMeasurement', 'genAlarms',
628
+ 'genTime', 'hvacUserInterfaceCfg',
629
+ ];
630
+
631
+ // Reporting
632
+
633
+ // Metering
634
+ await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
635
+ await reporting.readMeteringMultiplierDivisor(endpoint);
636
+ await reporting.rmsVoltage(endpoint, {min: 10, change: 20}); // Voltage - Min change of 2v
637
+ await reporting.rmsCurrent(endpoint, {min: 10, change: 10}); // A - z2m displays only the first decimals, so change of 10 (0,01)
638
+ await reporting.activePower(endpoint, {min: 10, change: 15}); // W - Min change of 1,5W
639
+ await reporting.currentSummDelivered(endpoint, {min: 300}); // Report KWH every 5min
640
+
641
+ // Thermostat reporting
642
+ await reporting.thermostatTemperature(endpoint);
643
+ await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
644
+ await reporting.thermostatTemperature(endpoint);
645
+ await reporting.thermostatKeypadLockMode(endpoint);
646
+ // LocalTemp is spammy, reports 0.01C diff by default, min change is now 0.5C
647
+ await reporting.thermostatTemperature(endpoint, {min: 0, change: 50});
648
+
649
+ // Namron proprietary stuff
650
+ const options = {manufacturerCode: 0x1224};
651
+
652
+ // display_brightnesss
653
+ await endpoint.configureReporting('hvacThermostat', [{
654
+ attribute: {ID: 0x1000, type: 0x30},
655
+ minimumReportInterval: 0,
656
+ maximumReportInterval: constants.repInterval.HOUR,
657
+ reportableChange: null}],
658
+ options);
659
+ // display_auto_off
660
+ await endpoint.configureReporting('hvacThermostat', [{
661
+ attribute: {ID: 0x1001, type: 0x30},
662
+ minimumReportInterval: 0,
663
+ maximumReportInterval: constants.repInterval.HOUR,
664
+ reportableChange: null}],
665
+ options);
666
+ // power_up_status
667
+ await endpoint.configureReporting('hvacThermostat', [{
668
+ attribute: {ID: 0x1004, type: 0x30},
669
+ minimumReportInterval: 0,
670
+ maximumReportInterval: constants.repInterval.HOUR,
671
+ reportableChange: null}],
672
+ options);
673
+ // window_open_check
674
+ await endpoint.configureReporting('hvacThermostat', [{
675
+ attribute: {ID: 0x1009, type: 0x30},
676
+ minimumReportInterval: 0,
677
+ maximumReportInterval: constants.repInterval.HOUR,
678
+ reportableChange: null}],
679
+ options);
680
+ // hysterersis
681
+ await endpoint.configureReporting('hvacThermostat', [{
682
+ attribute: {ID: 0x100A, type: 0x20},
683
+ minimumReportInterval: 0,
684
+ maximumReportInterval: constants.repInterval.HOUR,
685
+ reportableChange: null}],
686
+ options);
687
+
688
+ await endpoint.read('hvacThermostat', ['systemMode', 'runningState', 'occupiedHeatingSetpoint']);
689
+ await endpoint.read('hvacUserInterfaceCfg', ['keypadLockout']);
690
+ await endpoint.read('hvacThermostat', [0x1000, 0x1001, 0x1004, 0x1009, 0x100A], options);
691
+
692
+ await reporting.bind(endpoint, coordinatorEndpoint, binds);
693
+ },
694
+ },
505
695
  ];
@@ -1505,6 +1505,13 @@ module.exports = [
1505
1505
  description: 'Hue white PAR38 outdoor',
1506
1506
  extend: hueExtend.light_onoff_brightness(),
1507
1507
  },
1508
+ {
1509
+ zigbeeModel: ['LWS001'],
1510
+ model: '9290018189',
1511
+ vendor: 'Philips',
1512
+ description: 'Hue white PAR38 outdoor',
1513
+ extend: hueExtend.light_onoff_brightness(),
1514
+ },
1508
1515
  {
1509
1516
  zigbeeModel: ['LLC010'],
1510
1517
  model: '7199960PH',
@@ -180,7 +180,7 @@ module.exports = [
180
180
  },
181
181
  },
182
182
  {
183
- zigbeeModel: ['Micro Smart Dimmer', 'SM311', 'HK-SL-RDIM-A'],
183
+ zigbeeModel: ['Micro Smart Dimmer', 'SM311', 'HK-SL-RDIM-A', 'HK-SL-DIM-EU-A'],
184
184
  model: 'ZG2835RAC',
185
185
  vendor: 'Sunricher',
186
186
  description: 'ZigBee knob smart dimmer',
package/devices/tuya.js CHANGED
@@ -930,6 +930,7 @@ module.exports = [
930
930
  {modelID: 'TS0503B', manufacturerName: '_TZ3210_trm3l2aw'},
931
931
  {modelID: 'TS0503B', manufacturerName: '_TZ3210_95txyzbx'},
932
932
  {modelID: 'TS0503B', manufacturerName: '_TZ3210_odlghna1'},
933
+ {modelID: 'TS0503B', manufacturerName: '_TZB210_nfzrlz29'},
933
934
  {modelID: 'TS0503B', manufacturerName: '_TZ3220_wp1k8xws'},
934
935
  {modelID: 'TS0503B', manufacturerName: '_TZ3210_wp1k8xws'}],
935
936
  model: 'TS0503B',
@@ -1027,7 +1028,9 @@ module.exports = [
1027
1028
  configure: async (device, coordinatorEndpoint, logger) => {
1028
1029
  const endpoint = device.getEndpoint(1);
1029
1030
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
1030
- await reporting.batteryPercentageRemaining(endpoint);
1031
+ try {
1032
+ await reporting.batteryPercentageRemaining(endpoint);
1033
+ } catch (error) {/* Fails for some https://github.com/Koenkk/zigbee2mqtt/issues/13708*/}
1031
1034
  },
1032
1035
  },
1033
1036
  {
@@ -1953,6 +1956,7 @@ module.exports = [
1953
1956
  {modelID: 'TS0601', manufacturerName: '_TZE200_lllliz3p'}, /* model: 'TV02-Zigbee', vendor: 'TuYa' */
1954
1957
  {modelID: 'TS0601', manufacturerName: '_TZE200_mudxchsu'}, /* model: 'TV05-ZG curve', vendor: 'TuYa' */
1955
1958
  {modelID: 'TS0601', manufacturerName: '_TZE200_7yoranx2'}, /* model: 'TV01-ZB', vendor: 'Moes' */
1959
+ {modelID: 'TS0601', manufacturerName: '_TZE200_kds0pmmv'}, /* model: 'TV01-ZB', vendor: 'Moes' */
1956
1960
  ],
1957
1961
  model: 'TV02-Zigbee',
1958
1962
  vendor: 'TuYa',
@@ -2250,6 +2254,35 @@ module.exports = [
2250
2254
  exposes.binary('silence_siren', ea.STATE_SET, true, false).withDescription('Silence the siren')],
2251
2255
  onEvent: tuya.onEventsetTime,
2252
2256
  },
2257
+ {
2258
+ fingerprint: tuya.fingerprint('TS0601', ['_TZE200_lsanae15', '_TZE200_bkkmqmyo']),
2259
+ model: 'TS0601_din_1',
2260
+ vendor: 'TuYa',
2261
+ description: 'Zigbee DIN energy meter',
2262
+ fromZigbee: [tuya.fzDataPoints],
2263
+ toZigbee: [tuya.tzDataPoints],
2264
+ configure: tuya.configureMagicPacket,
2265
+ exposes: [tuya.exposes.switch, e.ac_frequency(), e.energy(), e.power(), e.power_factor(), e.voltage(), e.current()],
2266
+ meta: {
2267
+ tuyaDatapoints: [
2268
+ [1, 'energy', tuya.valueConverter.divideBy100],
2269
+ [6, null, tuya.valueConverterMultiProperty.phaseA], // voltage and current
2270
+ [16, 'state', tuya.valueConverter.onOff],
2271
+ [103, 'power', tuya.valueConverterBasic.raw],
2272
+ [105, 'ac_frequency', tuya.valueConverter.divideBy100],
2273
+ [111, 'power_factor', tuya.valueConverter.divideBy10],
2274
+ // Ignored for now; we don't know what the values mean
2275
+ [109, null, null], // reactive_power in VArh, ignored for now
2276
+ [101, null, null], // total active power (translated from chinese) - same as energy dp 1??
2277
+ [102, null, null], // Reverse active power (translated from chinese), produced power? (e.g. if solar panels are connected)
2278
+ [9, null, null], // Fault - we don't know the possible values here
2279
+ [110, null, null], // total reactive power (translated from chinese) - value is 0.03kvar, we already have kvarh on dp 109
2280
+ [17, null, null], // Alarm set1 - value seems garbage "AAAAAAAAAAAAAABkAAEOAACqAAAAAAAKAAAAAAAA"
2281
+ [18, null, null], // 18 - Alarm set2 - value seems garbage "AAUAZAAFAB4APAAAAAAAAAA="
2282
+ ],
2283
+ },
2284
+ whiteLabel: [{vendor: 'Hiking', model: 'DDS238-2'}, {vendor: 'TuYa', model: 'RC-MCB'}],
2285
+ },
2253
2286
  {
2254
2287
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_byzdayie'},
2255
2288
  {modelID: 'TS0601', manufacturerName: '_TZE200_fsb6zw01'},
@@ -2265,19 +2298,6 @@ module.exports = [
2265
2298
  },
2266
2299
  exposes: [e.switch().setAccess('state', ea.STATE_SET), e.voltage(), e.power(), e.current(), e.energy()],
2267
2300
  },
2268
- {
2269
- fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_bkkmqmyo'}],
2270
- model: 'DDS238-2',
2271
- vendor: 'TuYa',
2272
- description: 'Zigbee smart energy meter',
2273
- fromZigbee: [fzLocal.tuya_dinrail_switch2],
2274
- toZigbee: [tz.tuya_switch_state],
2275
- configure: async (device, coordinatorEndpoint, logger) => {
2276
- const endpoint = device.getEndpoint(1);
2277
- await reporting.bind(endpoint, coordinatorEndpoint, ['genBasic']);
2278
- },
2279
- exposes: [e.switch().setAccess('state', ea.STATE_SET), e.energy(), e.power()],
2280
- },
2281
2301
  {
2282
2302
  fingerprint: [{modelID: 'TS1101', manufacturerName: '_TZ3000_xfs39dbf'}],
2283
2303
  model: 'TS1101_dimmer_module_1ch',
package/devices/xiaomi.js CHANGED
@@ -1419,7 +1419,7 @@ module.exports = [
1419
1419
  exposes.numeric('gas_density', ea.STATE_GET).withUnit('%LEL').withDescription('Value of gas concentration'),
1420
1420
  exposes.enum('gas_sensitivity', ea.ALL, ['10%LEL', '15%LEL']).withDescription('Gas concentration value at which ' +
1421
1421
  'an alarm is triggered ("10%LEL" is more sensitive than "15%LEL")'),
1422
- exposes.enum('selftest', ea.SET, ['']).withDescription('Starts the self-test process (checking the indicator ' +
1422
+ exposes.enum('selftest', ea.SET, ['selftest']).withDescription('Starts the self-test process (checking the indicator ' +
1423
1423
  'light and buzzer work properly)'),
1424
1424
  exposes.binary('test', ea.STATE, true, false).withDescription('Self-test in progress'),
1425
1425
  exposes.enum('buzzer', ea.SET, ['mute', 'alarm']).withDescription('The buzzer can be muted and alarmed manually. ' +
@@ -1459,7 +1459,7 @@ module.exports = [
1459
1459
  exposes: [e.smoke().withAccess(ea.STATE_GET),
1460
1460
  exposes.numeric('smoke_density', ea.STATE_GET).withDescription('Value of smoke concentration'),
1461
1461
  exposes.numeric('smoke_density_dbm', ea.STATE_GET).withUnit('dB/m').withDescription('Value of smoke concentration in dB/m'),
1462
- exposes.enum('selftest', ea.SET, ['']).withDescription('Starts the self-test process (checking the indicator ' +
1462
+ exposes.enum('selftest', ea.SET, ['selftest']).withDescription('Starts the self-test process (checking the indicator ' +
1463
1463
  'light and buzzer work properly)'),
1464
1464
  exposes.binary('test', ea.STATE, true, false).withDescription('Self-test in progress'),
1465
1465
  exposes.enum('buzzer', ea.SET, ['mute', 'alarm']).withDescription('The buzzer can be muted and alarmed manually. ' +
package/lib/tuya.js CHANGED
@@ -1145,6 +1145,7 @@ const tuyaExposes = {
1145
1145
  'min_brightness', ea.STATE_SET).setAccess('max_brightness', ea.STATE_SET),
1146
1146
  countdown: exposes.numeric('countdown', ea.STATE_SET).withValueMin(0).withValueMax(43200).withValueStep(1).withUnit('s')
1147
1147
  .withDescription('Countdown to turn device off after a certain time'),
1148
+ switch: e.switch().setAccess('state', ea.STATE_SET),
1148
1149
  };
1149
1150
 
1150
1151
  const skip = {
@@ -1182,9 +1183,7 @@ const valueConverterBasic = {
1182
1183
  scale: (min1, max1, min2, max2) => {
1183
1184
  return {to: (v) => utils.mapNumberRange(v, min1, max1, min2, max2), from: (v) => utils.mapNumberRange(v, min2, max2, min1, max1)};
1184
1185
  },
1185
- raw: () => {
1186
- return {to: (v) => v, from: (v) => v};
1187
- },
1186
+ raw: {to: (v) => v, from: (v) => v},
1188
1187
  divideBy: (value) => {
1189
1188
  return {to: (v) => v * value, from: (v) => v / value};
1190
1189
  },
@@ -1195,10 +1194,20 @@ const valueConverter = {
1195
1194
  onOff: valueConverterBasic.lookup({'ON': true, 'OFF': false}),
1196
1195
  powerOnBehavior: valueConverterBasic.lookup({'off': 0, 'on': 1, 'previous': 2}),
1197
1196
  lightType: valueConverterBasic.lookup({'led': 0, 'incandescent': 1, 'halogen': 2}),
1198
- countdown: valueConverterBasic.raw(),
1197
+ countdown: valueConverterBasic.raw,
1199
1198
  scale0_254to0_1000: valueConverterBasic.scale(0, 254, 0, 1000),
1200
1199
  scale0_1to0_1000: valueConverterBasic.scale(0, 1, 0, 1000),
1201
1200
  divideBy100: valueConverterBasic.divideBy(100),
1201
+ divideBy10: valueConverterBasic.divideBy(10),
1202
+ };
1203
+
1204
+ const valueConverterMultiProperty = {
1205
+ phaseA: {
1206
+ from: (v) => {
1207
+ const buffer = Buffer.from(v, 'base64');
1208
+ return {voltage: (buffer[14] | buffer[13] << 8) / 10, current: (buffer[12] | buffer[11] << 8) / 1000};
1209
+ },
1210
+ },
1202
1211
  };
1203
1212
 
1204
1213
  const tzDataPoints = {
@@ -1234,7 +1243,7 @@ const fzDataPoints = {
1234
1243
  cluster: 'manuSpecificTuya',
1235
1244
  type: ['commandDataResponse', 'commandDataReport'],
1236
1245
  convert: (model, msg, publish, options, meta) => {
1237
- const result = {};
1246
+ let result = {};
1238
1247
  if (!model.meta || !model.meta.tuyaDatapoints) throw new Error('No datapoints map defined');
1239
1248
  const datapoints = model.meta.tuyaDatapoints;
1240
1249
  for (const dpValue of msg.data.dpValues) {
@@ -1242,7 +1251,11 @@ const fzDataPoints = {
1242
1251
  const dpEntry = datapoints.find((d) => d[0] === dpId);
1243
1252
  if (dpEntry) {
1244
1253
  const value = getDataValue(dpValue);
1245
- result[dpEntry[1]] = dpEntry[2].from(value);
1254
+ if (dpEntry[1]) {
1255
+ result[dpEntry[1]] = dpEntry[2].from(value);
1256
+ } else if (dpEntry[2]) {
1257
+ result = {...result, ...dpEntry[2].from(value)};
1258
+ }
1246
1259
  } else {
1247
1260
  meta.logger.warn(`Datapoint ${dpId} not defined for '${meta.device.manufacturerName}' ` +
1248
1261
  `with data ${JSON.stringify(dpValue)}`);
@@ -1257,6 +1270,7 @@ module.exports = {
1257
1270
  skip,
1258
1271
  configureMagicPacket,
1259
1272
  fingerprint,
1273
+ valueConverterMultiProperty,
1260
1274
  valueConverterBasic,
1261
1275
  valueConverter,
1262
1276
  tzDataPoints,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.635",
3
+ "version": "14.0.636",
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": "^2.2.0",
41
- "zigbee-herdsman": "^0.14.62"
41
+ "zigbee-herdsman": "^0.14.63"
42
42
  },
43
43
  "devDependencies": {
44
44
  "eslint": "*",