zigbee-herdsman-converters 15.0.17 → 15.0.19
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 +11 -51
- package/converters/toZigbee.js +58 -24
- package/devices/alchemy.js +7 -0
- package/devices/bosch.js +2 -0
- package/devices/bticino.js +16 -7
- package/devices/legrand.js +9 -3
- package/devices/mercator.js +113 -2
- package/devices/moes.js +1 -0
- package/devices/niko.js +48 -7
- package/devices/osram.js +2 -2
- package/devices/owon.js +7 -2
- package/devices/philips.js +4 -4
- package/devices/samotech.js +1 -1
- package/devices/schneider_electric.js +18 -4
- package/devices/sonoff.js +1 -1
- package/devices/sunricher.js +1 -1
- package/devices/tuya.js +47 -20
- package/devices/ubisys.js +15 -7
- package/lib/ota/common.js +2 -5
- package/lib/tuya.js +6 -2
- package/package.json +2 -2
package/converters/fromZigbee.js
CHANGED
|
@@ -7431,6 +7431,17 @@ const converters = {
|
|
|
7431
7431
|
const lookup = {1: 'manual', 2: 'schedule', 3: 'energy_saver', 6: 'holiday'};
|
|
7432
7432
|
result['zone_mode'] = lookup[msg.data[0xe010]];
|
|
7433
7433
|
}
|
|
7434
|
+
if (msg.data.hasOwnProperty(0xe011)) {
|
|
7435
|
+
// wiserSmartHactConfig
|
|
7436
|
+
const lookup = {0x00: 'unconfigured', 0x80: 'setpoint_switch', 0x82: 'setpoint_fip', 0x83: 'fip_fip'};
|
|
7437
|
+
result['hact_config'] = lookup[msg.data[0xe011]];
|
|
7438
|
+
}
|
|
7439
|
+
if (msg.data.hasOwnProperty(0xe020)) {
|
|
7440
|
+
// wiserSmartCurrentFilPiloteMode
|
|
7441
|
+
const lookup = {0: 'comfort', 1: 'comfort_-1', 2: 'comfort_-2', 3: 'energy_saving',
|
|
7442
|
+
4: 'frost_protection', 5: 'off'};
|
|
7443
|
+
result['fip_setting'] = lookup[msg.data[0xe020]];
|
|
7444
|
+
}
|
|
7434
7445
|
if (msg.data.hasOwnProperty(0xe030)) {
|
|
7435
7446
|
// wiserSmartValvePosition
|
|
7436
7447
|
result['pi_heating_demand'] = msg.data[0xe030];
|
|
@@ -7651,57 +7662,6 @@ const converters = {
|
|
|
7651
7662
|
return result;
|
|
7652
7663
|
},
|
|
7653
7664
|
},
|
|
7654
|
-
tuya_radar_sensor_fall: {
|
|
7655
|
-
cluster: 'manuSpecificTuya',
|
|
7656
|
-
type: ['commandDataResponse', 'commandDataReport'],
|
|
7657
|
-
convert: (model, msg, publish, options, meta) => {
|
|
7658
|
-
const dpValue = tuya.firstDpValue(msg, meta, 'tuya_radar_sensor_fall');
|
|
7659
|
-
const dp = dpValue.dp;
|
|
7660
|
-
const value = tuya.getDataValue(dpValue);
|
|
7661
|
-
let result = null;
|
|
7662
|
-
switch (dp) {
|
|
7663
|
-
case tuya.dataPoints.trsfPresenceState:
|
|
7664
|
-
result = {presence: {0: false, 1: true}[value]};
|
|
7665
|
-
break;
|
|
7666
|
-
case tuya.dataPoints.trsfMotionState:
|
|
7667
|
-
result = {occupancy: {1: false, 2: true}[value]};
|
|
7668
|
-
break;
|
|
7669
|
-
case tuya.dataPoints.trsfMotionSpeed:
|
|
7670
|
-
result = {motion_speed: value};
|
|
7671
|
-
break;
|
|
7672
|
-
case tuya.dataPoints.trsfMotionDirection:
|
|
7673
|
-
result = {motion_direction: tuya.tuyaRadar.motionDirection[value]};
|
|
7674
|
-
break;
|
|
7675
|
-
case tuya.dataPoints.trsfScene:
|
|
7676
|
-
result = {radar_scene: tuya.tuyaRadar.radarScene[value]};
|
|
7677
|
-
break;
|
|
7678
|
-
case tuya.dataPoints.trsfSensitivity:
|
|
7679
|
-
result = {radar_sensitivity: value};
|
|
7680
|
-
break;
|
|
7681
|
-
case tuya.dataPoints.trsfIlluminanceLux:
|
|
7682
|
-
result = {illuminance_lux: value};
|
|
7683
|
-
break;
|
|
7684
|
-
case tuya.dataPoints.trsfTumbleAlarmTime:
|
|
7685
|
-
result = {tumble_alarm_time: value+1};
|
|
7686
|
-
break;
|
|
7687
|
-
case tuya.dataPoints.trsfTumbleSwitch:
|
|
7688
|
-
result = {tumble_switch: {false: 'OFF', true: 'ON'}[value]};
|
|
7689
|
-
break;
|
|
7690
|
-
case tuya.dataPoints.trsfFallDownStatus:
|
|
7691
|
-
result = {fall_down_status: tuya.tuyaRadar.fallDown[value]};
|
|
7692
|
-
break;
|
|
7693
|
-
case tuya.dataPoints.trsfStaticDwellAlarm:
|
|
7694
|
-
result = {static_dwell_alarm: value};
|
|
7695
|
-
break;
|
|
7696
|
-
case tuya.dataPoints.trsfFallSensitivity:
|
|
7697
|
-
result = {fall_sensitivity: value};
|
|
7698
|
-
break;
|
|
7699
|
-
default:
|
|
7700
|
-
meta.logger.warn(`fromZigbee.tuya_radar_sensor_fall: NOT RECOGNIZED DP ${dp} with data ${JSON.stringify(dpValue)}`);
|
|
7701
|
-
}
|
|
7702
|
-
return result;
|
|
7703
|
-
},
|
|
7704
|
-
},
|
|
7705
7665
|
tuya_smart_vibration_sensor: {
|
|
7706
7666
|
cluster: 'manuSpecificTuya',
|
|
7707
7667
|
type: ['commandGetData', 'commandDataResponse', 'raw'],
|
package/converters/toZigbee.js
CHANGED
|
@@ -61,6 +61,12 @@ const converters = {
|
|
|
61
61
|
await entity.command('genBasic', 'resetFactDefault', {}, utils.getOptions(meta.mapped, entity));
|
|
62
62
|
},
|
|
63
63
|
},
|
|
64
|
+
identify: {
|
|
65
|
+
key: ['identify'],
|
|
66
|
+
convertSet: async (entity, key, value, meta) => {
|
|
67
|
+
await entity.command('genIdentify', 'identify', {identifytime: value}, utils.getOptions(meta.mapped, entity));
|
|
68
|
+
},
|
|
69
|
+
},
|
|
64
70
|
arm_mode: {
|
|
65
71
|
key: ['arm_mode'],
|
|
66
72
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -6485,6 +6491,58 @@ const converters = {
|
|
|
6485
6491
|
}
|
|
6486
6492
|
},
|
|
6487
6493
|
},
|
|
6494
|
+
wiser_fip_setting: {
|
|
6495
|
+
key: ['fip_setting'],
|
|
6496
|
+
convertSet: async (entity, key, value, meta) => {
|
|
6497
|
+
const zoneLookup = {'manual': 1, 'schedule': 2, 'energy_saver': 3, 'holiday': 6};
|
|
6498
|
+
const zonemodeNum = zoneLookup[meta.state.zone_mode];
|
|
6499
|
+
|
|
6500
|
+
const fipLookup = {'comfort': 0, 'comfort_-1': 1, 'comfort_-2': 2, 'energy_saving': 3,
|
|
6501
|
+
'frost_protection': 4, 'off': 5};
|
|
6502
|
+
value = value.toLowerCase();
|
|
6503
|
+
utils.validateValue(value, Object.keys(fipLookup));
|
|
6504
|
+
const fipmodeNum = fipLookup[value];
|
|
6505
|
+
|
|
6506
|
+
const payload = {
|
|
6507
|
+
zonemode: zonemodeNum,
|
|
6508
|
+
fipmode: fipmodeNum,
|
|
6509
|
+
reserved: 0xff,
|
|
6510
|
+
};
|
|
6511
|
+
await entity.command('hvacThermostat', 'wiserSmartSetFipMode', payload,
|
|
6512
|
+
{srcEndpoint: 11, disableDefaultResponse: true});
|
|
6513
|
+
|
|
6514
|
+
return {state: {'fip_setting': value}};
|
|
6515
|
+
},
|
|
6516
|
+
convertGet: async (entity, key, meta) => {
|
|
6517
|
+
await entity.read('hvacThermostat', [0xe020]);
|
|
6518
|
+
},
|
|
6519
|
+
},
|
|
6520
|
+
wiser_hact_config: {
|
|
6521
|
+
key: ['hact_config'],
|
|
6522
|
+
convertSet: async (entity, key, value, meta) => {
|
|
6523
|
+
const lookup = {'unconfigured': 0x00, 'setpoint_switch': 0x80, 'setpoint_fip': 0x82, 'fip_fip': 0x83};
|
|
6524
|
+
value = value.toLowerCase();
|
|
6525
|
+
utils.validateValue(value, Object.keys(lookup));
|
|
6526
|
+
const mode = lookup[value];
|
|
6527
|
+
await entity.write('hvacThermostat', {0xe011: {value: mode, type: 0x18}});
|
|
6528
|
+
return {state: {'hact_config': value}};
|
|
6529
|
+
},
|
|
6530
|
+
convertGet: async (entity, key, meta) => {
|
|
6531
|
+
await entity.read('hvacThermostat', [0xe011]);
|
|
6532
|
+
},
|
|
6533
|
+
},
|
|
6534
|
+
wiser_zone_mode: {
|
|
6535
|
+
key: ['zone_mode'],
|
|
6536
|
+
convertSet: async (entity, key, value, meta) => {
|
|
6537
|
+
const lookup = {'manual': 1, 'schedule': 2, 'energy_saver': 3, 'holiday': 6};
|
|
6538
|
+
const zonemodeNum = lookup[value];
|
|
6539
|
+
await entity.write('hvacThermostat', {0xe010: {value: zonemodeNum, type: 0x30}});
|
|
6540
|
+
return {state: {'zone_mode': value}};
|
|
6541
|
+
},
|
|
6542
|
+
convertGet: async (entity, key, meta) => {
|
|
6543
|
+
await entity.read('hvacThermostat', [0xe010]);
|
|
6544
|
+
},
|
|
6545
|
+
},
|
|
6488
6546
|
wiser_vact_calibrate_valve: {
|
|
6489
6547
|
key: ['calibrate_valve'],
|
|
6490
6548
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -6607,30 +6665,6 @@ const converters = {
|
|
|
6607
6665
|
}
|
|
6608
6666
|
},
|
|
6609
6667
|
},
|
|
6610
|
-
tuya_radar_sensor_fall: {
|
|
6611
|
-
key: ['radar_scene', 'radar_sensitivity', 'tumble_alarm_time', 'tumble_switch', 'fall_sensitivity'],
|
|
6612
|
-
convertSet: async (entity, key, value, meta) => {
|
|
6613
|
-
switch (key) {
|
|
6614
|
-
case 'radar_scene':
|
|
6615
|
-
await tuya.sendDataPointEnum(entity, tuya.dataPoints.trsfScene, utils.getKey(tuya.tuyaRadar.radarScene, value));
|
|
6616
|
-
break;
|
|
6617
|
-
case 'radar_sensitivity':
|
|
6618
|
-
await tuya.sendDataPointValue(entity, tuya.dataPoints.trsfSensitivity, value);
|
|
6619
|
-
break;
|
|
6620
|
-
case 'tumble_switch':
|
|
6621
|
-
await tuya.sendDataPointEnum(entity, tuya.dataPoints.trsfTumbleSwitch, {'on': true, 'off': false}[value.toLowerCase()]);
|
|
6622
|
-
break;
|
|
6623
|
-
case 'tumble_alarm_time':
|
|
6624
|
-
await tuya.sendDataPointEnum(entity, tuya.dataPoints.trsfTumbleAlarmTime, value-1);
|
|
6625
|
-
break;
|
|
6626
|
-
case 'fall_sensitivity':
|
|
6627
|
-
await tuya.sendDataPointValue(entity, tuya.dataPoints.trsfFallSensitivity, value);
|
|
6628
|
-
break;
|
|
6629
|
-
default: // Unknown Key
|
|
6630
|
-
meta.logger.warn(`toZigbee.tuya_radar_sensor_fall: Unhandled Key ${key}`);
|
|
6631
|
-
}
|
|
6632
|
-
},
|
|
6633
|
-
},
|
|
6634
6668
|
javis_microwave_sensor: {
|
|
6635
6669
|
key: [
|
|
6636
6670
|
'illuminance_calibration', 'led_enable',
|
package/devices/alchemy.js
CHANGED
|
@@ -8,4 +8,11 @@ module.exports = [
|
|
|
8
8
|
description: 'Downlight with tuneable white',
|
|
9
9
|
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 370]}),
|
|
10
10
|
},
|
|
11
|
+
{
|
|
12
|
+
zigbeeModel: ['AL8RGB13W-AP'],
|
|
13
|
+
model: 'AL8RGB13W-AP',
|
|
14
|
+
vendor: 'Alchemy',
|
|
15
|
+
description: 'Downlight RGBW',
|
|
16
|
+
extend: extend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 370]}),
|
|
17
|
+
},
|
|
11
18
|
];
|
package/devices/bosch.js
CHANGED
|
@@ -5,6 +5,7 @@ const tz = require('../converters/toZigbee');
|
|
|
5
5
|
const reporting = require('../lib/reporting');
|
|
6
6
|
const utils = require('../lib/utils');
|
|
7
7
|
const constants = require('../lib/constants');
|
|
8
|
+
const ota = require('../lib/ota');
|
|
8
9
|
const e = exposes.presets;
|
|
9
10
|
const ea = exposes.access;
|
|
10
11
|
|
|
@@ -396,6 +397,7 @@ const definition = [
|
|
|
396
397
|
model: 'BTH-RA',
|
|
397
398
|
vendor: 'Bosch',
|
|
398
399
|
description: 'Radiator thermostat II',
|
|
400
|
+
ota: ota.zigbeeOTA,
|
|
399
401
|
fromZigbee: [fz.thermostat, fz.battery, fzLocal.bosch_thermostat, fzLocal.bosch_userInterface],
|
|
400
402
|
toZigbee: [
|
|
401
403
|
tz.thermostat_occupied_heating_setpoint,
|
package/devices/bticino.js
CHANGED
|
@@ -16,9 +16,10 @@ module.exports = [
|
|
|
16
16
|
toZigbee: [tz.on_off, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn, tz.legrand_identify],
|
|
17
17
|
exposes: [
|
|
18
18
|
e.switch(), e.action(['identify', 'on', 'off']),
|
|
19
|
-
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing
|
|
20
|
-
see the switch in the dark`),
|
|
19
|
+
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing ` +
|
|
20
|
+
`to see the switch in the dark`),
|
|
21
21
|
exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on'),
|
|
22
|
+
exposes.enum('identify', ea.SET, ['blink']).withDescription(`Blinks the built-in LED to make it easier to find the device`),
|
|
22
23
|
],
|
|
23
24
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
24
25
|
const endpoint = device.getEndpoint(1);
|
|
@@ -34,15 +35,18 @@ module.exports = [
|
|
|
34
35
|
fromZigbee: [fz.brightness, fz.identify, fz.on_off, fz.lighting_ballast_configuration, fz.legrand_cluster_fc01],
|
|
35
36
|
toZigbee: [tz.light_onoff_brightness, tz.legrand_settingEnableLedInDark, tz.legrand_settingEnableLedIfOn,
|
|
36
37
|
tz.legrand_deviceMode, tz.legrand_identify, tz.ballast_config],
|
|
37
|
-
exposes: [
|
|
38
|
+
exposes: [
|
|
39
|
+
e.light_brightness(),
|
|
38
40
|
exposes.numeric('ballast_minimum_level', ea.ALL).withValueMin(1).withValueMax(254)
|
|
39
41
|
.withDescription('Specifies the minimum brightness value'),
|
|
40
42
|
exposes.numeric('ballast_maximum_level', ea.ALL).withValueMin(1).withValueMax(254)
|
|
41
43
|
.withDescription('Specifies the maximum brightness value'),
|
|
42
44
|
exposes.binary('device_mode', ea.ALL, 'dimmer_on', 'dimmer_off').withDescription('Allow the device to change brightness'),
|
|
43
|
-
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing
|
|
44
|
-
see the switch in the dark`),
|
|
45
|
-
exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on')
|
|
45
|
+
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing ` +
|
|
46
|
+
`to see the switch in the dark`),
|
|
47
|
+
exposes.binary('led_if_on', ea.ALL, 'ON', 'OFF').withDescription('Enables the LED when the light is turned on'),
|
|
48
|
+
exposes.enum('identify', ea.SET, ['blink']).withDescription(`Blinks the built-in LED to make it easier to find the device`),
|
|
49
|
+
],
|
|
46
50
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
47
51
|
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
48
52
|
const endpoint = device.getEndpoint(1);
|
|
@@ -65,7 +69,12 @@ module.exports = [
|
|
|
65
69
|
fz.cover_position_tilt],
|
|
66
70
|
toZigbee: [tz.bticino_4027C_cover_state, tz.bticino_4027C_cover_position, tz.legrand_identify,
|
|
67
71
|
tz.legrand_settingEnableLedInDark],
|
|
68
|
-
exposes: [
|
|
72
|
+
exposes: [
|
|
73
|
+
e.cover_position(), e.action(['moving', 'identify', '']),
|
|
74
|
+
exposes.binary('led_in_dark', ea.ALL, 'ON', 'OFF').withDescription(`Enables the LED when the light is turned off, allowing ` +
|
|
75
|
+
`to see the switch in the dark`),
|
|
76
|
+
exposes.enum('identify', ea.SET, ['blink']).withDescription(`Blinks the built-in LED to make it easier to find the device`),
|
|
77
|
+
],
|
|
69
78
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
70
79
|
const endpoint = device.getEndpoint(1);
|
|
71
80
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genBinaryInput', 'closuresWindowCovering', 'genIdentify']);
|
package/devices/legrand.js
CHANGED
|
@@ -311,9 +311,15 @@ module.exports = [
|
|
|
311
311
|
await reporting.bind(endpoint, coordinatorEndpoint, ['haElectricalMeasurement', 'genIdentify']);
|
|
312
312
|
await reporting.readEletricalMeasurementMultiplierDivisors(endpoint);
|
|
313
313
|
await reporting.activePower(endpoint);
|
|
314
|
-
await
|
|
315
|
-
|
|
316
|
-
|
|
314
|
+
await endpoint.read('haElectricalMeasurement', ['activePower']);
|
|
315
|
+
try {
|
|
316
|
+
await reporting.apparentPower(endpoint);
|
|
317
|
+
await endpoint.read('haElectricalMeasurement', ['apparentPower']);
|
|
318
|
+
} catch (e) {
|
|
319
|
+
// Some version/firmware don't seem to support this.
|
|
320
|
+
}
|
|
321
|
+
// Read configuration values that are not sent periodically.
|
|
322
|
+
await endpoint.read('haElectricalMeasurement', [0xf000, 0xf001, 0xf002]);
|
|
317
323
|
},
|
|
318
324
|
onEvent: async (type, data, device, options, state) => {
|
|
319
325
|
/**
|
package/devices/mercator.js
CHANGED
|
@@ -3,6 +3,7 @@ const fz = require('../converters/fromZigbee');
|
|
|
3
3
|
const tz = require('../converters/toZigbee');
|
|
4
4
|
const reporting = require('../lib/reporting');
|
|
5
5
|
const tuya = require('../lib/tuya');
|
|
6
|
+
const extend = require('../lib/extend');
|
|
6
7
|
const e = exposes.presets;
|
|
7
8
|
const ea = exposes.access;
|
|
8
9
|
|
|
@@ -30,7 +31,97 @@ module.exports = [
|
|
|
30
31
|
},
|
|
31
32
|
},
|
|
32
33
|
{
|
|
33
|
-
fingerprint:
|
|
34
|
+
fingerprint: [{modelID: 'TS0202', manufacturerName: '_TYZB01_qjqgmqxr'}],
|
|
35
|
+
model: 'SMA02P',
|
|
36
|
+
vendor: 'Mercator',
|
|
37
|
+
description: 'Ikuü battery motion sensor',
|
|
38
|
+
fromZigbee: [fz.ias_occupancy_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_occupancy_alarm_1_report],
|
|
39
|
+
toZigbee: [],
|
|
40
|
+
exposes: [e.occupancy(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
|
|
41
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
42
|
+
const endpoint = device.getEndpoint(1);
|
|
43
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
44
|
+
try {
|
|
45
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
46
|
+
} catch (error) {/* Fails for some https://github.com/Koenkk/zigbee2mqtt/issues/13708*/}
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
fingerprint: [{modelID: 'TS0201', manufacturerName: '_TZ3000_82ptnsd4'}],
|
|
51
|
+
model: 'SMA03P',
|
|
52
|
+
vendor: 'Mercator',
|
|
53
|
+
description: 'Ikuü temperature & humidity sensor',
|
|
54
|
+
fromZigbee: [fz.battery, fz.temperature, fz.humidity],
|
|
55
|
+
toZigbee: [],
|
|
56
|
+
exposes: [e.battery(), e.temperature(), e.humidity(), e.battery_voltage()],
|
|
57
|
+
configure: tuya.configureMagicPacket,
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
fingerprint: [{modelID: 'TS0203', manufacturerName: '_TZ3000_wbrlnkm9'}],
|
|
61
|
+
model: 'SMA04P',
|
|
62
|
+
vendor: 'Mercator',
|
|
63
|
+
description: 'Ikuü battery contact sensor',
|
|
64
|
+
fromZigbee: [fz.ias_contact_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_contact_alarm_1_report],
|
|
65
|
+
toZigbee: [],
|
|
66
|
+
exposes: [e.contact(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
|
|
67
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
68
|
+
try {
|
|
69
|
+
const endpoint = device.getEndpoint(1);
|
|
70
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
71
|
+
await reporting.batteryPercentageRemaining(endpoint);
|
|
72
|
+
await reporting.batteryVoltage(endpoint);
|
|
73
|
+
} catch (error) {/* Fails for some*/}
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
fingerprint: [{modelID: 'TS0502B', manufacturerName: '_TZ3000_6dwfra5l'}],
|
|
78
|
+
model: 'SMCL01-ZB',
|
|
79
|
+
vendor: 'Mercator',
|
|
80
|
+
description: 'Ikuü Ikon ceiling light CCT',
|
|
81
|
+
extend: extend.light_onoff_brightness_colortemp({colorTempRange: [153, 500], disablePowerOnBehavior: true}),
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
fingerprint: [{modelID: 'TS0505B', manufacturerName: '_TZ3000_xr5m6kfg'}],
|
|
85
|
+
model: 'SMD4109W-RGB-ZB',
|
|
86
|
+
vendor: 'Mercator',
|
|
87
|
+
description: 'Ikuü Walter downlight RGB + CCT',
|
|
88
|
+
extend: extend.light_onoff_brightness_colortemp_color(
|
|
89
|
+
{colorTempRange: [153, 500], disableColorTempStartup: true, disablePowerOnBehavior: true}),
|
|
90
|
+
meta: {applyRedFix: true, enhancedHue: false},
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3210_raqjcxo5'}],
|
|
94
|
+
model: 'SPP02G',
|
|
95
|
+
vendor: 'Mercator',
|
|
96
|
+
description: 'Ikuü double indoors power point',
|
|
97
|
+
extend: tuya.extend.switch({powerOutageMemory: true, electricalMeasurements: true, endpoints: ['left', 'right']}),
|
|
98
|
+
exposes: [e.switch().withEndpoint('left'), e.switch().withEndpoint('right'),
|
|
99
|
+
e.power().withEndpoint('left'), e.current().withEndpoint('left'),
|
|
100
|
+
e.voltage().withEndpoint('left').withAccess(ea.STATE), e.energy()],
|
|
101
|
+
endpoint: (device) => {
|
|
102
|
+
return {left: 1, right: 2};
|
|
103
|
+
},
|
|
104
|
+
meta: {multiEndpoint: true},
|
|
105
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
106
|
+
const endpoint1 = device.getEndpoint(1);
|
|
107
|
+
const endpoint2 = device.getEndpoint(2);
|
|
108
|
+
await reporting.bind(endpoint1, coordinatorEndpoint, ['genBasic', 'genOnOff', 'haElectricalMeasurement', 'seMetering']);
|
|
109
|
+
await reporting.bind(endpoint2, coordinatorEndpoint, ['genOnOff']);
|
|
110
|
+
await reporting.onOff(endpoint1);
|
|
111
|
+
await reporting.onOff(endpoint1);
|
|
112
|
+
await reporting.onOff(endpoint1);
|
|
113
|
+
await reporting.rmsVoltage(endpoint1, {change: 5});
|
|
114
|
+
await reporting.rmsCurrent(endpoint1, {change: 50});
|
|
115
|
+
await reporting.activePower(endpoint1, {change: 1});
|
|
116
|
+
await reporting.onOff(endpoint1);
|
|
117
|
+
await reporting.onOff(endpoint2);
|
|
118
|
+
endpoint1.saveClusterAttributeKeyValue('haElectricalMeasurement', {acCurrentDivisor: 1000, acCurrentMultiplier: 1});
|
|
119
|
+
endpoint1.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
|
|
120
|
+
device.save();
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
fingerprint: [{modelID: 'TS011F', manufacturerName: '_TZ3210_7jnk7l3k'}],
|
|
34
125
|
model: 'SPP02GIP',
|
|
35
126
|
vendor: 'Mercator',
|
|
36
127
|
description: 'Ikuü double outdoors power point',
|
|
@@ -60,11 +151,31 @@ module.exports = [
|
|
|
60
151
|
device.save();
|
|
61
152
|
},
|
|
62
153
|
},
|
|
154
|
+
{
|
|
155
|
+
fingerprint: [{modelID: 'TS0013', manufacturerName: '_TZ3000_khtlvdfc'}],
|
|
156
|
+
model: 'SSW03G',
|
|
157
|
+
vendor: 'Mercator',
|
|
158
|
+
description: 'Ikuü triple switch',
|
|
159
|
+
extend: tuya.extend.switch({backlightModeLowMediumHigh: true, endpoints: ['left', 'center', 'right']}),
|
|
160
|
+
endpoint: (device) => {
|
|
161
|
+
return {'left': 1, 'center': 2, 'right': 3};
|
|
162
|
+
},
|
|
163
|
+
meta: {multiEndpoint: true},
|
|
164
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
165
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
166
|
+
for (const ID of [1, 2, 3]) {
|
|
167
|
+
const endpoint = device.getEndpoint(ID);
|
|
168
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
169
|
+
}
|
|
170
|
+
device.powerSource = 'Mains (single phase)';
|
|
171
|
+
device.save();
|
|
172
|
+
},
|
|
173
|
+
},
|
|
63
174
|
{
|
|
64
175
|
fingerprint: [{modelID: 'TS0501', manufacturerName: '_TZ3210_lzqq3u4r'},
|
|
65
176
|
{modelID: 'TS0501', manufacturerName: '_TZ3210_4whigl8i'}],
|
|
66
177
|
model: 'SSWF01G',
|
|
67
|
-
description: 'AC fan controller',
|
|
178
|
+
description: 'Ikuü AC fan controller',
|
|
68
179
|
vendor: 'Mercator',
|
|
69
180
|
fromZigbee: [fz.on_off, fz.fan],
|
|
70
181
|
toZigbee: [tz.fan_mode, tz.on_off],
|
package/devices/moes.js
CHANGED
|
@@ -97,6 +97,7 @@ module.exports = [
|
|
|
97
97
|
{
|
|
98
98
|
fingerprint: [{modelID: 'TS0601', manufacturerName: '_TZE200_aoclfnxz'},
|
|
99
99
|
{modelID: 'TS0601', manufacturerName: '_TZE200_ztvwu4nk'},
|
|
100
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_5toc8efa'},
|
|
100
101
|
{modelID: 'TS0601', manufacturerName: '_TZE200_ye5jkfsb'},
|
|
101
102
|
{modelID: 'TS0601', manufacturerName: '_TZE200_u9bfwha0'}],
|
|
102
103
|
model: 'BHT-002-GCLZB',
|
package/devices/niko.js
CHANGED
|
@@ -36,6 +36,20 @@ const local = {
|
|
|
36
36
|
return state;
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
|
+
switch_status_led: {
|
|
40
|
+
cluster: 'manuSpecificNiko1',
|
|
41
|
+
type: ['attributeReport', 'readResponse'],
|
|
42
|
+
convert: (model, msg, publish, options, meta) => {
|
|
43
|
+
const state = {};
|
|
44
|
+
if (msg.data.hasOwnProperty('outletLedState')) {
|
|
45
|
+
state['led_enable'] = (msg.data['outletLedState'] == 1);
|
|
46
|
+
}
|
|
47
|
+
if (msg.data.hasOwnProperty('outletLedColor')) {
|
|
48
|
+
state['led_state'] = (msg.data['outletLedColor'] == 255 ? 'ON' : 'OFF');
|
|
49
|
+
}
|
|
50
|
+
return state;
|
|
51
|
+
},
|
|
52
|
+
},
|
|
39
53
|
outlet: {
|
|
40
54
|
cluster: 'manuSpecificNiko1',
|
|
41
55
|
type: ['attributeReport', 'readResponse'],
|
|
@@ -69,6 +83,27 @@ const local = {
|
|
|
69
83
|
await entity.read('manuSpecificNiko1', ['switchOperationMode']);
|
|
70
84
|
},
|
|
71
85
|
},
|
|
86
|
+
switch_led_enable: {
|
|
87
|
+
key: ['led_enable'],
|
|
88
|
+
convertSet: async (entity, key, value, meta) => {
|
|
89
|
+
await entity.write('manuSpecificNiko1', {'outletLedState': ((value) ? 1 : 0)});
|
|
90
|
+
await entity.read('manuSpecificNiko1', ['outletLedColor']);
|
|
91
|
+
return {state: {led_enable: ((value) ? true : false)}};
|
|
92
|
+
},
|
|
93
|
+
convertGet: async (entity, key, meta) => {
|
|
94
|
+
await entity.read('manuSpecificNiko1', ['outletLedState']);
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
switch_led_state: {
|
|
98
|
+
key: ['led_state'],
|
|
99
|
+
convertSet: async (entity, key, value, meta) => {
|
|
100
|
+
await entity.write('manuSpecificNiko1', {'outletLedColor': ((value.toLowerCase() === 'off') ? 0 : 255)});
|
|
101
|
+
return {state: {led_state: ((value.toLowerCase() === 'off') ? 'OFF' : 'ON')}};
|
|
102
|
+
},
|
|
103
|
+
convertGet: async (entity, key, meta) => {
|
|
104
|
+
await entity.read('manuSpecificNiko1', ['outletLedColor']);
|
|
105
|
+
},
|
|
106
|
+
},
|
|
72
107
|
outlet_child_lock: {
|
|
73
108
|
key: ['child_lock'],
|
|
74
109
|
convertSet: async (entity, key, value, meta) => {
|
|
@@ -198,18 +233,20 @@ module.exports = [
|
|
|
198
233
|
model: '552-721X1',
|
|
199
234
|
vendor: 'Niko',
|
|
200
235
|
description: 'Single connectable switch',
|
|
201
|
-
fromZigbee: [fz.on_off, local.fz.switch_operation_mode, local.fz.switch_action],
|
|
202
|
-
toZigbee: [tz.on_off, local.tz.switch_operation_mode],
|
|
236
|
+
fromZigbee: [fz.on_off, local.fz.switch_operation_mode, local.fz.switch_action, local.fz.switch_status_led],
|
|
237
|
+
toZigbee: [tz.on_off, local.tz.switch_operation_mode, local.tz.switch_led_enable, local.tz.switch_led_state],
|
|
203
238
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
204
239
|
const endpoint = device.getEndpoint(1);
|
|
205
240
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
206
241
|
await reporting.onOff(endpoint);
|
|
207
|
-
await endpoint.read('manuSpecificNiko1', ['switchOperationMode']);
|
|
242
|
+
await endpoint.read('manuSpecificNiko1', ['switchOperationMode', 'outletLedState', 'outletLedColor']);
|
|
208
243
|
},
|
|
209
244
|
exposes: [
|
|
210
245
|
e.switch(),
|
|
211
246
|
e.action(['single', 'hold', 'release']),
|
|
212
247
|
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']),
|
|
248
|
+
exposes.binary('led_enable', ea.ALL, true, false).withDescription('Enable LED'),
|
|
249
|
+
exposes.binary('led_state', ea.ALL, 'ON', 'OFF').withDescription('LED State'),
|
|
213
250
|
],
|
|
214
251
|
},
|
|
215
252
|
{
|
|
@@ -217,8 +254,8 @@ module.exports = [
|
|
|
217
254
|
model: '552-721X2',
|
|
218
255
|
vendor: 'Niko',
|
|
219
256
|
description: 'Double connectable switch',
|
|
220
|
-
fromZigbee: [fz.on_off, local.fz.switch_operation_mode, local.fz.switch_action],
|
|
221
|
-
toZigbee: [tz.on_off, local.tz.switch_operation_mode],
|
|
257
|
+
fromZigbee: [fz.on_off, local.fz.switch_operation_mode, local.fz.switch_action, local.fz.switch_status_led],
|
|
258
|
+
toZigbee: [tz.on_off, local.tz.switch_operation_mode, local.tz.switch_led_enable, local.tz.switch_led_state],
|
|
222
259
|
endpoint: (device) => {
|
|
223
260
|
return {'l1': 1, 'l2': 2};
|
|
224
261
|
},
|
|
@@ -230,8 +267,8 @@ module.exports = [
|
|
|
230
267
|
await reporting.bind(ep2, coordinatorEndpoint, ['genOnOff']);
|
|
231
268
|
await reporting.onOff(ep1);
|
|
232
269
|
await reporting.onOff(ep2);
|
|
233
|
-
await ep1.read('manuSpecificNiko1', ['switchOperationMode']);
|
|
234
|
-
await ep2.read('manuSpecificNiko1', ['switchOperationMode']);
|
|
270
|
+
await ep1.read('manuSpecificNiko1', ['switchOperationMode', 'outletLedState', 'outletLedColor']);
|
|
271
|
+
await ep2.read('manuSpecificNiko1', ['switchOperationMode', 'outletLedState', 'outletLedColor']);
|
|
235
272
|
},
|
|
236
273
|
exposes: [
|
|
237
274
|
e.switch().withEndpoint('l1'), e.switch().withEndpoint('l2'),
|
|
@@ -239,6 +276,10 @@ module.exports = [
|
|
|
239
276
|
e.action(['single', 'hold', 'release']).withEndpoint('l2'),
|
|
240
277
|
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']).withEndpoint('l1'),
|
|
241
278
|
exposes.enum('operation_mode', ea.ALL, ['control_relay', 'decoupled']).withEndpoint('l2'),
|
|
279
|
+
exposes.binary('led_enable', ea.ALL, true, false).withEndpoint('l1').withDescription('Enable LED'),
|
|
280
|
+
exposes.binary('led_enable', ea.ALL, true, false).withEndpoint('l2').withDescription('Enable LED'),
|
|
281
|
+
exposes.binary('led_state', ea.ALL, 'ON', 'OFF').withEndpoint('l1').withDescription('LED State'),
|
|
282
|
+
exposes.binary('led_state', ea.ALL, 'ON', 'OFF').withEndpoint('l2').withDescription('LED State'),
|
|
242
283
|
],
|
|
243
284
|
},
|
|
244
285
|
{
|
package/devices/osram.js
CHANGED
|
@@ -205,7 +205,7 @@ module.exports = [
|
|
|
205
205
|
model: 'AB3257001NJ',
|
|
206
206
|
description: 'Smart+ plug',
|
|
207
207
|
vendor: 'OSRAM',
|
|
208
|
-
extend: extend.switch(),
|
|
208
|
+
extend: extend.switch({disablePowerOnBehavior: true}),
|
|
209
209
|
whiteLabel: [{vendor: 'LEDVANCE', model: 'AB3257001NJ'}, {vendor: 'LEDVANCE', model: 'AC03360'}],
|
|
210
210
|
ota: ota.ledvance,
|
|
211
211
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
@@ -226,7 +226,7 @@ module.exports = [
|
|
|
226
226
|
model: 'AC10691',
|
|
227
227
|
description: 'Smart+ plug',
|
|
228
228
|
vendor: 'OSRAM',
|
|
229
|
-
extend: extend.switch(),
|
|
229
|
+
extend: extend.switch({disablePowerOnBehavior: true}),
|
|
230
230
|
ota: ota.ledvance,
|
|
231
231
|
whiteLabel: [{vendor: 'LEDVANCE', model: 'AC10691'}],
|
|
232
232
|
configure: async (device, coordinatorEndpoint, logger) => {
|
package/devices/owon.js
CHANGED
|
@@ -149,8 +149,13 @@ module.exports = [
|
|
|
149
149
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
150
150
|
const endpoint2 = device.getEndpoint(2);
|
|
151
151
|
const endpoint3 = device.getEndpoint(3);
|
|
152
|
-
|
|
153
|
-
|
|
152
|
+
if (device.modelID == 'PIR313') {
|
|
153
|
+
await reporting.bind(endpoint2, coordinatorEndpoint, ['msIlluminanceMeasurement']);
|
|
154
|
+
await reporting.bind(endpoint3, coordinatorEndpoint, ['msTemperatureMeasurement', 'msRelativeHumidity']);
|
|
155
|
+
} else {
|
|
156
|
+
await reporting.bind(endpoint3, coordinatorEndpoint, ['msIlluminanceMeasurement']);
|
|
157
|
+
await reporting.bind(endpoint2, coordinatorEndpoint, ['msTemperatureMeasurement', 'msRelativeHumidity']);
|
|
158
|
+
}
|
|
154
159
|
device.powerSource = 'Battery';
|
|
155
160
|
device.save();
|
|
156
161
|
},
|
package/devices/philips.js
CHANGED
|
@@ -1561,7 +1561,7 @@ module.exports = [
|
|
|
1561
1561
|
model: '4090230P9',
|
|
1562
1562
|
vendor: 'Philips',
|
|
1563
1563
|
description: 'Hue Liane (black)',
|
|
1564
|
-
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
1564
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500], disableHueEffects: false}),
|
|
1565
1565
|
},
|
|
1566
1566
|
{
|
|
1567
1567
|
zigbeeModel: ['929003053201'],
|
|
@@ -1589,14 +1589,14 @@ module.exports = [
|
|
|
1589
1589
|
model: '3261030P6',
|
|
1590
1590
|
vendor: 'Philips',
|
|
1591
1591
|
description: 'Hue Being black',
|
|
1592
|
-
extend: hueExtend.light_onoff_brightness_colortemp(),
|
|
1592
|
+
extend: hueExtend.light_onoff_brightness_colortemp({disableHueEffects: false}),
|
|
1593
1593
|
},
|
|
1594
1594
|
{
|
|
1595
1595
|
zigbeeModel: ['3261031P6', '929003055001', '929003055101'],
|
|
1596
1596
|
model: '3261031P6',
|
|
1597
1597
|
vendor: 'Philips',
|
|
1598
1598
|
description: 'Hue Being white',
|
|
1599
|
-
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
1599
|
+
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454], disableHueEffects: false}),
|
|
1600
1600
|
},
|
|
1601
1601
|
{
|
|
1602
1602
|
zigbeeModel: ['3261048P6'],
|
|
@@ -2560,7 +2560,7 @@ module.exports = [
|
|
|
2560
2560
|
model: '1741530P7',
|
|
2561
2561
|
vendor: 'Philips',
|
|
2562
2562
|
description: 'Hue Lily outdoor spot light',
|
|
2563
|
-
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
2563
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500], disableHueEffects: false}),
|
|
2564
2564
|
},
|
|
2565
2565
|
{
|
|
2566
2566
|
zigbeeModel: ['1741730V7'],
|
package/devices/samotech.js
CHANGED
|
@@ -51,7 +51,7 @@ module.exports = [
|
|
|
51
51
|
},
|
|
52
52
|
},
|
|
53
53
|
{
|
|
54
|
-
fingerprint: [{modelID: 'Dimmer-Switch-ZB3.0', manufacturerName: 'Samotech'}],
|
|
54
|
+
fingerprint: [{modelID: 'Dimmer-Switch-ZB3.0', manufacturerName: 'Samotech'}, {modelID: 'HK_DIM_A', manufacturerName: 'Samotech'}],
|
|
55
55
|
model: 'SM323',
|
|
56
56
|
vendor: 'Samotech',
|
|
57
57
|
description: 'ZigBee retrofit dimmer 250W',
|
|
@@ -766,14 +766,28 @@ module.exports = [
|
|
|
766
766
|
model: 'EER50000',
|
|
767
767
|
vendor: 'Schneider Electric',
|
|
768
768
|
description: 'Wiser H-Relay (HACT)',
|
|
769
|
-
fromZigbee: [fz.ignore_basic_report, fz.ignore_genOta, fz.ignore_zclversion_read, fz.wiser_smart_thermostat
|
|
770
|
-
|
|
771
|
-
|
|
769
|
+
fromZigbee: [fz.ignore_basic_report, fz.ignore_genOta, fz.ignore_zclversion_read, fz.wiser_smart_thermostat, fz.metering,
|
|
770
|
+
fz.identify],
|
|
771
|
+
toZigbee: [tz.thermostat_local_temperature, tz.thermostat_occupied_heating_setpoint, tz.wiser_fip_setting,
|
|
772
|
+
tz.wiser_hact_config, tz.wiser_zone_mode, tz.identify],
|
|
773
|
+
exposes: [exposes.climate().withSetpoint('occupied_heating_setpoint', 7, 30, 0.5).withLocalTemperature(),
|
|
774
|
+
e.power(), e.energy(),
|
|
775
|
+
exposes.enum('identify', ea.SET, ['0', '30', '60', '600', '900']).withDescription('Flash green tag for x seconds'),
|
|
776
|
+
exposes.enum('zone_mode',
|
|
777
|
+
ea.ALL, ['manual', 'schedule', 'energy_saver', 'holiday']),
|
|
778
|
+
exposes.enum('hact_config',
|
|
779
|
+
ea.ALL, ['unconfigured', 'setpoint_switch', 'setpoint_fip', 'fip_fip'])
|
|
780
|
+
.withDescription('Input (command) and output (control) behavior of actuator'),
|
|
781
|
+
exposes.enum('fip_setting',
|
|
782
|
+
ea.ALL, ['comfort', 'comfort_-1', 'comfort_-2', 'energy_saving', 'frost_protection', 'off'])
|
|
783
|
+
.withDescription('Output signal when operating in fil pilote mode (fip_fip)')],
|
|
772
784
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
773
785
|
const endpoint = device.getEndpoint(11);
|
|
774
|
-
const binds = ['genBasic', 'genPowerCfg', 'hvacThermostat', 'msTemperatureMeasurement'];
|
|
786
|
+
const binds = ['genBasic', 'genPowerCfg', 'hvacThermostat', 'msTemperatureMeasurement', 'seMetering'];
|
|
775
787
|
await reporting.bind(endpoint, coordinatorEndpoint, binds);
|
|
776
788
|
await reporting.thermostatOccupiedHeatingSetpoint(endpoint);
|
|
789
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
790
|
+
await reporting.instantaneousDemand(endpoint);
|
|
777
791
|
},
|
|
778
792
|
},
|
|
779
793
|
{
|
package/devices/sonoff.js
CHANGED
|
@@ -78,7 +78,7 @@ module.exports = [
|
|
|
78
78
|
model: 'ZBMINI',
|
|
79
79
|
vendor: 'SONOFF',
|
|
80
80
|
description: 'Zigbee two way smart switch',
|
|
81
|
-
extend: extend.switch(),
|
|
81
|
+
extend: extend.switch({disablePowerOnBehavior: true}),
|
|
82
82
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
83
83
|
// Has Unknown power source: https://github.com/Koenkk/zigbee2mqtt/issues/5362, force it here.
|
|
84
84
|
device.powerSource = 'Mains (single phase)';
|
package/devices/sunricher.js
CHANGED
|
@@ -606,7 +606,7 @@ module.exports = [
|
|
|
606
606
|
},
|
|
607
607
|
},
|
|
608
608
|
{
|
|
609
|
-
fingerprint: [{modelID: 'TERNCY-DC01',
|
|
609
|
+
fingerprint: [{modelID: 'TERNCY-DC01', manufacturerName: 'Sunricher'}],
|
|
610
610
|
model: 'SR-ZG9010A',
|
|
611
611
|
vendor: 'Sunricher',
|
|
612
612
|
description: 'Door windows sensor',
|
package/devices/tuya.js
CHANGED
|
@@ -1084,7 +1084,6 @@ module.exports = [
|
|
|
1084
1084
|
{modelID: 'TS0202', manufacturerName: '_TYZB01_71kfvvma'},
|
|
1085
1085
|
{modelID: 'TS0202', manufacturerName: '_TZE200_bq5c8xfe'},
|
|
1086
1086
|
{modelID: 'TS0202', manufacturerName: '_TYZB01_dl7cejts'},
|
|
1087
|
-
{modelID: 'TS0202', manufacturerName: '_TYZB01_qjqgmqxr'},
|
|
1088
1087
|
{modelID: 'TS0202', manufacturerName: '_TZ3000_nss8amz9'},
|
|
1089
1088
|
{modelID: 'TS0202', manufacturerName: '_TZ3000_mmtwjmaq'},
|
|
1090
1089
|
{modelID: 'TS0202', manufacturerName: '_TYZB01_zwvaj5wy'},
|
|
@@ -1513,6 +1512,7 @@ module.exports = [
|
|
|
1513
1512
|
fingerprint: [
|
|
1514
1513
|
{modelID: 'TS0601', manufacturerName: '_TZE200_nkjintbl'},
|
|
1515
1514
|
{modelID: 'TS0601', manufacturerName: '_TZE200_ji1gn7rw'},
|
|
1515
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_3t91nb6k'},
|
|
1516
1516
|
],
|
|
1517
1517
|
model: 'TS0601_switch_2_gang',
|
|
1518
1518
|
vendor: 'TuYa',
|
|
@@ -2126,6 +2126,7 @@ module.exports = [
|
|
|
2126
2126
|
{modelID: 'TS0601', manufacturerName: '_TZE200_9sfg7gm0'}, // HomeCloud
|
|
2127
2127
|
{modelID: 'TS0601', manufacturerName: '_TZE200_2atgpdho'}, // HY367
|
|
2128
2128
|
{modelID: 'TS0601', manufacturerName: '_TZE200_cpmgn2cf'},
|
|
2129
|
+
{modelID: 'TS0601', manufacturerName: '_TZE200_8thwkzxl'}, // Tervix eva2
|
|
2129
2130
|
{modelID: 'TS0601', manufacturerName: '_TZE200_4eeyebrt'}, // Immax 07732B
|
|
2130
2131
|
{modelID: 'TS0601', manufacturerName: '_TZE200_8whxpsiw'}, // EVOLVEO
|
|
2131
2132
|
{modelID: 'TS0601', manufacturerName: '_TZE200_xby0s3ta'}, // Sandy Beach HY367
|
|
@@ -2539,14 +2540,14 @@ module.exports = [
|
|
|
2539
2540
|
},
|
|
2540
2541
|
},
|
|
2541
2542
|
{
|
|
2542
|
-
fingerprint: [160, 69, 68, 65, 64, 66].map((applicationVersion) => {
|
|
2543
|
+
fingerprint: [160, 100, 69, 68, 65, 64, 66].map((applicationVersion) => {
|
|
2543
2544
|
return {modelID: 'TS011F', applicationVersion, priority: -1};
|
|
2544
2545
|
}),
|
|
2545
2546
|
model: 'TS011F_plug_3',
|
|
2546
2547
|
description: 'Smart plug (with power monitoring by polling)',
|
|
2547
2548
|
vendor: 'TuYa',
|
|
2548
2549
|
whiteLabel: [{vendor: 'VIKEFON', model: 'TS011F'}, {vendor: 'BlitzWolf', model: 'BW-SHP15'},
|
|
2549
|
-
{vendor: 'Avatto', model: 'MIUCOT10Z'}, {vendor: 'Neo', model: 'NAS-WR01B'}],
|
|
2550
|
+
{vendor: 'Avatto', model: 'MIUCOT10Z'}, {vendor: 'Neo', model: 'NAS-WR01B'}, {vendor: 'Neo', model: 'PLUG-001SPB2'}],
|
|
2550
2551
|
ota: ota.zigbeeOTA,
|
|
2551
2552
|
extend: tuya.extend.switch({electricalMeasurements: true, powerOutageMemory: true, indicatorMode: true, childLock: true}),
|
|
2552
2553
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
@@ -2560,7 +2561,7 @@ module.exports = [
|
|
|
2560
2561
|
onEvent: (type, data, device, options) =>
|
|
2561
2562
|
tuya.onEventMeasurementPoll(type, data, device, options,
|
|
2562
2563
|
device.applicationVersion !== 66, // polling for voltage, current and power
|
|
2563
|
-
|
|
2564
|
+
[66, 100, 160].includes(device.applicationVersion), // polling for energy
|
|
2564
2565
|
),
|
|
2565
2566
|
},
|
|
2566
2567
|
{
|
|
@@ -3366,34 +3367,60 @@ module.exports = [
|
|
|
3366
3367
|
],
|
|
3367
3368
|
},
|
|
3368
3369
|
{
|
|
3369
|
-
fingerprint:
|
|
3370
|
-
{modelID: 'TS0601', manufacturerName: '_TZE200_vrfecyku'}],
|
|
3370
|
+
fingerprint: tuya.fingerprint('TS0601', ['_TZE200_lu01t0zl', '_TZE200_vrfecyku']),
|
|
3371
3371
|
model: 'MIR-HE200-TY',
|
|
3372
3372
|
vendor: 'TuYa',
|
|
3373
3373
|
description: 'Human presence sensor with fall function',
|
|
3374
|
-
fromZigbee: [fz.
|
|
3375
|
-
toZigbee: [tz.
|
|
3374
|
+
fromZigbee: [tuya.fz.datapoints],
|
|
3375
|
+
toZigbee: [tuya.tz.datapoints],
|
|
3376
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
3377
|
+
const endpoint = device.getEndpoint(1);
|
|
3378
|
+
await tuya.sendDataPointEnum(endpoint, tuya.dataPoints.trsfTumbleSwitch, false);
|
|
3379
|
+
await tuya.configureMagicPacket(device, coordinatorEndpoint, logger);
|
|
3380
|
+
},
|
|
3376
3381
|
exposes: [
|
|
3377
3382
|
e.illuminance_lux(), e.presence(), e.occupancy(),
|
|
3378
3383
|
exposes.numeric('motion_speed', ea.STATE).withDescription('Speed of movement'),
|
|
3379
|
-
exposes.enum('motion_direction', ea.STATE,
|
|
3384
|
+
exposes.enum('motion_direction', ea.STATE, ['standing_still', 'moving_forward', 'moving_backward'])
|
|
3380
3385
|
.withDescription('direction of movement from the point of view of the radar'),
|
|
3381
3386
|
exposes.numeric('radar_sensitivity', ea.STATE_SET).withValueMin(0).withValueMax(10).withValueStep(1)
|
|
3382
|
-
.withDescription('
|
|
3383
|
-
exposes.enum('radar_scene', ea.STATE_SET,
|
|
3384
|
-
.withDescription('
|
|
3387
|
+
.withDescription('Sensitivity of the radar'),
|
|
3388
|
+
exposes.enum('radar_scene', ea.STATE_SET, ['default', 'area', 'toilet', 'bedroom', 'parlour', 'office', 'hotel'])
|
|
3389
|
+
.withDescription('Presets for sensitivity for presence and movement'),
|
|
3385
3390
|
exposes.enum('tumble_switch', ea.STATE_SET, ['ON', 'OFF']).withDescription('Tumble status switch'),
|
|
3386
3391
|
exposes.numeric('fall_sensitivity', ea.STATE_SET).withValueMin(1).withValueMax(10).withValueStep(1)
|
|
3387
|
-
.withDescription('
|
|
3392
|
+
.withDescription('Fall sensitivity of the radar'),
|
|
3388
3393
|
exposes.numeric('tumble_alarm_time', ea.STATE_SET).withValueMin(1).withValueMax(5).withValueStep(1)
|
|
3389
|
-
.withUnit('min').withDescription('
|
|
3390
|
-
exposes.enum('fall_down_status', ea.STATE,
|
|
3391
|
-
.withDescription('
|
|
3392
|
-
exposes.text('static_dwell_alarm', ea.STATE).withDescription('
|
|
3394
|
+
.withUnit('min').withDescription('Tumble alarm time'),
|
|
3395
|
+
exposes.enum('fall_down_status', ea.STATE, ['none', 'maybe_fall', 'fall'])
|
|
3396
|
+
.withDescription('Fall down status'),
|
|
3397
|
+
exposes.text('static_dwell_alarm', ea.STATE).withDescription('Static dwell alarm'),
|
|
3393
3398
|
],
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3399
|
+
meta: {
|
|
3400
|
+
tuyaDatapoints: [
|
|
3401
|
+
[1, 'presence', tuya.valueConverter.trueFalse],
|
|
3402
|
+
[2, 'radar_sensitivity', tuya.valueConverter.raw],
|
|
3403
|
+
[102, 'occupancy', tuya.valueConverterBasic.lookup({false: 1, true: 2})],
|
|
3404
|
+
[103, 'illuminance_lux', tuya.valueConverter.raw],
|
|
3405
|
+
[105, 'tumble_switch', tuya.valueConverter.plus1],
|
|
3406
|
+
[106, 'tumble_alarm_time', tuya.valueConverter.raw],
|
|
3407
|
+
[112, 'radar_scene', tuya.valueConverterBasic.lookup(
|
|
3408
|
+
{'default': 0, 'area': 1, 'toilet': 2, 'bedroom': 3, 'parlour': 4, 'office': 5, 'hotel': 6})],
|
|
3409
|
+
[114, 'motion_direction', tuya.valueConverterBasic.lookup(
|
|
3410
|
+
{'standing_still': 0, 'moving_forward': 1, 'moving_backward': 2})],
|
|
3411
|
+
[115, 'motion_speed', tuya.valueConverter.raw],
|
|
3412
|
+
[116, 'fall_down_status', tuya.valueConverterBasic.lookup({'none': 0, 'maybe_fall': 1, 'fall': 2})],
|
|
3413
|
+
[117, 'static_dwell_alarm', tuya.valueConverter.raw],
|
|
3414
|
+
[118, 'fall_sensitivity', tuya.valueConverter.raw],
|
|
3415
|
+
// Below are ignored
|
|
3416
|
+
[101, null, null], // reset_flag_code
|
|
3417
|
+
[104, null, null], // detection_flag_code
|
|
3418
|
+
[107, null, null], // radar_check_end_code
|
|
3419
|
+
[108, null, null], // radar_check_start_code
|
|
3420
|
+
[109, null, null], // hw_version_code
|
|
3421
|
+
[110, null, null], // sw_version_code
|
|
3422
|
+
[111, null, null], // radar_id_code
|
|
3423
|
+
],
|
|
3397
3424
|
},
|
|
3398
3425
|
},
|
|
3399
3426
|
{
|
package/devices/ubisys.js
CHANGED
|
@@ -837,13 +837,17 @@ module.exports = [
|
|
|
837
837
|
fromZigbee: [fz.legacy.ubisys_c4_scenes, fz.legacy.ubisys_c4_onoff, fz.legacy.ubisys_c4_level, fz.legacy.ubisys_c4_cover,
|
|
838
838
|
ubisys.fz.configure_device_setup],
|
|
839
839
|
toZigbee: [ubisys.tz.configure_device_setup],
|
|
840
|
-
exposes: [
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
840
|
+
exposes: [
|
|
841
|
+
e.action([
|
|
842
|
+
'toggle_s1', 'toggle_s2', 'toggle_s3', 'toggle_s4', 'on_s1', 'on_s2', 'on_s3', 'on_s4',
|
|
843
|
+
'off_s1', 'off_s2', 'off_s3', 'off_s4', 'recall_*_s1', 'recal_*_s2', 'recall_*_s3', 'recal_*_s4',
|
|
844
|
+
'brightness_move_up_s1', 'brightness_move_up_s2', 'brightness_move_up_s3', 'brightness_move_up_s4',
|
|
845
|
+
'brightness_move_down_s1', 'brightness_move_down_s2', 'brightness_move_down_s3', 'brightness_move_down_s4',
|
|
846
|
+
'brightness_stop_s1', 'brightness_stop_s2', 'brightness_stop_s3', 'brightness_stop_s4',
|
|
847
|
+
'cover_open_s5', 'cover_close_s5', 'cover_stop_s5',
|
|
848
|
+
'cover_open_s6', 'cover_close_s6', 'cover_stop_s6',
|
|
849
|
+
]),
|
|
850
|
+
],
|
|
847
851
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
848
852
|
for (const ep of [1, 2, 3, 4]) {
|
|
849
853
|
await reporting.bind(device.getEndpoint(ep), coordinatorEndpoint, ['genScenes', 'genOnOff', 'genLevelCtrl']);
|
|
@@ -852,6 +856,10 @@ module.exports = [
|
|
|
852
856
|
await reporting.bind(device.getEndpoint(ep), coordinatorEndpoint, ['genScenes', 'closuresWindowCovering']);
|
|
853
857
|
}
|
|
854
858
|
},
|
|
859
|
+
meta: {multiEndpoint: true},
|
|
860
|
+
endpoint: (device) => {
|
|
861
|
+
return {'s1': 1, 's2': 2, 's3': 3, 's4': 4, 's5': 5, 's6': 6};
|
|
862
|
+
},
|
|
855
863
|
ota: ota.ubisys,
|
|
856
864
|
},
|
|
857
865
|
{
|
package/lib/ota/common.js
CHANGED
|
@@ -261,12 +261,9 @@ async function isNewImageAvailable(current, logger, device, getImageMeta) {
|
|
|
261
261
|
const [currentS, metaS] = [JSON.stringify(current), JSON.stringify(meta)];
|
|
262
262
|
logger.debug(`Is new image available for '${device.ieeeAddr}', current '${currentS}', latest meta '${metaS}'`);
|
|
263
263
|
|
|
264
|
-
|
|
265
|
-
return -1; // Negative number means the new firmware is 'newer' than current one
|
|
266
|
-
}
|
|
267
|
-
|
|
264
|
+
// Negative number means the new firmware is 'newer' than current one
|
|
268
265
|
return {
|
|
269
|
-
available: Math.sign(current.fileVersion - meta.fileVersion),
|
|
266
|
+
available: meta.force ? -1 : Math.sign(current.fileVersion - meta.fileVersion),
|
|
270
267
|
currentFileVersion: current.fileVersion,
|
|
271
268
|
otaFileVersion: meta.fileVersion,
|
|
272
269
|
};
|
package/lib/tuya.js
CHANGED
|
@@ -1246,7 +1246,7 @@ const valueConverterBasic = {
|
|
|
1246
1246
|
};
|
|
1247
1247
|
|
|
1248
1248
|
const valueConverter = {
|
|
1249
|
-
trueFalse: valueConverterBasic.lookup({
|
|
1249
|
+
trueFalse: valueConverterBasic.lookup({true: 1, false: 0}),
|
|
1250
1250
|
onOff: valueConverterBasic.lookup({'ON': true, 'OFF': false}),
|
|
1251
1251
|
powerOnBehavior: valueConverterBasic.lookup({'off': 0, 'on': 1, 'previous': 2}),
|
|
1252
1252
|
lightType: valueConverterBasic.lookup({'led': 0, 'incandescent': 1, 'halogen': 2}),
|
|
@@ -1259,6 +1259,10 @@ const valueConverter = {
|
|
|
1259
1259
|
divideBy10: valueConverterBasic.divideBy(10),
|
|
1260
1260
|
divideBy1000: valueConverterBasic.divideBy(1000),
|
|
1261
1261
|
raw: valueConverterBasic.raw(),
|
|
1262
|
+
plus1: {
|
|
1263
|
+
from: (v) => v + 1,
|
|
1264
|
+
to: (v) => v - 1,
|
|
1265
|
+
},
|
|
1262
1266
|
static: (value) => {
|
|
1263
1267
|
return {
|
|
1264
1268
|
from: (v) => {
|
|
@@ -1577,7 +1581,7 @@ const tuyaTz = {
|
|
|
1577
1581
|
'holiday_start_stop', 'holiday_temperature', 'comfort_temperature', 'eco_temperature', 'working_day',
|
|
1578
1582
|
'week_schedule_programming', 'online', 'holiday_mode_date', 'schedule', 'schedule_monday', 'schedule_tuesday',
|
|
1579
1583
|
'schedule_wednesday', 'schedule_thursday', 'schedule_friday', 'schedule_saturday', 'schedule_sunday', 'clear_fault',
|
|
1580
|
-
'scale_protection', 'error',
|
|
1584
|
+
'scale_protection', 'error', 'radar_scene', 'radar_sensitivity', 'tumble_alarm_time', 'tumble_switch', 'fall_sensitivity',
|
|
1581
1585
|
],
|
|
1582
1586
|
convertSet: async (entity, key, value, meta) => {
|
|
1583
1587
|
// A set converter is only called once; therefore we need to loop
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "15.0.
|
|
3
|
+
"version": "15.0.19",
|
|
4
4
|
"description": "Collection of device converters to be used with zigbee-herdsman",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"files": [
|
|
@@ -38,7 +38,7 @@
|
|
|
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.84"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"eslint": "*",
|