zigbee-herdsman-converters 14.0.559 → 14.0.562

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.
@@ -1946,7 +1946,9 @@ const converters = {
1946
1946
  case 1:
1947
1947
  return {temperature: calibrateAndPrecisionRoundOptions(value / 10, options, 'temperature')};
1948
1948
  case 2:
1949
- return {humidity: calibrateAndPrecisionRoundOptions(value, options, 'humidity')};
1949
+ return {humidity: calibrateAndPrecisionRoundOptions(
1950
+ (value / (meta.device.manufacturerName === '_TZE200_bjawzodf' ? 10 : 1)),
1951
+ options, 'humidity')};
1950
1952
  case 4:
1951
1953
  return {battery: value};
1952
1954
  default:
@@ -3236,7 +3238,7 @@ const converters = {
3236
3238
  };
3237
3239
 
3238
3240
  let nameAlt = '';
3239
- if (unit === 'A') {
3241
+ if (unit === 'A' || unit === 'pf') {
3240
3242
  if (valRaw < 1) {
3241
3243
  val = precisionRound(valRaw, 3);
3242
3244
  }
@@ -2300,7 +2300,8 @@ const converters = {
2300
2300
  key: ['led_disabled_night'],
2301
2301
  convertSet: async (entity, key, value, meta) => {
2302
2302
  if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
2303
- 'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM', 'SSM-U01', 'WS-EUK01', 'WS-EUK02'].includes(meta.mapped.model)) {
2303
+ 'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM', 'SSM-U01', 'WS-EUK01', 'WS-EUK02',
2304
+ 'WS-EUK03', 'WS-EUK04'].includes(meta.mapped.model)) {
2304
2305
  await entity.write('aqaraOpple', {0x0203: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
2305
2306
  } else if (['ZNCZ11LM'].includes(meta.mapped.model)) {
2306
2307
  const payload = value ?
@@ -2315,7 +2316,8 @@ const converters = {
2315
2316
  },
2316
2317
  convertGet: async (entity, key, meta) => {
2317
2318
  if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ15LM', 'QBCZ14LM', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
2318
- 'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM', 'SSM-U01', 'WS-EUK01', 'WS-EUK02'].includes(meta.mapped.model)) {
2319
+ 'QBKG31LM', 'QBKG34LM', 'DLKZMK11LM', 'SSM-U01', 'WS-EUK01', 'WS-EUK02',
2320
+ 'WS-EUK03', 'WS-EUK04'].includes(meta.mapped.model)) {
2319
2321
  await entity.read('aqaraOpple', [0x0203], manufacturerOptions.xiaomi);
2320
2322
  } else {
2321
2323
  throw new Error('Not supported');
package/devices/acova.js CHANGED
@@ -63,4 +63,34 @@ module.exports = [
63
63
  await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
64
64
  },
65
65
  },
66
+ {
67
+ zigbeeModel: ['TAFFETAS2 D1.00P1.02Z1.00'],
68
+ model: 'TAFFETAS2',
69
+ vendor: 'Acova',
70
+ description: 'Taffetas 2 heater',
71
+ fromZigbee: [fz.thermostat, fz.hvac_user_interface],
72
+ toZigbee: [
73
+ tz.thermostat_local_temperature,
74
+ tz.thermostat_system_mode,
75
+ tz.thermostat_occupied_heating_setpoint,
76
+ tz.thermostat_unoccupied_heating_setpoint,
77
+ tz.thermostat_occupied_cooling_setpoint,
78
+ tz.thermostat_running_state,
79
+ ],
80
+ exposes: [
81
+ exposes.climate()
82
+ .withSetpoint('occupied_heating_setpoint', 7, 28, 0.5)
83
+ .withLocalTemperature()
84
+ .withSystemMode(['off', 'heat', 'auto'])
85
+ .withRunningState(['idle', 'heat']),
86
+ ],
87
+ configure: async (device, coordinatorEndpoint, logger) => {
88
+ const endpoint = device.getEndpoint(1);
89
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat']);
90
+ await reporting.thermostatTemperature(endpoint);
91
+ await reporting.thermostatRunningState(endpoint);
92
+ await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
93
+ await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
94
+ },
95
+ },
66
96
  ];
package/devices/adeo.js CHANGED
@@ -112,14 +112,28 @@ module.exports = [
112
112
  zigbeeModel: ['LXEK-2'],
113
113
  model: '9CZA-G1521-Q1A',
114
114
  vendor: 'ADEO',
115
- description: 'ENKI Lexman E27 14W to 100W LED RGBW',
115
+ description: 'ENKI LEXMAN E27 14W to 100W LED RGBW',
116
116
  extend: extend.light_onoff_brightness_colortemp_color(),
117
117
  },
118
+ {
119
+ zigbeeModel: ['LDSENK07'],
120
+ model: 'LDSENK07',
121
+ vendor: 'ADEO',
122
+ description: 'ENKI LEXMAN wireless smart outdoor siren',
123
+ fromZigbee: [fz.battery, fz.ias_siren],
124
+ toZigbee: [tz.warning],
125
+ exposes: [e.warning(), e.battery(), e.battery_low(), e.tamper()],
126
+ configure: async (device, coordinatorEndpoint, logger) => {
127
+ device.defaultSendRequestWhen = 'immediate';
128
+ device.save();
129
+ await device.getEndpoint(1).unbind('genPollCtrl', coordinatorEndpoint);
130
+ },
131
+ },
118
132
  {
119
133
  zigbeeModel: ['ZBEK-2'],
120
134
  model: 'IG-CDZOTAAG014RA-MAN',
121
135
  vendor: 'ADEO',
122
- description: 'ENKI Lexman E27 14W to 100W LED RGBW v2',
136
+ description: 'ENKI LEXMAN E27 14W to 100W LED RGBW v2',
123
137
  extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370]}),
124
138
  },
125
139
  {
@@ -133,7 +147,7 @@ module.exports = [
133
147
  zigbeeModel: ['LXEK-7'],
134
148
  model: '9CZA-A806ST-Q1Z',
135
149
  vendor: 'ADEO',
136
- description: 'ENKI Lexman E27 LED white',
150
+ description: 'ENKI LEXMAN E27 LED white',
137
151
  extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
138
152
  },
139
153
  {
@@ -157,7 +171,7 @@ module.exports = [
157
171
  zigbeeModel: ['LDSENK10'],
158
172
  model: 'LDSENK10',
159
173
  vendor: 'ADEO',
160
- description: 'LEXMAN motion sensor',
174
+ description: 'ENKI LEXMAN motion sensor',
161
175
  fromZigbee: [fz.ias_occupancy_alarm_1],
162
176
  toZigbee: [],
163
177
  exposes: [e.occupancy(), e.battery_low(), e.tamper()],
@@ -26,7 +26,7 @@ module.exports = [
26
26
  },
27
27
  {
28
28
  zigbeeModel: [' Dimmer switch with neutral\u0000\u0000\u0000\u0000'],
29
- model: 'L441C/N4411C/NT4411C',
29
+ model: 'L4411C/N4411C/NT4411C',
30
30
  vendor: 'BTicino',
31
31
  description: 'Dimmer switch with neutral',
32
32
  extend: extend.light_onoff_brightness({noConfigure: true}),
@@ -5,6 +5,13 @@ const e = exposes.presets;
5
5
  const fz = require('../converters/fromZigbee');
6
6
 
7
7
  module.exports = [
8
+ {
9
+ zigbeeModel: ['ZG_LED_DRIVER42CC'],
10
+ model: 'ZG_LED_DRIVER42CC',
11
+ vendor: 'ENVILAR',
12
+ description: 'Zigbee LED driver',
13
+ extend: extend.light_onoff_brightness(),
14
+ },
8
15
  {
9
16
  zigbeeModel: ['ZG50CC-CCT-DRIVER'],
10
17
  model: 'ZG50CC-CCT-DRIVER',
package/devices/insta.js CHANGED
@@ -53,7 +53,7 @@ module.exports = [
53
53
  {ID: 242, profileID: 41440, deviceID: 97},
54
54
  ]},
55
55
  ],
56
- zigbeeModel: ['57005000'],
56
+ zigbeeModel: ['NEXENTRO Switching Actuator', '57005000'],
57
57
  model: '57005000',
58
58
  vendor: 'Insta',
59
59
  description: 'Switching Actuator Mini with input for wall switch',
package/devices/lidl.js CHANGED
@@ -857,4 +857,12 @@ module.exports = [
857
857
  }),
858
858
  ],
859
859
  },
860
+ {
861
+ fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3000_taspddvq'}],
862
+ model: 'HG08383A',
863
+ vendor: 'Lidl',
864
+ description: 'Livarno outdoor LED light chain',
865
+ extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500], disableColorTempStartup: true}),
866
+ meta: {applyRedFix: true, enhancedHue: false},
867
+ },
860
868
  ];
@@ -3,9 +3,47 @@ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/lega
3
3
  const tz = require('../converters/toZigbee');
4
4
  const reporting = require('../lib/reporting');
5
5
  const extend = require('../lib/extend');
6
+ const utils = require('../lib/utils');
6
7
  const e = exposes.presets;
7
8
  const ea = exposes.access;
8
9
 
10
+ const fzLocal = {
11
+ TS110E_switch_type: {
12
+ cluster: 'genLevelCtrl',
13
+ type: ['attributeReport', 'readResponse'],
14
+ convert: (model, msg, publish, options, meta) => {
15
+ const property = 0xfc02;
16
+ if (msg.data.hasOwnProperty(property)) {
17
+ const value = msg.data[property];
18
+ const lookup = {0: 'momentary', 1: 'toggle', 2: 'state'};
19
+ if (lookup.hasOwnProperty(value)) {
20
+ const propertyName = utils.postfixWithEndpointName('switch_type', msg, model);
21
+ return {[propertyName]: lookup[value]};
22
+ }
23
+ }
24
+ },
25
+ },
26
+ };
27
+
28
+ const tzLocal = {
29
+ TS110E_switch_type: {
30
+ key: ['switch_type'],
31
+ convertSet: async (entity, key, value, meta) => {
32
+ value = value.toLowerCase();
33
+ const lookup = {'momentary': 0, 'toggle': 1, 'state': 2};
34
+
35
+ utils.validateValue(value, Object.keys(lookup));
36
+ const payload = lookup[value];
37
+
38
+ await entity.write('genLevelCtrl', {0xfc02: {value: payload, type: 0x20}});
39
+ return {state: {switch_type: value}};
40
+ },
41
+ convertGet: async (entity, key, meta) => {
42
+ await entity.read('genLevelCtrl', [0xfc02]);
43
+ },
44
+ },
45
+ };
46
+
9
47
  module.exports = [
10
48
  {
11
49
  fingerprint: [{modelID: 'TS130F', manufacturerName: '_TZ3000_vd43bbfq'}, {modelID: 'TS130F', manufacturerName: '_TZ3000_fccpjz5z'}],
@@ -221,9 +259,19 @@ module.exports = [
221
259
  model: 'TS110E_2gang',
222
260
  vendor: 'Lonsonho',
223
261
  description: 'Zigbee smart dimmer module 2 gang with neutral',
224
- extend: extend.light_onoff_brightness({noConfigure: true}),
262
+ fromZigbee: extend.light_onoff_brightness({disablePowerOnBehavior: true}).fromZigbee.concat([
263
+ fz.tuya_switch_power_outage_memory, fzLocal.TS110E_switch_type]),
264
+ toZigbee: extend.light_onoff_brightness({disablePowerOnBehavior: true}).toZigbee.concat([
265
+ tz.tuya_switch_power_outage_memory, tzLocal.TS110E_switch_type]),
225
266
  meta: {multiEndpoint: true},
226
- exposes: [e.light_brightness().withEndpoint('l1'), e.light_brightness().withEndpoint('l2')],
267
+ exposes: [
268
+ e.light_brightness().withEndpoint('l1'),
269
+ e.light_brightness().withEndpoint('l2'),
270
+ exposes.enum('power_outage_memory', ea.STATE_SET, ['on', 'off', 'restore']).withDescription('Recover state after power outage')
271
+ .withEndpoint('l1'),
272
+ exposes.presets.switch_type_2().withEndpoint('l1'),
273
+ exposes.presets.switch_type_2().withEndpoint('l2'),
274
+ ],
227
275
  configure: async (device, coordinatorEndpoint, logger) => {
228
276
  await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
229
277
  await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
package/devices/neo.js CHANGED
@@ -35,7 +35,7 @@ module.exports = [
35
35
  },
36
36
  },
37
37
  {
38
- fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_t1blo2bj'}, {modelID: 'TS0202', manufacturerName: '_TZ3000_kmh5qpmb'}],
38
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_t1blo2bj'}],
39
39
  zigbeeModel: ['1blo2bj'],
40
40
  model: 'NAS-AB02B2',
41
41
  vendor: 'Neo',
@@ -58,7 +58,7 @@ module.exports = [
58
58
  },
59
59
  },
60
60
  {
61
- fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_7hfcudw5'}],
61
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_7hfcudw5'}, {modelID: 'TS0202', manufacturerName: '_TZ3000_kmh5qpmb'}],
62
62
  model: 'NAS-PD07',
63
63
  vendor: 'Neo',
64
64
  description: 'Motion, temperature & humidity sensor',
package/devices/nous.js CHANGED
@@ -17,7 +17,9 @@ module.exports = [
17
17
  exposes: [e.temperature(), e.humidity(), e.battery()],
18
18
  },
19
19
  {
20
- fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_lve3dvpy'}, {modelID: 'TS0601', manufacturerName: '_TZE200_c7emyjom'}],
20
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_lve3dvpy'},
21
+ {modelID: 'TS0601', manufacturerName: '_TZE200_c7emyjom'},
22
+ {modelID: 'TS0601', manufacturerName: '_TZE200_locansqn'}],
21
23
  model: 'SZ-T04',
22
24
  vendor: 'Nous',
23
25
  description: 'Temperature and humidity sensor with clock',
package/devices/nue_3a.js CHANGED
@@ -4,6 +4,32 @@ const tz = require('../converters/toZigbee');
4
4
  const reporting = require('../lib/reporting');
5
5
  const extend = require('../lib/extend');
6
6
  const e = exposes.presets;
7
+ const ea = exposes.access;
8
+
9
+ const fzLocal = {
10
+ LXN59_cover_options: {
11
+ cluster: 'closuresWindowCovering',
12
+ type: ['attributeReport', 'readResponse'],
13
+ convert: (model, msg, publish, options, meta) => {
14
+ const result = {};
15
+ if (msg.data.hasOwnProperty('tuyaMovingState')) {
16
+ const value = msg.data['tuyaMovingState'];
17
+ const movingLookup = {0: 'DOWN', 1: 'UP', 2: 'STOP'};
18
+ result.moving = movingLookup[value];
19
+ }
20
+ return result;
21
+ },
22
+ },
23
+ LXN59_cover_state_via_onoff: {
24
+ cluster: 'genOnOff',
25
+ type: ['attributeReport', 'readResponse'],
26
+ convert: (model, msg, publish, options, meta) => {
27
+ if (msg.data.hasOwnProperty('onOff')) {
28
+ return {state: msg.data['onOff'] === 1 ? 'CLOSE' : 'OPEN'};
29
+ }
30
+ },
31
+ },
32
+ };
7
33
 
8
34
  module.exports = [
9
35
  {
@@ -247,6 +273,40 @@ module.exports = [
247
273
  description: 'Smart 7W E27 light bulb',
248
274
  extend: extend.light_onoff_brightness_colortemp_color(),
249
275
  },
276
+ {
277
+ zigbeeModel: ['LXN59-CS27LX1.0'],
278
+ model: 'ZW-EU-4C',
279
+ vendor: 'Nue / 3A',
280
+ description: 'Zigbee smart curtain switch',
281
+ fromZigbee: [fz.cover_position_tilt, fzLocal.LXN59_cover_state_via_onoff, fzLocal.LXN59_cover_options],
282
+ toZigbee: [tz.cover_state, tz.cover_position_tilt],
283
+ meta: {disableDefaultResponse: true},
284
+ exposes: [e.cover_position(), exposes.enum('moving', ea.STATE, ['UP', 'STOP', 'DOWN'])],
285
+ configure: async (device, coordinatorEndpoint, logger) => {
286
+ const endpoint1 = device.getEndpoint(1);
287
+ await reporting.bind(endpoint1, coordinatorEndpoint, ['genOnOff']);
288
+ await reporting.onOff(endpoint1);
289
+ await reporting.bind(endpoint1, coordinatorEndpoint, ['closuresWindowCovering']);
290
+ await reporting.currentPositionLiftPercentage(endpoint1);
291
+ device.powerSource = 'Mains (single phase)';
292
+ device.save();
293
+ },
294
+ },
295
+ {
296
+ zigbeeModel: ['LXX60-CS27LX1.0'],
297
+ model: 'ZW-EC-01',
298
+ vendor: 'Nue / 3A',
299
+ description: 'Zigbee smart curtain switch',
300
+ extend: extend.switch(),
301
+ configure: async (device, coordinatorEndpoint, logger) => {
302
+ const endpoint1 = device.getEndpoint(1);
303
+ await reporting.bind(endpoint1, coordinatorEndpoint, ['genOnOff']);
304
+ await reporting.bind(endpoint1, coordinatorEndpoint, ['closuresWindowCovering']);
305
+ await reporting.onOff(endpoint1);
306
+ device.powerSource = 'Mains (single phase)';
307
+ device.save();
308
+ },
309
+ },
250
310
  {
251
311
  zigbeeModel: ['LXN56-0S27LX1.1', 'LXN56-0S27LX1.3'],
252
312
  model: 'HGZB-20-UK',
@@ -2111,7 +2111,7 @@ module.exports = [
2111
2111
  extend: hueExtend.light_onoff_brightness_colortemp(),
2112
2112
  },
2113
2113
  {
2114
- zigbeeModel: ['929003047101'],
2114
+ zigbeeModel: ['929003047101', '929003045101_03'],
2115
2115
  model: '929003047101',
2116
2116
  vendor: 'Philips',
2117
2117
  description: 'Hue White ambiance Milliskin (round)',
@@ -2,8 +2,97 @@ const exposes = require('../lib/exposes');
2
2
  const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
3
3
  const tz = require('../converters/toZigbee');
4
4
  const reporting = require('../lib/reporting');
5
+ const utils = require('../lib/utils');
5
6
  const e = exposes.presets;
6
7
  const ea = exposes.access;
8
+ const herdsman = require('zigbee-herdsman');
9
+
10
+ const manufacturerOptions = {manufacturerCode: herdsman.Zcl.ManufacturerCode.PLUGWISE_BV};
11
+
12
+ const plugwisePushForce = {
13
+ 0: 'standard',
14
+ 0x60000: 'high',
15
+ 0x70000: 'very_high',
16
+ };
17
+
18
+ const plugwiseRadioStrength = {
19
+ 0: 'normal',
20
+ 1: 'high',
21
+ };
22
+
23
+ const fzLocal = {
24
+ plugwise_radiator_valve: {
25
+ cluster: 'hvacThermostat',
26
+ type: ['attributeReport', 'readResponse'],
27
+ convert: (model, msg, publish, options, meta) => {
28
+ const result = fz.thermostat.convert(model, msg, publish, options, meta);
29
+
30
+ // Reports pIHeatingDemand between 0 and 100 already
31
+ if (typeof msg.data['pIHeatingDemand'] == 'number') {
32
+ result.pi_heating_demand = utils.precisionRound(msg.data['pIHeatingDemand'], 0);
33
+ }
34
+
35
+ if (typeof msg.data[0x4003] == 'number') {
36
+ result.current_heating_setpoint = utils.precisionRound(msg.data[0x4003], 2) / 100;
37
+ }
38
+ if (typeof msg.data[0x4008] == 'number') {
39
+ result.plugwise_t_diff = msg.data[0x4008];
40
+ }
41
+ if (typeof msg.data[0x4002] == 'number') {
42
+ result.error_status = msg.data[0x4002];
43
+ }
44
+ if (typeof msg.data[0x4001] == 'number') {
45
+ result.valve_position = msg.data[0x4001];
46
+ }
47
+ return result;
48
+ },
49
+ },
50
+ };
51
+
52
+ const tzLocal = {
53
+ plugwise_calibrate_valve: {
54
+ key: ['calibrate_valve'],
55
+ convertSet: async (entity, key, value, meta) => {
56
+ await entity.command('hvacThermostat', 'plugwiseCalibrateValve', {},
57
+ {srcEndpoint: 11, disableDefaultResponse: true, sendWhen: 'active'});
58
+ return {state: {'calibrate_valve': value}};
59
+ },
60
+ },
61
+ plugwise_valve_position: {
62
+ key: ['plugwise_valve_position', 'valve_position'],
63
+ convertSet: async (entity, key, value, meta) => {
64
+ const payload = {0x4001: {value, type: 0x20}};
65
+ await entity.write('hvacThermostat', payload, manufacturerOptions);
66
+ // Tom does not automatically send back updated value so ask for it
67
+ await entity.read('hvacThermostat', [0x4001], manufacturerOptions);
68
+ },
69
+ convertGet: async (entity, key, meta) => {
70
+ await entity.read('hvacThermostat', [0x4001], manufacturerOptions);
71
+ },
72
+ },
73
+ plugwise_push_force: {
74
+ key: ['plugwise_push_force', 'force'],
75
+ convertSet: async (entity, key, value, meta) => {
76
+ const val = utils.getKey(plugwisePushForce, value, value, Number);
77
+ const payload = {0x4012: {value: val, type: 0x23}};
78
+ await entity.write('hvacThermostat', payload, manufacturerOptions);
79
+ },
80
+ convertGet: async (entity, key, meta) => {
81
+ await entity.read('hvacThermostat', [0x4012], manufacturerOptions);
82
+ },
83
+ },
84
+ plugwise_radio_strength: {
85
+ key: ['plugwise_radio_strength', 'radio_strength'],
86
+ convertSet: async (entity, key, value, meta) => {
87
+ const val = utils.getKey(plugwiseRadioStrength, value, value, Number);
88
+ const payload = {0x4014: {value: val, type: 0x10}};
89
+ await entity.write('hvacThermostat', payload, manufacturerOptions);
90
+ },
91
+ convertGet: async (entity, key, meta) => {
92
+ await entity.read('hvacThermostat', [0x4014], manufacturerOptions);
93
+ },
94
+ },
95
+ };
7
96
 
8
97
  module.exports = [
9
98
  {
@@ -27,18 +116,37 @@ module.exports = [
27
116
  model: '106-03',
28
117
  vendor: 'Plugwise',
29
118
  description: 'Tom thermostatic radiator valve',
30
- fromZigbee: [fz.thermostat, fz.temperature, fz.battery],
31
- toZigbee: [tz.thermostat_system_mode, tz.thermostat_occupied_heating_setpoint, tz.thermostat_pi_heating_demand],
119
+ fromZigbee: [fz.thermostat, fz.temperature, fz.battery, fzLocal.plugwise_radiator_valve],
120
+ toZigbee: [
121
+ tz.thermostat_system_mode,
122
+ tz.thermostat_occupied_heating_setpoint,
123
+ tz.thermostat_pi_heating_demand,
124
+ tzLocal.plugwise_valve_position,
125
+ tzLocal.plugwise_push_force,
126
+ tzLocal.plugwise_radio_strength,
127
+ tzLocal.plugwise_calibrate_valve,
128
+ ],
32
129
  configure: async (device, coordinatorEndpoint, logger) => {
33
130
  const endpoint = device.getEndpoint(1);
34
131
  await reporting.bind(endpoint, coordinatorEndpoint, ['genBasic', 'genPowerCfg', 'hvacThermostat']);
35
132
  await reporting.batteryPercentageRemaining(endpoint);
133
+ await reporting.thermostatTemperature(endpoint);
134
+ await reporting.thermostatPIHeatingDemand(endpoint);
36
135
  },
37
136
  exposes: [e.battery(),
38
137
  exposes.climate()
39
138
  .withSetpoint('occupied_heating_setpoint', 5, 30, 0.5, ea.ALL).withLocalTemperature(ea.STATE)
40
139
  .withSystemMode(['off', 'auto'], ea.ALL)
41
140
  .withPiHeatingDemand(ea.STATE_GET),
141
+ exposes.numeric('valve_position', ea.ALL).withValueMin(0).withValueMax(100)
142
+ .withDescription('Directly control the radiator valve. The values range from 0 (valve ' +
143
+ 'closed) to 100 (valve fully open)'),
144
+ exposes.enum('force', ea.ALL, ['standard', 'high', 'very_high'])
145
+ .withDescription('How hard the motor pushes the valve. The closer to the boiler, the higher the force needed'),
146
+ exposes.enum('radio_strength', ea.ALL, ['normal', 'high'])
147
+ .withDescription('Transmits with higher power when range is not sufficient'),
148
+ exposes.binary('calibrate_valve', ea.STATE_SET, 'calibrate', 'idle')
149
+ .withDescription('Calibrates valve on next wakeup'),
42
150
  ],
43
151
  },
44
152
  ];
@@ -357,6 +357,18 @@ module.exports = [
357
357
  await reporting.onOff(endpoint);
358
358
  },
359
359
  },
360
+ {
361
+ zigbeeModel: ['CH10AX/SWITCH/1'],
362
+ model: '41E10PBSWMZ-VW',
363
+ vendor: 'Schneider Electric',
364
+ description: 'Wiser 40/300-Series module switch 10A with ControlLink',
365
+ extend: extend.switch(),
366
+ configure: async (device, coordinatorEndpoint, logger) => {
367
+ const endpoint = device.getEndpoint(1);
368
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
369
+ await reporting.onOff(endpoint);
370
+ },
371
+ },
360
372
  {
361
373
  zigbeeModel: ['SMARTPLUG/1'],
362
374
  model: 'CCT711119',
@@ -121,4 +121,17 @@ module.exports = [
121
121
  },
122
122
  exposes: [e.cover_position(), e.battery()],
123
123
  },
124
+ {
125
+ zigbeeModel: ['3RSB22BZ'],
126
+ model: '3RSB22BZ',
127
+ vendor: 'Third Reality',
128
+ description: 'Smart button',
129
+ fromZigbee: [fz.battery, fz.itcmdr_clicks],
130
+ toZigbee: [],
131
+ exposes: [e.battery(), e.battery_low(), e.battery_voltage(), e.action(['single', 'double', 'long'])],
132
+ configure: async (device, coordinatorEndpoint, logger) => {
133
+ device.powerSource = 'Battery';
134
+ device.save();
135
+ },
136
+ },
124
137
  ];
package/devices/tuya.js CHANGED
@@ -338,7 +338,9 @@ module.exports = [
338
338
  },
339
339
  {
340
340
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_8ygsuhe1'},
341
- {modelID: 'TS0601', manufacturerName: '_TZE200_yvx5lh6k'}, {modelID: 'TS0601', manufacturerName: '_TZE200_ryfmq5rl'}],
341
+ {modelID: 'TS0601', manufacturerName: '_TZE200_yvx5lh6k'},
342
+ {modelID: 'TS0601', manufacturerName: '_TZE200_ryfmq5rl'},
343
+ {modelID: 'TS0601', manufacturerName: '_TZE200_c2fmom5z'}],
342
344
  model: 'TS0601_air_quality_sensor',
343
345
  vendor: 'TuYa',
344
346
  description: 'Air quality sensor',
package/devices/ubisys.js CHANGED
@@ -640,7 +640,8 @@ module.exports = [
640
640
  fz.command_move, fz.command_stop, fz.lighting_ballast_configuration, fz.level_config, ubisys.fz.dimmer_setup,
641
641
  ubisys.fz.dimmer_setup_genLevelCtrl],
642
642
  toZigbee: [tz.light_onoff_brightness, tz.ballast_config, tz.level_config, ubisys.tz.dimmer_setup,
643
- ubisys.tz.dimmer_setup_genLevelCtrl, ubisys.tz.configure_device_setup, tz.ignore_transition],
643
+ ubisys.tz.dimmer_setup_genLevelCtrl, ubisys.tz.configure_device_setup, tz.ignore_transition, tz.light_brightness_move,
644
+ tz.light_brightness_step],
644
645
  exposes: [e.light_brightness().withLevelConfig(), e.power(),
645
646
  exposes.numeric('ballast_physical_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
646
647
  .withDescription('Specifies the minimum light output the ballast can achieve.'),
package/devices/weiser.js CHANGED
@@ -40,14 +40,28 @@ module.exports = [
40
40
  model: '9GED21500-005',
41
41
  vendor: 'Weiser',
42
42
  description: 'SmartCode 10 Touch',
43
- fromZigbee: [fz.lock, fz.lock_operation_event, fz.battery],
44
- toZigbee: [tz.lock],
43
+ fromZigbee: [fz.lock, fz.lock_operation_event, fz.battery, fz.lock_programming_event, fz.lock_pin_code_response],
44
+ toZigbee: [tz.lock, tz.pincode_lock],
45
+ meta: {pinCodeCount: 30},
45
46
  configure: async (device, coordinatorEndpoint, logger) => {
46
47
  const endpoint = device.getEndpoint(2);
47
48
  await reporting.bind(endpoint, coordinatorEndpoint, ['closuresDoorLock', 'genPowerCfg']);
48
49
  await reporting.lockState(endpoint);
49
50
  await reporting.batteryPercentageRemaining(endpoint);
50
51
  },
51
- exposes: [e.lock(), e.battery(), e.lock_action(), e.lock_action_source_name(), e.lock_action_source_user()],
52
+ // Note - Keypad triggered deletions do not cause a zigbee event, though Adds work fine.
53
+ onEvent: async (type, data, device) => {
54
+ // When we receive a code updated message, lets read the new value
55
+ if (data.type === 'commandProgrammingEventNotification' &&
56
+ data.cluster === 'closuresDoorLock' &&
57
+ data.data &&
58
+ data.data.userid !== undefined &&
59
+ // Don't read RF events, we can do this with retrieve_state
60
+ (data.data.programeventsrc === undefined || constants.lockSourceName[data.data.programeventsrc] != 'rf')
61
+ ) {
62
+ await device.endpoints[0].command('closuresDoorLock', 'getPinCode', {userid: data.data.userid}, {});
63
+ }
64
+ },
65
+ exposes: [e.lock(), e.battery(), e.pincode(), e.lock_action(), e.lock_action_source_name(), e.lock_action_source_user()],
52
66
  },
53
67
  ];
package/devices/xiaomi.js CHANGED
@@ -47,7 +47,7 @@ module.exports = [
47
47
  description: 'Aqara E1 door & window contact sensor',
48
48
  fromZigbee: [fz.ias_contact_alarm_1, fz.aqara_opple, fz.battery],
49
49
  toZigbee: [],
50
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
50
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
51
51
  exposes: [e.contact(), e.battery(), e.battery_low(), e.battery_voltage()],
52
52
  configure: async (device, coordinatorEndpoint, logger) => {
53
53
  const endpoint = device.getEndpoint(1);
@@ -63,7 +63,7 @@ module.exports = [
63
63
  description: 'Aqara P1 door & window contact sensor',
64
64
  fromZigbee: [fz. xiaomi_contact, fz.ias_contact_alarm_1, fz.aqara_opple],
65
65
  toZigbee: [],
66
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
66
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
67
67
  exposes: [e.contact(), e.battery(), e.battery_voltage()],
68
68
  },
69
69
  {
@@ -168,7 +168,7 @@ module.exports = [
168
168
  whiteLabel: [{vendor: 'Xiaomi', model: 'YTC4040GL'}, {vendor: 'Xiaomi', model: 'YTC4006CN'},
169
169
  {vendor: 'Xiaomi', model: 'YTC4017CN'}, {vendor: 'Xiaomi', model: 'ZHTZ02LM'}],
170
170
  description: 'MiJia wireless switch',
171
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
171
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
172
172
  fromZigbee: [fz.xiaomi_basic, fz.xiaomi_WXKG01LM_action, fz.legacy.WXKG01LM_click],
173
173
  exposes: [e.battery(), e.action(['single', 'double', 'triple', 'quadruple', 'hold', 'release', 'many']), e.battery_voltage(),
174
174
  e.power_outage_count(false)],
@@ -179,7 +179,7 @@ module.exports = [
179
179
  model: 'WXKG11LM',
180
180
  vendor: 'Xiaomi',
181
181
  description: 'Aqara wireless switch',
182
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
182
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
183
183
  exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'triple', 'quadruple', 'hold', 'release']),
184
184
  e.device_temperature(), e.power_outage_count()],
185
185
  fromZigbee: [fz.xiaomi_multistate_action, fz.xiaomi_WXKG11LM_action, fz.xiaomi_basic,
@@ -191,7 +191,7 @@ module.exports = [
191
191
  model: 'WXKG12LM',
192
192
  vendor: 'Xiaomi',
193
193
  description: 'Aqara wireless switch (with gyroscope)',
194
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
194
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
195
195
  exposes: [e.battery(), e.action(['single', 'double', 'hold', 'release', 'shake']), e.battery_voltage()],
196
196
  fromZigbee: [fz.xiaomi_basic, fz.xiaomi_multistate_action, fz.legacy.WXKG12LM_action_click_multistate],
197
197
  toZigbee: [],
@@ -201,7 +201,7 @@ module.exports = [
201
201
  model: 'WXKG03LM_rev1',
202
202
  vendor: 'Xiaomi',
203
203
  description: 'Aqara single key wireless wall switch (2016 model)',
204
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
204
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
205
205
  exposes: [e.battery(), e.action(['single']), e.battery_voltage()],
206
206
  fromZigbee: [fz.xiaomi_on_off_action, fz.xiaomi_basic, fz.legacy.WXKG03LM_click],
207
207
  toZigbee: [],
@@ -212,7 +212,7 @@ module.exports = [
212
212
  model: 'WXKG03LM_rev2',
213
213
  vendor: 'Xiaomi',
214
214
  description: 'Aqara single key wireless wall switch (2018 model)',
215
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
215
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
216
216
  exposes: [e.battery(), e.action(['single', 'double', 'hold']), e.battery_voltage()],
217
217
  fromZigbee: [fz.xiaomi_on_off_action, fz.xiaomi_multistate_action, fz.xiaomi_basic,
218
218
  fz.legacy.WXKG03LM_click, fz.legacy.xiaomi_action_click_multistate],
@@ -230,7 +230,7 @@ module.exports = [
230
230
  e.action(['single', 'double', 'hold']),
231
231
  e.battery_voltage()],
232
232
  onEvent: preventReset,
233
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
233
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
234
234
  configure: async (device, coordinatorEndpoint, logger) => {
235
235
  try {
236
236
  const endpoint = device.endpoints[1];
@@ -245,7 +245,7 @@ module.exports = [
245
245
  model: 'WXKG02LM_rev1',
246
246
  vendor: 'Xiaomi',
247
247
  description: 'Aqara double key wireless wall switch (2016 model)',
248
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
248
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
249
249
  exposes: [e.battery(), e.action(['single_left', 'single_right', 'single_both']), e.battery_voltage(), e.power_outage_count(false)],
250
250
  fromZigbee: [fz.xiaomi_on_off_action, fz.xiaomi_basic, fz.legacy.WXKG02LM_click],
251
251
  toZigbee: [],
@@ -256,7 +256,7 @@ module.exports = [
256
256
  model: 'WXKG02LM_rev2',
257
257
  vendor: 'Xiaomi',
258
258
  description: 'Aqara double key wireless wall switch (2018 model)',
259
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
259
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
260
260
  exposes: [e.battery(), e.action(['single_left', 'single_right', 'single_both', 'double_left', 'double_right', 'double_both',
261
261
  'hold_left', 'hold_right', 'hold_both']), e.battery_voltage()],
262
262
  fromZigbee: [fz.xiaomi_on_off_action, fz.xiaomi_multistate_action, fz.xiaomi_basic,
@@ -410,9 +410,9 @@ module.exports = [
410
410
  description: 'Aqara smart wall switch H1 EU (with neutral, single rocker)',
411
411
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.xiaomi_multistate_action, fz.aqara_opple],
412
412
  toZigbee: [tz.on_off, tz.xiaomi_power, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory,
413
- tz.xiaomi_flip_indicator_light],
413
+ tz.xiaomi_flip_indicator_light, tz.xiaomi_led_disabled_night],
414
414
  exposes: [e.switch(), e.action(['single', 'double']), e.power().withAccess(ea.STATE_GET), e.energy(), e.flip_indicator_light(),
415
- e.power_outage_memory(), e.device_temperature().withAccess(ea.STATE),
415
+ e.power_outage_memory(), e.device_temperature().withAccess(ea.STATE), e.led_disabled_night(), e.power_outage_count(),
416
416
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']).withDescription('Decoupled mode')],
417
417
  onEvent: preventReset,
418
418
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -428,7 +428,7 @@ module.exports = [
428
428
  description: 'Aqara smart wall switch H1 EU (with neutral, double rocker)',
429
429
  fromZigbee: [fz.on_off, fz.xiaomi_power, fz.xiaomi_multistate_action, fz.aqara_opple],
430
430
  toZigbee: [tz.on_off, tz.xiaomi_power, tz.xiaomi_switch_operation_mode_opple, tz.xiaomi_switch_power_outage_memory,
431
- tz.xiaomi_flip_indicator_light],
431
+ tz.xiaomi_flip_indicator_light, tz.xiaomi_led_disabled_night],
432
432
  meta: {multiEndpoint: true},
433
433
  endpoint: (device) => {
434
434
  return {'left': 1, 'right': 2};
@@ -439,7 +439,8 @@ module.exports = [
439
439
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']).withDescription('Decoupled mode for right button')
440
440
  .withEndpoint('right'),
441
441
  e.action(['single_left', 'double_left', 'single_right', 'double_right', 'single_both', 'double_both']),
442
- e.device_temperature().withAccess(ea.STATE), e.power_outage_memory(), e.flip_indicator_light()],
442
+ e.device_temperature().withAccess(ea.STATE), e.power_outage_memory(), e.flip_indicator_light(),
443
+ e.led_disabled_night(), e.power_outage_count()],
443
444
  onEvent: preventReset,
444
445
  configure: async (device, coordinatorEndpoint, logger) => {
445
446
  const endpoint1 = device.getEndpoint(1);
@@ -560,7 +561,7 @@ module.exports = [
560
561
  model: 'WXKG07LM',
561
562
  vendor: 'Xiaomi',
562
563
  description: 'Aqara D1 double key wireless wall switch',
563
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
564
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
564
565
  fromZigbee: [fz.xiaomi_basic, fz.legacy.xiaomi_on_off_action, fz.legacy.xiaomi_multistate_action],
565
566
  toZigbee: [],
566
567
  endpoint: (device) => {
@@ -840,7 +841,7 @@ module.exports = [
840
841
  whiteLabel: [{vendor: 'Xiaomi', model: 'YTC4042GL'}, {vendor: 'Xiaomi', model: 'YTC4007CN'},
841
842
  {vendor: 'Xiaomi', model: 'YTC4018CN'}],
842
843
  description: 'MiJia temperature & humidity sensor',
843
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
844
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
844
845
  fromZigbee: [fz.xiaomi_basic, fz.xiaomi_temperature, fz.humidity],
845
846
  toZigbee: [],
846
847
  exposes: [e.battery(), e.temperature(), e.humidity(), e.battery_voltage()],
@@ -850,7 +851,7 @@ module.exports = [
850
851
  model: 'WSDCGQ11LM',
851
852
  vendor: 'Xiaomi',
852
853
  description: 'Aqara temperature, humidity and pressure sensor',
853
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
854
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
854
855
  fromZigbee: [fz.xiaomi_basic, fz.xiaomi_temperature, fz.humidity, fz.pressure],
855
856
  toZigbee: [],
856
857
  exposes: [e.battery(), e.temperature(), e.humidity(), e.pressure(), e.battery_voltage()],
@@ -868,7 +869,7 @@ module.exports = [
868
869
  toZigbee: [],
869
870
  exposes: [e.temperature(), e.humidity(), e.pressure(), e.device_temperature(), e.battery(), e.battery_voltage(),
870
871
  e.power_outage_count(false)],
871
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
872
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
872
873
  configure: async (device, coordinatorEndpoint, logger) => {
873
874
  const endpoint = device.getEndpoint(1);
874
875
  const binds = ['msTemperatureMeasurement', 'msRelativeHumidity', 'msPressureMeasurement'];
@@ -884,7 +885,7 @@ module.exports = [
884
885
  whiteLabel: [{vendor: 'Xiaomi', model: 'YTC4041GL'}, {vendor: 'Xiaomi', model: 'YTC4004CN'},
885
886
  {vendor: 'Xiaomi', model: 'YTC4016CN'}, {vendor: 'Xiaomi', model: 'ZHTZ02LM'}],
886
887
  description: 'MiJia human body movement sensor',
887
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
888
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
888
889
  fromZigbee: [fz.xiaomi_basic, fz.occupancy_with_timeout],
889
890
  toZigbee: [],
890
891
  exposes: [e.battery(), e.occupancy(), e.battery_voltage(), e.power_outage_count(false)],
@@ -894,7 +895,7 @@ module.exports = [
894
895
  model: 'RTCGQ11LM',
895
896
  vendor: 'Xiaomi',
896
897
  description: 'Aqara human body movement and illuminance sensor',
897
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
898
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
898
899
  fromZigbee: [fz.xiaomi_basic, fz.occupancy_with_timeout, fz.RTCGQ11LM_illuminance],
899
900
  toZigbee: [],
900
901
  exposes: [e.battery(), e.occupancy(), e.device_temperature(), e.battery_voltage(), e.illuminance_lux().withProperty('illuminance'),
@@ -912,7 +913,7 @@ module.exports = [
912
913
  exposes.numeric('detection_interval', ea.ALL).withValueMin(2).withValueMax(65535).withUnit('s')
913
914
  .withDescription('Time interval for detecting actions'),
914
915
  e.device_temperature(), e.battery(), e.battery_voltage(), e.power_outage_count(false)],
915
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
916
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
916
917
  configure: async (device, coordinatorEndpoint, logger) => {
917
918
  const endpoint = device.getEndpoint(1);
918
919
  await endpoint.read('genPowerCfg', ['batteryVoltage']);
@@ -931,7 +932,7 @@ module.exports = [
931
932
  exposes.numeric('detection_interval', ea.ALL).withValueMin(2).withValueMax(65535).withUnit('s')
932
933
  .withDescription('Time interval for detecting actions'),
933
934
  e.device_temperature(), e.battery(), e.battery_voltage(), e.power_outage_count(false)],
934
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
935
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
935
936
  configure: async (device, coordinatorEndpoint, logger) => {
936
937
  const endpoint = device.getEndpoint(1);
937
938
  await endpoint.read('genPowerCfg', ['batteryVoltage']);
@@ -959,7 +960,7 @@ module.exports = [
959
960
  'blue LED will blink once when motion is detected. ' +
960
961
  'Press pairing button right before changing this otherwise it will fail.'),
961
962
  e.device_temperature(), e.battery(), e.battery_voltage()],
962
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
963
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
963
964
  configure: async (device, coordinatorEndpoint, logger) => {
964
965
  const endpoint = device.getEndpoint(1);
965
966
  await endpoint.read('genPowerCfg', ['batteryVoltage']);
@@ -1005,7 +1006,7 @@ module.exports = [
1005
1006
  whiteLabel: [{vendor: 'Xiaomi', model: 'YTC4039GL'}, {vendor: 'Xiaomi', model: 'YTC4005CN'},
1006
1007
  {vendor: 'Xiaomi', model: 'YTC4015CN'}, {vendor: 'Xiaomi', model: 'ZHTZ02LM'}],
1007
1008
  description: 'MiJia door & window contact sensor',
1008
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1009
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1009
1010
  fromZigbee: [fz.xiaomi_basic, fz.xiaomi_contact],
1010
1011
  toZigbee: [],
1011
1012
  exposes: [e.battery(), e.contact(), e.battery_voltage(), e.power_outage_count(false)],
@@ -1015,7 +1016,7 @@ module.exports = [
1015
1016
  model: 'MCCGQ11LM',
1016
1017
  vendor: 'Xiaomi',
1017
1018
  description: 'Aqara door & window contact sensor',
1018
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1019
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1019
1020
  fromZigbee: [fz.xiaomi_basic, fz.xiaomi_contact],
1020
1021
  toZigbee: [],
1021
1022
  exposes: [e.battery(), e.contact(), e.device_temperature(), e.battery_voltage(), e.power_outage_count(false)],
@@ -1029,7 +1030,7 @@ module.exports = [
1029
1030
  model: 'SJCGQ11LM',
1030
1031
  vendor: 'Xiaomi',
1031
1032
  description: 'Aqara water leak sensor',
1032
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1033
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1033
1034
  fromZigbee: [fz.xiaomi_basic, fz.ias_water_leak_alarm_1],
1034
1035
  toZigbee: [],
1035
1036
  exposes: [e.battery(), e.water_leak(), e.battery_low(), e.battery_voltage(), e.device_temperature(), e.power_outage_count(false)],
@@ -1039,7 +1040,7 @@ module.exports = [
1039
1040
  model: 'SJCGQ12LM',
1040
1041
  vendor: 'Xiaomi',
1041
1042
  description: 'Aqara T1 water leak sensor',
1042
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1043
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1043
1044
  fromZigbee: [fz.xiaomi_basic, fz.ias_water_leak_alarm_1],
1044
1045
  toZigbee: [],
1045
1046
  exposes: [e.battery(), e.water_leak(), e.battery_low(), e.tamper(), e.battery_voltage()],
@@ -1050,7 +1051,7 @@ module.exports = [
1050
1051
  model: 'MFKZQ01LM',
1051
1052
  vendor: 'Xiaomi',
1052
1053
  description: 'Mi/Aqara smart home cube',
1053
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1054
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1054
1055
  fromZigbee: [fz.xiaomi_basic, fz.MFKZQ01LM_action_multistate, fz.MFKZQ01LM_action_analog],
1055
1056
  exposes: [e.battery(), e.battery_voltage(), e.angle('action_angle'), e.device_temperature(), e.power_outage_count(false),
1056
1057
  e.cube_side('action_from_side'), e.cube_side('action_side'), e.cube_side('action_to_side'), e.cube_side('side'),
@@ -1210,7 +1211,7 @@ module.exports = [
1210
1211
  description: 'MiJia Honeywell smoke detector',
1211
1212
  vendor: 'Xiaomi',
1212
1213
  whiteLabel: [{vendor: 'Xiaomi', model: 'YTC4020RT'}],
1213
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1214
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1214
1215
  fromZigbee: [fz.xiaomi_basic, fz.JTYJGD01LMBW_smoke],
1215
1216
  toZigbee: [tz.JTQJBF01LMBW_JTYJGD01LMBW_sensitivity, tz.JTQJBF01LMBW_JTYJGD01LMBW_selfest],
1216
1217
  exposes: [
@@ -1290,7 +1291,7 @@ module.exports = [
1290
1291
  exposes.binary('linkage_alarm', ea.ALL, true, false).withDescription('When this option is enabled and a smoke ' +
1291
1292
  'is detected, other detectors with this option enabled will also sound the alarm buzzer'),
1292
1293
  e.device_temperature(), e.battery(), e.battery_voltage(), e.power_outage_count(false)],
1293
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1294
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1294
1295
  configure: async (device, coordinatorEndpoint, logger) => {
1295
1296
  const endpoint = device.getEndpoint(1);
1296
1297
  await endpoint.read('genPowerCfg', ['batteryVoltage']);
@@ -1316,7 +1317,7 @@ module.exports = [
1316
1317
  model: 'DJT11LM',
1317
1318
  vendor: 'Xiaomi',
1318
1319
  description: 'Aqara vibration sensor',
1319
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1320
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1320
1321
  fromZigbee: [fz.xiaomi_basic, fz.DJT11LM_vibration],
1321
1322
  toZigbee: [tz.DJT11LM_vibration_sensitivity],
1322
1323
  exposes: [
@@ -1541,7 +1542,7 @@ module.exports = [
1541
1542
  ]), exposes.enum('operation_mode', ea.ALL, ['command', 'event'])
1542
1543
  .withDescription('Operation mode, select "command" to enable bindings (wake up the device before changing modes!)')],
1543
1544
  toZigbee: [tz.aqara_opple_operation_mode],
1544
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1545
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1545
1546
  configure: async (device, coordinatorEndpoint, logger) => {
1546
1547
  const endpoint = device.getEndpoint(1);
1547
1548
  await endpoint.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f});
@@ -1563,7 +1564,7 @@ module.exports = [
1563
1564
  ]), exposes.enum('operation_mode', ea.ALL, ['command', 'event'])
1564
1565
  .withDescription('Operation mode, select "command" to enable bindings (wake up the device before changing modes!)')],
1565
1566
  toZigbee: [tz.aqara_opple_operation_mode],
1566
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1567
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1567
1568
  configure: async (device, coordinatorEndpoint, logger) => {
1568
1569
  const endpoint = device.getEndpoint(1);
1569
1570
  await endpoint.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f});
@@ -1590,7 +1591,7 @@ module.exports = [
1590
1591
  .withDescription('Operation mode, select "command" to enable bindings (wake up the device before changing modes!)'),
1591
1592
  e.power_outage_count(false)],
1592
1593
  toZigbee: [tz.aqara_opple_operation_mode],
1593
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1594
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1594
1595
  configure: async (device, coordinatorEndpoint, logger) => {
1595
1596
  const endpoint = device.getEndpoint(1);
1596
1597
  await endpoint.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f});
@@ -1607,7 +1608,7 @@ module.exports = [
1607
1608
  description: 'MiJia light intensity sensor',
1608
1609
  fromZigbee: [fz.battery, fz.illuminance, fz.aqara_opple],
1609
1610
  toZigbee: [],
1610
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1611
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1611
1612
  configure: async (device, coordinatorEndpoint, logger) => {
1612
1613
  const endpoint = device.getEndpoint(1);
1613
1614
  await reporting.bind(endpoint, coordinatorEndpoint, ['msIlluminanceMeasurement']);
@@ -1761,7 +1762,7 @@ module.exports = [
1761
1762
  description: 'Aqara wireless remote switch H1 (double rocker)',
1762
1763
  fromZigbee: [fz.battery, fz.xiaomi_multistate_action, fz.aqara_opple, fz.command_toggle],
1763
1764
  toZigbee: [tz.xiaomi_switch_click_mode, tz.aqara_opple_operation_mode],
1764
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}, multiEndpoint: true},
1765
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}, multiEndpoint: true},
1765
1766
  exposes: [
1766
1767
  e.battery(), e.battery_voltage(), e.action([
1767
1768
  'single_left', 'single_right', 'single_both',
@@ -1848,7 +1849,7 @@ module.exports = [
1848
1849
  description: 'Aqara TVOC air quality monitor',
1849
1850
  fromZigbee: [fz.xiaomi_tvoc, fz.battery, fz.temperature, fz.humidity, fz.aqara_opple],
1850
1851
  toZigbee: [],
1851
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1852
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1852
1853
  exposes: [e.temperature(), e.humidity(), e.voc(), e.device_temperature(), e.battery(), e.battery_voltage()],
1853
1854
  configure: async (device, coordinatorEndpoint, logger) => {
1854
1855
  const endpoint = device.getEndpoint(1);
@@ -1927,7 +1928,7 @@ module.exports = [
1927
1928
  model: 'WXKG13LM',
1928
1929
  vendor: 'Xiaomi',
1929
1930
  description: 'Aqara T1 wireless mini switch',
1930
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1931
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1931
1932
  fromZigbee: [fz.battery, fz.aqara_opple_multistate, fz.aqara_opple],
1932
1933
  toZigbee: [],
1933
1934
  exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'triple', 'quintuple', 'hold', 'release', 'many'])],
@@ -1943,7 +1944,7 @@ module.exports = [
1943
1944
  description: 'Aqara T1 light intensity sensor',
1944
1945
  fromZigbee: [fz.battery, fz.illuminance, fz.aqara_opple],
1945
1946
  toZigbee: [tz.GZCGQ11LM_detection_period],
1946
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1947
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1947
1948
  exposes: [e.battery(), e.battery_voltage(), e.illuminance(), e.illuminance_lux(),
1948
1949
  exposes.numeric('detection_period', exposes.access.ALL).withValueMin(1).withValueMax(59).withUnit('s')
1949
1950
  .withDescription('Time interval in seconds to report after light changes')],
@@ -1982,7 +1983,7 @@ module.exports = [
1982
1983
  description: 'Aqara T1 door & window contact sensor',
1983
1984
  fromZigbee: [fz.xiaomi_contact, fz.aqara_opple],
1984
1985
  toZigbee: [],
1985
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1986
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
1986
1987
  exposes: [e.contact(), e.battery(), e.battery_voltage()],
1987
1988
  },
1988
1989
  {
@@ -2006,7 +2007,7 @@ module.exports = [
2006
2007
  model: 'ZNXNKG02LM',
2007
2008
  vendor: 'Xiaomi',
2008
2009
  description: 'Aqara knob H1 (wireless)',
2009
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
2010
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
2010
2011
  exposes: [e.battery(), e.battery_voltage(),
2011
2012
  e.action(['single', 'double', 'hold', 'release', 'start_rotating', 'rotation', 'stop_rotating']),
2012
2013
  exposes.enum('operation_mode', ea.ALL, ['event', 'command']).withDescription('Button mode'),
@@ -2029,7 +2030,7 @@ module.exports = [
2029
2030
  model: 'WXKG16LM',
2030
2031
  vendor: 'Xiaomi',
2031
2032
  description: 'Aqara wireless remote switch E1 (single rocker)',
2032
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
2033
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
2033
2034
  fromZigbee: [fz.xiaomi_multistate_action, fz.aqara_opple],
2034
2035
  toZigbee: [tz.xiaomi_switch_click_mode],
2035
2036
  exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'hold']),
@@ -2045,7 +2046,7 @@ module.exports = [
2045
2046
  model: 'WXKG17LM',
2046
2047
  vendor: 'Xiaomi',
2047
2048
  description: 'Aqara E1 double key wireless switch',
2048
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
2049
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
2049
2050
  exposes: [e.battery(), e.battery_voltage(),
2050
2051
  e.action(['single_left', 'single_right', 'single_both', 'double_left', 'double_right', 'hold_left', 'hold_right']),
2051
2052
  // eslint-disable-next-line max-len
@@ -2073,7 +2074,7 @@ module.exports = [
2073
2074
  'multi: supports more events like double and hold'),
2074
2075
  exposes.enum('operation_mode', ea.ALL, ['command', 'event'])
2075
2076
  .withDescription('Operation mode, select "command" to enable bindings (wake up the device before changing modes!)')],
2076
- meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
2077
+ meta: {battery: {voltageToPercentage: '3V_2850_3200'}},
2077
2078
  configure: async (device, coordinatorEndpoint, logger) => {
2078
2079
  const endpoint1 = device.getEndpoint(1);
2079
2080
  await endpoint1.write('aqaraOpple', {'mode': 1}, {manufacturerCode: 0x115f, disableResponse: true});
package/lib/extend.js CHANGED
@@ -12,11 +12,16 @@ const extend = {
12
12
  return {exposes, fromZigbee, toZigbee};
13
13
  },
14
14
  light_onoff_brightness: (options={}) => {
15
- options = {disableEffect: false, ...options};
15
+ options = {disableEffect: false, disablePowerOnBehavior: false, ...options};
16
16
  const exposes = [e.light_brightness(), ...(!options.disableEffect ? [e.effect()] : [])];
17
- const fromZigbee = [fz.on_off, fz.brightness, fz.level_config, fz.power_on_behavior, fz.ignore_basic_report];
17
+ const fromZigbee = [fz.on_off, fz.brightness, fz.level_config, fz.ignore_basic_report];
18
18
  const toZigbee = [tz.light_onoff_brightness, tz.ignore_transition, tz.ignore_rate, tz.light_brightness_move,
19
- tz.light_brightness_step, tz.level_config, tz.power_on_behavior, ...(!options.disableEffect ? [tz.effect] : [])];
19
+ tz.light_brightness_step, tz.level_config, ...(!options.disableEffect ? [tz.effect] : [])];
20
+
21
+ if (!options.disablePowerOnBehavior) {
22
+ fromZigbee.push(fz.power_on_behavior);
23
+ toZigbee.push(tz.power_on_behavior);
24
+ }
20
25
 
21
26
  const result = {exposes, fromZigbee, toZigbee};
22
27
  if (!options.noConfigure) {
@@ -28,18 +33,23 @@ const extend = {
28
33
  return result;
29
34
  },
30
35
  light_onoff_brightness_colortemp: (options={}) => {
31
- options = {disableEffect: false, disableColorTempStartup: false, ...options};
36
+ options = {disableEffect: false, disableColorTempStartup: false, disablePowerOnBehavior: false, ...options};
32
37
  const exposes = [e.light_brightness_colortemp(options.colorTempRange), ...(!options.disableEffect ? [e.effect()] : [])];
33
38
  const toZigbee = [tz.light_onoff_brightness, tz.light_colortemp, tz.ignore_transition, tz.ignore_rate, tz.light_brightness_move,
34
39
  tz.light_colortemp_move, tz.light_brightness_step, tz.light_colortemp_step, tz.light_colortemp_startup, tz.level_config,
35
- tz.power_on_behavior, tz.light_color_options, tz.light_color_mode, ...(!options.disableEffect ? [tz.effect] : [])];
36
- const fromZigbee = [fz.color_colortemp, fz.on_off, fz.brightness, fz.level_config, fz.power_on_behavior, fz.ignore_basic_report];
40
+ tz.light_color_options, tz.light_color_mode, ...(!options.disableEffect ? [tz.effect] : [])];
41
+ const fromZigbee = [fz.color_colortemp, fz.on_off, fz.brightness, fz.level_config, fz.ignore_basic_report];
37
42
 
38
43
  if (options.disableColorTempStartup) {
39
44
  exposes[0].removeFeature('color_temp_startup');
40
45
  toZigbee.splice(toZigbee.indexOf(tz.light_colortemp_startup), 1);
41
46
  }
42
47
 
48
+ if (!options.disablePowerOnBehavior) {
49
+ fromZigbee.push(fz.power_on_behavior);
50
+ toZigbee.push(tz.power_on_behavior);
51
+ }
52
+
43
53
  const result = {exposes, fromZigbee, toZigbee};
44
54
  if (!options.noConfigure) {
45
55
  result.configure = async (device, coordinatorEndpoint, logger) => {
@@ -50,14 +60,19 @@ const extend = {
50
60
  return result;
51
61
  },
52
62
  light_onoff_brightness_color: (options={}) => {
53
- options = {disableEffect: false, supportsHS: false, preferHS: false, ...options};
63
+ options = {disableEffect: false, supportsHS: false, preferHS: false, disablePowerOnBehavior: false, ...options};
54
64
  const exposes = [(options.supportsHS ? e.light_brightness_color(options.preferHS) : e.light_brightness_colorxy()),
55
65
  ...(!options.disableEffect ? [e.effect()] : [])];
56
- const fromZigbee = [fz.color_colortemp, fz.on_off, fz.brightness, fz.level_config, fz.power_on_behavior, fz.ignore_basic_report];
66
+ const fromZigbee = [fz.color_colortemp, fz.on_off, fz.brightness, fz.level_config, fz.ignore_basic_report];
57
67
  const toZigbee = [tz.light_onoff_brightness, tz.light_color, tz.ignore_transition, tz.ignore_rate, tz.light_brightness_move,
58
- tz.light_brightness_step, tz.level_config, tz.power_on_behavior, tz.light_hue_saturation_move,
68
+ tz.light_brightness_step, tz.level_config, tz.light_hue_saturation_move,
59
69
  tz.light_hue_saturation_step, tz.light_color_options, tz.light_color_mode, ...(!options.disableEffect ? [tz.effect] : [])];
60
70
 
71
+ if (!options.disablePowerOnBehavior) {
72
+ fromZigbee.push(fz.power_on_behavior);
73
+ toZigbee.push(tz.power_on_behavior);
74
+ }
75
+
61
76
  const result = {exposes, fromZigbee, toZigbee};
62
77
  if (!options.noConfigure) {
63
78
  result.configure = async (device, coordinatorEndpoint, logger) => {
@@ -68,14 +83,20 @@ const extend = {
68
83
  return result;
69
84
  },
70
85
  light_onoff_brightness_colortemp_color: (options={}) => {
71
- options = {disableEffect: false, supportsHS: false, disableColorTempStartup: false, preferHS: false, ...options};
86
+ options = {
87
+ disableEffect: false,
88
+ supportsHS: false,
89
+ disableColorTempStartup: false,
90
+ preferHS: false,
91
+ disablePowerOnBehavior: false,
92
+ ...options};
72
93
  const exposes = [(options.supportsHS ? e.light_brightness_colortemp_color(options.colorTempRange, options.preferHS) :
73
94
  e.light_brightness_colortemp_colorxy(options.colorTempRange)), ...(!options.disableEffect ? [e.effect()] : [])];
74
- const fromZigbee = [fz.color_colortemp, fz.on_off, fz.brightness, fz.level_config, fz.power_on_behavior, fz.ignore_basic_report];
95
+ const fromZigbee = [fz.color_colortemp, fz.on_off, fz.brightness, fz.level_config, fz.ignore_basic_report];
75
96
  const toZigbee = [
76
97
  tz.light_onoff_brightness, tz.light_color_colortemp, tz.ignore_transition, tz.ignore_rate, tz.light_brightness_move,
77
98
  tz.light_colortemp_move, tz.light_brightness_step, tz.light_colortemp_step, tz.light_hue_saturation_move,
78
- tz.light_hue_saturation_step, tz.light_colortemp_startup, tz.level_config, tz.power_on_behavior, tz.light_color_options,
99
+ tz.light_hue_saturation_step, tz.light_colortemp_startup, tz.level_config, tz.light_color_options,
79
100
  tz.light_color_mode, ...(!options.disableEffect ? [tz.effect] : [])];
80
101
 
81
102
  if (options.disableColorTempStartup) {
@@ -83,6 +104,11 @@ const extend = {
83
104
  toZigbee.splice(toZigbee.indexOf(tz.light_colortemp_startup), 1);
84
105
  }
85
106
 
107
+ if (!options.disablePowerOnBehavior) {
108
+ fromZigbee.push(fz.power_on_behavior);
109
+ toZigbee.push(tz.power_on_behavior);
110
+ }
111
+
86
112
  const result = {exposes, fromZigbee, toZigbee};
87
113
  if (!options.noConfigure) {
88
114
  result.configure = async (device, coordinatorEndpoint, logger) => {
package/lib/utils.js CHANGED
@@ -102,13 +102,7 @@ function toPercentage(value, min, max, log=false) {
102
102
  }
103
103
 
104
104
  const normalised = (value - min) / (max - min);
105
- let percentage;
106
- if (log == true) {
107
- percentage = normalised === 0 ? 0 : normalised * (1 - Math.log( normalised ));
108
- } else {
109
- percentage = normalised;
110
- }
111
- return Math.round(percentage * 100);
105
+ return Math.round(normalised * 100);
112
106
  }
113
107
 
114
108
  function addActionGroup(payload, msg, definition) {
@@ -169,8 +163,6 @@ function batteryVoltageToPercentage(voltage, option) {
169
163
  percentage = Math.round(percentage);
170
164
  } else if (option === '3V_2850_3200') {
171
165
  percentage = toPercentage(voltage, 2850, 3200);
172
- } else if (option === '3V_2850_3000_log') {
173
- percentage = toPercentage(voltage, 2850, 3000, true);
174
166
  } else if (option === '4LR6AA1_5v') {
175
167
  percentage = toPercentage(voltage, 3000, 4200);
176
168
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.559",
3
+ "version": "14.0.562",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [