zigbee-herdsman-converters 14.0.467 → 14.0.468
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 +9 -3
- package/converters/toZigbee.js +22 -9
- package/devices/datek.js +16 -10
- package/devices/legrand.js +18 -0
- package/devices/moes.js +1 -0
- package/devices/niko.js +67 -4
- package/devices/philips.js +9 -0
- package/devices/spotmau.js +3 -0
- package/devices/tuya.js +5 -1
- package/devices/xiaomi.js +38 -4
- package/lib/xiaomi.js +68 -16
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -3820,7 +3820,12 @@ const converters = {
|
|
|
3820
3820
|
return {deadzone_temperature: value};
|
|
3821
3821
|
case tuya.dataPoints.moesLocalTemp:
|
|
3822
3822
|
temperature = value & 1<<15 ? value - (1<<16) + 1 : value;
|
|
3823
|
-
|
|
3823
|
+
if (meta.device.manufacturerName === '_TZE200_ye5jkfsb') {
|
|
3824
|
+
// https://github.com/Koenkk/zigbee2mqtt/issues/11980
|
|
3825
|
+
temperature = temperature / 10;
|
|
3826
|
+
}
|
|
3827
|
+
|
|
3828
|
+
return {local_temperature: parseFloat(temperature.toFixed(1))};
|
|
3824
3829
|
case tuya.dataPoints.moesTempCalibration:
|
|
3825
3830
|
temperature = value;
|
|
3826
3831
|
// for negative values produce complimentary hex (equivalent to negative values)
|
|
@@ -4193,6 +4198,7 @@ const converters = {
|
|
|
4193
4198
|
const dpValue = tuya.firstDpValue(msg, meta, 'tuya_air_quality');
|
|
4194
4199
|
const dp = dpValue.dp;
|
|
4195
4200
|
const value = tuya.getDataValue(dpValue);
|
|
4201
|
+
const swapPM25CO2 = ['_TZE200_ryfmq5rl', '_TZE200_dwcarsat'];
|
|
4196
4202
|
switch (dp) {
|
|
4197
4203
|
case tuya.dataPoints.tuyaSabTemp:
|
|
4198
4204
|
return {temperature: calibrateAndPrecisionRoundOptions(value / 10, options, 'temperature')};
|
|
@@ -4200,14 +4206,14 @@ const converters = {
|
|
|
4200
4206
|
return {humidity: calibrateAndPrecisionRoundOptions(value / 10, options, 'humidity')};
|
|
4201
4207
|
// DP22: Smart Air Box: Formaldehyd, Smart Air Housekeeper: co2
|
|
4202
4208
|
case tuya.dataPoints.tuyaSabFormaldehyd:
|
|
4203
|
-
if (meta.device.manufacturerName
|
|
4209
|
+
if (swapPM25CO2.includes(meta.device.manufacturerName)) {
|
|
4204
4210
|
return {co2: calibrateAndPrecisionRoundOptions(value, options, 'co2')};
|
|
4205
4211
|
} else {
|
|
4206
4212
|
return {formaldehyd: calibrateAndPrecisionRoundOptions(value, options, 'formaldehyd')};
|
|
4207
4213
|
}
|
|
4208
4214
|
// DP2: Smart Air Box: co2, Smart Air Housekeeper: MP25
|
|
4209
4215
|
case tuya.dataPoints.tuyaSabCO2:
|
|
4210
|
-
if (meta.device.manufacturerName
|
|
4216
|
+
if (swapPM25CO2.includes(meta.device.manufacturerName)) {
|
|
4211
4217
|
return {pm25: calibrateAndPrecisionRoundOptions(value, options, 'pm25')};
|
|
4212
4218
|
} else {
|
|
4213
4219
|
return {co2: calibrateAndPrecisionRoundOptions(value, options, 'co2')};
|
package/converters/toZigbee.js
CHANGED
|
@@ -2584,14 +2584,14 @@ const converters = {
|
|
|
2584
2584
|
await entity.write('ssIasZone', {0xFFF1: {value: 0x03010000, type: 0x23}}, options);
|
|
2585
2585
|
},
|
|
2586
2586
|
},
|
|
2587
|
-
|
|
2588
|
-
key: ['gas'],
|
|
2587
|
+
aqara_alarm: {
|
|
2588
|
+
key: ['gas', 'smoke'],
|
|
2589
2589
|
convertGet: async (entity, key, meta) => {
|
|
2590
2590
|
await entity.read('aqaraOpple', [0x013a], manufacturerOptions.xiaomi);
|
|
2591
2591
|
},
|
|
2592
2592
|
},
|
|
2593
|
-
|
|
2594
|
-
key: ['gas_density'],
|
|
2593
|
+
aqara_density: {
|
|
2594
|
+
key: ['gas_density', 'smoke_density'],
|
|
2595
2595
|
convertGet: async (entity, key, meta) => {
|
|
2596
2596
|
await entity.read('aqaraOpple', [0x013b], manufacturerOptions.xiaomi);
|
|
2597
2597
|
},
|
|
@@ -2608,26 +2608,39 @@ const converters = {
|
|
|
2608
2608
|
await entity.read('aqaraOpple', [0x010c], manufacturerOptions.xiaomi);
|
|
2609
2609
|
},
|
|
2610
2610
|
},
|
|
2611
|
-
|
|
2611
|
+
aqara_selftest: {
|
|
2612
2612
|
key: ['selftest'],
|
|
2613
2613
|
convertSet: async (entity, key, value, meta) => {
|
|
2614
2614
|
await entity.write('aqaraOpple', {0x0127: {value: true, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
2615
2615
|
},
|
|
2616
2616
|
},
|
|
2617
|
-
|
|
2617
|
+
aqara_mute_buzzer: {
|
|
2618
2618
|
key: ['mute_buzzer'],
|
|
2619
2619
|
convertSet: async (entity, key, value, meta) => {
|
|
2620
|
-
|
|
2620
|
+
let attribute = 0x013f;
|
|
2621
|
+
if (['JY-GZ-01AQ'].includes(meta.mapped.model)) attribute = 0x013e;
|
|
2622
|
+
await entity.write('aqaraOpple', {[`${attribute}`]: {value: 15360, type: 0x23}}, manufacturerOptions.xiaomi);
|
|
2621
2623
|
await entity.write('aqaraOpple', {0x0126: {value: 1, type: 0x20}}, manufacturerOptions.xiaomi);
|
|
2622
2624
|
},
|
|
2623
2625
|
},
|
|
2624
|
-
|
|
2626
|
+
aqara_mute: {
|
|
2625
2627
|
key: ['mute'],
|
|
2626
2628
|
convertGet: async (entity, key, meta) => {
|
|
2627
2629
|
await entity.read('aqaraOpple', [0x0126], manufacturerOptions.xiaomi);
|
|
2628
2630
|
},
|
|
2629
2631
|
},
|
|
2630
|
-
|
|
2632
|
+
JYGZ01AQ_heartbeat_indicator: {
|
|
2633
|
+
key: ['heartbeat_indicator'],
|
|
2634
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2635
|
+
const lookup = {true: 1, false: 0};
|
|
2636
|
+
await entity.write('aqaraOpple', {0x013c: {value: lookup[value], type: 0x20}}, manufacturerOptions.xiaomi);
|
|
2637
|
+
return {state: {heartbeat_indicator: value}};
|
|
2638
|
+
},
|
|
2639
|
+
convertGet: async (entity, key, meta) => {
|
|
2640
|
+
await entity.read('aqaraOpple', [0x013c], manufacturerOptions.xiaomi);
|
|
2641
|
+
},
|
|
2642
|
+
},
|
|
2643
|
+
aqara_linkage_alarm: {
|
|
2631
2644
|
key: ['linkage_alarm'],
|
|
2632
2645
|
convertSet: async (entity, key, value, meta) => {
|
|
2633
2646
|
const lookup = {true: 1, false: 0};
|
package/devices/datek.js
CHANGED
|
@@ -41,39 +41,45 @@ module.exports = [
|
|
|
41
41
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
42
42
|
const endpoint = device.getEndpoint(1);
|
|
43
43
|
await reporting.bind(endpoint, coordinatorEndpoint, ['haElectricalMeasurement', 'seMetering', 'msTemperatureMeasurement']);
|
|
44
|
-
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
45
44
|
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
45
|
+
try {
|
|
46
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
47
|
+
} catch (error) {
|
|
48
|
+
/* fails for some: https://github.com/Koenkk/zigbee2mqtt/issues/11867 */
|
|
49
|
+
}
|
|
46
50
|
const payload = [{
|
|
47
51
|
attribute: 'rmsVoltagePhB',
|
|
48
|
-
minimumReportInterval:
|
|
52
|
+
minimumReportInterval: 60,
|
|
49
53
|
maximumReportInterval: 3600,
|
|
50
54
|
reportableChange: 0,
|
|
51
55
|
},
|
|
52
56
|
{
|
|
53
57
|
attribute: 'rmsVoltagePhC',
|
|
54
|
-
minimumReportInterval:
|
|
58
|
+
minimumReportInterval: 60,
|
|
55
59
|
maximumReportInterval: 3600,
|
|
56
60
|
reportableChange: 0,
|
|
57
61
|
},
|
|
58
62
|
{
|
|
59
63
|
attribute: 'rmsCurrentPhB',
|
|
60
|
-
minimumReportInterval:
|
|
64
|
+
minimumReportInterval: 60,
|
|
61
65
|
maximumReportInterval: 3600,
|
|
62
66
|
reportableChange: 0,
|
|
63
67
|
},
|
|
64
68
|
{
|
|
65
69
|
attribute: 'rmsCurrentPhC',
|
|
66
|
-
minimumReportInterval:
|
|
70
|
+
minimumReportInterval: 60,
|
|
67
71
|
maximumReportInterval: 3600,
|
|
68
72
|
reportableChange: 0,
|
|
69
73
|
}];
|
|
70
74
|
await endpoint.configureReporting('haElectricalMeasurement', payload);
|
|
71
|
-
await reporting.rmsVoltage(endpoint, {min:
|
|
72
|
-
await reporting.rmsCurrent(endpoint, {min:
|
|
73
|
-
await reporting.instantaneousDemand(endpoint, {min:
|
|
74
|
-
await reporting.currentSummDelivered(endpoint, {min:
|
|
75
|
+
await reporting.rmsVoltage(endpoint, {min: 60, max: 3600, change: 0});
|
|
76
|
+
await reporting.rmsCurrent(endpoint, {min: 60, max: 3600, change: 0});
|
|
77
|
+
await reporting.instantaneousDemand(endpoint, {min: 60, max: 3600, change: 0});
|
|
78
|
+
await reporting.currentSummDelivered(endpoint, {min: 60, max: 3600, change: [1, 1]});
|
|
75
79
|
await reporting.currentSummReceived(endpoint);
|
|
76
|
-
await reporting.temperature(endpoint);
|
|
80
|
+
await reporting.temperature(endpoint, {min: 60, max: 3600, change: 0});
|
|
81
|
+
device.powerSource = 'DC source';
|
|
82
|
+
device.save();
|
|
77
83
|
},
|
|
78
84
|
exposes: [e.power(), e.energy(), e.current(), e.voltage(), e.current_phase_b(), e.voltage_phase_b(), e.current_phase_c(),
|
|
79
85
|
e.voltage_phase_c(), e.temperature()],
|
package/devices/legrand.js
CHANGED
|
@@ -341,4 +341,22 @@ module.exports = [
|
|
|
341
341
|
return {left: 2, right: 1};
|
|
342
342
|
},
|
|
343
343
|
},
|
|
344
|
+
{
|
|
345
|
+
zigbeeModel: [' Mobile outlet\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'+
|
|
346
|
+
'\u0000\u0000\u0000\u0000\u0000\u0000\u0000'],
|
|
347
|
+
model: 'WNRR15/WNRR20',
|
|
348
|
+
vendor: 'Legrand',
|
|
349
|
+
ota: ota.zigbeeOTA,
|
|
350
|
+
description: 'Outlet with power consumption monitoring',
|
|
351
|
+
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement],
|
|
352
|
+
toZigbee: [tz.on_off, tz.legrand_settingAlwaysEnableLed, tz.legrand_identify],
|
|
353
|
+
exposes: [e.switch(), e.action(['identify']), e.power()],
|
|
354
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
355
|
+
const endpoint = device.getEndpoint(1);
|
|
356
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genIdentify', 'genOnOff', 'haElectricalMeasurement']);
|
|
357
|
+
await reporting.onOff(endpoint);
|
|
358
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
359
|
+
await reporting.activePower(endpoint);
|
|
360
|
+
},
|
|
361
|
+
},
|
|
344
362
|
];
|
package/devices/moes.js
CHANGED
|
@@ -99,6 +99,7 @@ module.exports = [
|
|
|
99
99
|
{
|
|
100
100
|
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_aoclfnxz'},
|
|
101
101
|
{modelID: 'TS0601', manufacturerName: '_TZE200_ztvwu4nk'},
|
|
102
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_ye5jkfsb'},
|
|
102
103
|
{modelID: 'TS0601', manufacturerName: '_TZE200_u9bfwha0'}],
|
|
103
104
|
model: 'BHT-002-GCLZB',
|
|
104
105
|
vendor: 'Moes',
|
package/devices/niko.js
CHANGED
|
@@ -5,6 +5,60 @@ const reporting = require('../lib/reporting');
|
|
|
5
5
|
const e = exposes.presets;
|
|
6
6
|
const ea = exposes.access;
|
|
7
7
|
|
|
8
|
+
const fzLocal = {
|
|
9
|
+
fz: {
|
|
10
|
+
switch_operation_mode: {
|
|
11
|
+
cluster: 'manuSpecificNikoSwitchSetup',
|
|
12
|
+
type: ['attributeReport', 'readResponse'],
|
|
13
|
+
convert: (model, msg, publish, options, meta) => {
|
|
14
|
+
const state = {};
|
|
15
|
+
if (msg.data.hasOwnProperty('operationMode')) {
|
|
16
|
+
const operationModeProperty = `operation_mode${meta.endpoint_name ? `_${meta.endpoint_name}` : ''}`;
|
|
17
|
+
const operationModeMap = {0x02: 'control_relay', 0x01: 'decoupled', 0x00: 'unknown'};
|
|
18
|
+
state[operationModeProperty] = operationModeMap[msg.data.operationMode];
|
|
19
|
+
}
|
|
20
|
+
return state;
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
switch_action: {
|
|
24
|
+
cluster: 'manuSpecificNikoSwitch',
|
|
25
|
+
type: ['attributeReport', 'readResponse'],
|
|
26
|
+
convert: (model, msg, publish, options, meta) => {
|
|
27
|
+
const state = {};
|
|
28
|
+
|
|
29
|
+
if (msg.data.hasOwnProperty('action')) {
|
|
30
|
+
// NOTE: a single press = two seperate values reported, 16 followed by 64
|
|
31
|
+
// a hold/release cyle = three seperate values, 16, 32, and 48
|
|
32
|
+
const actionProperty = `action${meta.endpoint_name ? `_${meta.endpoint_name}` : ''}`;
|
|
33
|
+
const actionMap = {16: null, 64: 'single', 32: 'hold', 48: 'release'};
|
|
34
|
+
state[actionProperty] = actionMap[msg.data.action];
|
|
35
|
+
}
|
|
36
|
+
return state;
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
tz: {
|
|
41
|
+
switch_operation_mode: {
|
|
42
|
+
key: ['operation_mode'],
|
|
43
|
+
convertSet: async (entity, key, value, meta) => {
|
|
44
|
+
// WARN: while we can technically write 0x00 to the operationMode attribute
|
|
45
|
+
// this seems to brick the device and it will need to be rejoined
|
|
46
|
+
const operationModeLookup = {control_relay: 0x02, decoupled: 0x01};
|
|
47
|
+
if (!operationModeLookup.hasOwnProperty(value)) {
|
|
48
|
+
throw new Error(`operation_mode was called with an invalid value (${value})`);
|
|
49
|
+
} else {
|
|
50
|
+
const operationModeProperty = `operation_mode${meta.endpoint_name ? `_${meta.endpoint_name}` : ''}`;
|
|
51
|
+
await entity.write('manuSpecificNikoSwitchSetup', {'operationMode': operationModeLookup[value]});
|
|
52
|
+
return {state: {[operationModeProperty]: value.toLowerCase()}};
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
convertGet: async (entity, key, meta) => {
|
|
56
|
+
await entity.read('manuSpecificNikoSwitchSetup', ['operationMode']);
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
8
62
|
module.exports = [
|
|
9
63
|
{
|
|
10
64
|
zigbeeModel: ['Connected socket outlet'],
|
|
@@ -80,15 +134,18 @@ module.exports = [
|
|
|
80
134
|
model: '552-721X1',
|
|
81
135
|
vendor: 'Niko',
|
|
82
136
|
description: 'Single connectable switch',
|
|
83
|
-
fromZigbee: [fz.on_off],
|
|
84
|
-
toZigbee: [tz.on_off],
|
|
137
|
+
fromZigbee: [fz.on_off, fzLocal.fz.switch_operation_mode, fzLocal.fz.switch_action],
|
|
138
|
+
toZigbee: [tz.on_off, fzLocal.tz.switch_operation_mode],
|
|
85
139
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
86
140
|
const endpoint = device.getEndpoint(1);
|
|
87
141
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
88
142
|
await reporting.onOff(endpoint);
|
|
143
|
+
await endpoint.read('manuSpecificNikoSwitchSetup', ['operationMode']);
|
|
89
144
|
},
|
|
90
145
|
exposes: [
|
|
91
146
|
e.switch(),
|
|
147
|
+
e.action(['single', 'hold', 'release']),
|
|
148
|
+
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']),
|
|
92
149
|
],
|
|
93
150
|
},
|
|
94
151
|
{
|
|
@@ -96,8 +153,8 @@ module.exports = [
|
|
|
96
153
|
model: '552-721X2',
|
|
97
154
|
vendor: 'Niko',
|
|
98
155
|
description: 'Double connectable switch',
|
|
99
|
-
fromZigbee: [fz.on_off],
|
|
100
|
-
toZigbee: [tz.on_off],
|
|
156
|
+
fromZigbee: [fz.on_off, fzLocal.fz.switch_operation_mode, fzLocal.fz.switch_action],
|
|
157
|
+
toZigbee: [tz.on_off, fzLocal.tz.switch_operation_mode],
|
|
101
158
|
endpoint: (device) => {
|
|
102
159
|
return {'l1': 1, 'l2': 2};
|
|
103
160
|
},
|
|
@@ -109,9 +166,15 @@ module.exports = [
|
|
|
109
166
|
await reporting.bind(ep2, coordinatorEndpoint, ['genOnOff']);
|
|
110
167
|
await reporting.onOff(ep1);
|
|
111
168
|
await reporting.onOff(ep2);
|
|
169
|
+
await ep1.read('manuSpecificNikoSwitchSetup', ['operationMode']);
|
|
170
|
+
await ep2.read('manuSpecificNikoSwitchSetup', ['operationMode']);
|
|
112
171
|
},
|
|
113
172
|
exposes: [
|
|
114
173
|
e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'),
|
|
174
|
+
e.action(['single', 'hold', 'release']).withEndpoint('l1'),
|
|
175
|
+
e.action(['single', 'hold', 'release']).withEndpoint('l2'),
|
|
176
|
+
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']).withEndpoint('l1'),
|
|
177
|
+
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']).withEndpoint('l2'),
|
|
115
178
|
],
|
|
116
179
|
},
|
|
117
180
|
];
|
package/devices/philips.js
CHANGED
|
@@ -2714,6 +2714,15 @@ module.exports = [
|
|
|
2714
2714
|
meta: {turnsOffAtBrightness1: true},
|
|
2715
2715
|
ota: ota.zigbeeOTA,
|
|
2716
2716
|
},
|
|
2717
|
+
{
|
|
2718
|
+
zigbeeModel: ['5060930P7_01', '5060930P7_02', '5060930P7_03', '5060930P7_04'],
|
|
2719
|
+
model: '5060930P7',
|
|
2720
|
+
vendor: 'Philips',
|
|
2721
|
+
description: 'Hue White & Color Ambiance Centris ceiling light (3 spots)',
|
|
2722
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
2723
|
+
meta: {turnsOffAtBrightness1: true},
|
|
2724
|
+
ota: ota.zigbeeOTA,
|
|
2725
|
+
},
|
|
2717
2726
|
{
|
|
2718
2727
|
zigbeeModel: ['5060931P7_01', '5060931P7_02', '5060931P7_03', '5060931P7_04'],
|
|
2719
2728
|
model: '5060931P7',
|
package/devices/spotmau.js
CHANGED
|
@@ -10,6 +10,9 @@ module.exports = [
|
|
|
10
10
|
vendor: 'Spotmau',
|
|
11
11
|
description: 'Smart wall switch - 1 gang',
|
|
12
12
|
extend: extend.switch(),
|
|
13
|
+
endpoint: (device) => {
|
|
14
|
+
return {default: 16};
|
|
15
|
+
},
|
|
13
16
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
14
17
|
await reporting.bind(device.getEndpoint(16), coordinatorEndpoint, ['genOnOff', 'genBasic']);
|
|
15
18
|
},
|
package/devices/tuya.js
CHANGED
|
@@ -1048,6 +1048,7 @@ module.exports = [
|
|
|
1048
1048
|
{modelID: 'TS0601', manufacturerName: '_TZE200_3i3exuay'},
|
|
1049
1049
|
{modelID: 'TS0601', manufacturerName: '_TZE200_tvrvdj6o'},
|
|
1050
1050
|
{modelID: 'zo2pocs\u0000', manufacturerName: '_TYST11_fzo2pocs'},
|
|
1051
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_cf1sl3tj'},
|
|
1051
1052
|
// Roller blinds:
|
|
1052
1053
|
{modelID: 'TS0601', manufacturerName: '_TZE200_sbordckq'},
|
|
1053
1054
|
{modelID: 'TS0601', manufacturerName: '_TZE200_fctwhugx'},
|
|
@@ -1076,6 +1077,7 @@ module.exports = [
|
|
|
1076
1077
|
{vendor: 'TuYa', model: 'ZD82TN', description: 'Curtain motor'},
|
|
1077
1078
|
{vendor: 'Moes', model: 'AM43-0.45/40-ES-EB'},
|
|
1078
1079
|
{vendor: 'Larkkey', model: 'ZSTY-SM-1SRZG-EU'},
|
|
1080
|
+
{vendor: 'Zemismart', model: 'ZM85EL-2Z', description: 'Roman Rod I type curtains track'},
|
|
1079
1081
|
{vendor: 'Zemismart', model: 'ZM25TQ', description: 'Tubular motor'},
|
|
1080
1082
|
{vendor: 'Zemismart', model: 'AM43', description: 'Roller blind motor'},
|
|
1081
1083
|
{vendor: 'Zemismart', model: 'M2805EGBZTN', description: 'Tubular motor'},
|
|
@@ -1103,6 +1105,7 @@ module.exports = [
|
|
|
1103
1105
|
{modelID: 'TS0601', manufacturerName: '_TZE200_9sfg7gm0'}, // HomeCloud
|
|
1104
1106
|
{modelID: 'TS0601', manufacturerName: '_TZE200_2atgpdho'}, // HY367
|
|
1105
1107
|
{modelID: 'TS0601', manufacturerName: '_TZE200_cpmgn2cf'},
|
|
1108
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_4eeyebrt'}, // Immax 07732B
|
|
1106
1109
|
],
|
|
1107
1110
|
model: 'TS0601_thermostat',
|
|
1108
1111
|
vendor: 'TuYa',
|
|
@@ -1112,6 +1115,7 @@ module.exports = [
|
|
|
1112
1115
|
{vendor: 'Moes', model: 'HY369RT'},
|
|
1113
1116
|
{vendor: 'SHOJZJ', model: '378RT'},
|
|
1114
1117
|
{vendor: 'Silvercrest', model: 'TVR01'},
|
|
1118
|
+
{vendor: 'Immax', model: '07732B'},
|
|
1115
1119
|
],
|
|
1116
1120
|
meta: {tuyaThermostatPreset: tuya.thermostatPresets, tuyaThermostatSystemMode: tuya.thermostatSystemModes3},
|
|
1117
1121
|
ota: ota.zigbeeOTA,
|
|
@@ -1705,7 +1709,7 @@ module.exports = [
|
|
|
1705
1709
|
},
|
|
1706
1710
|
},
|
|
1707
1711
|
{
|
|
1708
|
-
zigbeeModel: ['HY0017', '
|
|
1712
|
+
zigbeeModel: ['HY0017', '005f0c3b'],
|
|
1709
1713
|
model: 'U86KCJ-ZP',
|
|
1710
1714
|
vendor: 'TuYa',
|
|
1711
1715
|
description: 'Smart 6 key scene wall switch',
|
package/devices/xiaomi.js
CHANGED
|
@@ -1170,9 +1170,9 @@ module.exports = [
|
|
|
1170
1170
|
vendor: 'Xiaomi',
|
|
1171
1171
|
description: 'Aqara smart natural gas detector',
|
|
1172
1172
|
fromZigbee: [fz.aqara_opple],
|
|
1173
|
-
toZigbee: [tz.
|
|
1174
|
-
tz.
|
|
1175
|
-
exposes: [e.gas().withAccess(ea.STATE_GET),
|
|
1173
|
+
toZigbee: [tz.aqara_alarm, tz.aqara_density, tz.JTBZ01AQA_gas_sensitivity, tz.aqara_selftest, tz.aqara_mute_buzzer,
|
|
1174
|
+
tz.aqara_mute, tz.aqara_linkage_alarm, tz.JTBZ01AQA_state, tz.aqara_power_outage_count],
|
|
1175
|
+
exposes: [e.gas().withAccess(ea.STATE_GET),
|
|
1176
1176
|
exposes.numeric('gas_density', ea.STATE_GET).withUnit('%LEL').withDescription('Value of gas concentration'),
|
|
1177
1177
|
exposes.enum('gas_sensitivity', ea.ALL, ['10%LEL', '15%LEL']).withDescription('Gas concentration value at which ' +
|
|
1178
1178
|
'an alarm is triggered ("10%LEL" is more sensitive than "15%LEL")'),
|
|
@@ -1186,7 +1186,7 @@ module.exports = [
|
|
|
1186
1186
|
'is detected, other detectors with this option enabled will also sound the alarm buzzer'),
|
|
1187
1187
|
exposes.binary('state', ea.STATE_GET, 'preparation', 'work').withDescription('"Preparation" or "work" ' +
|
|
1188
1188
|
'(measurement of the gas concentration value and triggering of an alarm are only performed in the "work" state)'),
|
|
1189
|
-
|
|
1189
|
+
e.power_outage_count().withAccess(ea.STATE_GET)],
|
|
1190
1190
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1191
1191
|
const endpoint = device.getEndpoint(1);
|
|
1192
1192
|
await endpoint.read('aqaraOpple', [0x013a], {manufacturerCode: 0x115f});
|
|
@@ -1199,6 +1199,40 @@ module.exports = [
|
|
|
1199
1199
|
},
|
|
1200
1200
|
ota: ota.zigbeeOTA,
|
|
1201
1201
|
},
|
|
1202
|
+
{
|
|
1203
|
+
zigbeeModel: ['lumi.sensor_smoke.acn03'],
|
|
1204
|
+
model: 'JY-GZ-01AQ',
|
|
1205
|
+
vendor: 'Xiaomi',
|
|
1206
|
+
description: 'Aqara smart smoke detector',
|
|
1207
|
+
fromZigbee: [fz.aqara_opple, fz.battery],
|
|
1208
|
+
toZigbee: [tz.aqara_alarm, tz.aqara_density, tz.aqara_selftest, tz.aqara_mute_buzzer, tz.aqara_mute,
|
|
1209
|
+
tz.JYGZ01AQ_heartbeat_indicator, tz.aqara_linkage_alarm],
|
|
1210
|
+
exposes: [e.smoke().withAccess(ea.STATE_GET),
|
|
1211
|
+
exposes.numeric('smoke_density', ea.STATE_GET).withDescription('Value of smoke concentration'),
|
|
1212
|
+
exposes.numeric('smoke_density_dbm', ea.STATE).withUnit('dB/m').withDescription('Value of smoke concentration in dB/m'),
|
|
1213
|
+
exposes.enum('selftest', ea.SET, ['Test']).withDescription('Starts the self-test process (checking the indicator ' +
|
|
1214
|
+
'light and buzzer work properly)'),
|
|
1215
|
+
exposes.binary('test', ea.STATE, true, false).withDescription('Self-test in progress'),
|
|
1216
|
+
exposes.enum('mute_buzzer', ea.SET, ['Mute']).withDescription('Mute the buzzer for 80 seconds (buzzer cannot be ' +
|
|
1217
|
+
'pre-muted, because this function only works when the alarm is triggered)'),
|
|
1218
|
+
exposes.binary('mute', ea.STATE_GET, true, false).withDescription('Buzzer muted'),
|
|
1219
|
+
exposes.binary('heartbeat_indicator', ea.ALL, true, false).withDescription('When this option is enabled then in ' +
|
|
1220
|
+
'the normal monitoring state, the green indicator light flashes every 60 seconds'),
|
|
1221
|
+
exposes.binary('linkage_alarm', ea.ALL, true, false).withDescription('When this option is enabled and a smoke ' +
|
|
1222
|
+
'is detected, other detectors with this option enabled will also sound the alarm buzzer'),
|
|
1223
|
+
e.temperature(), e.battery()],
|
|
1224
|
+
meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}},
|
|
1225
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1226
|
+
const endpoint = device.getEndpoint(1);
|
|
1227
|
+
await endpoint.read('genPowerCfg', ['batteryVoltage']);
|
|
1228
|
+
await endpoint.read('aqaraOpple', [0x013a], {manufacturerCode: 0x115f});
|
|
1229
|
+
await endpoint.read('aqaraOpple', [0x013b], {manufacturerCode: 0x115f});
|
|
1230
|
+
await endpoint.read('aqaraOpple', [0x013c], {manufacturerCode: 0x115f});
|
|
1231
|
+
await endpoint.read('aqaraOpple', [0x0126], {manufacturerCode: 0x115f});
|
|
1232
|
+
await endpoint.read('aqaraOpple', [0x014b], {manufacturerCode: 0x115f});
|
|
1233
|
+
},
|
|
1234
|
+
ota: ota.zigbeeOTA,
|
|
1235
|
+
},
|
|
1202
1236
|
{
|
|
1203
1237
|
zigbeeModel: ['lumi.lock.v1'],
|
|
1204
1238
|
model: 'A6121',
|
package/lib/xiaomi.js
CHANGED
|
@@ -174,9 +174,11 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
174
174
|
payload.switch_type = {1: 'toggle', 2: 'momentary'}[value];
|
|
175
175
|
break;
|
|
176
176
|
case '11':
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
177
|
+
if (!['JT-BZ-01AQ/A'].includes(model.model)) {
|
|
178
|
+
payload.illuminance = calibrateAndPrecisionRoundOptions(value, options, 'illuminance');
|
|
179
|
+
// DEPRECATED: remove illuminance_lux here.
|
|
180
|
+
payload.illuminance_lux = calibrateAndPrecisionRoundOptions(value, options, 'illuminance_lux');
|
|
181
|
+
}
|
|
180
182
|
break;
|
|
181
183
|
case '100':
|
|
182
184
|
if (['QBKG20LM', 'QBKG31LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM', 'LLKZMK11LM', 'QBKG12LM', 'QBKG03LM'].includes(model.model)) {
|
|
@@ -300,25 +302,52 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
300
302
|
}
|
|
301
303
|
break;
|
|
302
304
|
case '159':
|
|
303
|
-
|
|
305
|
+
if (['JT-BZ-01AQ/A'].includes(model.model)) {
|
|
306
|
+
payload.gas_sensitivity = {1: '15%LEL', 2: '10%LEL'}[value];
|
|
307
|
+
}
|
|
304
308
|
break;
|
|
305
309
|
case '160':
|
|
306
|
-
|
|
310
|
+
if (['JT-BZ-01AQ/A'].includes(model.model)) {
|
|
311
|
+
payload.gas = value === 1;
|
|
312
|
+
} else if (['JY-GZ-01AQ'].includes(model.model)) {
|
|
313
|
+
payload.smoke = value === 1;
|
|
314
|
+
}
|
|
307
315
|
break;
|
|
308
316
|
case '161':
|
|
309
|
-
|
|
317
|
+
if (['JT-BZ-01AQ/A'].includes(model.model)) {
|
|
318
|
+
payload.gas_density = value;
|
|
319
|
+
} else if (['JY-GZ-01AQ'].includes(model.model)) {
|
|
320
|
+
payload.smoke_density = value;
|
|
321
|
+
payload.smoke_density_dbm = {0: 0, 1: 0.085, 2: 0.088, 3: 0.093, 4: 0.095, 5: 0.100, 6: 0.105, 7: 0.110,
|
|
322
|
+
8: 0.115, 9: 0.120, 10: 0.125}[value];
|
|
323
|
+
}
|
|
310
324
|
break;
|
|
311
325
|
case '162':
|
|
312
|
-
|
|
326
|
+
if (['JT-BZ-01AQ/A', 'JY-GZ-01AQ'].includes(model.model)) {
|
|
327
|
+
payload.test = value === 1;
|
|
328
|
+
}
|
|
313
329
|
break;
|
|
314
330
|
case '163':
|
|
315
|
-
|
|
331
|
+
if (['JT-BZ-01AQ/A', 'JY-GZ-01AQ'].includes(model.model)) {
|
|
332
|
+
payload.mute = value === 1;
|
|
333
|
+
}
|
|
316
334
|
break;
|
|
317
335
|
case '164':
|
|
318
|
-
|
|
336
|
+
if (['JT-BZ-01AQ/A'].includes(model.model)) {
|
|
337
|
+
payload.state = {0: 'work', 1: 'preparation'}[value];
|
|
338
|
+
} else if (['JY-GZ-01AQ'].includes(model.model)) {
|
|
339
|
+
payload.heartbeat_indicator = value === 1;
|
|
340
|
+
}
|
|
341
|
+
break;
|
|
342
|
+
case '165':
|
|
343
|
+
if (['JY-GZ-01AQ'].includes(model.model)) {
|
|
344
|
+
payload.linkage_alarm = value === 1;
|
|
345
|
+
}
|
|
319
346
|
break;
|
|
320
347
|
case '166':
|
|
321
|
-
|
|
348
|
+
if (['JT-BZ-01AQ/A'].includes(model.model)) {
|
|
349
|
+
payload.linkage_alarm = value === 1;
|
|
350
|
+
}
|
|
322
351
|
break;
|
|
323
352
|
case '240':
|
|
324
353
|
payload.flip_indicator_light = value === 1 ? 'ON' : 'OFF';
|
|
@@ -344,19 +373,40 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
344
373
|
payload.click_mode = {1: 'fast', 2: 'multi'}[value];
|
|
345
374
|
break;
|
|
346
375
|
case '294':
|
|
347
|
-
|
|
376
|
+
if (['JT-BZ-01AQ/A', 'JY-GZ-01AQ'].includes(model.model)) {
|
|
377
|
+
payload.mute = value === 1;
|
|
378
|
+
}
|
|
348
379
|
break;
|
|
349
380
|
case '295':
|
|
350
|
-
|
|
381
|
+
if (['JT-BZ-01AQ/A', 'JY-GZ-01AQ'].includes(model.model)) {
|
|
382
|
+
payload.test = value === 1;
|
|
383
|
+
}
|
|
351
384
|
break;
|
|
352
385
|
case '313':
|
|
353
|
-
|
|
386
|
+
if (['JT-BZ-01AQ/A'].includes(model.model)) {
|
|
387
|
+
payload.state = {0: 'work', 1: 'preparation'}[value];
|
|
388
|
+
}
|
|
354
389
|
break;
|
|
355
390
|
case '314':
|
|
356
|
-
|
|
391
|
+
if (['JT-BZ-01AQ/A'].includes(model.model)) {
|
|
392
|
+
payload.gas = value === 1;
|
|
393
|
+
} else if (['JY-GZ-01AQ'].includes(model.model)) {
|
|
394
|
+
payload.smoke = value === 1;
|
|
395
|
+
}
|
|
357
396
|
break;
|
|
358
397
|
case '315':
|
|
359
|
-
|
|
398
|
+
if (['JT-BZ-01AQ/A'].includes(model.model)) {
|
|
399
|
+
payload.gas_density = value;
|
|
400
|
+
} else if (['JY-GZ-01AQ'].includes(model.model)) {
|
|
401
|
+
payload.smoke_density = value;
|
|
402
|
+
payload.smoke_density_dbm = {0: 0, 1: 0.085, 2: 0.088, 3: 0.093, 4: 0.095, 5: 0.100, 6: 0.105, 7: 0.110,
|
|
403
|
+
8: 0.115, 9: 0.120, 10: 0.125}[value];
|
|
404
|
+
}
|
|
405
|
+
break;
|
|
406
|
+
case '316':
|
|
407
|
+
if (['JY-GZ-01AQ'].includes(model.model)) {
|
|
408
|
+
payload.heartbeat_indicator = value === 1;
|
|
409
|
+
}
|
|
360
410
|
break;
|
|
361
411
|
case '322':
|
|
362
412
|
if (['RTCZCGQ11LM'].includes(model.model)) {
|
|
@@ -380,7 +430,9 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
380
430
|
}
|
|
381
431
|
break;
|
|
382
432
|
case '331':
|
|
383
|
-
|
|
433
|
+
if (['JT-BZ-01AQ/A', 'JY-GZ-01AQ'].includes(model.model)) {
|
|
434
|
+
payload.linkage_alarm = value === 1;
|
|
435
|
+
}
|
|
384
436
|
break;
|
|
385
437
|
case '512':
|
|
386
438
|
if (['ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM'].includes(model.model)) {
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.468",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "zigbee-herdsman-converters",
|
|
9
|
-
"version": "14.0.
|
|
9
|
+
"version": "14.0.468",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"axios": "^0.26.1",
|