zigbee-herdsman-converters 14.0.403 → 14.0.407
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 +104 -16
- package/converters/toZigbee.js +118 -24
- package/devices/acova.js +60 -29
- package/devices/danfoss.js +5 -1
- package/devices/gledopto.js +8 -0
- package/devices/jasco.js +17 -0
- package/devices/kwikset.js +1 -1
- package/devices/legrand.js +24 -1
- package/devices/m/303/274ller_licht.js +8 -0
- package/devices/namron.js +13 -0
- package/devices/orvibo.js +198 -0
- package/devices/philips.js +19 -1
- package/devices/shinasystem.js +21 -0
- package/devices/sinope.js +51 -5
- package/devices/stelpro.js +30 -0
- package/devices/tplink.js +42 -0
- package/devices/tuya.js +41 -22
- package/devices/woox.js +19 -0
- package/devices/xiaomi.js +90 -47
- package/index.js +2 -1
- package/lib/exposes.js +2 -0
- package/lib/reporting.js +4 -0
- package/npm-shrinkwrap.json +186 -221
- 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']) ?
|
|
@@ -3815,19 +3819,21 @@ const converters = {
|
|
|
3815
3819
|
return {open_window_temperature: (value / 10).toFixed(1)};
|
|
3816
3820
|
case tuya.dataPoints.tvErrorStatus:
|
|
3817
3821
|
return {fault_alarm: value};
|
|
3818
|
-
case tuya.dataPoints.tvHolidayMode:
|
|
3819
|
-
|
|
3820
|
-
|
|
3822
|
+
case tuya.dataPoints.tvHolidayMode: {
|
|
3823
|
+
const sy = value.slice(0, 4); const sm = value.slice(4, 6); const sd = value.slice(6, 8);
|
|
3824
|
+
const sh = value.slice(8, 10); const smi = value.slice(10, 12); const ey = value.slice(12, 16);
|
|
3825
|
+
const em = value.slice(16, 18); const ed = value.slice(18, 20); const eh = value.slice(20, 22);
|
|
3826
|
+
const emi = value.slice(22, 24);
|
|
3827
|
+
const hMode = 'start --> ' + sy + ' - ' + sm + ' - ' + sd + ' ' + sh + ' : ' + smi +
|
|
3828
|
+
' stop --> ' + ey + ' - ' + em + ' - ' + ed + ' ' + eh + ' : ' + emi;
|
|
3829
|
+
return {holiday_start_stop: hMode};
|
|
3830
|
+
}
|
|
3821
3831
|
case tuya.dataPoints.tvBoostMode:
|
|
3822
|
-
//
|
|
3832
|
+
// 115 online / Is the device online
|
|
3823
3833
|
return {online: value ? 'ON' : 'OFF'};
|
|
3824
3834
|
case tuya.dataPoints.tvWorkingDay:
|
|
3825
|
-
//
|
|
3835
|
+
// DP-31, Send and Report, ENUM, Week select 0 - 5 days, 1 - 6 days, 2 - 7 days
|
|
3826
3836
|
return {working_day: value};
|
|
3827
|
-
case tuya.dataPoints.tvWeekSchedule:
|
|
3828
|
-
// tvWeekSchedule: 106, Week select 0 - 5 days, 1 - 6 days, 2 - 7 days
|
|
3829
|
-
return {week_schedule: value};
|
|
3830
|
-
|
|
3831
3837
|
case tuya.dataPoints.tvMondaySchedule:
|
|
3832
3838
|
return {schedule_monday:
|
|
3833
3839
|
' ' + value[0] / 6 + 'h:' + value[1] + 'm ' + value[2] / 10 + '°C' +
|
|
@@ -5027,6 +5033,9 @@ const converters = {
|
|
|
5027
5033
|
// dimmer
|
|
5028
5034
|
else if (option0 === 0x0101) payload.device_mode = 'dimmer_on';
|
|
5029
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';
|
|
5030
5039
|
// unknown case
|
|
5031
5040
|
else {
|
|
5032
5041
|
meta.logger.warn(`device_mode ${option0} not recognized, please fix me`);
|
|
@@ -5035,6 +5044,26 @@ const converters = {
|
|
|
5035
5044
|
return payload;
|
|
5036
5045
|
},
|
|
5037
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
|
+
},
|
|
5038
5067
|
legrand_power_alarm: {
|
|
5039
5068
|
cluster: 'haElectricalMeasurement',
|
|
5040
5069
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -5255,13 +5284,16 @@ const converters = {
|
|
|
5255
5284
|
payload.battery = batteryVoltageToPercentage(value, '3V_2100');
|
|
5256
5285
|
} else if (index === 3) payload.temperature = calibrateAndPrecisionRoundOptions(value, options, 'temperature'); // 0x03
|
|
5257
5286
|
else if (index === 5) {
|
|
5258
|
-
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;
|
|
5259
5288
|
} else if (index === 100) {
|
|
5260
5289
|
if (['QBKG20LM', 'QBKG31LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM'].includes(model.model)) {
|
|
5261
5290
|
const mapping = model.model === 'QBCZ15LM' ? 'relay' : 'left';
|
|
5262
5291
|
payload[`state_${mapping}`] = value === 1 ? 'ON' : 'OFF';
|
|
5263
5292
|
} else if (['WXKG14LM', 'WXKG16LM', 'WXKG17LM'].includes(model.model)) {
|
|
5264
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
|
|
5265
5297
|
} else {
|
|
5266
5298
|
payload.state = value === 1 ? 'ON' : 'OFF';
|
|
5267
5299
|
}
|
|
@@ -5273,13 +5305,24 @@ const converters = {
|
|
|
5273
5305
|
payload.state_center = value === 1 ? 'ON' : 'OFF';
|
|
5274
5306
|
} else if (['RTCGQ12LM'].includes(model.model)) {
|
|
5275
5307
|
payload.illuminance = calibrateAndPrecisionRoundOptions(value, options, 'illuminance');
|
|
5308
|
+
} else if (['ZNJLBL01LM'].includes(model.model)) {
|
|
5309
|
+
payload.battery = value;
|
|
5276
5310
|
}
|
|
5277
5311
|
} else if (index ===102 ) {
|
|
5278
5312
|
if (['QBKG25LM', 'QBKG34LM'].includes(model.model)) {
|
|
5279
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];
|
|
5280
5317
|
}
|
|
5281
|
-
} else if (index ===
|
|
5282
|
-
else if (index ===
|
|
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];
|
|
5324
|
+
}
|
|
5325
|
+
} else if (index === 149) {
|
|
5283
5326
|
payload.energy = precisionRound(value, 2); // 0x95
|
|
5284
5327
|
// Consumption is deprecated
|
|
5285
5328
|
payload.consumption = payload.energy;
|
|
@@ -5318,6 +5361,15 @@ const converters = {
|
|
|
5318
5361
|
if (msg.data.hasOwnProperty('313')) payload.state = msg.data['313'] === 1 ? 'preparation' : 'work'; // JT-BZ-01AQ/A
|
|
5319
5362
|
if (msg.data.hasOwnProperty('314')) payload.gas = msg.data['314'] === 1; // JT-BZ-01AQ/A
|
|
5320
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']];
|
|
5321
5373
|
if (msg.data.hasOwnProperty('331')) payload.linkage_alarm = msg.data['331'] === 1; // JT-BZ-01AQ/A
|
|
5322
5374
|
if (msg.data.hasOwnProperty('512')) {
|
|
5323
5375
|
if (['ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM'].includes(model.model)) {
|
|
@@ -5334,6 +5386,7 @@ const converters = {
|
|
|
5334
5386
|
if (msg.data.hasOwnProperty('523')) payload.overload_protection = precisionRound(msg.data['523'], 2);
|
|
5335
5387
|
if (msg.data.hasOwnProperty('550')) payload.button_switch_mode = msg.data['550'] === 1 ? 'relay_and_usb' : 'relay';
|
|
5336
5388
|
if (msg.data['mode'] !== undefined) payload.operation_mode = ['command', 'event'][msg.data['mode']];
|
|
5389
|
+
if (msg.data.hasOwnProperty('1289')) payload.dimmer_mode = {3: 'rgbw', 1: 'dual_ct'}[msg.data['1289']];
|
|
5337
5390
|
return payload;
|
|
5338
5391
|
},
|
|
5339
5392
|
},
|
|
@@ -5403,7 +5456,8 @@ const converters = {
|
|
|
5403
5456
|
}
|
|
5404
5457
|
|
|
5405
5458
|
let buttonLookup = null;
|
|
5406
|
-
if (['WXKG02LM_rev2', 'WXKG07LM', '
|
|
5459
|
+
if (['WXKG02LM_rev2', 'WXKG07LM', 'WXKG15LM', 'WXKG17LM',
|
|
5460
|
+
'WRS-R02'].includes(model.model)) buttonLookup = {1: 'left', 2: 'right', 3: 'both'};
|
|
5407
5461
|
if (['QBKG12LM', 'QBKG24LM'].includes(model.model)) buttonLookup = {5: 'left', 6: 'right', 7: 'both'};
|
|
5408
5462
|
if (['QBKG39LM', 'QBKG41LM', 'WS-EUK02', 'WS-EUK04', 'QBKG20LM', 'QBKG31LM'].includes(model.model)) {
|
|
5409
5463
|
buttonLookup = {41: 'left', 42: 'right', 51: 'both'};
|
|
@@ -5806,6 +5860,40 @@ const converters = {
|
|
|
5806
5860
|
}
|
|
5807
5861
|
},
|
|
5808
5862
|
},
|
|
5863
|
+
xiaomi_curtain_acn002_position: {
|
|
5864
|
+
cluster: 'genAnalogOutput',
|
|
5865
|
+
type: ['attributeReport', 'readResponse'],
|
|
5866
|
+
options: [exposes.options.invert_cover()],
|
|
5867
|
+
convert: (model, msg, publish, options, meta) => {
|
|
5868
|
+
let position = precisionRound(msg.data['presentValue'], 2);
|
|
5869
|
+
position = options.invert_cover ? 100 - position : position;
|
|
5870
|
+
return {position: position};
|
|
5871
|
+
},
|
|
5872
|
+
},
|
|
5873
|
+
xiaomi_curtain_acn002_status: {
|
|
5874
|
+
cluster: 'genMultistateOutput',
|
|
5875
|
+
type: ['attributeReport', 'readResponse'],
|
|
5876
|
+
convert: (model, msg, publish, options, meta) => {
|
|
5877
|
+
let running = false;
|
|
5878
|
+
const data = msg.data;
|
|
5879
|
+
const lookup = {
|
|
5880
|
+
0: 'declining',
|
|
5881
|
+
1: 'rising',
|
|
5882
|
+
2: 'pause',
|
|
5883
|
+
3: 'blocked',
|
|
5884
|
+
};
|
|
5885
|
+
if (data && data.hasOwnProperty('presentValue')) {
|
|
5886
|
+
const value = data['presentValue'];
|
|
5887
|
+
if (value < 2) {
|
|
5888
|
+
running = true;
|
|
5889
|
+
}
|
|
5890
|
+
return {
|
|
5891
|
+
motor_state: lookup[value],
|
|
5892
|
+
running: running,
|
|
5893
|
+
};
|
|
5894
|
+
}
|
|
5895
|
+
},
|
|
5896
|
+
},
|
|
5809
5897
|
xiaomi_operation_mode_basic: {
|
|
5810
5898
|
cluster: 'genBasic',
|
|
5811
5899
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -8154,7 +8242,7 @@ const converters = {
|
|
|
8154
8242
|
cluster: 'genOnOff',
|
|
8155
8243
|
type: 'raw',
|
|
8156
8244
|
convert: (model, msg, publish, options, meta) => {
|
|
8157
|
-
if (hasAlreadyProcessedMessage(msg, msg.data[
|
|
8245
|
+
if (hasAlreadyProcessedMessage(msg, msg.data[1])) return;
|
|
8158
8246
|
let action;
|
|
8159
8247
|
if (msg.data[2] == 253) {
|
|
8160
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]);
|
|
@@ -2206,6 +2244,25 @@ const converters = {
|
|
|
2206
2244
|
await entity.read('aqaraOpple', [0x00F0], manufacturerOptions.xiaomi);
|
|
2207
2245
|
},
|
|
2208
2246
|
},
|
|
2247
|
+
xiaomi_dimmer_mode: {
|
|
2248
|
+
key: ['dimmer_mode'],
|
|
2249
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2250
|
+
const lookup = {'rgbw': 3, 'dual_ct': 1};
|
|
2251
|
+
value = value.toLowerCase();
|
|
2252
|
+
if (['rgbw'].includes(value)) {
|
|
2253
|
+
await entity.write('aqaraOpple', {0x0509: {value: lookup[value], type: 0x23}}, manufacturerOptions.xiaomi);
|
|
2254
|
+
await entity.write('aqaraOpple', {0x050F: {value: 1, type: 0x23}}, manufacturerOptions.xiaomi);
|
|
2255
|
+
} else {
|
|
2256
|
+
await entity.write('aqaraOpple', {0x0509: {value: lookup[value], type: 0x23}}, manufacturerOptions.xiaomi);
|
|
2257
|
+
// Turn on dimming channel 1 and channel 2
|
|
2258
|
+
await entity.write('aqaraOpple', {0x050F: {value: 3, type: 0x23}}, manufacturerOptions.xiaomi);
|
|
2259
|
+
}
|
|
2260
|
+
return {state: {dimmer_mode: value}};
|
|
2261
|
+
},
|
|
2262
|
+
convertGet: async (entity, key, value, meta) => {
|
|
2263
|
+
await entity.read('aqaraOpple', [0x0509], manufacturerOptions.xiaomi);
|
|
2264
|
+
},
|
|
2265
|
+
},
|
|
2209
2266
|
xiaomi_switch_operation_mode_basic: {
|
|
2210
2267
|
key: ['operation_mode'],
|
|
2211
2268
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -2333,7 +2390,12 @@ const converters = {
|
|
|
2333
2390
|
options: [exposes.options.invert_cover()],
|
|
2334
2391
|
convertSet: async (entity, key, value, meta) => {
|
|
2335
2392
|
if (key === 'state' && typeof value === 'string' && value.toLowerCase() === 'stop') {
|
|
2336
|
-
|
|
2393
|
+
if (meta.mapped.model == 'ZNJLBL01LM') {
|
|
2394
|
+
const payload = {'presentValue': 2};
|
|
2395
|
+
await entity.write('genMultistateOutput', payload);
|
|
2396
|
+
} else {
|
|
2397
|
+
await entity.command('closuresWindowCovering', 'stop', {}, utils.getOptions(meta.mapped, entity));
|
|
2398
|
+
}
|
|
2337
2399
|
|
|
2338
2400
|
// Xiaomi curtain does not send position update on stop, request this.
|
|
2339
2401
|
await entity.read('genAnalogOutput', [0x0055]);
|
|
@@ -2355,6 +2417,12 @@ const converters = {
|
|
|
2355
2417
|
await entity.read('genAnalogOutput', [0x0055]);
|
|
2356
2418
|
},
|
|
2357
2419
|
},
|
|
2420
|
+
xiaomi_curtain_acn002_status: {
|
|
2421
|
+
key: ['motor_state'],
|
|
2422
|
+
convertGet: async (entity, key, meta) => {
|
|
2423
|
+
await entity.read('genMultistateOutput', [0x0055]);
|
|
2424
|
+
},
|
|
2425
|
+
},
|
|
2358
2426
|
ledvance_commands: {
|
|
2359
2427
|
/* deprectated osram_*/
|
|
2360
2428
|
key: ['set_transition', 'remember_state', 'osram_set_transition', 'osram_remember_state'],
|
|
@@ -2684,6 +2752,16 @@ const converters = {
|
|
|
2684
2752
|
await entity.read('hvacThermostat', ['danfossTriggerTime'], manufacturerOptions.danfoss);
|
|
2685
2753
|
},
|
|
2686
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
|
+
},
|
|
2687
2765
|
danfoss_window_open_internal: {
|
|
2688
2766
|
key: ['window_open_internal'],
|
|
2689
2767
|
convertGet: async (entity, key, meta) => {
|
|
@@ -2967,8 +3045,8 @@ const converters = {
|
|
|
2967
3045
|
key: [
|
|
2968
3046
|
'child_lock', 'open_window', 'open_window_temperature', 'frost_protection', 'heating_stop',
|
|
2969
3047
|
'current_heating_setpoint', 'local_temperature_calibration', 'preset', 'boost_timeset_countdown',
|
|
2970
|
-
'
|
|
2971
|
-
'working_day', '
|
|
3048
|
+
'holiday_start_stop', 'holiday_temperature', 'comfort_temperature', 'eco_temperature',
|
|
3049
|
+
'working_day', 'week_schedule_programming', 'online', 'holiday_mode_date',
|
|
2972
3050
|
],
|
|
2973
3051
|
convertSet: async (entity, key, value, meta) => {
|
|
2974
3052
|
switch (key) {
|
|
@@ -2981,6 +3059,7 @@ const converters = {
|
|
|
2981
3059
|
await tuya.sendDataPointBool(entity, tuya.dataPoints.tvHeatingStop, 1);
|
|
2982
3060
|
} else {
|
|
2983
3061
|
await tuya.sendDataPointBool(entity, tuya.dataPoints.tvHeatingStop, 0);
|
|
3062
|
+
await utils.sleep(500);
|
|
2984
3063
|
await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvMode, 1 /* manual */);
|
|
2985
3064
|
}
|
|
2986
3065
|
break;
|
|
@@ -2989,6 +3068,7 @@ const converters = {
|
|
|
2989
3068
|
await tuya.sendDataPointBool(entity, tuya.dataPoints.tvFrostDetection, 1);
|
|
2990
3069
|
} else {
|
|
2991
3070
|
await tuya.sendDataPointBool(entity, tuya.dataPoints.tvFrostDetection, 0);
|
|
3071
|
+
await utils.sleep(500);
|
|
2992
3072
|
await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvMode, 1 /* manual */);
|
|
2993
3073
|
}
|
|
2994
3074
|
break;
|
|
@@ -3005,6 +3085,7 @@ const converters = {
|
|
|
3005
3085
|
break;
|
|
3006
3086
|
case 'current_heating_setpoint':
|
|
3007
3087
|
await tuya.sendDataPointValue(entity, tuya.dataPoints.tvHeatingSetpoint, value * 10);
|
|
3088
|
+
await utils.sleep(500);
|
|
3008
3089
|
await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvMode, 1 /* manual */);
|
|
3009
3090
|
break;
|
|
3010
3091
|
case 'holiday_temperature':
|
|
@@ -3023,19 +3104,26 @@ const converters = {
|
|
|
3023
3104
|
case 'open_window_temperature':
|
|
3024
3105
|
await tuya.sendDataPointValue(entity, tuya.dataPoints.tvOpenWindowTemp, value * 10);
|
|
3025
3106
|
break;
|
|
3026
|
-
case '
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3107
|
+
case 'holiday_start_stop': {
|
|
3108
|
+
const numberPattern = /\d+/g;
|
|
3109
|
+
value = value.match(numberPattern).join([]).toString();
|
|
3110
|
+
return tuya.sendDataPointStringBuffer(entity, tuya.dataPoints.tvHolidayMode, value);
|
|
3111
|
+
}
|
|
3030
3112
|
case 'online':
|
|
3031
|
-
// 115
|
|
3113
|
+
// 115 online / Is the device online
|
|
3032
3114
|
await tuya.sendDataPointBool(entity, tuya.dataPoints.tvBoostMode, value === 'ON');
|
|
3033
3115
|
break;
|
|
3034
|
-
case '
|
|
3035
|
-
|
|
3036
|
-
const
|
|
3037
|
-
|
|
3038
|
-
|
|
3116
|
+
case 'working_day': {
|
|
3117
|
+
// DP-31, Send and Report, ENUM, Week select 0 - 5 days, 1 - 6 days, 2 - 7 days
|
|
3118
|
+
const workLookup = {'0': 0, '1': 1, '2': 2, '3': 3};
|
|
3119
|
+
const workDay = workLookup[value];
|
|
3120
|
+
await tuya.sendDataPointEnum(entity, tuya.dataPoints.tvWorkingDay, workDay);
|
|
3121
|
+
return {state: {working_day: value}};
|
|
3122
|
+
}
|
|
3123
|
+
case 'week_schedule_programming':
|
|
3124
|
+
// DP-106, Send Only, raw, week_program3_day
|
|
3125
|
+
await tuya.sendDataPointRaw(entity, tuya.dataPoints.tvWeekSchedule, value);
|
|
3126
|
+
break;
|
|
3039
3127
|
|
|
3040
3128
|
default: // Unknown key
|
|
3041
3129
|
meta.logger.warn(`toZigbee.tvtwo_thermostat: Unhandled key ${key}`);
|
|
@@ -4450,6 +4538,9 @@ const converters = {
|
|
|
4450
4538
|
// contactor
|
|
4451
4539
|
'switch': 0x0003,
|
|
4452
4540
|
'auto': 0x0004,
|
|
4541
|
+
// pilot wire
|
|
4542
|
+
'pilot_on': 0x0002,
|
|
4543
|
+
'pilot_off': 0x0001,
|
|
4453
4544
|
};
|
|
4454
4545
|
|
|
4455
4546
|
value = value.toLowerCase();
|
|
@@ -4462,6 +4553,15 @@ const converters = {
|
|
|
4462
4553
|
await entity.read('manuSpecificLegrandDevices', [0x0000, 0x0001, 0x0002], manufacturerOptions.legrand);
|
|
4463
4554
|
},
|
|
4464
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
|
+
},
|
|
4465
4565
|
legrand_powerAlarm: {
|
|
4466
4566
|
key: ['power_alarm'],
|
|
4467
4567
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -6669,7 +6769,7 @@ const converters = {
|
|
|
6669
6769
|
await tuya.sendDataPoints(entity, [
|
|
6670
6770
|
tuya.dpValueFromEnum(tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.white),
|
|
6671
6771
|
tuya.dpValueFromIntValue(tuya.dataPoints.dimmerLevel, newValue),
|
|
6672
|
-
], 'dataRequest'
|
|
6772
|
+
], 'dataRequest');
|
|
6673
6773
|
|
|
6674
6774
|
return {state: (key == 'white_brightness') ? {white_brightness: value} : {brightness: value}};
|
|
6675
6775
|
} else if (key == 'color_temp') {
|
|
@@ -6696,7 +6796,7 @@ const converters = {
|
|
|
6696
6796
|
await tuya.sendDataPoints(entity, [
|
|
6697
6797
|
tuya.dpValueFromEnum(tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.white),
|
|
6698
6798
|
tuya.dpValueFromIntValue(tuya.dataPoints.silvercrestSetColorTemp, data),
|
|
6699
|
-
], 'dataRequest'
|
|
6799
|
+
], 'dataRequest');
|
|
6700
6800
|
|
|
6701
6801
|
return {state: {color_temp: value}};
|
|
6702
6802
|
} else if (key == 'color' || (separateWhite && (key == 'brightness'))) {
|
|
@@ -6775,13 +6875,7 @@ const converters = {
|
|
|
6775
6875
|
tuya.dpValueFromStringBuffer(tuya.dataPoints.silvercrestSetColor, data),
|
|
6776
6876
|
];
|
|
6777
6877
|
|
|
6778
|
-
|
|
6779
|
-
// restore white state
|
|
6780
|
-
const newValue = utils.mapNumberRange(meta.state.white_brightness, 0, 255, 0, 1000);
|
|
6781
|
-
commands.push(tuya.dpValueFromEnum(tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.white));
|
|
6782
|
-
commands.push(tuya.dpValueFromIntValue(tuya.dataPoints.dimmerLevel, newValue));
|
|
6783
|
-
}
|
|
6784
|
-
await tuya.sendDataPoints(entity, commands, 'dataRequest', 1);
|
|
6878
|
+
await tuya.sendDataPoints(entity, commands, 'dataRequest');
|
|
6785
6879
|
|
|
6786
6880
|
return {state: newState};
|
|
6787
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
|
@@ -231,6 +231,14 @@ module.exports = [
|
|
|
231
231
|
extend: gledoptoExtend.light_onoff_brightness_colortemp_color(),
|
|
232
232
|
meta: {disableDefaultResponse: true},
|
|
233
233
|
},
|
|
234
|
+
{
|
|
235
|
+
zigbeeModel: ['GL-C-003P'],
|
|
236
|
+
model: 'GL-C-003P',
|
|
237
|
+
vendor: 'Gledopto',
|
|
238
|
+
ota: ota.zigbeeOTA,
|
|
239
|
+
description: 'Zigbee LED Controller RGB (pro)',
|
|
240
|
+
extend: gledoptoExtend.light_onoff_brightness_color(),
|
|
241
|
+
},
|
|
234
242
|
{
|
|
235
243
|
zigbeeModel: ['GL-C-008P'],
|
|
236
244
|
model: 'GL-C-008P',
|
package/devices/jasco.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const reporting = require('../lib/reporting');
|
|
2
2
|
const extend = require('../lib/extend');
|
|
3
|
+
const exposes = require('../lib/exposes');
|
|
4
|
+
const e = exposes.presets;
|
|
3
5
|
|
|
4
6
|
module.exports = [
|
|
5
7
|
{
|
|
@@ -15,4 +17,19 @@ module.exports = [
|
|
|
15
17
|
await reporting.onOff(endpoint);
|
|
16
18
|
},
|
|
17
19
|
},
|
|
20
|
+
{
|
|
21
|
+
zigbeeModel: ['43132'],
|
|
22
|
+
model: '43132',
|
|
23
|
+
vendor: 'Jasco',
|
|
24
|
+
description: 'Zigbee smart outlet',
|
|
25
|
+
extend: extend.switch(),
|
|
26
|
+
exposes: [e.switch(), e.power(), e.energy()],
|
|
27
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
28
|
+
const endpoint = device.getEndpoint(1);
|
|
29
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'seMetering']);
|
|
30
|
+
await reporting.onOff(endpoint);
|
|
31
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
32
|
+
await reporting.instantaneousDemand(endpoint);
|
|
33
|
+
},
|
|
34
|
+
},
|
|
18
35
|
];
|