zigbee-herdsman-converters 14.0.537 → 14.0.540

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,9 +2257,7 @@ 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)
2261
- return {running: true};
2262
- }
2260
+ case tuya.dataPoints.coverPosition: // Started moving to position (triggered from Zigbee)
2263
2261
  case tuya.dataPoints.coverArrived: { // Arrived at position
2264
2262
  const running = dp === tuya.dataPoints.coverArrived ? false : true;
2265
2263
  const invert = tuya.isCoverInverted(meta.device.manufacturerName) ? !options.invert_cover : options.invert_cover;
@@ -7308,7 +7306,7 @@ const converters = {
7308
7306
  case 4:
7309
7307
  return {battery: value};
7310
7308
  case 1:
7311
- return {battery_low: value.toFixed(1)};
7309
+ return {battery_low: value === 1};
7312
7310
  default:
7313
7311
  meta.logger.warn(`s_lux_zb_illuminance: NOT RECOGNIZED DP #${dp} with data ${JSON.stringify(dpValue)}`);
7314
7312
  }
@@ -6,6 +6,37 @@ const extend = require('../lib/extend');
6
6
  const e = exposes.presets;
7
7
  const ea = exposes.access;
8
8
 
9
+ const tzLocal = {
10
+ node_config: {
11
+ key: ['report_delay'],
12
+ convertSet: async (entity, key, rawValue, meta) => {
13
+ const lookup = {'OFF': 0x00, 'ON': 0x01};
14
+ const value = lookup.hasOwnProperty(rawValue) ? lookup[rawValue] : parseInt(rawValue, 10);
15
+ const payloads = {
16
+ report_delay: ['genPowerCfg', {0x0201: {value, type: 0x21}}],
17
+ };
18
+ await entity.write(payloads[key][0], payloads[key][1]);
19
+ return {
20
+ state: {[key]: rawValue},
21
+ };
22
+ },
23
+ },
24
+ };
25
+
26
+ const fzLocal = {
27
+ node_config: {
28
+ cluster: 'genPowerCfg',
29
+ type: ['attributeReport', 'readResponse'],
30
+ convert: (model, msg, publish, options, meta) => {
31
+ const result = {};
32
+ if (msg.data.hasOwnProperty(0x0201)) {
33
+ result.report_delay = msg.data[0x0201];
34
+ }
35
+ return result;
36
+ },
37
+ },
38
+ };
39
+
9
40
  module.exports = [
10
41
  {
11
42
  zigbeeModel: ['ti.router'],
@@ -257,17 +288,15 @@ module.exports = [
257
288
  model: 'EFEKTA_miniPWS',
258
289
  vendor: 'Custom devices (DiY)',
259
290
  description: '[Mini plant wattering sensor](http://efektalab.com/miniPWS)',
260
- fromZigbee: [fz.soil_moisture, fz.battery],
261
- toZigbee: [tz.factory_reset],
291
+ fromZigbee: [fz.soil_moisture, fz.battery, fzLocal.node_config],
292
+ toZigbee: [tz.factory_reset, tzLocal.node_config],
262
293
  configure: async (device, coordinatorEndpoint, logger) => {
263
294
  const firstEndpoint = device.getEndpoint(1);
264
295
  await reporting.bind(firstEndpoint, coordinatorEndpoint, ['genPowerCfg', 'msSoilMoisture']);
265
- const overides = {min: 0, max: 21600, change: 0};
266
- await reporting.batteryVoltage(firstEndpoint, overides);
267
- await reporting.batteryPercentageRemaining(firstEndpoint, overides);
268
- await reporting.soil_moisture(firstEndpoint, overides);
269
296
  },
270
- exposes: [e.soil_moisture(), e.battery()],
297
+ exposes: [e.soil_moisture(), e.battery(),
298
+ exposes.numeric('report_delay', ea.STATE_SET).withUnit('min').withDescription('Adjust Report Delay, by default 60 minutes')
299
+ .withValueMin(1).withValueMax(180)],
271
300
  },
272
301
  {
273
302
  zigbeeModel: ['EFEKTA_eON213wz'],
@@ -10,14 +10,15 @@ module.exports = [
10
10
  model: 'V3-BTZB/V3-BTZBE',
11
11
  vendor: 'Danalock',
12
12
  description: 'BT/ZB smartlock',
13
- fromZigbee: [fz.lock, fz.lock_operation_event, fz.battery],
14
- toZigbee: [tz.lock],
13
+ fromZigbee: [fz.lock, fz.lock_operation_event, fz.battery, fz.lock_programming_event, fz.lock_pin_code_response],
14
+ toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus],
15
+ meta: {pinCodeCount: 20},
15
16
  configure: async (device, coordinatorEndpoint, logger) => {
16
17
  const endpoint = device.getEndpoint(1);
17
18
  await reporting.bind(endpoint, coordinatorEndpoint, ['closuresDoorLock', 'genPowerCfg']);
18
19
  await reporting.lockState(endpoint);
19
20
  await reporting.batteryPercentageRemaining(endpoint);
20
21
  },
21
- exposes: [e.lock(), e.battery(), e.lock_action(), e.lock_action_source_name(), e.lock_action_source_user()],
22
+ exposes: [e.lock(), e.battery(), e.pincode(), e.lock_action(), e.lock_action_source_name(), e.lock_action_source_user()],
22
23
  },
23
24
  ];
package/devices/heiman.js CHANGED
@@ -117,6 +117,15 @@ module.exports = [
117
117
  toZigbee: [],
118
118
  exposes: [e.gas(), e.battery_low(), e.tamper()],
119
119
  },
120
+ {
121
+ zigbeeModel: ['RH3070'],
122
+ model: 'HS1CG',
123
+ vendor: 'Heiman',
124
+ description: 'Smart combustible gas sensor',
125
+ fromZigbee: [fz.ias_gas_alarm_1],
126
+ toZigbee: [],
127
+ exposes: [e.gas(), e.battery_low(), e.tamper()],
128
+ },
120
129
  {
121
130
  zigbeeModel: ['GAS_V15'],
122
131
  model: 'HS1CG_M',
package/devices/ikea.js CHANGED
@@ -36,10 +36,10 @@ const bulbOnEvent = async (type, data, device, options, state) => {
36
36
 
37
37
  // NOTE: execute_if_off default is false
38
38
  // we only restore if true, to save unneeded network writes
39
- if (state.color_options !== undefined && state.color_options.execute_if_off === true) {
39
+ if (state !== undefined && state.color_options !== undefined && state.color_options.execute_if_off === true) {
40
40
  device.endpoints[0].write('lightingColorCtrl', {'options': 1});
41
41
  }
42
- if (state.level_config !== undefined && state.level_config.execute_if_off === true) {
42
+ if (state !== undefined && state.level_config !== undefined && state.level_config.execute_if_off === true) {
43
43
  device.endpoints[0].write('genLevelCtrl', {'options': 1});
44
44
  }
45
45
  }
package/devices/lellki.js CHANGED
@@ -23,6 +23,9 @@ module.exports = [
23
23
  return {l1: 1, l2: 2, l3: 3, l4: 4, l5: 5};
24
24
  },
25
25
  configure: async (device, coordinatorEndpoint, logger) => {
26
+ await device.getEndpoint(1).read('genBasic', [
27
+ 'manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
28
+
26
29
  for (const ID of [1, 2, 3, 4, 5]) {
27
30
  await reporting.bind(device.getEndpoint(ID), coordinatorEndpoint, ['genOnOff']);
28
31
  }
@@ -155,6 +155,10 @@ module.exports = [
155
155
  exposes: [e.action(['on', 'off', 'brightness_step_up', 'brightness_step_down', 'brightness_move_up', 'brightness_move_down',
156
156
  'brightness_stop', 'color_temperature_move'])],
157
157
  toZigbee: [],
158
+ configure: async (device, coordinatorEndpoint, logger) => {
159
+ device.powerSource = 'Battery';
160
+ device.save();
161
+ },
158
162
  },
159
163
  {
160
164
  zigbeeModel: ['tint-ColorTemperature', 'tint-ColorTemperature2'],
package/devices/niko.js CHANGED
@@ -219,4 +219,19 @@ module.exports = [
219
219
  exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']).withEndpoint('l2'),
220
220
  ],
221
221
  },
222
+ {
223
+ zigbeeModel: ['Connectable dimmer,3-200W,2-wire'],
224
+ model: '552-72201',
225
+ vendor: 'Niko',
226
+ description: 'Connectable dimmer',
227
+ fromZigbee: [fz.on_off, fz.brightness, fz.level_config, fz.command_move, fz.command_stop],
228
+ toZigbee: [tz.light_onoff_brightness, tz.level_config],
229
+ exposes: [e.light_brightness().withLevelConfig()],
230
+ configure: async (device, coordinatorEndpoint, logger) => {
231
+ const endpoint = device.getEndpoint(1);
232
+ await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
233
+ await reporting.onOff(endpoint);
234
+ await reporting.brightness(endpoint);
235
+ },
236
+ },
222
237
  ];
package/devices/owon.js CHANGED
@@ -4,7 +4,78 @@ const tz = require('../converters/toZigbee');
4
4
  const constants = require('../lib/constants');
5
5
  const reporting = require('../lib/reporting');
6
6
  const e = exposes.presets;
7
+ const ea = exposes.access;
7
8
 
9
+ const fzLocal = {
10
+ PC321_metering: {
11
+ cluster: 'seMetering',
12
+ type: ['attributeReport', 'readResponse'],
13
+ convert: (model, msg, publish, options, meta) => {
14
+ const payload = {};
15
+ if (msg.data.hasOwnProperty('owonL1Energy')) {
16
+ payload.energy_l1 = msg.data['owonL1Energy'][1] / 1000.0;
17
+ }
18
+ if (msg.data.hasOwnProperty('owonL2Energy')) {
19
+ payload.energy_l2 = msg.data['owonL2Energy'][1] / 1000.0;
20
+ }
21
+ if (msg.data.hasOwnProperty('owonL3Energy')) {
22
+ payload.energy_l3 = msg.data['owonL3Energy'][1] / 1000.0;
23
+ }
24
+ if (msg.data.hasOwnProperty('owonL1ReactiveEnergy')) {
25
+ payload.reactive_energy_l1 = msg.data['owonL1ReactiveEnergy'][1] / 1000.0;
26
+ }
27
+ if (msg.data.hasOwnProperty('owonL2ReactiveEnergy')) {
28
+ payload.reactive_energy_l2 = msg.data['owonL2ReactiveEnergy'][1] / 1000.0;
29
+ }
30
+ if (msg.data.hasOwnProperty('owonL3ReactiveEnergy')) {
31
+ payload.reactive_energy_l3 = msg.data['owonL3ReactiveEnergy'][1] / 1000.0;
32
+ }
33
+ if (msg.data.hasOwnProperty('owonL1PhasePower')) {
34
+ payload.power_l1 = msg.data['owonL1PhasePower'];
35
+ }
36
+ if (msg.data.hasOwnProperty('owonL2PhasePower')) {
37
+ payload.power_l2 = msg.data['owonL2PhasePower'];
38
+ }
39
+ if (msg.data.hasOwnProperty('owonL3PhasePower')) {
40
+ payload.power_l3 = msg.data['owonL3PhasePower'];
41
+ }
42
+ if (msg.data.hasOwnProperty('owonL1PhaseReactivePower')) {
43
+ payload.reactive_power_l1 = msg.data['owonL1PhaseReactivePower'];
44
+ }
45
+ if (msg.data.hasOwnProperty('owonL2PhaseReactivePower')) {
46
+ payload.reactive_power_l2 = msg.data['owonL2PhaseReactivePower'];
47
+ }
48
+ if (msg.data.hasOwnProperty('owonL3PhaseReactivePower')) {
49
+ payload.reactive_power_l3 = msg.data['owonL3PhaseReactivePower'];
50
+ }
51
+ if (msg.data.hasOwnProperty('owonL1PhaseVoltage')) {
52
+ payload.voltage_l1 = msg.data['owonL1PhaseVoltage'] / 10.0;
53
+ }
54
+ if (msg.data.hasOwnProperty('owonL2PhaseVoltage')) {
55
+ payload.voltage_l2 = msg.data['owonL2PhaseVoltage'] / 10.0;
56
+ }
57
+ if (msg.data.hasOwnProperty('owonL3PhaseVoltage')) {
58
+ payload.voltage_l3 = msg.data['owonL3PhaseVoltage'] / 10.0;
59
+ }
60
+ if (msg.data.hasOwnProperty('owonL1PhaseCurrent')) {
61
+ payload.current_l1 = msg.data['owonL1PhaseCurrent'] / 1000.0;
62
+ }
63
+ if (msg.data.hasOwnProperty('owonL2PhaseCurrent')) {
64
+ payload.current_l2 = msg.data['owonL2PhaseCurrent'] / 1000.0;
65
+ }
66
+ if (msg.data.hasOwnProperty('owonL3PhaseCurrent')) {
67
+ payload.current_l3 = msg.data['owonL3PhaseCurrent'] / 1000.0;
68
+ }
69
+ if (msg.data.hasOwnProperty('owonFrequency')) {
70
+ payload.frequency = msg.data['owonFrequency'];
71
+ }
72
+ if (msg.data.hasOwnProperty('owonReactiveEnergySum')) {
73
+ payload.reactive_energy_sum = msg.data['owonReactiveEnergySum'];
74
+ }
75
+ return payload;
76
+ },
77
+ },
78
+ };
8
79
  module.exports = [
9
80
  {
10
81
  zigbeeModel: ['WSP404'],
@@ -119,4 +190,41 @@ module.exports = [
119
190
  device.save();
120
191
  },
121
192
  },
193
+ {
194
+ zigbeeModel: ['PC321'],
195
+ model: 'PC321',
196
+ vendor: 'OWON',
197
+ description: '3-Phase clamp power meter',
198
+ fromZigbee: [fz.metering, fzLocal.PC321_metering],
199
+ toZigbee: [],
200
+ configure: async (device, coordinatorEndpoint, logger) => {
201
+ const endpoint = device.getEndpoint(1);
202
+ await reporting.bind(endpoint, coordinatorEndpoint, ['seMetering']);
203
+ await reporting.readMeteringMultiplierDivisor(endpoint);
204
+ if (device.powerSource === 'Unknown') {
205
+ device.powerSource = 'Mains (single phase)';
206
+ device.save();
207
+ }
208
+ },
209
+ exposes: [e.energy(),
210
+ exposes.numeric('voltage_l1', ea.STATE).withUnit('V').withDescription('Phase 1 voltage'),
211
+ exposes.numeric('voltage_l2', ea.STATE).withUnit('V').withDescription('Phase 2 voltage'),
212
+ exposes.numeric('voltage_l3', ea.STATE).withUnit('V').withDescription('Phase 3 voltage'),
213
+ exposes.numeric('current_l1', ea.STATE).withUnit('A').withDescription('Phase 1 current'),
214
+ exposes.numeric('current_l2', ea.STATE).withUnit('A').withDescription('Phase 2 current'),
215
+ exposes.numeric('current_l3', ea.STATE).withUnit('A').withDescription('Phase 3 current'),
216
+ exposes.numeric('energy_l1', ea.STATE).withUnit('kWh').withDescription('Phase 1 energy'),
217
+ exposes.numeric('energy_l2', ea.STATE).withUnit('kWh').withDescription('Phase 2 energy'),
218
+ exposes.numeric('energy_l3', ea.STATE).withUnit('kWh').withDescription('Phase 3 energy'),
219
+ exposes.numeric('reactive_energy_l1', ea.STATE).withUnit('kVArh').withDescription('Phase 1 reactive energy'),
220
+ exposes.numeric('reactive_energy_l2', ea.STATE).withUnit('kVArh').withDescription('Phase 2 reactive energy'),
221
+ exposes.numeric('reactive_energy_l3', ea.STATE).withUnit('kVArh').withDescription('Phase 3 reactive energy'),
222
+ exposes.numeric('power_l1', ea.STATE).withUnit('W').withDescription('Phase 1 power'),
223
+ exposes.numeric('power_l2', ea.STATE).withUnit('W').withDescription('Phase 2 power'),
224
+ exposes.numeric('power_l3', ea.STATE).withUnit('W').withDescription('Phase 3 power'),
225
+ exposes.numeric('reactive_power_l1', ea.STATE).withUnit('VAr').withDescription('Phase 1 reactive power'),
226
+ exposes.numeric('reactive_power_l2', ea.STATE).withUnit('VAr').withDescription('Phase 2 reactive power'),
227
+ exposes.numeric('reactive_power_l3', ea.STATE).withUnit('VAr').withDescription('Phase 3 reactive power'),
228
+ ],
229
+ },
122
230
  ];
@@ -1671,9 +1671,9 @@ module.exports = [
1671
1671
  zigbeeModel: ['929002376801'],
1672
1672
  model: '929002376801',
1673
1673
  vendor: 'Philips',
1674
- description: 'Hue Iris (generation 4)',
1674
+ description: 'Hue Iris kobber limited edition (generation 4)',
1675
1675
  meta: {turnsOffAtBrightness1: true},
1676
- extend: hueExtend.light_onoff_brightness_color(),
1676
+ extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
1677
1677
  ota: ota.zigbeeOTA,
1678
1678
  },
1679
1679
  {
@@ -237,7 +237,6 @@ module.exports = [
237
237
  await reporting.instantaneousDemand(endpoint);
238
238
  },
239
239
  exposes: [e.switch(), e.power(), e.energy()],
240
- ota: ota.zigbeeOTA,
241
240
  },
242
241
  {
243
242
  zigbeeModel: ['E1E-G7F'],
package/devices/tuya.js CHANGED
@@ -14,7 +14,7 @@ const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak',
14
14
  '_TZ3000_jvzvulen', '_TZ3000_mraovvmm', '_TZ3000_nfnmi125', '_TZ3000_ps3dmato', '_TZ3000_w0qqde0g', '_TZ3000_u5u4cakc',
15
15
  '_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_kx0pris5', '_TZ3000_amdymr7l', '_TZ3000_z1pnpsdo', '_TZ3000_ksw8qtmt',
16
16
  '_TZ3000_nzkqcvvs', '_TZ3000_1h2x4akh', '_TZ3000_9vo5icau', '_TZ3000_cehuw1lw', '_TZ3000_ko6v90pg', '_TZ3000_f1bapcit',
17
- '_TZ3000_cjrngdr3', '_TZ3000_zloso4jk', '_TZ3000_r6buo8ba'];
17
+ '_TZ3000_cjrngdr3', '_TZ3000_zloso4jk', '_TZ3000_r6buo8ba', '_TZ3000_iksasdbv', '_TZ3000_dd8wwzcy'];
18
18
 
19
19
  const tzLocal = {
20
20
  TS0504B_color: {
@@ -43,6 +43,20 @@ const tzLocal = {
43
43
  }
44
44
  },
45
45
  },
46
+ power_on_behavior: {
47
+ key: ['power_on_behavior'],
48
+ convertSet: async (entity, key, value, meta) => {
49
+ value = value.toLowerCase();
50
+ const lookup = {'off': 0, 'on': 1, 'previous': 2};
51
+ utils.validateValue(value, Object.keys(lookup));
52
+ const pState = lookup[value];
53
+ await entity.write('manuSpecificTuya_3', {'powerOnBehavior': pState}, {disableDefaultResponse: true});
54
+ return {state: {power_on_behavior: value}};
55
+ },
56
+ convertGet: async (entity, key, meta) => {
57
+ await entity.read('manuSpecificTuya_3', ['powerOnBehavior']);
58
+ },
59
+ },
46
60
  zb_sm_cover: {
47
61
  key: ['state', 'position', 'reverse_direction', 'top_limit', 'bottom_limit', 'favorite_position', 'goto_positon', 'report'],
48
62
  convertSet: async (entity, key, value, meta) => {
@@ -166,6 +180,19 @@ const fzLocal = {
166
180
  }
167
181
  },
168
182
  },
183
+ power_on_behavior: {
184
+ cluster: 'manuSpecificTuya_3',
185
+ type: ['attributeReport', 'readResponse'],
186
+ convert: (model, msg, publish, options, meta) => {
187
+ const attribute = 'powerOnBehavior';
188
+ const lookup = {0: 'off', 1: 'on', 2: 'previous'};
189
+
190
+ if (msg.data.hasOwnProperty(attribute)) {
191
+ const property = utils.postfixWithEndpointName('power_on_behavior', msg, model);
192
+ return {[property]: lookup[msg.data[attribute]]};
193
+ }
194
+ },
195
+ },
169
196
  zb_sm_cover: {
170
197
  cluster: 'manuSpecificTuya',
171
198
  type: ['commandDataReport', 'commandDataResponse'],
@@ -220,7 +247,7 @@ const fzLocal = {
220
247
  case 116: // report confirmation
221
248
  break;
222
249
  case 121: // running state
223
- result.running_state = {0: 'OPENING', 1: 'STOPPED', 2: 'CLOSING'}[value];
250
+ result.motor_state = {0: 'OPENING', 1: 'STOPPED', 2: 'CLOSING'}[value];
224
251
  result.running = (value !== 1) ? true : false;
225
252
  break;
226
253
  default: // Unknown code
@@ -523,6 +550,7 @@ module.exports = [
523
550
  {modelID: 'TS0202', manufacturerName: '_TZ3000_otvn3lne'},
524
551
  {modelID: 'TS0202', manufacturerName: '_TZ3000_tiwq83wk'},
525
552
  {modelID: 'TS0202', manufacturerName: '_TZ3000_ykwcwxmz'},
553
+ {modelID: 'TS0202', manufacturerName: '_TZ3000_hgu1dlak'},
526
554
  {modelID: 'WHD02', manufacturerName: '_TZ3000_hktqahrq'}],
527
555
  model: 'TS0202',
528
556
  vendor: 'TuYa',
@@ -688,13 +716,7 @@ module.exports = [
688
716
  const endpoint = device.getEndpoint(1);
689
717
  await reporting.bind(endpoint, coordinatorEndpoint, ['genBasic']);
690
718
  },
691
- exposes: (device, options) => {
692
- if (device && device.manufacturerName === '_TZE200_pisltm67') {
693
- return [e.illuminance_lux(), e.linkquality()];
694
- } else {
695
- return [e.battery(), e.illuminance_lux(), e.battery_low(), e.linkquality()];
696
- }
697
- },
719
+ exposes: [e.battery(), e.illuminance_lux(), e.battery_low(), e.linkquality()],
698
720
  },
699
721
  {
700
722
  zigbeeModel: ['TS130F'],
@@ -1931,9 +1953,11 @@ module.exports = [
1931
1953
  model: 'TS0004',
1932
1954
  vendor: 'TuYa',
1933
1955
  description: 'Smart light switch - 4 gang with neutral wire',
1934
- extend: extend.switch(),
1935
- exposes: [e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'), e.switch().withEndpoint('l3'),
1936
- e.switch().withEndpoint('l4')],
1956
+ fromZigbee: [fz.on_off, fzLocal.power_on_behavior, fz.ignore_basic_report],
1957
+ toZigbee: [tz.on_off, tzLocal.power_on_behavior],
1958
+ exposes: [e.switch().withEndpoint('l1'), e.power_on_behavior().withEndpoint('l1'), e.switch().withEndpoint('l2'),
1959
+ e.power_on_behavior().withEndpoint('l2'), e.switch().withEndpoint('l3'), e.power_on_behavior().withEndpoint('l3'),
1960
+ e.switch().withEndpoint('l4'), e.power_on_behavior().withEndpoint('l4')],
1937
1961
  endpoint: (device) => {
1938
1962
  return {'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4};
1939
1963
  },
@@ -2568,7 +2592,7 @@ module.exports = [
2568
2592
  exposes: [
2569
2593
  e.cover_position().setAccess('position', ea.STATE_SET),
2570
2594
  exposes.enum('goto_positon', ea.SET, ['25', '50', '75', 'FAVORITE']),
2571
- exposes.enum('running_state', ea.STATE, ['OPENING', 'CLOSING', 'STOPPED']),
2595
+ exposes.enum('motor_state', ea.STATE, ['OPENING', 'CLOSING', 'STOPPED']),
2572
2596
  exposes.numeric('active_power', ea.STATE).withDescription('Active power').withUnit('mWt'),
2573
2597
  exposes.numeric('cycle_count', ea.STATE).withDescription('Cycle count'),
2574
2598
  exposes.numeric('cycle_time', ea.STATE).withDescription('Cycle time').withUnit('ms'),
package/devices/xiaomi.js CHANGED
@@ -1538,14 +1538,14 @@ module.exports = [
1538
1538
  model: 'GZCGQ01LM',
1539
1539
  vendor: 'Xiaomi',
1540
1540
  description: 'MiJia light intensity sensor',
1541
- fromZigbee: [fz.battery, fz.illuminance],
1541
+ fromZigbee: [fz.battery, fz.illuminance, fz.aqara_opple],
1542
1542
  toZigbee: [],
1543
1543
  meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
1544
1544
  configure: async (device, coordinatorEndpoint, logger) => {
1545
1545
  const endpoint = device.getEndpoint(1);
1546
- await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'msIlluminanceMeasurement']);
1547
- await reporting.batteryVoltage(endpoint);
1546
+ await reporting.bind(endpoint, coordinatorEndpoint, ['msIlluminanceMeasurement']);
1548
1547
  await reporting.illuminance(endpoint, {min: 15, max: constants.repInterval.HOUR, change: 500});
1548
+ await endpoint.read('genPowerCfg', ['batteryVoltage']);
1549
1549
  },
1550
1550
  exposes: [e.battery(), e.battery_voltage(), e.illuminance(), e.illuminance_lux()],
1551
1551
  },
@@ -144,6 +144,9 @@ module.exports = [
144
144
  },
145
145
  meta: {multiEndpoint: true},
146
146
  configure: async (device, coordinatorEndpoint, logger) => {
147
+ await device.getEndpoint(1).read('genBasic', [
148
+ 'manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
149
+
147
150
  await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
148
151
  await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
149
152
  await reporting.onOff(device.getEndpoint(1));
@@ -189,6 +192,30 @@ module.exports = [
189
192
  toZigbee: [tz.tuya_cover_control, tz.tuya_cover_options, tz.tuya_data_point_test],
190
193
  exposes: [e.cover_position().setAccess('position', ea.STATE_SET)],
191
194
  },
195
+ {
196
+ fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_1n2kyphz'}],
197
+ model: 'TB26-4',
198
+ vendor: 'Zemismart',
199
+ description: '4-gang smart wall switch',
200
+ exposes: [e.switch().withEndpoint('l1').setAccess('state', ea.STATE_SET),
201
+ e.switch().withEndpoint('l2').setAccess('state', ea.STATE_SET),
202
+ e.switch().withEndpoint('l3').setAccess('state', ea.STATE_SET),
203
+ e.switch().withEndpoint('l4').setAccess('state', ea.STATE_SET)],
204
+ fromZigbee: [fz.ignore_basic_report, fz.tuya_switch],
205
+ toZigbee: [tz.tuya_switch_state],
206
+ meta: {multiEndpoint: true},
207
+ endpoint: (device) => {
208
+ return {'l1': 1, 'l2': 1, 'l3': 1, 'l4': 1};
209
+ },
210
+ configure: async (device, coordinatorEndpoint, logger) => {
211
+ await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
212
+ if (device.getEndpoint(2)) await reporting.bind(device.getEndpoint(2), coordinatorEndpoint, ['genOnOff']);
213
+ if (device.getEndpoint(3)) await reporting.bind(device.getEndpoint(3), coordinatorEndpoint, ['genOnOff']);
214
+ if (device.getEndpoint(4)) await reporting.bind(device.getEndpoint(4), coordinatorEndpoint, ['genOnOff']);
215
+ device.powerSource = 'Mains (single phase)';
216
+ device.save();
217
+ },
218
+ },
192
219
  {
193
220
  fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_9mahtqtg'}],
194
221
  model: 'TB26-6',
package/devices/zen.js CHANGED
@@ -15,7 +15,8 @@ module.exports = [
15
15
  tz.thermostat_unoccupied_heating_setpoint, tz.thermostat_setpoint_raise_lower, tz.thermostat_running_state,
16
16
  tz.thermostat_remote_sensing, tz.thermostat_control_sequence_of_operation, tz.thermostat_system_mode,
17
17
  tz.thermostat_weekly_schedule, tz.thermostat_clear_weekly_schedule, tz.thermostat_relay_status_log],
18
- exposes: [exposes.climate().withSetpoint('occupied_heating_setpoint', 10, 30, 0.5).withLocalTemperature()
18
+ exposes: [exposes.climate().withSetpoint('occupied_heating_setpoint', 10, 30, 0.5)
19
+ .withSetpoint('occupied_cooling_setpoint', 10, 31, 0.5).withLocalTemperature()
19
20
  .withSystemMode(['off', 'auto', 'heat', 'cool']).withRunningState(['idle', 'heat', 'cool'])
20
21
  .withLocalTemperatureCalibration(-30, 30, 0.1).withPiHeatingDemand()],
21
22
  configure: async (device, coordinatorEndpoint, logger) => {
@@ -18,8 +18,8 @@ async function getImageMeta(current, logger, device) {
18
18
  .sort((a, b) => {
19
19
  const aRadix = a.version.match(/[A-F]/) ? 16 : 10;
20
20
  const bRadix = b.version.match(/[A-F]/) ? 16 : 10;
21
- const aVersion = parseInt(a.version.replace(/\./g, ''), aRadix);
22
- const bVersion = parseInt(b.version.replace(/\./g, ''), bRadix);
21
+ const aVersion = parseFloat(a.version, aRadix);
22
+ const bVersion = parseFloat(b.version, bRadix);
23
23
  // doesn't matter which order they are in
24
24
  if (aVersion < bVersion) {
25
25
  return -1;
@@ -37,7 +37,7 @@ async function getImageMeta(current, logger, device) {
37
37
  }
38
38
  // version in the firmare removes the zero padding and support hex versioning
39
39
  return {
40
- fileVersion: parseInt(image.version, image.version.match(/[A-F]/) ? 16 : 10),
40
+ fileVersion: parseFloat(image.version, image.version.match(/[A-F]/) ? 16 : 10),
41
41
  url: image.firmware,
42
42
  };
43
43
  }
package/lib/xiaomi.js CHANGED
@@ -158,7 +158,7 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
158
158
  }
159
159
  break;
160
160
  case '3':
161
- if (['WXCJKG11LM', 'WXCJKG12LM', 'WXCJKG13LM', 'MCCGQ14LM'].includes(model.model)) {
161
+ if (['WXCJKG11LM', 'WXCJKG12LM', 'WXCJKG13LM', 'MCCGQ14LM', 'GZCGQ01LM'].includes(model.model)) {
162
162
  // The temperature value is constant 25 °C and does not change, so we ignore it
163
163
  // https://github.com/Koenkk/zigbee2mqtt/issues/11126
164
164
  // https://github.com/Koenkk/zigbee-herdsman-converters/pull/3585
@@ -225,6 +225,9 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
225
225
  // payload.water_leak = value === 1;
226
226
  } else if (['JTYJ-GD-01LM/BW'].includes(model.model)) {
227
227
  payload.smoke_density = value;
228
+ } else if (['GZCGQ01LM'].includes(model.model)) {
229
+ // DEPRECATED: change illuminance_lux -> illuminance
230
+ payload.illuminance_lux = calibrateAndPrecisionRoundOptions(value, options, 'illuminance_lux');
228
231
  } else {
229
232
  payload.state = value === 1 ? 'ON' : 'OFF';
230
233
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zigbee-herdsman-converters",
3
- "version": "14.0.537",
3
+ "version": "14.0.540",
4
4
  "description": "Collection of device converters to be used with zigbee-herdsman",
5
5
  "main": "index.js",
6
6
  "files": [