zigbee-herdsman-converters 14.0.635 → 14.0.637

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.
@@ -516,20 +516,23 @@ module.exports = [
516
516
  return {default: 35};
517
517
  },
518
518
  configure: async (device, coordinatorEndpoint, logger) => {
519
- const endpoint1 = device.getEndpoint(35);
520
- await reporting.bind(endpoint1, coordinatorEndpoint, ['genPowerCfg']);
521
- await reporting.batteryVoltage(endpoint1, {min: constants.repInterval.HOUR, max: 43200, change: 100});
522
- await endpoint1.read('genPowerCfg', ['batteryVoltage']);
523
- await endpoint1.read('genBasic', ['develcoLedControl'], manufacturerOptions);
524
- await endpoint1.read('ssIasZone', ['develcoAlarmOffDelay'], manufacturerOptions);
519
+ const endpoint35 = device.getEndpoint(35);
520
+ await reporting.bind(endpoint35, coordinatorEndpoint, ['genPowerCfg']);
521
+ await reporting.batteryVoltage(endpoint35, {min: constants.repInterval.HOUR, max: 43200, change: 100});
522
+ try {
523
+ await endpoint35.read('ssIasZone', ['develcoAlarmOffDelay'], manufacturerOptions);
524
+ await endpoint35.read('genBasic', ['develcoLedControl'], manufacturerOptions);
525
+ } catch (error) {/* some reports of timeouts on reading these */}
525
526
 
526
- const endpoint2 = device.getEndpoint(38);
527
- await reporting.bind(endpoint2, coordinatorEndpoint, ['msTemperatureMeasurement']);
528
- await reporting.temperature(endpoint2);
527
+ const endpoint38 = device.getEndpoint(38);
528
+ await reporting.bind(endpoint38, coordinatorEndpoint, ['msTemperatureMeasurement']);
529
+ await reporting.temperature(endpoint38,
530
+ {min: constants.repInterval.MINUTE, max: constants.repInterval.MINUTES_10, change: 100});
529
531
 
530
- const endpoint3 = device.getEndpoint(39);
531
- await reporting.bind(endpoint3, coordinatorEndpoint, ['msIlluminanceMeasurement']);
532
- await reporting.illuminance(endpoint3);
532
+ const endpoint39 = device.getEndpoint(39);
533
+ await reporting.bind(endpoint39, coordinatorEndpoint, ['msIlluminanceMeasurement']);
534
+ await reporting.illuminance(endpoint39,
535
+ {min: constants.repInterval.MINUTE, max: constants.repInterval.MINUTES_10, change: 500});
533
536
  },
534
537
  },
535
538
  {
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
  ];
@@ -687,7 +687,7 @@ module.exports = [
687
687
  extend: hueExtend.light_onoff_brightness_colortemp_color(),
688
688
  },
689
689
  {
690
- zigbeeModel: ['4090531P9', '929003053601'],
690
+ zigbeeModel: ['4090531P9', '929003053601', '929003053501'],
691
691
  model: '4090531P9',
692
692
  vendor: 'Philips',
693
693
  description: 'Hue Flourish white and color ambiance ceiling light with Bluetooth',
@@ -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',
@@ -2225,6 +2229,23 @@ module.exports = [
2225
2229
  .withDescription('Plug LED indicator mode'), e.child_lock()],
2226
2230
  onEvent: tuya.onEventMeasurementPoll,
2227
2231
  },
2232
+ {
2233
+ fingerprint: tuya.fingerprint('TS0601', ['_TZE200_ntcy3xu1']),
2234
+ model: 'TS0601_smoke_1',
2235
+ vendor: 'TuYa',
2236
+ description: 'Smoke sensor',
2237
+ fromZigbee: [tuya.fzDataPoints],
2238
+ toZigbee: [tuya.tzDataPoints],
2239
+ configure: tuya.configureMagicPacket,
2240
+ exposes: [e.smoke(), e.tamper(), e.battery_low()],
2241
+ meta: {
2242
+ tuyaDatapoints: [
2243
+ [1, 'smoke', tuya.valueConverter.true0ElseFalse],
2244
+ [4, 'tamper', tuya.valueConverter.raw],
2245
+ [14, 'battery_low', tuya.valueConverter.true0ElseFalse],
2246
+ ],
2247
+ },
2248
+ },
2228
2249
  {
2229
2250
  zigbeeModel: ['5p1vj8r'],
2230
2251
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_t5p1vj8r'}, {modelID: 'TS0601', manufacturerName: '_TZE200_uebojraa'}],
@@ -2236,7 +2257,7 @@ module.exports = [
2236
2257
  exposes: [e.smoke(), e.battery()],
2237
2258
  },
2238
2259
  {
2239
- fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_5d3vhjro'}, {modelID: 'TS0601', manufacturerName: '_TZE200_ntcy3xu1'}],
2260
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_5d3vhjro'}],
2240
2261
  model: 'SA12IZL',
2241
2262
  vendor: 'TuYa',
2242
2263
  description: 'Smart smoke alarm',
@@ -2250,6 +2271,35 @@ module.exports = [
2250
2271
  exposes.binary('silence_siren', ea.STATE_SET, true, false).withDescription('Silence the siren')],
2251
2272
  onEvent: tuya.onEventsetTime,
2252
2273
  },
2274
+ {
2275
+ fingerprint: tuya.fingerprint('TS0601', ['_TZE200_lsanae15', '_TZE200_bkkmqmyo', '_TZE200_eaac7dkw']),
2276
+ model: 'TS0601_din_1',
2277
+ vendor: 'TuYa',
2278
+ description: 'Zigbee DIN energy meter',
2279
+ fromZigbee: [tuya.fzDataPoints],
2280
+ toZigbee: [tuya.tzDataPoints],
2281
+ configure: tuya.configureMagicPacket,
2282
+ exposes: [tuya.exposes.switch, e.ac_frequency(), e.energy(), e.power(), e.power_factor(), e.voltage(), e.current()],
2283
+ meta: {
2284
+ tuyaDatapoints: [
2285
+ [1, 'energy', tuya.valueConverter.divideBy100],
2286
+ [6, null, tuya.valueConverter.phaseA], // voltage and current
2287
+ [16, 'state', tuya.valueConverter.onOff],
2288
+ [103, 'power', tuya.valueConverter.raw],
2289
+ [105, 'ac_frequency', tuya.valueConverter.divideBy100],
2290
+ [111, 'power_factor', tuya.valueConverter.divideBy10],
2291
+ // Ignored for now; we don't know what the values mean
2292
+ [109, null, null], // reactive_power in VArh, ignored for now
2293
+ [101, null, null], // total active power (translated from chinese) - same as energy dp 1??
2294
+ [102, null, null], // Reverse active power (translated from chinese), produced power? (e.g. if solar panels are connected)
2295
+ [9, null, null], // Fault - we don't know the possible values here
2296
+ [110, null, null], // total reactive power (translated from chinese) - value is 0.03kvar, we already have kvarh on dp 109
2297
+ [17, null, null], // Alarm set1 - value seems garbage "AAAAAAAAAAAAAABkAAEOAACqAAAAAAAKAAAAAAAA"
2298
+ [18, null, null], // 18 - Alarm set2 - value seems garbage "AAUAZAAFAB4APAAAAAAAAAA="
2299
+ ],
2300
+ },
2301
+ whiteLabel: [{vendor: 'Hiking', model: 'DDS238-2'}, {vendor: 'TuYa', model: 'RC-MCB'}],
2302
+ },
2253
2303
  {
2254
2304
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_byzdayie'},
2255
2305
  {modelID: 'TS0601', manufacturerName: '_TZE200_fsb6zw01'},
@@ -2265,19 +2315,6 @@ module.exports = [
2265
2315
  },
2266
2316
  exposes: [e.switch().setAccess('state', ea.STATE_SET), e.voltage(), e.power(), e.current(), e.energy()],
2267
2317
  },
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
2318
  {
2282
2319
  fingerprint: [{modelID: 'TS1101', manufacturerName: '_TZ3000_xfs39dbf'}],
2283
2320
  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/devices/ynoa.js CHANGED
@@ -6,6 +6,13 @@ const e = exposes.presets;
6
6
  const extend = require('..//lib/extend');
7
7
 
8
8
  module.exports = [
9
+ {
10
+ zigbeeModel: ['ZBT-CCTLight-GU100001'],
11
+ model: '8718801528273',
12
+ vendor: 'Ynoa',
13
+ description: 'Smart LED GU10 CCT',
14
+ extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
15
+ },
9
16
  {
10
17
  zigbeeModel: ['ZBT-DIMSwitch-D0000'],
11
18
  model: '8718801528334',
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 = {
@@ -1195,10 +1196,19 @@ const valueConverter = {
1195
1196
  onOff: valueConverterBasic.lookup({'ON': true, 'OFF': false}),
1196
1197
  powerOnBehavior: valueConverterBasic.lookup({'off': 0, 'on': 1, 'previous': 2}),
1197
1198
  lightType: valueConverterBasic.lookup({'led': 0, 'incandescent': 1, 'halogen': 2}),
1198
- countdown: valueConverterBasic.raw(),
1199
+ countdown: valueConverterBasic.raw,
1199
1200
  scale0_254to0_1000: valueConverterBasic.scale(0, 254, 0, 1000),
1200
1201
  scale0_1to0_1000: valueConverterBasic.scale(0, 1, 0, 1000),
1201
1202
  divideBy100: valueConverterBasic.divideBy(100),
1203
+ divideBy10: valueConverterBasic.divideBy(10),
1204
+ raw: valueConverterBasic.raw(),
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
+ },
1211
+ true0ElseFalse: {from: (v) => v === 0},
1202
1212
  };
1203
1213
 
1204
1214
  const tzDataPoints = {
@@ -1234,7 +1244,7 @@ const fzDataPoints = {
1234
1244
  cluster: 'manuSpecificTuya',
1235
1245
  type: ['commandDataResponse', 'commandDataReport'],
1236
1246
  convert: (model, msg, publish, options, meta) => {
1237
- const result = {};
1247
+ let result = {};
1238
1248
  if (!model.meta || !model.meta.tuyaDatapoints) throw new Error('No datapoints map defined');
1239
1249
  const datapoints = model.meta.tuyaDatapoints;
1240
1250
  for (const dpValue of msg.data.dpValues) {
@@ -1242,7 +1252,11 @@ const fzDataPoints = {
1242
1252
  const dpEntry = datapoints.find((d) => d[0] === dpId);
1243
1253
  if (dpEntry) {
1244
1254
  const value = getDataValue(dpValue);
1245
- result[dpEntry[1]] = dpEntry[2].from(value);
1255
+ if (dpEntry[1]) {
1256
+ result[dpEntry[1]] = dpEntry[2].from(value);
1257
+ } else if (dpEntry[2]) {
1258
+ result = {...result, ...dpEntry[2].from(value)};
1259
+ }
1246
1260
  } else {
1247
1261
  meta.logger.warn(`Datapoint ${dpId} not defined for '${meta.device.manufacturerName}' ` +
1248
1262
  `with data ${JSON.stringify(dpValue)}`);
@@ -1257,8 +1271,8 @@ module.exports = {
1257
1271
  skip,
1258
1272
  configureMagicPacket,
1259
1273
  fingerprint,
1260
- valueConverterBasic,
1261
1274
  valueConverter,
1275
+ valueConverterBasic,
1262
1276
  tzDataPoints,
1263
1277
  fzDataPoints,
1264
1278
  sendDataPoint,
package/lib/utils.js CHANGED
@@ -121,10 +121,12 @@ function postfixWithEndpointName(value, msg, definition, meta) {
121
121
  if (definition.meta && definition.meta.multiEndpoint) {
122
122
  const endpointName = definition.hasOwnProperty('endpoint') ?
123
123
  getKey(definition.endpoint(meta.device), msg.endpoint.ID) : msg.endpoint.ID;
124
- return `${value}_${endpointName}`;
125
- } else {
126
- return value;
124
+
125
+ // NOTE: endpointName can be undefined if we have a definition.endpoint and the endpoint is
126
+ // not listed.
127
+ if (endpointName) return `${value}_${endpointName}`;
127
128
  }
129
+ return value;
128
130
  }
129
131
 
130
132
  function getKey(object, value, fallback, convertTo) {
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.637",
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": "*",