zigbee-herdsman-converters 14.0.407 → 14.0.411
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 +52 -4
- package/converters/toZigbee.js +24 -6
- package/devices/gledopto.js +31 -5
- package/devices/lixee.js +574 -0
- package/devices/moes.js +22 -9
- package/devices/m/303/274ller_licht.js +3 -2
- package/devices/philips.js +2 -2
- package/devices/schwaiger.js +7 -0
- package/devices/sengled.js +9 -2
- package/devices/sonoff.js +11 -0
- package/devices/sunricher.js +1 -1
- package/devices/tuya.js +3 -2
- package/devices/xiaomi.js +8 -7
- package/devices/yale.js +7 -0
- package/index.js +3 -2
- package/lib/extend.js +7 -5
- package/lib/ota/index.js +1 -0
- package/lib/ota/lixee.js +57 -0
- package/lib/tuya.js +17 -0
- package/npm-shrinkwrap.json +1 -1
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -616,6 +616,25 @@ const converters = {
|
|
|
616
616
|
return result;
|
|
617
617
|
},
|
|
618
618
|
},
|
|
619
|
+
meter_identification: {
|
|
620
|
+
cluster: 'haMeterIdentification',
|
|
621
|
+
type: ['readResponse'],
|
|
622
|
+
convert: (model, msg, publish, options, meta) => {
|
|
623
|
+
const result = {};
|
|
624
|
+
const elements = [
|
|
625
|
+
/* 0x000A*/ 'softwareRevision',
|
|
626
|
+
/* 0x000D*/ 'availablePower',
|
|
627
|
+
/* 0x000E*/ 'powerThreshold',
|
|
628
|
+
];
|
|
629
|
+
for (const at of elements) {
|
|
630
|
+
const atSnake = at.split(/(?=[A-Z])/).join('_').toLowerCase();
|
|
631
|
+
if (msg.data[at]) {
|
|
632
|
+
result[atSnake] = msg.data[at];
|
|
633
|
+
}
|
|
634
|
+
}
|
|
635
|
+
return result;
|
|
636
|
+
},
|
|
637
|
+
},
|
|
619
638
|
metering: {
|
|
620
639
|
/**
|
|
621
640
|
* When using this converter also add the following to the configure method of the device:
|
|
@@ -2395,6 +2414,26 @@ const converters = {
|
|
|
2395
2414
|
}
|
|
2396
2415
|
},
|
|
2397
2416
|
},
|
|
2417
|
+
moes_switch: {
|
|
2418
|
+
cluster: 'manuSpecificTuya',
|
|
2419
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
2420
|
+
convert: (model, msg, publish, options, meta) => {
|
|
2421
|
+
const dpValue = tuya.firstDpValue(msg, meta, 'moes_switch');
|
|
2422
|
+
const dp = dpValue.dp;
|
|
2423
|
+
const value = tuya.getDataValue(dpValue);
|
|
2424
|
+
|
|
2425
|
+
switch (dp) {
|
|
2426
|
+
case tuya.dataPoints.moesSwitchPowerOnBehavior:
|
|
2427
|
+
return {power_on_behavior: tuya.moesSwitch.powerOnBehavior[value]};
|
|
2428
|
+
case tuya.dataPoints.moesSwitchIndicateLight:
|
|
2429
|
+
return {indicate_light: tuya.moesSwitch.indicateLight[value]};
|
|
2430
|
+
default:
|
|
2431
|
+
meta.logger.warn(`fromZigbee:moes_switch: NOT RECOGNIZED DP #${
|
|
2432
|
+
dp} with data ${JSON.stringify(dpValue)}`);
|
|
2433
|
+
break;
|
|
2434
|
+
}
|
|
2435
|
+
},
|
|
2436
|
+
},
|
|
2398
2437
|
eurotronic_thermostat: {
|
|
2399
2438
|
cluster: 'hvacThermostat',
|
|
2400
2439
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -5168,8 +5207,16 @@ const converters = {
|
|
|
5168
5207
|
aqara_opple: {
|
|
5169
5208
|
cluster: 'aqaraOpple',
|
|
5170
5209
|
type: ['attributeReport', 'readResponse'],
|
|
5171
|
-
options:
|
|
5172
|
-
|
|
5210
|
+
options: (definition) => {
|
|
5211
|
+
const result = [];
|
|
5212
|
+
if (definition.exposes.find((e) => e.name === 'temperature')) {
|
|
5213
|
+
result.push(exposes.options.precision('temperature'), exposes.options.calibration('temperature'));
|
|
5214
|
+
}
|
|
5215
|
+
if (definition.exposes.find((e) => e.name === 'illuminance')) {
|
|
5216
|
+
result.push(exposes.options.precision('illuminance'), exposes.options.calibration('illuminance', 'percentual'));
|
|
5217
|
+
}
|
|
5218
|
+
return result;
|
|
5219
|
+
},
|
|
5173
5220
|
convert: (model, msg, publish, options, meta) => {
|
|
5174
5221
|
const payload = {};
|
|
5175
5222
|
if (msg.data.hasOwnProperty('247')) {
|
|
@@ -5315,8 +5362,9 @@ const converters = {
|
|
|
5315
5362
|
payload.presence_event = {0: 'enter', 1: 'leave', 2: 'left_enter', 3: 'right_leave', 4: 'right_enter',
|
|
5316
5363
|
5: 'left_leave', 6: 'approach', 7: 'away', 255: null}[value];
|
|
5317
5364
|
}
|
|
5318
|
-
} else if (index ===103)
|
|
5319
|
-
|
|
5365
|
+
} else if (index === 103) {
|
|
5366
|
+
if (['RTCZCGQ11LM'].includes(model.model)) payload.monitoring_mode = value === 1 ? 'left_right' : 'undirected';
|
|
5367
|
+
} else if (index === 105) {
|
|
5320
5368
|
if (['RTCGQ13LM'].includes(model.model)) {
|
|
5321
5369
|
payload.motion_sensitivity = {1: 'low', 2: 'medium', 3: 'high'}[value];
|
|
5322
5370
|
} else if (['RTCZCGQ11LM'].includes(model.model)) {
|
package/converters/toZigbee.js
CHANGED
|
@@ -2417,12 +2417,6 @@ const converters = {
|
|
|
2417
2417
|
await entity.read('genAnalogOutput', [0x0055]);
|
|
2418
2418
|
},
|
|
2419
2419
|
},
|
|
2420
|
-
xiaomi_curtain_acn002_status: {
|
|
2421
|
-
key: ['motor_state'],
|
|
2422
|
-
convertGet: async (entity, key, meta) => {
|
|
2423
|
-
await entity.read('genMultistateOutput', [0x0055]);
|
|
2424
|
-
},
|
|
2425
|
-
},
|
|
2426
2420
|
ledvance_commands: {
|
|
2427
2421
|
/* deprectated osram_*/
|
|
2428
2422
|
key: ['set_transition', 'remember_state', 'osram_set_transition', 'osram_remember_state'],
|
|
@@ -3212,6 +3206,30 @@ const converters = {
|
|
|
3212
3206
|
await entity.read('genOnOff', ['moesStartUpOnOff']);
|
|
3213
3207
|
},
|
|
3214
3208
|
},
|
|
3209
|
+
moes_switch: {
|
|
3210
|
+
key: ['power_on_behavior', 'indicate_light'],
|
|
3211
|
+
convertSet: async (entity, key, value, meta) => {
|
|
3212
|
+
switch (key) {
|
|
3213
|
+
case 'power_on_behavior':
|
|
3214
|
+
await tuya.sendDataPointEnum(
|
|
3215
|
+
entity,
|
|
3216
|
+
tuya.dataPoints.moesSwitchPowerOnBehavior,
|
|
3217
|
+
utils.getKey(tuya.moesSwitch.powerOnBehavior, value),
|
|
3218
|
+
);
|
|
3219
|
+
break;
|
|
3220
|
+
case 'indicate_light':
|
|
3221
|
+
await tuya.sendDataPointValue(
|
|
3222
|
+
entity,
|
|
3223
|
+
tuya.dataPoints.moesSwitchIndicateLight,
|
|
3224
|
+
utils.getKey(tuya.moesSwitch.indicateLight, value),
|
|
3225
|
+
);
|
|
3226
|
+
break;
|
|
3227
|
+
default:
|
|
3228
|
+
meta.logger.warn(`toZigbee.moes_switch: Unhandled Key ${key}`);
|
|
3229
|
+
break;
|
|
3230
|
+
}
|
|
3231
|
+
},
|
|
3232
|
+
},
|
|
3215
3233
|
moes_thermostat_sensor: {
|
|
3216
3234
|
key: ['sensor'],
|
|
3217
3235
|
convertSet: async (entity, key, value, meta) => {
|
package/devices/gledopto.js
CHANGED
|
@@ -62,6 +62,12 @@ const gledoptoExtend = {
|
|
|
62
62
|
}),
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
+
const configureReadModelID = async (device) => {
|
|
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: [
|
|
@@ -116,7 +122,11 @@ module.exports = [
|
|
|
116
122
|
vendor: 'Gledopto',
|
|
117
123
|
ota: ota.zigbeeOTA,
|
|
118
124
|
description: 'Zigbee LED Controller WW/CW (pro)',
|
|
119
|
-
extend: gledoptoExtend.light_onoff_brightness_colortemp(),
|
|
125
|
+
extend: gledoptoExtend.light_onoff_brightness_colortemp({noConfigure: true}),
|
|
126
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
127
|
+
await extend.light_onoff_brightness_colortemp().configure(device, coordinatorEndpoint, logger);
|
|
128
|
+
await configureReadModelID(device);
|
|
129
|
+
},
|
|
120
130
|
},
|
|
121
131
|
{
|
|
122
132
|
fingerprint: [
|
|
@@ -179,7 +189,11 @@ module.exports = [
|
|
|
179
189
|
vendor: 'Gledopto',
|
|
180
190
|
ota: ota.zigbeeOTA,
|
|
181
191
|
description: 'Zigbee LED Controller RGBW (pro)',
|
|
182
|
-
extend: gledoptoExtend.light_onoff_brightness_colortemp_color(),
|
|
192
|
+
extend: gledoptoExtend.light_onoff_brightness_colortemp_color({noConfigure: true}),
|
|
193
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
194
|
+
await extend.light_onoff_brightness_colortemp_color().configure(device, coordinatorEndpoint, logger);
|
|
195
|
+
await configureReadModelID(device);
|
|
196
|
+
},
|
|
183
197
|
},
|
|
184
198
|
{
|
|
185
199
|
fingerprint: [
|
|
@@ -237,7 +251,11 @@ module.exports = [
|
|
|
237
251
|
vendor: 'Gledopto',
|
|
238
252
|
ota: ota.zigbeeOTA,
|
|
239
253
|
description: 'Zigbee LED Controller RGB (pro)',
|
|
240
|
-
extend: gledoptoExtend.light_onoff_brightness_color(),
|
|
254
|
+
extend: gledoptoExtend.light_onoff_brightness_color({noConfigure: true}),
|
|
255
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
256
|
+
await extend.light_onoff_brightness_color().configure(device, coordinatorEndpoint, logger);
|
|
257
|
+
await configureReadModelID(device);
|
|
258
|
+
},
|
|
241
259
|
},
|
|
242
260
|
{
|
|
243
261
|
zigbeeModel: ['GL-C-008P'],
|
|
@@ -245,8 +263,12 @@ module.exports = [
|
|
|
245
263
|
vendor: 'Gledopto',
|
|
246
264
|
ota: ota.zigbeeOTA,
|
|
247
265
|
description: 'Zigbee LED Controller RGB+CCT (pro)',
|
|
248
|
-
extend: gledoptoExtend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495]}),
|
|
266
|
+
extend: gledoptoExtend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495], noConfigure: true}),
|
|
249
267
|
meta: {disableDefaultResponse: true},
|
|
268
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
269
|
+
await extend.light_onoff_brightness_colortemp_color().configure(device, coordinatorEndpoint, logger);
|
|
270
|
+
await configureReadModelID(device);
|
|
271
|
+
},
|
|
250
272
|
},
|
|
251
273
|
{
|
|
252
274
|
zigbeeModel: ['GL-C-009'],
|
|
@@ -267,7 +289,11 @@ module.exports = [
|
|
|
267
289
|
vendor: 'Gledopto',
|
|
268
290
|
ota: ota.zigbeeOTA,
|
|
269
291
|
description: 'Zigbee LED Controller W (pro)',
|
|
270
|
-
extend: gledoptoExtend.light_onoff_brightness(),
|
|
292
|
+
extend: gledoptoExtend.light_onoff_brightness({noConfigure: true}),
|
|
293
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
294
|
+
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
295
|
+
await configureReadModelID(device);
|
|
296
|
+
},
|
|
271
297
|
},
|
|
272
298
|
{
|
|
273
299
|
zigbeeModel: ['GL-C-009S'],
|
package/devices/lixee.js
ADDED
|
@@ -0,0 +1,574 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
2
|
+
/* eslint-disable max-len */
|
|
3
|
+
'use strict';
|
|
4
|
+
const exposes = require('../lib/exposes');
|
|
5
|
+
const globalStore = require('../lib/store');
|
|
6
|
+
const {repInterval} = require('../lib/constants');
|
|
7
|
+
const reporting = require('../lib/reporting');
|
|
8
|
+
const fz = require('../converters/fromZigbee');
|
|
9
|
+
const ea = exposes.access;
|
|
10
|
+
const e = exposes.presets;
|
|
11
|
+
const utils = require('../lib/utils');
|
|
12
|
+
const ota = require('../lib/ota');
|
|
13
|
+
const {Buffer} = require('buffer');
|
|
14
|
+
|
|
15
|
+
const fzLocal = {
|
|
16
|
+
lixee_ha_electrical_measurement: {
|
|
17
|
+
cluster: 'haElectricalMeasurement',
|
|
18
|
+
type: ['attributeReport', 'readResponse'],
|
|
19
|
+
convert: (model, msg, publish, options, meta) => {
|
|
20
|
+
const result = {};
|
|
21
|
+
|
|
22
|
+
const elements = [
|
|
23
|
+
/* 0x0305 */ 'totalReactivePower',
|
|
24
|
+
/* 0x0505 */ 'rmsVoltage',
|
|
25
|
+
/* 0x0508 */ 'rmsCurrent',
|
|
26
|
+
/* 0x050A */ 'rmsCurrentMax',
|
|
27
|
+
/* 0x050B */ 'activePower',
|
|
28
|
+
/* 0x050D */ 'activePowerMax',
|
|
29
|
+
/* 0x050E */ 'reactivePower',
|
|
30
|
+
/* 0x050F */ 'apparentPower',
|
|
31
|
+
/* 0x0511 */ 'averageRmsVoltageMeasPeriod',
|
|
32
|
+
/* 0x0905 */ 'rmsVoltagePhB',
|
|
33
|
+
/* 0x0908 */ 'rmsCurrentPhB',
|
|
34
|
+
/* 0x090A */ 'rmsCurrentMaxPhB',
|
|
35
|
+
/* 0x090B */ 'activePowerPhB',
|
|
36
|
+
/* 0x090E */ 'reactivePowerPhB',
|
|
37
|
+
/* 0x090D */ 'activePowerMaxPhB',
|
|
38
|
+
/* 0x090F */ 'apparentPowerPhB',
|
|
39
|
+
/* 0x0911 */ 'averageRmsVoltageMeasurePeriodPhB',
|
|
40
|
+
/* 0x0A05 */ 'rmsVoltagePhC',
|
|
41
|
+
/* 0x0A08 */ 'rmsCurrentPhC',
|
|
42
|
+
/* 0x0A0A */ 'rmsCurrentMaxPhC',
|
|
43
|
+
/* 0x0A0D */ 'activePowerMaxPhC',
|
|
44
|
+
/* 0x0A0E */ 'reactivePowerPhC',
|
|
45
|
+
/* 0x0A0F */ 'apparentPowerPhC',
|
|
46
|
+
/* 0x0A11 */ 'averageRmsVoltageMeasPeriodPhC',
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
for (const at of elements) {
|
|
50
|
+
const at_snake = at.split(/(?=[A-Z])/).join('_').toLowerCase();
|
|
51
|
+
if (msg.data[at]) {
|
|
52
|
+
result[at_snake] = msg.data[at];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
lixee_private_fz: {
|
|
59
|
+
cluster: 'liXeePrivate', // 0xFF66
|
|
60
|
+
type: ['attributeReport', 'readResponse'],
|
|
61
|
+
convert: (model, msg, publish, options, meta) => {
|
|
62
|
+
const result = {};
|
|
63
|
+
const elements = [
|
|
64
|
+
/* 0x0000 */ 'currentTarif',
|
|
65
|
+
/* 0x0001 */ 'tomorrowColor',
|
|
66
|
+
/* 0x0002 */ 'scheduleHPHC',
|
|
67
|
+
/* 0x0003 */ 'presencePotential',
|
|
68
|
+
/* 0x0004 */ 'startNoticeEJP',
|
|
69
|
+
/* 0x0005 */ 'warnDPS',
|
|
70
|
+
/* 0x0006 */ 'warnDIR1',
|
|
71
|
+
/* 0x0007 */ 'warnDIR2',
|
|
72
|
+
/* 0x0008 */ 'warnDIR3',
|
|
73
|
+
/* 0x0200 */ 'currentPrice',
|
|
74
|
+
/* 0x0201 */ 'currentIndexTarif',
|
|
75
|
+
/* 0x0202 */ 'currentDate',
|
|
76
|
+
/* 0x0203 */ 'activeEnerfyOutD01',
|
|
77
|
+
/* 0x0204 */ 'activeEnerfyOutD02',
|
|
78
|
+
/* 0x0205 */ 'activeEnerfyOutD03',
|
|
79
|
+
/* 0x0206 */ 'activeEnerfyOutD04',
|
|
80
|
+
/* 0x0207 */ 'injectedVA',
|
|
81
|
+
/* 0x0208 */ 'injectedVAMaxN',
|
|
82
|
+
/* 0x0209 */ 'injectedVAMaxN1',
|
|
83
|
+
/* 0x0210 */ 'injectedActiveLoadN',
|
|
84
|
+
/* 0x0211 */ 'injectedActiveLoadN1',
|
|
85
|
+
/* 0x0212 */ 'drawnVAMaxN1',
|
|
86
|
+
/* 0x0213 */ 'drawnVAMaxN1P2',
|
|
87
|
+
/* 0x0214 */ 'drawnVAMaxN1P3',
|
|
88
|
+
/* 0x0215 */ 'message1',
|
|
89
|
+
/* 0x0216 */ 'message2',
|
|
90
|
+
/* 0x0217 */ 'statusRegister',
|
|
91
|
+
/* 0x0218 */ 'startMobilePoint1',
|
|
92
|
+
/* 0x0219 */ 'stopMobilePoint1',
|
|
93
|
+
/* 0x0220 */ 'startMobilePoint2',
|
|
94
|
+
/* 0x0221 */ 'stopMobilePoint2',
|
|
95
|
+
/* 0x0222 */ 'startMobilePoint3',
|
|
96
|
+
/* 0x0223 */ 'stopMobilePoint3',
|
|
97
|
+
/* 0x0224 */ 'relais',
|
|
98
|
+
/* 0x0225 */ 'daysNumberCurrentCalendar',
|
|
99
|
+
/* 0x0226 */ 'daysNumberNextCalendar',
|
|
100
|
+
/* 0x0227 */ 'daysProfileCurrentCalendar',
|
|
101
|
+
/* 0x0228 */ 'daysProfileNextCalendar',
|
|
102
|
+
];
|
|
103
|
+
const kWh_p = options && options.kWh_precision ? options.kWh_precision : 0;
|
|
104
|
+
for (const at of elements) {
|
|
105
|
+
const at_snake = at.split(/(?=[A-Z])/).join('_').toLowerCase();
|
|
106
|
+
let val = msg.data[at];
|
|
107
|
+
if (val) {
|
|
108
|
+
if (val.hasOwnProperty('type') && val.type === 'Buffer') {
|
|
109
|
+
val = Buffer.from(val.data);
|
|
110
|
+
}
|
|
111
|
+
if (Buffer.isBuffer(val)) {
|
|
112
|
+
val = val.toString(); // Convert buffer to string
|
|
113
|
+
}
|
|
114
|
+
if (typeof val === 'string' || val instanceof String) {
|
|
115
|
+
val = val.replace(/\0/g, ''); // Remove all null chars when str
|
|
116
|
+
val = val.replace(/\s+/g, ' ').trim(); // Remove extra and leading spaces
|
|
117
|
+
}
|
|
118
|
+
switch (at) {
|
|
119
|
+
case 'activeEnerfyOutD01':
|
|
120
|
+
case 'activeEnerfyOutD02':
|
|
121
|
+
case 'activeEnerfyOutD03':
|
|
122
|
+
case 'activeEnerfyOutD04':
|
|
123
|
+
val = utils.precisionRound(val / 1000, kWh_p); // from Wh to kWh
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
result[at_snake] = val;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
lixee_metering: {
|
|
133
|
+
cluster: 'seMetering', // 0x0702
|
|
134
|
+
type: ['attributeReport', 'readResponse'],
|
|
135
|
+
convert: (model, msg, publish, options, meta) => {
|
|
136
|
+
const result = {};
|
|
137
|
+
const elements = [
|
|
138
|
+
/* 0x0000 */ 'currentSummDelivered',
|
|
139
|
+
/* 0x0001 */ 'currentSummReceived',
|
|
140
|
+
/* 0x0020 */ 'activeRegisterTierDelivered',
|
|
141
|
+
/* 0x0100 */ 'currentTier1SummDelivered',
|
|
142
|
+
/* 0x0102 */ 'currentTier2SummDelivered',
|
|
143
|
+
/* 0x0104 */ 'currentTier3SummDelivered',
|
|
144
|
+
/* 0x0106 */ 'currentTier4SummDelivered',
|
|
145
|
+
/* 0x0108 */ 'currentTier5SummDelivered',
|
|
146
|
+
/* 0x010A */ 'currentTier6SummDelivered',
|
|
147
|
+
/* 0x010C */ 'currentTier7SummDelivered',
|
|
148
|
+
/* 0x010E */ 'currentTier8SummDelivered',
|
|
149
|
+
/* 0x0110 */ 'currentTier9SummDelivered',
|
|
150
|
+
/* 0x0112 */ 'currentTier10SummDelivered',
|
|
151
|
+
/* 0x0307 */ 'siteId',
|
|
152
|
+
/* 0x0308 */ 'meterSerialNumber',
|
|
153
|
+
];
|
|
154
|
+
const kWh_p = options && options.kWh_precision ? options.kWh_precision : 0;
|
|
155
|
+
for (const at of elements) {
|
|
156
|
+
const at_snake = at.split(/(?=[A-Z])/).join('_').toLowerCase();
|
|
157
|
+
const val = msg.data[at];
|
|
158
|
+
if (val) {
|
|
159
|
+
result[at_snake] = val; // By default we assign raw value
|
|
160
|
+
switch (at) {
|
|
161
|
+
// If we receive a Buffer, transform to human readable text
|
|
162
|
+
case 'meterSerialNumber':
|
|
163
|
+
case 'siteId':
|
|
164
|
+
if (Buffer.isBuffer(val)) {
|
|
165
|
+
result[at_snake] = val.toString();
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
case 'currentSummDelivered':
|
|
169
|
+
case 'currentSummReceived':
|
|
170
|
+
case 'currentTier1SummDelivered':
|
|
171
|
+
case 'currentTier2SummDelivered':
|
|
172
|
+
case 'currentTier3SummDelivered':
|
|
173
|
+
case 'currentTier4SummDelivered':
|
|
174
|
+
case 'currentTier5SummDelivered':
|
|
175
|
+
case 'currentTier6SummDelivered':
|
|
176
|
+
case 'currentTier7SummDelivered':
|
|
177
|
+
case 'currentTier8SummDelivered':
|
|
178
|
+
case 'currentTier9SummDelivered':
|
|
179
|
+
case 'currentTier10SummDelivered':
|
|
180
|
+
result[at_snake] = utils.precisionRound(((val[0] << 32) + val[1]) / 1000, kWh_p); // Wh to kWh
|
|
181
|
+
break;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// TODO: Check if all tarifs which doesn't publish "currentSummDelivered" use just Tier1 & Tier2
|
|
186
|
+
if (result['current_summ_delivered'] == 0 &&
|
|
187
|
+
(result['current_tier1_summ_delivered'] > 0 || result['current_tier2_summ_delivered'] > 0)) {
|
|
188
|
+
result['current_summ_delivered'] = result['current_tier1_summ_delivered'] + result['current_tier2_summ_delivered'];
|
|
189
|
+
}
|
|
190
|
+
return result;
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
const tarifsDef = {
|
|
196
|
+
histo_BASE: {fname: 'Historique - BASE',
|
|
197
|
+
currentTarf: 'BASE', excluded: [
|
|
198
|
+
'HCHC',
|
|
199
|
+
'HCHP',
|
|
200
|
+
'HHPHC',
|
|
201
|
+
'EJPHN',
|
|
202
|
+
'EJPHPM',
|
|
203
|
+
'BBRHCJB',
|
|
204
|
+
'BBRHPJB',
|
|
205
|
+
'BBRHCJW',
|
|
206
|
+
'BBRHPJW',
|
|
207
|
+
'BBRHCJR',
|
|
208
|
+
'BBRHPJR',
|
|
209
|
+
'DEMAIN',
|
|
210
|
+
'PEJP',
|
|
211
|
+
]},
|
|
212
|
+
histo_HCHP: {fname: 'Historique - HCHP',
|
|
213
|
+
currentTarf: 'HC..', excluded: [
|
|
214
|
+
'BASE',
|
|
215
|
+
'EJPHN',
|
|
216
|
+
'EJPHPM',
|
|
217
|
+
'BBRHCJB',
|
|
218
|
+
'BBRHPJB',
|
|
219
|
+
'BBRHCJW',
|
|
220
|
+
'BBRHPJW',
|
|
221
|
+
'BBRHCJR',
|
|
222
|
+
'BBRHPJR',
|
|
223
|
+
'DEMAIN',
|
|
224
|
+
'PEJP',
|
|
225
|
+
]},
|
|
226
|
+
histo_EJP: {fname: 'Historique - EJP',
|
|
227
|
+
currentTarf: 'EJP.', excluded: [
|
|
228
|
+
'BASE',
|
|
229
|
+
'HCHC',
|
|
230
|
+
'HCHP',
|
|
231
|
+
'BBRHCJB',
|
|
232
|
+
'BBRHPJB',
|
|
233
|
+
'BBRHCJW',
|
|
234
|
+
'BBRHPJW',
|
|
235
|
+
'BBRHCJR',
|
|
236
|
+
'BBRHPJR',
|
|
237
|
+
'DEMAIN',
|
|
238
|
+
]},
|
|
239
|
+
histo_BBR: {fname: 'Historique - BBR',
|
|
240
|
+
currentTarf: 'BBR', excluded: [
|
|
241
|
+
'BASE',
|
|
242
|
+
'HCHC',
|
|
243
|
+
'HCHP',
|
|
244
|
+
'EJPHN',
|
|
245
|
+
'EJPHPM',
|
|
246
|
+
'PEJP',
|
|
247
|
+
]},
|
|
248
|
+
stand_SEM_WE_MERCR: {fname: 'Standard - Sem WE Mercredi',
|
|
249
|
+
currentTarf: 'SEM WE MERCREDI', excluded: [
|
|
250
|
+
'EASF04',
|
|
251
|
+
'EASF05',
|
|
252
|
+
'EASF06',
|
|
253
|
+
'EASF07',
|
|
254
|
+
'EASF08',
|
|
255
|
+
'EASF09',
|
|
256
|
+
'EASF10',
|
|
257
|
+
'EASD02',
|
|
258
|
+
'EASD03',
|
|
259
|
+
'EASD04',
|
|
260
|
+
'DPM1',
|
|
261
|
+
'DPM2',
|
|
262
|
+
'DPM3',
|
|
263
|
+
'FPM1',
|
|
264
|
+
'FPM2',
|
|
265
|
+
'FPM3',
|
|
266
|
+
'NJOURF',
|
|
267
|
+
'NJOURF+1',
|
|
268
|
+
'PJOURF+1',
|
|
269
|
+
'PPOINTE1',
|
|
270
|
+
]},
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
const linkyModeDef = {
|
|
274
|
+
standard: 'standard',
|
|
275
|
+
legacy: 'historique',
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const linkyPhaseDef = {
|
|
279
|
+
single: 'single_phase',
|
|
280
|
+
three: 'three_phase',
|
|
281
|
+
all: 'both',
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
const clustersDef = {
|
|
285
|
+
_0xFF66: 'liXeePrivate', // 0xFF66
|
|
286
|
+
_0x0B04: 'haElectricalMeasurement', // 0x0B04
|
|
287
|
+
_0x0702: 'seMetering', // 0x0702
|
|
288
|
+
_0x0B01: 'haMeterIdentification', // 0x0B01
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
// full list available on https://github.com/fairecasoimeme/Zlinky_TIC/blob/master/README.md
|
|
293
|
+
|
|
294
|
+
// Properties must be EAXCTLY ".split(/(?=[A-Z])/).join('_').toLowerCase()" of att
|
|
295
|
+
const exposedData = [
|
|
296
|
+
// Historique
|
|
297
|
+
{cluster: clustersDef._0x0702, att: 'meterSerialNumber', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.text('ADCO', ea.STATE).withProperty('meter_serial_number').withDescription('Serial Number')},
|
|
298
|
+
{cluster: clustersDef._0x0702, att: 'currentSummDelivered', reportable: true, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BASE', ea.STATE).withUnit('kWh').withProperty('current_summ_delivered').withDescription('Base index')},
|
|
299
|
+
{cluster: clustersDef._0xFF66, att: 'currentTarif', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.text('OPTARIF', ea.STATE).withProperty('current_tarif').withDescription('Tarif option')},
|
|
300
|
+
{cluster: clustersDef._0x0B01, att: 'availablePower', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('ISOUSC', ea.STATE).withUnit('A').withProperty('available_power').withDescription('Subscribed intensity level')},
|
|
301
|
+
{cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('HCHC', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('HCHC index')},
|
|
302
|
+
{cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('HCHP', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('HCHP index')},
|
|
303
|
+
{cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('EJPHN', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('EJPHN index')},
|
|
304
|
+
{cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('EJPHPM', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('EJPHPM index')},
|
|
305
|
+
{cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJB', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('BBRHCJB index')},
|
|
306
|
+
{cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJB', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('BBRHPJB index')},
|
|
307
|
+
{cluster: clustersDef._0x0702, att: 'currentTier3SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJW', ea.STATE).withUnit('kWh').withProperty('current_tier3_summ_delivered').withDescription('BBRHCJW index')},
|
|
308
|
+
{cluster: clustersDef._0x0702, att: 'currentTier4SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJW', ea.STATE).withUnit('kWh').withProperty('current_tier4_summ_delivered').withDescription('BBRHPJW index')},
|
|
309
|
+
{cluster: clustersDef._0x0702, att: 'currentTier5SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHCJR', ea.STATE).withUnit('kWh').withProperty('current_tier5_summ_delivered').withDescription('BBRHCJR index')},
|
|
310
|
+
{cluster: clustersDef._0x0702, att: 'currentTier6SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('BBRHPJR', ea.STATE).withUnit('kWh').withProperty('current_tier6_summ_delivered').withDescription('BBRHPJR index')},
|
|
311
|
+
{cluster: clustersDef._0x0B04, att: 'rmsCurrent', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IINST', ea.STATE).withUnit('A').withProperty('rms_current').withDescription('RMS current')},
|
|
312
|
+
{cluster: clustersDef._0x0B04, att: 'rmsCurrent', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IINST1', ea.STATE).withUnit('A').withProperty('rms_current').withDescription('RMS current (phase 1)')},
|
|
313
|
+
{cluster: clustersDef._0x0B04, att: 'rmsCurrentPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IINST2', ea.STATE).withUnit('A').withProperty('rms_current_ph_b').withDescription('RMS current (phase 2)')},
|
|
314
|
+
{cluster: clustersDef._0x0B04, att: 'rmsCurrentPhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IINST3', ea.STATE).withUnit('A').withProperty('rms_current_ph_c').withDescription('RMS current (phase 3)')},
|
|
315
|
+
{cluster: clustersDef._0x0B04, att: 'rmsCurrentMax', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IMAX', ea.STATE).withUnit('A').withProperty('rms_current_max').withDescription('RMS current peak')},
|
|
316
|
+
{cluster: clustersDef._0x0B04, att: 'rmsCurrentMax', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IMAX1', ea.STATE).withUnit('A').withProperty('rms_current_max').withDescription('RMS current peak (phase 1)')},
|
|
317
|
+
{cluster: clustersDef._0x0B04, att: 'rmsCurrentMaxPhB', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IMAX2', ea.STATE).withUnit('A').withProperty('rms_current_max_ph_b').withDescription('RMS current peak (phase 2)')},
|
|
318
|
+
{cluster: clustersDef._0x0B04, att: 'rmsCurrentMaxPhC', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('IMAX3', ea.STATE).withUnit('A').withProperty('rms_current_max_ph_c').withDescription('RMS current peak (phase 3)')},
|
|
319
|
+
{cluster: clustersDef._0x0B04, att: 'activePowerMax', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('PMAX', ea.STATE).withUnit('W').withProperty('active_power_max').withDescription('Three-phase power peak')},
|
|
320
|
+
{cluster: clustersDef._0x0B04, att: 'apparentPower', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('PAPP', ea.STATE).withUnit('VA').withProperty('apparent_power').withDescription('Apparent power')},
|
|
321
|
+
{cluster: clustersDef._0x0702, att: 'activeRegisterTierDelivered', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.text('PTEC', ea.STATE).withProperty('active_register_tier_delivered').withDescription('Current pricing period')},
|
|
322
|
+
{cluster: clustersDef._0xFF66, att: 'tomorrowColor', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.text('DEMAIN', ea.STATE).withProperty('tomorrow_color').withDescription('Tomorrow color')},
|
|
323
|
+
{cluster: clustersDef._0xFF66, att: 'scheduleHPHC', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('HHPHC', ea.STATE).withProperty('schedule_h_p_h_c').withDescription('Schedule HPHC')},
|
|
324
|
+
{cluster: clustersDef._0xFF66, att: 'presencePotential', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('PPOT', ea.STATE).withProperty('presence_potential').withDescription('Presence of potentials')},
|
|
325
|
+
{cluster: clustersDef._0xFF66, att: 'startNoticeEJP', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('PEJP', ea.STATE).withUnit('min').withProperty('start_notice_e_j_p').withDescription('EJP start notice (30min)')},
|
|
326
|
+
{cluster: clustersDef._0xFF66, att: 'warnDPS', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('ADPS', ea.STATE).withUnit('A').withProperty('warn_d_p_s').withDescription('Subscribed Power Exceeded Warning')},
|
|
327
|
+
{cluster: clustersDef._0xFF66, att: 'warnDIR1', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('ADIR1', ea.STATE).withUnit('A').withProperty('warn_d_i_r1').withDescription('Over Current Warning (phase 1)')},
|
|
328
|
+
{cluster: clustersDef._0xFF66, att: 'warnDIR2', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('ADIR2', ea.STATE).withUnit('A').withProperty('warn_d_i_r2').withDescription('Over Current Warning (phase 2)')},
|
|
329
|
+
{cluster: clustersDef._0xFF66, att: 'warnDIR3', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.legacy, exposes: exposes.numeric('ADIR3', ea.STATE).withUnit('A').withProperty('warn_d_i_r3').withDescription('Over Current Warning (phase 3)')},
|
|
330
|
+
{cluster: clustersDef._0x0702, att: 'meterSerialNumber', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.text('ADSC', ea.STATE).withProperty('meter_serial_number').withDescription('Serial Number')},
|
|
331
|
+
{cluster: clustersDef._0xFF66, att: 'currentTarif', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.text('NGTF', ea.STATE).withProperty('current_tarif').withDescription('Supplier pricing schedule name')},
|
|
332
|
+
{cluster: clustersDef._0xFF66, att: 'currentPrice', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.text('LTARF', ea.STATE).withProperty('current_price').withDescription('Current supplier price label')},
|
|
333
|
+
{cluster: clustersDef._0xFF66, att: 'currentIndexTarif', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('NTARF', ea.STATE).withProperty('current_index_tarif').withDescription('Current tariff index number')},
|
|
334
|
+
{cluster: clustersDef._0x0B01, att: 'softwareRevision', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('VTIC', ea.STATE).withProperty('software_revision').withDescription('Customer tele-information protocol version')},
|
|
335
|
+
{cluster: clustersDef._0xFF66, att: 'currentDate', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.text('DATE', ea.STATE).withProperty('current_date').withDescription('Current date and time')},
|
|
336
|
+
{cluster: clustersDef._0x0702, att: 'currentSummDelivered', reportable: true, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EAST', ea.STATE).withUnit('kWh').withProperty('current_summ_delivered').withDescription('Total active power delivered')},
|
|
337
|
+
{cluster: clustersDef._0x0702, att: 'currentTier1SummDelivered', reportable: true, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF01', ea.STATE).withUnit('kWh').withProperty('current_tier1_summ_delivered').withDescription('Total provider active power delivered (index 01)')},
|
|
338
|
+
{cluster: clustersDef._0x0702, att: 'currentTier2SummDelivered', reportable: true, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF02', ea.STATE).withUnit('kWh').withProperty('current_tier2_summ_delivered').withDescription('Total provider active power delivered (index 02)')},
|
|
339
|
+
{cluster: clustersDef._0x0702, att: 'currentTier3SummDelivered', reportable: true, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF03', ea.STATE).withUnit('kWh').withProperty('current_tier3_summ_delivered').withDescription('Total provider active power delivered (index 03)')},
|
|
340
|
+
{cluster: clustersDef._0x0702, att: 'currentTier4SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF04', ea.STATE).withUnit('kWh').withProperty('current_tier4_summ_delivered').withDescription('Total provider active power delivered (index 04)')},
|
|
341
|
+
{cluster: clustersDef._0x0702, att: 'currentTier5SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF05', ea.STATE).withUnit('kWh').withProperty('current_tier5_summ_delivered').withDescription('Total provider active power delivered (index 05)')},
|
|
342
|
+
{cluster: clustersDef._0x0702, att: 'currentTier6SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF06', ea.STATE).withUnit('kWh').withProperty('current_tier6_summ_delivered').withDescription('Total provider active power delivered (index 06)')},
|
|
343
|
+
{cluster: clustersDef._0x0702, att: 'currentTier7SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF07', ea.STATE).withUnit('kWh').withProperty('current_tier7_summ_delivered').withDescription('Total provider active power delivered (index 07)')},
|
|
344
|
+
{cluster: clustersDef._0x0702, att: 'currentTier8SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF08', ea.STATE).withUnit('kWh').withProperty('current_tier8_summ_delivered').withDescription('Total provider active power delivered (index 08)')},
|
|
345
|
+
{cluster: clustersDef._0x0702, att: 'currentTier9SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF09', ea.STATE).withUnit('kWh').withProperty('current_tier9_summ_delivered').withDescription('Total provider active power delivered (index 09)')},
|
|
346
|
+
{cluster: clustersDef._0x0702, att: 'currentTier10SummDelivered', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASF10', ea.STATE).withUnit('kWh').withProperty('current_tier10_summ_delivered').withDescription('Total provider active power delivered (index 10)')},
|
|
347
|
+
{cluster: clustersDef._0xFF66, att: 'activeEnerfyOutD01', reportable: true, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASD01', ea.STATE).withUnit('kWh').withProperty('active_enerfy_out_d01').withDescription('Active energy withdrawn Distributor (index 01)')},
|
|
348
|
+
{cluster: clustersDef._0xFF66, att: 'activeEnerfyOutD02', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASD02', ea.STATE).withUnit('kWh').withProperty('active_enerfy_out_d02').withDescription('Active energy withdrawn Distributor (index 02)')},
|
|
349
|
+
{cluster: clustersDef._0xFF66, att: 'activeEnerfyOutD03', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASD03', ea.STATE).withUnit('kWh').withProperty('active_enerfy_out_d03').withDescription('Active energy withdrawn Distributor (index 03)')},
|
|
350
|
+
{cluster: clustersDef._0xFF66, att: 'activeEnerfyOutD04', reportable: false, reportChange: 100, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EASD04', ea.STATE).withUnit('kWh').withProperty('active_enerfy_out_d04').withDescription('Active energy withdrawn Distributor (index 04)')},
|
|
351
|
+
{cluster: clustersDef._0x0702, att: 'currentSummReceived', reportable: true, reportChange: 100, onlyProducer: true, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('EAIT', ea.STATE).withUnit('kWh').withProperty('current_summ_received').withDescription('Total active power injected')},
|
|
352
|
+
{cluster: clustersDef._0x0B04, att: 'totalReactivePower', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('ERQ1', ea.STATE).withUnit('VArh').withProperty('total_reactive_power').withDescription('Total reactive power (Q1)')},
|
|
353
|
+
{cluster: clustersDef._0x0B04, att: 'reactivePower', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('ERQ2', ea.STATE).withUnit('VArh').withProperty('reactive_power').withDescription('Total reactive power (Q2)')},
|
|
354
|
+
{cluster: clustersDef._0x0B04, att: 'reactivePowerPhB', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('ERQ3', ea.STATE).withUnit('VArh').withProperty('reactive_power_ph_b').withDescription('Total reactive power (Q3)')},
|
|
355
|
+
{cluster: clustersDef._0x0B04, att: 'reactivePowerPhC', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('ERQ4', ea.STATE).withUnit('VArh').withProperty('reactive_power_ph_c').withDescription('Total reactive power (Q4)')},
|
|
356
|
+
{cluster: clustersDef._0x0B04, att: 'rmsCurrent', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('IRMS1', ea.STATE).withUnit('A').withProperty('rms_current').withDescription('RMS current')},
|
|
357
|
+
{cluster: clustersDef._0x0B04, att: 'rmsCurrentPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('IRMS2', ea.STATE).withUnit('A').withProperty('rms_current_ph_b').withDescription('RMS current (phase 2)')},
|
|
358
|
+
{cluster: clustersDef._0x0B04, att: 'rmsCurrentPhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('IRMS3', ea.STATE).withUnit('A').withProperty('rms_current_ph_c').withDescription('RMS current (phase 3)')},
|
|
359
|
+
{cluster: clustersDef._0x0B04, att: 'rmsVoltage', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('URMS1', ea.STATE).withUnit('V').withProperty('rms_voltage').withDescription('RMS voltage')},
|
|
360
|
+
{cluster: clustersDef._0x0B04, att: 'rmsVoltagePhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('URMS2', ea.STATE).withUnit('V').withProperty('rms_voltage_ph_b').withDescription('RMS voltage (phase 2)')},
|
|
361
|
+
{cluster: clustersDef._0x0B04, att: 'rmsVoltagePhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('URMS3', ea.STATE).withUnit('V').withProperty('rms_voltage_ph_c').withDescription('RMS voltage (phase 3)')},
|
|
362
|
+
{cluster: clustersDef._0x0B01, att: 'availablePower', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('PREF', ea.STATE).withUnit('kVA').withProperty('available_power').withDescription('Apparent power of reference')},
|
|
363
|
+
{cluster: clustersDef._0xFF66, att: 'statusRegister', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.text('STGE', ea.STATE).withProperty('status_register').withDescription('Register of Statutes')},
|
|
364
|
+
{cluster: clustersDef._0x0B01, att: 'powerThreshold', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('PCOUP', ea.STATE).withUnit('kVA').withProperty('power_threshold').withDescription('Apparent power threshold')},
|
|
365
|
+
{cluster: clustersDef._0xFF66, att: 'injectedVA', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SINSTI', ea.STATE).withUnit('VA').withProperty('injected_v_a').withDescription('Instantaneous apparent power injected')},
|
|
366
|
+
{cluster: clustersDef._0xFF66, att: 'injectedVAMaxN', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXIN', ea.STATE).withUnit('VA').withProperty('injected_v_a_max_n').withDescription('Apparent power max. injected n')},
|
|
367
|
+
{cluster: clustersDef._0xFF66, att: 'injectedVAMaxN1', reportable: false, onlyProducer: true, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXIN-1', ea.STATE).withUnit('VA').withProperty('injected_v_a_max_n1').withDescription('Apparent power max. injected n-1')},
|
|
368
|
+
{cluster: clustersDef._0x0B04, att: 'activePower', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('CCASN', ea.STATE).withUnit('W').withProperty('active_power').withDescription('Current point of the active load curve drawn')},
|
|
369
|
+
{cluster: clustersDef._0x0B04, att: 'activePowerPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('CCASN-1', ea.STATE).withUnit('W').withProperty('active_power_ph_b').withDescription('Previous point of the active load curve drawn')},
|
|
370
|
+
{cluster: clustersDef._0xFF66, att: 'injectedActiveLoadN', reportable: true, onlyProducer: true, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('CCAIN', ea.STATE).withUnit('W').withProperty('injected_active_load_n').withDescription('Point n of the withdrawn active load curve')},
|
|
371
|
+
{cluster: clustersDef._0xFF66, att: 'injectedActiveLoadN1', reportable: false, onlyProducer: true, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('CCAIN-1', ea.STATE).withUnit('W').withProperty('injected_active_load_n1').withDescription('Point n-1 of the withdrawn active load curve')},
|
|
372
|
+
{cluster: clustersDef._0x0B04, att: 'averageRmsVoltageMeasPeriod', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.all, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('UMOY1', ea.STATE).withUnit('V').withProperty('average_rms_voltage_meas_period').withDescription('Average RMS voltage (phase 1)')},
|
|
373
|
+
{cluster: clustersDef._0x0B04, att: 'averageRmsVoltageMeasurePeriodPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('UMOY2', ea.STATE).withUnit('V').withProperty('average_rms_voltage_measure_period_ph_b').withDescription('Average RMS voltage (phase 2)')},
|
|
374
|
+
{cluster: clustersDef._0x0B04, att: 'averageRmsVoltageMeasPeriodPhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('UMOY3', ea.STATE).withUnit('V').withProperty('average_rms_voltage_meas_period_ph_c').withDescription('Average RMS voltage (phase 3)')},
|
|
375
|
+
{cluster: clustersDef._0x0B04, att: 'apparentPower', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SINSTS', ea.STATE).withUnit('VA').withProperty('apparent_power').withDescription('Immediate apparent power delivered')},
|
|
376
|
+
{cluster: clustersDef._0x0B04, att: 'apparentPower', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SINSTS1', ea.STATE).withUnit('VA').withProperty('apparent_power').withDescription('Immediate apparent power delivered (phase 1)')},
|
|
377
|
+
{cluster: clustersDef._0x0B04, att: 'apparentPowerPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SINSTS2', ea.STATE).withUnit('VA').withProperty('apparent_power_ph_b').withDescription('Immediate apparent power delivered (phase 2)')},
|
|
378
|
+
{cluster: clustersDef._0x0B04, att: 'apparentPowerPhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SINSTS3', ea.STATE).withUnit('VA').withProperty('apparent_power_ph_c').withDescription('Immediate apparent power delivered (phase 3)')},
|
|
379
|
+
{cluster: clustersDef._0x0B04, att: 'activePowerMax', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN', ea.STATE).withUnit('VA').withProperty('active_power_max').withDescription('Apparent power delivered peak')},
|
|
380
|
+
{cluster: clustersDef._0x0B04, att: 'activePowerMax', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN1', ea.STATE).withUnit('VA').withProperty('active_power_max').withDescription('Apparent power delivered peak (phase 1)')},
|
|
381
|
+
{cluster: clustersDef._0x0B04, att: 'activePowerMaxPhB', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN2', ea.STATE).withUnit('VA').withProperty('active_power_max_ph_b').withDescription('Apparent power delivered peak (phase 2)')},
|
|
382
|
+
{cluster: clustersDef._0x0B04, att: 'activePowerMaxPhC', reportable: true, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN3', ea.STATE).withUnit('VA').withProperty('active_power_max_ph_c').withDescription('Apparent power delivered peak (phase 3)')},
|
|
383
|
+
{cluster: clustersDef._0xFF66, att: 'drawnVAMaxN1', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN-1', ea.STATE).withUnit('VA').withProperty('drawn_v_a_max_n1').withDescription('Apparent power max. draw-off n-1')},
|
|
384
|
+
{cluster: clustersDef._0xFF66, att: 'drawnVAMaxN1', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN1-1', ea.STATE).withUnit('VA').withProperty('drawn_v_a_max_n1').withDescription('Apparent power max. draw-off n-1 (phase 1)')},
|
|
385
|
+
{cluster: clustersDef._0xFF66, att: 'drawnVAMaxN1P2', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN2-1', ea.STATE).withUnit('VA').withProperty('drawn_v_a_max_n1_p2').withDescription('Apparent power max. draw-off n-1 (phase 2)')},
|
|
386
|
+
{cluster: clustersDef._0xFF66, att: 'drawnVAMaxN1P3', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.three, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('SMAXN3-1', ea.STATE).withUnit('VA').withProperty('drawn_v_a_max_n1_p3').withDescription('Apparent power max. draw-off n-1 (phase 3)')},
|
|
387
|
+
{cluster: clustersDef._0xFF66, att: 'message1', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.text('MSG1', ea.STATE).withProperty('message1').withDescription('Message short')},
|
|
388
|
+
{cluster: clustersDef._0xFF66, att: 'message2', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.text('MSG2', ea.STATE).withProperty('message2').withDescription('Message ultra-short')},
|
|
389
|
+
{cluster: clustersDef._0x0702, att: 'siteId', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.text('PRM', ea.STATE).withProperty('site_id').withDescription('PRM number')},
|
|
390
|
+
{cluster: clustersDef._0xFF66, att: 'startMobilePoint1', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('DPM1', ea.STATE).withProperty('start_mobile_point1').withDescription('Start mobile point 1')},
|
|
391
|
+
{cluster: clustersDef._0xFF66, att: 'stopMobilePoint1', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('FPM1', ea.STATE).withProperty('stop_mobile_point1').withDescription('Stop mobile point 1')},
|
|
392
|
+
{cluster: clustersDef._0xFF66, att: 'startMobilePoint2', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('DPM2', ea.STATE).withProperty('start_mobile_point2').withDescription('Start mobile point 2')},
|
|
393
|
+
{cluster: clustersDef._0xFF66, att: 'stopMobilePoint2', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('FPM2', ea.STATE).withProperty('stop_mobile_point2').withDescription('Stop mobile point 2')},
|
|
394
|
+
{cluster: clustersDef._0xFF66, att: 'startMobilePoint3', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('DPM3', ea.STATE).withProperty('start_mobile_point3').withDescription('Start mobile point 3')},
|
|
395
|
+
{cluster: clustersDef._0xFF66, att: 'stopMobilePoint3', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('FPM3', ea.STATE).withProperty('stop_mobile_point3').withDescription('Stop mobile point 3')},
|
|
396
|
+
{cluster: clustersDef._0xFF66, att: 'relais', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('RELAIS', ea.STATE).withProperty('relais')},
|
|
397
|
+
{cluster: clustersDef._0xFF66, att: 'daysNumberCurrentCalendar', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('NJOURF', ea.STATE).withProperty('days_number_current_calendar').withDescription('Current day number supplier calendar')},
|
|
398
|
+
{cluster: clustersDef._0xFF66, att: 'daysNumberNextCalendar', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.numeric('NJOURF+1', ea.STATE).withProperty('days_number_next_calendar').withDescription('Next day number supplier calendar')},
|
|
399
|
+
{cluster: clustersDef._0xFF66, att: 'daysProfileCurrentCalendar', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.text('PJOURF+1', ea.STATE).withProperty('days_profile_current_calendar').withDescription('Profile of the next supplier calendar day')},
|
|
400
|
+
{cluster: clustersDef._0xFF66, att: 'daysProfileNextCalendar', reportable: false, onlyProducer: false, linkyPhase: linkyPhaseDef.single, linkyMode: linkyModeDef.standard, exposes: exposes.text('PPOINTE1', ea.STATE).withProperty('days_profile_next_calendar').withDescription('Profile of the next check-in day')},
|
|
401
|
+
];
|
|
402
|
+
|
|
403
|
+
function getCurrentConfig(device, options, logger=console) {
|
|
404
|
+
let endpoint;
|
|
405
|
+
try {
|
|
406
|
+
endpoint = device.getEndpoint(1);
|
|
407
|
+
} catch (error) {
|
|
408
|
+
logger.debug(error);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function getConfig(targetOption, bitLinkyMode, valueTrue, valueFalse) {
|
|
412
|
+
const valueDefault = valueFalse;
|
|
413
|
+
if (options && options.hasOwnProperty(targetOption) && options[targetOption] != 'auto') {
|
|
414
|
+
if (options[targetOption] === 'true' || options[targetOption] === 'false') {
|
|
415
|
+
return options[targetOption] === 'true'; // special case for production
|
|
416
|
+
}
|
|
417
|
+
return options[targetOption];
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
let lMode;
|
|
421
|
+
try {
|
|
422
|
+
lMode = endpoint.clusters[clustersDef._0xFF66].attributes['linkyMode'];
|
|
423
|
+
lMode.raiseError; // raise if undefined
|
|
424
|
+
return (lMode >> bitLinkyMode & 1) == 1 ? valueTrue : valueFalse;
|
|
425
|
+
} catch (err) {
|
|
426
|
+
logger.warn(`Was not able to detect the Linky `+ targetOption +`. Default to ` + valueDefault);
|
|
427
|
+
return valueDefault; // default value in the worst case
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
const linkyMode = getConfig('linky_mode', 0, linkyModeDef.standard, linkyModeDef.legacy);
|
|
432
|
+
|
|
433
|
+
const linkyPhase = getConfig('energy_phase', 1, linkyPhaseDef.three, linkyPhaseDef.single);
|
|
434
|
+
|
|
435
|
+
let linkyProduction = false; // In historique we can't be producer
|
|
436
|
+
|
|
437
|
+
if (linkyMode == linkyModeDef.standard) {
|
|
438
|
+
linkyProduction = getConfig('production', 2, true, false);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
// Main filter
|
|
442
|
+
let myExpose = exposedData
|
|
443
|
+
.filter((e) => e.linkyMode == linkyMode && (e.linkyPhase == linkyPhase || e.linkyPhase == linkyPhaseDef.all) && (linkyProduction || !e.onlyProducer));
|
|
444
|
+
|
|
445
|
+
// Filter even more, based on our current tarif
|
|
446
|
+
let currentTarf;
|
|
447
|
+
|
|
448
|
+
try {
|
|
449
|
+
// Try to remove atributes which doesn't match current tarif
|
|
450
|
+
currentTarf = endpoint.clusters.liXeePrivate.attributes.currentTarif.replace(/\0/g, '');
|
|
451
|
+
} catch (error) {
|
|
452
|
+
currentTarf = '';
|
|
453
|
+
if (options && options.hasOwnProperty('tarif') && options['tarif'] != 'auto') {
|
|
454
|
+
currentTarf = Object.entries(tarifsDef).find(( [k, v] ) => (v.fname == options['tarif']))[1].currentTarf;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// logger.debug(`zlinky config: ` + linkyMode + `, `+ linkyPhase + `, `+ linkyProduction.toString() +`, `+ currentTarf);
|
|
459
|
+
|
|
460
|
+
switch (currentTarf) {
|
|
461
|
+
case linkyMode == linkyModeDef.legacy && tarifsDef.histo_BASE.currentTarf:
|
|
462
|
+
myExpose = myExpose.filter((a) => !tarifsDef.histo_BASE.excluded.includes(a.exposes.name));
|
|
463
|
+
break;
|
|
464
|
+
case linkyMode == linkyModeDef.legacy && tarifsDef.histo_HCHP.currentTarf:
|
|
465
|
+
myExpose = myExpose.filter((a) => !tarifsDef.histo_HCHP.excluded.includes(a.exposes.name));
|
|
466
|
+
break;
|
|
467
|
+
case linkyMode == linkyModeDef.legacy && tarifsDef.histo_EJP.currentTarf:
|
|
468
|
+
myExpose = myExpose.filter((a) => !tarifsDef.histo_EJP.excluded.includes(a.exposes.name));
|
|
469
|
+
break;
|
|
470
|
+
case linkyMode == linkyModeDef.legacy && currentTarf.startsWith(tarifsDef.histo_BBR.currentTarf):
|
|
471
|
+
myExpose = myExpose.filter((a) => !tarifsDef.histo_BBR.excluded.includes(a.exposes.name));
|
|
472
|
+
break;
|
|
473
|
+
case linkyMode == linkyModeDef.standard && tarifsDef.stand_SEM_WE_MERCR.currentTarf:
|
|
474
|
+
myExpose = myExpose.filter((a) => !tarifsDef.stand_SEM_WE_MERCR.excluded.includes(a.exposes.name));
|
|
475
|
+
break;
|
|
476
|
+
default:
|
|
477
|
+
break;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
return myExpose;
|
|
482
|
+
}
|
|
483
|
+
const definition = {
|
|
484
|
+
zigbeeModel: ['ZLinky_TIC'],
|
|
485
|
+
model: 'ZLinky_TIC',
|
|
486
|
+
vendor: 'LiXee',
|
|
487
|
+
description: 'Lixee ZLinky',
|
|
488
|
+
fromZigbee: [fzLocal.lixee_metering, fz.meter_identification, fzLocal.lixee_ha_electrical_measurement, fzLocal.lixee_private_fz],
|
|
489
|
+
toZigbee: [],
|
|
490
|
+
exposes: (device, options) => {
|
|
491
|
+
// docs generation
|
|
492
|
+
let exposes;
|
|
493
|
+
if (device == null && options == null) {
|
|
494
|
+
exposes = exposedData.map((e) => e.exposes);
|
|
495
|
+
} else {
|
|
496
|
+
exposes = getCurrentConfig(device, options).map((e) => e.exposes);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
exposes.push(e.linkquality());
|
|
500
|
+
return exposes;
|
|
501
|
+
},
|
|
502
|
+
options: [
|
|
503
|
+
exposes.options.measurement_poll_interval(),
|
|
504
|
+
exposes.enum(`linky_mode`, ea.SET, ['auto', linkyModeDef.legacy, linkyModeDef.standard])
|
|
505
|
+
.withDescription(`Counter with TIC in mode standard or historique. May require restart (default: auto)`),
|
|
506
|
+
exposes.enum(`energy_phase`, ea.SET, ['auto', linkyPhaseDef.single, linkyPhaseDef.three])
|
|
507
|
+
.withDescription(`Power with single or three phase. May require restart (default: auto)`),
|
|
508
|
+
exposes.enum(`production`, ea.SET, ['auto', 'true', 'false']).withDescription(`If you produce energy back to the grid (works ONLY when linky_mode: ${linkyModeDef.standard}, default: auto)`),
|
|
509
|
+
exposes.enum(`tarif`, ea.SET, [...Object.entries(tarifsDef).map(( [k, v] ) => (v.fname)), 'auto'])
|
|
510
|
+
.withDescription(`The current tarif. This option will exclude unnecesary attributes. Default: auto`),
|
|
511
|
+
exposes.options.precision(`kWh`),
|
|
512
|
+
],
|
|
513
|
+
configure: async (device, coordinatorEndpoint, logger, options) => {
|
|
514
|
+
const endpoint = device.getEndpoint(1);
|
|
515
|
+
|
|
516
|
+
await reporting.bind(endpoint, coordinatorEndpoint, [
|
|
517
|
+
clustersDef._0x0702, /* seMetering */
|
|
518
|
+
clustersDef._0x0B01, /* haMeterIdentification */
|
|
519
|
+
clustersDef._0x0B04, /* haElectricalMeasurement */
|
|
520
|
+
clustersDef._0xFF66, /* liXeePrivate */
|
|
521
|
+
]);
|
|
522
|
+
|
|
523
|
+
const configReportings = [];
|
|
524
|
+
const suscribeNew = getCurrentConfig(device, options, logger).filter((e) => e.reportable);
|
|
525
|
+
|
|
526
|
+
const unsuscribe = endpoint.configuredReportings
|
|
527
|
+
.filter((e) => !suscribeNew.some((r) => e.cluster.name == r.cluster && e.attribute.name == r.att));
|
|
528
|
+
// Unsuscribe reports that doesn't correspond with the current config
|
|
529
|
+
(await Promise.allSettled(unsuscribe.map((e) => endpoint.configureReporting(e.cluster.name, reporting.payload(e.attribute.name, e.minimumReportInterval, 65535, e.reportableChange)))))
|
|
530
|
+
.filter((e) => e.status == 'rejected')
|
|
531
|
+
.forEach((e) => {
|
|
532
|
+
throw e.reason;
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
for (const e of suscribeNew) {
|
|
536
|
+
let change = 1;
|
|
537
|
+
if (e.hasOwnProperty('reportChange')) {
|
|
538
|
+
change = e['reportChange'];
|
|
539
|
+
}
|
|
540
|
+
configReportings.push(endpoint
|
|
541
|
+
.configureReporting(
|
|
542
|
+
e.cluster, reporting.payload(e.att, 0, repInterval.MINUTES_15, change)),
|
|
543
|
+
);
|
|
544
|
+
}
|
|
545
|
+
(await Promise.allSettled(configReportings))
|
|
546
|
+
.filter((e) => e.status == 'rejected')
|
|
547
|
+
.forEach((e) => {
|
|
548
|
+
throw e.reason;
|
|
549
|
+
});
|
|
550
|
+
},
|
|
551
|
+
ota: ota.lixee,
|
|
552
|
+
onEvent: async (type, data, device, options) => {
|
|
553
|
+
const endpoint = device.getEndpoint(1);
|
|
554
|
+
if (type === 'stop') {
|
|
555
|
+
clearInterval(globalStore.getValue(device, 'interval'));
|
|
556
|
+
globalStore.clearValue(device, 'interval');
|
|
557
|
+
} else if (!globalStore.hasValue(device, 'interval')) {
|
|
558
|
+
const seconds = options && options.measurement_poll_interval ? options.measurement_poll_interval : 60;
|
|
559
|
+
|
|
560
|
+
const interval = setInterval(async () => {
|
|
561
|
+
const currentExposes = getCurrentConfig(device, options)
|
|
562
|
+
.filter((e) => !endpoint.configuredReportings.some((r) => r.cluster.name == e.cluster && r.attribute.name == e.att));
|
|
563
|
+
for (const e of currentExposes) {
|
|
564
|
+
await endpoint
|
|
565
|
+
.read(e.cluster, [e.att])
|
|
566
|
+
.catch((err) => { }); // TODO: Ignore reads error?
|
|
567
|
+
}
|
|
568
|
+
}, seconds * 1000);
|
|
569
|
+
globalStore.putValue(device, 'interval', interval);
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
module.exports = [definition];
|
package/devices/moes.js
CHANGED
|
@@ -118,9 +118,13 @@ module.exports = [
|
|
|
118
118
|
model: 'ZTS-EU_1gang',
|
|
119
119
|
vendor: 'Moes',
|
|
120
120
|
description: 'Wall touch light switch (1 gang)',
|
|
121
|
-
exposes: [e.switch().setAccess('state', ea.STATE_SET)
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
exposes: [e.switch().setAccess('state', ea.STATE_SET),
|
|
122
|
+
exposes.enum('indicate_light', ea.STATE_SET, ['off', 'switch', 'position'])
|
|
123
|
+
.withDescription('Indicator light status'),
|
|
124
|
+
exposes.enum('power_on_behavior', ea.STATE_SET, ['off', 'on', 'previous'])
|
|
125
|
+
.withDescription('Controls the behavior when the device is powered on')],
|
|
126
|
+
fromZigbee: [fz.tuya_switch, fz.moes_switch],
|
|
127
|
+
toZigbee: [tz.tuya_switch_state, tz.moes_switch],
|
|
124
128
|
onEvent: tuya.onEventSetLocalTime,
|
|
125
129
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
126
130
|
await reporting.bind(device.getEndpoint(1), coordinatorEndpoint, ['genOnOff']);
|
|
@@ -135,9 +139,13 @@ module.exports = [
|
|
|
135
139
|
vendor: 'Moes',
|
|
136
140
|
description: 'Wall touch light switch (2 gang)',
|
|
137
141
|
exposes: [e.switch().withEndpoint('l1').setAccess('state', ea.STATE_SET),
|
|
138
|
-
e.switch().withEndpoint('l2').setAccess('state', ea.STATE_SET)
|
|
139
|
-
|
|
140
|
-
|
|
142
|
+
e.switch().withEndpoint('l2').setAccess('state', ea.STATE_SET),
|
|
143
|
+
exposes.enum('indicate_light', ea.STATE_SET, ['off', 'switch', 'position'])
|
|
144
|
+
.withDescription('Indicator light status'),
|
|
145
|
+
exposes.enum('power_on_behavior', ea.STATE_SET, ['off', 'on', 'previous'])
|
|
146
|
+
.withDescription('Controls the behavior when the device is powered on')],
|
|
147
|
+
fromZigbee: [fz.ignore_basic_report, fz.tuya_switch, fz.moes_switch],
|
|
148
|
+
toZigbee: [tz.tuya_switch_state, tz.moes_switch],
|
|
141
149
|
onEvent: tuya.onEventSetLocalTime,
|
|
142
150
|
meta: {multiEndpoint: true},
|
|
143
151
|
endpoint: (device) => {
|
|
@@ -158,9 +166,14 @@ module.exports = [
|
|
|
158
166
|
vendor: 'Moes',
|
|
159
167
|
description: 'Wall touch light switch (3 gang)',
|
|
160
168
|
exposes: [e.switch().withEndpoint('l1').setAccess('state', ea.STATE_SET),
|
|
161
|
-
e.switch().withEndpoint('l2').setAccess('state', ea.STATE_SET),
|
|
162
|
-
|
|
163
|
-
|
|
169
|
+
e.switch().withEndpoint('l2').setAccess('state', ea.STATE_SET),
|
|
170
|
+
e.switch().withEndpoint('l3').setAccess('state', ea.STATE_SET),
|
|
171
|
+
exposes.enum('indicate_light', ea.STATE_SET, ['off', 'switch', 'position'])
|
|
172
|
+
.withDescription('Indicator light status'),
|
|
173
|
+
exposes.enum('power_on_behavior', ea.STATE_SET, ['off', 'on', 'previous'])
|
|
174
|
+
.withDescription('Controls the behavior when the device is powered on')],
|
|
175
|
+
fromZigbee: [fz.ignore_basic_report, fz.tuya_switch, fz.moes_switch],
|
|
176
|
+
toZigbee: [tz.tuya_switch_state, tz.moes_switch],
|
|
164
177
|
onEvent: tuya.onEventSetLocalTime,
|
|
165
178
|
meta: {multiEndpoint: true},
|
|
166
179
|
endpoint: (device) => {
|
|
@@ -29,7 +29,7 @@ module.exports = [
|
|
|
29
29
|
description: 'Smart power strip',
|
|
30
30
|
extend: extend.switch(),
|
|
31
31
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
32
|
-
const endpoint = device.getEndpoint(11);
|
|
32
|
+
const endpoint = device.getEndpoint(11) || device.getEndpoint(1);
|
|
33
33
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
34
34
|
await reporting.onOff(endpoint);
|
|
35
35
|
},
|
|
@@ -96,7 +96,8 @@ module.exports = [
|
|
|
96
96
|
toZigbee: extend.light_onoff_brightness_colortemp_color().toZigbee.concat([tz.tint_scene]),
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
|
-
|
|
99
|
+
fingerprint: [{manufacturerName: '_TZ3000_bdbb0fon'}],
|
|
100
|
+
zigbeeModel: ['ZBT-Remote-ALL-RGBW', 'TS1001'],
|
|
100
101
|
model: 'MLI-404011',
|
|
101
102
|
description: 'Tint remote control',
|
|
102
103
|
vendor: 'Müller Licht',
|
package/devices/philips.js
CHANGED
|
@@ -1904,10 +1904,10 @@ module.exports = [
|
|
|
1904
1904
|
vendor: 'Philips',
|
|
1905
1905
|
description: 'Hue dimmer switch',
|
|
1906
1906
|
fromZigbee: [fz.ignore_command_on, fz.ignore_command_off, fz.ignore_command_step, fz.ignore_command_stop,
|
|
1907
|
-
fz.hue_dimmer_switch, fz.battery],
|
|
1907
|
+
fz.hue_dimmer_switch, fz.battery, fz.command_recall],
|
|
1908
1908
|
exposes: [e.battery(), e.action(['on_press', 'on_hold', 'on_press_release', 'on_hold_release',
|
|
1909
1909
|
'off_press', 'off_hold', 'off_press_release', 'off_hold_release', 'up_press', 'up_hold', 'up_press_release', 'up_hold_release',
|
|
1910
|
-
'down_press', 'down_hold', 'down_press_release', 'down_hold_release'])],
|
|
1910
|
+
'down_press', 'down_hold', 'down_press_release', 'down_hold_release', 'recall_0', 'recall_1'])],
|
|
1911
1911
|
toZigbee: [],
|
|
1912
1912
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1913
1913
|
const endpoint = device.getEndpoint(1);
|
package/devices/schwaiger.js
CHANGED
|
@@ -45,4 +45,11 @@ module.exports = [
|
|
|
45
45
|
description: 'LED bulb GU10 350 lumen, dimmable, color, white 2700-6500K',
|
|
46
46
|
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
|
|
47
47
|
},
|
|
48
|
+
{
|
|
49
|
+
zigbeeModel: ['ZBT-DIMLight-GU100800'],
|
|
50
|
+
model: 'HAL400',
|
|
51
|
+
vendor: 'Schwaiger',
|
|
52
|
+
description: 'LED Schwaiger HAL400 GU10 dimmable, warm white',
|
|
53
|
+
extend: extend.light_onoff_brightness(),
|
|
54
|
+
},
|
|
48
55
|
];
|
package/devices/sengled.js
CHANGED
|
@@ -60,13 +60,20 @@ module.exports = [
|
|
|
60
60
|
model: 'E11-G13',
|
|
61
61
|
vendor: 'Sengled',
|
|
62
62
|
description: 'Element classic (A19)',
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
fromZigbee: extend.light_onoff_brightness().fromZigbee.concat([fz.metering]),
|
|
64
|
+
toZigbee: extend.light_onoff_brightness().toZigbee,
|
|
65
65
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
66
66
|
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
67
67
|
device.powerSource = 'Mains (single phase)';
|
|
68
68
|
device.save();
|
|
69
|
+
|
|
70
|
+
const endpoint = device.getEndpoint(1);
|
|
71
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'seMetering']);
|
|
72
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
73
|
+
await reporting.currentSummDelivered(endpoint);
|
|
74
|
+
await reporting.instantaneousDemand(endpoint);
|
|
69
75
|
},
|
|
76
|
+
exposes: [e.power(), e.energy(), e.light_brightness()],
|
|
70
77
|
},
|
|
71
78
|
{
|
|
72
79
|
zigbeeModel: ['E11-G23', 'E11-G33'],
|
package/devices/sonoff.js
CHANGED
|
@@ -14,6 +14,17 @@ module.exports = [
|
|
|
14
14
|
extend: extend.switch(),
|
|
15
15
|
fromZigbee: [fz.on_off_skip_duplicate_transaction],
|
|
16
16
|
},
|
|
17
|
+
{
|
|
18
|
+
zigbeeModel: ['ZBMINI-L'],
|
|
19
|
+
model: 'ZBMINI-L',
|
|
20
|
+
vendor: 'SONOFF',
|
|
21
|
+
description: 'Zigbee smart switch (no neutral)',
|
|
22
|
+
extend: extend.switch(),
|
|
23
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
24
|
+
device.powerSource = 'Mains (single phase)';
|
|
25
|
+
device.save();
|
|
26
|
+
},
|
|
27
|
+
},
|
|
17
28
|
{
|
|
18
29
|
zigbeeModel: ['01MINIZB'],
|
|
19
30
|
model: 'ZBMINI',
|
package/devices/sunricher.js
CHANGED
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'];
|
|
15
|
+
'_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_2xlvlnez'];
|
|
16
16
|
|
|
17
17
|
const tzLocal = {
|
|
18
18
|
TS0504B_color: {
|
|
@@ -250,7 +250,7 @@ module.exports = [
|
|
|
250
250
|
model: 'TS0202',
|
|
251
251
|
vendor: 'TuYa',
|
|
252
252
|
description: 'Motion sensor',
|
|
253
|
-
whiteLabel: [{vendor: 'Mercator Ikuü', model: 'SMA02P'}, {vendor: 'TuYa
|
|
253
|
+
whiteLabel: [{vendor: 'Mercator Ikuü', model: 'SMA02P'}, {vendor: 'TuYa', model: 'TY-ZPR06'}],
|
|
254
254
|
fromZigbee: [fz.ias_occupancy_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_occupancy_alarm_1_report],
|
|
255
255
|
toZigbee: [],
|
|
256
256
|
exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery()],
|
|
@@ -882,6 +882,7 @@ module.exports = [
|
|
|
882
882
|
{modelID: 'TS0601', manufacturerName: '_TZE200_5sbebbzs'},
|
|
883
883
|
{modelID: 'TS0601', manufacturerName: '_TZE200_zuz7f94z'},
|
|
884
884
|
{modelID: 'TS0601', manufacturerName: '_TZE200_zyrdrmno'},
|
|
885
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_68nvbio9'},
|
|
885
886
|
],
|
|
886
887
|
model: 'TS0601_cover',
|
|
887
888
|
vendor: 'TuYa',
|
package/devices/xiaomi.js
CHANGED
|
@@ -1174,8 +1174,8 @@ module.exports = [
|
|
|
1174
1174
|
exposes.enum('mute_buzzer', ea.SET, ['Mute']).withDescription('Mute the buzzer for 10 minutes (buzzer cannot be ' +
|
|
1175
1175
|
'pre-muted, because this function only works when the alarm is triggered)'),
|
|
1176
1176
|
exposes.binary('mute', ea.STATE_GET, true, false).withDescription('Buzzer muted'),
|
|
1177
|
-
exposes.
|
|
1178
|
-
'
|
|
1177
|
+
exposes.binary('linkage_alarm', ea.ALL, true, false).withDescription('When this option is enabled and a gas leak ' +
|
|
1178
|
+
'is detected, other detectors with this option enabled will also sound the alarm buzzer'),
|
|
1179
1179
|
exposes.binary('state', ea.STATE_GET, 'preparation', 'work').withDescription('"Preparation" or "work" ' +
|
|
1180
1180
|
'(measurement of the gas concentration value and triggering of an alarm are only performed in the "work" state)'),
|
|
1181
1181
|
exposes.numeric('power_outage_count', ea.STATE_GET).withDescription('Number of power outages (since last pairing)')],
|
|
@@ -1272,9 +1272,9 @@ module.exports = [
|
|
|
1272
1272
|
vendor: 'Xiaomi',
|
|
1273
1273
|
fromZigbee: [fz.xiaomi_curtain_acn002_position, fz.xiaomi_curtain_acn002_status, fz.cover_position_tilt, fz.ignore_basic_report,
|
|
1274
1274
|
fz.aqara_opple],
|
|
1275
|
-
toZigbee: [tz.xiaomi_curtain_position_state
|
|
1275
|
+
toZigbee: [tz.xiaomi_curtain_position_state],
|
|
1276
1276
|
exposes: [e.cover_position().setAccess('state', ea.ALL), e.battery(),
|
|
1277
|
-
exposes.enum('motor_state', ea.
|
|
1277
|
+
exposes.enum('motor_state', ea.STATE, ['declining', 'rising', 'pause', 'blocked'])
|
|
1278
1278
|
.withDescription('The current state of the motor.'),
|
|
1279
1279
|
exposes.binary('running', ea.STATE, true, false)
|
|
1280
1280
|
.withDescription('Whether the motor is moving or not.')],
|
|
@@ -1289,7 +1289,7 @@ module.exports = [
|
|
|
1289
1289
|
model: 'LLKZMK11LM',
|
|
1290
1290
|
vendor: 'Xiaomi',
|
|
1291
1291
|
description: 'Aqara wireless relay controller',
|
|
1292
|
-
fromZigbee: [fz.xiaomi_switch_basic, fz.xiaomi_power, fz.ignore_multistate_report, fz.on_off],
|
|
1292
|
+
fromZigbee: [fz.xiaomi_switch_basic, fz.xiaomi_power, fz.ignore_multistate_report, fz.on_off, fz.aqara_opple],
|
|
1293
1293
|
meta: {multiEndpoint: true},
|
|
1294
1294
|
toZigbee: [tz.on_off, tz.LLKZMK11LM_interlock, tz.xiaomi_power],
|
|
1295
1295
|
endpoint: (device) => {
|
|
@@ -1299,7 +1299,7 @@ module.exports = [
|
|
|
1299
1299
|
e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'),
|
|
1300
1300
|
exposes.binary('interlock', ea.STATE_SET, true, false)
|
|
1301
1301
|
.withDescription('Enabling prevents both relais being on at the same time')],
|
|
1302
|
-
|
|
1302
|
+
ota: ota.zigbeeOTA,
|
|
1303
1303
|
},
|
|
1304
1304
|
{
|
|
1305
1305
|
zigbeeModel: ['lumi.lock.acn02'],
|
|
@@ -1597,7 +1597,8 @@ module.exports = [
|
|
|
1597
1597
|
e.battery(), e.battery_voltage(), e.action([
|
|
1598
1598
|
'single_left', 'single_right', 'single_both',
|
|
1599
1599
|
'double_left', 'double_right', 'double_both',
|
|
1600
|
-
'triple_left', 'triple_right', 'triple_both'
|
|
1600
|
+
'triple_left', 'triple_right', 'triple_both',
|
|
1601
|
+
'hold_left', 'hold_right', 'hold_both']),
|
|
1601
1602
|
exposes.enum('click_mode', ea.ALL, ['fast', 'multi'])
|
|
1602
1603
|
.withDescription('Click mode, fast: only supports single click which will be send immediately after clicking.' +
|
|
1603
1604
|
'multi: supports more events like double and hold'),
|
package/devices/yale.js
CHANGED
|
@@ -124,4 +124,11 @@ module.exports = [
|
|
|
124
124
|
description: 'Real living lock / Intelligent biometric digital lock',
|
|
125
125
|
extend: lockExtend(),
|
|
126
126
|
},
|
|
127
|
+
{
|
|
128
|
+
zigbeeModel: ['06ffff2027'],
|
|
129
|
+
model: 'YMF40A RL',
|
|
130
|
+
vendor: 'Yale',
|
|
131
|
+
description: 'Real living lock / Intelligent biometric digital lock',
|
|
132
|
+
extend: lockExtend({battery: {dontDividePercentage: true}}),
|
|
133
|
+
},
|
|
127
134
|
];
|
package/index.js
CHANGED
|
@@ -62,7 +62,7 @@ function addDefinition(definition) {
|
|
|
62
62
|
const {extend, ...definitionWithoutExtend} = definition;
|
|
63
63
|
if (extend) {
|
|
64
64
|
if (extend.hasOwnProperty('configure') && definition.hasOwnProperty('configure')) {
|
|
65
|
-
|
|
65
|
+
assert.fail(`'${definition.model}' has configure in extend and device, this is not allowed`);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
definition = {
|
|
@@ -89,7 +89,8 @@ function addDefinition(definition) {
|
|
|
89
89
|
const optionKeys = definition.options.map((o) => o.name);
|
|
90
90
|
for (const converter of [...definition.toZigbee, ...definition.fromZigbee]) {
|
|
91
91
|
if (converter.options) {
|
|
92
|
-
|
|
92
|
+
const options = typeof converter.options === 'function' ? converter.options(definition) : converter.options;
|
|
93
|
+
for (const option of options) {
|
|
93
94
|
if (!optionKeys.includes(option.name)) {
|
|
94
95
|
definition.options.push(option);
|
|
95
96
|
optionKeys.push(option.name);
|
package/lib/extend.js
CHANGED
|
@@ -58,12 +58,14 @@ const extend = {
|
|
|
58
58
|
tz.light_brightness_step, tz.level_config, tz.power_on_behavior, tz.light_hue_saturation_move,
|
|
59
59
|
tz.light_hue_saturation_step, tz.light_color_options, tz.light_color_mode, ...(!options.disableEffect ? [tz.effect] : [])];
|
|
60
60
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
configure
|
|
61
|
+
const result = {exposes, fromZigbee, toZigbee};
|
|
62
|
+
if (!options.noConfigure) {
|
|
63
|
+
result.configure = async (device, coordinatorEndpoint, logger) => {
|
|
64
64
|
await light.configure(device, coordinatorEndpoint, logger, false);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return result;
|
|
67
69
|
},
|
|
68
70
|
light_onoff_brightness_colortemp_color: (options={}) => {
|
|
69
71
|
options = {disableEffect: false, supportsHS: false, disableColorTempStartup: false, preferHS: false, ...options};
|
package/lib/ota/index.js
CHANGED
package/lib/ota/lixee.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const firmwareOrigin = 'https://api.github.com/repos/fairecasoimeme/Zlinky_TIC/releases';
|
|
2
|
+
const assert = require('assert');
|
|
3
|
+
const common = require('./common');
|
|
4
|
+
const axios = common.getAxios();
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Helper functions
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
async function getImageMeta(current, logger, device) {
|
|
11
|
+
const manufacturerCode = current.manufacturerCode;
|
|
12
|
+
const imageType = current.imageType;
|
|
13
|
+
const releasesLIST = (await axios.get(firmwareOrigin)).data;
|
|
14
|
+
|
|
15
|
+
let firmURL;
|
|
16
|
+
|
|
17
|
+
// Find the most recent OTA file available
|
|
18
|
+
for (const e of releasesLIST.sort((a, b) => a.published_at - a.published_at)) {
|
|
19
|
+
if (e.assets) {
|
|
20
|
+
const targetObj = e.assets
|
|
21
|
+
.find((a) => a.name.endsWith('.ota'));
|
|
22
|
+
if (targetObj && targetObj.browser_download_url) {
|
|
23
|
+
firmURL = targetObj;
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
assert(firmURL,
|
|
30
|
+
`No image available for manufacturerCode '${manufacturerCode}' imageType '${imageType} on Github repo'`);
|
|
31
|
+
|
|
32
|
+
logger.info(`Using firmware file ` + firmURL.name);
|
|
33
|
+
const image = common.parseImage((await common.getAxios().get(firmURL.browser_download_url, {responseType: 'arraybuffer'})).data);
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
fileVersion: image.header.fileVersion,
|
|
37
|
+
fileSize: firmURL.size,
|
|
38
|
+
url: firmURL.browser_download_url,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Interface implementation
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
async function isUpdateAvailable(device, logger, requestPayload=null) {
|
|
47
|
+
return common.isUpdateAvailable(device, logger, common.isNewImageAvailable, requestPayload, getImageMeta);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function updateToLatest(device, logger, onProgress) {
|
|
51
|
+
return common.updateToLatest(device, logger, onProgress, common.getNewImage, getImageMeta);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = {
|
|
55
|
+
isUpdateAvailable,
|
|
56
|
+
updateToLatest,
|
|
57
|
+
};
|
package/lib/tuya.js
CHANGED
|
@@ -578,6 +578,9 @@ const dataPoints = {
|
|
|
578
578
|
garageDoorTrigger: 1,
|
|
579
579
|
garageDoorContact: 3,
|
|
580
580
|
garageDoorStatus: 12,
|
|
581
|
+
// Moes switch with optional neutral
|
|
582
|
+
moesSwitchPowerOnBehavior: 14,
|
|
583
|
+
moesSwitchIndicateLight: 15,
|
|
581
584
|
};
|
|
582
585
|
|
|
583
586
|
const thermostatWeekFormat = {
|
|
@@ -731,6 +734,19 @@ const ZMAM02 = {
|
|
|
731
734
|
},
|
|
732
735
|
};
|
|
733
736
|
|
|
737
|
+
const moesSwitch = {
|
|
738
|
+
powerOnBehavior: {
|
|
739
|
+
0: 'off',
|
|
740
|
+
1: 'on',
|
|
741
|
+
2: 'previous',
|
|
742
|
+
},
|
|
743
|
+
indicateLight: {
|
|
744
|
+
0: 'off',
|
|
745
|
+
1: 'switch',
|
|
746
|
+
2: 'position',
|
|
747
|
+
},
|
|
748
|
+
};
|
|
749
|
+
|
|
734
750
|
// Return `seq` - transaction ID for handling concrete response
|
|
735
751
|
async function sendDataPoints(entity, dpValues, cmd, seq=undefined) {
|
|
736
752
|
if (seq === undefined) {
|
|
@@ -881,4 +897,5 @@ module.exports = {
|
|
|
881
897
|
tvThermostatPreset,
|
|
882
898
|
tuyaRadar,
|
|
883
899
|
ZMAM02,
|
|
900
|
+
moesSwitch,
|
|
884
901
|
};
|
package/npm-shrinkwrap.json
CHANGED