zigbee-herdsman-converters 15.0.36 → 15.0.38
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 +9 -7
- package/devices/ajax_online.js +1 -1
- package/devices/kami.js +2 -2
- package/devices/philips.js +1 -1
- package/devices/schneider_electric.js +20 -0
- package/devices/sinope.js +24 -7
- package/devices/tuya.js +16 -1
- package/devices/xiaomi.js +101 -0
- package/devices/yale.js +4 -2
- package/lib/reporting.js +1 -0
- package/lib/xiaomi.js +36 -6
- package/package.json +3 -3
package/converters/fromZigbee.js
CHANGED
|
@@ -5387,19 +5387,19 @@ const converters = {
|
|
|
5387
5387
|
cluster: 'genBasic',
|
|
5388
5388
|
type: ['attributeReport', 'readResponse'],
|
|
5389
5389
|
options: xiaomi.numericAttributes2Options,
|
|
5390
|
-
convert: (model, msg, publish, options, meta) => {
|
|
5391
|
-
return xiaomi.numericAttributes2Payload(msg, meta, model, options, msg.data);
|
|
5390
|
+
convert: async (model, msg, publish, options, meta) => {
|
|
5391
|
+
return await xiaomi.numericAttributes2Payload(msg, meta, model, options, msg.data);
|
|
5392
5392
|
},
|
|
5393
5393
|
},
|
|
5394
5394
|
xiaomi_basic_raw: {
|
|
5395
5395
|
cluster: 'genBasic',
|
|
5396
5396
|
type: ['raw'],
|
|
5397
5397
|
options: xiaomi.numericAttributes2Options,
|
|
5398
|
-
convert: (model, msg, publish, options, meta) => {
|
|
5398
|
+
convert: async (model, msg, publish, options, meta) => {
|
|
5399
5399
|
let payload = {};
|
|
5400
5400
|
if (Buffer.isBuffer(msg.data)) {
|
|
5401
5401
|
const dataObject = xiaomi.buffer2DataObject(meta, model, msg.data);
|
|
5402
|
-
payload = xiaomi.numericAttributes2Payload(msg, meta, model, options, dataObject);
|
|
5402
|
+
payload = await xiaomi.numericAttributes2Payload(msg, meta, model, options, dataObject);
|
|
5403
5403
|
}
|
|
5404
5404
|
return payload;
|
|
5405
5405
|
},
|
|
@@ -5408,8 +5408,8 @@ const converters = {
|
|
|
5408
5408
|
cluster: 'aqaraOpple',
|
|
5409
5409
|
type: ['attributeReport', 'readResponse'],
|
|
5410
5410
|
options: xiaomi.numericAttributes2Options,
|
|
5411
|
-
convert: (model, msg, publish, options, meta) => {
|
|
5412
|
-
return xiaomi.numericAttributes2Payload(msg, meta, model, options, msg.data);
|
|
5411
|
+
convert: async (model, msg, publish, options, meta) => {
|
|
5412
|
+
return await xiaomi.numericAttributes2Payload(msg, meta, model, options, msg.data);
|
|
5413
5413
|
},
|
|
5414
5414
|
},
|
|
5415
5415
|
xiaomi_on_off_action: {
|
|
@@ -6862,7 +6862,9 @@ const converters = {
|
|
|
6862
6862
|
cluster: 'msOccupancySensing',
|
|
6863
6863
|
type: ['raw'],
|
|
6864
6864
|
convert: (model, msg, publish, options, meta) => {
|
|
6865
|
-
|
|
6865
|
+
if (msg.data[7] === 1) {
|
|
6866
|
+
return {action: 'motion'};
|
|
6867
|
+
}
|
|
6866
6868
|
},
|
|
6867
6869
|
},
|
|
6868
6870
|
DNCKAT_S00X_buttons: {
|
package/devices/ajax_online.js
CHANGED
|
@@ -16,7 +16,7 @@ module.exports = [
|
|
|
16
16
|
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [158, 495], disableEffect: true}),
|
|
17
17
|
},
|
|
18
18
|
{
|
|
19
|
-
zigbeeModel: ['AJ_ZBPROA60'],
|
|
19
|
+
zigbeeModel: ['AJ_ZBPROA60', 'AJ_ZBPROA6'],
|
|
20
20
|
model: 'AJ_ZIGPROA60',
|
|
21
21
|
vendor: 'Ajax Online',
|
|
22
22
|
description: 'Smart Zigbee pro 12W A60 bulb',
|
package/devices/kami.js
CHANGED
|
@@ -7,9 +7,9 @@ module.exports = [
|
|
|
7
7
|
zigbeeModel: ['Z3ContactSensor'],
|
|
8
8
|
model: 'N20',
|
|
9
9
|
vendor: 'KAMI',
|
|
10
|
-
description: '
|
|
10
|
+
description: 'Contact sensor or motion sensor',
|
|
11
11
|
fromZigbee: [fz.KAMI_contact, fz.KAMI_occupancy],
|
|
12
12
|
toZigbee: [],
|
|
13
|
-
exposes: [e.contact(), e.
|
|
13
|
+
exposes: [e.contact(), e.action(['motion'])],
|
|
14
14
|
},
|
|
15
15
|
];
|
package/devices/philips.js
CHANGED
|
@@ -2383,7 +2383,7 @@ module.exports = [
|
|
|
2383
2383
|
model: '929002422702',
|
|
2384
2384
|
vendor: 'Philips',
|
|
2385
2385
|
description: 'Hue Play gradient lightstrip 55',
|
|
2386
|
-
extend: philips.extend.light_onoff_brightness_colortemp_color_gradient({colorTempRange: [153, 500]}),
|
|
2386
|
+
extend: philips.extend.light_onoff_brightness_colortemp_color_gradient({disableHueEffects: false, colorTempRange: [153, 500]}),
|
|
2387
2387
|
},
|
|
2388
2388
|
{
|
|
2389
2389
|
zigbeeModel: ['LCX002'],
|
|
@@ -682,6 +682,26 @@ module.exports = [
|
|
|
682
682
|
await reporting.instantaneousDemand(endpoint);
|
|
683
683
|
},
|
|
684
684
|
},
|
|
685
|
+
{
|
|
686
|
+
zigbeeModel: ['2GANG/SWITCH/2'],
|
|
687
|
+
model: 'MEG5126-0300',
|
|
688
|
+
vendor: 'Schneider Electric',
|
|
689
|
+
description: 'Merten MEG5165 PlusLink shutter insert with Merten Wiser System M push button (2fold)',
|
|
690
|
+
extend: extend.switch(),
|
|
691
|
+
exposes: [e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2')],
|
|
692
|
+
meta: {multiEndpoint: true},
|
|
693
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
694
|
+
const endpoint1 = device.getEndpoint(1);
|
|
695
|
+
await reporting.bind(endpoint1, coordinatorEndpoint, ['genOnOff']);
|
|
696
|
+
await reporting.onOff(endpoint1);
|
|
697
|
+
const endpoint2 = device.getEndpoint(2);
|
|
698
|
+
await reporting.bind(endpoint2, coordinatorEndpoint, ['genOnOff']);
|
|
699
|
+
await reporting.onOff(endpoint2);
|
|
700
|
+
},
|
|
701
|
+
endpoint: (device) => {
|
|
702
|
+
return {l1: 1, l2: 2};
|
|
703
|
+
},
|
|
704
|
+
},
|
|
685
705
|
{
|
|
686
706
|
zigbeeModel: ['EH-ZB-VACT'],
|
|
687
707
|
model: 'EER53000',
|
package/devices/sinope.js
CHANGED
|
@@ -12,6 +12,18 @@ const {precisionRound} = require('../lib/utils');
|
|
|
12
12
|
const manuSinope = {manufacturerCode: 0x119C};
|
|
13
13
|
|
|
14
14
|
const fzLocal = {
|
|
15
|
+
ias_water_leak_alarm: {
|
|
16
|
+
// RM3500ZB specific
|
|
17
|
+
cluster: 'ssIasZone',
|
|
18
|
+
type: ['commandStatusChangeNotification', 'attributeReport', 'readResponse'],
|
|
19
|
+
convert: (model, msg, publish, options, meta) => {
|
|
20
|
+
const zoneStatus = msg.data.zoneStatus;
|
|
21
|
+
return {
|
|
22
|
+
water_leak: (zoneStatus & 1) > 0,
|
|
23
|
+
tamper: (zoneStatus & 1<<2) > 0,
|
|
24
|
+
};
|
|
25
|
+
},
|
|
26
|
+
},
|
|
15
27
|
thermostat: {
|
|
16
28
|
cluster: 'hvacThermostat',
|
|
17
29
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -1179,21 +1191,26 @@ module.exports = [
|
|
|
1179
1191
|
model: 'RM3500ZB',
|
|
1180
1192
|
vendor: 'Sinopé',
|
|
1181
1193
|
description: 'Calypso smart water heater controller',
|
|
1182
|
-
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering,
|
|
1194
|
+
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fzLocal.ias_water_leak_alarm,
|
|
1195
|
+
fzLocal.sinope, fz.temperature],
|
|
1183
1196
|
toZigbee: [tz.on_off],
|
|
1184
1197
|
exposes: [e.switch(), e.power(), e.current(), e.voltage(), e.energy(), e.water_leak(), e.temperature()],
|
|
1185
1198
|
configure: async (device, coordinatorEndpoint) => {
|
|
1186
1199
|
const endpoint = device.getEndpoint(1);
|
|
1187
|
-
const binds = ['genOnOff', 'haElectricalMeasurement', 'seMetering', '
|
|
1200
|
+
const binds = ['genOnOff', 'haElectricalMeasurement', 'seMetering', 'msTemperatureMeasurement', 'ssIasZone',
|
|
1201
|
+
'manuSpecificSinope'];
|
|
1188
1202
|
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
1189
1203
|
await reporting.onOff(endpoint);
|
|
1204
|
+
await reporting.temperature(endpoint, {min: 10, max: 301, change: 10}); // divider 100: 0.1C
|
|
1190
1205
|
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
1191
|
-
await reporting.activePower(endpoint);
|
|
1192
|
-
await reporting.rmsCurrent(endpoint);
|
|
1193
|
-
await reporting.rmsVoltage(endpoint);
|
|
1206
|
+
await reporting.activePower(endpoint, {min: 10, max: 305, change: 2}); // divider 1 : 2W
|
|
1207
|
+
await reporting.rmsCurrent(endpoint, {min: 10, max: 306, change: 10}); // divider 1000: 0.01Arms
|
|
1208
|
+
await reporting.rmsVoltage(endpoint, {min: 10, max: 307, change: 1}); // divider 1: 1Vrms
|
|
1194
1209
|
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
1195
|
-
await reporting.currentSummDelivered(endpoint);
|
|
1196
|
-
|
|
1210
|
+
await reporting.currentSummDelivered(endpoint, {min: 10, max: 303, change: [10, 10]}); // divider 1000: 0,01kWh
|
|
1211
|
+
|
|
1212
|
+
await endpoint.configureReporting('ssIasZone', [{attribute: 'zoneStatus', minimumReportInterval: 1,
|
|
1213
|
+
maximumReportInterval: constants.repInterval.HOUR, reportableChange: 1}]);
|
|
1197
1214
|
},
|
|
1198
1215
|
},
|
|
1199
1216
|
];
|
package/devices/tuya.js
CHANGED
|
@@ -2118,7 +2118,7 @@ module.exports = [
|
|
|
2118
2118
|
{modelID: 'TS0601', manufacturerName: '_TZE200_3ylew7b4'},
|
|
2119
2119
|
{modelID: 'TS0601', manufacturerName: '_TZE200_llm0epxg'},
|
|
2120
2120
|
],
|
|
2121
|
-
model: '
|
|
2121
|
+
model: 'TS0601_cover_1',
|
|
2122
2122
|
vendor: 'TuYa',
|
|
2123
2123
|
description: 'Curtain motor/roller blind motor/window pusher/tubular motor',
|
|
2124
2124
|
whiteLabel: [
|
|
@@ -2150,6 +2150,21 @@ module.exports = [
|
|
|
2150
2150
|
.withValueMax(255)
|
|
2151
2151
|
.withDescription('Motor speed'))],
|
|
2152
2152
|
},
|
|
2153
|
+
{
|
|
2154
|
+
fingerprint: [
|
|
2155
|
+
// Curtain motors:
|
|
2156
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_eegnwoyw'},
|
|
2157
|
+
],
|
|
2158
|
+
model: 'TS0601_cover_2',
|
|
2159
|
+
vendor: 'TuYa',
|
|
2160
|
+
description: 'Curtain motor fixed speed',
|
|
2161
|
+
whiteLabel: [
|
|
2162
|
+
{vendor: 'Zemismart', model: 'BCM100DB'},
|
|
2163
|
+
],
|
|
2164
|
+
fromZigbee: [fz.tuya_cover, fz.ignore_basic_report],
|
|
2165
|
+
toZigbee: [tz.tuya_cover_control],
|
|
2166
|
+
exposes: [e.cover_position().setAccess('position', ea.STATE_SET)],
|
|
2167
|
+
},
|
|
2153
2168
|
{
|
|
2154
2169
|
zigbeeModel: ['kud7u2l'],
|
|
2155
2170
|
fingerprint: [
|
package/devices/xiaomi.js
CHANGED
|
@@ -297,6 +297,49 @@ const fzLocal = {
|
|
|
297
297
|
return payload;
|
|
298
298
|
},
|
|
299
299
|
},
|
|
300
|
+
CTPR01_action_multistate: {
|
|
301
|
+
cluster: 'genMultistateInput',
|
|
302
|
+
type: ['attributeReport', 'readResponse'],
|
|
303
|
+
options: [],
|
|
304
|
+
convert: (model, msg, publish, options, meta) => {
|
|
305
|
+
const value = msg.data['presentValue'];
|
|
306
|
+
let payload;
|
|
307
|
+
|
|
308
|
+
if (value === 0) payload = {action: 'shake'};
|
|
309
|
+
else if (value === 1) payload = {action: 'throw'};
|
|
310
|
+
else if (value === 2) payload = {action: '1_min_inactivity'};
|
|
311
|
+
else if (value === 4) payload = {action: 'hold'};
|
|
312
|
+
else if (value >= 1024) payload = {action: 'flip_to_side', side: value - 1023};
|
|
313
|
+
else if (value >= 512) payload = {action: 'tap', side: value - 511};
|
|
314
|
+
else if (value >= 256) payload = {action: 'slide', side: value - 255};
|
|
315
|
+
else if (value >= 128) {
|
|
316
|
+
payload = {
|
|
317
|
+
action: 'flip180', side: value - 127,
|
|
318
|
+
action_from_side: 7 - value + 127,
|
|
319
|
+
};
|
|
320
|
+
} else if (value >= 64) {
|
|
321
|
+
payload = {
|
|
322
|
+
action: 'flip90', side: value % 8 + 1,
|
|
323
|
+
action_from_side: Math.floor((value - 64) / 8) + 1,
|
|
324
|
+
};
|
|
325
|
+
} else {
|
|
326
|
+
meta.logger.debug(`${model.zigbeeModel}: unknown action with value ${value}`);
|
|
327
|
+
}
|
|
328
|
+
return payload;
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
CTPR01_action_analog: {
|
|
332
|
+
cluster: 'genAnalogInput',
|
|
333
|
+
type: ['attributeReport', 'readResponse'],
|
|
334
|
+
options: [],
|
|
335
|
+
convert: (model, msg, publish, options, meta) => {
|
|
336
|
+
const value = msg.data['presentValue'];
|
|
337
|
+
return {
|
|
338
|
+
action: value < 0 ? 'rotate_left' : 'rotate_right',
|
|
339
|
+
action_angle: Math.floor(value * 100) / 100,
|
|
340
|
+
};
|
|
341
|
+
},
|
|
342
|
+
},
|
|
300
343
|
};
|
|
301
344
|
|
|
302
345
|
const tzLocal = {
|
|
@@ -608,6 +651,25 @@ const tzLocal = {
|
|
|
608
651
|
await entity.write('aqaraOpple', payload, {manufacturerCode});
|
|
609
652
|
},
|
|
610
653
|
},
|
|
654
|
+
CTPR01_operation_mode: {
|
|
655
|
+
key: ['operation_mode'],
|
|
656
|
+
convertSet: async (entity, key, value, meta) => {
|
|
657
|
+
const lookup = {action_mode: 0, scene_mode: 1};
|
|
658
|
+
/**
|
|
659
|
+
* schedule the callback to run when the configuration window comes
|
|
660
|
+
*/
|
|
661
|
+
const callback = async () => {
|
|
662
|
+
await entity.write(
|
|
663
|
+
'aqaraOpple',
|
|
664
|
+
{0x0148: {value: lookup[value], type: 0x20}},
|
|
665
|
+
{manufacturerCode: 0x115f, disableDefaultResponse: true},
|
|
666
|
+
);
|
|
667
|
+
meta.logger.info('operation_mode switch success!');
|
|
668
|
+
};
|
|
669
|
+
globalStore.putValue(meta.device, 'opModeSwitchTask', {callback, newMode: value});
|
|
670
|
+
meta.logger.info('Now give your cube a forceful throw motion (Careful not to drop it)!');
|
|
671
|
+
},
|
|
672
|
+
},
|
|
611
673
|
};
|
|
612
674
|
|
|
613
675
|
module.exports = [
|
|
@@ -2991,4 +3053,43 @@ module.exports = [
|
|
|
2991
3053
|
exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'hold', 'release']),
|
|
2992
3054
|
e.device_temperature(), e.power_outage_count()],
|
|
2993
3055
|
},
|
|
3056
|
+
{
|
|
3057
|
+
zigbeeModel: ['lumi.remote.cagl02'],
|
|
3058
|
+
model: 'CTP-R01',
|
|
3059
|
+
vendor: 'Xiaomi',
|
|
3060
|
+
description: 'Aqara magic cube T1 Pro',
|
|
3061
|
+
meta: {battery: {voltageToPercentage: '3V_2850_3000'}},
|
|
3062
|
+
ota: ota.zigbeeOTA,
|
|
3063
|
+
fromZigbee: [fz.aqara_opple, fzLocal.CTPR01_action_multistate, fzLocal.CTPR01_action_analog, fz.ignore_onoff_report],
|
|
3064
|
+
toZigbee: [tzLocal.CTPR01_operation_mode],
|
|
3065
|
+
exposes: [
|
|
3066
|
+
e.battery(),
|
|
3067
|
+
e.battery_voltage(),
|
|
3068
|
+
e.device_temperature(),
|
|
3069
|
+
e.power_outage_count(false),
|
|
3070
|
+
exposes
|
|
3071
|
+
.enum('operation_mode', ea.SET, ['action_mode', 'scene_mode'])
|
|
3072
|
+
.withDescription('[Soft Switch]: There is a configuration window, opens once an hour on itself, ' +
|
|
3073
|
+
'only during which the cube will respond to mode switch. ' +
|
|
3074
|
+
'Mode switch will be scheduled to take effect when the window becomes available. ' +
|
|
3075
|
+
'You can also give it a throw action (no backward motion) to force a respond! ' +
|
|
3076
|
+
'Otherwise, you may open lid and click LINK once to make the cube respond immediately. ' +
|
|
3077
|
+
'[Hard Switch]: Open lid and click LINK button 5 times.'),
|
|
3078
|
+
e.cube_side('side'),
|
|
3079
|
+
e.action([
|
|
3080
|
+
'shake', 'throw', 'tap', 'slide', 'flip180', 'flip90', 'hold', 'side_up',
|
|
3081
|
+
'rotate_left', 'rotate_right', '1_min_inactivity', 'flip_to_side',
|
|
3082
|
+
]).withDescription('Triggered action'),
|
|
3083
|
+
e.cube_side('action_from_side'),
|
|
3084
|
+
e.angle('action_angle'),
|
|
3085
|
+
],
|
|
3086
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
3087
|
+
device.softwareBuildID = `0.0.0_00${device.applicationVersion}`;
|
|
3088
|
+
device.save();
|
|
3089
|
+
|
|
3090
|
+
const endpoint = device.getEndpoint(1);
|
|
3091
|
+
await endpoint.write('aqaraOpple', {mode: 1}, {manufacturerCode: 0x115f, disableDefaultResponse: true, disableResponse: true});
|
|
3092
|
+
await endpoint.read('aqaraOpple', [0x148], {manufacturerCode: 0x115f, disableDefaultResponse: true, disableResponse: true});
|
|
3093
|
+
},
|
|
3094
|
+
},
|
|
2994
3095
|
];
|
package/devices/yale.js
CHANGED
|
@@ -8,14 +8,16 @@ const lockExtend = (meta, lockStateOptions=null, binds=['closuresDoorLock', 'gen
|
|
|
8
8
|
return {
|
|
9
9
|
fromZigbee: [fz.lock, fz.battery, fz.lock_operation_event, fz.lock_programming_event, fz.lock_pin_code_response,
|
|
10
10
|
fz.lock_user_status_response],
|
|
11
|
-
toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus],
|
|
11
|
+
toZigbee: [tz.lock, tz.pincode_lock, tz.lock_userstatus, tz.lock_auto_relock_time, tz.lock_sound_volume],
|
|
12
12
|
meta: {pinCodeCount: 250, ...meta},
|
|
13
|
-
exposes: [e.lock(), e.battery(), e.pincode(), e.lock_action(), e.lock_action_source_name(), e.lock_action_user()
|
|
13
|
+
exposes: [e.lock(), e.battery(), e.pincode(), e.lock_action(), e.lock_action_source_name(), e.lock_action_user(),
|
|
14
|
+
e.auto_relock_time().withValueMin(0).withValueMax(3600), e.sound_volume(), e.battery_low()],
|
|
14
15
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
15
16
|
const endpoint = device.getEndpoint(1);
|
|
16
17
|
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
17
18
|
await reporting.lockState(endpoint, lockStateOptions);
|
|
18
19
|
await reporting.batteryPercentageRemaining(endpoint);
|
|
20
|
+
await reporting.batteryAlarmState(endpoint);
|
|
19
21
|
},
|
|
20
22
|
};
|
|
21
23
|
};
|
package/lib/reporting.js
CHANGED
|
@@ -69,6 +69,7 @@ module.exports = {
|
|
|
69
69
|
batteryAlarmState: async (endpoint, overrides) => {
|
|
70
70
|
const p = payload('batteryAlarmState', repInterval.HOUR, repInterval.MAX, 0, overrides);
|
|
71
71
|
await endpoint.configureReporting('genPowerCfg', p);
|
|
72
|
+
await endpoint.read('genPowerCfg', ['batteryAlarmState']);
|
|
72
73
|
},
|
|
73
74
|
onOff: async (endpoint, overrides) => {
|
|
74
75
|
const p = payload('onOff', 0, repInterval.HOUR, 0, overrides);
|
package/lib/xiaomi.js
CHANGED
|
@@ -10,6 +10,7 @@ const {
|
|
|
10
10
|
} = require('./utils');
|
|
11
11
|
|
|
12
12
|
const exposes = require('../lib/exposes');
|
|
13
|
+
const globalStore = require('../lib/store');
|
|
13
14
|
|
|
14
15
|
const buffer2DataObject = (meta, model, buffer) => {
|
|
15
16
|
const dataObject = {};
|
|
@@ -142,10 +143,10 @@ const buffer2DataObject = (meta, model, buffer) => {
|
|
|
142
143
|
return dataObject;
|
|
143
144
|
};
|
|
144
145
|
|
|
145
|
-
const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
146
|
+
const numericAttributes2Payload = async (msg, meta, model, options, dataObject) => {
|
|
146
147
|
let payload = {};
|
|
147
148
|
|
|
148
|
-
|
|
149
|
+
for (const [key, value] of Object.entries(dataObject)) {
|
|
149
150
|
switch (key) {
|
|
150
151
|
case '0':
|
|
151
152
|
payload.detection_period = value;
|
|
@@ -188,7 +189,7 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
188
189
|
}
|
|
189
190
|
break;
|
|
190
191
|
case '10':
|
|
191
|
-
if (['ZNLDP13LM'].includes(model.model)) {
|
|
192
|
+
if (['ZNLDP13LM', 'CTP-R01'].includes(model.model)) {
|
|
192
193
|
// We don't know what the value means for these devices.
|
|
193
194
|
} else {
|
|
194
195
|
payload.switch_type = {1: 'toggle', 2: 'momentary'}[value];
|
|
@@ -422,7 +423,23 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
422
423
|
case '247':
|
|
423
424
|
{
|
|
424
425
|
const dataObject247 = buffer2DataObject(meta, model, value);
|
|
425
|
-
|
|
426
|
+
if (['CTP-R01'].includes(model.model)) {
|
|
427
|
+
// execute pending soft switch of operation_mode, if exists
|
|
428
|
+
const opModeSwitchTask = globalStore.getValue(meta.device, 'opModeSwitchTask');
|
|
429
|
+
if (opModeSwitchTask) {
|
|
430
|
+
const {callback, newMode} = opModeSwitchTask;
|
|
431
|
+
try {
|
|
432
|
+
await callback();
|
|
433
|
+
payload.operation_mode = newMode;
|
|
434
|
+
globalStore.putValue(meta.device, 'opModeSwitchTask', null);
|
|
435
|
+
} catch (error) {
|
|
436
|
+
// do nothing when callback fails
|
|
437
|
+
}
|
|
438
|
+
} else {
|
|
439
|
+
payload.operation_mode = {0: 'action_mode', 1: 'scene_mode'}[dataObject247[155]];
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
const payload247 = await numericAttributes2Payload(msg, meta, model, options, dataObject247);
|
|
426
443
|
payload = {...payload, ...payload247};
|
|
427
444
|
}
|
|
428
445
|
break;
|
|
@@ -506,6 +523,19 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
506
523
|
payload.approach_distance = {0: 'far', 1: 'medium', 2: 'near'}[value];
|
|
507
524
|
}
|
|
508
525
|
break;
|
|
526
|
+
case '328':
|
|
527
|
+
if (['CTP-R01'].includes(model.model)) {
|
|
528
|
+
// detected hard switch of operation_mode (attribute 0x148[328])
|
|
529
|
+
payload.operation_mode = {0: 'action_mode', 1: 'scene_mode'}[msg.data[328]];
|
|
530
|
+
}
|
|
531
|
+
break;
|
|
532
|
+
case '329':
|
|
533
|
+
if (['CTP-R01'].includes(model.model)) {
|
|
534
|
+
// side_up attribute report (attribute 0x149[329])
|
|
535
|
+
payload.action = 'side_up';
|
|
536
|
+
payload.side = msg.data[329] + 1;
|
|
537
|
+
}
|
|
538
|
+
break;
|
|
509
539
|
case '331':
|
|
510
540
|
if (['JT-BZ-01AQ/A', 'JY-GZ-01AQ'].includes(model.model)) {
|
|
511
541
|
payload.linkage_alarm = value === 1;
|
|
@@ -621,7 +651,7 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
621
651
|
break;
|
|
622
652
|
case '65281':
|
|
623
653
|
{
|
|
624
|
-
const payload65281 = numericAttributes2Payload(msg, meta, model, options, value);
|
|
654
|
+
const payload65281 = await numericAttributes2Payload(msg, meta, model, options, value);
|
|
625
655
|
payload = {...payload, ...payload65281};
|
|
626
656
|
}
|
|
627
657
|
break;
|
|
@@ -650,7 +680,7 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
650
680
|
default:
|
|
651
681
|
if (meta.logger) meta.logger.debug(`${model.zigbeeModel}: unknown key ${key} with value ${value}`);
|
|
652
682
|
}
|
|
653
|
-
}
|
|
683
|
+
}
|
|
654
684
|
|
|
655
685
|
if (meta.logger) meta.logger.debug(`${model.zigbeeModel}: Processed data into payload ${JSON.stringify(payload)}`);
|
|
656
686
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "15.0.
|
|
3
|
+
"version": "15.0.38",
|
|
4
4
|
"description": "Collection of device converters to be used with zigbee-herdsman",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
},
|
|
35
35
|
"homepage": "https://github.com/Koenkk/zigbee-herdsman-converters",
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"axios": "^1.
|
|
37
|
+
"axios": "^1.3.0",
|
|
38
38
|
"buffer-crc32": "^0.2.13",
|
|
39
39
|
"https-proxy-agent": "^5.0.1",
|
|
40
40
|
"tar-stream": "^3.0.0",
|
|
41
|
-
"zigbee-herdsman": "^0.14.
|
|
41
|
+
"zigbee-herdsman": "^0.14.89"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"eslint": "*",
|