zigbee-herdsman-converters 14.0.609 → 14.0.612

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.
@@ -8022,7 +8022,7 @@ const converters = {
8022
8022
  const value = tuya.getDataValue(dpValue);
8023
8023
  switch (dpValue.dp) {
8024
8024
  case tuya.dataPoints.state:
8025
- result.contact = Boolean(value);
8025
+ result.contact = !value;
8026
8026
  break;
8027
8027
  case tuya.dataPoints.thitBatteryPercentage:
8028
8028
  result.battery = value;
@@ -859,6 +859,7 @@ const converters = {
859
859
  state = meta.message.state = brightness === 0 ? 'off' : 'on';
860
860
  }
861
861
 
862
+ let publishFakeOnLevel = false;
862
863
  let publishBrightness = brightness !== undefined;
863
864
  const targetState = state === 'toggle' ? (meta.state.state === 'ON' ? 'off' : 'on') : state;
864
865
  if (targetState === 'off') {
@@ -885,17 +886,27 @@ const converters = {
885
886
  // TODO: same problem as above.
886
887
  // TODO: if transition is not specified, should use device default (OnTransitionTime), not 0.
887
888
  if (transition.specified || globalStore.getValue(entity, 'turnedOffWithTransition') === true) {
888
- const current = utils.getObjectProperty(meta.state, 'brightness', 254);
889
- brightness = globalStore.getValue(entity, 'brightness', current);
890
- try {
891
- const attributeRead = await entity.read('genLevelCtrl', ['onLevel']);
892
- // TODO: for groups, `read` does not wait for responses. If it did, we could still issue a single
893
- // command if all values of `OnLevel` are equal, or split into one command per device if not.
894
- if (attributeRead !== undefined && attributeRead['onLevel'] != 255) {
895
- brightness = attributeRead['onLevel'];
889
+ const levelConfig = utils.getObjectProperty(meta.state, 'level_config', {});
890
+ let onLevel = utils.getObjectProperty(levelConfig, 'on_level', 0);
891
+ if (onLevel === 0) {
892
+ try {
893
+ const attributeRead = await entity.read('genLevelCtrl', ['onLevel']);
894
+ if (attributeRead !== undefined) {
895
+ onLevel = attributeRead['onLevel'];
896
+ }
897
+ } catch (e) {
898
+ // OnLevel not supported; write a 'previous' value to state to avoid re-reads
896
899
  }
897
- } catch (e) {
898
- // OnLevel not supported
900
+ }
901
+ if (onLevel === 0) {
902
+ onLevel = 'previous';
903
+ publishFakeOnLevel = true;
904
+ }
905
+ if (onLevel === 255 || onLevel === 'previous') {
906
+ const current = utils.getObjectProperty(meta.state, 'brightness', 254);
907
+ brightness = globalStore.getValue(entity, 'brightness', current);
908
+ } else {
909
+ brightness = onLevel;
899
910
  }
900
911
  // Published state might have gotten clobbered by reporting.
901
912
  publishBrightness = true;
@@ -933,6 +944,9 @@ const converters = {
933
944
  if (publishBrightness) {
934
945
  result.state.brightness = Number(brightness);
935
946
  }
947
+ if (publishFakeOnLevel) {
948
+ result.state.level_config = {on_level: 'previous'};
949
+ }
936
950
  if (state !== null) {
937
951
  result.state.state = brightness === 0 ? 'OFF' : 'ON';
938
952
  }
@@ -1510,6 +1524,12 @@ const converters = {
1510
1524
  await entity.read('msTemperatureMeasurement', ['measuredValue']);
1511
1525
  },
1512
1526
  },
1527
+ illuminance: {
1528
+ key: ['illuminance', 'illuminance_lux'],
1529
+ convertGet: async (entity, key, meta) => {
1530
+ await entity.read('msIlluminanceMeasurement', ['measuredValue']);
1531
+ },
1532
+ },
1513
1533
  // #endregion
1514
1534
 
1515
1535
  // #region Non-generic converters
@@ -4633,22 +4653,22 @@ const converters = {
4633
4653
  }
4634
4654
  },
4635
4655
  },
4636
- legrand_settingAlwaysEnableLed: {
4656
+ legrand_settingEnableLedInDark: {
4637
4657
  // connected power outlet is on attribute 2 and not 1
4638
- key: ['led_when_off'],
4658
+ key: ['led_in_dark'],
4639
4659
  convertSet: async (entity, key, value, meta) => {
4640
4660
  // enable or disable the LED (blue) when permitJoin=false (LED off)
4641
4661
  const enableLedIfOn = value === 'ON' || (value === 'OFF' ? false : !!value);
4642
4662
  const payload = {1: {value: enableLedIfOn, type: 16}};
4643
4663
  await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
4644
- return {state: {'led_when_off': value}};
4664
+ return {state: {'led_in_dark': value}};
4645
4665
  },
4646
4666
  convertGet: async (entity, key, meta) => {
4647
4667
  await entity.read('manuSpecificLegrandDevices', [0x0001], manufacturerOptions.legrand);
4648
4668
  },
4649
4669
  },
4650
4670
  legrand_settingEnableLedIfOn: {
4651
- key: ['led_when_on'],
4671
+ key: ['led_if_on'],
4652
4672
  convertSet: async (entity, key, value, meta) => {
4653
4673
  // enable the LED when the light object is "doing something"
4654
4674
  // on the light switch, the LED is on when the light is on,
@@ -4656,7 +4676,7 @@ const converters = {
4656
4676
  const enableLedIfOn = value === 'ON' || (value === 'OFF' ? false : !!value);
4657
4677
  const payload = {2: {value: enableLedIfOn, type: 16}};
4658
4678
  await entity.write('manuSpecificLegrandDevices', payload, manufacturerOptions.legrand);
4659
- return {state: {'led_when_on': value}};
4679
+ return {state: {'led_if_on': value}};
4660
4680
  },
4661
4681
  convertGet: async (entity, key, meta) => {
4662
4682
  await entity.read('manuSpecificLegrandDevices', [0x0002], manufacturerOptions.legrand);
@@ -0,0 +1,13 @@
1
+ const fz = require('../converters/fromZigbee');
2
+
3
+ module.exports = [
4
+ {
5
+ zigbeeModel: ['WG001-Z01'],
6
+ model: 'WG001',
7
+ vendor: 'Aeotec',
8
+ description: 'Range extender Zi',
9
+ fromZigbee: [fz.linkquality_from_basic],
10
+ toZigbee: [],
11
+ exposes: [],
12
+ },
13
+ ];
@@ -109,7 +109,7 @@ module.exports = [
109
109
  extend: extend.light_onoff_brightness({disableEffect: true}),
110
110
  },
111
111
  {
112
- zigbeeModel: ['RGBGU10Bulb50AU'],
112
+ zigbeeModel: ['RGBGU10Bulb50AU', 'RGBGU10Bulb50AU2'],
113
113
  model: 'AU-A1GUZBRGBW',
114
114
  vendor: 'Aurora Lighting',
115
115
  description: 'AOne 5.6w smart RGBW tuneable GU10 lamp',
@@ -13,11 +13,12 @@ module.exports = [
13
13
  vendor: 'BTicino',
14
14
  description: 'Light switch with neutral',
15
15
  fromZigbee: [fz.identify, fz.on_off, fz.K4003C_binary_input, fz.legrand_cluster_fc01],
16
- toZigbee: [tz.on_off, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn, tz.legrand_identify],
16
+ toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn, tz.legrand_identify],
17
17
  exposes: [
18
18
  e.switch(), e.action(['identify', 'on', 'off']),
19
- exposes.binary('led_when_off', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is off'),
20
- exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on'),
19
+ exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
20
+ see the switch in the dark`),
21
+ exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on'),
21
22
  ],
22
23
  configure: async (device, coordinatorEndpoint, logger) => {
23
24
  const endpoint = device.getEndpoint(1);
@@ -31,7 +32,7 @@ module.exports = [
31
32
  description: 'Dimmer switch with neutral',
32
33
  extend: extend.light_onoff_brightness({noConfigure: true}),
33
34
  fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration, fz.legrand_cluster_fc01],
34
- toZigbee: [tz.light_onoff_brightness, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn,
35
+ toZigbee: [tz.light_onoff_brightness, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn,
35
36
  tz.legrand_deviceMode, tz.legrand_identify, tz.ballast_config],
36
37
  exposes: [e.light_brightness(),
37
38
  exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
@@ -39,8 +40,9 @@ module.exports = [
39
40
  exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
40
41
  .withDescription('Specifies the maximum brightness value'),
41
42
  exposes.binary('device_mode', ea.ALL, 'dimmer_on', 'dimmer_off').withDescription('Allow the device to change brightness'),
42
- exposes.binary('led_when_off', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is off'),
43
- exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on')],
43
+ exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
44
+ see the switch in the dark`),
45
+ exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on')],
44
46
  configure: async (device, coordinatorEndpoint, logger) => {
45
47
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
46
48
  const endpoint = device.getEndpoint(1);
@@ -62,7 +64,7 @@ module.exports = [
62
64
  fromZigbee: [fz.identify, fz.ignore_basic_report, fz.ignore_zclversion_read, fz.bticino_4027C_binary_input_moving,
63
65
  fz.cover_position_tilt],
64
66
  toZigbee: [tz.bticino_4027C_cover_state, tz.bticino_4027C_cover_position, tz.legrand_identify,
65
- tz.legrand_settingAlwaysEnableLed],
67
+ tz.legrand_settingEnableLedInDark],
66
68
  exposes: [e.cover_position()],
67
69
  meta: {coverInverted: true},
68
70
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -95,7 +97,7 @@ module.exports = [
95
97
  vendor: 'BTicino',
96
98
  description: 'Power socket with power consumption monitoring',
97
99
  fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement],
98
- toZigbee: [tz.on_off, tz.legrand_settingAlwaysEnableLed, tz.legrand_identify],
100
+ toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_identify],
99
101
  exposes: [e.switch(), e.action(['identify']), e.power(), e.voltage(), e.current()],
100
102
  configure: async (device, coordinatorEndpoint, logger) => {
101
103
  const endpoint = device.getEndpoint(1);
@@ -144,7 +144,7 @@ module.exports = [
144
144
  model: 'EMIZB-132',
145
145
  vendor: 'Develco',
146
146
  description: 'Wattle AMS HAN power-meter sensor',
147
- fromZigbee: [fz.metering, fz.electrical_measurement, fz.develco_fw],
147
+ fromZigbee: [fzLocal.SPLZB134_metering, fzLocal.SPLZB134_electrical_measurement, fz.develco_fw],
148
148
  toZigbee: [tz.EMIZB_132_mode],
149
149
  ota: ota.zigbeeOTA,
150
150
  configure: async (device, coordinatorEndpoint, logger) => {
package/devices/ikea.js CHANGED
@@ -356,10 +356,10 @@ module.exports = [
356
356
  extend: tradfriExtend.light_onoff_brightness_colortemp(),
357
357
  },
358
358
  {
359
- zigbeeModel: ['TRADFRIbulbT120E26WSopal450lm'],
359
+ zigbeeModel: ['TRADFRIbulbT120E26WSopal450lm', 'TRADFRIbulbT120E26WSopal470lm'],
360
360
  model: 'LED1937T5_E26',
361
361
  vendor: 'IKEA',
362
- description: 'LED bulb E26 450 lumen, wireless dimmable white spectrum/tube-shaped white frosted glass',
362
+ description: 'LED bulb E26 450/470 lumen, wireless dimmable white spectrum/tube-shaped white frosted glass',
363
363
  extend: tradfriExtend.light_onoff_brightness_colortemp(),
364
364
  },
365
365
  {
@@ -397,6 +397,13 @@ module.exports = [
397
397
  description: 'TRADFRI bulb E12/E14/E17 WS 450/470/440 lumen, dimmable, white spectrum, opal white',
398
398
  extend: tradfriExtend.light_onoff_brightness_colortemp(),
399
399
  },
400
+ {
401
+ zigbeeModel: ['TRADFRI bulb E14 WS globe 470lm'],
402
+ model: 'LED2101G4',
403
+ vendor: 'IKEA',
404
+ description: 'TRADFRI bulb E14 WS globe 470lm, dimmable, white spectrum, opal white',
405
+ extend: tradfriExtend.light_onoff_brightness_colortemp(),
406
+ },
400
407
  {
401
408
  zigbeeModel: ['TRADFRI bulb GU10 WW 400lm'],
402
409
  model: 'LED1837R5',
@@ -932,4 +939,11 @@ module.exports = [
932
939
  description: 'NYMÅNE Pendant lamp',
933
940
  extend: tradfriExtend.light_onoff_brightness_colortemp(),
934
941
  },
942
+ {
943
+ zigbeeModel: ['STOFTMOLN ceiling/wall lamp WW37'],
944
+ model: 'T2037',
945
+ vendor: 'IKEA',
946
+ description: 'STOFTMOLN ceiling/wall lamp 37 warm light dimmable',
947
+ extend: tradfriExtend.light_onoff_brightness(),
948
+ },
935
949
  ];
package/devices/kmpcil.js CHANGED
@@ -6,6 +6,7 @@ const reporting = require('../lib/reporting');
6
6
  const globalStore = require('../lib/store');
7
7
  const utils = require('../lib/utils');
8
8
  const e = exposes.presets;
9
+ const ea = exposes.access;
9
10
 
10
11
  const kmpcilOptions={
11
12
  presence_timeout_dc: () => {
@@ -74,11 +75,11 @@ module.exports = [
74
75
  model: 'KMPCIL_RES005',
75
76
  vendor: 'KMPCIL',
76
77
  description: 'Environment sensor',
77
- exposes: [e.battery(), e.temperature(), e.humidity(), e.pressure(), e.illuminance(), e.illuminance_lux(), e.occupancy(),
78
- e.switch()],
78
+ exposes: [e.battery(), e.temperature(), e.humidity(), e.pressure(), e.illuminance().withAccess(ea.STATE_GET),
79
+ e.illuminance_lux().withAccess(ea.STATE_GET), e.occupancy(), e.switch()],
79
80
  fromZigbee: [fz.battery, fz.temperature, fz.humidity, fz.pressure, fz.illuminance, fz.kmpcil_res005_occupancy,
80
81
  fz.kmpcil_res005_on_off],
81
- toZigbee: [tz.kmpcil_res005_on_off],
82
+ toZigbee: [tz.kmpcil_res005_on_off, tz.illuminance],
82
83
  configure: async (device, coordinatorEndpoint, logger) => {
83
84
  const endpoint = device.getEndpoint(8);
84
85
  const binds = ['genPowerCfg', 'msTemperatureMeasurement', 'msRelativeHumidity', 'msPressureMeasurement',
@@ -167,4 +167,12 @@ module.exports = [
167
167
  extend: extend.ledvance.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370]}),
168
168
  ota: ota.ledvance,
169
169
  },
170
+ {
171
+ zigbeeModel: ['A60 DIM T'],
172
+ model: '4058075728981',
173
+ vendor: 'LEDVANCE',
174
+ description: 'SMART+ Classic A E27 dimmable white',
175
+ extend: extend.ledvance.light_onoff_brightness(),
176
+ ota: ota.ledvance,
177
+ },
170
178
  ];
@@ -106,7 +106,7 @@ module.exports = [
106
106
  fz.identify, fz.ignore_basic_report,
107
107
  // support binary report on moving state (supposed)
108
108
  fz.legrand_binary_input_moving, fz.cover_position_tilt],
109
- toZigbee: [tz.cover_state, tz.cover_position_tilt, tz.legrand_identify, tz.legrand_settingAlwaysEnableLed],
109
+ toZigbee: [tz.cover_state, tz.cover_position_tilt, tz.legrand_identify, tz.legrand_settingEnableLedInDark],
110
110
  configure: async (device, coordinatorEndpoint, logger) => {
111
111
  const endpoint = device.getEndpoint(1);
112
112
  await reporting.bind(endpoint, coordinatorEndpoint, ['genBinaryInput', 'closuresWindowCovering', 'genIdentify']);
@@ -175,7 +175,7 @@ module.exports = [
175
175
  description: 'Wired switch without neutral',
176
176
  extend: extend.light_onoff_brightness({noConfigure: true}),
177
177
  fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration, fz.legrand_cluster_fc01],
178
- toZigbee: [tz.light_onoff_brightness, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn,
178
+ toZigbee: [tz.light_onoff_brightness, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn,
179
179
  tz.legrand_deviceMode, tz.legrand_identify, tz.ballast_config],
180
180
  exposes: [e.light_brightness(),
181
181
  exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
@@ -183,8 +183,9 @@ module.exports = [
183
183
  exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
184
184
  .withDescription('Specifies the maximum brightness value'),
185
185
  exposes.binary('device_mode', ea.ALL, 'dimmer_on', 'dimmer_off').withDescription('Allow the device to change brightness'),
186
- exposes.binary('led_when_off', ea.ALL, 'ON', 'OFF').withDescription('Enable the LED when the light is off'),
187
- exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on')],
186
+ exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
187
+ see the switch in the dark`),
188
+ exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on')],
188
189
  configure: async (device, coordinatorEndpoint, logger) => {
189
190
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
190
191
  const endpoint = device.getEndpoint(1);
@@ -201,8 +202,9 @@ module.exports = [
201
202
  ota: ota.zigbeeOTA,
202
203
  description: 'Power socket with power consumption monitoring',
203
204
  fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement],
204
- toZigbee: [tz.on_off, tz.legrand_settingAlwaysEnableLed, tz.legrand_identify],
205
- exposes: [e.switch(), e.action(['identify']), e.power()],
205
+ toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_identify, tz.legrand_settingEnableLedIfOn],
206
+ exposes: [e.switch(), e.action(['identify']), e.power(),
207
+ exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the device is turned on')],
206
208
  configure: async (device, coordinatorEndpoint, logger) => {
207
209
  const endpoint = device.getEndpoint(1);
208
210
  await reporting.bind(endpoint, coordinatorEndpoint, ['genIdentify', 'genOnOff', 'haElectricalMeasurement']);
@@ -256,7 +258,7 @@ module.exports = [
256
258
  vendor: 'Legrand',
257
259
  description: 'DIN power consumption module',
258
260
  fromZigbee: [fz.identify, fz.metering, fz.electrical_measurement, fz.ignore_basic_report, fz.ignore_genOta, fz.legrand_power_alarm],
259
- toZigbee: [tz.legrand_settingAlwaysEnableLed, tz.legrand_identify, tz.electrical_measurement_power, tz.legrand_powerAlarm],
261
+ toZigbee: [tz.legrand_settingEnableLedInDark, tz.legrand_identify, tz.electrical_measurement_power, tz.legrand_powerAlarm],
260
262
  exposes: [e.power().withAccess(ea.STATE_GET), exposes.binary('power_alarm_active', ea.STATE, true, false),
261
263
  exposes.binary('power_alarm', ea.ALL, true, false).withDescription('Enable/disable the power alarm')],
262
264
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -344,11 +346,12 @@ module.exports = [
344
346
  vendor: 'Legrand',
345
347
  description: 'Double wired switch with neutral',
346
348
  fromZigbee: [fz.on_off, fz.legrand_binary_input_on_off, fz.legrand_cluster_fc01],
347
- toZigbee: [tz.on_off, tz.legrand_settingAlwaysEnableLed, tz.legrand_settingEnableLedIfOn],
349
+ toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn],
348
350
  exposes: [e.switch().withEndpoint('left'),
349
351
  e.switch().withEndpoint('right'),
350
- exposes.binary('led_when_off', ea.ALL, 'ON', 'OFF').withDescription('Enable the LED when the light is off'),
351
- exposes.binary('led_when_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is on')],
352
+ exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing to
353
+ see the switch in the dark`),
354
+ exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on')],
352
355
  meta: {multiEndpoint: true},
353
356
  configure: async (device, coordinatorEndpoint, logger) => {
354
357
  const endpointLeft = device.getEndpoint(2);
@@ -368,7 +371,7 @@ module.exports = [
368
371
  ota: ota.zigbeeOTA,
369
372
  description: 'Outlet with power consumption monitoring',
370
373
  fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement],
371
- toZigbee: [tz.on_off, tz.legrand_settingAlwaysEnableLed, tz.legrand_identify],
374
+ toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_identify],
372
375
  exposes: [e.switch(), e.action(['identify']), e.power()],
373
376
  configure: async (device, coordinatorEndpoint, logger) => {
374
377
  const endpoint = device.getEndpoint(1);
package/devices/lellki.js CHANGED
@@ -137,6 +137,7 @@ module.exports = [
137
137
  toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
138
138
  configure: async (device, coordinatorEndpoint, logger) => {
139
139
  const endpoint = device.getEndpoint(1);
140
+ await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
140
141
  await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
141
142
  await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
142
143
  await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']);
package/devices/lidl.js CHANGED
@@ -378,6 +378,28 @@ module.exports = [
378
378
  await reporting.onOff(endpoint);
379
379
  },
380
380
  },
381
+ {
382
+ fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_ynmowqk2'}],
383
+ model: 'HG08673-FR',
384
+ vendor: 'Lidl',
385
+ description: 'Silvercrest smart plug FR with power monitoring',
386
+ fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, fz.tuya_switch_power_outage_memory],
387
+ toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
388
+ exposes: [e.switch(), e.power(), e.current(), e.voltage().withAccess(ea.STATE),
389
+ e.energy(), exposes.enum('power_outage_memory', ea.ALL, ['on', 'off', 'restore'])
390
+ .withDescription('Recover state after power outage')],
391
+ configure: async (device, coordinatorEndpoint, logger) => {
392
+ const endpoint = device.getEndpoint(1);
393
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement']);
394
+ endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
395
+ endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {
396
+ acVoltageMultiplier: 1, acVoltageDivisor: 1, acCurrentMultiplier: 1, acCurrentDivisor: 1000, acPowerMultiplier: 1,
397
+ acPowerDivisor: 1,
398
+ });
399
+ },
400
+ options: [exposes.options.measurement_poll_interval()],
401
+ onEvent: tuya.onEventMeasurementPoll,
402
+ },
381
403
  {
382
404
  fingerprint: [{modelID: 'TS004F', manufacturerName: '_TZ3000_rco1yzb1'}],
383
405
  model: 'HG08164',
@@ -134,7 +134,7 @@ module.exports = [
134
134
  },
135
135
  },
136
136
  {
137
- fingerprint: [{modelID: 'TS110F', manufacturerName: '_TZ3000_ktuoyvt5'}],
137
+ fingerprint: [{modelID: 'TS110F', manufacturerName: '_TZ3000_ktuoyvt5'}, {modelID: 'TS110E', manufacturerName: '_TZ3210_weaqkhab'}],
138
138
  model: 'QS-Zigbee-D02-TRIAC-L',
139
139
  vendor: 'Lonsonho',
140
140
  description: '1 gang smart dimmer switch module without neutral',
@@ -62,4 +62,21 @@ module.exports = [
62
62
  device.save();
63
63
  },
64
64
  },
65
+ {
66
+ fingerprint: [{modelID: 'TS0501', manufacturerName: '_TZ3210_lzqq3u4r'},
67
+ {modelID: 'TS0501', manufacturerName: '_TZ3210_4whigl8i'}],
68
+ model: 'SSWF01G',
69
+ description: 'AC fan controller',
70
+ vendor: 'Mercator',
71
+ fromZigbee: [fz.on_off, fz.fan],
72
+ toZigbee: [tz.fan_mode, tz.on_off],
73
+ exposes: [e.switch(), e.fan().withModes(['off', 'low', 'medium', 'high', 'on'])],
74
+ configure: async (device, coordinatorEndpoint, logger) => {
75
+ const endpoint = device.getEndpoint(1);
76
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genBasic', 'genOta', 'genTime', 'genGroups', 'genScenes']);
77
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genIdentify', 'manuSpecificTuya', 'hvacFanCtrl']);
78
+ await reporting.onOff(endpoint);
79
+ await reporting.fanMode(endpoint);
80
+ },
81
+ },
65
82
  ];
package/devices/moes.js CHANGED
@@ -273,9 +273,14 @@ module.exports = [
273
273
  exposes: [e.switch().withEndpoint('l1').setAccess('state', ea.STATE_SET),
274
274
  e.switch().withEndpoint('l2').setAccess('state', ea.STATE_SET),
275
275
  e.switch().withEndpoint('l3').setAccess('state', ea.STATE_SET),
276
- e.switch().withEndpoint('l4').setAccess('state', ea.STATE_SET)],
277
- fromZigbee: [fz.ignore_basic_report, fz.tuya_switch],
278
- toZigbee: [tz.tuya_switch_state],
276
+ e.switch().withEndpoint('l4').setAccess('state', ea.STATE_SET),
277
+ exposes.enum('indicate_light', ea.STATE_SET, Object.values(tuya.moesSwitch.indicateLight))
278
+ .withDescription('Indicator light status'),
279
+ exposes.enum('power_on_behavior', ea.STATE_SET, Object.values(tuya.moesSwitch.powerOnBehavior))
280
+ .withDescription('Controls the behavior when the device is powered on')],
281
+ fromZigbee: [fz.ignore_basic_report, fz.tuya_switch, fz.moes_switch],
282
+ toZigbee: [tz.tuya_switch_state, tz.moes_switch],
283
+ onEvent: tuya.onEventSetLocalTime,
279
284
  meta: {multiEndpoint: true},
280
285
  endpoint: (device) => {
281
286
  // Endpoint selection is made in tuya_switch_state
@@ -428,7 +433,10 @@ module.exports = [
428
433
  exposes.enum('calibration', ea.STATE_SET, ['OFF', 'ON']), exposes.enum('motor_reversal', ea.STATE_SET, ['OFF', 'ON'])],
429
434
  },
430
435
  {
431
- fingerprint: [{modelID: 'TS1201', manufacturerName: '_TZ3290_j37rooaxrcdcqo5n'}],
436
+ fingerprint: [
437
+ {modelID: 'TS1201', manufacturerName: '_TZ3290_j37rooaxrcdcqo5n'},
438
+ {modelID: 'TS1201', manufacturerName: '_TZ3290_ot6ewjvmejq5ekhl'},
439
+ ],
432
440
  model: 'UFO-R11',
433
441
  vendor: 'Moes',
434
442
  description: 'Universal smart IR remote control',
@@ -447,4 +455,24 @@ module.exports = [
447
455
  await reporting.batteryVoltage(endpoint);
448
456
  },
449
457
  },
458
+ {
459
+ fingerprint: [{modelID: 'TS0011', manufacturerName: '_TZ3000_hhiodade'}],
460
+ model: 'ZS-EUB_1gang',
461
+ vendor: 'Moes',
462
+ description: 'Wall light switch (1 gang)',
463
+ toZigbee: extend.switch().toZigbee.concat([tz.moes_power_on_behavior, tz.tuya_switch_type, tz.tuya_backlight_mode]),
464
+ fromZigbee: extend.switch().fromZigbee.concat([fz.moes_power_on_behavior, fz.tuya_switch_type, fz.tuya_backlight_mode]),
465
+ exposes: [
466
+ e.switch(),
467
+ exposes.presets.power_on_behavior(),
468
+ exposes.presets.switch_type_2(),
469
+ exposes.enum('backlight_mode', ea.ALL, ['LOW', 'MEDIUM', 'HIGH'])
470
+ .withDescription('Indicator light status: LOW: Off | MEDIUM: On| HIGH: Inverted'),
471
+ ],
472
+ configure: async (device, coordinatorEndpoint, logger) => {
473
+ await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
474
+ device.powerSource = 'Mains (single phase)';
475
+ device.save();
476
+ },
477
+ },
450
478
  ];
@@ -0,0 +1,17 @@
1
+ const exposes = require('../lib/exposes');
2
+ const fz = require('../converters/fromZigbee');
3
+ const tz = require('../converters/toZigbee');
4
+ const e = exposes.presets;
5
+ const ea = exposes.access;
6
+
7
+ module.exports = [
8
+ {
9
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_swhwv3k3'}],
10
+ model: 'C10-3E-1.2',
11
+ vendor: 'Novo',
12
+ description: 'Curtain switch',
13
+ fromZigbee: [fz.tuya_cover, fz.ignore_basic_report],
14
+ toZigbee: [tz.tuya_cover_control, tz.tuya_cover_options],
15
+ exposes: [e.cover_position().setAccess('position', ea.STATE_SET)],
16
+ },
17
+ ];
@@ -7,7 +7,7 @@ const ea = exposes.access;
7
7
 
8
8
  module.exports = [
9
9
  {
10
- zigbeeModel: ['ivfvd7h', 'eaxp72v\u0000', 'kfvq6avy\u0000', 'fvq6avy\u0000', 'fvq6avy'],
10
+ zigbeeModel: ['ivfvd7h', 'eaxp72v\u0000', 'kfvq6avy\u0000', 'fvq6avy\u0000', 'fvq6avy', 'zk78ptr\u0000'],
11
11
  fingerprint: [
12
12
  {modelID: 'TS0601', manufacturerName: '_TZE200_zivfvd7h'},
13
13
  {modelId: 'TS0601', manufacturerName: '_TZE200_kfvq6avy'},
@@ -30,7 +30,8 @@ module.exports = [
30
30
  {vendor: 'Revolt', description: 'Thermostatic Radiator Valve Controller', model: 'NX-4911'},
31
31
  {vendor: 'Unitec', description: 'Thermostatic Radiator Valve Controller', model: '30946'},
32
32
  {vendor: 'Tesla', description: 'Thermostatic Radiator Valve Controller', model: 'TSL-TRV-GS361A'},
33
- {vendor: 'Nedis', description: 'Thermostatic Radiator Valve Controller', model: 'ZBHTR10WT'}],
33
+ {vendor: 'Nedis', description: 'Thermostatic Radiator Valve Controller', model: 'ZBHTR10WT'},
34
+ {vendor: 'TCP Smart', description: 'Smart Thermostatic Radiator Valve', model: 'TBUWTRV'}],
34
35
  exposes: [e.child_lock(), e.window_detection(), e.battery(), e.valve_detection(), e.position(), exposes.climate()
35
36
  .withSetpoint('current_heating_setpoint', 5, 30, 0.5, ea.STATE_SET).withLocalTemperature(ea.STATE)
36
37
  .withSystemMode(['off', 'auto', 'heat'], ea.STATE_SET)
@@ -41,7 +41,7 @@ module.exports = [
41
41
  },
42
42
  },
43
43
  {
44
- zigbeeModel: ['LIGHTIFY RT Tunable White'],
44
+ zigbeeModel: ['LIGHTIFY RT Tunable White', 'RT TW'],
45
45
  model: '73742',
46
46
  vendor: 'Sylvania',
47
47
  description: 'LIGHTIFY LED adjustable white RT 5/6',
package/devices/tuya.js CHANGED
@@ -20,7 +20,7 @@ const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak',
20
20
  '_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_kx0pris5', '_TZ3000_amdymr7l', '_TZ3000_z1pnpsdo', '_TZ3000_ksw8qtmt',
21
21
  '_TZ3000_1h2x4akh', '_TZ3000_9vo5icau', '_TZ3000_cehuw1lw', '_TZ3000_ko6v90pg', '_TZ3000_f1bapcit', '_TZ3000_cjrngdr3',
22
22
  '_TZ3000_zloso4jk', '_TZ3000_r6buo8ba', '_TZ3000_iksasdbv', '_TZ3000_idrffznf', '_TZ3000_okaz9tjs', '_TZ3210_q7oryllx',
23
- '_TZ3000_ss98ec5d', '_TZ3000_gznh2xla', '_TZ3000_hdopuwv6'];
23
+ '_TZ3000_ss98ec5d', '_TZ3000_gznh2xla', '_TZ3000_hdopuwv6', '_TZ3000_gvn91tmx', '_TZ3000_dksbtrzs', '_TZ3000_b28wrpvx'];
24
24
 
25
25
  const tzLocal = {
26
26
  hpsz: {
@@ -737,7 +737,8 @@ module.exports = [
737
737
  {
738
738
  fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_mvn6jl7x'},
739
739
  {modelID: 'TS011F', manufacturerName: '_TZ3000_raviyuvk'}, {modelID: 'TS011F', manufacturerName: '_TYZB01_hlla45kx'},
740
- {modelID: 'TS011F', manufacturerName: '_TZ3000_92qd4sqa'}, {modelID: 'TS011F', manufacturerName: '_TZ3000_zwaadvus'}],
740
+ {modelID: 'TS011F', manufacturerName: '_TZ3000_92qd4sqa'}, {modelID: 'TS011F', manufacturerName: '_TZ3000_zwaadvus'},
741
+ {modelID: 'TS011F', manufacturerName: '_TZ3000_k6fvknrr'}],
741
742
  model: 'TS011F_2_gang_wall',
742
743
  vendor: 'TuYa',
743
744
  description: '2 gang wall outlet',
@@ -801,6 +802,7 @@ module.exports = [
801
802
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_remypqqm'},
802
803
  {modelID: 'TS0505B', manufacturerName: '_TZ3000_kohbva1f'},
803
804
  {modelID: 'TS0505B', manufacturerName: '_TZ3000_luit1t00'},
805
+ {modelID: 'TS0505B', manufacturerName: '_TZ3210_r5afgmkl'},
804
806
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_wslkvrau'},
805
807
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_0rn9qhnu'},
806
808
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_ejctepku'},
@@ -818,6 +820,7 @@ module.exports = [
818
820
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_mzdax7ha'},
819
821
  {modelID: 'TS0505B', manufacturerName: '_TZB210_tmi0rihb'},
820
822
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_a4s41wm4'},
823
+ {modelID: 'TS0505B', manufacturerName: '_TZ3210_ijczzg9h'},
821
824
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_qxenlrin'},
822
825
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_iwbaamgh'},
823
826
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_klv2wul0'},
@@ -826,6 +829,7 @@ module.exports = [
826
829
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_cuqkfz2q'},
827
830
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_6amjviba'},
828
831
  {modelID: 'TS0505B', manufacturerName: '_TZ3000_xr5m6kfg'},
832
+ {modelID: 'TS0505B', manufacturerName: '_TZ3210_xr5m6kfg'},
829
833
  {modelID: 'TS0505B', manufacturerName: '_TZ3210_bf175wi4'}],
830
834
  model: 'TS0505B',
831
835
  vendor: 'TuYa',
@@ -887,7 +891,9 @@ module.exports = [
887
891
  {modelID: 'TS0501B', manufacturerName: '_TZ3210_wuheofsg'},
888
892
  {modelID: 'TS0501B', manufacturerName: '_TZ3210_e5t9bfdv'},
889
893
  {modelID: 'TS0501B', manufacturerName: '_TZ3210_19qb27da'},
890
- {modelID: 'TS0501B', manufacturerName: '_TZ3210_4zinq6io'}],
894
+ {modelID: 'TS0501B', manufacturerName: '_TZ3210_aurnbfv4'},
895
+ {modelID: 'TS0501B', manufacturerName: '_TZ3210_4zinq6io'},
896
+ {modelID: 'TS0501B', manufacturerName: '_TZ3210_93gnbdgz'}],
891
897
  model: 'TS0501B',
892
898
  description: 'Zigbee light',
893
899
  vendor: 'TuYa',
@@ -1102,6 +1108,7 @@ module.exports = [
1102
1108
  description: 'Curtain/blind switch',
1103
1109
  fromZigbee: [fz.cover_position_tilt, fz.tuya_backlight_mode, fz.tuya_cover_options],
1104
1110
  toZigbee: [tz.cover_state, tz.cover_position_tilt, tz.tuya_cover_calibration, tz.tuya_cover_reversal, tz.tuya_backlight_mode],
1111
+ meta: {coverInverted: true},
1105
1112
  whiteLabel: [{vendor: 'LoraTap', model: 'SC400'}],
1106
1113
  exposes: [e.cover_position(), exposes.enum('moving', ea.STATE, ['UP', 'STOP', 'DOWN']),
1107
1114
  exposes.binary('calibration', ea.ALL, 'ON', 'OFF'), exposes.binary('motor_reversal', ea.ALL, 'ON', 'OFF'),
@@ -1465,7 +1472,7 @@ module.exports = [
1465
1472
  },
1466
1473
  },
1467
1474
  {
1468
- fingerprint: [{modelID: 'TS004F', manufacturerName: '_TZ3000_xabckq1v'}],
1475
+ fingerprint: [{modelID: 'TS004F', manufacturerName: '_TZ3000_xabckq1v'}, {modelID: 'TS004F', manufacturerName: '_TZ3000_czuyt8lz'}],
1469
1476
  model: 'TS004F',
1470
1477
  vendor: 'TuYa',
1471
1478
  description: 'Wireless switch with 4 buttons',
@@ -2406,6 +2413,8 @@ module.exports = [
2406
2413
  },
2407
2414
  meta: {multiEndpoint: true},
2408
2415
  configure: async (device, coordinatorEndpoint, logger) => {
2416
+ await device.getEndpoint(1).read('genBasic',
2417
+ ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
2409
2418
  await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
2410
2419
  await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
2411
2420
  await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']);
package/devices/woox.js CHANGED
@@ -34,6 +34,7 @@ const fzLocal = {
34
34
  case 14: {
35
35
  const batteryLevels = {0: 'low', 1: 'middle', 2: 'high'};
36
36
  result.battery_level = batteryLevels[value];
37
+ result.battery_low = value === 0;
37
38
  break;
38
39
  }
39
40
  case 16:
package/devices/xiaomi.js CHANGED
@@ -39,6 +39,94 @@ const preventReset = async (type, data, device) => {
39
39
  await device.getEndpoint(1).write('genBasic', payload, options);
40
40
  };
41
41
 
42
+
43
+ const fzLocal = {
44
+ aqara_trv: {
45
+ cluster: 'aqaraOpple',
46
+ type: ['attributeReport', 'readResponse'],
47
+ convert: (model, msg, publish, options, meta) => {
48
+ const result = {};
49
+ Object.entries(msg.data).forEach(([key, value]) => {
50
+ switch (parseInt(key)) {
51
+ case 0x0271:
52
+ result['state'] = {1: 'ON', 0: 'OFF'}[value];
53
+ break;
54
+ case 0x0272:
55
+ result['preset'] = {2: 'away', 1: 'auto', 0: 'manual'}[value];
56
+ break;
57
+ case 0x0273:
58
+ result['window_detection'] = {1: 'ON', 0: 'OFF'}[value];
59
+ break;
60
+ case 0x0274:
61
+ result['valve_detection'] = {1: 'ON', 0: 'OFF'}[value];
62
+ break;
63
+ case 0x0277:
64
+ result['child_lock'] = {1: 'LOCK', 0: 'UNLOCK'}[value];
65
+ break;
66
+ case 0x0279:
67
+ result['away_preset_temperature'] = (value / 100).toFixed(1);
68
+ break;
69
+ case 0x027b:
70
+ result['calibration'] = {1: true, 0: false}[value];
71
+ break;
72
+ case 0x027e:
73
+ result['sensor'] = {1: 'external', 0: 'internal'}[value];
74
+ break;
75
+ case 0x00ff: // 4e:27:49:bb:24:b6:30:dd:74:de:53:76:89:44:c4:81
76
+ case 0x00f7: // 03:28:1f:05:21:01:00:0a:21:00:00:0d:23:19:08:00:00:11:23...
77
+ case 0x0275: // 0x00000001
78
+ case 0x0276: // 04:3e:01:e0:00:00:09:60:04:38:00:00:06:a4:05:64:00:00:08:98:81:e0:00:00:08:98
79
+ case 0x027a: // 0x00
80
+ case 0x027c: // 0x00
81
+ case 0x027d: // 0x00
82
+ case 0x0280: // 0x00/0x01
83
+ case 0x040a: // 0x64
84
+ meta.logger.debug(`zigbee-herdsman-converters:aqara_trv: Unhandled key ${key} = ${value}`);
85
+ break;
86
+ default:
87
+ meta.logger.warn(`zigbee-herdsman-converters:aqara_trv: Unknown key ${key} = ${value}`);
88
+ }
89
+ });
90
+ return result;
91
+ },
92
+ },
93
+ };
94
+
95
+ const tzLocal = {
96
+ aqara_trv: {
97
+ key: ['state', 'preset', 'window_detection', 'valve_detection', 'child_lock', 'away_preset_temperature'],
98
+ convertSet: async (entity, key, value, meta) => {
99
+ switch (key) {
100
+ case 'state':
101
+ await entity.write('aqaraOpple', {0x0271: {value: {'OFF': 0, 'ON': 1}[value], type: 0x20}},
102
+ {manufacturerCode: 0x115f});
103
+ break;
104
+ case 'preset':
105
+ await entity.write('aqaraOpple', {0x0272: {value: {'manual': 0, 'auto': 1, 'away': 2}[value], type: 0x20}},
106
+ {manufacturerCode: 0x115f});
107
+ break;
108
+ case 'window_detection':
109
+ await entity.write('aqaraOpple', {0x0273: {value: {'OFF': 0, 'ON': 1}[value], type: 0x20}},
110
+ {manufacturerCode: 0x115f});
111
+ break;
112
+ case 'valve_detection':
113
+ await entity.write('aqaraOpple', {0x0274: {value: {'OFF': 0, 'ON': 1}[value], type: 0x20}},
114
+ {manufacturerCode: 0x115f});
115
+ break;
116
+ case 'child_lock':
117
+ await entity.write('aqaraOpple', {0x0277: {value: {'UNLOCK': 0, 'LOCK': 1}[value], type: 0x20}},
118
+ {manufacturerCode: 0x115f});
119
+ break;
120
+ case 'away_preset_temperature':
121
+ await entity.write('aqaraOpple', {0x0279: {value: Math.round(value * 100), type: 0x23}}, {manufacturerCode: 0x115f});
122
+ break;
123
+ default: // Unknown key
124
+ meta.logger.warn(`zigbee-herdsman-converters:aqara_trv: Unhandled key ${key}`);
125
+ }
126
+ },
127
+ },
128
+ };
129
+
42
130
  module.exports = [
43
131
  {
44
132
  zigbeeModel: ['lumi.flood.acn001'],
@@ -724,7 +812,7 @@ module.exports = [
724
812
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
725
813
  .withDescription('Decoupled mode for right button')
726
814
  .withEndpoint('right'),
727
- e.power().withAccess(ea.STATE), e.power_outage_memory(), e.led_disabled_night(),
815
+ e.power().withAccess(ea.STATE), e.power_outage_memory(), e.led_disabled_night(), e.voltage(),
728
816
  e.device_temperature().withAccess(ea.STATE), e.flip_indicator_light(),
729
817
  e.action([
730
818
  'single_left', 'double_left', 'single_center', 'double_center', 'single_right', 'double_right',
@@ -1685,7 +1773,7 @@ module.exports = [
1685
1773
  whiteLabel: [{vendor: 'Xiaomi', model: 'YTC4043GL'}],
1686
1774
  description: 'MiJia light intensity sensor',
1687
1775
  fromZigbee: [fz.battery, fz.illuminance, fz.aqara_opple],
1688
- toZigbee: [],
1776
+ toZigbee: [tz.illuminance],
1689
1777
  meta: {battery: {voltageToPercentage: '3V_2850_3000'}},
1690
1778
  configure: async (device, coordinatorEndpoint, logger) => {
1691
1779
  const endpoint = device.getEndpoint(1);
@@ -1693,7 +1781,8 @@ module.exports = [
1693
1781
  await reporting.illuminance(endpoint, {min: 15, max: constants.repInterval.HOUR, change: 500});
1694
1782
  await endpoint.read('genPowerCfg', ['batteryVoltage']);
1695
1783
  },
1696
- exposes: [e.battery(), e.battery_voltage(), e.illuminance(), e.illuminance_lux(), e.power_outage_count(false)],
1784
+ exposes: [e.battery(), e.battery_voltage(), e.illuminance().withAccess(ea.STATE_GET),
1785
+ e.illuminance_lux().withAccess(ea.STATE_GET), e.power_outage_count(false)],
1697
1786
  },
1698
1787
  {
1699
1788
  zigbeeModel: ['lumi.light.rgbac1'],
@@ -2164,4 +2253,18 @@ module.exports = [
2164
2253
  await endpoint1.read('aqaraOpple', [0x0125], {manufacturerCode: 0x115f});
2165
2254
  },
2166
2255
  },
2256
+ {
2257
+ zigbeeModel: ['lumi.airrtc.agl001'],
2258
+ model: 'SRTS-A01',
2259
+ vendor: 'Xiaomi',
2260
+ description: 'Aqara Smart Radiator Thermostat E1',
2261
+ fromZigbee: [fzLocal.aqara_trv, fz.thermostat],
2262
+ toZigbee: [tzLocal.aqara_trv, tz.thermostat_occupied_heating_setpoint],
2263
+ exposes: [e.switch().setAccess('state', ea.STATE_SET),
2264
+ exposes.climate().withSetpoint('occupied_heating_setpoint', 5, 30, 0.5)
2265
+ .withLocalTemperature(ea.STATE).withPreset(['manual', 'away', 'auto'], ea.STATE_SET),
2266
+ e.child_lock(), e.window_detection(), e.valve_detection(),
2267
+ e.away_preset_temperature(),
2268
+ ],
2269
+ },
2167
2270
  ];
package/devices/yale.js CHANGED
@@ -47,7 +47,7 @@ module.exports = [
47
47
  model: 'YMF30',
48
48
  vendor: 'Yale',
49
49
  description: 'Digital lock',
50
- extend: lockExtend(),
50
+ extend: lockExtend({battery: {dontDividePercentage: true}}),
51
51
  },
52
52
  {
53
53
  zigbeeModel: ['iZBModule01', '0700000001'],
package/lib/exposes.js CHANGED
@@ -423,6 +423,12 @@ class Climate extends Base {
423
423
  return this;
424
424
  }
425
425
 
426
+ withSwingMode(modes, access=a.ALL) {
427
+ assert(!this.endpoint, 'Cannot add feature after adding endpoint');
428
+ this.features.push(new Enum('swing_mode', access, modes).withDescription('Swing mode'));
429
+ return this;
430
+ }
431
+
426
432
  withSensor(sensors) {
427
433
  assert(!this.endpoint, 'Cannot add feature after adding endpoint');
428
434
  this.features.push(new Enum('sensor', access.STATE_SET, sensors).withDescription('Select temperature sensor to use'));
package/lib/reporting.js CHANGED
@@ -159,7 +159,7 @@ module.exports = {
159
159
  await endpoint.configureReporting('hvacThermostat', p);
160
160
  },
161
161
  thermostatUnoccupiedCoolingSetpoint: async (endpoint, overrides) => {
162
- const p = payload('occupiedCoolingSetpoint', 0, repInterval.HOUR, 10, overrides);
162
+ const p = payload('unoccupiedCoolingSetpoint', 0, repInterval.HOUR, 10, overrides);
163
163
  await endpoint.configureReporting('hvacThermostat', p);
164
164
  },
165
165
  thermostatPIHeatingDemand: async (endpoint, overrides) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.609",
3
+ "version": "14.0.612",
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.48"
41
+ "zigbee-herdsman": "^0.14.53"
42
42
  },
43
43
  "devDependencies": {
44
44
  "eslint": "*",