zigbee-herdsman-converters 14.0.458 → 14.0.461
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 +19 -24
- package/converters/toZigbee.js +48 -4
- package/devices/danfoss.js +32 -2
- package/devices/enocean.js +2 -1
- package/devices/keen_home.js +1 -1
- package/devices/niko.js +20 -7
- package/devices/orvibo.js +7 -0
- package/devices/philips.js +18 -0
- package/devices/spotmau.js +33 -0
- package/devices/tuya.js +33 -7
- package/devices/xiaomi.js +7 -5
- package/devices/xinghuoyuan.js +11 -0
- package/lib/constants.js +14 -0
- package/lib/xiaomi.js +13 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -3392,6 +3392,23 @@ const converters = {
|
|
|
3392
3392
|
if (msg.data.hasOwnProperty('danfossLoadEstimate')) {
|
|
3393
3393
|
result[postfixWithEndpointName('load_estimate', msg, model)] = msg.data['danfossLoadEstimate'];
|
|
3394
3394
|
}
|
|
3395
|
+
if (msg.data.hasOwnProperty('danfossPreheatStatus')) {
|
|
3396
|
+
result[postfixWithEndpointName('preheat_status', msg, model)] = (msg.data['danfossPreheatStatus'] === 1);
|
|
3397
|
+
}
|
|
3398
|
+
if (msg.data.hasOwnProperty('danfossAdaptionRunStatus')) {
|
|
3399
|
+
result[postfixWithEndpointName('adaptation_run_status', msg, model)] =
|
|
3400
|
+
constants.danfossAdaptionRunStatus[msg.data['danfossAdaptionRunStatus']];
|
|
3401
|
+
}
|
|
3402
|
+
if (msg.data.hasOwnProperty('danfossAdaptionRunSettings')) {
|
|
3403
|
+
result[postfixWithEndpointName('adaptation_run_settings', msg, model)] = (msg.data['danfossAdaptionRunSettings'] === 1);
|
|
3404
|
+
}
|
|
3405
|
+
if (msg.data.hasOwnProperty('danfossAdaptionRunControl')) {
|
|
3406
|
+
result[postfixWithEndpointName('adaptation_run_control', msg, model)] =
|
|
3407
|
+
constants.danfossAdaptionRunControl[msg.data['danfossAdaptionRunControl']];
|
|
3408
|
+
}
|
|
3409
|
+
if (msg.data.hasOwnProperty('danfossRegulationSetpointOffset')) {
|
|
3410
|
+
result[postfixWithEndpointName('regulation_setpoint_offset', msg, model)] = msg.data['danfossRegulationSetpointOffset'];
|
|
3411
|
+
}
|
|
3395
3412
|
// Danfoss Icon Converters
|
|
3396
3413
|
if (msg.data.hasOwnProperty('danfossRoomStatusCode')) {
|
|
3397
3414
|
result[postfixWithEndpointName('room_status_code', msg, model)] =
|
|
@@ -4806,6 +4823,7 @@ const converters = {
|
|
|
4806
4823
|
0x1e: 'press_1_and_4', 0x1f: 'release_1_and_4', 0x1c: 'press_2_and_3', 0x1d: 'release_2_and_3', 0x1a: 'press_2_and_4',
|
|
4807
4824
|
0x1b: 'release_2_and_4', 0x16: 'press_3_and_4', 0x17: 'release_3_and_4', 0x10: 'press_energy_bar',
|
|
4808
4825
|
0x11: 'release_energy_bar', 0x0: 'press_or_release_all',
|
|
4826
|
+
0x50: 'lock', 0x51: 'unlock', 0x52: 'half_open', 0x53: 'tilt',
|
|
4809
4827
|
};
|
|
4810
4828
|
|
|
4811
4829
|
if (!lookup.hasOwnProperty(commandID)) {
|
|
@@ -5662,38 +5680,15 @@ const converters = {
|
|
|
5662
5680
|
type: ['attributeReport', 'readResponse'],
|
|
5663
5681
|
options: [exposes.options.invert_cover()],
|
|
5664
5682
|
convert: (model, msg, publish, options, meta) => {
|
|
5665
|
-
let running = false;
|
|
5666
|
-
|
|
5667
5683
|
if (model.model === 'ZNCLDJ12LM' && msg.type === 'attributeReport' && [0, 2].includes(msg.data['presentValue'])) {
|
|
5668
5684
|
// Incorrect reports from the device, ignore (re-read by onEvent of ZNCLDJ12LM)
|
|
5669
5685
|
// https://github.com/Koenkk/zigbee-herdsman-converters/pull/1427#issuecomment-663862724
|
|
5670
5686
|
return;
|
|
5671
5687
|
}
|
|
5672
5688
|
|
|
5673
|
-
if (msg.data['61440']) {
|
|
5674
|
-
const value = msg.data['61440'];
|
|
5675
|
-
// 63025664 comes from https://github.com/Koenkk/zigbee2mqtt/issues/5155#issuecomment-753344248
|
|
5676
|
-
running = value !== 0 && value !== 63025664;
|
|
5677
|
-
}
|
|
5678
|
-
|
|
5679
5689
|
let position = precisionRound(msg.data['presentValue'], 2);
|
|
5680
5690
|
position = options.invert_cover ? 100 - position : position;
|
|
5681
|
-
return {position
|
|
5682
|
-
},
|
|
5683
|
-
},
|
|
5684
|
-
xiaomi_curtain_options: {
|
|
5685
|
-
cluster: 'genBasic',
|
|
5686
|
-
type: ['attributeReport', 'readResponse'],
|
|
5687
|
-
convert: (model, msg, publish, options, meta) => {
|
|
5688
|
-
const data = msg.data['1025'];
|
|
5689
|
-
if (data) {
|
|
5690
|
-
return {
|
|
5691
|
-
options: { // next values update only when curtain finished initial setup and knows current position
|
|
5692
|
-
reverse_direction: data[2]=='\u0001',
|
|
5693
|
-
hand_open: data[5]=='\u0000',
|
|
5694
|
-
},
|
|
5695
|
-
};
|
|
5696
|
-
}
|
|
5691
|
+
return {position};
|
|
5697
5692
|
},
|
|
5698
5693
|
},
|
|
5699
5694
|
xiaomi_curtain_acn002_position: {
|
package/converters/toZigbee.js
CHANGED
|
@@ -2446,10 +2446,7 @@ const converters = {
|
|
|
2446
2446
|
|
|
2447
2447
|
value = typeof value === 'string' ? value.toLowerCase() : value;
|
|
2448
2448
|
value = lookup.hasOwnProperty(value) ? lookup[value] : value;
|
|
2449
|
-
|
|
2450
|
-
if (key === 'position') {
|
|
2451
|
-
value = meta.options.invert_cover ? 100 - value : value;
|
|
2452
|
-
}
|
|
2449
|
+
value = meta.options.invert_cover ? 100 - value : value;
|
|
2453
2450
|
|
|
2454
2451
|
const payload = {0x0055: {value, type: 0x39}};
|
|
2455
2452
|
await entity.write('genAnalogOutput', payload);
|
|
@@ -2854,6 +2851,53 @@ const converters = {
|
|
|
2854
2851
|
await entity.read('hvacThermostat', ['danfossLoadEstimate'], manufacturerOptions.danfoss);
|
|
2855
2852
|
},
|
|
2856
2853
|
},
|
|
2854
|
+
danfoss_preheat_status: {
|
|
2855
|
+
key: ['preheat_status'],
|
|
2856
|
+
convertGet: async (entity, key, meta) => {
|
|
2857
|
+
await entity.read('hvacThermostat', ['danfossPreheatStatus'], manufacturerOptions.danfoss);
|
|
2858
|
+
},
|
|
2859
|
+
},
|
|
2860
|
+
danfoss_adaptation_status: {
|
|
2861
|
+
key: ['adaptation_run_status'],
|
|
2862
|
+
convertGet: async (entity, key, meta) => {
|
|
2863
|
+
await entity.read('hvacThermostat', ['danfossAdaptionRunStatus'], manufacturerOptions.danfoss);
|
|
2864
|
+
},
|
|
2865
|
+
},
|
|
2866
|
+
danfoss_adaptation_settings: {
|
|
2867
|
+
key: ['adaptation_run_settings'],
|
|
2868
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2869
|
+
await entity.write('hvacThermostat', {'danfossAdaptionRunSettings': value}, manufacturerOptions.danfoss);
|
|
2870
|
+
return {readAfterWriteTime: 200, state: {'adaptation_run_settings': value}};
|
|
2871
|
+
},
|
|
2872
|
+
|
|
2873
|
+
convertGet: async (entity, key, meta) => {
|
|
2874
|
+
await entity.read('hvacThermostat', ['danfossAdaptionRunSettings'], manufacturerOptions.danfoss);
|
|
2875
|
+
},
|
|
2876
|
+
},
|
|
2877
|
+
danfoss_adaptation_control: {
|
|
2878
|
+
key: ['adaptation_run_control'],
|
|
2879
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2880
|
+
const payload = {'danfossAdaptionRunControl': utils.getKey(constants.danfossAdaptionRunControl, value, value, Number)};
|
|
2881
|
+
await entity.write('hvacThermostat', payload, manufacturerOptions.danfoss);
|
|
2882
|
+
return {readAfterWriteTime: 250, state: {'adaptation_run_control': value}};
|
|
2883
|
+
},
|
|
2884
|
+
|
|
2885
|
+
convertGet: async (entity, key, meta) => {
|
|
2886
|
+
await entity.read('hvacThermostat', ['danfossAdaptionRunControl'], manufacturerOptions.danfoss);
|
|
2887
|
+
},
|
|
2888
|
+
},
|
|
2889
|
+
danfoss_regulation_setpoint_offset: {
|
|
2890
|
+
key: ['regulation_setpoint_offset'],
|
|
2891
|
+
convertSet: async (entity, key, value, meta) => {
|
|
2892
|
+
const payload = {'danfossRegulationSetpointOffset': value};
|
|
2893
|
+
await entity.write('hvacThermostat', payload, manufacturerOptions.danfoss);
|
|
2894
|
+
return {readAfterWriteTime: 250, state: {'regulation_setpoint_offset': value}};
|
|
2895
|
+
},
|
|
2896
|
+
|
|
2897
|
+
convertGet: async (entity, key, meta) => {
|
|
2898
|
+
await entity.read('hvacThermostat', ['danfossRegulationSetpointOffset'], manufacturerOptions.danfoss);
|
|
2899
|
+
},
|
|
2900
|
+
},
|
|
2857
2901
|
danfoss_output_status: {
|
|
2858
2902
|
key: ['output_status'],
|
|
2859
2903
|
convertGet: async (entity, key, meta) => {
|
package/devices/danfoss.js
CHANGED
|
@@ -24,7 +24,8 @@ module.exports = [
|
|
|
24
24
|
tz.danfoss_viewing_direction, tz.danfoss_external_measured_room_sensor, tz.danfoss_radiator_covered,
|
|
25
25
|
tz.thermostat_keypad_lockout, tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean,
|
|
26
26
|
tz.thermostat_weekly_schedule, tz.thermostat_clear_weekly_schedule, tz.thermostat_programming_operation_mode,
|
|
27
|
-
tz.danfoss_window_open_feature
|
|
27
|
+
tz.danfoss_window_open_feature, tz.danfoss_preheat_status, tz.danfoss_adaptation_status, tz.danfoss_adaptation_settings,
|
|
28
|
+
tz.danfoss_adaptation_control, tz.danfoss_regulation_setpoint_offset],
|
|
28
29
|
exposes: [e.battery(), e.keypad_lockout(), e.programming_operation_mode(),
|
|
29
30
|
exposes.binary('mounted_mode_active', ea.STATE_GET, true, false)
|
|
30
31
|
.withDescription('Is the unit in mounting mode. This is set to `false` for mounted (already on ' +
|
|
@@ -78,7 +79,19 @@ module.exports = [
|
|
|
78
79
|
.withDescription('Mean radiator load for room calculated by gateway for load balancing purposes (-8000=undefined)')
|
|
79
80
|
.withValueMin(-8000).withValueMax(2000),
|
|
80
81
|
exposes.numeric('load_estimate', ea.STATE_GET)
|
|
81
|
-
.withDescription('Load estimate on this radiator')
|
|
82
|
+
.withDescription('Load estimate on this radiator'),
|
|
83
|
+
exposes.binary('preheat_status', ea.STATE_GET, true, false)
|
|
84
|
+
.withDescription('Specific for pre-heat running in Zigbee Weekly Schedule mode'),
|
|
85
|
+
exposes.enum('adaptation_run_status', ea.STATE_GET, ['none', 'in_progress', 'found', 'lost'])
|
|
86
|
+
.withDescription('Status of adaptation run: None (before first run), In Progress, Valve Characteristic Found, ' +
|
|
87
|
+
'Valve Characteristic Lost'),
|
|
88
|
+
exposes.binary('adaptation_run_settings', ea.ALL, true, false)
|
|
89
|
+
.withDescription('Automatic adaptation run enabled (the one during the night)'),
|
|
90
|
+
exposes.enum('adaptation_run_control', ea.ALL, ['initate_adaptation', 'cancel_adaptation'])
|
|
91
|
+
.withDescription('Adaptation run control: Initiate Adaptation Run or Cancel Adaptation Run'),
|
|
92
|
+
exposes.numeric('regulation_setpoint_offset', ea.ALL)
|
|
93
|
+
.withDescription('Regulation SetPoint Offset in range -2.5°C to 2.5°C in steps of 0.1°C. Value 2.5°C = 25.')
|
|
94
|
+
.withValueMin(-25).withValueMax(25)],
|
|
82
95
|
ota: ota.zigbeeOTA,
|
|
83
96
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
84
97
|
const endpoint = device.getEndpoint(1);
|
|
@@ -117,6 +130,20 @@ module.exports = [
|
|
|
117
130
|
reportableChange: 1,
|
|
118
131
|
}], options);
|
|
119
132
|
|
|
133
|
+
await endpoint.configureReporting('hvacThermostat', [{
|
|
134
|
+
attribute: 'danfossPreheatStatus',
|
|
135
|
+
minimumReportInterval: constants.repInterval.MINUTE,
|
|
136
|
+
maximumReportInterval: constants.repInterval.MAX,
|
|
137
|
+
reportableChange: 1,
|
|
138
|
+
}], options);
|
|
139
|
+
|
|
140
|
+
await endpoint.configureReporting('hvacThermostat', [{
|
|
141
|
+
attribute: 'danfossAdaptionRunStatus',
|
|
142
|
+
minimumReportInterval: constants.repInterval.MINUTE,
|
|
143
|
+
maximumReportInterval: constants.repInterval.HOUR,
|
|
144
|
+
reportableChange: 1,
|
|
145
|
+
}], options);
|
|
146
|
+
|
|
120
147
|
try {
|
|
121
148
|
await endpoint.read('hvacThermostat', [
|
|
122
149
|
'danfossWindowOpenFeatureEnable',
|
|
@@ -131,6 +158,9 @@ module.exports = [
|
|
|
131
158
|
'danfossRadiatorCovered',
|
|
132
159
|
'danfossLoadBalancingEnable',
|
|
133
160
|
'danfossLoadRoomMean',
|
|
161
|
+
'danfossAdaptionRunControl',
|
|
162
|
+
'danfossAdaptionRunSettings',
|
|
163
|
+
'danfossRegulationSetpointOffset',
|
|
134
164
|
], options);
|
|
135
165
|
} catch (e) {
|
|
136
166
|
/* not supported by all https://github.com/Koenkk/zigbee2mqtt/issues/11872 */
|
package/devices/enocean.js
CHANGED
|
@@ -28,7 +28,8 @@ module.exports = [
|
|
|
28
28
|
exposes: [e.action(['press_1', 'release_1', 'press_2', 'release_2', 'press_3', 'release_3', 'press_4', 'release_4',
|
|
29
29
|
'press_1_and_2', 'release_1_and_2', 'press_1_and_3', 'release_1_and_3', 'press_1_and_4', 'release_1_and_4',
|
|
30
30
|
'press_2_and_3', 'release_2_and_3', 'press_2_and_4', 'release_2_and_4', 'press_3_and_4', 'release_3_and_4',
|
|
31
|
-
'press_energy_bar', 'release_energy_bar', 'press_or_release_all'
|
|
31
|
+
'press_energy_bar', 'release_energy_bar', 'press_or_release_all',
|
|
32
|
+
'lock', 'unlock', 'half_open', 'tilt'])],
|
|
32
33
|
whiteLabel: [
|
|
33
34
|
{vendor: 'Easyfit by EnOcean', description: 'Wall switch for Zigbee', model: 'EWSxZ'},
|
|
34
35
|
{vendor: 'Trio2sys', description: 'Zigbee Green Power complete switch', model: '20020002'},
|
package/devices/keen_home.js
CHANGED
|
@@ -22,7 +22,7 @@ module.exports = [
|
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
zigbeeModel: ['SV01-410-MP-1.0', 'SV01-410-MP-1.1', 'SV01-410-MP-1.4', 'SV01-410-MP-1.5', 'SV01-412-MP-1.0',
|
|
25
|
-
'SV01-412-MP-1.4', 'SV01-610-MP-1.0', 'SV01-610-MP-1.1', 'SV01-612-MP-1.0', 'SV01-610-MP-1.4'],
|
|
25
|
+
'SV01-412-MP-1.1', 'SV01-412-MP-1.4', 'SV01-610-MP-1.0', 'SV01-610-MP-1.1', 'SV01-612-MP-1.0', 'SV01-610-MP-1.4'],
|
|
26
26
|
model: 'SV01',
|
|
27
27
|
vendor: 'Keen Home',
|
|
28
28
|
description: 'Smart vent',
|
package/devices/niko.js
CHANGED
|
@@ -11,17 +11,30 @@ module.exports = [
|
|
|
11
11
|
model: '170-33505',
|
|
12
12
|
vendor: 'Niko',
|
|
13
13
|
description: 'Connected socket outlet',
|
|
14
|
-
fromZigbee: [fz.on_off, fz.electrical_measurement],
|
|
15
|
-
toZigbee: [tz.on_off, tz.electrical_measurement_power],
|
|
14
|
+
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering],
|
|
15
|
+
toZigbee: [tz.on_off, tz.electrical_measurement_power, tz.currentsummdelivered],
|
|
16
16
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
17
17
|
const endpoint = device.getEndpoint(1);
|
|
18
|
-
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement']);
|
|
19
|
-
await reporting.
|
|
18
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
|
|
19
|
+
await reporting.onOff(endpoint);
|
|
20
|
+
|
|
21
|
+
// NOTE: we read them individually, acFrequency* is not supported
|
|
22
|
+
// so we cannot use readEletricalMeasurementMultiplierDivisors
|
|
23
|
+
await endpoint.read('haElectricalMeasurement', ['acPowerMultiplier', 'acPowerDivisor']);
|
|
20
24
|
await reporting.activePower(endpoint, {min: 5, max: 3600, change: 1000});
|
|
25
|
+
await endpoint.read('haElectricalMeasurement', ['acCurrentDivisor', 'acPowerMultiplier', 'acPowerDivisor']);
|
|
21
26
|
await reporting.rmsCurrent(endpoint, {min: 5, max: 3600, change: 100});
|
|
27
|
+
await endpoint.read('haElectricalMeasurement', ['acVoltageMultiplier', 'acVoltageDivisor', 'acCurrentMultiplier']);
|
|
22
28
|
await reporting.rmsVoltage(endpoint, {min: 5, max: 3600, change: 100});
|
|
29
|
+
|
|
30
|
+
await reporting.readMeteringMultiplierDivisor(endpoint);
|
|
31
|
+
await reporting.currentSummDelivered(endpoint, {min: 60, change: 1});
|
|
23
32
|
},
|
|
24
|
-
exposes: [
|
|
33
|
+
exposes: [
|
|
34
|
+
e.switch(),
|
|
35
|
+
e.power().withAccess(ea.STATE_GET), e.current(), e.voltage(),
|
|
36
|
+
e.energy().withAccess(ea.STATE_GET),
|
|
37
|
+
],
|
|
25
38
|
},
|
|
26
39
|
{
|
|
27
40
|
zigbeeModel: ['Smart plug Zigbee PE'],
|
|
@@ -29,7 +42,7 @@ module.exports = [
|
|
|
29
42
|
vendor: 'Niko',
|
|
30
43
|
description: 'Smart plug with earthing pin',
|
|
31
44
|
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.power_on_behavior],
|
|
32
|
-
toZigbee: [tz.on_off, tz.power_on_behavior, tz.electrical_measurement_power],
|
|
45
|
+
toZigbee: [tz.on_off, tz.power_on_behavior, tz.electrical_measurement_power, tz.currentsummdelivered],
|
|
33
46
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
34
47
|
const endpoint = device.getEndpoint(1);
|
|
35
48
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'haElectricalMeasurement', 'seMetering']);
|
|
@@ -41,7 +54,7 @@ module.exports = [
|
|
|
41
54
|
await reporting.currentSummDelivered(endpoint, {min: 60, change: 1});
|
|
42
55
|
},
|
|
43
56
|
exposes: [
|
|
44
|
-
e.switch(), e.power().withAccess(ea.STATE_GET), e.energy(),
|
|
57
|
+
e.switch(), e.power().withAccess(ea.STATE_GET), e.energy().withAccess(ea.STATE_GET),
|
|
45
58
|
exposes.enum('power_on_behavior', ea.ALL, ['off', 'previous', 'on'])
|
|
46
59
|
.withDescription('Controls the behaviour when the device is powered on'),
|
|
47
60
|
],
|
package/devices/orvibo.js
CHANGED
|
@@ -6,6 +6,13 @@ const extend = require('../lib/extend');
|
|
|
6
6
|
const e = exposes.presets;
|
|
7
7
|
|
|
8
8
|
module.exports = [
|
|
9
|
+
{
|
|
10
|
+
zigbeeModel: ['ORVIBO Socket'],
|
|
11
|
+
model: 'OR-ZB-S010-3C',
|
|
12
|
+
vendor: 'ORVIBO',
|
|
13
|
+
description: 'Smart Socket',
|
|
14
|
+
extend: extend.switch(),
|
|
15
|
+
},
|
|
9
16
|
{
|
|
10
17
|
zigbeeModel: ['3c4e4fc81ed442efaf69353effcdfc5f', '51725b7bcba945c8a595b325127461e9'],
|
|
11
18
|
model: 'CR11S8UZ',
|
package/devices/philips.js
CHANGED
|
@@ -1513,6 +1513,15 @@ module.exports = [
|
|
|
1513
1513
|
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 500]}),
|
|
1514
1514
|
ota: ota.zigbeeOTA,
|
|
1515
1515
|
},
|
|
1516
|
+
{
|
|
1517
|
+
zigbeeModel: ['4023331P6'],
|
|
1518
|
+
model: '4023331P6',
|
|
1519
|
+
vendor: 'Philips',
|
|
1520
|
+
description: 'Hue white ambiance Amaze',
|
|
1521
|
+
meta: {turnsOffAtBrightness1: true},
|
|
1522
|
+
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 500]}),
|
|
1523
|
+
ota: ota.zigbeeOTA,
|
|
1524
|
+
},
|
|
1516
1525
|
{
|
|
1517
1526
|
zigbeeModel: ['929003054801'],
|
|
1518
1527
|
model: '929003054801',
|
|
@@ -2732,6 +2741,15 @@ module.exports = [
|
|
|
2732
2741
|
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
2733
2742
|
ota: ota.zigbeeOTA,
|
|
2734
2743
|
},
|
|
2744
|
+
{
|
|
2745
|
+
zigbeeModel: ['1746530P7'],
|
|
2746
|
+
model: '1746530P7',
|
|
2747
|
+
vendor: 'Philips',
|
|
2748
|
+
description: 'Hue White and color ambiance Daylo outdoor wall lamp',
|
|
2749
|
+
meta: {turnsOffAtBrightness1: true},
|
|
2750
|
+
extend: hueExtend.light_onoff_brightness_colortemp_color({colorTempRange: [153, 500]}),
|
|
2751
|
+
ota: ota.zigbeeOTA,
|
|
2752
|
+
},
|
|
2735
2753
|
{
|
|
2736
2754
|
zigbeeModel: ['1746547P7'],
|
|
2737
2755
|
model: '1746547P7',
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const exposes = require('../lib/exposes');
|
|
2
|
+
const reporting = require('../lib/reporting');
|
|
3
|
+
const extend = require('../lib/extend');
|
|
4
|
+
const e = exposes.presets;
|
|
5
|
+
|
|
6
|
+
module.exports = [
|
|
7
|
+
{
|
|
8
|
+
zigbeeModel: ['1719SP-PS1-02'],
|
|
9
|
+
model: 'SP-PS1-02',
|
|
10
|
+
vendor: 'Spotmau',
|
|
11
|
+
description: 'Smart wall switch - 1 gang',
|
|
12
|
+
extend: extend.switch(),
|
|
13
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
14
|
+
await reporting.bind(device.getEndpoint(16), coordinatorEndpoint, ['genOnOff', 'genBasic']);
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
zigbeeModel: ['1719SP-PS2-02'],
|
|
19
|
+
model: 'SP-PS2-02',
|
|
20
|
+
vendor: 'Spotmau',
|
|
21
|
+
description: 'Smart wall switch - 2 gang',
|
|
22
|
+
extend: extend.switch(),
|
|
23
|
+
exposes: [e.switch().withEndpoint('left'), e.switch().withEndpoint('right')],
|
|
24
|
+
endpoint: (device) => {
|
|
25
|
+
return {'left': 16, 'right': 17};
|
|
26
|
+
},
|
|
27
|
+
meta: {multiEndpoint: true},
|
|
28
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
29
|
+
await reporting.bind(device.getEndpoint(16), coordinatorEndpoint, ['genOnOff', 'genBasic']);
|
|
30
|
+
await reporting.bind(device.getEndpoint(17), coordinatorEndpoint, ['genOnOff', 'genBasic']);
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
];
|
package/devices/tuya.js
CHANGED
|
@@ -12,7 +12,7 @@ const utils = require('../lib/utils');
|
|
|
12
12
|
|
|
13
13
|
const TS011Fplugs = ['_TZ3000_5f43h46b', '_TZ3000_cphmq0q7', '_TZ3000_dpo1ysak', '_TZ3000_ew3ldmgx', '_TZ3000_gjnozsaz',
|
|
14
14
|
'_TZ3000_jvzvulen', '_TZ3000_mraovvmm', '_TZ3000_nfnmi125', '_TZ3000_ps3dmato', '_TZ3000_w0qqde0g', '_TZ3000_u5u4cakc',
|
|
15
|
-
'_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_kx0pris5', '_TZ3000_amdymr7l', '_TZ3000_z1pnpsdo'];
|
|
15
|
+
'_TZ3000_rdtixbnu', '_TZ3000_typdpbpg', '_TZ3000_kx0pris5', '_TZ3000_amdymr7l', '_TZ3000_z1pnpsdo', '_TZ3000_ksw8qtmt'];
|
|
16
16
|
|
|
17
17
|
const tzLocal = {
|
|
18
18
|
TS0504B_color: {
|
|
@@ -53,6 +53,29 @@ const fzLocal = {
|
|
|
53
53
|
return fz.battery.convert(model, msg, publish, options, meta);
|
|
54
54
|
},
|
|
55
55
|
},
|
|
56
|
+
TS0222: {
|
|
57
|
+
cluster: 'manuSpecificTuya',
|
|
58
|
+
type: ['commandDataResponse', 'commandDataReport'],
|
|
59
|
+
convert: (model, msg, publish, options, meta) => {
|
|
60
|
+
const result = {};
|
|
61
|
+
for (const dpValue of msg.data.dpValues) {
|
|
62
|
+
const dp = dpValue.dp;
|
|
63
|
+
const value = tuya.getDataValue(dpValue);
|
|
64
|
+
switch (dp) {
|
|
65
|
+
case 2:
|
|
66
|
+
result.illuminance = value;
|
|
67
|
+
result.illuminance_lux = value;
|
|
68
|
+
break;
|
|
69
|
+
case 4:
|
|
70
|
+
result.battery = value;
|
|
71
|
+
break;
|
|
72
|
+
default:
|
|
73
|
+
meta.logger.warn(`zigbee-herdsman-converters:TS0222 Unrecognized DP #${dp} with data ${JSON.stringify(dpValue)}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
},
|
|
78
|
+
},
|
|
56
79
|
};
|
|
57
80
|
|
|
58
81
|
module.exports = [
|
|
@@ -97,13 +120,14 @@ module.exports = [
|
|
|
97
120
|
description: 'Door sensor',
|
|
98
121
|
fromZigbee: [fz.ias_contact_alarm_1, fz.battery, fz.ignore_basic_report, fz.ias_contact_alarm_1_report],
|
|
99
122
|
toZigbee: [],
|
|
100
|
-
exposes: [e.contact(), e.battery_low(), e.tamper(), e.battery()],
|
|
123
|
+
exposes: [e.contact(), e.battery_low(), e.tamper(), e.battery(), e.battery_voltage()],
|
|
101
124
|
whiteLabel: [{vendor: 'CR Smart Home', model: 'TS0203'}],
|
|
102
125
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
103
126
|
try {
|
|
104
127
|
const endpoint = device.getEndpoint(1);
|
|
105
128
|
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
106
129
|
await reporting.batteryPercentageRemaining(endpoint);
|
|
130
|
+
await reporting.batteryVoltage(endpoint);
|
|
107
131
|
} catch (error) {/* Fails for some*/}
|
|
108
132
|
},
|
|
109
133
|
},
|
|
@@ -1029,8 +1053,6 @@ module.exports = [
|
|
|
1029
1053
|
toZigbee: [tz.tuya_cover_control, tz.tuya_cover_options],
|
|
1030
1054
|
exposes: [
|
|
1031
1055
|
e.cover_position().setAccess('position', ea.STATE_SET),
|
|
1032
|
-
exposes.binary('running', ea.STATE, true, false)
|
|
1033
|
-
.withDescription('Whether the motor is moving or not'),
|
|
1034
1056
|
exposes.composite('options', 'options')
|
|
1035
1057
|
.withFeature(exposes.numeric('motor_speed', ea.STATE_SET)
|
|
1036
1058
|
.withValueMin(0)
|
|
@@ -1275,7 +1297,7 @@ module.exports = [
|
|
|
1275
1297
|
description: 'Smart plug (with power monitoring)',
|
|
1276
1298
|
vendor: 'TuYa',
|
|
1277
1299
|
whiteLabel: [{vendor: 'LELLKI', model: 'TS011F_plug'}, {vendor: 'NEO', model: 'NAS-WR01B'},
|
|
1278
|
-
{vendor: 'BlitzWolf', model: 'BW-SHP15'}],
|
|
1300
|
+
{vendor: 'BlitzWolf', model: 'BW-SHP15'}, {vendor: 'Nous', model: 'A1Z'}],
|
|
1279
1301
|
ota: ota.zigbeeOTA,
|
|
1280
1302
|
fromZigbee: [fz.on_off, fz.electrical_measurement, fz.metering, fz.ignore_basic_report, fz.tuya_switch_power_outage_memory,
|
|
1281
1303
|
fz.ts011f_plug_indicator_mode, fz.ts011f_plug_child_mode],
|
|
@@ -1649,7 +1671,7 @@ module.exports = [
|
|
|
1649
1671
|
},
|
|
1650
1672
|
},
|
|
1651
1673
|
{
|
|
1652
|
-
zigbeeModel: ['HY0017'],
|
|
1674
|
+
zigbeeModel: ['HY0017', '005f0c3'],
|
|
1653
1675
|
model: 'U86KCJ-ZP',
|
|
1654
1676
|
vendor: 'TuYa',
|
|
1655
1677
|
description: 'Smart 6 key scene wall switch',
|
|
@@ -1805,9 +1827,13 @@ module.exports = [
|
|
|
1805
1827
|
model: 'TS0222',
|
|
1806
1828
|
vendor: 'TuYa',
|
|
1807
1829
|
description: 'Light intensity sensor',
|
|
1808
|
-
fromZigbee: [fz.battery, fz.illuminance],
|
|
1830
|
+
fromZigbee: [fz.battery, fz.illuminance, fzLocal.TS0222],
|
|
1809
1831
|
toZigbee: [],
|
|
1810
1832
|
exposes: [e.battery(), e.illuminance(), e.illuminance_lux()],
|
|
1833
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
1834
|
+
const endpoint = device.getEndpoint(1);
|
|
1835
|
+
await endpoint.read('genBasic', ['manufacturerName', 'zclVersion', 'appVersion', 'modelId', 'powerSource', 0xfffe]);
|
|
1836
|
+
},
|
|
1811
1837
|
},
|
|
1812
1838
|
{
|
|
1813
1839
|
fingerprint: [{modelID: 'TS0210', manufacturerName: '_TYZB01_3zv6oleo'},
|
package/devices/xiaomi.js
CHANGED
|
@@ -1236,11 +1236,13 @@ module.exports = [
|
|
|
1236
1236
|
model: 'ZNCLDJ11LM',
|
|
1237
1237
|
description: 'Aqara curtain motor',
|
|
1238
1238
|
vendor: 'Xiaomi',
|
|
1239
|
-
fromZigbee: [fz.
|
|
1239
|
+
fromZigbee: [fz.xiaomi_basic, fz.xiaomi_curtain_position, fz.cover_position_tilt],
|
|
1240
1240
|
toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
|
|
1241
1241
|
exposes: [e.cover_position().setAccess('state', ea.ALL),
|
|
1242
1242
|
exposes.binary('running', ea.STATE, true, false)
|
|
1243
|
-
.withDescription('Whether the motor is moving or not')
|
|
1243
|
+
.withDescription('Whether the motor is moving or not'),
|
|
1244
|
+
exposes.enum('motor_state', ea.STATE, ['stopped', 'opening', 'closing'])
|
|
1245
|
+
.withDescription('Motor state')],
|
|
1244
1246
|
ota: ota.zigbeeOTA,
|
|
1245
1247
|
},
|
|
1246
1248
|
{
|
|
@@ -1248,7 +1250,7 @@ module.exports = [
|
|
|
1248
1250
|
model: 'SRSC-M01',
|
|
1249
1251
|
description: 'Aqara roller shade motor',
|
|
1250
1252
|
vendor: 'Xiaomi',
|
|
1251
|
-
fromZigbee: [fz.
|
|
1253
|
+
fromZigbee: [fz.xiaomi_basic, fz.xiaomi_curtain_position, fz.cover_position_tilt],
|
|
1252
1254
|
toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
|
|
1253
1255
|
exposes: [e.cover_position().setAccess('state', ea.ALL),
|
|
1254
1256
|
exposes.binary('running', ea.STATE, true, false)
|
|
@@ -1259,8 +1261,8 @@ module.exports = [
|
|
|
1259
1261
|
zigbeeModel: ['lumi.curtain.hagl04'],
|
|
1260
1262
|
model: 'ZNCLDJ12LM',
|
|
1261
1263
|
vendor: 'Xiaomi',
|
|
1262
|
-
description: 'Aqara B1 curtain motor
|
|
1263
|
-
fromZigbee: [fz.
|
|
1264
|
+
description: 'Aqara B1 curtain motor',
|
|
1265
|
+
fromZigbee: [fz.xiaomi_basic, fz.xiaomi_curtain_position, fz.battery, fz.cover_position_tilt],
|
|
1264
1266
|
toZigbee: [tz.xiaomi_curtain_position_state, tz.xiaomi_curtain_options],
|
|
1265
1267
|
onEvent: async (type, data, device) => {
|
|
1266
1268
|
// The position (genAnalogOutput.presentValue) reported via an attribute contains an invaid value
|
package/lib/constants.js
CHANGED
|
@@ -97,6 +97,18 @@ const temperatureDisplayMode = {
|
|
|
97
97
|
1: 'fahrenheit',
|
|
98
98
|
};
|
|
99
99
|
|
|
100
|
+
const danfossAdaptationRunStatus= {
|
|
101
|
+
0: 'none',
|
|
102
|
+
1: 'in_progress',
|
|
103
|
+
2: 'found',
|
|
104
|
+
4: 'lost',
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const danfossAdaptationRunControl = {
|
|
108
|
+
1: 'initate_adaptation',
|
|
109
|
+
2: 'cancel_adaptation',
|
|
110
|
+
};
|
|
111
|
+
|
|
100
112
|
const danfossWindowOpen = {
|
|
101
113
|
0: 'quarantine',
|
|
102
114
|
1: 'closed',
|
|
@@ -267,6 +279,8 @@ module.exports = {
|
|
|
267
279
|
dayOfWeek,
|
|
268
280
|
fanMode,
|
|
269
281
|
temperatureDisplayMode,
|
|
282
|
+
danfossAdaptationRunControl,
|
|
283
|
+
danfossAdaptationRunStatus,
|
|
270
284
|
danfossWindowOpen,
|
|
271
285
|
danfossRoomStatusCode,
|
|
272
286
|
danfossOutputStatus,
|
package/lib/xiaomi.js
CHANGED
|
@@ -408,6 +408,19 @@ const numericAttributes2Payload = (msg, meta, model, options, dataObject) => {
|
|
|
408
408
|
case '550':
|
|
409
409
|
payload.button_switch_mode = value === 1 ? 'relay_and_usb' : 'relay';
|
|
410
410
|
break;
|
|
411
|
+
case '1025':
|
|
412
|
+
payload.options = {...payload.options, // next values update only when curtain finished initial setup and knows current position
|
|
413
|
+
reverse_direction: value[2] == '\u0001',
|
|
414
|
+
hand_open: value[5] == '\u0000',
|
|
415
|
+
};
|
|
416
|
+
break;
|
|
417
|
+
case '1028':
|
|
418
|
+
payload = {...payload,
|
|
419
|
+
motor_state: (options.invert_cover ? {0: 'stopped', 1: 'closing', 2: 'opening'} :
|
|
420
|
+
{0: 'stopped', 1: 'opening', 2: 'closing'})[value],
|
|
421
|
+
running: !!value,
|
|
422
|
+
};
|
|
423
|
+
break;
|
|
411
424
|
case '1033':
|
|
412
425
|
if (['ZNJLBL01LM'].includes(model.model)) {
|
|
413
426
|
payload.charging_status = value === 1;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zigbee-herdsman-converters",
|
|
3
|
-
"version": "14.0.
|
|
3
|
+
"version": "14.0.461",
|
|
4
4
|
"lockfileVersion": 2,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "zigbee-herdsman-converters",
|
|
9
|
-
"version": "14.0.
|
|
9
|
+
"version": "14.0.461",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"axios": "^0.26.1",
|