zigbee-herdsman-converters 14.0.520 → 14.0.523

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.
@@ -2257,7 +2257,9 @@ const converters = {
2257
2257
  const value = tuya.getDataValue(dpValue);
2258
2258
 
2259
2259
  switch (dp) {
2260
- case tuya.dataPoints.coverPosition: // Started moving to position (triggered from Zigbee)
2260
+ case tuya.dataPoints.coverPosition: { // Started moving to position (triggered from Zigbee)
2261
+ return {running: true};
2262
+ }
2261
2263
  case tuya.dataPoints.coverArrived: { // Arrived at position
2262
2264
  const running = dp === tuya.dataPoints.coverArrived ? false : true;
2263
2265
  const invert = tuya.isCoverInverted(meta.device.manufacturerName) ? !options.invert_cover : options.invert_cover;
@@ -5529,6 +5531,9 @@ const converters = {
5529
5531
  if (definition.exposes.find((e) => e.name === 'temperature')) {
5530
5532
  result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
5531
5533
  }
5534
+ if (definition.exposes.find((e) => e.name === 'device_temperature')) {
5535
+ result.push(exposes.options.precision('device_temperature'), exposes.options.calibration('device_temperature'));
5536
+ }
5532
5537
  if (definition.exposes.find((e) => e.name === 'illuminance')) {
5533
5538
  result.push(exposes.options.precision('illuminance'), exposes.options.calibration('illuminance', 'percentual'));
5534
5539
  }
@@ -5550,6 +5555,9 @@ const converters = {
5550
5555
  if (definition.exposes.find((e) => e.name === 'temperature')) {
5551
5556
  result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
5552
5557
  }
5558
+ if (definition.exposes.find((e) => e.name === 'device_temperature')) {
5559
+ result.push(exposes.options.precision('device_temperature'), exposes.options.calibration('device_temperature'));
5560
+ }
5553
5561
  return result;
5554
5562
  },
5555
5563
  convert: (model, msg, publish, options, meta) => {
@@ -5569,6 +5577,9 @@ const converters = {
5569
5577
  if (definition.exposes.find((e) => e.name === 'temperature')) {
5570
5578
  result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
5571
5579
  }
5580
+ if (definition.exposes.find((e) => e.name === 'device_temperature')) {
5581
+ result.push(exposes.options.precision('device_temperature'), exposes.options.calibration('device_temperature'));
5582
+ }
5572
5583
  if (definition.exposes.find((e) => e.name === 'illuminance')) {
5573
5584
  result.push(exposes.options.precision('illuminance'), exposes.options.calibration('illuminance', 'percentual'));
5574
5585
  }
@@ -2727,6 +2727,17 @@ const converters = {
2727
2727
  await entity.read('aqaraOpple', [0x0002], manufacturerOptions.xiaomi);
2728
2728
  },
2729
2729
  },
2730
+ RTCGQ14LM_trigger_indicator: {
2731
+ key: ['trigger_indicator'],
2732
+ convertSet: async (entity, key, value, meta) => {
2733
+ const lookup = {true: 1, false: 0};
2734
+ await entity.write('aqaraOpple', {0x0152: {value: lookup[value], type: 0x20}}, manufacturerOptions.xiaomi);
2735
+ return {state: {trigger_indicator: value}};
2736
+ },
2737
+ convertGet: async (entity, key, meta) => {
2738
+ await entity.read('aqaraOpple', [0x0152], manufacturerOptions.xiaomi);
2739
+ },
2740
+ },
2730
2741
  LLKZMK11LM_interlock: {
2731
2742
  key: ['interlock'],
2732
2743
  convertSet: async (entity, key, value, meta) => {
@@ -161,36 +161,10 @@ module.exports = [
161
161
  extend: extend.light_onoff_brightness(),
162
162
  },
163
163
  {
164
- zigbeeModel: ['3157100'],
164
+ fingerprint: [{modelID: '3157100', manufacturerName: 'Centralite'}, {modelID: '3157100-E', manufacturerName: 'Centralite'}],
165
165
  model: '3157100',
166
166
  vendor: 'Centralite',
167
- description: '3-Series pearl touch thermostat,',
168
- fromZigbee: [fz.battery, fz.legacy.thermostat_att_report, fz.fan, fz.ignore_time_read],
169
- toZigbee: [tz.factory_reset, tz.thermostat_local_temperature, tz.thermostat_local_temperature_calibration,
170
- tz.thermostat_occupied_heating_setpoint, tz.thermostat_occupied_cooling_setpoint,
171
- tz.thermostat_setpoint_raise_lower, tz.thermostat_remote_sensing,
172
- tz.thermostat_control_sequence_of_operation, tz.thermostat_system_mode,
173
- tz.thermostat_relay_status_log, tz.fan_mode, tz.thermostat_running_state],
174
- exposes: [e.battery(), exposes.climate().withSetpoint('occupied_heating_setpoint', 10, 30, 1).withLocalTemperature()
175
- .withSystemMode(['off', 'heat', 'cool', 'emergency_heating'])
176
- .withRunningState(['idle', 'heat', 'cool', 'fan_only']).withFanMode(['auto', 'on'])
177
- .withSetpoint('occupied_cooling_setpoint', 10, 30, 1)
178
- .withLocalTemperatureCalibration(-30, 30, 0.1)],
179
- meta: {battery: {voltageToPercentage: '3V_1500_2800'}},
180
- configure: async (device, coordinatorEndpoint, logger) => {
181
- const endpoint = device.getEndpoint(1);
182
- await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat', 'hvacFanCtrl']);
183
- await reporting.batteryVoltage(endpoint);
184
- await reporting.thermostatRunningState(endpoint);
185
- await reporting.thermostatTemperature(endpoint);
186
- await reporting.fanMode(endpoint);
187
- },
188
- },
189
- {
190
- zigbeeModel: ['3157100-E'],
191
- model: '3157100-E',
192
- vendor: 'Centralite',
193
- description: '3-Series pearl touch thermostat,',
167
+ description: '3-Series pearl touch thermostat',
194
168
  fromZigbee: [fz.battery, fz.thermostat, fz.fan, fz.ignore_time_read],
195
169
  toZigbee: [tz.factory_reset, tz.thermostat_local_temperature, tz.thermostat_local_temperature_calibration,
196
170
  tz.thermostat_occupied_heating_setpoint, tz.thermostat_occupied_cooling_setpoint,
@@ -200,11 +174,11 @@ module.exports = [
200
174
  exposes: [e.battery(),
201
175
  exposes.binary('temperature_setpoint_hold', ea.ALL, true, false)
202
176
  .withDescription('Prevent changes. `false` = run normally. `true` = prevent from making changes.'),
203
- exposes.climate().withSetpoint('occupied_heating_setpoint', 10, 30, 1).withLocalTemperature()
177
+ exposes.climate().withSetpoint('occupied_heating_setpoint', 7, 30, 1).withLocalTemperature()
204
178
  .withSystemMode(['off', 'heat', 'cool', 'emergency_heating'])
205
179
  .withRunningState(['idle', 'heat', 'cool', 'fan_only']).withFanMode(['auto', 'on'])
206
- .withSetpoint('occupied_cooling_setpoint', 10, 30, 1)
207
- .withLocalTemperatureCalibration(-30, 30, 0.1)],
180
+ .withSetpoint('occupied_cooling_setpoint', 7, 30, 1)
181
+ .withLocalTemperatureCalibration(-2.5, 2.5, 0.1)],
208
182
  meta: {battery: {voltageToPercentage: '3V_1500_2800'}},
209
183
  configure: async (device, coordinatorEndpoint, logger) => {
210
184
  const endpoint = device.getEndpoint(1);
@@ -222,7 +196,7 @@ module.exports = [
222
196
  vendor: 'Centralite',
223
197
  description: 'HA thermostat',
224
198
  fromZigbee: [fz.battery, fz.thermostat, fz.fan, fz.ignore_time_read],
225
- toZigbee: [tz.factory_reset, tz.thermostat_local_temperature, tz.thermostat_local_temperature_calibration,
199
+ toZigbee: [tz.factory_reset, tz.thermostat_local_temperature,
226
200
  tz.thermostat_occupied_heating_setpoint, tz.thermostat_occupied_cooling_setpoint,
227
201
  tz.thermostat_setpoint_raise_lower, tz.thermostat_remote_sensing,
228
202
  tz.thermostat_control_sequence_of_operation, tz.thermostat_system_mode,
@@ -230,11 +204,10 @@ module.exports = [
230
204
  exposes: [e.battery(),
231
205
  exposes.binary('temperature_setpoint_hold', ea.ALL, true, false)
232
206
  .withDescription('Prevent changes. `false` = run normally. `true` = prevent from making changes.'),
233
- exposes.climate().withSetpoint('occupied_heating_setpoint', 6.66, 30, 1).withLocalTemperature()
207
+ exposes.climate().withSetpoint('occupied_heating_setpoint', 7, 30, 1).withLocalTemperature()
234
208
  .withSystemMode(['off', 'heat', 'cool', 'emergency_heating'])
235
209
  .withRunningState(['idle', 'heat', 'cool', 'fan_only']).withFanMode(['auto', 'on'])
236
- .withSetpoint('occupied_cooling_setpoint', 6.66, 30, 1)
237
- .withLocalTemperatureCalibration(-30, 30, 0.1)],
210
+ .withSetpoint('occupied_cooling_setpoint', 7, 30, 1)],
238
211
  meta: {battery: {voltageToPercentage: '3V_1500_2800'}},
239
212
  configure: async (device, coordinatorEndpoint, logger) => {
240
213
  const endpoint = device.getEndpoint(1);
package/devices/innr.js CHANGED
@@ -60,7 +60,8 @@ module.exports = [
60
60
  model: 'OPL 130 C',
61
61
  vendor: 'Innr',
62
62
  description: 'Outdoor smart pedestal light colour',
63
- extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
63
+ extend: extend.light_onoff_brightness_colortemp_color(
64
+ {colorTempRange: [153, 555], supportsHS: true, disableColorTempStartup: true}),
64
65
  meta: {applyRedFix: true, turnsOffAtBrightness1: true},
65
66
  },
66
67
  {
package/devices/insta.js CHANGED
@@ -21,7 +21,7 @@ module.exports = [
21
21
  ota: ota.zigbeeOTA,
22
22
  },
23
23
  {
24
- zigbeeModel: ['Generic UP Device'],
24
+ zigbeeModel: ['NEXENTRO Blinds Actuator', 'Generic UP Device'],
25
25
  model: '57008000',
26
26
  vendor: 'Insta',
27
27
  description: 'Blinds actor with lift/tilt calibration & with with inputs for wall switches',
package/devices/kmpcil.js CHANGED
@@ -3,8 +3,71 @@ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/lega
3
3
  const tz = require('../converters/toZigbee');
4
4
  const constants = require('../lib/constants');
5
5
  const reporting = require('../lib/reporting');
6
+ const globalStore = require('../lib/store');
7
+ const utils = require('../lib/utils');
6
8
  const e = exposes.presets;
7
9
 
10
+ const kmpcilOptions={
11
+ presence_timeout_dc: () => {
12
+ return exposes.numeric('presence_timeout_dc').withValueMin(60).withDescription(
13
+ 'Time in seconds after which presence is cleared after detecting it (default 60 seconds) while in DC.');
14
+ },
15
+ presence_timeout_battery: () => {
16
+ return exposes.numeric('presence_timeout_battery').withValueMin(120).withDescription(
17
+ 'Time in seconds after which presence is cleared after detecting it (default 420 seconds) while in Battery.');
18
+ },
19
+ };
20
+
21
+ function handleKmpcilPresence(model, msg, publish, options, meta) {
22
+ const useOptionsTimeoutBattery = options && options.hasOwnProperty('presence_timeout_battery');
23
+ const timeoutBattery = useOptionsTimeoutBattery ? options.presence_timeout_battery : 420; // 100 seconds by default
24
+
25
+ const useOptionsTimeoutDc = options && options.hasOwnProperty('presence_timeout_dc');
26
+ const timeoutDc = useOptionsTimeoutDc ? options.presence_timeout_dc : 60;
27
+
28
+ const mode = meta.state? meta.state['power_state'] : false;
29
+
30
+ const timeout = mode ? timeoutDc : timeoutBattery;
31
+ // Stop existing timer because motion is detected and set a new one.
32
+ clearTimeout(globalStore.getValue(msg.endpoint, 'timer'));
33
+ const timer = setTimeout(() => publish({presence: false}), timeout * 1000);
34
+ globalStore.putValue(msg.endpoint, 'timer', timer);
35
+
36
+ return {presence: true};
37
+ }
38
+
39
+ const kmpcilConverters = {
40
+ presence_binary_input: {
41
+ cluster: 'genBinaryInput',
42
+ type: ['attributeReport', 'readResponse'],
43
+ convert: (model, msg, publish, options, meta) => {
44
+ const payload = handleKmpcilPresence(model, msg, publish, options, meta);
45
+ if (msg.data.hasOwnProperty('presentValue')) {
46
+ const presentValue = msg.data['presentValue'];
47
+ payload.power_state = (presentValue & 0x01)> 0;
48
+ payload.occupancy = (presentValue & 0x04) > 0;
49
+ payload.vibration = (presentValue & 0x02) > 0;
50
+ }
51
+ return payload;
52
+ },
53
+ },
54
+ presence_power: {
55
+ cluster: 'genPowerCfg',
56
+ type: ['attributeReport', 'readResponse'],
57
+ options: [kmpcilOptions.presence_timeout_dc(), kmpcilOptions.presence_timeout_battery()],
58
+ convert: (model, msg, publish, options, meta) => {
59
+ const payload = handleKmpcilPresence(model, msg, publish, options, meta);
60
+ if (msg.data.hasOwnProperty('batteryVoltage')) {
61
+ payload.voltage = msg.data['batteryVoltage'] * 100;
62
+ if (model.meta && model.meta.battery && model.meta.battery.voltageToPercentage) {
63
+ payload.battery = utils.batteryVoltageToPercentage(payload.voltage, model.meta.battery.voltageToPercentage);
64
+ }
65
+ }
66
+ return payload;
67
+ },
68
+ },
69
+ };
70
+
8
71
  module.exports = [
9
72
  {
10
73
  zigbeeModel: ['RES005'],
@@ -47,4 +110,38 @@ module.exports = [
47
110
  await endpoint.configureReporting('genBinaryOutput', payloadBinaryOutput);
48
111
  },
49
112
  },
113
+ {
114
+ zigbeeModel: ['tagv1'],
115
+ model: 'KMPCIL-tag-001',
116
+ vendor: 'KMPCIL',
117
+ description: 'Arrival sensor',
118
+ fromZigbee: [kmpcilConverters.presence_binary_input, kmpcilConverters.presence_power, fz.temperature],
119
+ exposes: [e.battery(), e.presence(), exposes.binary('power_state', exposes.access.STATE, true, false),
120
+ e.occupancy(), e.vibration(), e.temperature()],
121
+ toZigbee: [],
122
+ meta: {battery: {voltageToPercentage: '3V_1500_2800'}},
123
+ configure: async (device, coordinatorEndpoint, logger) => {
124
+ const endpoint = device.getEndpoint(1);
125
+ for (const cluster of ['msTemperatureMeasurement', 'genPowerCfg', 'genBinaryInput']) {
126
+ // This sleep here(and the sleep) after is to allow the command to be
127
+ // fully sent to coordinator. In case repeater involved and the repeater
128
+ // is litted in resources, we may want to give some time so that the sequence of
129
+ // commands does not overwhelm the repeater.
130
+ await utils.sleep(2000);
131
+ await endpoint.bind(cluster, coordinatorEndpoint);
132
+ }
133
+
134
+ await utils.sleep(1000);
135
+ const p = reporting.payload('batteryVoltage', 0, 10, 1);
136
+ await endpoint.configureReporting('genPowerCfg', p);
137
+
138
+ await utils.sleep(1000);
139
+ const p2 = reporting.payload('presentValue', 0, 300, 1);
140
+ await endpoint.configureReporting('genBinaryInput', p2);
141
+
142
+ await utils.sleep(1000);
143
+ await reporting.temperature(endpoint);
144
+ await endpoint.read('genBinaryInput', ['presentValue']);
145
+ },
146
+ },
50
147
  ];
@@ -32,8 +32,8 @@ module.exports = [
32
32
  {
33
33
  zigbeeModel: [' Contactor\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'+
34
34
  '\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'],
35
- model: 'FC80CC',
36
- description: 'Legrand (or Bticino) DIN contactor module',
35
+ model: '412171',
36
+ description: 'DIN contactor module ( Bticino FC80CC )',
37
37
  vendor: 'Legrand',
38
38
  extend: extend.switch(),
39
39
  fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_cluster_fc01, fz.ignore_basic_report, fz.ignore_genOta],
@@ -52,8 +52,8 @@ module.exports = [
52
52
  {
53
53
  zigbeeModel: [' Teleruptor\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'+
54
54
  '\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'],
55
- model: 'FC80RC',
56
- description: 'Legrand (or Bticino) DIN smart relay for light control (note: Legrand 412170 may be similar to Bticino FC80RC)',
55
+ model: '412170',
56
+ description: 'DIN smart relay for light control ( Bticino FC80RC ) ',
57
57
  vendor: 'Legrand',
58
58
  extend: extend.switch(),
59
59
  fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_cluster_fc01, fz.ignore_basic_report, fz.ignore_genOta],
@@ -14,6 +14,7 @@ module.exports = [
14
14
  description: 'Water leak switch',
15
15
  fromZigbee: [fz.ias_water_leak_alarm_1, fz.battery],
16
16
  toZigbee: [],
17
+ meta: {battery: {dontDividePercentage: true}},
17
18
  exposes: [e.water_leak(), e.battery_low(), e.tamper(), e.battery()],
18
19
  },
19
20
  {
@@ -82,6 +83,7 @@ module.exports = [
82
83
  description: 'Air sensor',
83
84
  fromZigbee: [fz.lifecontrolVoc, fz.battery],
84
85
  toZigbee: [],
86
+ meta: {battery: {dontDividePercentage: true}},
85
87
  exposes: [e.temperature(), e.humidity(), e.voc(), e.eco2(), e.battery()],
86
88
  },
87
89
  ];
@@ -25,6 +25,15 @@ module.exports = [
25
25
  toZigbee: [tz.tuya_cover_control, tz.tuya_cover_options],
26
26
  exposes: [e.cover_position().setAccess('position', ea.STATE_SET)],
27
27
  },
28
+ {
29
+ zigbeeModel: ['sbordckq'],
30
+ model: 'SM-1CTW-EU',
31
+ vendor: 'Somgoms',
32
+ description: 'Curtain switch',
33
+ fromZigbee: [fz.tuya_cover, fz.ignore_basic_report],
34
+ toZigbee: [tz.tuya_cover_control, tz.tuya_cover_options],
35
+ exposes: [e.cover_position().setAccess('position', ea.STATE_SET)],
36
+ },
28
37
  {
29
38
  zigbeeModel: ['hpb9yts'],
30
39
  model: 'ZSTY-SM-1DMZG-US-W',
package/devices/sonoff.js CHANGED
@@ -5,6 +5,7 @@ const constants = require('../lib/constants');
5
5
  const reporting = require('../lib/reporting');
6
6
  const extend = require('../lib/extend');
7
7
  const e = exposes.presets;
8
+ const ota = require('../lib/ota');
8
9
 
9
10
  module.exports = [
10
11
  {
@@ -20,6 +21,7 @@ module.exports = [
20
21
  model: 'ZBMINI-L',
21
22
  vendor: 'SONOFF',
22
23
  description: 'Zigbee smart switch (no neutral)',
24
+ ota: ota.zigbeeOTA,
23
25
  extend: extend.switch(),
24
26
  toZigbee: extend.switch().toZigbee.concat([tz.power_on_behavior]),
25
27
  fromZigbee: extend.switch().fromZigbee.concat([fz.power_on_behavior]),
@@ -1,10 +1,34 @@
1
1
  const exposes = require('../lib/exposes');
2
- const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
2
+ const fz = require('../converters/fromZigbee');
3
+ const tz = require('../converters/toZigbee');
3
4
  const reporting = require('../lib/reporting');
4
5
  const extend = require('../lib/extend');
5
6
  const e = exposes.presets;
6
7
 
7
8
  module.exports = [
9
+ {
10
+ zigbeeModel: ['S24019'],
11
+ model: 'S24019',
12
+ vendor: 'The Light Group',
13
+ description: 'SLC SmartOne led dimmer',
14
+ fromZigbee: [fz.on_off, fz.brightness, fz.metering, fz.electrical_measurement],
15
+ toZigbee: [tz.light_onoff_brightness, tz.level_config],
16
+ exposes: [e.light_brightness().withLevelConfig()],
17
+ configure: async (device, coordinatorEndpoint, logger) => {
18
+ // Endpoint 1
19
+ const endpoint1 = device.getEndpoint(1);
20
+ const binds1 = ['genOnOff', 'genLevelCtrl', 'haElectricalMeasurement', 'seMetering'];
21
+ await reporting.bind(endpoint1, coordinatorEndpoint, binds1);
22
+ await reporting.onOff(endpoint1);
23
+ await reporting.brightness(endpoint1);
24
+ await reporting.readEletricalMeasurementMultiplierDivisors(endpoint1);
25
+ await reporting.activePower(endpoint1, {min: 5, max: 3600, change: 1000});
26
+ await reporting.rmsCurrent(endpoint1, {min: 5, max: 3600, change: 100});
27
+ await reporting.rmsVoltage(endpoint1, {min: 5, max: 3600, change: 100});
28
+ // read switch state
29
+ await endpoint1.read('genOnOff', ['onOff']);
30
+ },
31
+ },
8
32
  {
9
33
  zigbeeModel: ['S57003'],
10
34
  model: 'S57003',
@@ -98,4 +98,20 @@ module.exports = [
98
98
  await reporting.onOff(endpoint);
99
99
  },
100
100
  },
101
+ {
102
+ zigbeeModel: ['3RSB015BZ'],
103
+ model: '3RSB015BZ',
104
+ vendor: 'Third Reality',
105
+ description: 'Roller shade',
106
+ fromZigbee: [fz.cover_position_tilt, fz.battery],
107
+ toZigbee: [tz.cover_state, tz.cover_position_tilt],
108
+ meta: {battery: {dontDividePercentage: false}},
109
+ configure: async (device, coordinatorEndpoint, logger) => {
110
+ const endpoint = device.getEndpoint(1);
111
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'closuresWindowCovering']);
112
+ await reporting.batteryPercentageRemaining(endpoint);
113
+ await reporting.currentPositionLiftPercentage(endpoint);
114
+ },
115
+ exposes: [e.cover_position(), e.battery()],
116
+ },
101
117
  ];
package/devices/tuya.js CHANGED
@@ -214,7 +214,8 @@ module.exports = [
214
214
  {modelID: 'TS0001', manufacturerName: '_TZ3000_5ng23zjs'},
215
215
  {modelID: 'TS0001', manufacturerName: '_TZ3000_rmjr4ufz'},
216
216
  {modelID: 'TS0001', manufacturerName: '_TZ3000_v7gnj3ad'},
217
- {modelID: 'TS0001', manufacturerName: '_TZ3000_mx3vgyea'}],
217
+ {modelID: 'TS0001', manufacturerName: '_TZ3000_mx3vgyea'},
218
+ {modelID: 'TS0001', manufacturerName: '_TZ3000_qsp2pwtf'}],
218
219
  model: 'WHD02',
219
220
  vendor: 'TuYa',
220
221
  description: 'Wall switch module',
@@ -247,7 +248,7 @@ module.exports = [
247
248
  fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3000_rk2yzt0u'},
248
249
  {modelID: 'TS0001', manufacturerName: '_TZ3000_o4cjetlm'}, {manufacturerName: '_TZ3000_o4cjetlm'},
249
250
  {modelID: 'TS0001', manufacturerName: '_TZ3000_iedbgyxt'}, {modelID: 'TS0001', manufacturerName: '_TZ3000_h3noz0a5'},
250
- {modelID: 'TS0001', manufacturerName: '_TYZB01_4tlksk8a'}],
251
+ {modelID: 'TS0001', manufacturerName: '_TYZB01_4tlksk8a'}, {modelID: 'TS0011', manufacturerName: '_TYZB01_rifa0wlb'}],
251
252
  model: 'ZN231392',
252
253
  vendor: 'TuYa',
253
254
  description: 'Smart water/gas valve',
@@ -1099,7 +1100,6 @@ module.exports = [
1099
1100
  {modelID: 'zo2pocs\u0000', manufacturerName: '_TYST11_fzo2pocs'},
1100
1101
  {modelID: 'TS0601', manufacturerName: '_TZE200_cf1sl3tj'},
1101
1102
  // Roller blinds:
1102
- {modelID: 'TS0601', manufacturerName: '_TZE200_sbordckq'},
1103
1103
  {modelID: 'TS0601', manufacturerName: '_TZE200_fctwhugx'},
1104
1104
  {modelID: 'TS0601', manufacturerName: '_TZE200_zah67ekd'},
1105
1105
  {modelID: 'TS0601', manufacturerName: '_TZE200_hsgrhjpf'},
package/devices/xiaomi.js CHANGED
@@ -79,7 +79,7 @@ module.exports = [
79
79
  endpoint: (device) => {
80
80
  return {l1: 1, l2: 2};
81
81
  },
82
- exposes: [e.power(), e.energy(), e.voltage(), e.temperature(), e.power_outage_memory(),
82
+ exposes: [e.power(), e.energy(), e.voltage(), e.device_temperature(), e.power_outage_memory(),
83
83
  // When in rgbw mode, only one of color and colortemp will be valid, and l2 will be invalid
84
84
  // Do not control l2 in rgbw mode
85
85
  e.light_brightness_colortemp_colorxy([153, 370]).removeFeature('color_temp_startup').withEndpoint('l1'),
@@ -177,7 +177,8 @@ module.exports = [
177
177
  vendor: 'Xiaomi',
178
178
  description: 'Aqara wireless switch',
179
179
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
180
- exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'triple', 'quadruple', 'hold', 'release'])],
180
+ exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'triple', 'quadruple', 'hold', 'release']),
181
+ e.device_temperature(), e.power_outage_count()],
181
182
  fromZigbee: [fz.xiaomi_multistate_action, fz.xiaomi_WXKG11LM_action, fz.xiaomi_basic,
182
183
  fz.legacy.WXKG11LM_click, fz.legacy.xiaomi_action_click_multistate],
183
184
  toZigbee: [],
@@ -336,8 +337,8 @@ module.exports = [
336
337
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.aqara_opple, fz.xiaomi_multistate_action],
337
338
  toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory,
338
339
  tz.xiaomi_led_disabled_night, tz.xiaomi_flip_indicator_light],
339
- exposes: [e.switch().withEndpoint('left'), e.switch().withEndpoint('right'),
340
- e.power(), e.energy(), e.voltage(), e.temperature(), e.power_outage_memory(), e.led_disabled_night(), e.flip_indicator_light(),
340
+ exposes: [e.switch().withEndpoint('left'), e.switch().withEndpoint('right'), e.power(), e.energy(), e.voltage(),
341
+ e.device_temperature(), e.power_outage_memory(), e.led_disabled_night(), e.flip_indicator_light(),
341
342
  e.action([
342
343
  'single_left', 'single_right', 'single_both',
343
344
  'double_left', 'double_right', 'double_both']),
@@ -397,7 +398,7 @@ module.exports = [
397
398
  toZigbee: [tz.on_off, tz.xiaomi_power, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory,
398
399
  tz.xiaomi_flip_indicator_light],
399
400
  exposes: [e.switch(), e.action(['single', 'double']), e.power().withAccess(ea.STATE_GET), e.energy(), e.flip_indicator_light(),
400
- e.power_outage_memory(), e.temperature().withAccess(ea.STATE),
401
+ e.power_outage_memory(), e.device_temperature().withAccess(ea.STATE),
401
402
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']).withDescription('Decoupled mode')],
402
403
  onEvent: preventReset,
403
404
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -424,7 +425,7 @@ module.exports = [
424
425
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']).withDescription('Decoupled mode for right button')
425
426
  .withEndpoint('right'),
426
427
  e.action(['single_left', 'double_left', 'single_right', 'double_right', 'single_both', 'double_both']),
427
- e.temperature().withAccess(ea.STATE), e.power_outage_memory(), e.flip_indicator_light()],
428
+ e.device_temperature().withAccess(ea.STATE), e.power_outage_memory(), e.flip_indicator_light()],
428
429
  onEvent: preventReset,
429
430
  configure: async (device, coordinatorEndpoint, logger) => {
430
431
  const endpoint1 = device.getEndpoint(1);
@@ -465,7 +466,7 @@ module.exports = [
465
466
  fz.legacy.QBKG04LM_QBKG11LM_click, fz.xiaomi_basic, fz.xiaomi_operation_mode_basic,
466
467
  fz.legacy.QBKG11LM_click, fz.ignore_multistate_report, fz.xiaomi_power],
467
468
  exposes: [
468
- e.switch(), e.power().withAccess(ea.STATE_GET), e.temperature(),
469
+ e.switch(), e.power().withAccess(ea.STATE_GET), e.device_temperature(),
469
470
  e.action(['single', 'double', 'release', 'hold']),
470
471
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
471
472
  .withDescription('Decoupled mode'),
@@ -487,7 +488,7 @@ module.exports = [
487
488
  exposes: [
488
489
  e.switch().withEndpoint('left'),
489
490
  e.switch().withEndpoint('right'),
490
- e.temperature(),
491
+ e.device_temperature(),
491
492
  e.action(['release_left', 'release_right', 'release_both', 'double_left', 'double_right',
492
493
  'single_left', 'single_right', 'hold_release_left', 'hold_release_left']),
493
494
  exposes.enum('operation_mode', ea.STATE_SET, ['control_left_relay', 'control_right_relay', 'decoupled'])
@@ -521,7 +522,7 @@ module.exports = [
521
522
  exposes: [
522
523
  e.switch().withEndpoint('left'),
523
524
  e.switch().withEndpoint('right'),
524
- e.temperature(),
525
+ e.device_temperature(),
525
526
  e.power().withAccess(ea.STATE_GET),
526
527
  e.action(['single_left', 'single_right', 'single_both', 'double_left', 'double_right', 'double_both',
527
528
  'hold_left', 'hold_right', 'hold_both', 'release_left', 'release_right', 'release_both']),
@@ -637,7 +638,7 @@ module.exports = [
637
638
  exposes.enum('mode_switch', ea.ALL, ['anti_flicker_mode', 'quick_mode'])
638
639
  .withDescription('Anti flicker mode can be used to solve blinking issues of some lights.' +
639
640
  'Quick mode makes the device respond faster.'),
640
- e.power_outage_memory(), e.led_disabled_night(), e.temperature().withAccess(ea.STATE), e.flip_indicator_light(),
641
+ e.power_outage_memory(), e.led_disabled_night(), e.device_temperature().withAccess(ea.STATE), e.flip_indicator_light(),
641
642
  e.action([
642
643
  'left_single', 'left_double', 'center_single', 'center_double', 'right_single', 'right_double',
643
644
  'single_left_center', 'double_left_center', 'single_left_right', 'double_left_right',
@@ -667,7 +668,7 @@ module.exports = [
667
668
  .withDescription('Decoupled mode for right button')
668
669
  .withEndpoint('right'),
669
670
  e.power().withAccess(ea.STATE), e.power_outage_memory(), e.led_disabled_night(),
670
- e.temperature().withAccess(ea.STATE), e.flip_indicator_light(),
671
+ e.device_temperature().withAccess(ea.STATE), e.flip_indicator_light(),
671
672
  e.action([
672
673
  'single_left', 'double_left', 'single_center', 'double_center', 'single_right', 'double_right',
673
674
  'single_left_center', 'double_left_center', 'single_left_right', 'double_left_right',
@@ -698,7 +699,7 @@ module.exports = [
698
699
  onEvent: preventReset,
699
700
  exposes: [
700
701
  e.switch(), e.power().withAccess(ea.STATE_GET),
701
- e.energy(), e.temperature().withAccess(ea.STATE),
702
+ e.energy(), e.device_temperature().withAccess(ea.STATE),
702
703
  e.voltage().withAccess(ea.STATE), e.action(['single', 'release']),
703
704
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
704
705
  .withDescription('Decoupled mode'),
@@ -748,7 +749,7 @@ module.exports = [
748
749
  tz.xiaomi_led_disabled_night, tz.xiaomi_flip_indicator_light],
749
750
  exposes: [
750
751
  e.switch(), e.action(['single', 'double']), e.power().withAccess(ea.STATE), e.energy(),
751
- e.voltage().withAccess(ea.STATE), e.temperature().withAccess(ea.STATE),
752
+ e.voltage().withAccess(ea.STATE), e.device_temperature().withAccess(ea.STATE),
752
753
  e.power_outage_memory(), e.led_disabled_night(), e.flip_indicator_light(),
753
754
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
754
755
  .withDescription('Decoupled mode for left button'),
@@ -771,7 +772,7 @@ module.exports = [
771
772
  exposes: [
772
773
  e.switch().withEndpoint('left'), e.switch().withEndpoint('right'),
773
774
  e.power().withAccess(ea.STATE), e.energy(), e.voltage().withAccess(ea.STATE), e.flip_indicator_light(),
774
- e.power_outage_memory(), e.led_disabled_night(), e.temperature().withAccess(ea.STATE),
775
+ e.power_outage_memory(), e.led_disabled_night(), e.device_temperature().withAccess(ea.STATE),
775
776
  e.action([
776
777
  'single_left', 'double_left', 'single_right', 'double_right', 'single_both', 'double_both']),
777
778
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
@@ -799,7 +800,7 @@ module.exports = [
799
800
  exposes: [
800
801
  e.switch().withEndpoint('left'), e.switch().withEndpoint('center'), e.switch().withEndpoint('right'),
801
802
  e.power().withAccess(ea.STATE), e.energy(), e.voltage().withAccess(ea.STATE), e.flip_indicator_light(),
802
- e.power_outage_memory(), e.led_disabled_night(), e.temperature().withAccess(ea.STATE),
803
+ e.power_outage_memory(), e.led_disabled_night(), e.device_temperature().withAccess(ea.STATE),
803
804
  e.action([
804
805
  'single_left', 'double_left', 'single_center', 'double_center',
805
806
  'single_right', 'double_right', 'single_left_center', 'double_left_center',
@@ -849,7 +850,7 @@ module.exports = [
849
850
  description: 'Aqara T1 temperature, humidity and pressure sensor',
850
851
  fromZigbee: [fz.aqara_opple, fz.temperature, fz.humidity, fz.pressure, fz.battery],
851
852
  toZigbee: [],
852
- exposes: [e.temperature(), e.humidity(), e.pressure(), e.battery(), e.battery_voltage()],
853
+ exposes: [e.temperature(), e.humidity(), e.pressure(), e.device_temperature(), e.battery(), e.battery_voltage()],
853
854
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
854
855
  configure: async (device, coordinatorEndpoint, logger) => {
855
856
  const endpoint = device.getEndpoint(1);
@@ -877,7 +878,7 @@ module.exports = [
877
878
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
878
879
  fromZigbee: [fz.xiaomi_basic, fz.occupancy_with_timeout, fz.RTCGQ11LM_illuminance],
879
880
  toZigbee: [],
880
- exposes: [e.battery(), e.occupancy(), e.temperature(), e.battery_voltage(), e.illuminance_lux().withProperty('illuminance'),
881
+ exposes: [e.battery(), e.occupancy(), e.device_temperature(), e.battery_voltage(), e.illuminance_lux().withProperty('illuminance'),
881
882
  e.illuminance().withUnit('lx').withDescription('Measured illuminance in lux')],
882
883
  },
883
884
  {
@@ -890,7 +891,7 @@ module.exports = [
890
891
  exposes: [e.occupancy(), e.illuminance_lux().withProperty('illuminance'),
891
892
  e.illuminance().withUnit('lx').withDescription('Measured illuminance in lux'),
892
893
  exposes.numeric('detection_interval', ea.ALL).withValueMin(2).withValueMax(65535).withUnit('s')
893
- .withDescription('Time interval for detecting actions'), e.temperature(), e.battery()],
894
+ .withDescription('Time interval for detecting actions'), e.device_temperature(), e.battery(), e.battery_voltage()],
894
895
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
895
896
  configure: async (device, coordinatorEndpoint, logger) => {
896
897
  const endpoint = device.getEndpoint(1);
@@ -908,7 +909,7 @@ module.exports = [
908
909
  toZigbee: [tz.aqara_detection_interval, tz.aqara_motion_sensitivity],
909
910
  exposes: [e.occupancy(), exposes.enum('motion_sensitivity', ea.ALL, ['low', 'medium', 'high']),
910
911
  exposes.numeric('detection_interval', ea.ALL).withValueMin(2).withValueMax(65535).withUnit('s')
911
- .withDescription('Time interval for detecting actions'), e.temperature(), e.battery()],
912
+ .withDescription('Time interval for detecting actions'), e.device_temperature(), e.battery(), e.battery_voltage()],
912
913
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
913
914
  configure: async (device, coordinatorEndpoint, logger) => {
914
915
  const endpoint = device.getEndpoint(1);
@@ -925,18 +926,21 @@ module.exports = [
925
926
  whiteLabel: [{vendor: 'Xiaomi', model: 'MS-S02'}],
926
927
  description: 'Aqara P1 human body movement and illuminance sensor',
927
928
  fromZigbee: [fz.aqara_occupancy_illuminance, fz.aqara_opple, fz.battery],
928
- toZigbee: [tz.aqara_detection_interval, tz.aqara_motion_sensitivity],
929
+ toZigbee: [tz.aqara_detection_interval, tz.aqara_motion_sensitivity, tz.RTCGQ14LM_trigger_indicator],
929
930
  exposes: [e.occupancy(), e.illuminance_lux().withProperty('illuminance'),
930
931
  e.illuminance().withUnit('lx').withDescription('Measured illuminance in lux'),
931
932
  exposes.enum('motion_sensitivity', ea.ALL, ['low', 'medium', 'high']),
932
933
  exposes.numeric('detection_interval', ea.ALL).withValueMin(2).withValueMax(65535).withUnit('s')
933
- .withDescription('Time interval for detecting actions'), e.temperature(), e.battery()],
934
+ .withDescription('Time interval for detecting actions'),
935
+ exposes.binary('trigger_indicator', ea.ALL, true, false).withDescription('When this option is enabled then ' +
936
+ 'blue LED will blink once when motion is detected'), e.device_temperature(), e.battery(), e.battery_voltage()],
934
937
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
935
938
  configure: async (device, coordinatorEndpoint, logger) => {
936
939
  const endpoint = device.getEndpoint(1);
937
940
  await endpoint.read('genPowerCfg', ['batteryVoltage']);
938
941
  await endpoint.read('aqaraOpple', [0x0102], {manufacturerCode: 0x115f});
939
942
  await endpoint.read('aqaraOpple', [0x010c], {manufacturerCode: 0x115f});
943
+ await endpoint.read('aqaraOpple', [0x0152], {manufacturerCode: 0x115f});
940
944
  },
941
945
  ota: ota.zigbeeOTA,
942
946
  },
@@ -948,7 +952,7 @@ module.exports = [
948
952
  fromZigbee: [fz.aqara_opple],
949
953
  toZigbee: [tz.RTCZCGQ11LM_presence, tz.RTCZCGQ11LM_monitoring_mode, tz.RTCZCGQ11LM_approach_distance,
950
954
  tz.aqara_motion_sensitivity, tz.RTCZCGQ11LM_reset_nopresence_status],
951
- exposes: [e.presence().withAccess(ea.STATE_GET), e.power_outage_count(), e.temperature(),
955
+ exposes: [e.presence().withAccess(ea.STATE_GET),
952
956
  exposes.enum('presence_event', ea.STATE, ['enter', 'leave', 'left_enter', 'right_leave', 'right_enter', 'left_leave',
953
957
  'approach', 'away']).withDescription('Presence events: "enter", "leave", "left_enter", "right_leave", ' +
954
958
  '"right_enter", "left_leave", "approach", "away"'),
@@ -959,7 +963,7 @@ module.exports = [
959
963
  exposes.enum('motion_sensitivity', ea.ALL, ['low', 'medium', 'high']).withDescription('Different sensitivities ' +
960
964
  'means different static human body recognition rate and response speed of occupied'),
961
965
  exposes.enum('reset_nopresence_status', ea.SET, ['Reset']).withDescription('Reset the status of no presence'),
962
- ],
966
+ e.device_temperature(), e.power_outage_count()],
963
967
  configure: async (device, coordinatorEndpoint, logger) => {
964
968
  const endpoint = device.getEndpoint(1);
965
969
  await endpoint.read('aqaraOpple', [0x010c], {manufacturerCode: 0x115f});
@@ -987,7 +991,7 @@ module.exports = [
987
991
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
988
992
  fromZigbee: [fz.xiaomi_basic, fz.xiaomi_contact],
989
993
  toZigbee: [],
990
- exposes: [e.battery(), e.contact(), e.temperature(), e.battery_voltage()],
994
+ exposes: [e.battery(), e.contact(), e.device_temperature(), e.battery_voltage()],
991
995
  configure: async (device) => {
992
996
  device.powerSource = 'Battery';
993
997
  device.save();
@@ -1001,7 +1005,7 @@ module.exports = [
1001
1005
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1002
1006
  fromZigbee: [fz.xiaomi_basic, fz.ias_water_leak_alarm_1],
1003
1007
  toZigbee: [],
1004
- exposes: [e.battery(), e.water_leak(), e.battery_low(), e.battery_voltage(), e.temperature(), e.power_outage_count()],
1008
+ exposes: [e.battery(), e.water_leak(), e.battery_low(), e.battery_voltage(), e.device_temperature(), e.power_outage_count()],
1005
1009
  },
1006
1010
  {
1007
1011
  zigbeeModel: ['lumi.flood.agl02'],
@@ -1021,7 +1025,7 @@ module.exports = [
1021
1025
  description: 'Mi/Aqara smart home cube',
1022
1026
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1023
1027
  fromZigbee: [fz.xiaomi_basic, fz.MFKZQ01LM_action_multistate, fz.MFKZQ01LM_action_analog],
1024
- exposes: [e.battery(), e.battery_voltage(), e.angle('action_angle'), e.temperature(), e.power_outage_count(),
1028
+ exposes: [e.battery(), e.battery_voltage(), e.angle('action_angle'), e.device_temperature(), e.power_outage_count(),
1025
1029
  e.cube_side('action_from_side'), e.cube_side('action_side'), e.cube_side('action_to_side'),
1026
1030
  e.action(['shake', 'wakeup', 'fall', 'tap', 'slide', 'flip180', 'flip90', 'rotate_left', 'rotate_right'])],
1027
1031
  toZigbee: [],
@@ -1033,7 +1037,7 @@ module.exports = [
1033
1037
  vendor: 'Xiaomi',
1034
1038
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.xiaomi_basic, fz.ignore_occupancy_report, fz.ignore_illuminance_report],
1035
1039
  toZigbee: [tz.on_off, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_power],
1036
- exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.temperature(), e.power_outage_memory()],
1040
+ exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.device_temperature(), e.power_outage_memory()],
1037
1041
  ota: ota.zigbeeOTA,
1038
1042
  },
1039
1043
  {
@@ -1043,7 +1047,7 @@ module.exports = [
1043
1047
  vendor: 'Xiaomi',
1044
1048
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.xiaomi_basic, fz.ignore_occupancy_report, fz.ignore_illuminance_report],
1045
1049
  toZigbee: [tz.on_off, tz.xiaomi_power],
1046
- exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.temperature().withAccess(ea.STATE),
1050
+ exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.device_temperature().withAccess(ea.STATE),
1047
1051
  e.voltage().withAccess(ea.STATE)],
1048
1052
  },
1049
1053
  {
@@ -1056,7 +1060,7 @@ module.exports = [
1056
1060
  toZigbee: [tz.on_off, tz.xiaomi_power, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_auto_off, tz.xiaomi_led_disabled_night,
1057
1061
  tz.xiaomi_overload_protection],
1058
1062
  exposes: [
1059
- e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.temperature().withAccess(ea.STATE),
1063
+ e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.device_temperature().withAccess(ea.STATE),
1060
1064
  e.voltage().withAccess(ea.STATE), e.current(), e.consumer_connected(), e.led_disabled_night(),
1061
1065
  e.power_outage_memory(), exposes.binary('auto_off', ea.STATE_SET, true, false)
1062
1066
  .withDescription('Turn the device automatically off when attached device consumes less than 2W for 20 minutes'),
@@ -1071,7 +1075,7 @@ module.exports = [
1071
1075
  vendor: 'Xiaomi',
1072
1076
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.xiaomi_basic, fz.ignore_occupancy_report, fz.ignore_illuminance_report],
1073
1077
  toZigbee: [tz.on_off, tz.xiaomi_power],
1074
- exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.temperature().withAccess(ea.STATE),
1078
+ exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.device_temperature().withAccess(ea.STATE),
1075
1079
  e.voltage().withAccess(ea.STATE)],
1076
1080
  },
1077
1081
  {
@@ -1143,7 +1147,7 @@ module.exports = [
1143
1147
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.ignore_occupancy_report, fz.xiaomi_basic],
1144
1148
  toZigbee: [tz.on_off, tz.xiaomi_power, tz.xiaomi_led_disabled_night,
1145
1149
  tz.xiaomi_switch_power_outage_memory, tz.xiaomi_auto_off],
1146
- exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.temperature(), e.voltage().withAccess(ea.STATE),
1150
+ exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.device_temperature(), e.voltage().withAccess(ea.STATE),
1147
1151
  e.power_outage_memory(), e.led_disabled_night(),
1148
1152
  exposes.binary('auto_off', ea.STATE_SET, true, false)
1149
1153
  .withDescription('If the power is constantly lower than 2W within half an hour, ' +
@@ -1169,7 +1173,7 @@ module.exports = [
1169
1173
  vendor: 'Xiaomi',
1170
1174
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.xiaomi_basic],
1171
1175
  toZigbee: [tz.on_off, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_power],
1172
- exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.temperature().withAccess(ea.STATE),
1176
+ exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.device_temperature().withAccess(ea.STATE),
1173
1177
  e.voltage().withAccess(ea.STATE), e.power_outage_memory()],
1174
1178
  ota: ota.zigbeeOTA,
1175
1179
  },
@@ -1255,7 +1259,7 @@ module.exports = [
1255
1259
  'the normal monitoring state, the green indicator light flashes every 60 seconds'),
1256
1260
  exposes.binary('linkage_alarm', ea.ALL, true, false).withDescription('When this option is enabled and a smoke ' +
1257
1261
  'is detected, other detectors with this option enabled will also sound the alarm buzzer'),
1258
- e.temperature(), e.battery()],
1262
+ e.device_temperature(), e.battery(), e.battery_voltage()],
1259
1263
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1260
1264
  configure: async (device, coordinatorEndpoint, logger) => {
1261
1265
  const endpoint = device.getEndpoint(1);
@@ -1286,7 +1290,7 @@ module.exports = [
1286
1290
  fromZigbee: [fz.xiaomi_basic, fz.DJT11LM_vibration],
1287
1291
  toZigbee: [tz.DJT11LM_vibration_sensitivity],
1288
1292
  exposes: [
1289
- e.battery(), e.vibration(), e.action(['vibration', 'tilt', 'drop']),
1293
+ e.battery(), e.device_temperature(), e.vibration(), e.action(['vibration', 'tilt', 'drop']),
1290
1294
  exposes.numeric('strength', ea.STATE), exposes.enum('sensitivity', ea.STATE_SET, ['low', 'medium', 'high']),
1291
1295
  e.angle_axis('angle_x'), e.angle_axis('angle_y'), e.angle_axis('angle_z'), e.battery_voltage(),
1292
1296
  ],
@@ -1362,7 +1366,7 @@ module.exports = [
1362
1366
  await device.getEndpoint(1).read('genAnalogOutput', ['presentValue']);
1363
1367
  }
1364
1368
  },
1365
- exposes: [e.cover_position().setAccess('state', ea.ALL), e.battery().withAccess(ea.STATE_GET), e.temperature(),
1369
+ exposes: [e.cover_position().setAccess('state', ea.ALL), e.battery().withAccess(ea.STATE_GET), e.device_temperature(),
1366
1370
  exposes.binary('charging_status', ea.STATE_GET, true, false)
1367
1371
  .withDescription('The current charging status.'),
1368
1372
  exposes.enum('motor_state', ea.STATE, ['declining', 'rising', 'pause', 'blocked'])
@@ -1388,7 +1392,7 @@ module.exports = [
1388
1392
  endpoint: (device) => {
1389
1393
  return {'l1': 1, 'l2': 2};
1390
1394
  },
1391
- exposes: [e.power().withAccess(ea.STATE_GET), e.energy(), e.temperature(), e.voltage(), e.current(),
1395
+ exposes: [e.power().withAccess(ea.STATE_GET), e.energy(), e.device_temperature(), e.voltage(), e.current(),
1392
1396
  e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'), e.power_outage_count(false),
1393
1397
  e.power_outage_memory(),
1394
1398
  exposes.binary('interlock', ea.STATE_SET, true, false)
@@ -1466,7 +1470,7 @@ module.exports = [
1466
1470
  vendor: 'Xiaomi',
1467
1471
  description: 'Aqara Opple switch 1 band',
1468
1472
  fromZigbee: [fz.aqara_opple_on, fz.aqara_opple_off, fz.battery, fz.aqara_opple_multistate, fz.aqara_opple],
1469
- exposes: [e.battery(), e.action([
1473
+ exposes: [e.battery(), e.battery_voltage(), e.action([
1470
1474
  'button_1_hold', 'button_1_release', 'button_1_single', 'button_1_double', 'button_1_triple',
1471
1475
  'button_2_hold', 'button_2_release', 'button_2_single', 'button_2_double', 'button_2_triple',
1472
1476
  ]), exposes.enum('operation_mode', ea.ALL, ['command', 'event'])
@@ -1486,7 +1490,7 @@ module.exports = [
1486
1490
  description: 'Aqara Opple switch 2 bands',
1487
1491
  fromZigbee: [fz.aqara_opple_on, fz.aqara_opple_off, fz.aqara_opple_step, fz.aqara_opple_step_color_temp, fz.battery,
1488
1492
  fz.aqara_opple_multistate, fz.aqara_opple],
1489
- exposes: [e.battery(), e.action([
1493
+ exposes: [e.battery(), e.battery_voltage(), e.action([
1490
1494
  'button_1_hold', 'button_1_release', 'button_1_single', 'button_1_double', 'button_1_triple',
1491
1495
  'button_2_hold', 'button_2_release', 'button_2_single', 'button_2_double', 'button_2_triple',
1492
1496
  'button_3_hold', 'button_3_release', 'button_3_single', 'button_3_double', 'button_3_triple',
@@ -1510,7 +1514,7 @@ module.exports = [
1510
1514
  description: 'Aqara Opple switch 3 bands',
1511
1515
  fromZigbee: [fz.aqara_opple_on, fz.aqara_opple_off, fz.aqara_opple_step, fz.aqara_opple_move, fz.aqara_opple_stop,
1512
1516
  fz.aqara_opple_step_color_temp, fz.aqara_opple_move_color_temp, fz.battery, fz.aqara_opple_multistate, fz.aqara_opple],
1513
- exposes: [e.battery(), e.action([
1517
+ exposes: [e.battery(), e.battery_voltage(), e.action([
1514
1518
  'button_1_hold', 'button_1_release', 'button_1_single', 'button_1_double', 'button_1_triple',
1515
1519
  'button_2_hold', 'button_2_release', 'button_2_single', 'button_2_double', 'button_2_triple',
1516
1520
  'button_3_hold', 'button_3_release', 'button_3_single', 'button_3_double', 'button_3_triple',
@@ -1568,7 +1572,7 @@ module.exports = [
1568
1572
  fromZigbee: [fz.on_off, fz.device_temperature, fz.aqara_opple, fz.ignore_metering, fz.ignore_electrical_measurement,
1569
1573
  fz.xiaomi_power],
1570
1574
  exposes: [e.switch(), e.energy(), e.power(), e.device_temperature(), e.power_outage_memory(), e.power_outage_count(),
1571
- e.switch_type(), e.voltage(), e.temperature(), e.current(),
1575
+ e.switch_type(), e.voltage(), e.current(),
1572
1576
  ],
1573
1577
  toZigbee: [tz.xiaomi_switch_type, tz.on_off, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_led_disabled_night],
1574
1578
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -1589,7 +1593,7 @@ module.exports = [
1589
1593
  description: 'Aqara single switch module T1 (with neutral)',
1590
1594
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.aqara_opple],
1591
1595
  toZigbee: [tz.on_off, tz.xiaomi_power, tz.xiaomi_switch_type, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_led_disabled_night],
1592
- exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.temperature().withAccess(ea.STATE),
1596
+ exposes: [e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(), e.device_temperature().withAccess(ea.STATE),
1593
1597
  e.voltage().withAccess(ea.STATE), e.power_outage_memory(), e.led_disabled_night(), e.switch_type()],
1594
1598
  configure: async (device, coordinatorEndpoint, logger) => {
1595
1599
  await device.getEndpoint(1).write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
@@ -1602,7 +1606,7 @@ module.exports = [
1602
1606
  vendor: 'Xiaomi',
1603
1607
  description: 'Aqara single switch module T1 (without neutral). Doesn\'t work as a router and doesn\'t support power meter',
1604
1608
  fromZigbee: [fz.on_off, fz.aqara_opple],
1605
- exposes: [e.switch(), e.power_outage_memory(), e.switch_type()],
1609
+ exposes: [e.switch(), e.power_outage_memory(), e.switch_type(), e.power_outage_count(), e.device_temperature()],
1606
1610
  toZigbee: [tz.xiaomi_switch_type, tz.on_off, tz.xiaomi_switch_power_outage_memory],
1607
1611
  configure: async (device, coordinatorEndpoint, logger) => {
1608
1612
  const endpoint = device.getEndpoint(1);
@@ -1727,7 +1731,7 @@ module.exports = [
1727
1731
  toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory,
1728
1732
  tz.aqara_switch_mode_switch, tz.xiaomi_flip_indicator_light],
1729
1733
  exposes: [e.switch(), e.power_outage_memory(), e.action(['single', 'double']),
1730
- e.temperature(), e.flip_indicator_light(),
1734
+ e.device_temperature(), e.flip_indicator_light(),
1731
1735
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
1732
1736
  .withDescription('Decoupled mode for button'),
1733
1737
  exposes.enum('mode_switch', ea.ALL, ['anti_flicker_mode', 'quick_mode'])
@@ -1751,7 +1755,7 @@ module.exports = [
1751
1755
  return {'left': 1, 'right': 2};
1752
1756
  },
1753
1757
  exposes: [
1754
- e.switch().withEndpoint('left'), e.switch().withEndpoint('right'), e.temperature(),
1758
+ e.switch().withEndpoint('left'), e.switch().withEndpoint('right'), e.device_temperature(),
1755
1759
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
1756
1760
  .withDescription('Decoupled mode for left button')
1757
1761
  .withEndpoint('left'),
@@ -1778,7 +1782,7 @@ module.exports = [
1778
1782
  fromZigbee: [fz.xiaomi_tvoc, fz.battery, fz.temperature, fz.humidity],
1779
1783
  toZigbee: [],
1780
1784
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1781
- exposes: [e.battery(), e.temperature(), e.humidity(), e.voc()],
1785
+ exposes: [e.temperature(), e.humidity(), e.voc(), e.battery(), e.battery_voltage()],
1782
1786
  configure: async (device, coordinatorEndpoint, logger) => {
1783
1787
  const endpoint = device.getEndpoint(1);
1784
1788
  const binds = ['msTemperatureMeasurement', 'msRelativeHumidity', 'genPowerCfg', 'genAnalogInput'];
@@ -1812,7 +1816,7 @@ module.exports = [
1812
1816
  .withDescription('Decoupled mode for right button')
1813
1817
  .withEndpoint('right'),
1814
1818
  e.action(['single_left', 'double_left', 'single_right', 'double_right', 'single_both', 'double_both']),
1815
- e.power_outage_memory(), e.temperature(), e.flip_indicator_light(),
1819
+ e.power_outage_memory(), e.device_temperature(), e.flip_indicator_light(),
1816
1820
  ],
1817
1821
  onEvent: preventReset,
1818
1822
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -1828,7 +1832,7 @@ module.exports = [
1828
1832
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.aqara_opple],
1829
1833
  toZigbee: [tz.on_off, tz.xiaomi_switch_power_outage_memory, tz.xiaomi_led_disabled_night,
1830
1834
  tz.xiaomi_overload_protection, tz.xiaomi_socket_button_lock],
1831
- exposes: [e.switch(), e.power().withAccess(ea.STATE), e.energy(), e.temperature().withAccess(ea.STATE),
1835
+ exposes: [e.switch(), e.power().withAccess(ea.STATE), e.energy(), e.device_temperature().withAccess(ea.STATE),
1832
1836
  e.voltage().withAccess(ea.STATE), e.current(), e.consumer_connected().withAccess(ea.STATE),
1833
1837
  e.power_outage_memory(), e.led_disabled_night(), e.button_lock(),
1834
1838
  exposes.numeric('overload_protection', exposes.access.ALL).withValueMin(100).withValueMax(2500).withUnit('W')
@@ -1843,7 +1847,7 @@ module.exports = [
1843
1847
  fromZigbee: [fz.on_off, fz.xiaomi_multistate_action, fz.aqara_opple],
1844
1848
  toZigbee: [tz.on_off, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory,
1845
1849
  tz.xiaomi_flip_indicator_light],
1846
- exposes: [e.switch(), e.action(['single', 'double']), e.power_outage_memory(), e.temperature(), e.flip_indicator_light(),
1850
+ exposes: [e.switch(), e.action(['single', 'double']), e.power_outage_memory(), e.device_temperature(), e.flip_indicator_light(),
1847
1851
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']).withDescription('Decoupled mode')],
1848
1852
  onEvent: preventReset,
1849
1853
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -1896,7 +1900,7 @@ module.exports = [
1896
1900
  },
1897
1901
  exposes: [
1898
1902
  e.switch().withEndpoint('relay'), e.switch().withEndpoint('usb'),
1899
- e.power().withAccess(ea.STATE), e.energy(), e.temperature().withAccess(ea.STATE), e.voltage().withAccess(ea.STATE),
1903
+ e.power().withAccess(ea.STATE), e.energy(), e.device_temperature().withAccess(ea.STATE), e.voltage().withAccess(ea.STATE),
1900
1904
  e.current(), e.power_outage_memory(), e.led_disabled_night(), e.button_lock(),
1901
1905
  exposes.enum('button_switch_mode', exposes.access.ALL, ['relay', 'relay_and_usb'])
1902
1906
  .withDescription('Control both relay and usb or only the relay with the physical switch button'),
@@ -1924,7 +1928,7 @@ module.exports = [
1924
1928
  tz.xiaomi_overload_protection, tz.xiaomi_socket_button_lock],
1925
1929
  exposes: [
1926
1930
  e.switch(), e.power().withAccess(ea.STATE), e.energy(),
1927
- e.temperature().withAccess(ea.STATE), e.voltage().withAccess(ea.STATE),
1931
+ e.device_temperature().withAccess(ea.STATE), e.voltage().withAccess(ea.STATE),
1928
1932
  e.current(), e.power_outage_memory(), e.led_disabled_night(), e.button_lock(),
1929
1933
  exposes.numeric('overload_protection', exposes.access.ALL).withValueMin(100).withValueMax(2500).withUnit('W')
1930
1934
  .withDescription('Maximum allowed load, turns off if exceeded')],
@@ -2002,6 +2006,7 @@ module.exports = [
2002
2006
  'multi: supports more events like double and hold'),
2003
2007
  exposes.enum('operation_mode', ea.ALL, ['command', 'event'])
2004
2008
  .withDescription('Operation mode, select "command" to enable bindings (wake up the device before changing modes!)')],
2009
+ meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
2005
2010
  configure: async (device, coordinatorEndpoint, logger) => {
2006
2011
  const endpoint1 = device.getEndpoint(1);
2007
2012
  await endpoint1.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
@@ -70,6 +70,8 @@ module.exports = [
70
70
  whiteLabel: [{vendor: 'BSEED', model: 'TS0003', description: 'Zigbee switch'}],
71
71
  meta: {multiEndpoint: true, disableDefaultResponse: true},
72
72
  configure: async (device, coordinatorEndpoint, logger) => {
73
+ await device.getEndpoint(1).read('genBasic',
74
+ ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
73
75
  await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
74
76
  await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
75
77
  await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']);
package/lib/legacy.js CHANGED
@@ -2107,7 +2107,7 @@ const fromZigbee = {
2107
2107
  hue_dimmer_switch: {
2108
2108
  cluster: 'manuSpecificPhilips',
2109
2109
  type: 'commandHueNotification',
2110
- options: [exposes.options.legacy()],
2110
+ options: [exposes.options.legacy(), exposes.options.simulated_brightness('Only works when legacy is false.')],
2111
2111
  convert: (model, msg, publish, options, meta) => {
2112
2112
  if (!isLegacyEnabled(options)) {
2113
2113
  return fromZigbeeConverters.hue_dimmer_switch.convert(model, msg, publish, options, meta);
package/lib/xiaomi.js CHANGED
@@ -158,10 +158,11 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
158
158
  }
159
159
  break;
160
160
  case '3':
161
- if (['WSDCGQ12LM'].includes(model.model)) {
162
- // This temperature value is ignored because with greater accuracy it is reported in key №100
163
- } else if (!['WXCJKG11LM', 'WXCJKG12LM', 'WXCJKG13LM'].includes(model.model)) {
164
- payload.temperature = calibrateAndPrecisionRoundOptions(value, options, 'temperature'); // 0x03
161
+ if (['WXCJKG11LM', 'WXCJKG12LM', 'WXCJKG13LM'].includes(model.model)) {
162
+ // The temperature value is constant 25 °C and does not change, so we ignore it
163
+ // https://github.com/Koenkk/zigbee2mqtt/issues/11126
164
+ } else {
165
+ payload.device_temperature = calibrateAndPrecisionRoundOptions(value, options, 'device_temperature'); // 0x03
165
166
  }
166
167
  break;
167
168
  case '4':
@@ -202,7 +203,7 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
202
203
  payload[`state_${mapping}`] = value === 1 ? 'ON' : 'OFF';
203
204
  } else if (['WXKG14LM', 'WXKG16LM', 'WXKG17LM'].includes(model.model)) {
204
205
  payload.click_mode = {1: 'fast', 2: 'multi'}[value];
205
- } else if (['WXCJKG11LM', 'WXCJKG12LM', 'WXCJKG13LM', 'ZNMS12LM'].includes(model.model)) {
206
+ } else if (['WXCJKG11LM', 'WXCJKG12LM', 'WXCJKG13LM', 'ZNMS12LM', 'RTCGQ14LM'].includes(model.model)) {
206
207
  // We don't know what the value means for these devices.
207
208
  // https://github.com/Koenkk/zigbee2mqtt/issues/11126
208
209
  // https://github.com/Koenkk/zigbee2mqtt/issues/12279
@@ -297,6 +298,11 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
297
298
  payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[value];
298
299
  }
299
300
  break;
301
+ case '107':
302
+ if (['RTCGQ14LM'].includes(model.model)) {
303
+ payload.trigger_indicator = value === 1;
304
+ }
305
+ break;
300
306
  case '149':
301
307
  payload.energy = precisionRound(value, 2); // 0x95
302
308
  // Consumption is deprecated
@@ -383,7 +389,7 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
383
389
  payload.detection_interval = value;
384
390
  break;
385
391
  case '268':
386
- if (['RTCGQ13LM', 'RTCZCGQ11LM'].includes(model.model)) {
392
+ if (['RTCGQ13LM', 'RTCGQ14LM', 'RTCZCGQ11LM'].includes(model.model)) {
387
393
  payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[value];
388
394
  } else if (['JT-BZ-01AQ/A'].includes(model.model)) {
389
395
  payload.gas_sensitivity = {1: '15%LEL', 2: '10%LEL'}[value];
@@ -454,6 +460,11 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
454
460
  payload.linkage_alarm = value === 1;
455
461
  }
456
462
  break;
463
+ case '338':
464
+ if (['RTCGQ14LM'].includes(model.model)) {
465
+ payload.trigger_indicator = value === 1;
466
+ }
467
+ break;
457
468
  case '512':
458
469
  if (['ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM'].includes(model.model)) {
459
470
  payload.button_lock = value === 1 ? 'OFF' : 'ON';
@@ -530,6 +541,9 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
530
541
  case 'modelId':
531
542
  // We ignore it, but we add it here to not shown an unknown key in the log
532
543
  break;
544
+ case 'illuminance':
545
+ // It contains the illuminance and occupancy, but in z2m we use a custom timer to do it, so we ignore it
546
+ break;
533
547
  default:
534
548
  if (meta.logger) meta.logger.debug(`${model.zigbeeModel}: unknown key ${key} with value ${value}`);
535
549
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.520",
3
+ "version": "14.0.523",
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.30"
41
+ "zigbee-herdsman": "^0.14.32"
42
42
  },
43
43
  "devDependencies": {
44
44
  "eslint": "*",