The dual_smart_thermostat
is an enhanced version of generic thermostat implemented in Home Assistant.
Heater/Cooler Mode | docs | |
Heater Only Mode | docs | |
Two Stage (AUX) Heating Mode | docs | |
Fan Only mode | docs | |
Fan With Cooler mode | docs | |
Cooler Only mode | docs | |
Dry mode | docs | |
Heat Pump mode | docs | |
Floor Temperature Control | docs | |
Window/Door sensor integration | docs | |
Presets | docs | |
HVAC Action Reason | docs |
If both heater
and cooler
entities configured. The thermostat can control heating and cooling and you are able to set min/max low and min/max high temperatures.
In this mode you can turn the thermostat to heat only, cooler only and back to heat/cool mode.
If the fan
entity is set the thermostat can control the fan mode of the AC. The fan will turn on when the temperature is above the target temperature and the fan_hot_tolerance is not reached. If the temperature is above the target temperature and the fan_hot_tolerance is reached the AC will turn on.
If only the heater
entity is set the thermostat works only in heater mode.
Two stage or AUX heating can be enabled by adding the required configuration entities: secondary_heater
, secondary heater_timeout
. If these are set the feature will enable automatically.
Optionally you can set secondary heater_dual_mode
to true
to turn on the secondary heater together with the primary heater.
If the timeout ends and the heater
was on for the whole time the thermostat switches to the secondary heater
. In this case the primary heater (heater
) will be turned off. This will be remembered for the day it turned on and in the next heating cycle the secondary heater
will turn on automatically.
On the next day the primary heater will turn on again the second stage will again only turn on after a timeout.
If the third secondary heater_dual_mode
is set to true
the secondary heater will be turned on together with the primary heater.
secondary_heater: switch.study_secondary_heater # <-- required
secondary_heater_timeout: 00:00:30 # <-- required
secondary_heater_timeout: true # <-- optional
If the fan_mode
entity is set to true the thermostat works only in fan mode. The heater entity will be treated as a fan only device.
heater: switch.study_heater
fan_mode: true
If the ac_mode
is set to true and the fan
entity is also set, the heater entity will be treated as a cooler (AC) device with an additional fan device. This will allow not only to use a separate physical fan device but also to turn on the fan mode of an AC using advanced switches.
With this setup, you can use the fan mode of your AC in a simpler way.
heater: switch.study_heater
ac_mode: true
fan: switch.study_fan
If you also set the fan_hot_tolerance
the fan will turn on when the temperature is above the target temperature and the fan_hot_tolerance is not reached. If the temperature is above the target temperature and the fan_hot_tolerance is reached the AC will turn on.
heater: switch.study_heater
ac_mode: true
fan: switch.study_fan
fan_hot_tolerance: 0.5
If you set the fan_hot_tolerance
, outside_sensor
and the fan_air_outside
the fan will turn on only if the outside temperature is colder than the inside temperature and the fan_hot_tolerance is not reached. If the outside temperature is colder than the inside temperature and the fan_hot_tolerance is reached the AC will turn on.
Some AC systems have independent fan controls to cycle the house air for filtering or humidity control; without using the heating or cooling elements. Central AC systems require the thermostat to turn on both the AC wire ("Y" wire) and the air-handler/fan wire ("G" wire) in order to activate the AC
This feature lets you do just that.
In order to use this feature you need to set the heater
entity, the ac_mode
, the fan)
entity and the fan_on_with_ac
to true
.
heater: switch.study_heater
ac_mode: true
fan: switch.study_fan
fan_on_with_ac: true
If only the cooler
entity is set the thermostat works only in cooling mode.
If the dryer
entity is set the thermostat can switch to dry mode. The dryer will turn on when the humidity is above the target humidity and the moist_tolerance
is not reached. If the humidity is above the target humidity and the moist_tolerance
is reached the dryer will stop.
heater: switch.study_heater
target_sensor: sensor.study_temperature
ac_mode: true
dryer: switch.study_dryer
humidity_sensor: sensor.study_humidity
moist_tolerance: 5
dry_tolerance: 5
heater: switch.study_heater
cooler: switch.study_cooler
target_sensor: sensor.study_temperature
dryer: switch.study_dryer
humidity_sensor: sensor.study_humidity
moist_tolerance: 5
dry_tolerance: 5
This setup allows you to use a single switch for both heating and cooling. To enable this mode you define only a single switch for the heater and set the set youer heat pump's current state (heating or cooling) as for the heat_pump_cooling
attribute. This must be an entity id of a sensor that has a state of heating
or cooling
.
The entity can be an input buulean for manual control or an entity that provided by the heat pump.
heater: switch.study_heat_pump
target_sensor: sensor.study_temperature
heat_pump_cooling: sensor.study_heat_pump_state
heater: switch.study_heat_pump
target_sensor: sensor.study_temperature
heat_pump_cooling: sensor.study_heat_pump_state
heat_cool_mode: true
heating (heat_pump_cooling: false):
- heat/cool
- heat
- off
cooling (heat_pump_cooling: true):
- heat/cool
- cool
- off
heater: switch.study_heat_pump
target_sensor: sensor.study_temperature
heat_pump_cooling: sensor.study_heat_pump_state
heat_cool_mode: false # <-- or not set
heating (heat_pump_cooling: false):
- heat
- off
cooling (heat_pump_cooling: true):
- cool
- off
The dual_smart_thermostat
can turn off heating or cooling if a window or door is opened and turn heating or cooling back on when the door or window is closed to save energy.
The openings
configuration variable accepts a list of opening entities and opening objects.
An opening entity is a sensor that can be in two states: on
or off
. If the state is on
the opening is considered open, if the state is off
the opening is considered closed.
The opening object can contain a timeout property that defines the time in seconds after which the opening is considered open even if the state is still on
. This is useful if you would want to ignore windows opened only for a short time.
The openings_scope
configuration variable defines the scope of the openings. If set to all
or not defined, any open openings will turn off the current hvac device and it will be in the idle state. If set, only devices that operating in the defined HVAC modes will be turned off. For example, if set to heat
only the heater will be turned off if any of the openings are open.
openings_scope: [heat, cool, heat_cool, fan_only, dry]
openings_scope:
- heat
- cool
# Example configuration.yaml entry
climate:
- platform: dual_smart_thermostat
name: Study
heater: switch.study_heater
cooler: switch.study_cooler
openings:
- binary_sensor.window1
- binary_sensor.window2
- entity_id: binary_sensor.window3
timeout: 00:00:30
openings_scope: [heat, cool]
target_sensor: sensor.study_temperature
The dual_smart_thermostat
can turn off if the floor heating reaches the maximum allowed temperature you define in order to protect the floor from overheating and damage.
To enable this protection you need to set two variables:
floor_sensor: sensor.floor_temp
max_floor_temp: 28
The dual_smart_thermostat
can turn on if the floor temperature reaches the minimum required temperature you define in order to protect the floor from freezing or to keep it on a comfortable temperature.
# Example configuration.yaml entry
climate:
- platform: dual_smart_thermostat
name: Study
unique_id: study
heater: switch.study_heater
cooler: switch.study_cooler
target_sensor: sensor.study_temperature
floor_sensor: sensor.floor_temp
max_floor_temp: 28
min_floor_temp: 5
Currently supported presets are:
To set presets you need to add entries for them in the configuration file like this:
You have 4 options here:
- Set the
temperature
for heat, cool or fan-only mode - Set the
target_temp_low
andtarget_temp_high
for heat_cool mode. Iftemperature
is not set buttarget_temp_low
andtarget_temp_high
are set, thetemperature
will be picked based on hvac mode. For heat mode it will betarget_temp_low
and for cool, fan_only mode it will betarget_temp_high
- Set the
humidity
for dry mode - Set all above
preset_name:
temperature: 13
humidity: 50 # <-- only if dry mode configured
target_temp_low: 12
target_temp_high: 14
State attribute: hvac_action_reason
The dual_smart_thermostat
will set the hvac_action
attribute to heating
, cooling
, idle
or off
based on the current state of the thermostat. The hvac_action
attribute is used to indicate the current action of the thermostat. The dual_smart_thermostat
will also set the hvac_action_reason
attribute based on the current state of the thermostat. The hvac_action_reason
attribute is used to indicate the reason for the current action of the thermostat.
The hvac_action_reason
attribute is grouped by internal and external values.
The internal values can be set by the component only and the external values can be set by the user or automations.
Value | Description |
---|---|
none |
No action reason |
target_temp_not_reached |
The target temperature has not been reached |
target_temp_not_reached_with_fan |
The target temperature has not been reached trying it with a fan |
target_temp_reached |
The target temperature has been reached |
target_humidity_reached |
The target humidity has been reached |
target_humidity_not_reached |
The target humidity has not been reached |
misconfiguration |
The thermostat is misconfigured |
opening |
The thermostat is idle because an opening is open |
limit |
The thermostat is idle because the floor temperature is at the limit |
overheat |
The thermostat is idle because the floor temperature is too high |
temperature_sensor_stalled |
The thermostat is idle because the temperature sensor is not provided data for the defined time that could indicate a malfunctioning sensor |
humidity_sensor_sstalled |
The thermostat is idle because the temperature sensor is not provided data for the defined time that could indicate a malfunctioning sensor |
Value | Description |
---|---|
none |
No action reason |
presence |
the last HVAc action was triggered by presence |
schedule |
the last HVAc action was triggered by schedule |
emergency |
the last HVAc action was triggered by emergency |
malfunction |
the last HVAc action was triggered by malfunction |
dial_smart_thermostat.set_hvac_action_reason
is exposed for automations to set the hvac_action_reason
attribute. The service accepts the following parameters:
Parameter | Description | Type | Required |
---|---|---|---|
entity_id | The entity id of the thermostat | string | yes |
hvac_action_reason | The reason for the current action of the thermostat | HVACActionReasonExternal | yes |
(required) (string) Name of thermostat
default: Dual Smart
(optional) (string) the unique id for the thermostat. It allows you to customize it in the UI and to assign the component to an area.
_default: none
(required) (string) "entity_id
for heater switch, must be a toggle device. Becomes air conditioning switch when ac_mode
is set to true
"
(optional, required for two stage heating) (string) "entity_id
for secondary heater switch, must be a toggle device.
(optional, required for two stage heating) (time, integer) Set a minimum amount of time that the switch specified in the heater option must be in its ON state before secondary heater devices needs to be turned on.
(optional, (bool) If set true the secondary (aux) heater will be turned on together with the primary heater.
(optional) (string) "entity_id
for cooler switch, must be a toggle device."
(optional) (bool) If set to true
the heater entity will be treated as a fan only device.
(optional) (string) "entity_id
for fan switch, must be a toggle device."
(optional) (float) Set a maximum amount of difference between the temperature read by the sensor specified in the target_sensor option and the target temperature and the hot_tolerance that considered to be ok for the fan to be turned on. For example, if the target temperature is 25 and the hot_tolerance is 1 and the fan_hot_tolerance is 0.5 the fan will start when the sensor equals or goes above 25 but not above 25.5. In that case the AC will turn on.
requires: fan
(optional) (string) entity_id
for a switch that will toggle the fan_hot_tolerance
feature on and off.
This is enabled by default.
default: True
requires: fan
, fan_hot_tolerance
(optional) (boolean) If set to true
the fan will be turned on together with the AC. This is useful for central AC systems that require the fan to be turned on together with the AC.
requires: fan
(optional) (boolean) "If set to true
the fan will be turned on only if the outside temperature is colder than the inside temperature and the fan_hot_tolerance
is not reached. If the outside temperature is colder than the inside temperature and the fan_hot_tolerance
is reached the AC will turn on."
requires: fan
, sensor_outside
(optional) (string) "entity_id
for dryer switch, must be a toggle device."
(optional) (float) Set a minimum amount of difference between the humidity read by the sensor specified in the humidity_sensor option and the target humidity that must change prior to being switched on. For example, if the target humidity is 50 and the tolerance is 5 the dryer will start when the sensor equals or goes below 45.
requires: dryer
, humidity_sensor
(optional) (float) Set a minimum amount of difference between the humidity read by the sensor specified in the humidity_sensor option and the target humidity that must change prior to being switched off. For example, if the target humidity is 50 and the tolerance is 5 the dryer will stop when the sensor equals or goes above 55.
requires: dryer
, humidity_sensor
(optional) (string) "entity_id
for a humidity sensor, humidity_sensor.state must be humidity."
(required) (string) "entity_id
for a temperature sensor, target_sensor.state must be temperature."
(optional) (timedelta) Set a delay for the target sensor to be considered not stalled. If the sensor is not available for the specified time or doesn't get updated the thermostat will be turned off.
requires: target_sensor
and/or huidity_sensor
(optional) (string) "entity_id
for the floor temperature sensor, floor_sensor.state must be temperature."
(optional) (string) "entity_id
for the outside temperature sensor, oustide_sensor.state must be temperature."
(optional) (list) "list of opening entity_id
's and/or objects for detecting open widows or doors that will idle the thermostat until any of them are open. Note: if min_floor_temp is set and the floor temperature is below the minimum temperature, the thermostat will not idle even if any of the openings are open."
entity_id: <value>
The entity id of the opening bstate sensor (string)
timeout: <value>
The time after which the opening is considered open even if the state is still on
(timedata)
(optional) (array[string]) "The scope of the openings. If set to [all
] or not defined, any open openings will turn off the current hvac device and it will be in the idle state. If set, only devices that operating in the defined HVAC modes will be turned off. For example, if set to heat
only the heater will be turned off if any of the openings are open."
default: all
options:
- all
- heat
- cool
- heat_cool
- fan_only
(optional) (string) "entity_id
for the heat pump cooling state sensor, heat_pump_cooling.state must be heating
or cooling
."
enables heat pump mode
(optional) (float)
default: 7
(optional) (float)
default: 35
(optional) (float)
default: 28
(optional) (float)
(optional) (float) Set initial target temperature. If this variable is not set, it will retain the target temperature set before restart if available.
(optional) (float) Set initial target low temperature. If this variable is not set, it will retain the target low temperature set before restart if available.
(optional) (float) Set initial target high temperature. If this variable is not set, it will retain the target high temperature set before restart if available.
(optional) (boolean) Set the switch specified in the heater
option to be treated as a cooling device instead of a heating device. This parameter will be ignored if cooler
entity is defined.
default: false
(optional) (boolean) If variable target_temp_low
and target_temp_high
are not set, this parameter must be set to true to enable the heat_cool
mode.
default: false
(optional) (time, integer) Set a minimum amount of time that the switch specified in the heater and/or cooler option must be in its current state prior to being switched either off or on.
(optional) (float) Set a minimum amount of difference between the temperature read by the sensor specified in the target_sensor option and the target temperature that must change prior to being switched on. For example, if the target temperature is 25 and the tolerance is 0.5 the heater will start when the sensor equals or goes below 24.5.
default: 0.3
(optional) (float) Set a minimum amount of difference between the temperature read by the sensor specified in the target_sensor option and the target temperature that must change prior to being switched off. For example, if the target temperature is 25 and the tolerance is 0.5 the heater will stop when the sensor equals or goes above 25.5.
default: 0.3
(optional) (time, integer) Set a keep-alive interval. If set, the switch specified in the heater and/or cooler option will be triggered every time the interval elapses. Use with heaters and A/C units that shut off if they don't receive a signal from their remote for a while. Use also with switches that might lose state. The keep-alive call is done with the current valid climate integration state (either on or off).
(optional) (string) Set the initial HVAC mode. Valid values are off
, heat
, cool
or heat_cool
. Value has to be double quoted. If this parameter is not set, it is preferable to set a keep_alive value. This is helpful to align any discrepancies between dual_smart_thermostat heater and cooler state.
NOTE! If this is set, the saved state will not be restored after HA restarts.
(optional) (list) Set the temperatures used by preset_mode: away
. If this is not specified, the preset mode feature will not be available.
Possible values are:
temperature: <value>
The preset temperature to use in heat
or cool
mode (float)
target_temp_low: <value>
The preset low temperature to use in heat_cool
mode (float)
target_temp_high: <value>
The preset high temperature to use in heat_cool
mode (float)
(optional) (list) Set the temperature used by preset_mode: eco
. If this is not specified, the preset mode feature will not be available.
Possible values are:
temperature: <value>
The preset temperature to use in heat
or cool
mode (float)
target_temp_low: <value>
The preset low temperature to use in heat_cool
mode (float)
target_temp_high: <value>
The preset high temperature to use in heat_cool
mode (float)
(optional) (list) Set the temperature used by preset_mode: home
. If this is not specified, the preset mode feature will not be available.
Possible values are:
temperature: <value>
The preset temperature to use in heat
or cool
mode (float)
target_temp_low: <value>
The preset low temperature to use in heat_cool
mode (float)
target_temp_high: <value>
The preset high temperature to use in heat_cool
mode (float)
(optional) (list) Set the temperature used by preset_mode: comfort
. If this is not specified, the preset mode feature will not be available.
Possible values are:
temperature: <value>
The preset temperature to use in heat
or cool
mode (float)
target_temp_low: <value>
The preset low temperature to use in heat_cool
mode (float)
target_temp_high: <value>
The preset high temperature to use in heat_cool
mode (float)
(optional) (list) Set the temperature used by preset_mode: sleep
. If this is not specified, the preset mode feature will not be available.
Possible values are:
temperature: <value>
The preset temperature to use in heat
or cool
mode (float)
target_temp_low: <value>
The preset low temperature to use in heat_cool
mode (float)
target_temp_high: <value>
The preset high temperature to use in heat_cool
mode (float)
(optional) (list) Set the temperature used by preset_mode: Anti Freeze
. If this is not specified, the preset mode feature will not be available.
Possible values are:
temperature: <value>
The preset temperature to use in heat
or cool
mode (float)
target_temp_low: <value>
The preset low temperature to use in heat_cool
mode (float)
target_temp_high: <value>
The preset high temperature to use in heat_cool
mode (float)
(optional) (list) Set the temperature used by preset_mode: Activity
. If this is not specified, the preset mode feature will not be available.
Possible values are:
temperature: <value>
The preset temperature to use in heat
or cool
mode (float)
target_temp_low: <value>
The preset low temperature to use in heat_cool
mode (float)
target_temp_high: <value>
The preset high temperature to use in heat_cool
mode (float)
(optional) (list) Set the temperature used by preset_mode: Boost
. If this is not specified, the preset mode feature will not be available.
This preset mode only works in heat
or cool
mode because boosting temperatures on heat_cools
mode will require setting target_temp_low
higher than target_temp_high
and vice versa.
Possible values are:
temperature: <value>
The preset temperature to use in heat
or cool
mode (float)
(optional) (float) The desired precision for this device. Can be used to match your actual thermostat's precision. Supported values are 0.1
, 0.5
and 1.0
.
default: 0.5
for Celsius and 1.0
for Fahrenheit.
(optional) (float) The desired step size for setting the target temperature. Supported values are 0.1
, 0.5
and 1.0
.
default: Value used for precision
Installation is via the Home Assistant Community Store (HACS), which is the best place to get third-party integrations for Home Assistant. Once you have HACS set up, simply search the Integrations
section for Dual Smart Thermostat.
climate:
- platform: dual_smart_thermostat
name: Study
heater: switch.study_heater
target_sensor: sensor.study_temperature
initial_hvac_mode: "heat"
For two stage heating both the heater
and secondary_heater
must be defined. The secondary_heater
will be turned on only if the heater
is on for the amount of time defined in secondary_heater_timeout
.
climate:
- platform: dual_smart_thermostat
name: Study
heater: switch.study_heater
secondary_heater: switch.study_secondary_heater # <-requred
secondary_heater_timeout: 00:00:30 # <-requred
target_sensor: sensor.study_temperature
initial_hvac_mode: "heat"
climate:
- platform: dual_smart_thermostat
name: Study
heater: switch.study_cooler
ac_mode: true # <-important
target_sensor: sensor.study_temperature
initial_hvac_mode: "cool"
climate:
- platform: dual_smart_thermostat
name: Study
heater: switch.study_heater
target_sensor: sensor.study_temperature
initial_hvac_mode: "heat"
floor_sensor: sensor.floor_temp # <-required
max_floor_temp: 28 # <-required
min_floor_temp: 20 # <-required
This mode is used when you want (and can) control both the heater and the cooler. In this mode the target_temp_low
and target_temp_high
must be set.
In this mode you can switch between heating and cooling by setting the hvac_mode
to heat
or cool
or heat_cool
.
climate:
- platform: dual_smart_thermostat
name: Study
heater: switch.study_heater # <-required
cooler: switch.study_cooler # <-required
target_sensor: sensor.study_temperature
heat_cool_mode: true # <-required
initial_hvac_mode: "heat_cool"
climate:
- platform: dual_smart_thermostat
name: Study
heater: switch.study_heater
cooler: switch.study_cooler
target_sensor: sensor.study_temperature
openings: # <-required
- binary_sensor.window1
- binary_sensor.window2
- entity_id: binary_sensor.window3
timeout: 00:00:30 # <-optional
The dual_smart_thermostat
has two tolerance variables: cold_tolerance
and hot_tolerance
. These variables are used to prevent the heater or cooler from switching on and off too frequently. For example, if the target temperature is 25 and the tolerance is 0.5 the heater will start when the sensor equals or goes below 24.5. The heater will stop when the sensor equals or goes above 25.5. This prevents the heater from switching on and off too frequently when the temperature is close to the target temperature.
If the thermostat is set to heat_cool mode the tolerance will work in the same way for both the heater and the cooler.
climate:
- platform: dual_smart_thermostat
name: Study
heater: switch.study_heater
cooler: switch.study_cooler
target_sensor: sensor.study_temperature
cold_tolerance: 0.3
hot_tolerance: 0
climate:
- platform: dual_smart_thermostat
name: Study
heater: switch.study_heater
cooler: switch.study_cooler
secondary_heater: switch.study_secondary_heater
secondary_heater_timeout: 00:00:30
target_sensor: sensor.study_temperature
floor_sensor: sensor.floor_temp
max_floor_temp: 28
openings:
- binary_sensor.window1
- binary_sensor.window2
- entity_id: binary_sensor.window3
timeout: 00:00:30
min_temp: 10
max_temp: 28
ac_mode: false
target_temp: 17
target_temp_high: 26
target_temp_low: 23
cold_tolerance: 0.3
hot_tolerance: 0
min_cycle_duration:
seconds: 5
seconds: 5
keep_alive:
minutes: 3
initial_hvac_mode: "off" # hvac mode will reset to this value after restart
away: # this preset will be available for all hvac modes
temperature: 13
target_temp_low: 12
target_temp_high: 14
home: # this preset will be available only for heat or cool hvac mode
temperature: 21
precision: 0.1
target_temp_step: 0.5
I am happy to help the Home Assistant community but I do it in my free time at the cost of spending less time with my family. Feel free to motivate me and appreciate my sacrifice by donating:
Use pytest to run the tests:
pytest
Specific test
pytest tests/test_heater_mode.py
Log Level
pytest --log-cli-level=DEBUG