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.
- package/converters/fromZigbee.js +2 -4
- package/devices/custom_devices_diy.js +36 -7
- package/devices/danalock.js +4 -3
- package/devices/heiman.js +9 -0
- package/devices/ikea.js +2 -2
- package/devices/lellki.js +3 -0
- package/devices/m/303/274ller_licht.js +4 -0
- package/devices/niko.js +15 -0
- package/devices/owon.js +108 -0
- package/devices/philips.js +2 -2
- package/devices/sengled.js +0 -1
- package/devices/tuya.js +37 -13
- package/devices/xiaomi.js +3 -3
- package/devices/zemismart.js +27 -0
- package/devices/zen.js +2 -1
- package/lib/ota/inovelli.js +3 -3
- package/lib/xiaomi.js +4 -1
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -2257,9 +2257,7 @@ const converters = {
|
|
|
2257
2257
|
const value = tuya.getDataValue(dpValue);
|
|
2258
2258
|
|
|
2259
2259
|
switch (dp) {
|
|
2260
|
-
case tuya.dataPoints.coverPosition:
|
|
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
|
|
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'],
|
package/devices/danalock.js
CHANGED
|
@@ -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
|
];
|
package/devices/philips.js
CHANGED
|
@@ -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.
|
|
1676
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
1677
1677
|
ota: ota.zigbeeOTA,
|
|
1678
1678
|
},
|
|
1679
1679
|
{
|
package/devices/sengled.js
CHANGED
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.
|
|
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: (
|
|
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
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
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('
|
|
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, ['
|
|
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
|
},
|
package/devices/zemismart.js
CHANGED
|
@@ -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)
|
|
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) => {
|
package/lib/ota/inovelli.js
CHANGED
|
@@ -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 =
|
|
22
|
-
const bVersion =
|
|
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:
|
|
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
|
}
|