Skip to content

Commit

Permalink
danfoss: Add thermostat schedule support
Browse files Browse the repository at this point in the history
  • Loading branch information
kennylevinsen committed Dec 15, 2021
1 parent 10f29e0 commit 1c30ecb
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 9 deletions.
4 changes: 4 additions & 0 deletions converters/fromZigbee.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ const converters = {
result[postfixWithEndpointName('control_sequence_of_operation', msg, model)] =
constants.thermostatControlSequenceOfOperations[msg.data['ctrlSeqeOfOper']];
}
if (msg.data.hasOwnProperty('programingOperMode')) {
result[postfixWithEndpointName('programming_operation_mode', msg, model)] =
constants.thermostatProgrammingOperationModes[msg.data['programingOperMode']];
}
if (msg.data.hasOwnProperty('systemMode')) {
result[postfixWithEndpointName('system_mode', msg, model)] = constants.thermostatSystemModes[msg.data['systemMode']];
}
Expand Down
14 changes: 14 additions & 0 deletions converters/toZigbee.js
Original file line number Diff line number Diff line change
Expand Up @@ -1154,6 +1154,20 @@ const converters = {
await entity.read('hvacThermostat', ['ctrlSeqeOfOper']);
},
},
thermostat_programming_operation_mode: {
key: ['programming_operation_mode'],
convertSet: async (entity, key, value, meta) => {
const val = utils.getKey(constants.thermostatProgrammingOperationModes, value, undefined, Number);
if (val === undefined) {
throw new Error('Programming operation mode invalid, must be one of: ' +
Object.values(constants.thermostatProgrammingOperationModes).join(', '));
}
await entity.write('hvacThermostat', {programingOperMode: val});
},
convertGet: async (entity, key, meta) => {
await entity.read('hvacThermostat', ['programingOperMode']);
},
},
thermostat_temperature_display_mode: {
key: ['temperature_display_mode'],
convertSet: async (entity, key, value, meta) => {
Expand Down
8 changes: 5 additions & 3 deletions devices/danfoss.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ module.exports = [
model: '014G2461',
vendor: 'Danfoss',
description: 'Ally thermostat',
fromZigbee: [fz.battery, fz.thermostat, fz.hvac_user_interface, fz.danfoss_thermostat],
fromZigbee: [fz.battery, fz.thermostat, fz.thermostat_weekly_schedule, fz.hvac_user_interface, fz.danfoss_thermostat],
toZigbee: [tz.danfoss_thermostat_occupied_heating_setpoint, tz.thermostat_local_temperature, tz.danfoss_mounted_mode_active,
tz.danfoss_mounted_mode_control, tz.danfoss_thermostat_vertical_orientation, tz.danfoss_algorithm_scale_factor,
tz.danfoss_heat_available, tz.danfoss_heat_required, tz.danfoss_day_of_week, tz.danfoss_trigger_time,
tz.danfoss_window_open_internal, tz.danfoss_window_open_external, tz.danfoss_load_estimate,
tz.danfoss_viewing_direction, tz.danfoss_external_measured_room_sensor, tz.thermostat_keypad_lockout,
tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean],
tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean,
tz.thermostat_weekly_schedule, tz.thermostat_clear_weekly_schedule, tz.thermostat_programming_operation_mode],
exposes: [e.battery(), e.keypad_lockout(),
exposes.binary('mounted_mode_active', ea.STATE_GET, true, false)
.withDescription('Is the unit in mounting mode. This is set to `false` for mounted (already on ' +
Expand Down Expand Up @@ -68,7 +69,8 @@ module.exports = [
.withDescription('Mean radiator load for room calculated by gateway for load balancing purposes (-8000=undefined)')
.withValueMin(-8000).withValueMax(100),
exposes.numeric('load_estimate', ea.STATE_GET)
.withDescription('Load estimate on this radiator')],
.withDescription('Load estimate on this radiator'),
exposes.programming_operation_mode()],
ota: ota.zigbeeOTA,
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
Expand Down
8 changes: 5 additions & 3 deletions devices/hive.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,13 +156,14 @@ module.exports = [
model: 'UK7004240',
vendor: 'Hive',
description: 'Radiator valve based on Danfos Ally',
fromZigbee: [fz.battery, fz.thermostat, fz.hvac_user_interface, fz.danfoss_thermostat],
fromZigbee: [fz.battery, fz.thermostat, fz.thermostat_weekly_schedule, fz.hvac_user_interface, fz.danfoss_thermostat],
toZigbee: [tz.danfoss_thermostat_occupied_heating_setpoint, tz.thermostat_local_temperature, tz.danfoss_mounted_mode_active,
tz.danfoss_mounted_mode_control, tz.danfoss_thermostat_vertical_orientation, tz.danfoss_algorithm_scale_factor,
tz.danfoss_heat_available, tz.danfoss_heat_required, tz.danfoss_day_of_week, tz.danfoss_trigger_time,
tz.danfoss_window_open_internal, tz.danfoss_window_open_external, tz.danfoss_load_estimate,
tz.danfoss_viewing_direction, tz.danfoss_external_measured_room_sensor, tz.thermostat_keypad_lockout,
tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean],
tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean,
tz.thermostat_weekly_schedule, tz.thermostat_clear_weekly_schedule, tz.thermostat_programming_operation_mode],
exposes: [e.battery(), e.keypad_lockout(),
exposes.binary('mounted_mode_active', ea.STATE_GET, true, false)
.withDescription('Is the unit in mounting mode. This is set to `false` for mounted (already on ' +
Expand Down Expand Up @@ -207,7 +208,8 @@ module.exports = [
.withDescription('Mean radiator load for room calculated by gateway for load balancing purposes (-8000=undefined)')
.withValueMin(-8000).withValueMax(100),
exposes.numeric('load_estimate', ea.STATE_GET)
.withDescription('Load estimate on this radiator')],
.withDescription('Load estimate on this radiator'),
exposes.programming_operation_mode()],
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
const options = {manufacturerCode: 0x1246};
Expand Down
8 changes: 5 additions & 3 deletions devices/popp.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ module.exports = [
model: '701721',
vendor: 'Popp',
description: 'Smart thermostat',
fromZigbee: [fz.battery, fz.thermostat, fz.hvac_user_interface, fz.danfoss_thermostat],
fromZigbee: [fz.battery, fz.thermostat, fz.thermostat_weekly_schedule, fz.hvac_user_interface, fz.danfoss_thermostat],
toZigbee: [tz.danfoss_thermostat_occupied_heating_setpoint, tz.thermostat_local_temperature, tz.danfoss_mounted_mode_active,
tz.danfoss_mounted_mode_control, tz.danfoss_thermostat_vertical_orientation, tz.danfoss_algorithm_scale_factor,
tz.danfoss_heat_available, tz.danfoss_heat_required, tz.danfoss_day_of_week, tz.danfoss_trigger_time,
tz.danfoss_window_open_internal, tz.danfoss_window_open_external, tz.danfoss_load_estimate,
tz.danfoss_viewing_direction, tz.danfoss_external_measured_room_sensor, tz.thermostat_keypad_lockout,
tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean],
tz.thermostat_system_mode, tz.danfoss_load_balancing_enable, tz.danfoss_load_room_mean,
tz.thermostat_weekly_schedule, tz.thermostat_clear_weekly_schedule, tz.thermostat_programming_operation_mode],
exposes: [e.battery(), e.keypad_lockout(),
exposes.binary('mounted_mode_active', ea.STATE_GET, true, false)
.withDescription('Is the unit in mounting mode. This is set to `false` for mounted (already on ' +
Expand Down Expand Up @@ -66,7 +67,8 @@ module.exports = [
.withDescription('Mean radiator load for room calculated by gateway for load balancing purposes (-8000=undefined)')
.withValueMin(-8000).withValueMax(100),
exposes.numeric('load_estimate', ea.STATE_GET)
.withDescription('Load estimate on this radiator')],
.withDescription('Load estimate on this radiator'),
exposes.programming_operation_mode()],
ota: ota.zigbeeOTA,
configure: async (device, coordinatorEndpoint, logger) => {
const endpoint = device.getEndpoint(1);
Expand Down
6 changes: 6 additions & 0 deletions lib/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ const thermostatControlSequenceOfOperations = {
5: 'cooling_and_heating_4-pipes_with_reheat',
};

const thermostatProgrammingOperationModes = {
0: 'setpoint',
1: 'schedule',
};

const thermostatSystemModes = {
0: 'off',
1: 'auto',
Expand Down Expand Up @@ -247,6 +252,7 @@ module.exports = {
repInterval,
defaultBindGroup,
thermostatControlSequenceOfOperations,
thermostatProgrammingOperationModes,
thermostatSystemModes,
thermostatRunningStates,
thermostatRunningMode,
Expand Down
1 change: 1 addition & 0 deletions lib/exposes.js
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,7 @@ module.exports = {
power_outage_memory: () => new Binary('power_outage_memory', access.ALL, true, false).withDescription('Enable/disable the power outage memory, this recovers the on/off mode after power failure'),
presence: () => new Binary('presence', access.STATE, true, false).withDescription('Indicates whether the device detected presence'),
pressure: () => new Numeric('pressure', access.STATE).withUnit('hPa').withDescription('The measured atmospheric pressure'),
programming_operation_mode: () => new Enum('programming_operation_mode', access.ALL, ['setpoint', 'schedule']).withDescription('Controls how programming affects the thermostat. Possible values: setpoint (only use specified setpoint), schedule (follow programmed setpoint schedule). Changing this value does not clear programmed schedules.'),
smoke: () => new Binary('smoke', access.STATE, true, false).withDescription('Indicates whether the device detected smoke'),
soil_moisture: () => new Numeric('soil_moisture', access.STATE).withUnit('%').withDescription('Measured soil moisture value'),
sos: () => new Binary('sos', access.STATE, true, false).withDescription('SOS alarm'),
Expand Down

0 comments on commit 1c30ecb

Please sign in to comment.