zigbee-herdsman-converters 15.0.5 → 15.0.7
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 +48 -32
- package/devices/bosch.js +223 -0
- package/devices/centralite.js +2 -2
- package/devices/custom_devices_diy.js +16 -16
- package/devices/diyruz.js +6 -6
- package/devices/ecozy.js +1 -1
- package/devices/leviton.js +1 -1
- package/devices/lidl.js +0 -6
- package/devices/lux.js +1 -1
- package/devices/{mecrator.js → mercator.js} +0 -0
- package/devices/neo.js +1 -1
- package/devices/philips.js +8 -1
- package/devices/sinope.js +118 -108
- package/devices/tuya.js +11 -7
- package/devices/vimar.js +4 -2
- package/devices/yale.js +6 -6
- package/devices/zen.js +1 -1
- package/index.js +1 -1
- package/lib/legacy.js +0 -32
- package/lib/tuya.js +0 -1
- package/package.json +2 -2
package/converters/fromZigbee.js
CHANGED
|
@@ -2304,43 +2304,59 @@ const converters = {
|
|
|
2304
2304
|
// Protocol description
|
|
2305
2305
|
// https://github.com/Koenkk/zigbee-herdsman-converters/issues/1159#issuecomment-614659802
|
|
2306
2306
|
|
|
2307
|
-
const
|
|
2308
|
-
const dp = dpValue.dp;
|
|
2309
|
-
const value = tuya.getDataValue(dpValue);
|
|
2307
|
+
const result = {};
|
|
2310
2308
|
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
const
|
|
2315
|
-
const
|
|
2316
|
-
const running = dp !== tuya.dataPoints.coverArrived;
|
|
2309
|
+
// Iterate through dpValues in case of some zigbee models returning multiple dp values in one message
|
|
2310
|
+
// For example: [TS0601, _TZE200_3ylew7b4]
|
|
2311
|
+
for (const dpValue of msg.data.dpValues) {
|
|
2312
|
+
const dp = dpValue.dp;
|
|
2313
|
+
const value = tuya.getDataValue(dpValue);
|
|
2317
2314
|
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
const
|
|
2322
|
-
|
|
2323
|
-
|
|
2315
|
+
switch (dp) {
|
|
2316
|
+
case tuya.dataPoints.coverPosition: // Started moving to position (triggered from Zigbee)
|
|
2317
|
+
case tuya.dataPoints.coverArrived: { // Arrived at position
|
|
2318
|
+
const invert = tuya.isCoverInverted(meta.device.manufacturerName) ? !options.invert_cover : options.invert_cover;
|
|
2319
|
+
const position = invert ? 100 - (value & 0xff) : value & 0xff;
|
|
2320
|
+
const running = dp !== tuya.dataPoints.coverArrived;
|
|
2321
|
+
|
|
2322
|
+
// Not all covers report coverArrived, so set running to false if device doesn't report position
|
|
2323
|
+
// for a few seconds
|
|
2324
|
+
clearTimeout(globalStore.getValue(msg.endpoint, 'running_timer'));
|
|
2325
|
+
if (running) {
|
|
2326
|
+
const timer = setTimeout(() => publish({running: false}), 3 * 1000);
|
|
2327
|
+
globalStore.putValue(msg.endpoint, 'running_timer', timer);
|
|
2328
|
+
}
|
|
2324
2329
|
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2330
|
+
if (position > 0 && position <= 100) {
|
|
2331
|
+
result.running = running;
|
|
2332
|
+
result.position = position;
|
|
2333
|
+
result.state = 'OPEN';
|
|
2334
|
+
} else if (position == 0) {
|
|
2335
|
+
// Report fully closed
|
|
2336
|
+
result.running = running;
|
|
2337
|
+
result.position = position;
|
|
2338
|
+
result.state = 'CLOSE';
|
|
2339
|
+
} else {
|
|
2340
|
+
result.running = running; // Not calibrated yet, no position is available
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2343
|
+
break;
|
|
2344
|
+
case tuya.dataPoints.coverSpeed: // Cover is reporting its current speed setting
|
|
2345
|
+
result.motor_speed = value;
|
|
2346
|
+
break;
|
|
2347
|
+
case tuya.dataPoints.state: // Ignore the cover state, it's not reliable between different covers!
|
|
2348
|
+
break;
|
|
2349
|
+
case tuya.dataPoints.coverChange: // Ignore manual cover change, it's not reliable between different covers!
|
|
2350
|
+
break;
|
|
2351
|
+
case tuya.dataPoints.config: // Returned by configuration set; ignore
|
|
2352
|
+
break;
|
|
2353
|
+
default: // Unknown code
|
|
2354
|
+
meta.logger.warn(`TuYa_cover_control: Unhandled DP #${dp} for ${meta.device.manufacturerName}:
|
|
2355
|
+
${JSON.stringify(dpValue)}`);
|
|
2331
2356
|
}
|
|
2332
2357
|
}
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
case tuya.dataPoints.state: // Ignore the cover state, it's not reliable between different covers!
|
|
2336
|
-
case tuya.dataPoints.coverChange: // Ignore manual cover change, it's not reliable between different covers!
|
|
2337
|
-
break;
|
|
2338
|
-
case tuya.dataPoints.config: // Returned by configuration set; ignore
|
|
2339
|
-
break;
|
|
2340
|
-
default: // Unknown code
|
|
2341
|
-
meta.logger.warn(`TuYa_cover_control: Unhandled DP #${dp} for ${meta.device.manufacturerName}:
|
|
2342
|
-
${JSON.stringify(dpValue)}`);
|
|
2343
|
-
}
|
|
2358
|
+
|
|
2359
|
+
return result;
|
|
2344
2360
|
},
|
|
2345
2361
|
},
|
|
2346
2362
|
wiser_device_info: {
|
package/devices/bosch.js
CHANGED
|
@@ -11,6 +11,21 @@ const ea = exposes.access;
|
|
|
11
11
|
// Radiator Thermostat II
|
|
12
12
|
const boschManufacturer = {manufacturerCode: 0x1209};
|
|
13
13
|
|
|
14
|
+
// Twinguard
|
|
15
|
+
const smokeSensitivity = {
|
|
16
|
+
'low': 3,
|
|
17
|
+
'medium': 2,
|
|
18
|
+
'high': 1,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
// Twinguard
|
|
22
|
+
const sirenState = {
|
|
23
|
+
'stop': 0,
|
|
24
|
+
'pre_alarm': 1,
|
|
25
|
+
'fire': 2,
|
|
26
|
+
'burglar': 3,
|
|
27
|
+
};
|
|
28
|
+
|
|
14
29
|
// Radiator Thermostat II
|
|
15
30
|
const operatingModes = {
|
|
16
31
|
'automatic': 0,
|
|
@@ -122,6 +137,67 @@ const tzLocal = {
|
|
|
122
137
|
}
|
|
123
138
|
},
|
|
124
139
|
},
|
|
140
|
+
bosch_twinguard: {
|
|
141
|
+
key: ['sensitivity', 'pre_alarm', 'self_test', 'alarm', 'heartbeat'],
|
|
142
|
+
convertSet: async (entity, key, value, meta) => {
|
|
143
|
+
if (key === 'sensitivity') {
|
|
144
|
+
value = value.toUpperCase();
|
|
145
|
+
const index = smokeSensitivity[value];
|
|
146
|
+
await entity.write('manuSpecificBosch', {0x4003: {value: index, type: 0x21}}, boschManufacturer);
|
|
147
|
+
return {state: {sensitivity: value}};
|
|
148
|
+
}
|
|
149
|
+
if (key === 'pre_alarm') {
|
|
150
|
+
value = value.toUpperCase();
|
|
151
|
+
const index = stateOffOn[value];
|
|
152
|
+
await entity.write('manuSpecificBosch5', {0x4001: {value: index, type: 0x18}}, boschManufacturer);
|
|
153
|
+
return {state: {pre_alarm: value}};
|
|
154
|
+
}
|
|
155
|
+
if (key === 'heartbeat') {
|
|
156
|
+
const endpoint = meta.device.getEndpoint(12);
|
|
157
|
+
value = value.toUpperCase();
|
|
158
|
+
const index = stateOffOn[value];
|
|
159
|
+
await endpoint.write('manuSpecificBosch7', {0x5005: {value: index, type: 0x18}}, boschManufacturer);
|
|
160
|
+
return {state: {heartbeat: value}};
|
|
161
|
+
}
|
|
162
|
+
if (key === 'self_test') {
|
|
163
|
+
if (value) {
|
|
164
|
+
await entity.command('manuSpecificBosch', 'initiateTestMode', boschManufacturer);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (key === 'alarm') {
|
|
168
|
+
const endpoint = meta.device.getEndpoint(12);
|
|
169
|
+
const index = sirenState[value];
|
|
170
|
+
if (index == 0) {
|
|
171
|
+
await entity.commandResponse('genAlarms', 'alarm', {alarmcode: 0x16, clusterid: 0xe000}, {direction: 1});
|
|
172
|
+
await entity.commandResponse('genAlarms', 'alarm', {alarmcode: 0x14, clusterid: 0xe000}, {direction: 1});
|
|
173
|
+
await endpoint.command('manuSpecificBosch8', 'burglarAlarm', {data: 0}, boschManufacturer);
|
|
174
|
+
} else if (index == 1) {
|
|
175
|
+
await entity.commandResponse('genAlarms', 'alarm', {alarmcode: 0x11, clusterid: 0xe000}, {direction: 1});
|
|
176
|
+
return {state: {siren_state: 'pre-alarm'}};
|
|
177
|
+
} else if (index == 2) {
|
|
178
|
+
await entity.commandResponse('genAlarms', 'alarm', {alarmcode: 0x10, clusterid: 0xe000}, {direction: 1});
|
|
179
|
+
return {state: {siren_state: 'fire'}};
|
|
180
|
+
} else if (index == 3) {
|
|
181
|
+
await endpoint.command('manuSpecificBosch8', 'burglarAlarm', {data: 1}, boschManufacturer);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
},
|
|
185
|
+
convertGet: async (entity, key, meta) => {
|
|
186
|
+
switch (key) {
|
|
187
|
+
case 'sensitivity':
|
|
188
|
+
await entity.read('manuSpecificBosch', [0x4003], boschManufacturer);
|
|
189
|
+
break;
|
|
190
|
+
case 'pre_alarm':
|
|
191
|
+
await entity.read('manuSpecificBosch5', [0x4001], boschManufacturer);
|
|
192
|
+
break;
|
|
193
|
+
case 'heartbeat':
|
|
194
|
+
await meta.device.getEndpoint(12).read('manuSpecificBosch7', [0x5005], boschManufacturer);
|
|
195
|
+
break;
|
|
196
|
+
default: // Unknown key
|
|
197
|
+
throw new Error(`Unhandled key toZigbee.bosch_twinguard.convertGet ${key}`);
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
},
|
|
125
201
|
};
|
|
126
202
|
|
|
127
203
|
|
|
@@ -172,6 +248,112 @@ const fzLocal = {
|
|
|
172
248
|
return result;
|
|
173
249
|
},
|
|
174
250
|
},
|
|
251
|
+
bosch_twinguard_sensitivity: {
|
|
252
|
+
cluster: 'manuSpecificBosch',
|
|
253
|
+
type: ['attributeReport', 'readResponse'],
|
|
254
|
+
options: [],
|
|
255
|
+
convert: (model, msg, publish, options, meta) => {
|
|
256
|
+
const result = {};
|
|
257
|
+
if (msg.data.hasOwnProperty(0x4003)) {
|
|
258
|
+
result.sensitivity = (Object.keys(smokeSensitivity)[msg.data[0x4003]]);
|
|
259
|
+
}
|
|
260
|
+
return result;
|
|
261
|
+
},
|
|
262
|
+
},
|
|
263
|
+
bosch_twinguard_measurements: {
|
|
264
|
+
cluster: 'manuSpecificBosch3',
|
|
265
|
+
type: ['attributeReport', 'readResponse'],
|
|
266
|
+
options: [exposes.options.precision('temperature'), exposes.options.calibration('temperature'),
|
|
267
|
+
exposes.options.precision('humidity'), exposes.options.calibration('humidity'),
|
|
268
|
+
exposes.options.calibration('illuminance_lux', 'percentual')],
|
|
269
|
+
convert: (model, msg, publish, options, meta) => {
|
|
270
|
+
const result = {};
|
|
271
|
+
if (msg.data.hasOwnProperty('humidity')) {
|
|
272
|
+
result.humidity = utils.calibrateAndPrecisionRoundOptions(msg.data['humidity'] / 100.0, options, 'humidity');
|
|
273
|
+
}
|
|
274
|
+
if (msg.data.hasOwnProperty('airpurity')) {
|
|
275
|
+
result.co2 = msg.data['airpurity'] * 10.0 + 500.0;
|
|
276
|
+
}
|
|
277
|
+
if (msg.data.hasOwnProperty('temperature')) {
|
|
278
|
+
result.temperature = utils.calibrateAndPrecisionRoundOptions(msg.data['temperature'] / 100.0, options, 'temperature');
|
|
279
|
+
}
|
|
280
|
+
if (msg.data.hasOwnProperty('illuminance_lux')) {
|
|
281
|
+
result.illuminance_lux = utils.calibrateAndPrecisionRoundOptions(
|
|
282
|
+
msg.data['illuminance_lux'] / 2.0, options, 'illuminance_lux');
|
|
283
|
+
}
|
|
284
|
+
if (msg.data.hasOwnProperty('battery')) {
|
|
285
|
+
result.battery = msg.data['battery'] / 2.0;
|
|
286
|
+
}
|
|
287
|
+
return result;
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
bosch_twinguard_pre_alarm: {
|
|
291
|
+
cluster: 'manuSpecificBosch5',
|
|
292
|
+
type: ['attributeReport', 'readResponse'],
|
|
293
|
+
options: [],
|
|
294
|
+
convert: (model, msg, publish, options, meta) => {
|
|
295
|
+
const result = {};
|
|
296
|
+
if (msg.data.hasOwnProperty('pre_alarm')) {
|
|
297
|
+
result.pre_alarm = (Object.keys(stateOffOn)[msg.data['pre_alarm']]);
|
|
298
|
+
}
|
|
299
|
+
return result;
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
bosch_twinguard_heartbeat: {
|
|
303
|
+
cluster: 'manuSpecificBosch7',
|
|
304
|
+
type: ['attributeReport', 'readResponse'],
|
|
305
|
+
options: [],
|
|
306
|
+
convert: (model, msg, publish, options, meta) => {
|
|
307
|
+
const result = {};
|
|
308
|
+
if (msg.data.hasOwnProperty('heartbeat')) {
|
|
309
|
+
result.heartbeat = (Object.keys(stateOffOn)[msg.data['heartbeat']]);
|
|
310
|
+
}
|
|
311
|
+
return result;
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
bosch_twinguard_alarm_state: {
|
|
315
|
+
cluster: 'manuSpecificBosch8',
|
|
316
|
+
type: ['attributeReport', 'readResponse'],
|
|
317
|
+
options: [],
|
|
318
|
+
convert: (model, msg, publish, options, meta) => {
|
|
319
|
+
const result = {};
|
|
320
|
+
const lookup = {
|
|
321
|
+
0x00200020: 'clear',
|
|
322
|
+
0x01200020: 'self_test',
|
|
323
|
+
0x02200020: 'burglar',
|
|
324
|
+
0x00200082: 'pre-alarm',
|
|
325
|
+
0x00200081: 'fire',
|
|
326
|
+
0x00200040: 'silenced',
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
if (msg.data.hasOwnProperty('alarm_status')) {
|
|
330
|
+
result.self_test = (msg.data['alarm_status'] & 1<<24) > 0;
|
|
331
|
+
result.smoke = (msg.data['alarm_status'] & 1<<7) > 0;
|
|
332
|
+
result.siren_state = lookup[msg.data['alarm_status']];
|
|
333
|
+
}
|
|
334
|
+
return result;
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
bosch_twinguard_smoke_alarm_state: {
|
|
338
|
+
cluster: 'genAlarms',
|
|
339
|
+
type: ['commandAlarm', 'readResponse'],
|
|
340
|
+
options: [],
|
|
341
|
+
convert: async (model, msg, publish, options, meta) => {
|
|
342
|
+
const result = {};
|
|
343
|
+
const lookup = {
|
|
344
|
+
0x10: 'fire',
|
|
345
|
+
0x11: 'pre-alarm',
|
|
346
|
+
0x14: 'clear',
|
|
347
|
+
0x16: 'silenced',
|
|
348
|
+
};
|
|
349
|
+
result.siren_state = lookup[msg.data.alarmcode];
|
|
350
|
+
if (msg.data.alarmcode == 0x10 || msg.data.alarmcode == 0x11) {
|
|
351
|
+
await msg.endpoint.commandResponse('genAlarms', 'alarm',
|
|
352
|
+
{alarmcode: msg.data.alarmcode, clusterid: 0xe000}, {direction: 1});
|
|
353
|
+
}
|
|
354
|
+
return result;
|
|
355
|
+
},
|
|
356
|
+
},
|
|
175
357
|
};
|
|
176
358
|
|
|
177
359
|
const definition = [
|
|
@@ -283,6 +465,47 @@ const definition = [
|
|
|
283
465
|
await endpoint.read('hvacUserInterfaceCfg', [0x400b, 0x403a, 0x403b], boschManufacturer);
|
|
284
466
|
},
|
|
285
467
|
},
|
|
468
|
+
{
|
|
469
|
+
zigbeeModel: ['Champion'],
|
|
470
|
+
model: '8750001213',
|
|
471
|
+
vendor: 'Bosch',
|
|
472
|
+
description: 'Twinguard',
|
|
473
|
+
fromZigbee: [fzLocal.bosch_twinguard_measurements, fzLocal.bosch_twinguard_sensitivity,
|
|
474
|
+
fzLocal.bosch_twinguard_pre_alarm, fzLocal.bosch_twinguard_alarm_state, fzLocal.bosch_twinguard_smoke_alarm_state,
|
|
475
|
+
fzLocal.bosch_twinguard_heartbeat],
|
|
476
|
+
toZigbee: [tzLocal.bosch_twinguard],
|
|
477
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
478
|
+
const coordinatorEndpointB = coordinatorEndpoint.getDevice().getEndpoint(1);
|
|
479
|
+
await reporting.bind(device.getEndpoint(1), coordinatorEndpointB, [0x0009]);
|
|
480
|
+
await reporting.bind(device.getEndpoint(7), coordinatorEndpointB, [0x0019]);
|
|
481
|
+
await reporting.bind(device.getEndpoint(7), coordinatorEndpointB, [0x0020]);
|
|
482
|
+
await reporting.bind(device.getEndpoint(1), coordinatorEndpointB, [0xe000]);
|
|
483
|
+
await reporting.bind(device.getEndpoint(3), coordinatorEndpointB, [0xe002]);
|
|
484
|
+
await reporting.bind(device.getEndpoint(1), coordinatorEndpointB, [0xe004]);
|
|
485
|
+
await reporting.bind(device.getEndpoint(12), coordinatorEndpointB, [0xe006]);
|
|
486
|
+
await reporting.bind(device.getEndpoint(12), coordinatorEndpointB, [0xe007]);
|
|
487
|
+
await device.getEndpoint(1).read('manuSpecificBosch5', ['unknown_attribute'], boschManufacturer); // Needed for pairing
|
|
488
|
+
await device.getEndpoint(12).command('manuSpecificBosch7', 'pairingCompleted', boschManufacturer); // Needed for pairing
|
|
489
|
+
await device.getEndpoint(1).write('manuSpecificBosch',
|
|
490
|
+
{0x4003: {value: 0x0002, type: 0x21}}, boschManufacturer); // Setting defaults
|
|
491
|
+
await device.getEndpoint(1).write('manuSpecificBosch5',
|
|
492
|
+
{0x4001: {value: 0x01, type: 0x18}}, boschManufacturer); // Setting defaults
|
|
493
|
+
await device.getEndpoint(12).write('manuSpecificBosch7',
|
|
494
|
+
{0x5005: {value: 0x01, type: 0x18}}, boschManufacturer); // Setting defaults
|
|
495
|
+
await device.getEndpoint(1).read('manuSpecificBosch', ['sensitivity'], boschManufacturer);
|
|
496
|
+
await device.getEndpoint(1).read('manuSpecificBosch5', ['pre_alarm'], boschManufacturer);
|
|
497
|
+
await device.getEndpoint(12).read('manuSpecificBosch7', ['heartbeat'], boschManufacturer);
|
|
498
|
+
},
|
|
499
|
+
exposes: [
|
|
500
|
+
e.smoke(), e.temperature(), e.humidity(), e.co2(), e.illuminance_lux(), e.battery(),
|
|
501
|
+
exposes.enum('alarm', ea.ALL, Object.keys(sirenState)).withDescription('Mode of the alarm (sound effect)'),
|
|
502
|
+
exposes.text('siren_state', ea.STATE).withDescription('Siren state'),
|
|
503
|
+
exposes.binary('self_test', ea.ALL, true, false).withDescription('Initiate self-test'),
|
|
504
|
+
exposes.enum('sensitivity', ea.ALL, Object.keys(smokeSensitivity)).withDescription('Sensitivity of the smoke alarm'),
|
|
505
|
+
exposes.enum('pre_alarm', ea.ALL, Object.keys(stateOffOn)).withDescription('Enable/disable pre-alarm'),
|
|
506
|
+
exposes.enum('heartbeat', ea.ALL, Object.keys(stateOffOn)).withDescription('Enable/disable heartbeat'),
|
|
507
|
+
],
|
|
508
|
+
},
|
|
286
509
|
];
|
|
287
510
|
|
|
288
511
|
module.exports = definition;
|
package/devices/centralite.js
CHANGED
|
@@ -212,7 +212,7 @@ module.exports = [
|
|
|
212
212
|
vendor: 'Centralite',
|
|
213
213
|
description: '3-Series pearl touch thermostat',
|
|
214
214
|
fromZigbee: [fz.battery, fz.thermostat, fz.fan, fz.ignore_time_read],
|
|
215
|
-
toZigbee: [tz.
|
|
215
|
+
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_local_temperature_calibration,
|
|
216
216
|
tz.thermostat_occupied_heating_setpoint, tz.thermostat_occupied_cooling_setpoint,
|
|
217
217
|
tz.thermostat_setpoint_raise_lower, tz.thermostat_remote_sensing,
|
|
218
218
|
tz.thermostat_control_sequence_of_operation, tz.thermostat_system_mode,
|
|
@@ -242,7 +242,7 @@ module.exports = [
|
|
|
242
242
|
vendor: 'Centralite',
|
|
243
243
|
description: 'HA thermostat',
|
|
244
244
|
fromZigbee: [fz.battery, fzLocal.thermostat_3156105, fz.fan, fz.ignore_time_read],
|
|
245
|
-
toZigbee: [tz.
|
|
245
|
+
toZigbee: [tz.thermostat_local_temperature,
|
|
246
246
|
tz.thermostat_occupied_heating_setpoint, tz.thermostat_occupied_cooling_setpoint,
|
|
247
247
|
tz.thermostat_setpoint_raise_lower, tz.thermostat_remote_sensing,
|
|
248
248
|
tz.thermostat_control_sequence_of_operation, tz.thermostat_system_mode,
|
|
@@ -437,7 +437,7 @@ module.exports = [
|
|
|
437
437
|
vendor: 'Custom devices (DiY)',
|
|
438
438
|
description: 'Flower sensor with rechargeable battery',
|
|
439
439
|
fromZigbee: [fz.temperature, fz.illuminance, fz.soil_moisture, fz.battery],
|
|
440
|
-
toZigbee: [
|
|
440
|
+
toZigbee: [],
|
|
441
441
|
meta: {multiEndpoint: true},
|
|
442
442
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
443
443
|
const firstEndpoint = device.getEndpoint(1);
|
|
@@ -458,7 +458,7 @@ module.exports = [
|
|
|
458
458
|
vendor: 'Custom devices (DiY)',
|
|
459
459
|
description: '[Plant Wattering Sensor, CR2450, CR2477 batteries, temperature ]',
|
|
460
460
|
fromZigbee: [fz.temperature, fz.humidity, fz.illuminance, fz.soil_moisture, fz.battery, fzLocal.node_config],
|
|
461
|
-
toZigbee: [
|
|
461
|
+
toZigbee: [tzLocal.node_config],
|
|
462
462
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
463
463
|
const firstEndpoint = device.getEndpoint(1);
|
|
464
464
|
await reporting.bind(firstEndpoint, coordinatorEndpoint, [
|
|
@@ -482,7 +482,7 @@ module.exports = [
|
|
|
482
482
|
vendor: 'Custom devices (DiY)',
|
|
483
483
|
description: 'DIY outdoor long-range sensor for temperature, humidity and atmospheric pressure',
|
|
484
484
|
fromZigbee: [fz.temperature, fz.humidity, fz.pressure, fz.battery],
|
|
485
|
-
toZigbee: [
|
|
485
|
+
toZigbee: [],
|
|
486
486
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
487
487
|
const endpoint = device.getEndpoint(1);
|
|
488
488
|
await reporting.bind(endpoint, coordinatorEndpoint, [
|
|
@@ -503,7 +503,7 @@ module.exports = [
|
|
|
503
503
|
vendor: 'Custom devices (DiY)',
|
|
504
504
|
description: '[Plant wattering sensor with e-ink display](https://efektalab.com/epws102)',
|
|
505
505
|
fromZigbee: [fz.temperature, fz.soil_moisture, fz.battery],
|
|
506
|
-
toZigbee: [
|
|
506
|
+
toZigbee: [],
|
|
507
507
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
508
508
|
const firstEndpoint = device.getEndpoint(1);
|
|
509
509
|
await reporting.bind(firstEndpoint, coordinatorEndpoint, ['genPowerCfg', 'msTemperatureMeasurement', 'msSoilMoisture']);
|
|
@@ -521,7 +521,7 @@ module.exports = [
|
|
|
521
521
|
vendor: 'Custom devices (DiY)',
|
|
522
522
|
description: '[Temperature and humidity sensor with e-ink2.13](http://efektalab.com/eON213z)',
|
|
523
523
|
fromZigbee: [fz.temperature, fz.humidity, fz.battery],
|
|
524
|
-
toZigbee: [
|
|
524
|
+
toZigbee: [],
|
|
525
525
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
526
526
|
const endpoint = device.getEndpoint(1);
|
|
527
527
|
await reporting.bind(endpoint, coordinatorEndpoint, [
|
|
@@ -540,7 +540,7 @@ module.exports = [
|
|
|
540
540
|
vendor: 'Custom devices (DiY)',
|
|
541
541
|
description: '[Mini plant wattering sensor](http://efektalab.com/miniPWS)',
|
|
542
542
|
fromZigbee: [fz.soil_moisture, fz.battery, fzLocal.node_config],
|
|
543
|
-
toZigbee: [
|
|
543
|
+
toZigbee: [tzLocal.node_config],
|
|
544
544
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
545
545
|
const firstEndpoint = device.getEndpoint(1);
|
|
546
546
|
await reporting.bind(firstEndpoint, coordinatorEndpoint, ['genPowerCfg', 'msSoilMoisture']);
|
|
@@ -555,7 +555,7 @@ module.exports = [
|
|
|
555
555
|
vendor: 'Custom devices (DiY)',
|
|
556
556
|
description: '[Mini weather station, digital barometer, forecast, charts, temperature, humidity](http://efektalab.com/eON213wz)',
|
|
557
557
|
fromZigbee: [fz.temperature, fz.humidity, fz.pressure, fz.battery],
|
|
558
|
-
toZigbee: [
|
|
558
|
+
toZigbee: [],
|
|
559
559
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
560
560
|
const endpoint = device.getEndpoint(1);
|
|
561
561
|
await reporting.bind(endpoint, coordinatorEndpoint, [
|
|
@@ -576,7 +576,7 @@ module.exports = [
|
|
|
576
576
|
vendor: 'Custom devices (DiY)',
|
|
577
577
|
description: '[DIY temperature, humidity and atmospheric pressure sensor, long battery life](http://efektalab.com/eON_THP)',
|
|
578
578
|
fromZigbee: [fz.temperature, fz.humidity, fz.pressure, fz.battery],
|
|
579
|
-
toZigbee: [
|
|
579
|
+
toZigbee: [],
|
|
580
580
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
581
581
|
const endpoint = device.getEndpoint(1);
|
|
582
582
|
await reporting.bind(endpoint, coordinatorEndpoint, [
|
|
@@ -597,7 +597,7 @@ module.exports = [
|
|
|
597
597
|
vendor: 'Custom devices (DiY)',
|
|
598
598
|
description: '[Plant watering sensor EFEKTA PWS max](http://efektalab.com/PWS_Max)',
|
|
599
599
|
fromZigbee: [fz.temperature, fz.humidity, fz.illuminance, fz.soil_moisture, fz.battery],
|
|
600
|
-
toZigbee: [
|
|
600
|
+
toZigbee: [],
|
|
601
601
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
602
602
|
const firstEndpoint = device.getEndpoint(1);
|
|
603
603
|
await reporting.bind(firstEndpoint, coordinatorEndpoint, [
|
|
@@ -618,7 +618,7 @@ module.exports = [
|
|
|
618
618
|
vendor: 'Custom devices (DiY)',
|
|
619
619
|
description: '[Plant watering sensor EFEKTA PWS Max Pro, long battery life](http://efektalab.com/PWS_MaxPro)',
|
|
620
620
|
fromZigbee: [fz.temperature, fz.humidity, fz.illuminance, fz.soil_moisture, fz.battery],
|
|
621
|
-
toZigbee: [
|
|
621
|
+
toZigbee: [],
|
|
622
622
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
623
623
|
const firstEndpoint = device.getEndpoint(1);
|
|
624
624
|
await reporting.bind(firstEndpoint, coordinatorEndpoint, [
|
|
@@ -639,7 +639,7 @@ module.exports = [
|
|
|
639
639
|
vendor: 'Custom devices (DiY)',
|
|
640
640
|
description: '[Mini weather station, barometer, forecast, charts, temperature, humidity, light](http://efektalab.com/eON290wz)',
|
|
641
641
|
fromZigbee: [fz.temperature, fz.humidity, fz.pressure, fz.illuminance, fz.battery],
|
|
642
|
-
toZigbee: [
|
|
642
|
+
toZigbee: [],
|
|
643
643
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
644
644
|
const endpoint = device.getEndpoint(1);
|
|
645
645
|
await reporting.bind(endpoint, coordinatorEndpoint, [
|
|
@@ -661,7 +661,7 @@ module.exports = [
|
|
|
661
661
|
vendor: 'Custom devices (DiY)',
|
|
662
662
|
description: '[Plant Wattering Sensor with e-ink display 2.13](https://efektalab.com/eFlowerPro)',
|
|
663
663
|
fromZigbee: [fz.temperature, fz.humidity, fz.illuminance, fz.soil_moisture, fz.battery],
|
|
664
|
-
toZigbee: [
|
|
664
|
+
toZigbee: [],
|
|
665
665
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
666
666
|
const firstEndpoint = device.getEndpoint(1);
|
|
667
667
|
await reporting.bind(firstEndpoint, coordinatorEndpoint, [
|
|
@@ -682,7 +682,7 @@ module.exports = [
|
|
|
682
682
|
vendor: 'Custom devices (DiY)',
|
|
683
683
|
description: '[Mini digital thermometer & hygrometer with e-ink1.02](http://efektalab.com/eTH102)',
|
|
684
684
|
fromZigbee: [fz.temperature, fz.humidity, fz.battery],
|
|
685
|
-
toZigbee: [
|
|
685
|
+
toZigbee: [],
|
|
686
686
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
687
687
|
const endpoint = device.getEndpoint(1);
|
|
688
688
|
await reporting.bind(endpoint, coordinatorEndpoint, [
|
|
@@ -702,7 +702,7 @@ module.exports = [
|
|
|
702
702
|
description: '[CO2 Monitor with IPS TFT Display, outdoor temperature and humidity, date and time](http://efektalab.com/iAQ)',
|
|
703
703
|
fromZigbee: [fz.temperature, fz.humidity, fz.illuminance, fzLocal.co2, fzLocal.co2_config,
|
|
704
704
|
fzLocal.temperature_config, fzLocal.humidity_config],
|
|
705
|
-
toZigbee: [
|
|
705
|
+
toZigbee: [tzLocal.co2_config, tzLocal.temperature_config, tzLocal.humidity_config, tzLocal.local_time],
|
|
706
706
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
707
707
|
const endpoint = device.getEndpoint(1);
|
|
708
708
|
const clusters = ['msTemperatureMeasurement', 'msRelativeHumidity', 'msIlluminanceMeasurement', 'msCO2'];
|
|
@@ -762,7 +762,7 @@ module.exports = [
|
|
|
762
762
|
description: '[EFEKTA CO2 Smart Monitor, ws2812b indicator, can control the relay, binding](https://efektalab.com/CO2_Monitor)',
|
|
763
763
|
fromZigbee: [fz.temperature, fz.humidity, fzLocal.co2, fzLocal.co2_config, fzLocal.temperature_config,
|
|
764
764
|
fzLocal.humidity_config, fzLocal.termostat_config, fzLocal.hydrostat_config, fzLocal.co2_gasstat_config],
|
|
765
|
-
toZigbee: [
|
|
765
|
+
toZigbee: [tzLocal.co2_config, tzLocal.temperature_config, tzLocal.humidity_config,
|
|
766
766
|
tzLocal.termostat_config, tzLocal.hydrostat_config, tzLocal.co2_gasstat_config],
|
|
767
767
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
768
768
|
const endpoint = device.getEndpoint(1);
|
|
@@ -813,7 +813,7 @@ module.exports = [
|
|
|
813
813
|
vendor: 'Custom devices (DiY)',
|
|
814
814
|
description: 'Alternative firmware for the SONOFF SNZB-02 sensor from EfektaLab, DIY',
|
|
815
815
|
fromZigbee: [fz.temperature, fz.humidity, fz.battery, fzLocal.termostat_config, fzLocal.hydrostat_config, fzLocal.node_config],
|
|
816
|
-
toZigbee: [
|
|
816
|
+
toZigbee: [tzLocal.termostat_config, tzLocal.hydrostat_config, tzLocal.node_config],
|
|
817
817
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
818
818
|
const endpoint = device.getEndpoint(1);
|
|
819
819
|
await reporting.bind(endpoint, coordinatorEndpoint, [
|
package/devices/diyruz.js
CHANGED
|
@@ -73,7 +73,7 @@ module.exports = [
|
|
|
73
73
|
}
|
|
74
74
|
return features;
|
|
75
75
|
})(20)),
|
|
76
|
-
toZigbee: [tz.diyruz_freepad_on_off_config
|
|
76
|
+
toZigbee: [tz.diyruz_freepad_on_off_config],
|
|
77
77
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
78
78
|
const endpoint = device.getEndpoint(1);
|
|
79
79
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
@@ -116,7 +116,7 @@ module.exports = [
|
|
|
116
116
|
}
|
|
117
117
|
return features;
|
|
118
118
|
})(8)),
|
|
119
|
-
toZigbee: [tz.diyruz_freepad_on_off_config
|
|
119
|
+
toZigbee: [tz.diyruz_freepad_on_off_config],
|
|
120
120
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
121
121
|
const endpoint = device.getEndpoint(1);
|
|
122
122
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
@@ -157,7 +157,7 @@ module.exports = [
|
|
|
157
157
|
exposes.numeric('sensors_count', ea.ALL).withDescription('Count of installed tubes').withValueMin(0).withValueMax(50),
|
|
158
158
|
exposes.numeric('sensitivity', ea.ALL).withDescription('This is applicable if tubes type is set to other')
|
|
159
159
|
.withValueMin(0).withValueMax(100)],
|
|
160
|
-
toZigbee: [tz.diyruz_geiger_config
|
|
160
|
+
toZigbee: [tz.diyruz_geiger_config],
|
|
161
161
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
162
162
|
const endpoint = device.getEndpoint(1);
|
|
163
163
|
await reporting.bind(endpoint, coordinatorEndpoint, ['msIlluminanceMeasurement', 'genOnOff']);
|
|
@@ -202,7 +202,7 @@ module.exports = [
|
|
|
202
202
|
vendor: 'DIYRuZ',
|
|
203
203
|
description: '[Flower sensor](http://modkam.ru/?p=1700)',
|
|
204
204
|
fromZigbee: [fz.temperature, fz.humidity, fz.illuminance, fz.soil_moisture, fz.pressure, fz.battery],
|
|
205
|
-
toZigbee: [
|
|
205
|
+
toZigbee: [],
|
|
206
206
|
meta: {multiEndpoint: true},
|
|
207
207
|
endpoint: (device) => {
|
|
208
208
|
return {'bme': 1, 'ds': 2};
|
|
@@ -237,7 +237,7 @@ module.exports = [
|
|
|
237
237
|
description: '[Air quality sensor](https://modkam.ru/?p=1715)',
|
|
238
238
|
fromZigbee: [fz.temperature, fz.humidity, fz.co2, fz.pressure, fz.diyruz_airsense_config_co2,
|
|
239
239
|
fz.diyruz_airsense_config_temp, fz.diyruz_airsense_config_pres, fz.diyruz_airsense_config_hum],
|
|
240
|
-
toZigbee: [tz.
|
|
240
|
+
toZigbee: [tz.diyruz_airsense_config],
|
|
241
241
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
242
242
|
const endpoint = device.getEndpoint(1);
|
|
243
243
|
const clusters = ['msTemperatureMeasurement', 'msRelativeHumidity', 'msPressureMeasurement', 'msCO2'];
|
|
@@ -269,7 +269,7 @@ module.exports = [
|
|
|
269
269
|
vendor: 'DIYRuZ',
|
|
270
270
|
description: '[Matrix intercom auto opener](https://diyruz.github.io/posts/zintercom/)',
|
|
271
271
|
fromZigbee: [fz.battery, fz.diyruz_zintercom_config],
|
|
272
|
-
toZigbee: [tz.
|
|
272
|
+
toZigbee: [tz.diyruz_zintercom_config],
|
|
273
273
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
274
274
|
const firstEndpoint = device.getEndpoint(1);
|
|
275
275
|
await reporting.bind(firstEndpoint, coordinatorEndpoint, ['closuresDoorLock', 'genPowerCfg']);
|
package/devices/ecozy.js
CHANGED
|
@@ -12,7 +12,7 @@ module.exports = [
|
|
|
12
12
|
vendor: 'eCozy',
|
|
13
13
|
description: 'Smart heating thermostat',
|
|
14
14
|
fromZigbee: [fz.battery, fz.legacy.thermostat_att_report],
|
|
15
|
-
toZigbee: [tz.
|
|
15
|
+
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_local_temperature_calibration, tz.thermostat_occupancy,
|
|
16
16
|
tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint, tz.thermostat_setpoint_raise_lower,
|
|
17
17
|
tz.thermostat_remote_sensing, tz.thermostat_control_sequence_of_operation, tz.thermostat_system_mode,
|
|
18
18
|
tz.thermostat_weekly_schedule, tz.thermostat_clear_weekly_schedule, tz.thermostat_relay_status_log,
|
package/devices/leviton.js
CHANGED
|
@@ -90,7 +90,7 @@ module.exports = [
|
|
|
90
90
|
vendor: 'Leviton',
|
|
91
91
|
description: 'Omnistat2 wireless thermostat',
|
|
92
92
|
fromZigbee: [fz.legacy.thermostat_att_report, fz.fan],
|
|
93
|
-
toZigbee: [tz.
|
|
93
|
+
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_local_temperature_calibration, tz.thermostat_occupancy,
|
|
94
94
|
tz.thermostat_occupied_heating_setpoint, tz.thermostat_unoccupied_heating_setpoint, tz.thermostat_occupied_cooling_setpoint,
|
|
95
95
|
tz.thermostat_unoccupied_cooling_setpoint, tz.thermostat_setpoint_raise_lower, tz.thermostat_remote_sensing,
|
|
96
96
|
tz.thermostat_control_sequence_of_operation, tz.thermostat_system_mode, tz.thermostat_weekly_schedule,
|
package/devices/lidl.js
CHANGED
|
@@ -8,7 +8,6 @@ const ea = exposes.access;
|
|
|
8
8
|
const tuya = require('../lib/tuya');
|
|
9
9
|
const globalStore = require('../lib/store');
|
|
10
10
|
const ota = require('../lib/ota');
|
|
11
|
-
const utils = require('../lib/utils');
|
|
12
11
|
|
|
13
12
|
const tuyaLocal = {
|
|
14
13
|
dataPoints: {
|
|
@@ -543,11 +542,6 @@ module.exports = [
|
|
|
543
542
|
vendor: 'Lidl',
|
|
544
543
|
description: 'Livarno smart LED ceiling light',
|
|
545
544
|
...extend.light_onoff_brightness_colortemp_color({disableColorTempStartup: true, colorTempRange: [153, 500]}),
|
|
546
|
-
toZigbee: utils.replaceInArray(
|
|
547
|
-
extend.light_onoff_brightness_colortemp_color({disableColorTempStartup: true, colorTempRange: [153, 500]}).toZigbee,
|
|
548
|
-
[tz.light_color_colortemp],
|
|
549
|
-
[tz.light_color_and_colortemp_via_color],
|
|
550
|
-
),
|
|
551
545
|
meta: {applyRedFix: true, enhancedHue: false},
|
|
552
546
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
553
547
|
device.getEndpoint(1).saveClusterAttributeKeyValue('lightingColorCtrl', {colorCapabilities: 29});
|
package/devices/lux.js
CHANGED
|
@@ -10,7 +10,7 @@ module.exports = [
|
|
|
10
10
|
vendor: 'LUX',
|
|
11
11
|
description: 'KONOz thermostat',
|
|
12
12
|
fromZigbee: [fz.battery, fz.thermostat, fz.fan, fz.thermostat_weekly_schedule],
|
|
13
|
-
toZigbee: [tz.
|
|
13
|
+
toZigbee: [tz.thermostat_local_temperature,
|
|
14
14
|
tz.thermostat_occupancy, tz.thermostat_occupied_heating_setpoint, tz.thermostat_occupied_cooling_setpoint,
|
|
15
15
|
tz.thermostat_unoccupied_heating_setpoint, tz.thermostat_setpoint_raise_lower, tz.thermostat_running_state,
|
|
16
16
|
tz.fan_mode, tz.thermostat_system_mode,
|
|
File without changes
|
package/devices/neo.js
CHANGED
|
@@ -35,7 +35,7 @@ module.exports = [
|
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
|
-
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_t1blo2bj'}],
|
|
38
|
+
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_t1blo2bj'}, {modelID: 'TS0601', manufacturerName: '_TZE204_t1blo2bj'}],
|
|
39
39
|
zigbeeModel: ['1blo2bj'],
|
|
40
40
|
model: 'NAS-AB02B2',
|
|
41
41
|
vendor: 'Neo',
|
package/devices/philips.js
CHANGED
|
@@ -1693,7 +1693,7 @@ module.exports = [
|
|
|
1693
1693
|
extend: hueExtend.light_onoff_brightness_colortemp_color(),
|
|
1694
1694
|
},
|
|
1695
1695
|
{
|
|
1696
|
-
zigbeeModel: ['1746430P7'],
|
|
1696
|
+
zigbeeModel: ['1746430P7', '929003098701'],
|
|
1697
1697
|
model: '1746430P7',
|
|
1698
1698
|
vendor: 'Philips',
|
|
1699
1699
|
description: 'Hue outdoor Resonate wall lamp (black)',
|
|
@@ -2271,6 +2271,13 @@ module.exports = [
|
|
|
2271
2271
|
description: 'Hue White Fuzo outdoor floor light',
|
|
2272
2272
|
extend: hueExtend.light_onoff_brightness(),
|
|
2273
2273
|
},
|
|
2274
|
+
{
|
|
2275
|
+
zigbeeModel: ['929003098901'],
|
|
2276
|
+
model: '929003098901',
|
|
2277
|
+
vendor: 'Philips',
|
|
2278
|
+
description: 'Hue White Inara outdoor light',
|
|
2279
|
+
extend: hueExtend.light_onoff_brightness(),
|
|
2280
|
+
},
|
|
2274
2281
|
{
|
|
2275
2282
|
zigbeeModel: ['1744530P7', '1744630P7', '1744430P7', '1744730P7'],
|
|
2276
2283
|
model: '8718696170625',
|