zigbee-herdsman-converters 14.0.442 → 14.0.443
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 +4 -4
- package/devices/aurora_lighting.js +1 -1
- package/devices/sengled.js +40 -5
- package/devices/smartwings.js +24 -0
- package/devices/tuya.js +8 -5
- package/lib/exposes.js +2 -1
- package/lib/utils.js +17 -12
- package/npm-shrinkwrap.json +1 -1
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -423,11 +423,11 @@ const converters = {
|
|
|
423
423
|
// This is for occupancy sensor that send motion start AND stop messages
|
|
424
424
|
cluster: 'msOccupancySensing',
|
|
425
425
|
type: ['attributeReport', 'readResponse'],
|
|
426
|
-
options: [exposes.options.
|
|
426
|
+
options: [exposes.options.no_occupancy_since_false()],
|
|
427
427
|
convert: (model, msg, publish, options, meta) => {
|
|
428
428
|
if (msg.data.hasOwnProperty('occupancy')) {
|
|
429
429
|
const payload = {occupancy: (msg.data.occupancy % 2) > 0};
|
|
430
|
-
utils.noOccupancySince(msg.endpoint, payload, options, publish);
|
|
430
|
+
utils.noOccupancySince(msg.endpoint, payload, options, publish, payload.occupancy ? 'stop' : 'start');
|
|
431
431
|
return payload;
|
|
432
432
|
}
|
|
433
433
|
},
|
|
@@ -438,7 +438,7 @@ const converters = {
|
|
|
438
438
|
// Therefore we need to publish the no_motion detected by ourselves.
|
|
439
439
|
cluster: 'msOccupancySensing',
|
|
440
440
|
type: ['attributeReport', 'readResponse'],
|
|
441
|
-
options: [exposes.options.occupancy_timeout(), exposes.options.
|
|
441
|
+
options: [exposes.options.occupancy_timeout(), exposes.options.no_occupancy_since_true()],
|
|
442
442
|
convert: (model, msg, publish, options, meta) => {
|
|
443
443
|
if (msg.data.occupancy !== 1) {
|
|
444
444
|
// In case of 0 no occupancy is reported.
|
|
@@ -463,7 +463,7 @@ const converters = {
|
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
const payload = {occupancy: true};
|
|
466
|
-
utils.noOccupancySince(msg.endpoint, payload, options, publish);
|
|
466
|
+
utils.noOccupancySince(msg.endpoint, payload, options, publish, 'start');
|
|
467
467
|
return payload;
|
|
468
468
|
},
|
|
469
469
|
},
|
|
@@ -13,7 +13,7 @@ const tzLocal = {
|
|
|
13
13
|
convertSet: async (entity, key, value, meta) => {
|
|
14
14
|
const state = value.toLowerCase();
|
|
15
15
|
utils.validateValue(state, ['toggle', 'off', 'on']);
|
|
16
|
-
const endpoint = meta.device.getEndpoint(3);
|
|
16
|
+
const endpoint = meta.mapped.model === 'AU-A1ZBDSS' ? meta.device.getEndpoint(3) : meta.device.getEndpoint(2);
|
|
17
17
|
await endpoint.command('genOnOff', state, {});
|
|
18
18
|
return {state: {backlight_led: state.toUpperCase()}};
|
|
19
19
|
},
|
package/devices/sengled.js
CHANGED
|
@@ -14,7 +14,8 @@ module.exports = [
|
|
|
14
14
|
description: 'Flood light with motion sensor light outdoor',
|
|
15
15
|
fromZigbee: extend.light_onoff_brightness().fromZigbee.concat([fz.ias_occupancy_alarm_1]),
|
|
16
16
|
toZigbee: extend.light_onoff_brightness().toZigbee,
|
|
17
|
-
exposes:
|
|
17
|
+
exposes: extend.light_onoff_brightness().exposes.concat([e.occupancy()]),
|
|
18
|
+
ota: ota.zigbeeOTA,
|
|
18
19
|
},
|
|
19
20
|
{
|
|
20
21
|
zigbeeModel: ['E21-N13A'],
|
|
@@ -29,7 +30,22 @@ module.exports = [
|
|
|
29
30
|
model: 'E21-N1EA',
|
|
30
31
|
vendor: 'Sengled',
|
|
31
32
|
description: 'Smart LED multicolor A19 bulb',
|
|
32
|
-
|
|
33
|
+
fromZigbee: extend.light_onoff_brightness_colortemp_color({colorTempRange: [154, 500]}).fromZigbee.concat([fz.metering]),
|
|
34
|
+
toZigbee: extend.light_onoff_brightness_colortemp_color({colorTempRange: [154, 500]}).toZigbee,
|
|
35
|
+
exposes: extend.light_onoff_brightness_colortemp_color({colorTempRange: [154, 500]}).exposes.concat([e.power(), e.energy()]),
|
|
36
|
+
ota: ota.zigbeeOTA,
|
|
37
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
38
|
+
await extend.light_onoff_brightness_colortemp_color({colorTempRange: [154, 500]})
|
|
39
|
+
.configure(device, coordinatorEndpoint, logger);
|
|
40
|
+
device.powerSource = 'Mains (single phase)';
|
|
41
|
+
device.save();
|
|
42
|
+
|
|
43
|
+
const endpoint = device.getEndpoint(1);
|
|
44
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'seMetering']);
|
|
45
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
46
|
+
await reporting.currentSummDelivered(endpoint);
|
|
47
|
+
await reporting.instantaneousDemand(endpoint);
|
|
48
|
+
},
|
|
33
49
|
},
|
|
34
50
|
{
|
|
35
51
|
zigbeeModel: ['E12-N1E'],
|
|
@@ -62,6 +78,7 @@ module.exports = [
|
|
|
62
78
|
description: 'Element classic (A19)',
|
|
63
79
|
fromZigbee: extend.light_onoff_brightness().fromZigbee.concat([fz.metering]),
|
|
64
80
|
toZigbee: extend.light_onoff_brightness().toZigbee,
|
|
81
|
+
ota: ota.zigbeeOTA,
|
|
65
82
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
66
83
|
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
67
84
|
device.powerSource = 'Mains (single phase)';
|
|
@@ -73,7 +90,7 @@ module.exports = [
|
|
|
73
90
|
await reporting.currentSummDelivered(endpoint);
|
|
74
91
|
await reporting.instantaneousDemand(endpoint);
|
|
75
92
|
},
|
|
76
|
-
exposes: [e.power(), e.energy()
|
|
93
|
+
exposes: extend.light_onoff_brightness().exposes.concat([e.power(), e.energy()]),
|
|
77
94
|
},
|
|
78
95
|
{
|
|
79
96
|
zigbeeModel: ['E11-G23', 'E11-G33'],
|
|
@@ -149,8 +166,22 @@ module.exports = [
|
|
|
149
166
|
model: 'E1F-N5E',
|
|
150
167
|
vendor: 'Sengled',
|
|
151
168
|
description: 'Element color plus E12',
|
|
152
|
-
|
|
169
|
+
fromZigbee: extend.light_onoff_brightness_colortemp_color({colorTempRange: [154, 500]}).fromZigbee.concat([fz.metering]),
|
|
170
|
+
toZigbee: extend.light_onoff_brightness_colortemp_color({colorTempRange: [154, 500]}).toZigbee,
|
|
171
|
+
exposes: extend.light_onoff_brightness_colortemp_color({colorTempRange: [154, 500]}).exposes.concat([e.power(), e.energy()]),
|
|
153
172
|
ota: ota.zigbeeOTA,
|
|
173
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
174
|
+
await extend.light_onoff_brightness_colortemp_color({colorTempRange: [154, 500]})
|
|
175
|
+
.configure(device, coordinatorEndpoint, logger);
|
|
176
|
+
device.powerSource = 'Mains (single phase)';
|
|
177
|
+
device.save();
|
|
178
|
+
|
|
179
|
+
const endpoint = device.getEndpoint(1);
|
|
180
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'seMetering']);
|
|
181
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
182
|
+
await reporting.currentSummDelivered(endpoint);
|
|
183
|
+
await reporting.instantaneousDemand(endpoint);
|
|
184
|
+
},
|
|
154
185
|
},
|
|
155
186
|
{
|
|
156
187
|
zigbeeModel: ['E12-N14'],
|
|
@@ -206,15 +237,17 @@ module.exports = [
|
|
|
206
237
|
await reporting.instantaneousDemand(endpoint);
|
|
207
238
|
},
|
|
208
239
|
exposes: [e.switch(), e.power(), e.energy()],
|
|
240
|
+
ota: ota.zigbeeOTA,
|
|
209
241
|
},
|
|
210
242
|
{
|
|
211
243
|
zigbeeModel: ['E1E-G7F'],
|
|
212
244
|
model: 'E1E-G7F',
|
|
213
245
|
vendor: 'Sengled',
|
|
214
|
-
description: 'Smart switch
|
|
246
|
+
description: 'Smart switch',
|
|
215
247
|
fromZigbee: [fz.E1E_G7F_action],
|
|
216
248
|
exposes: [e.action(['on', 'up', 'down', 'off', 'on_double', 'on_long', 'off_double', 'off_long'])],
|
|
217
249
|
toZigbee: [],
|
|
250
|
+
ota: ota.zigbeeOTA,
|
|
218
251
|
},
|
|
219
252
|
{
|
|
220
253
|
zigbeeModel: ['E11-N1G'],
|
|
@@ -222,6 +255,7 @@ module.exports = [
|
|
|
222
255
|
vendor: 'Sengled',
|
|
223
256
|
description: 'Vintage LED edison bulb (ST19)',
|
|
224
257
|
extend: extend.light_onoff_brightness(),
|
|
258
|
+
ota: ota.zigbeeOTA,
|
|
225
259
|
},
|
|
226
260
|
{
|
|
227
261
|
zigbeeModel: ['E1F-N9G'],
|
|
@@ -229,5 +263,6 @@ module.exports = [
|
|
|
229
263
|
vendor: 'Sengled',
|
|
230
264
|
description: 'Smart LED filament candle (E12)',
|
|
231
265
|
extend: extend.light_onoff_brightness(),
|
|
266
|
+
ota: ota.zigbeeOTA,
|
|
232
267
|
},
|
|
233
268
|
];
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const exposes = require('../lib/exposes');
|
|
2
|
+
const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
|
|
3
|
+
const tz = require('../converters/toZigbee');
|
|
4
|
+
const reporting = require('../lib/reporting');
|
|
5
|
+
const e = exposes.presets;
|
|
6
|
+
|
|
7
|
+
module.exports = [
|
|
8
|
+
{
|
|
9
|
+
zigbeeModel: ['WM25/L-Z'],
|
|
10
|
+
model: 'WM25L-Z',
|
|
11
|
+
vendor: 'Smartwings',
|
|
12
|
+
description: 'Roller shade',
|
|
13
|
+
fromZigbee: [fz.cover_position_tilt, fz.battery],
|
|
14
|
+
toZigbee: [tz.cover_state, tz.cover_position_tilt],
|
|
15
|
+
meta: {battery: {dontDividePercentage: true}},
|
|
16
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
17
|
+
const endpoint = device.getEndpoint(1);
|
|
18
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'closuresWindowCovering']);
|
|
19
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
20
|
+
await reporting.currentPositionLiftPercentage(endpoint);
|
|
21
|
+
},
|
|
22
|
+
exposes: [e.cover_position(), e.battery()],
|
|
23
|
+
},
|
|
24
|
+
];
|
package/devices/tuya.js
CHANGED
|
@@ -12,7 +12,7 @@ const utils = require('../lib/utils');
|
|
|
12
12
|
|
|
13
13
|
const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak', '_TZ3000_ew3ldmgx', '_TZ3000_gjnozsaz',
|
|
14
14
|
'_TZ3000_jvzvulen', '_TZ3000_mraovvmm', '_TZ3000_nfnmi125', '_TZ3000_ps3dmato', '_TZ3000_w0qqde0g', '_TZ3000_u5u4cakc',
|
|
15
|
-
'_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_kx0pris5'];
|
|
15
|
+
'_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_kx0pris5', '_TZ3000_amdymr7l'];
|
|
16
16
|
|
|
17
17
|
const tzLocal = {
|
|
18
18
|
TS0504B_color: {
|
|
@@ -49,7 +49,7 @@ const fzLocal = {
|
|
|
49
49
|
type: ['attributeReport', 'readResponse'],
|
|
50
50
|
convert: (model, msg, publish, options, meta) => {
|
|
51
51
|
// https://github.com/Koenkk/zigbee2mqtt/issues/11470
|
|
52
|
-
if (msg.data.batteryVoltage < 30) return;
|
|
52
|
+
if (msg.data.batteryPercentageRemaining == 200 && msg.data.batteryVoltage < 30) return;
|
|
53
53
|
return fz.battery.convert(model, msg, publish, options, meta);
|
|
54
54
|
},
|
|
55
55
|
},
|
|
@@ -61,9 +61,9 @@ module.exports = [
|
|
|
61
61
|
model: 'TS0204',
|
|
62
62
|
vendor: 'TuYa',
|
|
63
63
|
description: 'Gas sensor',
|
|
64
|
-
fromZigbee: [fz.ias_gas_alarm_1, fz.
|
|
64
|
+
fromZigbee: [fz.ias_gas_alarm_1, fz.ignore_basic_report],
|
|
65
65
|
toZigbee: [],
|
|
66
|
-
exposes: [e.gas(), e.
|
|
66
|
+
exposes: [e.gas(), e.tamper()],
|
|
67
67
|
},
|
|
68
68
|
{
|
|
69
69
|
zigbeeModel: ['TS0205'],
|
|
@@ -108,7 +108,8 @@ module.exports = [
|
|
|
108
108
|
},
|
|
109
109
|
},
|
|
110
110
|
{
|
|
111
|
-
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_bq5c8xfe'}
|
|
111
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_bq5c8xfe'},
|
|
112
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_bjawzodf'}],
|
|
112
113
|
model: 'TS0601_temperature_humidity_sensor',
|
|
113
114
|
vendor: 'TuYa',
|
|
114
115
|
description: 'Temperature & humidity sensor',
|
|
@@ -166,6 +167,7 @@ module.exports = [
|
|
|
166
167
|
fingerprint: [{modelID: 'TS0001', manufacturerName: '_TZ3000_hktqahrq'}, {manufacturerName: '_TZ3000_hktqahrq'},
|
|
167
168
|
{manufacturerName: '_TZ3000_q6a3tepg'}, {modelID: 'TS000F', manufacturerName: '_TZ3000_m9af2l6g'},
|
|
168
169
|
{modelID: 'TS0001', manufacturerName: '_TZ3000_npzfdcof'},
|
|
170
|
+
{modelID: 'TS0001', manufacturerName: '_TZ3000_5ng23zjs'},
|
|
169
171
|
{modelID: 'TS0001', manufacturerName: '_TZ3000_v7gnj3ad'}],
|
|
170
172
|
model: 'WHD02',
|
|
171
173
|
vendor: 'TuYa',
|
|
@@ -227,6 +229,7 @@ module.exports = [
|
|
|
227
229
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_wslkvrau'},
|
|
228
230
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_0rn9qhnu'},
|
|
229
231
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_bicjqpg4'},
|
|
232
|
+
{modelID: 'TS0505B', manufacturerName: '_TZ3210_jmiuubkz'},
|
|
230
233
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_cmaky9gq'},
|
|
231
234
|
{modelID: 'TS0505B', manufacturerName: '_TZ3000_tza2vjxx'},
|
|
232
235
|
{modelID: 'TS0505B', manufacturerName: '_TZ3210_k1pe6ibm'},
|
package/lib/exposes.js
CHANGED
|
@@ -492,7 +492,8 @@ module.exports = {
|
|
|
492
492
|
.withDescription(`Simulate a brightness value. If this device provides a brightness_move_up or brightness_move_down action it is possible to specify the update interval and delta.${extraNote}`)
|
|
493
493
|
.withFeature(new Numeric('delta', access.SET).withValueMin(0).withDescription('Delta per interval, 20 by default'))
|
|
494
494
|
.withFeature(new Numeric('interval', access.SET).withValueMin(0).withUnit('ms').withDescription('Interval duration')),
|
|
495
|
-
|
|
495
|
+
no_occupancy_since_true: () => new List(`no_occupancy_since`, access.SET).withDescription('Sends a message the last time occupancy (occupancy: true) was detected. When setting this for example to [10, 60] a `{"no_occupancy_since": 10}` will be send after 10 seconds and a `{"no_occupancy_since": 60}` after 60 seconds.'),
|
|
496
|
+
no_occupancy_since_false: () => new List(`no_occupancy_since`, access.SET).withDescription('Sends a message after the last time no occupancy (occupancy: false) was detected. When setting this for example to [10, 60] a `{"no_occupancy_since": 10}` will be send after 10 seconds and a `{"no_occupancy_since": 60}` after 60 seconds.'),
|
|
496
497
|
presence_timeout: () => new Numeric(`presence_timeout`).withValueMin(0).withDescription('Time in seconds after which presence is cleared after detecting it (default 100 seconds).'),
|
|
497
498
|
no_position_support: () => new Binary('no_position_support', access.SET, true, false).withDescription('Set to true when your device only reports position 0, 100 and 50 (in this case your device has an older firmware) (default false).'),
|
|
498
499
|
transition: () => new Numeric(`transition`, access.SET).withValueMin(0).withDescription('Controls the transition time (in seconds) of on/off, brightness, color temperature (if applicable) and color (if applicable) changes. Defaults to `0` (no transition).'),
|
package/lib/utils.js
CHANGED
|
@@ -397,18 +397,23 @@ function extendDevice(deviceConfigs, modelName, adjustments) {
|
|
|
397
397
|
return {...baseDevice, ...adjustments};
|
|
398
398
|
}
|
|
399
399
|
|
|
400
|
-
function noOccupancySince(endpoint, newPayload, options, publish) {
|
|
401
|
-
if (options && options.no_occupancy_since
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
400
|
+
function noOccupancySince(endpoint, newPayload, options, publish, action) {
|
|
401
|
+
if (options && options.no_occupancy_since) {
|
|
402
|
+
if (action == 'start') {
|
|
403
|
+
globalStore.getValue(endpoint, 'no_occupancy_since_timers', []).forEach((t) => clearTimeout(t));
|
|
404
|
+
globalStore.putValue(endpoint, 'no_occupancy_since_timers', []);
|
|
405
|
+
|
|
406
|
+
newPayload.no_occupancy_since = 0;
|
|
407
|
+
options.no_occupancy_since.forEach((since) => {
|
|
408
|
+
const timer = setTimeout(() => {
|
|
409
|
+
publish({no_occupancy_since: since});
|
|
410
|
+
}, since * 1000);
|
|
411
|
+
globalStore.getValue(endpoint, 'no_occupancy_since_timers').push(timer);
|
|
412
|
+
});
|
|
413
|
+
} else if (action === 'stop') {
|
|
414
|
+
globalStore.getValue(endpoint, 'no_occupancy_since_timers', []).forEach((t) => clearTimeout(t));
|
|
415
|
+
globalStore.putValue(endpoint, 'no_occupancy_since_timers', []);
|
|
416
|
+
}
|
|
412
417
|
}
|
|
413
418
|
}
|
|
414
419
|
|
package/npm-shrinkwrap.json
CHANGED