zigbee-herdsman-converters 14.0.459 → 14.0.460

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.
@@ -3392,6 +3392,23 @@ const converters = {
3392
3392
  if (msg.data.hasOwnProperty('danfossLoadEstimate')) {
3393
3393
  result[postfixWithEndpointName('load_estimate', msg, model)] = msg.data['danfossLoadEstimate'];
3394
3394
  }
3395
+ if (msg.data.hasOwnProperty('danfossPreheatStatus')) {
3396
+ result[postfixWithEndpointName('preheat_status', msg, model)] = (msg.data['danfossPreheatStatus'] === 1);
3397
+ }
3398
+ if (msg.data.hasOwnProperty('danfossAdaptionRunStatus')) {
3399
+ result[postfixWithEndpointName('adaptation_run_status', msg, model)] =
3400
+ constants.danfossAdaptionRunStatus[msg.data['danfossAdaptionRunStatus']];
3401
+ }
3402
+ if (msg.data.hasOwnProperty('danfossAdaptionRunSettings')) {
3403
+ result[postfixWithEndpointName('adaptation_run_settings', msg, model)] = (msg.data['danfossAdaptionRunSettings'] === 1);
3404
+ }
3405
+ if (msg.data.hasOwnProperty('danfossAdaptionRunControl')) {
3406
+ result[postfixWithEndpointName('adaptation_run_control', msg, model)] =
3407
+ constants.danfossAdaptionRunControl[msg.data['danfossAdaptionRunControl']];
3408
+ }
3409
+ if (msg.data.hasOwnProperty('danfossRegulationSetpointOffset')) {
3410
+ result[postfixWithEndpointName('regulation_setpoint_offset', msg, model)] = msg.data['danfossRegulationSetpointOffset'];
3411
+ }
3395
3412
  // Danfoss Icon Converters
3396
3413
  if (msg.data.hasOwnProperty('danfossRoomStatusCode')) {
3397
3414
  result[postfixWithEndpointName('room_status_code', msg, model)] =
@@ -5662,38 +5679,15 @@ const converters = {
5662
5679
  type: ['attributeReport', 'readResponse'],
5663
5680
  options: [exposes.options.invert_cover()],
5664
5681
  convert: (model, msg, publish, options, meta) => {
5665
- let running = false;
5666
-
5667
5682
  if (model.model === 'ZNCLDJ12LM' && msg.type === 'attributeReport' && [0, 2].includes(msg.data['presentValue'])) {
5668
5683
  // Incorrect reports from the device, ignore (re-read by onEvent of ZNCLDJ12LM)
5669
5684
  // https://github.com/Koenkk/zigbee-herdsman-converters/pull/1427#issuecomment-663862724
5670
5685
  return;
5671
5686
  }
5672
5687
 
5673
- if (msg.data['61440']) {
5674
- const value = msg.data['61440'];
5675
- // 63025664 comes from https://github.com/Koenkk/zigbee2mqtt/issues/5155#issuecomment-753344248
5676
- running = value !== 0 && value !== 63025664;
5677
- }
5678
-
5679
5688
  let position = precisionRound(msg.data['presentValue'], 2);
5680
5689
  position = options.invert_cover ? 100 - position : position;
5681
- return {position: position, running: running};
5682
- },
5683
- },
5684
- xiaomi_curtain_options: {
5685
- cluster: 'genBasic',
5686
- type: ['attributeReport', 'readResponse'],
5687
- convert: (model, msg, publish, options, meta) => {
5688
- const data = msg.data['1025'];
5689
- if (data) {
5690
- return {
5691
- options: { // next values update only when curtain finished initial setup and knows current position
5692
- reverse_direction: data[2]=='\u0001',
5693
- hand_open: data[5]=='\u0000',
5694
- },
5695
- };
5696
- }
5690
+ return {position};
5697
5691
  },
5698
5692
  },
5699
5693
  xiaomi_curtain_acn002_position: {
@@ -2854,6 +2854,53 @@ const converters = {
2854
2854
  await entity.read('hvacThermostat', ['danfossLoadEstimate'], manufacturerOptions.danfoss);
2855
2855
  },
2856
2856
  },
2857
+ danfoss_preheat_status: {
2858
+ key: ['preheat_status'],
2859
+ convertGet: async (entity, key, meta) => {
2860
+ await entity.read('hvacThermostat', ['danfossPreheatStatus'], manufacturerOptions.danfoss);
2861
+ },
2862
+ },
2863
+ danfoss_adaptation_status: {
2864
+ key: ['adaptation_run_status'],
2865
+ convertGet: async (entity, key, meta) => {
2866
+ await entity.read('hvacThermostat', ['danfossAdaptionRunStatus'], manufacturerOptions.danfoss);
2867
+ },
2868
+ },
2869
+ danfoss_adaptation_settings: {
2870
+ key: ['adaptation_run_settings'],
2871
+ convertSet: async (entity, key, value, meta) => {
2872
+ await entity.write('hvacThermostat', {'danfossAdaptionRunSettings': value}, manufacturerOptions.danfoss);
2873
+ return {readAfterWriteTime: 200, state: {'adaptation_run_settings': value}};
2874
+ },
2875
+
2876
+ convertGet: async (entity, key, meta) => {
2877
+ await entity.read('hvacThermostat', ['danfossAdaptionRunSettings'], manufacturerOptions.danfoss);
2878
+ },
2879
+ },
2880
+ danfoss_adaptation_control: {
2881
+ key: ['adaptation_run_control'],
2882
+ convertSet: async (entity, key, value, meta) => {
2883
+ const payload = {'danfossAdaptionRunControl': utils.getKey(constants.danfossAdaptionRunControl, value, value, Number)};
2884
+ await entity.write('hvacThermostat', payload, manufacturerOptions.danfoss);
2885
+ return {readAfterWriteTime: 250, state: {'adaptation_run_control': value}};
2886
+ },
2887
+
2888
+ convertGet: async (entity, key, meta) => {
2889
+ await entity.read('hvacThermostat', ['danfossAdaptionRunControl'], manufacturerOptions.danfoss);
2890
+ },
2891
+ },
2892
+ danfoss_regulation_setpoint_offset: {
2893
+ key: ['regulation_setpoint_offset'],
2894
+ convertSet: async (entity, key, value, meta) => {
2895
+ const payload = {'danfossRegulationSetpointOffset': value};
2896
+ await entity.write('hvacThermostat', payload, manufacturerOptions.danfoss);
2897
+ return {readAfterWriteTime: 250, state: {'regulation_setpoint_offset': value}};
2898
+ },
2899
+
2900
+ convertGet: async (entity, key, meta) => {
2901
+ await entity.read('hvacThermostat', ['danfossRegulationSetpointOffset'], manufacturerOptions.danfoss);
2902
+ },
2903
+ },
2857
2904
  danfoss_output_status: {
2858
2905
  key: ['output_status'],
2859
2906
  convertGet: async (entity, key, meta) => {
@@ -24,7 +24,8 @@ module.exports = [
24
24
  tz.danfoss_viewing_direction, tz.danfoss_external_measured_room_sensor, tz.danfoss_radiator_covered,
25
25
  tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean,
26
26
  tz.thermostat_weekly_schedule, tz.thermostat_clear_weekly_schedule, tz.thermostat_programming_operation_mode,
27
- tz.danfoss_window_open_feature],
27
+ tz.danfoss_window_open_feature, tz.danfoss_preheat_status, tz.danfoss_adaptation_status, tz.danfoss_adaptation_settings,
28
+ tz.danfoss_adaptation_control, tz.danfoss_regulation_setpoint_offset],
28
29
  exposes: [e.battery(), e.keypad_lockout(), e.programming_operation_mode(),
29
30
  exposes.binary('mounted_mode_active', ea.STATE_GET, true, false)
30
31
  .withDescription('Is the unit in mounting mode. This is set to `false` for mounted (already on ' +
@@ -78,7 +79,19 @@ module.exports = [
78
79
  .withDescription('Mean radiator load for room calculated by gateway for load balancing purposes (-8000=undefined)')
79
80
  .withValueMin(-8000).withValueMax(2000),
80
81
  exposes.numeric('load_estimate', ea.STATE_GET)
81
- .withDescription('Load estimate on this radiator')],
82
+ .withDescription('Load estimate on this radiator'),
83
+ exposes.binary('preheat_status', ea.STATE_GET, true, false)
84
+ .withDescription('Specific for pre-heat running in Zigbee Weekly Schedule mode'),
85
+ exposes.enum('adaptation_run_status', ea.STATE_GET, ['none', 'in_progress', 'found', 'lost'])
86
+ .withDescription('Status of adaptation run: None (before first run), In Progress, Valve Characteristic Found, ' +
87
+ 'Valve Characteristic Lost'),
88
+ exposes.binary('adaptation_run_settings', ea.ALL, true, false)
89
+ .withDescription('Automatic adaptation run enabled (the one during the night)'),
90
+ exposes.enum('adaptation_run_control', ea.ALL, ['initate_adaptation', 'cancel_adaptation'])
91
+ .withDescription('Adaptation run control: Initiate Adaptation Run or Cancel Adaptation Run'),
92
+ exposes.numeric('regulation_setpoint_offset', ea.ALL)
93
+ .withDescription('Regulation SetPoint Offset in range -2.5°C to 2.5°C in steps of 0.1°C. Value 2.5°C = 25.')
94
+ .withValueMin(-25).withValueMax(25)],
82
95
  ota: ota.zigbeeOTA,
83
96
  configure: async (device, coordinatorEndpoint, logger) => {
84
97
  const endpoint = device.getEndpoint(1);
@@ -117,6 +130,20 @@ module.exports = [
117
130
  reportableChange: 1,
118
131
  }], options);
119
132
 
133
+ await endpoint.configureReporting('hvacThermostat', [{
134
+ attribute: 'danfossPreheatStatus',
135
+ minimumReportInterval: constants.repInterval.MINUTE,
136
+ maximumReportInterval: constants.repInterval.MAX,
137
+ reportableChange: 1,
138
+ }], options);
139
+
140
+ await endpoint.configureReporting('hvacThermostat', [{
141
+ attribute: 'danfossAdaptionRunStatus',
142
+ minimumReportInterval: constants.repInterval.MINUTE,
143
+ maximumReportInterval: constants.repInterval.HOUR,
144
+ reportableChange: 1,
145
+ }], options);
146
+
120
147
  try {
121
148
  await endpoint.read('hvacThermostat', [
122
149
  'danfossWindowOpenFeatureEnable',
@@ -131,6 +158,9 @@ module.exports = [
131
158
  'danfossRadiatorCovered',
132
159
  'danfossLoadBalancingEnable',
133
160
  'danfossLoadRoomMean',
161
+ 'danfossAdaptionRunControl',
162
+ 'danfossAdaptionRunSettings',
163
+ 'danfossRegulationSetpointOffset',
134
164
  ], options);
135
165
  } catch (e) {
136
166
  /* not supported by all https://github.com/Koenkk/zigbee2mqtt/issues/11872 */
package/devices/niko.js CHANGED
@@ -11,17 +11,30 @@ module.exports = [
11
11
  model: '170-33505',
12
12
  vendor: 'Niko',
13
13
  description: 'Connected socket outlet',
14
- fromZigbee: [fz.on_off, fz.electrical_measurement],
15
- toZigbee: [tz.on_off, tz.electrical_measurement_power],
14
+ fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering],
15
+ toZigbee: [tz.on_off, tz.electrical_measurement_power, tz.currentsummdelivered],
16
16
  configure: async (device, coordinatorEndpoint, logger) => {
17
17
  const endpoint = device.getEndpoint(1);
18
- await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement']);
19
- await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
18
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
19
+ await reporting.onOff(endpoint);
20
+
21
+ // NOTE: we read them individually, acFrequency* is not supported
22
+ // so we cannot use readEletricalMeasurementMultiplierDivisors
23
+ await endpoint.read('haElectricalMeasurement', ['acPowerMultiplier', 'acPowerDivisor']);
20
24
  await reporting.activePower(endpoint, {min: 5, max: 3600, change: 1000});
25
+ await endpoint.read('haElectricalMeasurement', ['acCurrentDivisor', 'acPowerMultiplier', 'acPowerDivisor']);
21
26
  await reporting.rmsCurrent(endpoint, {min: 5, max: 3600, change: 100});
27
+ await endpoint.read('haElectricalMeasurement', ['acVoltageMultiplier', 'acVoltageDivisor', 'acCurrentMultiplier']);
22
28
  await reporting.rmsVoltage(endpoint, {min: 5, max: 3600, change: 100});
29
+
30
+ await reporting.readMeteringMultiplierDivisor(endpoint);
31
+ await reporting.currentSummDelivered(endpoint, {min: 60, change: 1});
23
32
  },
24
- exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.current(), e.voltage()],
33
+ exposes: [
34
+ e.switch(),
35
+ e.power().withAccess(ea.STATE_GET), e.current(), e.voltage(),
36
+ e.energy().withAccess(ea.STATE_GET),
37
+ ],
25
38
  },
26
39
  {
27
40
  zigbeeModel: ['Smart plug Zigbee PE'],
@@ -29,7 +42,7 @@ module.exports = [
29
42
  vendor: 'Niko',
30
43
  description: 'Smart plug with earthing pin',
31
44
  fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.power_on_behavior],
32
- toZigbee: [tz.on_off, tz.power_on_behavior, tz.electrical_measurement_power],
45
+ toZigbee: [tz.on_off, tz.power_on_behavior, tz.electrical_measurement_power, tz.currentsummdelivered],
33
46
  configure: async (device, coordinatorEndpoint, logger) => {
34
47
  const endpoint = device.getEndpoint(1);
35
48
  await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
@@ -41,7 +54,7 @@ module.exports = [
41
54
  await reporting.currentSummDelivered(endpoint, {min: 60, change: 1});
42
55
  },
43
56
  exposes: [
44
- e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(),
57
+ e.switch(), e.power().withAccess(ea.STATE_GET), e.energy().withAccess(ea.STATE_GET),
45
58
  exposes.enum('power_on_behavior', ea.ALL, ['off', 'previous', 'on'])
46
59
  .withDescription('Controls the behaviour when the device is powered on'),
47
60
  ],
package/devices/tuya.js CHANGED
@@ -97,13 +97,14 @@ module.exports = [
97
97
  description: 'Door sensor',
98
98
  fromZigbee: [fz.ias_contact_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_contact_alarm_1_report],
99
99
  toZigbee: [],
100
- exposes: [e.contact(), e.battery_low(), e.tamper(), e.battery()],
100
+ exposes: [e.contact(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
101
101
  whiteLabel: [{vendor: 'CR Smart Home', model: 'TS0203'}],
102
102
  configure: async (device, coordinatorEndpoint, logger) => {
103
103
  try {
104
104
  const endpoint = device.getEndpoint(1);
105
105
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
106
106
  await reporting.batteryPercentageRemaining(endpoint);
107
+ await reporting.batteryVoltage(endpoint);
107
108
  } catch (error) {/* Fails for some*/}
108
109
  },
109
110
  },
@@ -1273,7 +1274,7 @@ module.exports = [
1273
1274
  description: 'Smart plug (with power monitoring)',
1274
1275
  vendor: 'TuYa',
1275
1276
  whiteLabel: [{vendor: 'LELLKI', model: 'TS011F_plug'}, {vendor: 'NEO', model: 'NAS-WR01B'},
1276
- {vendor: 'BlitzWolf', model: 'BW-SHP15'}],
1277
+ {vendor: 'BlitzWolf', model: 'BW-SHP15'}, {vendor: 'Nous', model: 'A1Z'}],
1277
1278
  ota: ota.zigbeeOTA,
1278
1279
  fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, fz.tuya_switch_power_outage_memory,
1279
1280
  fz.ts011f_plug_indicator_mode, fz.ts011f_plug_child_mode],
@@ -1647,7 +1648,7 @@ module.exports = [
1647
1648
  },
1648
1649
  },
1649
1650
  {
1650
- zigbeeModel: ['HY0017'],
1651
+ zigbeeModel: ['HY0017', '005f0c3'],
1651
1652
  model: 'U86KCJ-ZP',
1652
1653
  vendor: 'TuYa',
1653
1654
  description: 'Smart 6 key scene wall switch',
package/devices/xiaomi.js CHANGED
@@ -1236,11 +1236,13 @@ module.exports = [
1236
1236
  model: 'ZNCLDJ11LM',
1237
1237
  description: 'Aqara curtain motor',
1238
1238
  vendor: 'Xiaomi',
1239
- fromZigbee: [fz.xiaomi_curtain_position, fz.cover_position_tilt, fz.xiaomi_curtain_options],
1239
+ fromZigbee: [fz.xiaomi_basic, fz.xiaomi_curtain_position, fz.cover_position_tilt],
1240
1240
  toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
1241
1241
  exposes: [e.cover_position().setAccess('state', ea.ALL),
1242
1242
  exposes.binary('running', ea.STATE, true, false)
1243
- .withDescription('Whether the motor is moving or not')],
1243
+ .withDescription('Whether the motor is moving or not'),
1244
+ exposes.enum('motor_state', ea.STATE, ['stopped', 'opening', 'closing'])
1245
+ .withDescription('Motor state')],
1244
1246
  ota: ota.zigbeeOTA,
1245
1247
  },
1246
1248
  {
@@ -1248,7 +1250,7 @@ module.exports = [
1248
1250
  model: 'SRSC-M01',
1249
1251
  description: 'Aqara roller shade motor',
1250
1252
  vendor: 'Xiaomi',
1251
- fromZigbee: [fz.xiaomi_curtain_position, fz.cover_position_tilt, fz.xiaomi_curtain_options],
1253
+ fromZigbee: [fz.xiaomi_basic, fz.xiaomi_curtain_position, fz.cover_position_tilt],
1252
1254
  toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
1253
1255
  exposes: [e.cover_position().setAccess('state', ea.ALL),
1254
1256
  exposes.binary('running', ea.STATE, true, false)
@@ -1259,8 +1261,8 @@ module.exports = [
1259
1261
  zigbeeModel: ['lumi.curtain.hagl04'],
1260
1262
  model: 'ZNCLDJ12LM',
1261
1263
  vendor: 'Xiaomi',
1262
- description: 'Aqara B1 curtain motor ',
1263
- fromZigbee: [fz.xiaomi_curtain_position, fz.battery, fz.cover_position_tilt, fz.ignore_basic_report, fz.xiaomi_curtain_options],
1264
+ description: 'Aqara B1 curtain motor',
1265
+ fromZigbee: [fz.xiaomi_basic, fz.xiaomi_curtain_position, fz.battery, fz.cover_position_tilt],
1264
1266
  toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
1265
1267
  onEvent: async (type, data, device) => {
1266
1268
  // The position (genAnalogOutput.presentValue) reported via an attribute contains an invaid value
package/lib/constants.js CHANGED
@@ -97,6 +97,18 @@ const temperatureDisplayMode = {
97
97
  1: 'fahrenheit',
98
98
  };
99
99
 
100
+ const danfossAdaptationRunStatus= {
101
+ 0: 'none',
102
+ 1: 'in_progress',
103
+ 2: 'found',
104
+ 4: 'lost',
105
+ };
106
+
107
+ const danfossAdaptationRunControl = {
108
+ 1: 'initate_adaptation',
109
+ 2: 'cancel_adaptation',
110
+ };
111
+
100
112
  const danfossWindowOpen = {
101
113
  0: 'quarantine',
102
114
  1: 'closed',
@@ -267,6 +279,8 @@ module.exports = {
267
279
  dayOfWeek,
268
280
  fanMode,
269
281
  temperatureDisplayMode,
282
+ danfossAdaptationRunControl,
283
+ danfossAdaptationRunStatus,
270
284
  danfossWindowOpen,
271
285
  danfossRoomStatusCode,
272
286
  danfossOutputStatus,
package/lib/xiaomi.js CHANGED
@@ -408,6 +408,18 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
408
408
  case '550':
409
409
  payload.button_switch_mode = value === 1 ? 'relay_and_usb' : 'relay';
410
410
  break;
411
+ case '1025':
412
+ payload.options = {...payload.options, // next values update only when curtain finished initial setup and knows current position
413
+ reverse_direction: value[2] == '\u0001',
414
+ hand_open: value[5] == '\u0000',
415
+ };
416
+ break;
417
+ case '1028':
418
+ payload = {...payload,
419
+ motor_state: {0: 'stopped', 1: 'opening', 2: 'closing'}[value],
420
+ running: !!value,
421
+ };
422
+ break;
411
423
  case '1033':
412
424
  if (['ZNJLBL01LM'].includes(model.model)) {
413
425
  payload.charging_status = value === 1;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.459",
3
+ "version": "14.0.460",
4
4
  "lockfileVersion": 2,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "zigbee-herdsman-converters",
9
- "version": "14.0.459",
9
+ "version": "14.0.460",
10
10
  "license": "MIT",
11
11
  "dependencies": {
12
12
  "axios": "^0.26.1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.459",
3
+ "version": "14.0.460",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [