zigbee-herdsman-converters 14.0.295 → 14.0.296
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 +81 -1
- package/converters/toZigbee.js +62 -0
- package/devices/adeo.js +9 -0
- package/devices/danfoss.js +129 -0
- package/devices/philips.js +18 -0
- package/devices/shinasystem.js +46 -0
- package/devices/the_light_group.js +15 -0
- package/devices/tuya.js +1 -0
- package/devices/yale.js +7 -0
- package/lib/constants.js +43 -0
- package/npm-shrinkwrap.json +1 -1
- package/package.json +1 -1
package/converters/fromZigbee.js
CHANGED
|
@@ -108,6 +108,26 @@ const converters = {
|
|
|
108
108
|
if (msg.data.hasOwnProperty('tempSetpointHoldDuration')) {
|
|
109
109
|
result[postfixWithEndpointName('temperature_setpoint_hold_duration', msg, model)] = msg.data['tempSetpointHoldDuration'];
|
|
110
110
|
}
|
|
111
|
+
if (msg.data.hasOwnProperty('minHeatSetpointLimit')) {
|
|
112
|
+
let value = precisionRound(msg.data['minHeatSetpointLimit'], 2) / 100;
|
|
113
|
+
value = value < -250 ? 0 : value;
|
|
114
|
+
result[postfixWithEndpointName('min_heat_setpoint_limit', msg, model)] = value;
|
|
115
|
+
}
|
|
116
|
+
if (msg.data.hasOwnProperty('maxHeatSetpointLimit')) {
|
|
117
|
+
let value = precisionRound(msg.data['maxHeatSetpointLimit'], 2) / 100;
|
|
118
|
+
value = value < -250 ? 0 : value;
|
|
119
|
+
result[postfixWithEndpointName('max_heat_setpoint_limit', msg, model)] = value;
|
|
120
|
+
}
|
|
121
|
+
if (msg.data.hasOwnProperty('absMinHeatSetpointLimit')) {
|
|
122
|
+
let value = precisionRound(msg.data['absMinHeatSetpointLimit'], 2) / 100;
|
|
123
|
+
value = value < -250 ? 0 : value;
|
|
124
|
+
result[postfixWithEndpointName('abs_min_heat_setpoint_limit', msg, model)] = value;
|
|
125
|
+
}
|
|
126
|
+
if (msg.data.hasOwnProperty('absMaxHeatSetpointLimit')) {
|
|
127
|
+
let value = precisionRound(msg.data['absMaxHeatSetpointLimit'], 2) / 100;
|
|
128
|
+
value = value < -250 ? 0 : value;
|
|
129
|
+
result[postfixWithEndpointName('abs_max_heat_setpoint_limit', msg, model)] = value;
|
|
130
|
+
}
|
|
111
131
|
return result;
|
|
112
132
|
},
|
|
113
133
|
},
|
|
@@ -3007,6 +3027,62 @@ const converters = {
|
|
|
3007
3027
|
if (msg.data.hasOwnProperty('danfossLoadEstimate')) {
|
|
3008
3028
|
result[postfixWithEndpointName('load_estimate', msg, model)] = msg.data['danfossLoadEstimate'];
|
|
3009
3029
|
}
|
|
3030
|
+
// Danfoss Icon Converters
|
|
3031
|
+
if (msg.data.hasOwnProperty('danfossRoomStatusCode')) {
|
|
3032
|
+
result[postfixWithEndpointName('room_status_code', msg, model)] =
|
|
3033
|
+
constants.danfossRoomStatusCode.hasOwnProperty(msg.data['danfossRoomStatusCode']) ?
|
|
3034
|
+
constants.danfossRoomStatusCode[msg.data['danfossRoomStatusCode']] :
|
|
3035
|
+
msg.data['danfossRoomStatusCode'];
|
|
3036
|
+
}
|
|
3037
|
+
if (msg.data.hasOwnProperty('danfossOutputStatus')) {
|
|
3038
|
+
result[postfixWithEndpointName('output_status', msg, model)] =
|
|
3039
|
+
constants.danfossOutputStatus.hasOwnProperty(msg.data['danfossOutputStatus']) ?
|
|
3040
|
+
constants.danfossOutputStatus[msg.data['danfossOutputStatus']] :
|
|
3041
|
+
msg.data['danfossOutputStatus'];
|
|
3042
|
+
}
|
|
3043
|
+
return result;
|
|
3044
|
+
},
|
|
3045
|
+
},
|
|
3046
|
+
danfoss_icon_battery: {
|
|
3047
|
+
cluster: 'genPowerCfg',
|
|
3048
|
+
type: ['attributeReport', 'readResponse'],
|
|
3049
|
+
convert: (model, msg, publish, options, meta) => {
|
|
3050
|
+
const result = {};
|
|
3051
|
+
if (msg.data.hasOwnProperty('batteryPercentageRemaining')) {
|
|
3052
|
+
// Some devices do not comply to the ZCL and report a
|
|
3053
|
+
// batteryPercentageRemaining of 100 when the battery is full (should be 200).
|
|
3054
|
+
const dontDividePercentage = model.meta && model.meta.battery && model.meta.battery.dontDividePercentage;
|
|
3055
|
+
let percentage = msg.data['batteryPercentageRemaining'];
|
|
3056
|
+
percentage = dontDividePercentage ? percentage : percentage / 2;
|
|
3057
|
+
|
|
3058
|
+
result[postfixWithEndpointName('battery', msg, model)] = precisionRound(percentage, 2);
|
|
3059
|
+
}
|
|
3060
|
+
return result;
|
|
3061
|
+
},
|
|
3062
|
+
},
|
|
3063
|
+
danfoss_icon_regulator: {
|
|
3064
|
+
cluster: 'haDiagnostic',
|
|
3065
|
+
type: ['attributeReport', 'readResponse'],
|
|
3066
|
+
convert: (model, msg, publish, options, meta) => {
|
|
3067
|
+
const result = {};
|
|
3068
|
+
if (msg.data.hasOwnProperty('danfossSystemStatusCode')) {
|
|
3069
|
+
result[postfixWithEndpointName('system_status_code', msg, model)] =
|
|
3070
|
+
constants.danfossSystemStatusCode.hasOwnProperty(msg.data['danfossSystemStatusCode']) ?
|
|
3071
|
+
constants.danfossSystemStatusCode[msg.data['danfossSystemStatusCode']] :
|
|
3072
|
+
msg.data['danfossSystemStatusCode'];
|
|
3073
|
+
}
|
|
3074
|
+
if (msg.data.hasOwnProperty('danfossSystemStatusWater')) {
|
|
3075
|
+
result[postfixWithEndpointName('system_status_water', msg, model)] =
|
|
3076
|
+
constants.danfossSystemStatusWater.hasOwnProperty(msg.data['danfossSystemStatusWater']) ?
|
|
3077
|
+
constants.danfossSystemStatusWater[msg.data['danfossSystemStatusWater']] :
|
|
3078
|
+
msg.data['danfossSystemStatusWater'];
|
|
3079
|
+
}
|
|
3080
|
+
if (msg.data.hasOwnProperty('danfossMultimasterRole')) {
|
|
3081
|
+
result[postfixWithEndpointName('multimaster_role', msg, model)] =
|
|
3082
|
+
constants.danfossMultimasterRole.hasOwnProperty(msg.data['danfossMultimasterRole']) ?
|
|
3083
|
+
constants.danfossMultimasterRole[msg.data['danfossMultimasterRole']] :
|
|
3084
|
+
msg.data['danfossMultimasterRole'];
|
|
3085
|
+
}
|
|
3010
3086
|
return result;
|
|
3011
3087
|
},
|
|
3012
3088
|
},
|
|
@@ -6945,7 +7021,11 @@ const converters = {
|
|
|
6945
7021
|
convert: (model, msg, publish, options, meta) => {
|
|
6946
7022
|
const lookup = {'commandToggle': 'long', 'commandOn': 'double', 'commandOff': 'single'};
|
|
6947
7023
|
let buttonMapping = null;
|
|
6948
|
-
if (model.model === '
|
|
7024
|
+
if (model.model === 'SBM300ZB2') {
|
|
7025
|
+
buttonMapping = {1: '1', 2: '2'};
|
|
7026
|
+
} else if (model.model === 'SBM300ZB3') {
|
|
7027
|
+
buttonMapping = {1: '1', 2: '2', 3: '3'};
|
|
7028
|
+
} else if (model.model === 'MSM-300ZB') {
|
|
6949
7029
|
buttonMapping = {1: '1', 2: '2', 3: '3', 4: '4'};
|
|
6950
7030
|
}
|
|
6951
7031
|
const button = buttonMapping ? `${buttonMapping[msg.endpoint.ID]}_` : '';
|
package/converters/toZigbee.js
CHANGED
|
@@ -1327,6 +1327,38 @@ const converters = {
|
|
|
1327
1327
|
await entity.read('hvacThermostat', ['runningMode']);
|
|
1328
1328
|
},
|
|
1329
1329
|
},
|
|
1330
|
+
thermostat_min_heat_setpoint_limit: {
|
|
1331
|
+
key: ['min_heat_setpoint_limit'],
|
|
1332
|
+
convertSet: async (entity, key, value, meta) => {
|
|
1333
|
+
let result;
|
|
1334
|
+
if (meta.options.thermostat_unit === 'fahrenheit') {
|
|
1335
|
+
result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
|
|
1336
|
+
} else {
|
|
1337
|
+
result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
|
|
1338
|
+
}
|
|
1339
|
+
const minHeatSetpointLimit = result;
|
|
1340
|
+
await entity.write('hvacThermostat', {minHeatSetpointLimit});
|
|
1341
|
+
},
|
|
1342
|
+
convertGet: async (entity, key, meta) => {
|
|
1343
|
+
await entity.read('hvacThermostat', ['minHeatSetpointLimit']);
|
|
1344
|
+
},
|
|
1345
|
+
},
|
|
1346
|
+
thermostat_max_heat_setpoint_limit: {
|
|
1347
|
+
key: ['max_heat_setpoint_limit'],
|
|
1348
|
+
convertSet: async (entity, key, value, meta) => {
|
|
1349
|
+
let result;
|
|
1350
|
+
if (meta.options.thermostat_unit === 'fahrenheit') {
|
|
1351
|
+
result = utils.normalizeCelsiusVersionOfFahrenheit(value) * 100;
|
|
1352
|
+
} else {
|
|
1353
|
+
result = (Math.round((value * 2).toFixed(1)) / 2).toFixed(1) * 100;
|
|
1354
|
+
}
|
|
1355
|
+
const maxHeatSetpointLimit = result;
|
|
1356
|
+
await entity.write('hvacThermostat', {maxHeatSetpointLimit});
|
|
1357
|
+
},
|
|
1358
|
+
convertGet: async (entity, key, meta) => {
|
|
1359
|
+
await entity.read('hvacThermostat', ['maxHeatSetpointLimit']);
|
|
1360
|
+
},
|
|
1361
|
+
},
|
|
1330
1362
|
electrical_measurement_power: {
|
|
1331
1363
|
key: ['power'],
|
|
1332
1364
|
convertGet: async (entity, key, meta) => {
|
|
@@ -2484,6 +2516,36 @@ const converters = {
|
|
|
2484
2516
|
await entity.read('hvacThermostat', ['danfossLoadEstimate'], manufacturerOptions.danfoss);
|
|
2485
2517
|
},
|
|
2486
2518
|
},
|
|
2519
|
+
danfoss_output_status: {
|
|
2520
|
+
key: ['output_status'],
|
|
2521
|
+
convertGet: async (entity, key, meta) => {
|
|
2522
|
+
await entity.read('hvacThermostat', ['danfossOutputStatus'], manufacturerOptions.danfoss);
|
|
2523
|
+
},
|
|
2524
|
+
},
|
|
2525
|
+
danfoss_room_status_code: {
|
|
2526
|
+
key: ['room_status_code'],
|
|
2527
|
+
convertGet: async (entity, key, meta) => {
|
|
2528
|
+
await entity.read('hvacThermostat', ['danfossRoomStatusCode'], manufacturerOptions.danfoss);
|
|
2529
|
+
},
|
|
2530
|
+
},
|
|
2531
|
+
danfoss_system_status_code: {
|
|
2532
|
+
key: ['system_status_code'],
|
|
2533
|
+
convertGet: async (entity, key, meta) => {
|
|
2534
|
+
await entity.read('haDiagnostic', ['danfossSystemStatusCode'], manufacturerOptions.danfoss);
|
|
2535
|
+
},
|
|
2536
|
+
},
|
|
2537
|
+
danfoss_system_status_water: {
|
|
2538
|
+
key: ['system_status_water'],
|
|
2539
|
+
convertGet: async (entity, key, meta) => {
|
|
2540
|
+
await entity.read('haDiagnostic', ['danfossSystemStatusWater'], manufacturerOptions.danfoss);
|
|
2541
|
+
},
|
|
2542
|
+
},
|
|
2543
|
+
danfoss_multimaster_role: {
|
|
2544
|
+
key: ['multimaster_role'],
|
|
2545
|
+
convertGet: async (entity, key, meta) => {
|
|
2546
|
+
await entity.read('haDiagnostic', ['danfossMultimasterRole'], manufacturerOptions.danfoss);
|
|
2547
|
+
},
|
|
2548
|
+
},
|
|
2487
2549
|
ZMCSW032D_cover_position: {
|
|
2488
2550
|
key: ['position', 'tilt'],
|
|
2489
2551
|
convertSet: async (entity, key, value, meta) => {
|
package/devices/adeo.js
CHANGED
|
@@ -76,4 +76,13 @@ module.exports = [
|
|
|
76
76
|
},
|
|
77
77
|
exposes: [e.power(), e.switch(), e.energy()],
|
|
78
78
|
},
|
|
79
|
+
{
|
|
80
|
+
zigbeeModel: ['LDSENK10'],
|
|
81
|
+
model: 'LDSENK10',
|
|
82
|
+
vendor: 'ADEO',
|
|
83
|
+
description: 'LEXMAN motion sensor',
|
|
84
|
+
fromZigbee: [fz.ias_occupancy_alarm_1],
|
|
85
|
+
toZigbee: [],
|
|
86
|
+
exposes: [e.occupancy(), e.battery_low(), e.tamper()],
|
|
87
|
+
},
|
|
79
88
|
];
|
package/devices/danfoss.js
CHANGED
|
@@ -122,4 +122,133 @@ module.exports = [
|
|
|
122
122
|
endpoint.write('genTime', values);
|
|
123
123
|
},
|
|
124
124
|
},
|
|
125
|
+
{
|
|
126
|
+
fingerprint: [
|
|
127
|
+
{modelID: '0x8020', manufacturerName: 'Danfoss'}, // RT24V Display
|
|
128
|
+
{modelID: '0x8021', manufacturerName: 'Danfoss'}, // RT24V Display Floor sensor
|
|
129
|
+
{modelID: '0x8030', manufacturerName: 'Danfoss'}, // RTbattery Display
|
|
130
|
+
{modelID: '0x8031', manufacturerName: 'Danfoss'}, // RTbattery Display Infrared
|
|
131
|
+
{modelID: '0x8034', manufacturerName: 'Danfoss'}, // RTbattery Dial
|
|
132
|
+
{modelID: '0x8035', manufacturerName: 'Danfoss'}], // RTbattery Dial Infrared
|
|
133
|
+
model: 'Icon',
|
|
134
|
+
vendor: 'Danfoss',
|
|
135
|
+
description: 'Icon floor heating (regulator, Zigbee module & thermostats)',
|
|
136
|
+
fromZigbee: [
|
|
137
|
+
fz.danfoss_icon_regulator,
|
|
138
|
+
fz.danfoss_thermostat,
|
|
139
|
+
fz.danfoss_icon_battery,
|
|
140
|
+
fz.thermostat],
|
|
141
|
+
toZigbee: [
|
|
142
|
+
tz.thermostat_local_temperature,
|
|
143
|
+
tz.thermostat_occupied_heating_setpoint,
|
|
144
|
+
tz.thermostat_system_mode,
|
|
145
|
+
tz.thermostat_min_heat_setpoint_limit,
|
|
146
|
+
tz.thermostat_max_heat_setpoint_limit,
|
|
147
|
+
tz.danfoss_output_status,
|
|
148
|
+
tz.danfoss_room_status_code,
|
|
149
|
+
tz.danfoss_system_status_water,
|
|
150
|
+
tz.danfoss_system_status_code,
|
|
151
|
+
tz.danfoss_multimaster_role,
|
|
152
|
+
],
|
|
153
|
+
meta: {multiEndpoint: true},
|
|
154
|
+
// ota: ota.zigbeeOTA,
|
|
155
|
+
endpoint: (device) => {
|
|
156
|
+
return {
|
|
157
|
+
'l1': 1, 'l2': 2, 'l3': 3, 'l4': 4, 'l5': 5,
|
|
158
|
+
'l6': 6, 'l7': 7, 'l8': 8, 'l9': 9, 'l10': 10,
|
|
159
|
+
'l11': 11, 'l12': 12, 'l13': 13, 'l14': 14, 'l15': 15, 'l16': 232,
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
exposes: [].concat(((endpointsCount) => {
|
|
163
|
+
const features = [];
|
|
164
|
+
for (let i = 1; i <= endpointsCount; i++) {
|
|
165
|
+
const epName = `l${i}`;
|
|
166
|
+
if (i!=16) {
|
|
167
|
+
features.push(e.battery().withEndpoint(epName));
|
|
168
|
+
features.push(exposes.climate().withSetpoint('occupied_heating_setpoint', 4, 30, 0.5)
|
|
169
|
+
.withLocalTemperature().withSystemMode(['heat']).withEndpoint(epName));
|
|
170
|
+
features.push(exposes.numeric('abs_min_heat_setpoint_limit', ea.STATE)
|
|
171
|
+
.withUnit('°C').withEndpoint(epName)
|
|
172
|
+
.withDescription('Absolute min temperature allowed on the device'));
|
|
173
|
+
features.push(exposes.numeric('abs_max_heat_setpoint_limit', ea.STATE)
|
|
174
|
+
.withUnit('°C').withEndpoint(epName)
|
|
175
|
+
.withDescription('Absolute max temperature allowed on the device'));
|
|
176
|
+
features.push(exposes.numeric('min_heat_setpoint_limit', ea.ALL)
|
|
177
|
+
.withValueMin(4).withValueMax(30).withValueStep(0.5).withUnit('°C')
|
|
178
|
+
.withEndpoint(epName).withDescription('Min temperature limit set on the device'));
|
|
179
|
+
features.push(exposes.numeric('max_heat_setpoint_limit', ea.ALL)
|
|
180
|
+
.withValueMin(4).withValueMax(30).withValueStep(0.5).withUnit('°C')
|
|
181
|
+
.withEndpoint(epName).withDescription('Max temperature limit set on the device'));
|
|
182
|
+
features.push(exposes.enum('setpoint_change_source', ea.STATE, ['manual', 'schedule', 'externally'])
|
|
183
|
+
.withEndpoint(epName));
|
|
184
|
+
features.push(exposes.enum('output_status', ea.STATE_GET, ['inactive', 'active'])
|
|
185
|
+
.withEndpoint(epName).withDescription('Danfoss Output Status [Active vs Inactive])'));
|
|
186
|
+
features.push(exposes.enum('room_status_code', ea.STATE_GET, ['no_error', 'missing_rt',
|
|
187
|
+
'rt_touch_error', 'floor_sensor_short_circuit', 'floor_sensor_disconnected'])
|
|
188
|
+
.withEndpoint(epName).withDescription('Thermostat status'));
|
|
189
|
+
} else {
|
|
190
|
+
features.push(exposes.enum('system_status_code', ea.STATE_GET, ['no_error', 'missing_expansion_board',
|
|
191
|
+
'missing_radio_module', 'missing_command_module', 'missing_master_rail', 'missing_slave_rail_no_1',
|
|
192
|
+
'missing_slave_rail_no_2', 'pt1000_input_short_circuit', 'pt1000_input_open_circuit',
|
|
193
|
+
'error_on_one_or_more_output']).withEndpoint('l16').withDescription('Regulator Status'));
|
|
194
|
+
features.push(exposes.enum('system_status_water', ea.STATE_GET, ['hot_water_flow_in_pipes', 'cool_water_flow_in_pipes'])
|
|
195
|
+
.withEndpoint('l16').withDescription('Water Status of Regulator'));
|
|
196
|
+
features.push(exposes.enum('multimaster_role', ea.STATE_GET, ['invalid_unused', 'master', 'slave_1', 'slave_2'])
|
|
197
|
+
.withEndpoint('l16').withDescription('Regulator role (Master vs Slave)'));
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
return features;
|
|
202
|
+
})(16)),
|
|
203
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
204
|
+
const options = {manufacturerCode: 0x1246};
|
|
205
|
+
|
|
206
|
+
for (let i = 1; i <= 15; i++) {
|
|
207
|
+
const endpoint = device.getEndpoint(i);
|
|
208
|
+
if (typeof endpoint !== 'undefined') {
|
|
209
|
+
await reporting.bind(endpoint, coordinatorEndpoint,
|
|
210
|
+
['genPowerCfg', 'hvacThermostat', 'hvacUserInterfaceCfg']);
|
|
211
|
+
await reporting.batteryPercentageRemaining(endpoint,
|
|
212
|
+
{min: constants.repInterval.HOUR, max: 43200, change: 1});
|
|
213
|
+
await reporting.thermostatTemperature(endpoint,
|
|
214
|
+
{min: 0, max: constants.repInterval.MINUTES_10, change: 10});
|
|
215
|
+
await reporting.thermostatOccupiedHeatingSetpoint(endpoint,
|
|
216
|
+
{min: 0, max: constants.repInterval.MINUTES_10, change: 10});
|
|
217
|
+
|
|
218
|
+
await endpoint.configureReporting('hvacThermostat', [{
|
|
219
|
+
attribute: 'danfossOutputStatus',
|
|
220
|
+
minimumReportInterval: constants.repInterval.MINUTE,
|
|
221
|
+
maximumReportInterval: constants.repInterval.MINUTES_10,
|
|
222
|
+
reportableChange: 1,
|
|
223
|
+
}], options);
|
|
224
|
+
|
|
225
|
+
// Danfoss Icon Thermostat Specific
|
|
226
|
+
await endpoint.read('hvacThermostat', [
|
|
227
|
+
'danfossOutputStatus',
|
|
228
|
+
'danfossRoomStatusCode'], options);
|
|
229
|
+
|
|
230
|
+
// Standard Thermostat
|
|
231
|
+
await endpoint.read('hvacThermostat', ['localTemp']);
|
|
232
|
+
await endpoint.read('hvacThermostat', ['occupiedHeatingSetpoint']);
|
|
233
|
+
await endpoint.read('hvacThermostat', ['systemMode']);
|
|
234
|
+
await endpoint.read('hvacThermostat', ['setpointChangeSource']);
|
|
235
|
+
await endpoint.read('hvacThermostat', ['absMinHeatSetpointLimit']);
|
|
236
|
+
await endpoint.read('hvacThermostat', ['absMaxHeatSetpointLimit']);
|
|
237
|
+
await endpoint.read('hvacThermostat', ['minHeatSetpointLimit']);
|
|
238
|
+
await endpoint.read('hvacThermostat', ['maxHeatSetpointLimit']);
|
|
239
|
+
await endpoint.read('genPowerCfg', ['batteryPercentageRemaining']);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Danfoss Icon Regulator Specific
|
|
244
|
+
const endpoint232 = device.getEndpoint(232);
|
|
245
|
+
|
|
246
|
+
await reporting.bind(endpoint232, coordinatorEndpoint, ['haDiagnostic']);
|
|
247
|
+
|
|
248
|
+
await endpoint232.read('haDiagnostic', [
|
|
249
|
+
'danfossSystemStatusCode',
|
|
250
|
+
'danfossSystemStatusWater',
|
|
251
|
+
'danfossMultimasterRole'], options);
|
|
252
|
+
},
|
|
253
|
+
},
|
|
125
254
|
];
|
package/devices/philips.js
CHANGED
|
@@ -2165,4 +2165,22 @@ module.exports = [
|
|
|
2165
2165
|
meta: {turnsOffAtBrightness1: true},
|
|
2166
2166
|
ota: ota.zigbeeOTA,
|
|
2167
2167
|
},
|
|
2168
|
+
{
|
|
2169
|
+
zigbeeModel: ['LTF001'],
|
|
2170
|
+
model: '6109231C5',
|
|
2171
|
+
vendor: 'Philips',
|
|
2172
|
+
description: 'Hue white ambiance Apogee square',
|
|
2173
|
+
meta: {turnsOffAtBrightness1: true},
|
|
2174
|
+
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
2175
|
+
ota: ota.zigbeeOTA,
|
|
2176
|
+
},
|
|
2177
|
+
{
|
|
2178
|
+
zigbeeModel: ['LTF002'],
|
|
2179
|
+
model: '6109331C5',
|
|
2180
|
+
vendor: 'Philips',
|
|
2181
|
+
description: 'Hue white ambiance Apogee round',
|
|
2182
|
+
meta: {turnsOffAtBrightness1: true},
|
|
2183
|
+
extend: hueExtend.light_onoff_brightness_colortemp({colorTempRange: [153, 454]}),
|
|
2184
|
+
ota: ota.zigbeeOTA,
|
|
2185
|
+
},
|
|
2168
2186
|
];
|
package/devices/shinasystem.js
CHANGED
|
@@ -236,4 +236,50 @@ module.exports = [
|
|
|
236
236
|
await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
|
|
237
237
|
},
|
|
238
238
|
},
|
|
239
|
+
{
|
|
240
|
+
zigbeeModel: ['SBM300ZB1'],
|
|
241
|
+
model: 'SBM300ZB1',
|
|
242
|
+
vendor: 'ShinaSystem',
|
|
243
|
+
description: 'SiHAS remote control',
|
|
244
|
+
meta: {battery: {voltageToPercentage: '3V_2100'}},
|
|
245
|
+
fromZigbee: [fz.battery, fz.sihas_action],
|
|
246
|
+
toZigbee: [],
|
|
247
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
248
|
+
const endpoint = device.getEndpoint(1);
|
|
249
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
250
|
+
await reporting.batteryVoltage(endpoint);
|
|
251
|
+
},
|
|
252
|
+
exposes: [e.battery(), e.battery_voltage(), e.action(['single', 'double', 'long'])],
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
zigbeeModel: ['SBM300ZB2'],
|
|
256
|
+
model: 'SBM300ZB2',
|
|
257
|
+
vendor: 'ShinaSystem',
|
|
258
|
+
description: 'SiHAS remote control 2 button',
|
|
259
|
+
fromZigbee: [fz.sihas_action, fz.battery],
|
|
260
|
+
toZigbee: [],
|
|
261
|
+
exposes: [e.action(['1_single', '1_double', '1_long', '2_single', '2_double', '2_long']), e.battery(), e.battery_voltage()],
|
|
262
|
+
meta: {battery: {voltageToPercentage: '3V_2100'}},
|
|
263
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
264
|
+
const endpoint = device.getEndpoint(1);
|
|
265
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
266
|
+
await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
zigbeeModel: ['SBM300ZB3'],
|
|
271
|
+
model: 'SBM300ZB3',
|
|
272
|
+
vendor: 'ShinaSystem',
|
|
273
|
+
description: 'SiHAS remote control 3 button',
|
|
274
|
+
fromZigbee: [fz.sihas_action, fz.battery],
|
|
275
|
+
toZigbee: [],
|
|
276
|
+
exposes: [e.action(['1_single', '1_double', '1_long', '2_single', '2_double', '2_long',
|
|
277
|
+
'3_single', '3_double', '3_long']), e.battery(), e.battery_voltage()],
|
|
278
|
+
meta: {battery: {voltageToPercentage: '3V_2100'}},
|
|
279
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
280
|
+
const endpoint = device.getEndpoint(1);
|
|
281
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg']);
|
|
282
|
+
await reporting.batteryVoltage(endpoint, {min: 30, max: 21600, change: 1});
|
|
283
|
+
},
|
|
284
|
+
},
|
|
239
285
|
];
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const exposes = require('../lib/exposes');
|
|
2
2
|
const fz = {...require('../converters/fromZigbee'), legacy: require('../lib/legacy').fromZigbee};
|
|
3
|
+
const reporting = require('../lib/reporting');
|
|
4
|
+
const extend = require('../lib/extend');
|
|
3
5
|
const e = exposes.presets;
|
|
4
6
|
|
|
5
7
|
module.exports = [
|
|
@@ -21,4 +23,17 @@ module.exports = [
|
|
|
21
23
|
return {l1: 1, l2: 2, l3: 3, l4: 4};
|
|
22
24
|
},
|
|
23
25
|
},
|
|
26
|
+
{
|
|
27
|
+
zigbeeModel: ['S24013'],
|
|
28
|
+
model: 'S24013',
|
|
29
|
+
vendor: 'The Light Group',
|
|
30
|
+
description: 'SLC SmartOne AC dimmer mini 200W Zigbee LN',
|
|
31
|
+
extend: extend.light_onoff_brightness({noConfigure: true}),
|
|
32
|
+
configure: async (device, coordinatorEndpoint, logger) => {
|
|
33
|
+
await extend.light_onoff_brightness().configure(device, coordinatorEndpoint, logger);
|
|
34
|
+
const endpoint = device.getEndpoint(1);
|
|
35
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff', 'genLevelCtrl']);
|
|
36
|
+
await reporting.onOff(endpoint);
|
|
37
|
+
},
|
|
38
|
+
},
|
|
24
39
|
];
|
package/devices/tuya.js
CHANGED
|
@@ -916,6 +916,7 @@ module.exports = [
|
|
|
916
916
|
toZigbee: [tz.on_off, tz.tuya_switch_power_outage_memory],
|
|
917
917
|
configure: async (device, coordinatorEndpoint, logger) => {
|
|
918
918
|
const endpoint = device.getEndpoint(1);
|
|
919
|
+
await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']);
|
|
919
920
|
endpoint.saveClusterAttributeKeyValue('haElectricalMeasurement', {acCurrentDivisor: 1000, acCurrentMultiplier: 1});
|
|
920
921
|
endpoint.saveClusterAttributeKeyValue('seMetering', {divisor: 100, multiplier: 1});
|
|
921
922
|
device.save();
|
package/devices/yale.js
CHANGED
|
@@ -100,6 +100,13 @@ module.exports = [
|
|
|
100
100
|
description: 'Assure lock SL',
|
|
101
101
|
extend: lockExtend(),
|
|
102
102
|
},
|
|
103
|
+
{
|
|
104
|
+
zigbeeModel: ['YRL226 TS'],
|
|
105
|
+
model: 'YRL226 TS',
|
|
106
|
+
vendor: 'Yale',
|
|
107
|
+
description: 'Assure lock SL',
|
|
108
|
+
extend: lockExtend(),
|
|
109
|
+
},
|
|
103
110
|
{
|
|
104
111
|
// Appears to be a slightly rebranded Assure lock SL
|
|
105
112
|
// Just with Lockwood | Assa Abloy branding instead of Yale
|
package/lib/constants.js
CHANGED
|
@@ -91,6 +91,44 @@ const danfossWindowOpen = {
|
|
|
91
91
|
4: 'external_open',
|
|
92
92
|
};
|
|
93
93
|
|
|
94
|
+
const danfossRoomStatusCode = {
|
|
95
|
+
0x0000: 'no_error',
|
|
96
|
+
0x0101: 'missing_rt',
|
|
97
|
+
0x0201: 'rt_touch_error',
|
|
98
|
+
0x0401: 'floor_sensor_short_circuit',
|
|
99
|
+
0x0801: 'floor_sensor_disconnected',
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const danfossOutputStatus = {
|
|
103
|
+
0: 'inactive',
|
|
104
|
+
1: 'active',
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
const danfossSystemStatusWater = {
|
|
108
|
+
0: 'hot_water_flow_in_pipes',
|
|
109
|
+
1: 'cool_water_flow_in_pipes',
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const danfossSystemStatusCode = {
|
|
113
|
+
0x0000: 'no_error',
|
|
114
|
+
0x0101: 'missing_expansion_board',
|
|
115
|
+
0x0201: 'missing_radio_module',
|
|
116
|
+
0x0401: 'missing_command_module',
|
|
117
|
+
0x0801: 'missing_master_rail',
|
|
118
|
+
0x1001: 'missing_slave_rail_no_1',
|
|
119
|
+
0x2001: 'missing_slave_rail_no_2',
|
|
120
|
+
0x4001: 'pt1000_input_short_circuit',
|
|
121
|
+
0x8001: 'pt1000_input_open_circuit',
|
|
122
|
+
0x0102: 'error_on_one_or_more_output',
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const danfossMultimasterRole = {
|
|
126
|
+
0: 'invalid_unused',
|
|
127
|
+
1: 'master',
|
|
128
|
+
2: 'slave_1',
|
|
129
|
+
3: 'slave_2',
|
|
130
|
+
};
|
|
131
|
+
|
|
94
132
|
const keypadLockoutMode = {
|
|
95
133
|
0: 'unlock',
|
|
96
134
|
1: 'lock1',
|
|
@@ -196,6 +234,11 @@ module.exports = {
|
|
|
196
234
|
fanMode,
|
|
197
235
|
temperatureDisplayMode,
|
|
198
236
|
danfossWindowOpen,
|
|
237
|
+
danfossRoomStatusCode,
|
|
238
|
+
danfossOutputStatus,
|
|
239
|
+
danfossSystemStatusWater,
|
|
240
|
+
danfossSystemStatusCode,
|
|
241
|
+
danfossMultimasterRole,
|
|
199
242
|
keypadLockoutMode,
|
|
200
243
|
lockSourceName,
|
|
201
244
|
armMode,
|
package/npm-shrinkwrap.json
CHANGED