zigbee-herdsman-converters 14.0.404 → 14.0.408
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 +54 -6
- package/converters/toZigbee.js +65 -11
- package/devices/acova.js +60 -29
- package/devices/danfoss.js +5 -1
- package/devices/gledopto.js +19 -0
- package/devices/kwikset.js +1 -1
- package/devices/legrand.js +24 -1
- package/devices/m/303/274ller_licht.js +8 -0
- package/devices/orvibo.js +198 -0
- package/devices/philips.js +1 -1
- package/devices/shinasystem.js +21 -0
- package/devices/sinope.js +51 -5
- package/devices/stelpro.js +30 -0
- package/devices/tplink.js +16 -0
- package/devices/tuya.js +22 -4
- package/devices/woox.js +19 -0
- package/devices/xiaomi.js +55 -26
- package/index.js +2 -1
- package/lib/exposes.js +2 -0
- package/lib/reporting.js +4 -0
- package/npm-shrinkwrap.json +109 -109
- package/package.json +2 -2
package/converters/fromZigbee.js
CHANGED
|
@@ -2522,8 +2522,8 @@ const converters = {
|
|
|
2522
2522
|
return {battpercentage: value};
|
|
2523
2523
|
case tuya.dataPoints.neoAOMelody: // 0x21 [5] Melody
|
|
2524
2524
|
return {melody: value};
|
|
2525
|
-
case tuya.dataPoints.neoAOVolume: // 0x5 [0]/[1]/[2] Volume 0-
|
|
2526
|
-
return {volume: {
|
|
2525
|
+
case tuya.dataPoints.neoAOVolume: // 0x5 [0]/[1]/[2] Volume 0-low, 2-max
|
|
2526
|
+
return {volume: {0: 'low', 1: 'medium', 2: 'high'}[value]};
|
|
2527
2527
|
default: // Unknown code
|
|
2528
2528
|
meta.logger.warn(`Unhandled DP #${dp}: ${JSON.stringify(msg.data)}`);
|
|
2529
2529
|
}
|
|
@@ -3211,6 +3211,10 @@ const converters = {
|
|
|
3211
3211
|
result[postfixWithEndpointName('pi_heating_demand', msg, model)] =
|
|
3212
3212
|
precisionRound(msg.data['pIHeatingDemand'], 0);
|
|
3213
3213
|
}
|
|
3214
|
+
if (msg.data.hasOwnProperty('danfossWindowOpenFeatureEnable')) {
|
|
3215
|
+
result[postfixWithEndpointName('window_open_feature', msg, model)] =
|
|
3216
|
+
(msg.data['danfossWindowOpenFeatureEnable'] === 1);
|
|
3217
|
+
}
|
|
3214
3218
|
if (msg.data.hasOwnProperty('danfossWindowOpenInternal')) {
|
|
3215
3219
|
result[postfixWithEndpointName('window_open_internal', msg, model)] =
|
|
3216
3220
|
constants.danfossWindowOpen.hasOwnProperty(msg.data['danfossWindowOpenInternal']) ?
|
|
@@ -5029,6 +5033,9 @@ const converters = {
|
|
|
5029
5033
|
// dimmer
|
|
5030
5034
|
else if (option0 === 0x0101) payload.device_mode = 'dimmer_on';
|
|
5031
5035
|
else if (option0 === 0x0100) payload.device_mode = 'dimmer_off';
|
|
5036
|
+
// pilot wire
|
|
5037
|
+
else if (option0 === 0x0002) payload.device_mode = 'pilot_on';
|
|
5038
|
+
else if (option0 === 0x0001) payload.device_mode = 'pilot_off';
|
|
5032
5039
|
// unknown case
|
|
5033
5040
|
else {
|
|
5034
5041
|
meta.logger.warn(`device_mode ${option0} not recognized, please fix me`);
|
|
@@ -5037,6 +5044,26 @@ const converters = {
|
|
|
5037
5044
|
return payload;
|
|
5038
5045
|
},
|
|
5039
5046
|
},
|
|
5047
|
+
legrand_cable_outlet_mode: {
|
|
5048
|
+
cluster: '64576',
|
|
5049
|
+
type: ['readResponse'],
|
|
5050
|
+
convert: (model, msg, publish, options, meta) => {
|
|
5051
|
+
const payload = {};
|
|
5052
|
+
const mode = msg.data['0'];
|
|
5053
|
+
|
|
5054
|
+
if (mode === 0x00) payload.cable_outlet_mode = 'comfort';
|
|
5055
|
+
else if (mode === 0x01) payload.cable_outlet_mode = 'comfort-1';
|
|
5056
|
+
else if (mode === 0x02) payload.cable_outlet_mode = 'comfort-2';
|
|
5057
|
+
else if (mode === 0x03) payload.cable_outlet_mode = 'eco';
|
|
5058
|
+
else if (mode === 0x04) payload.cable_outlet_mode = 'frost_protection';
|
|
5059
|
+
else if (mode === 0x05) payload.cable_outlet_mode = 'off';
|
|
5060
|
+
else {
|
|
5061
|
+
meta.logger.warn(`Bad mode : ${mode}`);
|
|
5062
|
+
payload.cable_outlet_mode = 'unknown';
|
|
5063
|
+
}
|
|
5064
|
+
return payload;
|
|
5065
|
+
},
|
|
5066
|
+
},
|
|
5040
5067
|
legrand_power_alarm: {
|
|
5041
5068
|
cluster: 'haElectricalMeasurement',
|
|
5042
5069
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -5257,13 +5284,16 @@ const converters = {
|
|
|
5257
5284
|
payload.battery = batteryVoltageToPercentage(value, '3V_2100');
|
|
5258
5285
|
} else if (index === 3) payload.temperature = calibrateAndPrecisionRoundOptions(value, options, 'temperature'); // 0x03
|
|
5259
5286
|
else if (index === 5) {
|
|
5260
|
-
if (['JT-BZ-01AQ/A'].includes(model.model)) payload.power_outage_count = value;
|
|
5287
|
+
if (['JT-BZ-01AQ/A', 'RTCZCGQ11LM'].includes(model.model)) payload.power_outage_count = value;
|
|
5261
5288
|
} else if (index === 100) {
|
|
5262
5289
|
if (['QBKG20LM', 'QBKG31LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM'].includes(model.model)) {
|
|
5263
5290
|
const mapping = model.model === 'QBCZ15LM' ? 'relay' : 'left';
|
|
5264
5291
|
payload[`state_${mapping}`] = value === 1 ? 'ON' : 'OFF';
|
|
5265
5292
|
} else if (['WXKG14LM', 'WXKG16LM', 'WXKG17LM'].includes(model.model)) {
|
|
5266
5293
|
payload.click_mode = {1: 'fast', 2: 'multi'}[value];
|
|
5294
|
+
} else if (['WXCJKG11LM ', 'WXCJKG12LM', 'WXCJKG13LM'].includes(model.model)) {
|
|
5295
|
+
// We don't know what the value means for these devices.
|
|
5296
|
+
// https://github.com/Koenkk/zigbee2mqtt/issues/11126
|
|
5267
5297
|
} else {
|
|
5268
5298
|
payload.state = value === 1 ? 'ON' : 'OFF';
|
|
5269
5299
|
}
|
|
@@ -5281,9 +5311,18 @@ const converters = {
|
|
|
5281
5311
|
} else if (index ===102 ) {
|
|
5282
5312
|
if (['QBKG25LM', 'QBKG34LM'].includes(model.model)) {
|
|
5283
5313
|
payload.state_right = value === 1 ? 'ON' : 'OFF';
|
|
5314
|
+
} else if (['RTCZCGQ11LM'].includes(model.model)) {
|
|
5315
|
+
payload.presence_event = {0: 'enter', 1: 'leave', 2: 'left_enter', 3: 'right_leave', 4: 'right_enter',
|
|
5316
|
+
5: 'left_leave', 6: 'approach', 7: 'away', 255: null}[value];
|
|
5317
|
+
}
|
|
5318
|
+
} else if (index ===103) payload.monitoring_mode = value === 1 ? 'left_right' : 'undirected'; // RTCZCGQ11LM
|
|
5319
|
+
else if (index === 105) {
|
|
5320
|
+
if (['RTCGQ13LM'].includes(model.model)) {
|
|
5321
|
+
payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[value];
|
|
5322
|
+
} else if (['RTCZCGQ11LM'].includes(model.model)) {
|
|
5323
|
+
payload.approach_distance = {0: 'far', 1: 'medium', 2: 'near'}[value];
|
|
5284
5324
|
}
|
|
5285
|
-
} else if (index ===
|
|
5286
|
-
else if (index === 149) {
|
|
5325
|
+
} else if (index === 149) {
|
|
5287
5326
|
payload.energy = precisionRound(value, 2); // 0x95
|
|
5288
5327
|
// Consumption is deprecated
|
|
5289
5328
|
payload.consumption = payload.energy;
|
|
@@ -5322,6 +5361,15 @@ const converters = {
|
|
|
5322
5361
|
if (msg.data.hasOwnProperty('313')) payload.state = msg.data['313'] === 1 ? 'preparation' : 'work'; // JT-BZ-01AQ/A
|
|
5323
5362
|
if (msg.data.hasOwnProperty('314')) payload.gas = msg.data['314'] === 1; // JT-BZ-01AQ/A
|
|
5324
5363
|
if (msg.data.hasOwnProperty('315')) payload.gas_density = msg.data['315']; // JT-BZ-01AQ/A
|
|
5364
|
+
if (msg.data.hasOwnProperty('322')) payload.presence = msg.data['322'] === 1; // RTCZCGQ11LM
|
|
5365
|
+
if (msg.data.hasOwnProperty('323')) {
|
|
5366
|
+
payload.presence_event = {0: 'enter', 1: 'leave', 2: 'left_enter', 3: 'right_leave', 4: 'right_enter',
|
|
5367
|
+
5: 'left_leave', 6: 'approach', 7: 'away'}[msg.data['323']]; // RTCZCGQ11LM
|
|
5368
|
+
}
|
|
5369
|
+
// RTCZCGQ11LM
|
|
5370
|
+
if (msg.data.hasOwnProperty('324')) payload.monitoring_mode = msg.data['324'] === 1 ? 'left_right' : 'undirected';
|
|
5371
|
+
// RTCZCGQ11LM
|
|
5372
|
+
if (msg.data.hasOwnProperty('326')) payload.approach_distance = {0: 'far', 1: 'medium', 2: 'near'}[msg.data['326']];
|
|
5325
5373
|
if (msg.data.hasOwnProperty('331')) payload.linkage_alarm = msg.data['331'] === 1; // JT-BZ-01AQ/A
|
|
5326
5374
|
if (msg.data.hasOwnProperty('512')) {
|
|
5327
5375
|
if (['ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM'].includes(model.model)) {
|
|
@@ -8194,7 +8242,7 @@ const converters = {
|
|
|
8194
8242
|
cluster: 'genOnOff',
|
|
8195
8243
|
type: 'raw',
|
|
8196
8244
|
convert: (model, msg, publish, options, meta) => {
|
|
8197
|
-
if (hasAlreadyProcessedMessage(msg, msg.data[
|
|
8245
|
+
if (hasAlreadyProcessedMessage(msg, msg.data[1])) return;
|
|
8198
8246
|
let action;
|
|
8199
8247
|
if (msg.data[2] == 253) {
|
|
8200
8248
|
action = {0: 'single', 1: 'double', 2: 'hold'}[msg.data[3]];
|
package/converters/toZigbee.js
CHANGED
|
@@ -54,6 +54,14 @@ const converters = {
|
|
|
54
54
|
meta.logger.info(`Wrote '${JSON.stringify(value.payload)}' to '${value.cluster}'`);
|
|
55
55
|
},
|
|
56
56
|
},
|
|
57
|
+
command: {
|
|
58
|
+
key: ['command'],
|
|
59
|
+
convertSet: async (entity, key, value, meta) => {
|
|
60
|
+
const options = utils.getOptions(meta.mapped, entity);
|
|
61
|
+
await entity.command(value.cluster, value.command, (value.hasOwnProperty('payload') ? value.payload : {}), options);
|
|
62
|
+
meta.logger.info(`Invoked '${value.cluster}.${value.command}' with payload '${JSON.stringify(value.payload)}'`);
|
|
63
|
+
},
|
|
64
|
+
},
|
|
57
65
|
factory_reset: {
|
|
58
66
|
key: ['reset'],
|
|
59
67
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -2006,6 +2014,36 @@ const converters = {
|
|
|
2006
2014
|
await entity.read('aqaraOpple', [0x010c], manufacturerOptions.xiaomi);
|
|
2007
2015
|
},
|
|
2008
2016
|
},
|
|
2017
|
+
RTCZCGQ11LM_presence: {
|
|
2018
|
+
key: ['presence'],
|
|
2019
|
+
convertGet: async (entity, key, meta) => {
|
|
2020
|
+
await entity.read('aqaraOpple', [0x0142], manufacturerOptions.xiaomi);
|
|
2021
|
+
},
|
|
2022
|
+
},
|
|
2023
|
+
RTCZCGQ11LM_monitoring_mode: {
|
|
2024
|
+
key: ['monitoring_mode'],
|
|
2025
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2026
|
+
value = value.toLowerCase();
|
|
2027
|
+
const lookup = {'undirected': 0, 'left_right': 1};
|
|
2028
|
+
await entity.write('aqaraOpple', {0x0144: {value: lookup[value], type: 0x20}}, manufacturerOptions.xiaomi);
|
|
2029
|
+
return {state: {monitoring_mode: value}};
|
|
2030
|
+
},
|
|
2031
|
+
convertGet: async (entity, key, meta) => {
|
|
2032
|
+
await entity.read('aqaraOpple', [0x0144], manufacturerOptions.xiaomi);
|
|
2033
|
+
},
|
|
2034
|
+
},
|
|
2035
|
+
RTCZCGQ11LM_approach_distance: {
|
|
2036
|
+
key: ['approach_distance'],
|
|
2037
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2038
|
+
value = value.toLowerCase();
|
|
2039
|
+
const lookup = {'far': 0, 'medium': 1, 'near': 2};
|
|
2040
|
+
await entity.write('aqaraOpple', {0x0146: {value: lookup[value], type: 0x20}}, manufacturerOptions.xiaomi);
|
|
2041
|
+
return {state: {approach_distance: value}};
|
|
2042
|
+
},
|
|
2043
|
+
convertGet: async (entity, key, meta) => {
|
|
2044
|
+
await entity.read('aqaraOpple', [0x0146], manufacturerOptions.xiaomi);
|
|
2045
|
+
},
|
|
2046
|
+
},
|
|
2009
2047
|
ZigUP_lock: {
|
|
2010
2048
|
key: ['led'],
|
|
2011
2049
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -2040,7 +2078,7 @@ const converters = {
|
|
|
2040
2078
|
convertSet: async (entity, key, value, meta) => {
|
|
2041
2079
|
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'DLKZMK12LM',
|
|
2042
2080
|
'WS-EUK01', 'WS-EUK02', 'WS-EUK03', 'WS-EUK04', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
|
|
2043
|
-
'QBKG31LM', 'QBKG34LM', 'QBKG38LM', 'QBKG39LM', 'QBKG40LM', 'QBKG41LM'].includes(meta.mapped.model)) {
|
|
2081
|
+
'QBKG31LM', 'QBKG34LM', 'QBKG38LM', 'QBKG39LM', 'QBKG40LM', 'QBKG41LM', 'ZNDDMK11LM'].includes(meta.mapped.model)) {
|
|
2044
2082
|
await entity.write('aqaraOpple', {0x0201: {value: value ? 1 : 0, type: 0x10}}, manufacturerOptions.xiaomi);
|
|
2045
2083
|
} else if (['ZNCZ02LM', 'QBCZ11LM'].includes(meta.mapped.model)) {
|
|
2046
2084
|
const payload = value ?
|
|
@@ -2063,7 +2101,7 @@ const converters = {
|
|
|
2063
2101
|
convertGet: async (entity, key, meta) => {
|
|
2064
2102
|
if (['ZNCZ04LM', 'ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM', 'SSM-U01', 'SSM-U02', 'DLKZMK11LM', 'DLKZMK12LM',
|
|
2065
2103
|
'WS-EUK01', 'WS-EUK02', 'WS-EUK03', 'WS-EUK04', 'QBKG19LM', 'QBKG20LM', 'QBKG25LM', 'QBKG26LM',
|
|
2066
|
-
'QBKG31LM', 'QBKG34LM', 'QBKG38LM', 'QBKG39LM', 'QBKG40LM', 'QBKG41LM'].includes(meta.mapped.model)) {
|
|
2104
|
+
'QBKG31LM', 'QBKG34LM', 'QBKG38LM', 'QBKG39LM', 'QBKG40LM', 'QBKG41LM', 'ZNDDMK11LM'].includes(meta.mapped.model)) {
|
|
2067
2105
|
await entity.read('aqaraOpple', [0x0201]);
|
|
2068
2106
|
} else if (['ZNCZ02LM', 'QBCZ11LM', 'ZNCZ11LM'].includes(meta.mapped.model)) {
|
|
2069
2107
|
await entity.read('aqaraOpple', [0xFFF0]);
|
|
@@ -2714,6 +2752,16 @@ const converters = {
|
|
|
2714
2752
|
await entity.read('hvacThermostat', ['danfossTriggerTime'], manufacturerOptions.danfoss);
|
|
2715
2753
|
},
|
|
2716
2754
|
},
|
|
2755
|
+
danfoss_window_open_feature: {
|
|
2756
|
+
key: ['window_open_feature'],
|
|
2757
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2758
|
+
await entity.write('hvacThermostat', {'danfossWindowOpenFeatureEnable': value}, manufacturerOptions.danfoss);
|
|
2759
|
+
return {readAfterWriteTime: 200, state: {'window_open_feature': value}};
|
|
2760
|
+
},
|
|
2761
|
+
convertGet: async (entity, key, meta) => {
|
|
2762
|
+
await entity.read('hvacThermostat', ['danfossWindowOpenFeatureEnable'], manufacturerOptions.danfoss);
|
|
2763
|
+
},
|
|
2764
|
+
},
|
|
2717
2765
|
danfoss_window_open_internal: {
|
|
2718
2766
|
key: ['window_open_internal'],
|
|
2719
2767
|
convertGet: async (entity, key, meta) => {
|
|
@@ -4490,6 +4538,9 @@ const converters = {
|
|
|
4490
4538
|
// contactor
|
|
4491
4539
|
'switch': 0x0003,
|
|
4492
4540
|
'auto': 0x0004,
|
|
4541
|
+
// pilot wire
|
|
4542
|
+
'pilot_on': 0x0002,
|
|
4543
|
+
'pilot_off': 0x0001,
|
|
4493
4544
|
};
|
|
4494
4545
|
|
|
4495
4546
|
value = value.toLowerCase();
|
|
@@ -4502,6 +4553,15 @@ const converters = {
|
|
|
4502
4553
|
await entity.read('manuSpecificLegrandDevices', [0x0000, 0x0001, 0x0002], manufacturerOptions.legrand);
|
|
4503
4554
|
},
|
|
4504
4555
|
},
|
|
4556
|
+
legrand_cableOutletMode: {
|
|
4557
|
+
key: ['cable_outlet_mode'],
|
|
4558
|
+
convertSet: async (entity, key, value, meta) => {
|
|
4559
|
+
meta.logger.warn('Feature under development !');
|
|
4560
|
+
},
|
|
4561
|
+
convertGet: async (entity, key, meta) => {
|
|
4562
|
+
await entity.read(64576, [0x0000], manufacturerOptions.legrand);
|
|
4563
|
+
},
|
|
4564
|
+
},
|
|
4505
4565
|
legrand_powerAlarm: {
|
|
4506
4566
|
key: ['power_alarm'],
|
|
4507
4567
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -6709,7 +6769,7 @@ const converters = {
|
|
|
6709
6769
|
await tuya.sendDataPoints(entity, [
|
|
6710
6770
|
tuya.dpValueFromEnum(tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.white),
|
|
6711
6771
|
tuya.dpValueFromIntValue(tuya.dataPoints.dimmerLevel, newValue),
|
|
6712
|
-
], 'dataRequest'
|
|
6772
|
+
], 'dataRequest');
|
|
6713
6773
|
|
|
6714
6774
|
return {state: (key == 'white_brightness') ? {white_brightness: value} : {brightness: value}};
|
|
6715
6775
|
} else if (key == 'color_temp') {
|
|
@@ -6736,7 +6796,7 @@ const converters = {
|
|
|
6736
6796
|
await tuya.sendDataPoints(entity, [
|
|
6737
6797
|
tuya.dpValueFromEnum(tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.white),
|
|
6738
6798
|
tuya.dpValueFromIntValue(tuya.dataPoints.silvercrestSetColorTemp, data),
|
|
6739
|
-
], 'dataRequest'
|
|
6799
|
+
], 'dataRequest');
|
|
6740
6800
|
|
|
6741
6801
|
return {state: {color_temp: value}};
|
|
6742
6802
|
} else if (key == 'color' || (separateWhite && (key == 'brightness'))) {
|
|
@@ -6815,13 +6875,7 @@ const converters = {
|
|
|
6815
6875
|
tuya.dpValueFromStringBuffer(tuya.dataPoints.silvercrestSetColor, data),
|
|
6816
6876
|
];
|
|
6817
6877
|
|
|
6818
|
-
|
|
6819
|
-
// restore white state
|
|
6820
|
-
const newValue = utils.mapNumberRange(meta.state.white_brightness, 0, 255, 0, 1000);
|
|
6821
|
-
commands.push(tuya.dpValueFromEnum(tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.white));
|
|
6822
|
-
commands.push(tuya.dpValueFromIntValue(tuya.dataPoints.dimmerLevel, newValue));
|
|
6823
|
-
}
|
|
6824
|
-
await tuya.sendDataPoints(entity, commands, 'dataRequest', 1);
|
|
6878
|
+
await tuya.sendDataPoints(entity, commands, 'dataRequest');
|
|
6825
6879
|
|
|
6826
6880
|
return {state: newState};
|
|
6827
6881
|
}
|
package/devices/acova.js
CHANGED
|
@@ -3,33 +3,64 @@ const fz = require('../converters/fromZigbee');
|
|
|
3
3
|
const tz = require('../converters/toZigbee');
|
|
4
4
|
const reporting = require('../lib/reporting');
|
|
5
5
|
|
|
6
|
-
module.exports = [
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
exposes
|
|
22
|
-
.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
6
|
+
module.exports = [
|
|
7
|
+
{
|
|
8
|
+
zigbeeModel: ['PERCALE2 D1.00P1.01Z1.00'],
|
|
9
|
+
model: 'PERCALE2',
|
|
10
|
+
vendor: 'Acova',
|
|
11
|
+
description: 'Percale 2 heater',
|
|
12
|
+
fromZigbee: [fz.thermostat, fz.hvac_user_interface],
|
|
13
|
+
toZigbee: [
|
|
14
|
+
tz.thermostat_local_temperature,
|
|
15
|
+
tz.thermostat_system_mode,
|
|
16
|
+
tz.thermostat_occupied_heating_setpoint,
|
|
17
|
+
tz.thermostat_unoccupied_heating_setpoint,
|
|
18
|
+
tz.thermostat_occupied_cooling_setpoint,
|
|
19
|
+
tz.thermostat_running_state,
|
|
20
|
+
],
|
|
21
|
+
exposes: [
|
|
22
|
+
exposes.climate()
|
|
23
|
+
.withSetpoint('occupied_heating_setpoint', 7, 28, 0.5)
|
|
24
|
+
.withLocalTemperature()
|
|
25
|
+
.withSystemMode(['off', 'heat', 'auto'])
|
|
26
|
+
.withRunningState(['idle', 'heat']),
|
|
27
|
+
],
|
|
28
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
29
|
+
const endpoint = device.getEndpoint(1);
|
|
30
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat']);
|
|
31
|
+
await reporting.thermostatTemperature(endpoint);
|
|
32
|
+
await reporting.thermostatRunningState(endpoint);
|
|
33
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
34
|
+
await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
|
|
35
|
+
},
|
|
34
36
|
},
|
|
35
|
-
|
|
37
|
+
{
|
|
38
|
+
zigbeeModel: ['ALCANTARA2 D1.00P1.02Z1.00\u0000\u0000\u0000\u0000\u0000\u0000'],
|
|
39
|
+
model: 'ALCANTARA2',
|
|
40
|
+
vendor: 'Acova',
|
|
41
|
+
description: 'Alcantara 2 heater',
|
|
42
|
+
fromZigbee: [fz.thermostat, fz.hvac_user_interface],
|
|
43
|
+
toZigbee: [
|
|
44
|
+
tz.thermostat_local_temperature,
|
|
45
|
+
tz.thermostat_system_mode,
|
|
46
|
+
tz.thermostat_occupied_heating_setpoint,
|
|
47
|
+
tz.thermostat_unoccupied_heating_setpoint,
|
|
48
|
+
tz.thermostat_running_state,
|
|
49
|
+
],
|
|
50
|
+
exposes: [
|
|
51
|
+
exposes.climate()
|
|
52
|
+
.withSetpoint('occupied_heating_setpoint', 7, 28, 0.5)
|
|
53
|
+
.withLocalTemperature()
|
|
54
|
+
.withSystemMode(['off', 'heat', 'auto'])
|
|
55
|
+
.withRunningState(['idle', 'heat']),
|
|
56
|
+
],
|
|
57
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
58
|
+
const endpoint = device.getEndpoint(1);
|
|
59
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'hvacThermostat']);
|
|
60
|
+
await reporting.thermostatTemperature(endpoint);
|
|
61
|
+
await reporting.thermostatRunningState(endpoint);
|
|
62
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
63
|
+
await reporting.thermostatUnoccupiedHeatingSetpoint(endpoint);
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
];
|
package/devices/danfoss.js
CHANGED
|
@@ -22,7 +22,8 @@ module.exports = [
|
|
|
22
22
|
tz.danfoss_window_open_internal, tz.danfoss_window_open_external, tz.danfoss_load_estimate,
|
|
23
23
|
tz.danfoss_viewing_direction, tz.danfoss_external_measured_room_sensor, tz.danfoss_radiator_covered,
|
|
24
24
|
tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean,
|
|
25
|
-
tz.thermostat_weekly_schedule, tz.thermostat_clear_weekly_schedule, tz.thermostat_programming_operation_mode
|
|
25
|
+
tz.thermostat_weekly_schedule, tz.thermostat_clear_weekly_schedule, tz.thermostat_programming_operation_mode,
|
|
26
|
+
tz.danfoss_window_open_feature],
|
|
26
27
|
exposes: [e.battery(), e.keypad_lockout(), e.programming_operation_mode(),
|
|
27
28
|
exposes.binary('mounted_mode_active', ea.STATE_GET, true, false)
|
|
28
29
|
.withDescription('Is the unit in mounting mode. This is set to `false` for mounted (already on ' +
|
|
@@ -53,6 +54,8 @@ module.exports = [
|
|
|
53
54
|
exposes.binary('radiator_covered', ea.ALL, true, false)
|
|
54
55
|
.withDescription('Set if the TRV should solely rely on external_measured_room_sensor or operate in offset mode. ' +
|
|
55
56
|
'`false` = Auto Offset Mode or `true` = Room Sensor Mode'),
|
|
57
|
+
exposes.binary('window_open_feature', ea.ALL, true, false)
|
|
58
|
+
.withDescription('Whether or not the window open feature is enabled'),
|
|
56
59
|
exposes.numeric('window_open_internal', ea.STATE_GET).withValueMin(0).withValueMax(4)
|
|
57
60
|
.withDescription('0=Quarantine, 1=Windows are closed, 2=Hold - Windows are maybe about to open, ' +
|
|
58
61
|
'3=Open window detected, 4=In window open state from external but detected closed locally'),
|
|
@@ -114,6 +117,7 @@ module.exports = [
|
|
|
114
117
|
}], options);
|
|
115
118
|
|
|
116
119
|
await endpoint.read('hvacThermostat', [
|
|
120
|
+
'danfossWindowOpenFeatureEnable',
|
|
117
121
|
'danfossWindowOpenExternal',
|
|
118
122
|
'danfossDayOfWeek',
|
|
119
123
|
'danfossTriggerTime',
|
package/devices/gledopto.js
CHANGED
|
@@ -62,6 +62,12 @@ const gledoptoExtend = {
|
|
|
62
62
|
}),
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
+
const configureReadModelID = async (device, coordinatorEndpoint, logger) => {
|
|
66
|
+
// https://github.com/Koenkk/zigbee-herdsman-converters/issues/3016#issuecomment-1027726604
|
|
67
|
+
const endpoint = device.endpoints[0];
|
|
68
|
+
await endpoint.read('genBasic', ['modelId']);
|
|
69
|
+
};
|
|
70
|
+
|
|
65
71
|
module.exports = [
|
|
66
72
|
{
|
|
67
73
|
fingerprint: [
|
|
@@ -117,6 +123,7 @@ module.exports = [
|
|
|
117
123
|
ota: ota.zigbeeOTA,
|
|
118
124
|
description: 'Zigbee LED Controller WW/CW (pro)',
|
|
119
125
|
extend: gledoptoExtend.light_onoff_brightness_colortemp(),
|
|
126
|
+
configure: configureReadModelID,
|
|
120
127
|
},
|
|
121
128
|
{
|
|
122
129
|
fingerprint: [
|
|
@@ -180,6 +187,7 @@ module.exports = [
|
|
|
180
187
|
ota: ota.zigbeeOTA,
|
|
181
188
|
description: 'Zigbee LED Controller RGBW (pro)',
|
|
182
189
|
extend: gledoptoExtend.light_onoff_brightness_colortemp_color(),
|
|
190
|
+
configure: configureReadModelID,
|
|
183
191
|
},
|
|
184
192
|
{
|
|
185
193
|
fingerprint: [
|
|
@@ -231,6 +239,15 @@ module.exports = [
|
|
|
231
239
|
extend: gledoptoExtend.light_onoff_brightness_colortemp_color(),
|
|
232
240
|
meta: {disableDefaultResponse: true},
|
|
233
241
|
},
|
|
242
|
+
{
|
|
243
|
+
zigbeeModel: ['GL-C-003P'],
|
|
244
|
+
model: 'GL-C-003P',
|
|
245
|
+
vendor: 'Gledopto',
|
|
246
|
+
ota: ota.zigbeeOTA,
|
|
247
|
+
description: 'Zigbee LED Controller RGB (pro)',
|
|
248
|
+
extend: gledoptoExtend.light_onoff_brightness_color(),
|
|
249
|
+
configure: configureReadModelID,
|
|
250
|
+
},
|
|
234
251
|
{
|
|
235
252
|
zigbeeModel: ['GL-C-008P'],
|
|
236
253
|
model: 'GL-C-008P',
|
|
@@ -239,6 +256,7 @@ module.exports = [
|
|
|
239
256
|
description: 'Zigbee LED Controller RGB+CCT (pro)',
|
|
240
257
|
extend: gledoptoExtend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495]}),
|
|
241
258
|
meta: {disableDefaultResponse: true},
|
|
259
|
+
configure: configureReadModelID,
|
|
242
260
|
},
|
|
243
261
|
{
|
|
244
262
|
zigbeeModel: ['GL-C-009'],
|
|
@@ -260,6 +278,7 @@ module.exports = [
|
|
|
260
278
|
ota: ota.zigbeeOTA,
|
|
261
279
|
description: 'Zigbee LED Controller W (pro)',
|
|
262
280
|
extend: gledoptoExtend.light_onoff_brightness(),
|
|
281
|
+
configure: configureReadModelID,
|
|
263
282
|
},
|
|
264
283
|
{
|
|
265
284
|
zigbeeModel: ['GL-C-009S'],
|
package/devices/kwikset.js
CHANGED
|
@@ -36,7 +36,7 @@ module.exports = [
|
|
|
36
36
|
exposes: [e.lock(), e.battery()],
|
|
37
37
|
},
|
|
38
38
|
{
|
|
39
|
-
zigbeeModel: ['SMARTCODE_DEADBOLT_10_W3'],
|
|
39
|
+
zigbeeModel: ['SMARTCODE_DEADBOLT_10_W3', 'SMARTCODE_DEADBOLT_10T_W3'],
|
|
40
40
|
model: '99140-031',
|
|
41
41
|
vendor: 'Kwikset',
|
|
42
42
|
description: 'SmartCode traditional electronic deadbolt',
|
package/devices/legrand.js
CHANGED
|
@@ -6,6 +6,7 @@ const extend = require('../lib/extend');
|
|
|
6
6
|
const e = exposes.presets;
|
|
7
7
|
const ea = exposes.access;
|
|
8
8
|
const ota = require('../lib/ota');
|
|
9
|
+
const utils = require('../lib/utils');
|
|
9
10
|
|
|
10
11
|
const readInitialBatteryState = async (type, data, device) => {
|
|
11
12
|
if (['deviceAnnounce'].includes(type)) {
|
|
@@ -20,7 +21,9 @@ const fzLocal = {
|
|
|
20
21
|
cluster: 'genOnOff',
|
|
21
22
|
type: 'commandOff',
|
|
22
23
|
convert: (model, msg, publish, options, meta) => {
|
|
23
|
-
|
|
24
|
+
const payload = {action: utils.postfixWithEndpointName('off', msg, model)};
|
|
25
|
+
utils.addActionGroup(payload, msg, model);
|
|
26
|
+
return payload;
|
|
24
27
|
},
|
|
25
28
|
},
|
|
26
29
|
};
|
|
@@ -297,4 +300,24 @@ module.exports = [
|
|
|
297
300
|
toZigbee: [],
|
|
298
301
|
exposes: [e.action(['press_once', 'press_twice'])],
|
|
299
302
|
},
|
|
303
|
+
{
|
|
304
|
+
zigbeeModel: [' Cable outlet\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000' +
|
|
305
|
+
'\u0000\u0000'],
|
|
306
|
+
model: '064882',
|
|
307
|
+
vendor: 'Legrand',
|
|
308
|
+
description: 'Cable outlet with pilot wire and consumption measurement',
|
|
309
|
+
fromZigbee: [fz.legrand_device_mode, fz.legrand_cable_outlet_mode, fz.on_off, fz.electrical_measurement],
|
|
310
|
+
toZigbee: [tz.legrand_deviceMode, tz.legrand_cableOutletMode, tz.on_off, tz.electrical_measurement_power],
|
|
311
|
+
exposes: [exposes.enum('device_mode', ea.ALL, ['pilot_off', 'pilot_on']),
|
|
312
|
+
exposes.enum('cable_outlet_mode', ea.ALL, ['comfort', 'comfort-1', 'comfort-2', 'eco', 'frost_protection', 'off']),
|
|
313
|
+
exposes.switch().withState('state', true, 'Works only when the pilot wire is deactivated'),
|
|
314
|
+
e.power().withAccess(ea.STATE_GET)],
|
|
315
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
316
|
+
const endpoint = device.getEndpoint(1);
|
|
317
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 64576]);
|
|
318
|
+
await reporting.onOff(endpoint);
|
|
319
|
+
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
320
|
+
await reporting.activePower(endpoint);
|
|
321
|
+
},
|
|
322
|
+
},
|
|
300
323
|
];
|
|
@@ -87,6 +87,14 @@ module.exports = [
|
|
|
87
87
|
extend: extend.light_onoff_brightness_colortemp_color(),
|
|
88
88
|
toZigbee: extend.light_onoff_brightness_colortemp_color().toZigbee.concat([tz.tint_scene]),
|
|
89
89
|
},
|
|
90
|
+
{
|
|
91
|
+
fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3210_mntza0sw'}],
|
|
92
|
+
model: '404062',
|
|
93
|
+
vendor: 'Müller Licht',
|
|
94
|
+
description: 'Kea RGB+CCT',
|
|
95
|
+
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
96
|
+
toZigbee: extend.light_onoff_brightness_colortemp_color().toZigbee.concat([tz.tint_scene]),
|
|
97
|
+
},
|
|
90
98
|
{
|
|
91
99
|
zigbeeModel: ['ZBT-Remote-ALL-RGBW'],
|
|
92
100
|
model: 'MLI-404011',
|