zigbee-herdsman-converters 14.0.370 → 14.0.374
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 +149 -3
- package/converters/toZigbee.js +132 -3
- package/devices/awox.js +5 -0
- package/devices/bticino.js +1 -1
- package/devices/centralite.js +10 -6
- package/devices/innr.js +8 -0
- package/devices/iris.js +15 -0
- package/devices/legrand.js +1 -1
- package/devices/lidl.js +1 -1
- package/devices/nous.js +9 -0
- package/devices/osram.js +7 -4
- package/devices/philips.js +12 -3
- package/devices/shinasystem.js +1 -0
- package/devices/skydance.js +74 -0
- package/devices/tuya.js +27 -2
- package/devices/xiaomi.js +35 -16
- package/devices/zemismart.js +11 -7
- package/lib/exposes.js +1 -1
- package/lib/tuya.js +6 -1
- package/npm-shrinkwrap.json +1 -1
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -2577,6 +2577,28 @@ const converters = {
|
|
|
2577
2577
|
}
|
|
2578
2578
|
},
|
|
2579
2579
|
},
|
|
2580
|
+
wls100z_water_leak: {
|
|
2581
|
+
cluster: 'manuSpecificTuya',
|
|
2582
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
2583
|
+
convert: (model, msg, publish, options, meta) => {
|
|
2584
|
+
const result = {};
|
|
2585
|
+
for (const dpValue of msg.data.dpValues) {
|
|
2586
|
+
const value = tuya.getDataValue(dpValue);
|
|
2587
|
+
switch (dpValue.dp) {
|
|
2588
|
+
case tuya.dataPoints.wlsWaterLeak:
|
|
2589
|
+
result.water_leak = value < 1;
|
|
2590
|
+
break;
|
|
2591
|
+
case tuya.dataPoints.wlsBatteryPercentage:
|
|
2592
|
+
result.battery = value;
|
|
2593
|
+
break;
|
|
2594
|
+
default:
|
|
2595
|
+
meta.logger.warn(`zigbee-herdsman-converters:wls100z_water_leak:` +
|
|
2596
|
+
`NOT RECOGNIZED DP #${dpValue.dp} with data ${JSON.stringify(dpValue)}`);
|
|
2597
|
+
}
|
|
2598
|
+
}
|
|
2599
|
+
return result;
|
|
2600
|
+
},
|
|
2601
|
+
},
|
|
2580
2602
|
livolo_switch_state: {
|
|
2581
2603
|
cluster: 'genOnOff',
|
|
2582
2604
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -4995,7 +5017,8 @@ const converters = {
|
|
|
4995
5017
|
aqara_opple: {
|
|
4996
5018
|
cluster: 'aqaraOpple',
|
|
4997
5019
|
type: ['attributeReport', 'readResponse'],
|
|
4998
|
-
options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature')
|
|
5020
|
+
options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
|
|
5021
|
+
exposes.options.precision('illuminance'), exposes.options.calibration('illuminance', 'percentual')],
|
|
4999
5022
|
convert: (model, msg, publish, options, meta) => {
|
|
5000
5023
|
const payload = {};
|
|
5001
5024
|
if (msg.data.hasOwnProperty('247')) {
|
|
@@ -5120,6 +5143,8 @@ const converters = {
|
|
|
5120
5143
|
if (['QBKG19LM', 'QBKG20LM', 'QBKG39LM', 'QBKG41LM', 'QBCZ15LM'].includes(model.model)) {
|
|
5121
5144
|
const mapping = model.model === 'QBCZ15LM' ? 'usb' : 'right';
|
|
5122
5145
|
payload[`state_${mapping}`] = value === 1 ? 'ON' : 'OFF';
|
|
5146
|
+
} else if (['RTCGQ12LM'].includes(model.model)) {
|
|
5147
|
+
payload.illuminance = calibrateAndPrecisionRoundOptions(value, options, 'illuminance');
|
|
5123
5148
|
}
|
|
5124
5149
|
} else if (index === 149) {
|
|
5125
5150
|
payload.energy = precisionRound(value, 2); // 0x95
|
|
@@ -5135,7 +5160,7 @@ const converters = {
|
|
|
5135
5160
|
if (msg.data.hasOwnProperty('0')) payload.detection_period = msg.data['0'];
|
|
5136
5161
|
if (msg.data.hasOwnProperty('4')) payload.mode_switch = {4: 'anti_flicker_mode', 1: 'quick_mode'}[msg.data['4']];
|
|
5137
5162
|
if (msg.data.hasOwnProperty('10')) payload.switch_type = {1: 'toggle', 2: 'momentary'}[msg.data['10']];
|
|
5138
|
-
if (msg.data.hasOwnProperty('258')) payload.
|
|
5163
|
+
if (msg.data.hasOwnProperty('258')) payload.occupancy_timeout = msg.data['258'];
|
|
5139
5164
|
if (msg.data.hasOwnProperty('268')) payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[msg.data['268']];
|
|
5140
5165
|
if (msg.data.hasOwnProperty('512')) {
|
|
5141
5166
|
if (['ZNCZ15LM', 'QBCZ14LM', 'QBCZ15LM'].includes(model.model)) {
|
|
@@ -5288,6 +5313,65 @@ const converters = {
|
|
|
5288
5313
|
return payload;
|
|
5289
5314
|
},
|
|
5290
5315
|
},
|
|
5316
|
+
RTCGQ12LM_occupancy_illuminance: {
|
|
5317
|
+
cluster: 'aqaraOpple',
|
|
5318
|
+
type: ['attributeReport', 'readResponse'],
|
|
5319
|
+
options: [exposes.options.precision('illuminance'), exposes.options.calibration('illuminance', 'percentual')],
|
|
5320
|
+
convert: (model, msg, publish, options, meta) => {
|
|
5321
|
+
if (msg.data.hasOwnProperty('illuminance')) {
|
|
5322
|
+
// The occupancy sensor only sends a message when motion detected.
|
|
5323
|
+
// Therefore we need to publish the no_motion detected by ourselves.
|
|
5324
|
+
const timeout = meta && meta.state && meta.state.hasOwnProperty('occupancy_timeout') ? meta.state.occupancy_timeout : 60;
|
|
5325
|
+
|
|
5326
|
+
// Stop existing timers because motion is detected and set a new one.
|
|
5327
|
+
globalStore.getValue(msg.endpoint, 'timers', []).forEach((t) => clearTimeout(t));
|
|
5328
|
+
globalStore.putValue(msg.endpoint, 'timers', []);
|
|
5329
|
+
|
|
5330
|
+
if (timeout !== 0) {
|
|
5331
|
+
const timer = setTimeout(() => {
|
|
5332
|
+
publish({occupancy: false});
|
|
5333
|
+
}, timeout * 1000);
|
|
5334
|
+
|
|
5335
|
+
globalStore.getValue(msg.endpoint, 'timers').push(timer);
|
|
5336
|
+
}
|
|
5337
|
+
|
|
5338
|
+
const illuminance = msg.data['illuminance'] - 65536;
|
|
5339
|
+
return {occupancy: true, illuminance: calibrateAndPrecisionRoundOptions(illuminance, options, 'illuminance')};
|
|
5340
|
+
}
|
|
5341
|
+
},
|
|
5342
|
+
},
|
|
5343
|
+
RTCGQ13LM_occupancy: {
|
|
5344
|
+
// This is for occupancy sensor that only send a message when motion detected,
|
|
5345
|
+
// but do not send a motion stop.
|
|
5346
|
+
// Therefore we need to publish the no_motion detected by ourselves.
|
|
5347
|
+
cluster: 'msOccupancySensing',
|
|
5348
|
+
type: ['attributeReport', 'readResponse'],
|
|
5349
|
+
convert: (model, msg, publish, options, meta) => {
|
|
5350
|
+
if (msg.data.occupancy !== 1) {
|
|
5351
|
+
// In case of 0 no occupancy is reported.
|
|
5352
|
+
// https://github.com/Koenkk/zigbee2mqtt/issues/467
|
|
5353
|
+
return;
|
|
5354
|
+
}
|
|
5355
|
+
|
|
5356
|
+
// The occupancy sensor only sends a message when motion detected.
|
|
5357
|
+
// Therefore we need to publish the no_motion detected by ourselves.
|
|
5358
|
+
const timeout = meta && meta.state && meta.state.hasOwnProperty('occupancy_timeout') ? meta.state.occupancy_timeout : 60;
|
|
5359
|
+
|
|
5360
|
+
// Stop existing timers because motion is detected and set a new one.
|
|
5361
|
+
globalStore.getValue(msg.endpoint, 'timers', []).forEach((t) => clearTimeout(t));
|
|
5362
|
+
globalStore.putValue(msg.endpoint, 'timers', []);
|
|
5363
|
+
|
|
5364
|
+
if (timeout !== 0) {
|
|
5365
|
+
const timer = setTimeout(() => {
|
|
5366
|
+
publish({occupancy: false});
|
|
5367
|
+
}, timeout * 1000);
|
|
5368
|
+
|
|
5369
|
+
globalStore.getValue(msg.endpoint, 'timers').push(timer);
|
|
5370
|
+
}
|
|
5371
|
+
|
|
5372
|
+
return {occupancy: true};
|
|
5373
|
+
},
|
|
5374
|
+
},
|
|
5291
5375
|
xiaomi_WXKG01LM_action: {
|
|
5292
5376
|
cluster: 'genOnOff',
|
|
5293
5377
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -7450,6 +7534,25 @@ const converters = {
|
|
|
7450
7534
|
}
|
|
7451
7535
|
},
|
|
7452
7536
|
},
|
|
7537
|
+
tuya_smart_vibration_sensor: {
|
|
7538
|
+
cluster: 'manuSpecificTuya',
|
|
7539
|
+
type: ['commandGetData', 'commandDataResponse', 'raw'],
|
|
7540
|
+
convert: (model, msg, publish, options, meta) => {
|
|
7541
|
+
const dp = msg.data.dp;
|
|
7542
|
+
const value = tuya.getDataValue(msg.data.datatype, msg.data.data);
|
|
7543
|
+
switch (dp) {
|
|
7544
|
+
case tuya.dataPoints.state:
|
|
7545
|
+
return {contact: Boolean(value)};
|
|
7546
|
+
case tuya.dataPoints.thitBatteryPercentage:
|
|
7547
|
+
return {battery: value};
|
|
7548
|
+
case tuya.dataPoints.tuyaVibration:
|
|
7549
|
+
return {vibration: Boolean(value)};
|
|
7550
|
+
default:
|
|
7551
|
+
meta.logger.warn(`zigbee-herdsman-converters:tuya_smart_vibration_sensor: NOT RECOGNIZED ` +
|
|
7552
|
+
`DP #${dp} with data ${JSON.stringify(msg.data)}`);
|
|
7553
|
+
}
|
|
7554
|
+
},
|
|
7555
|
+
},
|
|
7453
7556
|
moes_thermostat_tv: {
|
|
7454
7557
|
cluster: 'manuSpecificTuya',
|
|
7455
7558
|
type: ['commandDataResponse', 'commandDataReport', 'raw'],
|
|
@@ -7540,7 +7643,11 @@ const converters = {
|
|
|
7540
7643
|
cluster: 'genAnalogInput',
|
|
7541
7644
|
type: ['attributeReport', 'readResponse'],
|
|
7542
7645
|
convert: (model, msg, publish, options, meta) => {
|
|
7543
|
-
|
|
7646
|
+
const lookup = {'0': 'idle', '1': 'in', '2': 'out'};
|
|
7647
|
+
const value = precisionRound(parseFloat(msg.data['presentValue']), 1);
|
|
7648
|
+
let result = null;
|
|
7649
|
+
result = {people: precisionRound(msg.data.presentValue, 0), status: lookup[value*10%10]};
|
|
7650
|
+
return result;
|
|
7544
7651
|
},
|
|
7545
7652
|
},
|
|
7546
7653
|
sihas_action: {
|
|
@@ -7725,6 +7832,40 @@ const converters = {
|
|
|
7725
7832
|
};
|
|
7726
7833
|
},
|
|
7727
7834
|
},
|
|
7835
|
+
tuya_light_wz5: {
|
|
7836
|
+
cluster: 'manuSpecificTuya',
|
|
7837
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
7838
|
+
convert: (model, msg, publish, options, meta) => {
|
|
7839
|
+
const separateWhite = (model.meta && model.meta.separateWhite);
|
|
7840
|
+
const result = {};
|
|
7841
|
+
// eslint-disable-next-line no-unused-vars
|
|
7842
|
+
for (const [i, dpValue] of msg.data.dpValues.entries()) {
|
|
7843
|
+
const dp = dpValue.dp;
|
|
7844
|
+
const value = tuya.getDataValue(dpValue);
|
|
7845
|
+
if (dp === tuya.dataPoints.state) {
|
|
7846
|
+
result.state = value ? 'ON': 'OFF';
|
|
7847
|
+
} else if (dp === tuya.dataPoints.silvercrestSetBrightness) {
|
|
7848
|
+
const brightness = mapNumberRange(value, 0, 1000, 0, 255);
|
|
7849
|
+
if (separateWhite) {
|
|
7850
|
+
result.white_brightness = brightness;
|
|
7851
|
+
} else {
|
|
7852
|
+
result.brightness = brightness;
|
|
7853
|
+
}
|
|
7854
|
+
} else if (dp === tuya.dataPoints.silvercrestSetColor) {
|
|
7855
|
+
const h = parseInt(value.substring(0, 4), 16);
|
|
7856
|
+
const s = parseInt(value.substring(4, 8), 16);
|
|
7857
|
+
const b = parseInt(value.substring(8, 12), 16);
|
|
7858
|
+
result.color_mode = 'hs';
|
|
7859
|
+
result.color = {hue: h, saturation: mapNumberRange(s, 0, 1000, 0, 100)};
|
|
7860
|
+
result.brightness = mapNumberRange(b, 0, 1000, 0, 255);
|
|
7861
|
+
} else if (dp === tuya.dataPoints.silvercrestSetColorTemp) {
|
|
7862
|
+
const [colorTempMin, colorTempMax] = [250, 454];
|
|
7863
|
+
result.color_temp = mapNumberRange(value, 0, 1000, colorTempMax, colorTempMin);
|
|
7864
|
+
}
|
|
7865
|
+
}
|
|
7866
|
+
return result;
|
|
7867
|
+
},
|
|
7868
|
+
},
|
|
7728
7869
|
// #endregion
|
|
7729
7870
|
|
|
7730
7871
|
// #region Ignore converters (these message dont need parsing).
|
|
@@ -7878,6 +8019,11 @@ const converters = {
|
|
|
7878
8019
|
type: ['commandMcuSyncTime'],
|
|
7879
8020
|
convert: (model, msg, publish, options, meta) => null,
|
|
7880
8021
|
},
|
|
8022
|
+
ignore_tuya_raw: {
|
|
8023
|
+
cluster: 'manuSpecificTuya',
|
|
8024
|
+
type: ['raw'],
|
|
8025
|
+
convert: (model, msg, publish, options, meta) => null,
|
|
8026
|
+
},
|
|
7881
8027
|
// #endregion
|
|
7882
8028
|
};
|
|
7883
8029
|
|
package/converters/toZigbee.js
CHANGED
|
@@ -1915,6 +1915,8 @@ const converters = {
|
|
|
1915
1915
|
}
|
|
1916
1916
|
}
|
|
1917
1917
|
}
|
|
1918
|
+
|
|
1919
|
+
return {state: {hue_power_on_behavior: value}};
|
|
1918
1920
|
},
|
|
1919
1921
|
},
|
|
1920
1922
|
hue_power_on_error: {
|
|
@@ -2076,12 +2078,12 @@ const converters = {
|
|
|
2076
2078
|
await entity.read('aqaraOpple', [0x0000], manufacturerOptions.xiaomi);
|
|
2077
2079
|
},
|
|
2078
2080
|
},
|
|
2079
|
-
|
|
2080
|
-
key: ['
|
|
2081
|
+
aqara_occupancy_timeout: {
|
|
2082
|
+
key: ['occupancy_timeout'],
|
|
2081
2083
|
convertSet: async (entity, key, value, meta) => {
|
|
2082
2084
|
value *= 1;
|
|
2083
2085
|
await entity.write('aqaraOpple', {0x0102: {value: [value], type: 0x20}}, manufacturerOptions.xiaomi);
|
|
2084
|
-
return {state: {
|
|
2086
|
+
return {state: {occupancy_timeout: value}};
|
|
2085
2087
|
},
|
|
2086
2088
|
convertGet: async (entity, key, meta) => {
|
|
2087
2089
|
await entity.read('aqaraOpple', [0x0102], manufacturerOptions.xiaomi);
|
|
@@ -6404,6 +6406,133 @@ const converters = {
|
|
|
6404
6406
|
return {state: {click_mode: value}};
|
|
6405
6407
|
},
|
|
6406
6408
|
},
|
|
6409
|
+
tuya_light_wz5: {
|
|
6410
|
+
key: ['color', 'color_temp', 'brightness', 'white_brightness'],
|
|
6411
|
+
convertSet: async (entity, key, value, meta) => {
|
|
6412
|
+
const separateWhite = (meta.mapped.meta && meta.mapped.meta.separateWhite);
|
|
6413
|
+
if (key == 'white_brightness' || (!separateWhite && (key == 'brightness'))) {
|
|
6414
|
+
// upscale to 1000
|
|
6415
|
+
let newValue;
|
|
6416
|
+
if (value >= 0 && value <= 255) {
|
|
6417
|
+
newValue = utils.mapNumberRange(value, 0, 255, 0, 1000);
|
|
6418
|
+
} else {
|
|
6419
|
+
throw new Error('Dimmer brightness is out of range 0..255');
|
|
6420
|
+
}
|
|
6421
|
+
await tuya.sendDataPointEnum(entity, tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.white);
|
|
6422
|
+
await tuya.sendDataPointValue(entity, tuya.dataPoints.dimmerLevel, newValue);
|
|
6423
|
+
|
|
6424
|
+
return {state: {white_brightness: value}};
|
|
6425
|
+
} else if (key == 'color_temp') {
|
|
6426
|
+
const [colorTempMin, colorTempMax] = [250, 454];
|
|
6427
|
+
const preset = {
|
|
6428
|
+
'warmest': colorTempMax,
|
|
6429
|
+
'warm': 454,
|
|
6430
|
+
'neutral': 370,
|
|
6431
|
+
'cool': 250,
|
|
6432
|
+
'coolest': colorTempMin,
|
|
6433
|
+
};
|
|
6434
|
+
if (typeof value === 'string' && isNaN(value)) {
|
|
6435
|
+
const presetName = value.toLowerCase();
|
|
6436
|
+
if (presetName in preset) {
|
|
6437
|
+
value = preset[presetName];
|
|
6438
|
+
} else {
|
|
6439
|
+
throw new Error(`Unknown preset '${value}'`);
|
|
6440
|
+
}
|
|
6441
|
+
} else {
|
|
6442
|
+
value = light.clampColorTemp(Number(value), colorTempMin, colorTempMax, meta.logger);
|
|
6443
|
+
}
|
|
6444
|
+
const data = utils.mapNumberRange(value, colorTempMax, colorTempMin, 0, 1000);
|
|
6445
|
+
|
|
6446
|
+
await tuya.sendDataPointEnum(entity, tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.white);
|
|
6447
|
+
await tuya.sendDataPointValue(entity, tuya.dataPoints.silvercrestSetColorTemp, data);
|
|
6448
|
+
|
|
6449
|
+
return {state: {color_temp: value}};
|
|
6450
|
+
} else if (key == 'color' || (separateWhite && (key == 'brightness'))) {
|
|
6451
|
+
const newState = {};
|
|
6452
|
+
if (key == 'brightness') {
|
|
6453
|
+
newState.brightness = value;
|
|
6454
|
+
} else if (key == 'color') {
|
|
6455
|
+
newState.color = value;
|
|
6456
|
+
newState.color_mode = 'hs';
|
|
6457
|
+
}
|
|
6458
|
+
|
|
6459
|
+
const make4sizedString = (v) => {
|
|
6460
|
+
if (v.length >= 4) {
|
|
6461
|
+
return v;
|
|
6462
|
+
} else if (v.length === 3) {
|
|
6463
|
+
return '0' + v;
|
|
6464
|
+
} else if (v.length === 2) {
|
|
6465
|
+
return '00' + v;
|
|
6466
|
+
} else if (v.length === 1) {
|
|
6467
|
+
return '000' + v;
|
|
6468
|
+
} else {
|
|
6469
|
+
return '0000';
|
|
6470
|
+
}
|
|
6471
|
+
};
|
|
6472
|
+
|
|
6473
|
+
const fillInHSB = (h, s, b, state) => {
|
|
6474
|
+
// Define default values. Device expects leading zero in string.
|
|
6475
|
+
const hsb = {
|
|
6476
|
+
h: '0168', // 360
|
|
6477
|
+
s: '03e8', // 1000
|
|
6478
|
+
b: '03e8', // 1000
|
|
6479
|
+
};
|
|
6480
|
+
|
|
6481
|
+
if (h) {
|
|
6482
|
+
// The device expects 0-359
|
|
6483
|
+
if (h >= 360) {
|
|
6484
|
+
h = 359;
|
|
6485
|
+
}
|
|
6486
|
+
hsb.h = make4sizedString(h.toString(16));
|
|
6487
|
+
} else if (state.color && state.color.hue) {
|
|
6488
|
+
hsb.h = make4sizedString(state.color.hue.toString(16));
|
|
6489
|
+
}
|
|
6490
|
+
|
|
6491
|
+
// Device expects 0-1000, saturation normally is 0-100 so we expect that from the user
|
|
6492
|
+
// The device expects a round number, otherwise everything breaks
|
|
6493
|
+
if (s) {
|
|
6494
|
+
hsb.s = make4sizedString(utils.mapNumberRange(s, 0, 100, 0, 1000).toString(16));
|
|
6495
|
+
} else if (state.color && state.color.saturation) {
|
|
6496
|
+
hsb.s = make4sizedString(utils.mapNumberRange(state.color.saturation, 0, 100, 0, 1000).toString(16));
|
|
6497
|
+
}
|
|
6498
|
+
|
|
6499
|
+
// Scale 0-255 to 0-1000 what the device expects.
|
|
6500
|
+
if (b) {
|
|
6501
|
+
hsb.b = make4sizedString(utils.mapNumberRange(b, 0, 255, 0, 1000).toString(16));
|
|
6502
|
+
} else if (state.brightness) {
|
|
6503
|
+
hsb.b = make4sizedString(utils.mapNumberRange(state.brightness, 0, 255, 0, 1000).toString(16));
|
|
6504
|
+
}
|
|
6505
|
+
|
|
6506
|
+
return hsb;
|
|
6507
|
+
};
|
|
6508
|
+
|
|
6509
|
+
const hsb = fillInHSB(
|
|
6510
|
+
value.h || value.hue || null,
|
|
6511
|
+
value.s || value.saturation || null,
|
|
6512
|
+
value.b || value.brightness || (key == 'brightness') ? value : null,
|
|
6513
|
+
meta.state,
|
|
6514
|
+
);
|
|
6515
|
+
|
|
6516
|
+
|
|
6517
|
+
let data = [];
|
|
6518
|
+
data = data.concat(tuya.convertStringToHexArray(hsb.h));
|
|
6519
|
+
data = data.concat(tuya.convertStringToHexArray(hsb.s));
|
|
6520
|
+
data = data.concat(tuya.convertStringToHexArray(hsb.b));
|
|
6521
|
+
|
|
6522
|
+
await tuya.sendDataPointEnum(entity, tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.color);
|
|
6523
|
+
await tuya.sendDataPointStringBuffer(entity, tuya.dataPoints.silvercrestSetColor, data);
|
|
6524
|
+
|
|
6525
|
+
if (separateWhite && meta.state.white_brightness != undefined) {
|
|
6526
|
+
// restore white state
|
|
6527
|
+
const newValue = utils.mapNumberRange(meta.state.white_brightness, 0, 255, 0, 1000);
|
|
6528
|
+
await tuya.sendDataPointEnum(entity, tuya.dataPoints.silvercrestChangeMode, tuya.silvercrestModes.white);
|
|
6529
|
+
await tuya.sendDataPointValue(entity, tuya.dataPoints.dimmerLevel, newValue);
|
|
6530
|
+
}
|
|
6531
|
+
|
|
6532
|
+
return {state: newState};
|
|
6533
|
+
}
|
|
6534
|
+
},
|
|
6535
|
+
},
|
|
6407
6536
|
// #endregion
|
|
6408
6537
|
|
|
6409
6538
|
// #region Ignore converters
|
package/devices/awox.js
CHANGED
|
@@ -10,6 +10,11 @@ module.exports = [
|
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
fingerprint: [
|
|
13
|
+
{type: 'Router', manufacturerName: 'AwoX', modelID: 'TLSR82xx', endpoints: [
|
|
14
|
+
{ID: 1, profileID: 260, deviceID: 269, inputClusters: [0, 3, 4, 5, 6, 8, 768, 4096, 64599, 10], outputClusters: [6]},
|
|
15
|
+
{ID: 3, profileID: 4751, deviceID: 269, inputClusters: [65360, 65361], outputClusters: [65360, 65361]},
|
|
16
|
+
{ID: 242, profileID: 41440, deviceID: 97, inputClusters: [], outputClusters: [33]},
|
|
17
|
+
]},
|
|
13
18
|
{type: 'Router', manufacturerName: 'AwoX', modelID: 'TLSR82xx', endpoints: [
|
|
14
19
|
{ID: 1, profileID: 260, deviceID: 258, inputClusters: [0, 3, 4, 5, 6, 8, 768, 4096], outputClusters: [6, 25]},
|
|
15
20
|
{ID: 3, profileID: 49152, deviceID: 258, inputClusters: [65360, 65361], outputClusters: [65360, 65361]},
|
package/devices/bticino.js
CHANGED
|
@@ -70,7 +70,7 @@ module.exports = [
|
|
|
70
70
|
{
|
|
71
71
|
zigbeeModel: ['Bticino Din power consumption module '],
|
|
72
72
|
model: 'F20T60A',
|
|
73
|
-
description: 'DIN power consumption module',
|
|
73
|
+
description: 'DIN power consumption module (same as Legrand 412015)',
|
|
74
74
|
vendor: 'BTicino',
|
|
75
75
|
extend: extend.switch(),
|
|
76
76
|
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_device_mode, fz.ignore_basic_report, fz.ignore_genOta],
|
package/devices/centralite.js
CHANGED
|
@@ -196,12 +196,15 @@ module.exports = [
|
|
|
196
196
|
tz.thermostat_occupied_heating_setpoint, tz.thermostat_occupied_cooling_setpoint,
|
|
197
197
|
tz.thermostat_setpoint_raise_lower, tz.thermostat_remote_sensing,
|
|
198
198
|
tz.thermostat_control_sequence_of_operation, tz.thermostat_system_mode,
|
|
199
|
-
tz.thermostat_relay_status_log, tz.fan_mode, tz.thermostat_running_state],
|
|
200
|
-
exposes: [e.battery(),
|
|
201
|
-
.
|
|
202
|
-
|
|
203
|
-
.withSetpoint('
|
|
204
|
-
|
|
199
|
+
tz.thermostat_relay_status_log, tz.fan_mode, tz.thermostat_running_state, tz.thermostat_temperature_setpoint_hold],
|
|
200
|
+
exposes: [e.battery(),
|
|
201
|
+
exposes.binary('temperature_setpoint_hold', ea.ALL, true, false)
|
|
202
|
+
.withDescription('Prevent changes. `false` = run normally. `true` = prevent from making changes.'),
|
|
203
|
+
exposes.climate().withSetpoint('occupied_heating_setpoint', 10, 30, 1).withLocalTemperature()
|
|
204
|
+
.withSystemMode(['off', 'heat', 'cool', 'emergency_heating'])
|
|
205
|
+
.withRunningState(['idle', 'heat', 'cool', 'fan_only']).withFanMode(['auto', 'on'])
|
|
206
|
+
.withSetpoint('occupied_cooling_setpoint', 10, 30, 1)
|
|
207
|
+
.withLocalTemperatureCalibration(-30, 30, 0.1)],
|
|
205
208
|
meta: {battery: {voltageToPercentage: '3V_1500_2800'}},
|
|
206
209
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
207
210
|
const endpoint = device.getEndpoint(1);
|
|
@@ -210,6 +213,7 @@ module.exports = [
|
|
|
210
213
|
await reporting.thermostatRunningState(endpoint);
|
|
211
214
|
await reporting.thermostatTemperature(endpoint);
|
|
212
215
|
await reporting.fanMode(endpoint);
|
|
216
|
+
await reporting.thermostatTemperatureSetpointHold(endpoint);
|
|
213
217
|
},
|
|
214
218
|
},
|
|
215
219
|
{
|
package/devices/innr.js
CHANGED
|
@@ -79,6 +79,14 @@ module.exports = [
|
|
|
79
79
|
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
|
|
80
80
|
meta: {enhancedHue: false, applyRedFix: true, turnsOffAtBrightness1: true},
|
|
81
81
|
},
|
|
82
|
+
{
|
|
83
|
+
zigbeeModel: ['RB 251 C'],
|
|
84
|
+
model: 'RB 251 C',
|
|
85
|
+
vendor: 'Innr',
|
|
86
|
+
description: 'E14 bulb RGBW',
|
|
87
|
+
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 555], supportsHS: true}),
|
|
88
|
+
meta: {enhancedHue: false, applyRedFix: true, turnsOffAtBrightness1: true},
|
|
89
|
+
},
|
|
82
90
|
{
|
|
83
91
|
zigbeeModel: ['RB 265'],
|
|
84
92
|
model: 'RB 265',
|
package/devices/iris.js
CHANGED
|
@@ -3,6 +3,7 @@ const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/lega
|
|
|
3
3
|
const tz = require('../converters/toZigbee');
|
|
4
4
|
const reporting = require('../lib/reporting');
|
|
5
5
|
const e = exposes.presets;
|
|
6
|
+
const extend = require('../lib/extend');
|
|
6
7
|
|
|
7
8
|
module.exports = [
|
|
8
9
|
{
|
|
@@ -144,4 +145,18 @@ module.exports = [
|
|
|
144
145
|
},
|
|
145
146
|
exposes: [e.switch(), e.battery()],
|
|
146
147
|
},
|
|
148
|
+
{
|
|
149
|
+
zigbeeModel: ['1113-S'],
|
|
150
|
+
model: 'iL03_1',
|
|
151
|
+
vendor: 'Iris',
|
|
152
|
+
description: 'Smart plug',
|
|
153
|
+
extend: extend.switch(),
|
|
154
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
155
|
+
const endpoint = device.getEndpoint(1);
|
|
156
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
157
|
+
await reporting.onOff(endpoint);
|
|
158
|
+
device.powerSource = 'Mains (single phase)';
|
|
159
|
+
device.save();
|
|
160
|
+
},
|
|
161
|
+
},
|
|
147
162
|
];
|
package/devices/legrand.js
CHANGED
|
@@ -19,7 +19,7 @@ module.exports = [
|
|
|
19
19
|
zigbeeModel: [' Contactor\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'+
|
|
20
20
|
'\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0000'],
|
|
21
21
|
model: 'FC80CC',
|
|
22
|
-
description: 'Legrand (or Bticino) DIN contactor module
|
|
22
|
+
description: 'Legrand (or Bticino) DIN contactor module',
|
|
23
23
|
vendor: 'Legrand',
|
|
24
24
|
extend: extend.switch(),
|
|
25
25
|
fromZigbee: [fz.identify, fz.on_off, fz.electrical_measurement, fz.legrand_device_mode, fz.ignore_basic_report, fz.ignore_genOta],
|
package/devices/lidl.js
CHANGED
|
@@ -667,7 +667,7 @@ module.exports = [
|
|
|
667
667
|
fingerprint: [{modelID: 'TS0101', manufacturerName: '_TZ3000_pnzfdr9y'}],
|
|
668
668
|
model: 'HG06619',
|
|
669
669
|
vendor: 'Lidl',
|
|
670
|
-
description: 'Silvercrest
|
|
670
|
+
description: 'Silvercrest outdoor plug',
|
|
671
671
|
extend: extend.switch(),
|
|
672
672
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
673
673
|
const endpoint = device.getEndpoint(1);
|
package/devices/nous.js
CHANGED
|
@@ -7,6 +7,15 @@ const e = exposes.presets;
|
|
|
7
7
|
const ea = exposes.access;
|
|
8
8
|
|
|
9
9
|
module.exports = [
|
|
10
|
+
{
|
|
11
|
+
fingerprint: [{modelID: 'TS0201', manufacturerName: '_TZ3000_lbtpiody'}],
|
|
12
|
+
model: 'E5',
|
|
13
|
+
vendor: 'Nous',
|
|
14
|
+
description: 'Temperature & humidity',
|
|
15
|
+
fromZigbee: [fz.temperature, fz.humidity, fz.battery],
|
|
16
|
+
toZigbee: [],
|
|
17
|
+
exposes: [e.temperature(), e.humidity(), e.battery()],
|
|
18
|
+
},
|
|
10
19
|
{
|
|
11
20
|
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_nnrfa68v'}],
|
|
12
21
|
model: 'E6',
|
package/devices/osram.js
CHANGED
|
@@ -390,14 +390,15 @@ module.exports = [
|
|
|
390
390
|
ota: ota.ledvance,
|
|
391
391
|
},
|
|
392
392
|
{
|
|
393
|
-
zigbeeModel: ['Zigbee 3.0 DALI CONV LI'],
|
|
393
|
+
zigbeeModel: ['Zigbee 3.0 DALI CONV LI', 'Zigbee 3.0 DALI CONV LI\u0000'],
|
|
394
394
|
model: '4062172044776_1',
|
|
395
395
|
vendor: 'OSRAM',
|
|
396
396
|
description: 'Zigbee 3.0 DALI CONV LI dimmer for DALI-based luminaires (only one device)',
|
|
397
397
|
extend: extend.ledvance.light_onoff_brightness(),
|
|
398
398
|
},
|
|
399
399
|
{
|
|
400
|
-
fingerprint: [{modelID: 'Zigbee 3.0 DALI CONV LI', endpoints: [{ID: 10}, {ID: 25}, {ID: 242}]}
|
|
400
|
+
fingerprint: [{modelID: 'Zigbee 3.0 DALI CONV LI', endpoints: [{ID: 10}, {ID: 25}, {ID: 242}]},
|
|
401
|
+
{modelID: 'Zigbee 3.0 DALI CONV LI\u0000', endpoints: [{ID: 10}, {ID: 25}, {ID: 242}]}],
|
|
401
402
|
model: '4062172044776_2',
|
|
402
403
|
vendor: 'OSRAM',
|
|
403
404
|
description: 'Zigbee 3.0 DALI CONV LI dimmer for DALI-based luminaires (one device and pushbutton)',
|
|
@@ -410,7 +411,8 @@ module.exports = [
|
|
|
410
411
|
},
|
|
411
412
|
},
|
|
412
413
|
{
|
|
413
|
-
fingerprint: [{modelID: 'Zigbee 3.0 DALI CONV LI', endpoints: [{ID: 10}, {ID: 11}, {ID: 242}]}
|
|
414
|
+
fingerprint: [{modelID: 'Zigbee 3.0 DALI CONV LI', endpoints: [{ID: 10}, {ID: 11}, {ID: 242}]},
|
|
415
|
+
{modelID: 'Zigbee 3.0 DALI CONV LI\u0000', endpoints: [{ID: 10}, {ID: 11}, {ID: 242}]}],
|
|
414
416
|
model: '4062172044776_3',
|
|
415
417
|
vendor: 'OSRAM',
|
|
416
418
|
description: 'Zigbee 3.0 DALI CONV LI dimmer for DALI-based luminaires (with two devices)',
|
|
@@ -430,7 +432,8 @@ module.exports = [
|
|
|
430
432
|
},
|
|
431
433
|
},
|
|
432
434
|
{
|
|
433
|
-
fingerprint: [{modelID: 'Zigbee 3.0 DALI CONV LI', endpoints: [{ID: 10}, {ID: 11}, {ID: 25}, {ID: 242}]}
|
|
435
|
+
fingerprint: [{modelID: 'Zigbee 3.0 DALI CONV LI', endpoints: [{ID: 10}, {ID: 11}, {ID: 25}, {ID: 242}]},
|
|
436
|
+
{modelID: 'Zigbee 3.0 DALI CONV LI\u0000', endpoints: [{ID: 10}, {ID: 11}, {ID: 25}, {ID: 242}]}],
|
|
434
437
|
model: '4062172044776_4',
|
|
435
438
|
vendor: 'OSRAM',
|
|
436
439
|
description: 'Zigbee 3.0 DALI CONV LI dimmer for DALI-based luminaires (with two devices and pushbutton)',
|
package/devices/philips.js
CHANGED
|
@@ -29,6 +29,15 @@ const hueExtend = {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
module.exports = [
|
|
32
|
+
{
|
|
33
|
+
zigbeeModel: ['929003047501'],
|
|
34
|
+
model: '929003047501',
|
|
35
|
+
vendor: 'Philips',
|
|
36
|
+
description: 'Centura recessed spotlight',
|
|
37
|
+
meta: {turnsOffAtBrightness1: true},
|
|
38
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
39
|
+
ota: ota.zigbeeOTA,
|
|
40
|
+
},
|
|
32
41
|
{
|
|
33
42
|
zigbeeModel: ['915005996401'],
|
|
34
43
|
model: '915005996401',
|
|
@@ -2324,7 +2333,7 @@ module.exports = [
|
|
|
2324
2333
|
ota: ota.zigbeeOTA,
|
|
2325
2334
|
},
|
|
2326
2335
|
{
|
|
2327
|
-
zigbeeModel: ['5309331P6'],
|
|
2336
|
+
zigbeeModel: ['5309331P6', '5309330P6'],
|
|
2328
2337
|
model: '5309331P6',
|
|
2329
2338
|
vendor: 'Philips',
|
|
2330
2339
|
description: 'Hue White ambiance Runner triple spotlight',
|
|
@@ -2333,7 +2342,7 @@ module.exports = [
|
|
|
2333
2342
|
ota: ota.zigbeeOTA,
|
|
2334
2343
|
},
|
|
2335
2344
|
{
|
|
2336
|
-
zigbeeModel: ['5309230P6'],
|
|
2345
|
+
zigbeeModel: ['5309230P6', '5309231P6'],
|
|
2337
2346
|
model: '5309230P6',
|
|
2338
2347
|
vendor: 'Philips',
|
|
2339
2348
|
description: 'Hue White ambiance Runner double spotlight',
|
|
@@ -2378,7 +2387,7 @@ module.exports = [
|
|
|
2378
2387
|
ota: ota.zigbeeOTA,
|
|
2379
2388
|
},
|
|
2380
2389
|
{
|
|
2381
|
-
zigbeeModel: ['5309030P9'],
|
|
2390
|
+
zigbeeModel: ['5309030P9', '5309031P9', '5309030P6', '5309031P6'],
|
|
2382
2391
|
model: '5309030P9',
|
|
2383
2392
|
vendor: 'Philips',
|
|
2384
2393
|
description: 'Hue White ambiance Runner single spotlight',
|
package/devices/shinasystem.js
CHANGED
|
@@ -24,6 +24,7 @@ module.exports = [
|
|
|
24
24
|
await endpoint.configureReporting('genAnalogInput', payload);
|
|
25
25
|
},
|
|
26
26
|
exposes: [e.battery(), e.battery_voltage(),
|
|
27
|
+
exposes.enum('status', ea.STATE, ['idle', 'in', 'out']).withDescription('Currently status'),
|
|
27
28
|
exposes.numeric('people', ea.ALL).withValueMin(0).withValueMax(50).withDescription('People count')],
|
|
28
29
|
},
|
|
29
30
|
{
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
const exposes = require('../lib/exposes');
|
|
2
|
+
const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
|
|
3
|
+
const tz = require('../converters/toZigbee');
|
|
4
|
+
const ea = exposes.access;
|
|
5
|
+
|
|
6
|
+
module.exports = [
|
|
7
|
+
{
|
|
8
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_6qoazbre'}],
|
|
9
|
+
model: 'WZ5_dim',
|
|
10
|
+
vendor: 'Skydance',
|
|
11
|
+
description: 'Zigbee & RF 5 in 1 LED controller (DIM mode)',
|
|
12
|
+
fromZigbee: [fz.tuya_light_wz5],
|
|
13
|
+
toZigbee: [tz.tuya_dimmer_state, tz.tuya_light_wz5],
|
|
14
|
+
exposes: [
|
|
15
|
+
exposes.light().withBrightness().setAccess('state',
|
|
16
|
+
ea.STATE_SET).setAccess('brightness', ea.STATE_SET),
|
|
17
|
+
],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_gz3n0tzf'}],
|
|
21
|
+
model: 'WZ5_cct',
|
|
22
|
+
vendor: 'Skydance',
|
|
23
|
+
description: 'Zigbee & RF 5 in 1 LED controller (CCT mode)',
|
|
24
|
+
fromZigbee: [fz.tuya_light_wz5],
|
|
25
|
+
toZigbee: [tz.tuya_dimmer_state, tz.tuya_light_wz5],
|
|
26
|
+
exposes: [
|
|
27
|
+
exposes.light().withBrightness().setAccess('state',
|
|
28
|
+
ea.STATE_SET).setAccess('brightness', ea.STATE_SET).withColorTemp([250, 454]).setAccess('color_temp', ea.STATE_SET),
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_9hghastn'}],
|
|
33
|
+
model: 'WZ5_rgb',
|
|
34
|
+
vendor: 'Skydance',
|
|
35
|
+
description: 'Zigbee & RF 5 in 1 LED controller (RGB mode)',
|
|
36
|
+
fromZigbee: [fz.tuya_light_wz5],
|
|
37
|
+
toZigbee: [tz.tuya_dimmer_state, tz.tuya_light_wz5],
|
|
38
|
+
exposes: [
|
|
39
|
+
exposes.light().withBrightness().setAccess('state', ea.STATE_SET).setAccess('brightness',
|
|
40
|
+
ea.STATE_SET).withColor('hs'),
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_3thxjahu'}],
|
|
45
|
+
model: 'WZ5_rgbw',
|
|
46
|
+
vendor: 'Skydance',
|
|
47
|
+
description: 'Zigbee & RF 5 in 1 LED controller (RGBW mode)',
|
|
48
|
+
fromZigbee: [fz.tuya_light_wz5],
|
|
49
|
+
toZigbee: [tz.tuya_dimmer_state, tz.tuya_light_wz5],
|
|
50
|
+
exposes: [
|
|
51
|
+
exposes.light().withBrightness().setAccess('state', ea.STATE_SET).setAccess('brightness',
|
|
52
|
+
ea.STATE_SET).withColor('hs'),
|
|
53
|
+
exposes.numeric('white_brightness', ea.STATE_SET).withValueMin(0).withValueMax(254).withDescription(
|
|
54
|
+
'White brightness of this light'),
|
|
55
|
+
],
|
|
56
|
+
meta: {separateWhite: true},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_mde0utnv'}],
|
|
60
|
+
model: 'WZ5_rgbcct',
|
|
61
|
+
vendor: 'Skydance',
|
|
62
|
+
description: 'Zigbee & RF 5 in 1 LED controller (RGB+CCT mode)',
|
|
63
|
+
fromZigbee: [fz.tuya_light_wz5],
|
|
64
|
+
toZigbee: [tz.tuya_dimmer_state, tz.tuya_light_wz5],
|
|
65
|
+
exposes: [
|
|
66
|
+
exposes.light().withBrightness().setAccess('state', ea.STATE_SET).setAccess('brightness',
|
|
67
|
+
ea.STATE_SET).withColor('hs').withColorTemp([250, 454]).setAccess('color_temp',
|
|
68
|
+
ea.STATE_SET),
|
|
69
|
+
exposes.numeric('white_brightness', ea.STATE_SET).withValueMin(0).withValueMax(254).withDescription(
|
|
70
|
+
'White brightness of this light'),
|
|
71
|
+
],
|
|
72
|
+
meta: {separateWhite: true},
|
|
73
|
+
},
|
|
74
|
+
];
|
package/devices/tuya.js
CHANGED
|
@@ -12,7 +12,7 @@ const utils = require('../lib/utils');
|
|
|
12
12
|
|
|
13
13
|
const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak', '_TZ3000_ew3ldmgx', '_TZ3000_gjnozsaz',
|
|
14
14
|
'_TZ3000_jvzvulen', '_TZ3000_mraovvmm', '_TZ3000_nfnmi125', '_TZ3000_ps3dmato', '_TZ3000_w0qqde0g', '_TZ3000_u5u4cakc',
|
|
15
|
-
'_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_v1pdxuqq'];
|
|
15
|
+
'_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_v1pdxuqq', '_TZ3000_bfn1w0mm'];
|
|
16
16
|
|
|
17
17
|
const tzLocal = {
|
|
18
18
|
TS0504B_color: {
|
|
@@ -664,6 +664,20 @@ module.exports = [
|
|
|
664
664
|
toZigbee: [],
|
|
665
665
|
whiteLabel: [{vendor: 'Neo', model: 'NAS-WS02B0'}],
|
|
666
666
|
},
|
|
667
|
+
{
|
|
668
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_jthf7vb6'}],
|
|
669
|
+
model: 'WLS-100z',
|
|
670
|
+
vendor: 'TuYa',
|
|
671
|
+
description: 'Water leak sensor',
|
|
672
|
+
fromZigbee: [fz.ignore_basic_report, fz.ignore_tuya_raw, fz.wls100z_water_leak],
|
|
673
|
+
toZigbee: [],
|
|
674
|
+
onEvent: tuya.onEventSetTime,
|
|
675
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
676
|
+
const endpoint = device.getEndpoint(1);
|
|
677
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genBasic']);
|
|
678
|
+
},
|
|
679
|
+
exposes: [e.battery(), e.water_leak()],
|
|
680
|
+
},
|
|
667
681
|
{
|
|
668
682
|
zigbeeModel: ['TS0001'],
|
|
669
683
|
model: 'TS0001',
|
|
@@ -1682,7 +1696,9 @@ module.exports = [
|
|
|
1682
1696
|
],
|
|
1683
1697
|
},
|
|
1684
1698
|
{
|
|
1685
|
-
fingerprint: [
|
|
1699
|
+
fingerprint: [
|
|
1700
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_vrfecyku'},
|
|
1701
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_lu01t0zl'}],
|
|
1686
1702
|
model: 'MIR-HE200-TY',
|
|
1687
1703
|
vendor: 'TuYa',
|
|
1688
1704
|
description: 'Human presence sensor',
|
|
@@ -1810,4 +1826,13 @@ module.exports = [
|
|
|
1810
1826
|
toZigbee: [],
|
|
1811
1827
|
exposes: [e.action(['toggle', 'brightness_step_up', 'brightness_step_down'])],
|
|
1812
1828
|
},
|
|
1829
|
+
{
|
|
1830
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_kzm5w4iz'}],
|
|
1831
|
+
model: 'TS0601_vibration_sensor',
|
|
1832
|
+
vendor: 'TuYa',
|
|
1833
|
+
description: 'Smart vibration sensor',
|
|
1834
|
+
fromZigbee: [fz.tuya_smart_vibration_sensor],
|
|
1835
|
+
toZigbee: [],
|
|
1836
|
+
exposes: [e.contact(), e.battery(), e.vibration()],
|
|
1837
|
+
},
|
|
1813
1838
|
];
|
package/devices/xiaomi.js
CHANGED
|
@@ -89,6 +89,22 @@ module.exports = [
|
|
|
89
89
|
e.power_outage_memory().withAccess(ea.STATE_SET)]),
|
|
90
90
|
ota: ota.zigbeeOTA,
|
|
91
91
|
},
|
|
92
|
+
{
|
|
93
|
+
zigbeeModel: ['lumi.light.acn003'],
|
|
94
|
+
model: 'ZNXDD01LM',
|
|
95
|
+
vendor: 'Xiaomi',
|
|
96
|
+
description: 'Aqara ceiling light L1-350',
|
|
97
|
+
extend: xiaomiExtend.light_onoff_brightness_colortemp({disableEffect: true, colorTempRange: [153, 370]}),
|
|
98
|
+
ota: ota.zigbeeOTA,
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
zigbeeModel: ['lumi.light.cwac02'],
|
|
102
|
+
model: 'ZNLDP13LM',
|
|
103
|
+
vendor: 'Xiaomi',
|
|
104
|
+
description: 'Aqara T1 smart LED bulb',
|
|
105
|
+
extend: xiaomiExtend.light_onoff_brightness_colortemp({disableEffect: true, colorTempRange: [153, 370]}),
|
|
106
|
+
ota: ota.zigbeeOTA,
|
|
107
|
+
},
|
|
92
108
|
{
|
|
93
109
|
zigbeeModel: ['lumi.light.cwopcn01'],
|
|
94
110
|
model: 'XDD11LM',
|
|
@@ -670,6 +686,11 @@ module.exports = [
|
|
|
670
686
|
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled'])
|
|
671
687
|
.withDescription('Decoupled mode'),
|
|
672
688
|
],
|
|
689
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
690
|
+
device.type = 'Router';
|
|
691
|
+
device.powerSource = 'Mains (single phase)';
|
|
692
|
+
device.save();
|
|
693
|
+
},
|
|
673
694
|
},
|
|
674
695
|
{
|
|
675
696
|
zigbeeModel: ['lumi.switch.b2nacn02'],
|
|
@@ -852,19 +873,17 @@ module.exports = [
|
|
|
852
873
|
zigbeeModel: ['lumi.motion.agl02'],
|
|
853
874
|
model: 'RTCGQ12LM',
|
|
854
875
|
vendor: 'Xiaomi',
|
|
855
|
-
description: 'Aqara T1 human body movement and illuminance sensor
|
|
856
|
-
fromZigbee: [fz.
|
|
857
|
-
toZigbee: [tz.
|
|
858
|
-
exposes: [e.occupancy(), e.
|
|
859
|
-
exposes.numeric('occupancy_timeout',
|
|
860
|
-
.withDescription('Time in seconds till occupancy goes to false')],
|
|
876
|
+
description: 'Aqara T1 human body movement and illuminance sensor',
|
|
877
|
+
fromZigbee: [fz.RTCGQ12LM_occupancy_illuminance, fz.aqara_opple, fz.battery],
|
|
878
|
+
toZigbee: [tz.aqara_occupancy_timeout],
|
|
879
|
+
exposes: [e.occupancy(), e.illuminance().withUnit('lx').withDescription('Measured illuminance in lux'),
|
|
880
|
+
exposes.numeric('occupancy_timeout', ea.ALL).withValueMin(2).withValueMax(65535).withUnit('s')
|
|
881
|
+
.withDescription('Time in seconds till occupancy goes to false'), e.battery()],
|
|
861
882
|
meta: {battery: {voltageToPercentage: '3V_2100'}},
|
|
862
883
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
863
884
|
const endpoint = device.getEndpoint(1);
|
|
864
|
-
await
|
|
865
|
-
await
|
|
866
|
-
await reporting.batteryVoltage(endpoint);
|
|
867
|
-
await endpoint.read('msOccupancySensing', ['pirOToUDelay']);
|
|
885
|
+
await endpoint.read('genPowerCfg', ['batteryVoltage']);
|
|
886
|
+
await endpoint.read('aqaraOpple', [0x0102], {manufacturerCode: 0x115f});
|
|
868
887
|
},
|
|
869
888
|
},
|
|
870
889
|
{
|
|
@@ -872,15 +891,15 @@ module.exports = [
|
|
|
872
891
|
model: 'RTCGQ13LM',
|
|
873
892
|
vendor: 'Xiaomi',
|
|
874
893
|
description: 'Aqara high precision motion sensor',
|
|
875
|
-
fromZigbee: [fz.
|
|
876
|
-
toZigbee: [tz.
|
|
877
|
-
exposes: [e.occupancy(),
|
|
878
|
-
exposes.
|
|
879
|
-
|
|
880
|
-
.withDescription('Time interval for detecting actions')],
|
|
894
|
+
fromZigbee: [fz.RTCGQ13LM_occupancy, fz.aqara_opple, fz.battery],
|
|
895
|
+
toZigbee: [tz.aqara_occupancy_timeout, tz.RTCGQ13LM_motion_sensitivity],
|
|
896
|
+
exposes: [e.occupancy(), exposes.enum('motion_sensitivity', ea.ALL, ['low', 'medium', 'high']),
|
|
897
|
+
exposes.numeric('occupancy_timeout', ea.ALL).withValueMin(2).withValueMax(65535).withUnit('s')
|
|
898
|
+
.withDescription('Time in seconds till occupancy goes to false'), e.battery()],
|
|
881
899
|
meta: {battery: {voltageToPercentage: '3V_2100'}},
|
|
882
900
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
883
901
|
const endpoint = device.getEndpoint(1);
|
|
902
|
+
await endpoint.read('genPowerCfg', ['batteryVoltage']);
|
|
884
903
|
await endpoint.read('aqaraOpple', [0x0102], {manufacturerCode: 0x115f});
|
|
885
904
|
await endpoint.read('aqaraOpple', [0x010c], {manufacturerCode: 0x115f});
|
|
886
905
|
},
|
package/devices/zemismart.js
CHANGED
|
@@ -9,14 +9,18 @@ const tuya = require('../lib/tuya');
|
|
|
9
9
|
const fzLocal = {
|
|
10
10
|
ZMRM02: {
|
|
11
11
|
cluster: 'manuSpecificTuya',
|
|
12
|
-
type: ['commandGetData', 'commandSetDataResponse'],
|
|
12
|
+
type: ['commandGetData', 'commandSetDataResponse', 'commandDataResponse'],
|
|
13
13
|
convert: (model, msg, publish, options, meta) => {
|
|
14
14
|
const dpValue = tuya.firstDpValue(msg, meta, 'ZMRM02');
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
if (dpValue.dp === 10) {
|
|
16
|
+
return {battery: tuya.getDataValue(dpValue)};
|
|
17
|
+
} else {
|
|
18
|
+
const button = dpValue.dp;
|
|
19
|
+
const actionValue = tuya.getDataValue(dpValue);
|
|
20
|
+
const lookup = {0: 'single', 1: 'double', 2: 'hold'};
|
|
21
|
+
const action = lookup[actionValue];
|
|
22
|
+
return {action: `button_${button}_${action}`};
|
|
23
|
+
}
|
|
20
24
|
},
|
|
21
25
|
},
|
|
22
26
|
};
|
|
@@ -90,7 +94,7 @@ module.exports = [
|
|
|
90
94
|
fromZigbee: [fzLocal.ZMRM02],
|
|
91
95
|
toZigbee: [],
|
|
92
96
|
onEvent: tuya.onEventSetTime,
|
|
93
|
-
exposes: [e.action([
|
|
97
|
+
exposes: [e.battery(), e.action([
|
|
94
98
|
'button_1_hold', 'button_1_single', 'button_1_double',
|
|
95
99
|
'button_2_hold', 'button_2_single', 'button_2_double',
|
|
96
100
|
'button_3_hold', 'button_3_single', 'button_3_double',
|
package/lib/exposes.js
CHANGED
|
@@ -527,7 +527,7 @@ module.exports = {
|
|
|
527
527
|
current: () => new Numeric('current', access.STATE).withUnit('A').withDescription('Instantaneous measured electrical current'),
|
|
528
528
|
current_phase_b: () => new Numeric('current_phase_b', access.STATE).withUnit('A').withDescription('Instantaneous measured electrical current on phase B'),
|
|
529
529
|
current_phase_c: () => new Numeric('current_phase_c', access.STATE).withUnit('A').withDescription('Instantaneous measured electrical current on phase C'),
|
|
530
|
-
deadzone_temperature: () => new Numeric('deadzone_temperature', access.STATE_SET).withUnit('°C').withDescription('The delta between local_temperature and current_heating_setpoint to trigger Heat').withValueMin(0
|
|
530
|
+
deadzone_temperature: () => new Numeric('deadzone_temperature', access.STATE_SET).withUnit('°C').withDescription('The delta between local_temperature and current_heating_setpoint to trigger Heat').withValueMin(0).withValueMax(5).withValueStep(1),
|
|
531
531
|
device_temperature: () => new Numeric('device_temperature', access.STATE).withUnit('°C').withDescription('Temperature of the device'),
|
|
532
532
|
eco2: () => new Numeric('eco2', access.STATE).withUnit('ppm').withDescription('Measured eCO2 value'),
|
|
533
533
|
eco_mode: () => new Binary('eco_mode', access.STATE_SET, 'ON', 'OFF').withDescription('ECO mode (energy saving mode)'),
|
package/lib/tuya.js
CHANGED
|
@@ -384,6 +384,7 @@ const dataPoints = {
|
|
|
384
384
|
// Silvercrest
|
|
385
385
|
silvercrestChangeMode: 2,
|
|
386
386
|
silvercrestSetBrightness: 3,
|
|
387
|
+
silvercrestSetColorTemp: 4,
|
|
387
388
|
silvercrestSetColor: 5,
|
|
388
389
|
silvercrestSetEffect: 6,
|
|
389
390
|
// Fantem
|
|
@@ -524,12 +525,16 @@ const dataPoints = {
|
|
|
524
525
|
nousMinTemp: 11,
|
|
525
526
|
nousTempAlarm: 14,
|
|
526
527
|
nousTempSensitivity: 19,
|
|
527
|
-
|
|
528
528
|
// TUYA / HUMIDITY/ILLUMINANCE/TEMPERATURE SENSOR
|
|
529
529
|
thitBatteryPercentage: 3,
|
|
530
530
|
thitIlluminanceLux: 7,
|
|
531
531
|
thitHumidity: 9,
|
|
532
532
|
thitTemperature: 8,
|
|
533
|
+
// TUYA SMART VIBRATION SENSOR
|
|
534
|
+
tuyaVibration: 10,
|
|
535
|
+
// TUYA WLS-100z Water Leak Sensor
|
|
536
|
+
wlsWaterLeak: 1,
|
|
537
|
+
wlsBatteryPercentage: 4,
|
|
533
538
|
};
|
|
534
539
|
|
|
535
540
|
const thermostatWeekFormat = {
|
package/npm-shrinkwrap.json
CHANGED