zigbee-herdsman-converters 14.0.459 → 14.0.462

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)] =
@@ -4806,6 +4823,7 @@ const converters = {
4806
4823
  0x1e: 'press_1_and_4', 0x1f: 'release_1_and_4', 0x1c: 'press_2_and_3', 0x1d: 'release_2_and_3', 0x1a: 'press_2_and_4',
4807
4824
  0x1b: 'release_2_and_4', 0x16: 'press_3_and_4', 0x17: 'release_3_and_4', 0x10: 'press_energy_bar',
4808
4825
  0x11: 'release_energy_bar', 0x0: 'press_or_release_all',
4826
+ 0x50: 'lock', 0x51: 'unlock', 0x52: 'half_open', 0x53: 'tilt',
4809
4827
  };
4810
4828
 
4811
4829
  if (!lookup.hasOwnProperty(commandID)) {
@@ -5662,38 +5680,33 @@ const converters = {
5662
5680
  type: ['attributeReport', 'readResponse'],
5663
5681
  options: [exposes.options.invert_cover()],
5664
5682
  convert: (model, msg, publish, options, meta) => {
5665
- let running = false;
5666
-
5667
5683
  if (model.model === 'ZNCLDJ12LM' && msg.type === 'attributeReport' && [0, 2].includes(msg.data['presentValue'])) {
5668
5684
  // Incorrect reports from the device, ignore (re-read by onEvent of ZNCLDJ12LM)
5669
5685
  // https://github.com/Koenkk/zigbee-herdsman-converters/pull/1427#issuecomment-663862724
5670
5686
  return;
5671
5687
  }
5672
5688
 
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
5689
  let position = precisionRound(msg.data['presentValue'], 2);
5680
5690
  position = options.invert_cover ? 100 - position : position;
5681
- return {position: position, running: running};
5691
+ return {position};
5682
5692
  },
5683
5693
  },
5684
- xiaomi_curtain_options: {
5685
- cluster: 'genBasic',
5694
+ xiaomi_curtain_position_tilt: {
5695
+ cluster: 'closuresWindowCovering',
5686
5696
  type: ['attributeReport', 'readResponse'],
5697
+ options: [exposes.options.invert_cover()],
5687
5698
  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
- };
5699
+ const result = {};
5700
+ const invert = model.meta && model.meta.coverInverted ? !options.invert_cover : options.invert_cover;
5701
+ if (msg.data.hasOwnProperty('currentPositionLiftPercentage') && msg.data['currentPositionLiftPercentage'] <= 100) {
5702
+ const value = msg.data['currentPositionLiftPercentage'];
5703
+ result[postfixWithEndpointName('position', msg, model)] = invert ? 100 - value : value;
5704
+ }
5705
+ if (msg.data.hasOwnProperty('currentPositionTiltPercentage') && msg.data['currentPositionTiltPercentage'] <= 100) {
5706
+ const value = msg.data['currentPositionTiltPercentage'];
5707
+ result[postfixWithEndpointName('tilt', msg, model)] = invert ? 100 - value : value;
5696
5708
  }
5709
+ return result;
5697
5710
  },
5698
5711
  },
5699
5712
  xiaomi_curtain_acn002_position: {
@@ -2438,18 +2438,12 @@ const converters = {
2438
2438
  } else {
2439
2439
  await entity.command('closuresWindowCovering', 'stop', {}, utils.getOptions(meta.mapped, entity));
2440
2440
  }
2441
-
2442
- // Xiaomi curtain does not send position update on stop, request this.
2443
- await entity.read('genAnalogOutput', [0x0055]);
2444
2441
  } else {
2445
2442
  const lookup = {'open': 100, 'close': 0, 'on': 100, 'off': 0};
2446
2443
 
2447
2444
  value = typeof value === 'string' ? value.toLowerCase() : value;
2448
2445
  value = lookup.hasOwnProperty(value) ? lookup[value] : value;
2449
-
2450
- if (key === 'position') {
2451
- value = meta.options.invert_cover ? 100 - value : value;
2452
- }
2446
+ value = meta.options.invert_cover ? 100 - value : value;
2453
2447
 
2454
2448
  const payload = {0x0055: {value, type: 0x39}};
2455
2449
  await entity.write('genAnalogOutput', payload);
@@ -2854,6 +2848,53 @@ const converters = {
2854
2848
  await entity.read('hvacThermostat', ['danfossLoadEstimate'], manufacturerOptions.danfoss);
2855
2849
  },
2856
2850
  },
2851
+ danfoss_preheat_status: {
2852
+ key: ['preheat_status'],
2853
+ convertGet: async (entity, key, meta) => {
2854
+ await entity.read('hvacThermostat', ['danfossPreheatStatus'], manufacturerOptions.danfoss);
2855
+ },
2856
+ },
2857
+ danfoss_adaptation_status: {
2858
+ key: ['adaptation_run_status'],
2859
+ convertGet: async (entity, key, meta) => {
2860
+ await entity.read('hvacThermostat', ['danfossAdaptionRunStatus'], manufacturerOptions.danfoss);
2861
+ },
2862
+ },
2863
+ danfoss_adaptation_settings: {
2864
+ key: ['adaptation_run_settings'],
2865
+ convertSet: async (entity, key, value, meta) => {
2866
+ await entity.write('hvacThermostat', {'danfossAdaptionRunSettings': value}, manufacturerOptions.danfoss);
2867
+ return {readAfterWriteTime: 200, state: {'adaptation_run_settings': value}};
2868
+ },
2869
+
2870
+ convertGet: async (entity, key, meta) => {
2871
+ await entity.read('hvacThermostat', ['danfossAdaptionRunSettings'], manufacturerOptions.danfoss);
2872
+ },
2873
+ },
2874
+ danfoss_adaptation_control: {
2875
+ key: ['adaptation_run_control'],
2876
+ convertSet: async (entity, key, value, meta) => {
2877
+ const payload = {'danfossAdaptionRunControl': utils.getKey(constants.danfossAdaptionRunControl, value, value, Number)};
2878
+ await entity.write('hvacThermostat', payload, manufacturerOptions.danfoss);
2879
+ return {readAfterWriteTime: 250, state: {'adaptation_run_control': value}};
2880
+ },
2881
+
2882
+ convertGet: async (entity, key, meta) => {
2883
+ await entity.read('hvacThermostat', ['danfossAdaptionRunControl'], manufacturerOptions.danfoss);
2884
+ },
2885
+ },
2886
+ danfoss_regulation_setpoint_offset: {
2887
+ key: ['regulation_setpoint_offset'],
2888
+ convertSet: async (entity, key, value, meta) => {
2889
+ const payload = {'danfossRegulationSetpointOffset': value};
2890
+ await entity.write('hvacThermostat', payload, manufacturerOptions.danfoss);
2891
+ return {readAfterWriteTime: 250, state: {'regulation_setpoint_offset': value}};
2892
+ },
2893
+
2894
+ convertGet: async (entity, key, meta) => {
2895
+ await entity.read('hvacThermostat', ['danfossRegulationSetpointOffset'], manufacturerOptions.danfoss);
2896
+ },
2897
+ },
2857
2898
  danfoss_output_status: {
2858
2899
  key: ['output_status'],
2859
2900
  convertGet: async (entity, key, meta) => {
package/devices/awox.js CHANGED
@@ -183,7 +183,7 @@ module.exports = [
183
183
  model: '33943/33944/33946',
184
184
  vendor: 'AwoX',
185
185
  description: 'LED RGB & brightness',
186
- extend: extend.light_onoff_brightness_colortemp_color(),
186
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370], supportsHS: true}),
187
187
  },
188
188
  {
189
189
  fingerprint: [
@@ -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 */
@@ -28,7 +28,8 @@ module.exports = [
28
28
  exposes: [e.action(['press_1', 'release_1', 'press_2', 'release_2', 'press_3', 'release_3', 'press_4', 'release_4',
29
29
  'press_1_and_2', 'release_1_and_2', 'press_1_and_3', 'release_1_and_3', 'press_1_and_4', 'release_1_and_4',
30
30
  'press_2_and_3', 'release_2_and_3', 'press_2_and_4', 'release_2_and_4', 'press_3_and_4', 'release_3_and_4',
31
- 'press_energy_bar', 'release_energy_bar', 'press_or_release_all'])],
31
+ 'press_energy_bar', 'release_energy_bar', 'press_or_release_all',
32
+ 'lock', 'unlock', 'half_open', 'tilt'])],
32
33
  whiteLabel: [
33
34
  {vendor: 'Easyfit by EnOcean', description: 'Wall switch for Zigbee', model: 'EWSxZ'},
34
35
  {vendor: 'Trio2sys', description: 'Zigbee Green Power complete switch', model: '20020002'},
@@ -2,8 +2,20 @@ const reporting = require('../lib/reporting');
2
2
  const extend = require('../lib/extend');
3
3
  const exposes = require('../lib/exposes');
4
4
  const e = exposes.presets;
5
+ const fz = require('../converters/fromZigbee');
5
6
 
6
7
  module.exports = [
8
+ {
9
+ zigbeeModel: ['ZGR904-S'],
10
+ model: 'ZGR904-S',
11
+ vendor: 'Envilar',
12
+ description: 'Envilar touchlink remote',
13
+ meta: {battery: {dontDividePercentage: true}},
14
+ fromZigbee: [fz.command_recall, fz.command_on, fz.command_off, fz.command_move, fz.command_stop, fz.battery],
15
+ toZigbee: [],
16
+ exposes: [e.battery(),
17
+ e.action(['recall_1', 'recall_2', 'on', 'off', 'brightness_stop', 'brightness_move_up', 'brightness_move_down'])],
18
+ },
7
19
  {
8
20
  zigbeeModel: ['ZG102-BOX-UNIDIM'],
9
21
  model: 'ZG102-BOX-UNIDIM',
package/devices/evn.js CHANGED
@@ -1,26 +1,31 @@
1
1
  const exposes = require('../lib/exposes');
2
+ const extend = require('../lib/extend');
2
3
  const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
- const reporting = require('../lib/reporting');
4
4
  const e = exposes.presets;
5
5
 
6
6
  module.exports = [
7
7
  {
8
- zigbeeModel: ['EVN ZBHS4RGBW'],
8
+ zigbeeModel: ['ZBHS4RGBW'],
9
9
  model: 'ZBHS4RGBW',
10
10
  vendor: 'EVN',
11
11
  description: 'Zigbee 4 channel RGBW remote control',
12
- fromZigbee: [fz.battery, fz.command_on, fz.command_off, fz.command_step, fz.command_move, fz.command_stop, fz.command_recall,
13
- fz.command_move_hue, fz.command_move_to_color, fz.command_move_to_color_temp],
14
- exposes: [e.battery(), e.action(['on', 'off', 'brightness_step_up', 'brightness_step_down', 'brightness_move_up',
15
- 'brightness_move_down', 'brightness_stop', 'recall_1', 'recall_2', 'recall_3', 'hue_move', 'color_temperature_move',
16
- 'color_move', 'hue_stop'])],
12
+ fromZigbee: [fz.battery, fz.command_move_to_color, fz.command_move_to_color_temp, fz.command_move_hue,
13
+ fz.command_step, fz.command_stop, fz.command_move, fz.command_recall, fz.command_on, fz.command_off],
14
+ exposes: [e.battery(), e.action([
15
+ 'color_move', 'color_temperature_move', 'brightness_step_up', 'brightness_step_down',
16
+ 'brightness_move_up', 'brightness_move_down', 'brightness_stop',
17
+ 'hue_move', 'hue_stop', 'recall_*', 'on', 'off'])],
17
18
  toZigbee: [],
18
19
  meta: {multiEndpoint: true, battery: {dontDividePercentage: true}},
19
- configure: async (device, coordinatorEndpoint) => {
20
- const endpoint = device.getEndpoint(1);
21
- await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genPowerCfg']);
22
- await reporting.batteryVoltage(endpoint);
23
- await reporting.batteryPercentageRemaining(endpoint);
20
+ endpoint: (device) => {
21
+ return {ep1: 1, ep2: 2, ep3: 3, ep4: 4};
24
22
  },
25
23
  },
24
+ {
25
+ zigbeeModel: ['ZB24100VS'],
26
+ model: 'ZB24100VS',
27
+ vendor: 'EVN',
28
+ description: 'Zigbee multicolor controller with power supply',
29
+ extend: extend.light_onoff_brightness_colortemp_color({supportsHS: true, colorTempRange: [160, 450]}),
30
+ },
26
31
  ];
@@ -22,7 +22,7 @@ module.exports = [
22
22
  },
23
23
  {
24
24
  zigbeeModel: ['SV01-410-MP-1.0', 'SV01-410-MP-1.1', 'SV01-410-MP-1.4', 'SV01-410-MP-1.5', 'SV01-412-MP-1.0',
25
- 'SV01-412-MP-1.4', 'SV01-610-MP-1.0', 'SV01-610-MP-1.1', 'SV01-612-MP-1.0', 'SV01-610-MP-1.4'],
25
+ 'SV01-412-MP-1.1', 'SV01-412-MP-1.4', 'SV01-610-MP-1.0', 'SV01-610-MP-1.1', 'SV01-612-MP-1.0', 'SV01-610-MP-1.4'],
26
26
  model: 'SV01',
27
27
  vendor: 'Keen Home',
28
28
  description: 'Smart vent',
package/devices/lidl.js CHANGED
@@ -378,6 +378,15 @@ module.exports = [
378
378
  await reporting.onOff(endpoint);
379
379
  },
380
380
  },
381
+ {
382
+ fingerprint: [{modelID: 'TS004F', manufacturerName: '_TZ3000_rco1yzb1'}],
383
+ model: 'HG08164',
384
+ vendor: 'Lidl',
385
+ description: 'Silvercrest smart button',
386
+ fromZigbee: [fz.command_on, fz.command_off, fz.command_step, fz.command_stop, fz.battery],
387
+ toZigbee: [],
388
+ exposes: [e.action(['on', 'off', 'brightness_stop', 'brightness_step_up', 'brightness_step_down']), e.battery()],
389
+ },
381
390
  {
382
391
  fingerprint: [{modelID: 'TS0211', manufacturerName: '_TZ1800_ladpngdx'}],
383
392
  model: 'HG06668',
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/orvibo.js CHANGED
@@ -6,6 +6,13 @@ const extend = require('../lib/extend');
6
6
  const e = exposes.presets;
7
7
 
8
8
  module.exports = [
9
+ {
10
+ zigbeeModel: ['ORVIBO Socket'],
11
+ model: 'OR-ZB-S010-3C',
12
+ vendor: 'ORVIBO',
13
+ description: 'Smart Socket',
14
+ extend: extend.switch(),
15
+ },
9
16
  {
10
17
  zigbeeModel: ['3c4e4fc81ed442efaf69353effcdfc5f', '51725b7bcba945c8a595b325127461e9'],
11
18
  model: 'CR11S8UZ',
@@ -1513,6 +1513,15 @@ module.exports = [
1513
1513
  extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 500]}),
1514
1514
  ota: ota.zigbeeOTA,
1515
1515
  },
1516
+ {
1517
+ zigbeeModel: ['4023331P6'],
1518
+ model: '4023331P6',
1519
+ vendor: 'Philips',
1520
+ description: 'Hue white ambiance Amaze',
1521
+ meta: {turnsOffAtBrightness1: true},
1522
+ extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 500]}),
1523
+ ota: ota.zigbeeOTA,
1524
+ },
1516
1525
  {
1517
1526
  zigbeeModel: ['929003054801'],
1518
1527
  model: '929003054801',
@@ -2732,6 +2741,15 @@ module.exports = [
2732
2741
  extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
2733
2742
  ota: ota.zigbeeOTA,
2734
2743
  },
2744
+ {
2745
+ zigbeeModel: ['1746530P7'],
2746
+ model: '1746530P7',
2747
+ vendor: 'Philips',
2748
+ description: 'Hue White and color ambiance Daylo outdoor wall lamp',
2749
+ meta: {turnsOffAtBrightness1: true},
2750
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
2751
+ ota: ota.zigbeeOTA,
2752
+ },
2735
2753
  {
2736
2754
  zigbeeModel: ['1746547P7'],
2737
2755
  model: '1746547P7',
@@ -0,0 +1,33 @@
1
+ const exposes = require('../lib/exposes');
2
+ const reporting = require('../lib/reporting');
3
+ const extend = require('../lib/extend');
4
+ const e = exposes.presets;
5
+
6
+ module.exports = [
7
+ {
8
+ zigbeeModel: ['1719SP-PS1-02'],
9
+ model: 'SP-PS1-02',
10
+ vendor: 'Spotmau',
11
+ description: 'Smart wall switch - 1 gang',
12
+ extend: extend.switch(),
13
+ configure: async (device, coordinatorEndpoint, logger) => {
14
+ await reporting.bind(device.getEndpoint(16), coordinatorEndpoint, ['genOnOff', 'genBasic']);
15
+ },
16
+ },
17
+ {
18
+ zigbeeModel: ['1719SP-PS2-02'],
19
+ model: 'SP-PS2-02',
20
+ vendor: 'Spotmau',
21
+ description: 'Smart wall switch - 2 gang',
22
+ extend: extend.switch(),
23
+ exposes: [e.switch().withEndpoint('left'), e.switch().withEndpoint('right')],
24
+ endpoint: (device) => {
25
+ return {'left': 16, 'right': 17};
26
+ },
27
+ meta: {multiEndpoint: true},
28
+ configure: async (device, coordinatorEndpoint, logger) => {
29
+ await reporting.bind(device.getEndpoint(16), coordinatorEndpoint, ['genOnOff', 'genBasic']);
30
+ await reporting.bind(device.getEndpoint(17), coordinatorEndpoint, ['genOnOff', 'genBasic']);
31
+ },
32
+ },
33
+ ];
package/devices/tuya.js CHANGED
@@ -53,6 +53,29 @@ const fzLocal = {
53
53
  return fz.battery.convert(model, msg, publish, options, meta);
54
54
  },
55
55
  },
56
+ TS0222: {
57
+ cluster: 'manuSpecificTuya',
58
+ type: ['commandDataResponse', 'commandDataReport'],
59
+ convert: (model, msg, publish, options, meta) => {
60
+ const result = {};
61
+ for (const dpValue of msg.data.dpValues) {
62
+ const dp = dpValue.dp;
63
+ const value = tuya.getDataValue(dpValue);
64
+ switch (dp) {
65
+ case 2:
66
+ result.illuminance = value;
67
+ result.illuminance_lux = value;
68
+ break;
69
+ case 4:
70
+ result.battery = value;
71
+ break;
72
+ default:
73
+ meta.logger.warn(`zigbee-herdsman-converters:TS0222 Unrecognized DP #${dp} with data ${JSON.stringify(dpValue)}`);
74
+ }
75
+ }
76
+ return result;
77
+ },
78
+ },
56
79
  };
57
80
 
58
81
  module.exports = [
@@ -97,13 +120,14 @@ module.exports = [
97
120
  description: 'Door sensor',
98
121
  fromZigbee: [fz.ias_contact_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_contact_alarm_1_report],
99
122
  toZigbee: [],
100
- exposes: [e.contact(), e.battery_low(), e.tamper(), e.battery()],
123
+ exposes: [e.contact(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
101
124
  whiteLabel: [{vendor: 'CR Smart Home', model: 'TS0203'}],
102
125
  configure: async (device, coordinatorEndpoint, logger) => {
103
126
  try {
104
127
  const endpoint = device.getEndpoint(1);
105
128
  await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
106
129
  await reporting.batteryPercentageRemaining(endpoint);
130
+ await reporting.batteryVoltage(endpoint);
107
131
  } catch (error) {/* Fails for some*/}
108
132
  },
109
133
  },
@@ -1273,7 +1297,7 @@ module.exports = [
1273
1297
  description: 'Smart plug (with power monitoring)',
1274
1298
  vendor: 'TuYa',
1275
1299
  whiteLabel: [{vendor: 'LELLKI', model: 'TS011F_plug'}, {vendor: 'NEO', model: 'NAS-WR01B'},
1276
- {vendor: 'BlitzWolf', model: 'BW-SHP15'}],
1300
+ {vendor: 'BlitzWolf', model: 'BW-SHP15'}, {vendor: 'Nous', model: 'A1Z'}],
1277
1301
  ota: ota.zigbeeOTA,
1278
1302
  fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, fz.tuya_switch_power_outage_memory,
1279
1303
  fz.ts011f_plug_indicator_mode, fz.ts011f_plug_child_mode],
@@ -1647,7 +1671,7 @@ module.exports = [
1647
1671
  },
1648
1672
  },
1649
1673
  {
1650
- zigbeeModel: ['HY0017'],
1674
+ zigbeeModel: ['HY0017', '005f0c3'],
1651
1675
  model: 'U86KCJ-ZP',
1652
1676
  vendor: 'TuYa',
1653
1677
  description: 'Smart 6 key scene wall switch',
@@ -1803,9 +1827,13 @@ module.exports = [
1803
1827
  model: 'TS0222',
1804
1828
  vendor: 'TuYa',
1805
1829
  description: 'Light intensity sensor',
1806
- fromZigbee: [fz.battery, fz.illuminance],
1830
+ fromZigbee: [fz.battery, fz.illuminance, fzLocal.TS0222],
1807
1831
  toZigbee: [],
1808
1832
  exposes: [e.battery(), e.illuminance(), e.illuminance_lux()],
1833
+ configure: async (device, coordinatorEndpoint, logger) => {
1834
+ const endpoint = device.getEndpoint(1);
1835
+ await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
1836
+ },
1809
1837
  },
1810
1838
  {
1811
1839
  fingerprint: [{modelID: 'TS0210', manufacturerName: '_TYZB01_3zv6oleo'},
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.xiaomi_curtain_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.xiaomi_curtain_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.xiaomi_curtain_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
@@ -1284,8 +1286,8 @@ module.exports = [
1284
1286
  model: 'ZNJLBL01LM',
1285
1287
  description: 'Aqara roller shade companion E1',
1286
1288
  vendor: 'Xiaomi',
1287
- fromZigbee: [fz.xiaomi_curtain_acn002_position, fz.xiaomi_curtain_acn002_status, fz.cover_position_tilt, fz.ignore_basic_report,
1288
- fz.aqara_opple],
1289
+ fromZigbee: [fz.xiaomi_curtain_acn002_position, fz.xiaomi_curtain_acn002_status, fz.xiaomi_curtain_position_tilt,
1290
+ fz.ignore_basic_report, fz.aqara_opple],
1289
1291
  toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_acn002_battery, tz.xiaomi_curtain_acn002_charging_status],
1290
1292
  exposes: [e.cover_position().setAccess('state', ea.ALL), e.battery().withAccess(ea.STATE_GET),
1291
1293
  exposes.binary('charging_status', ea.STATE_GET, true, false)
@@ -0,0 +1,11 @@
1
+ const extend = require('../lib/extend');
2
+
3
+ module.exports = [
4
+ {
5
+ zigbeeModel: ['X2SK11'],
6
+ model: 'X2SK11',
7
+ vendor: 'XingHuoYuan',
8
+ description: 'Smart socket',
9
+ extend: extend.switch(),
10
+ },
11
+ ];
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/tuya.js CHANGED
@@ -164,7 +164,7 @@ function convertStringToHexArray(value) {
164
164
  // Default is 100 = open, 0 = closed; Devices listed here will use 0 = open, 100 = closed instead
165
165
  // Use manufacturerName to identify device!
166
166
  // Dont' invert _TZE200_cowvfni3: https://github.com/Koenkk/zigbee2mqtt/issues/6043
167
- const coverPositionInvert = ['_TZE200_wmcdj3aq', '_TZE200_nogaemzt', '_TZE200_xuzcvlku', '_TZE200_xaabybja'];
167
+ const coverPositionInvert = ['_TZE200_wmcdj3aq', '_TZE200_nogaemzt', '_TZE200_xuzcvlku', '_TZE200_xaabybja', '_TZE200_rmymn92d'];
168
168
 
169
169
  // Gets a boolean indicating whether the cover by this manufacturerName needs reversed positions
170
170
  function isCoverInverted(manufacturerName) {
package/lib/xiaomi.js CHANGED
@@ -408,6 +408,19 @@ 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: (options.invert_cover ? {0: 'stopped', 1: 'closing', 2: 'opening'} :
420
+ {0: 'stopped', 1: 'opening', 2: 'closing'})[value],
421
+ running: !!value,
422
+ };
423
+ break;
411
424
  case '1033':
412
425
  if (['ZNJLBL01LM'].includes(model.model)) {
413
426
  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.462",
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.462",
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.462",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [