An external ESPHome component to control a boiler (or other supported HVAC appliances) over the OpenTherm protocol. Note that special hardware is required, like the DIYLESS Master OpenTherm Shield or Ihor Melnyk's OpenTherm Adapter. This component acts only as an OpenTherm master (i.e. a thermostat or controller) and not as a slave or gateway. You can no longer use your existing thermostat if you control your boiler through ESPHome with this component.
We aim for maximum flexibility in this component by exposing most of the information available through the OpenTherm protocol, while allowing all configuration in YAML. (No custom component code required!) Since every boiler and every situation is different, you have to play around a bit with the sensors you'd want to read. There is no requirement for a boiler to support everything in the protocol, so not every sensor in this component will work with your boiler. (For example, my Remeha Avanta does not report ch_pressure
, dhw_flow_rate
or t_dhw
.)
This component uses @FreeBear-nc's OpenTherm Library (MIT licensed) (a fork of @ihormelnyk's OpenTherm Library) as its communication layer. The message loop is inspired by code for the DIYLESS ESP32 Wi-Fi Thermostat (MIT licensed).
Alternatives:
- ESPHome-OpenTherm by @rsciriano, a custom component based on the same library as this project
- esphome-opentherm by @wichers, which works as a gateway, rather than a master, allowing you to combine the system with your own thermostat
- And more options if you search on GitHub
- CH: Central Heating
- DHW: Domestic Hot Water
The OpenTherm Master component is available as an external component in ESPHome and can be included in your configuration as follows:
external_components:
source: github://freebear-nc/esphome-opentherm@main
A forked version of @ihormelnyk's OpenTherm Library is also required:
esphome:
platformio_options:
lib_deps:
- https://github.com/freebear-nc/opentherm_library.git
This references the main branch, which is cool if you want to stay up to date, but may also break your configuration if breaking changes happen here. A better idea would be to reference a specific version, see the tags for available versions. Instead of a specific version, you could also choose to follow a major version by specifying @v1
etc.
Then you can define the OpenTherm hub in your configuration:
opentherm:
master_id: 5
in_pin: 4
out_pin: 5
ch_enable: true
dhw_enable: true
cooling_enable: false
otc_active: false
ch2_active: false
sync_mode: false
master_id
: Some boilers require a master member ID before functioning properly. Defaults to 5ch_enable
: Central Heating enabled Defaults to Truedhw_enable
: Domestic Hot Water enabled Defaults to Truecooling_enable
: Cooling enabled Defaults to Falseotc_active
: Outside temperature compensation active Defaults to Falsech2_active
: Central Heating 2 active Defaults to Falsesync_mode
: Synchronous communication mode prevents other components from disabling interrupts whilst communicating with the boiler. Enable if you experience random intermittent invalid response errors. Very likely to happen while using Dallas temperature sensors. Defaults to False
The most important function for a thermostat is to set the boiler temperature setpoint. This component has three ways to provide this input: using a sensor from which the setpoint can be read, using a number, or defining an output to which other components can write. For most users, the last option is the most useful one, as it can be combined with the PID Climate component to create a thermostat that works as you would expect a thermostat to work. See thermostat-pid-basic.yaml for an example.
There are three ways to set an input value:
-
As an input sensor, defined in the hub configuration:
opentherm: t_set: setpoint_sensor sensor: - platform: homeassistant id: setpoint_sensor entity_id: sensor.boiler_setpoint
This can be useful if you have an external thermostat-like device that provides the setpoint as a sensor.
-
As a number:
number: - platform: opentherm t_set: name: Boiler Setpoint
This is useful if you want full control over your boiler and want to manually set all values.
-
As an output:
output: - platform: opentherm t_set: id: setpoint
This is especially useful in combination with the PID Climate component:
climate: - platform: pid heat_output: setpoint # ...
For the output and number variants, there are four more properties you can configure beyond those included in the output and number components by default:
min_value
(float): The minimum value. For a number this is the minimum value you are allowed to input. For an output this is the number that will be sent to the boiler when the output is at 0%.max_value
(float): The maximum value. For a number this is the maximum value you are allowed to input. For an output this is the number that will be sent to the boiler when the output is at 100%.auto_max_value
(boolean): Automatically configure the maximum value to a value reported by the boiler. Not available for all inputs.auto_min_value
(boolean): Automatically configure the minimum value to a value reported by the boiler. Not available for all inputs.
The following inputs are available:
t_set
: Control setpoint: temperature setpoint for the boiler's supply water (°C) Defaultmin_value
: 0 Defaultmax_value
: 100 Supportsauto_max_value
t_set_ch2
: Control setpoint 2: temperature setpoint for the boiler's supply water on the second heating circuit (°C) Defaultmin_value
: 0 Defaultmax_value
: 100 Supportsauto_max_value
cooling_control
: Cooling control signal (%) Defaultmin_value
: 0 Defaultmax_value
: 100t_dhw_set
: Domestic hot water temperature setpoint (°C) Defaultmin_value
: 0 Defaultmax_value
: 127 Supportsauto_min_value
Supportsauto_max_value
max_t_set
: Maximum allowable CH water setpoint (°C) Defaultmin_value
: 0 Defaultmax_value
: 127 Supportsauto_min_value
Supportsauto_max_value
t_room_set
: Current room temperature setpoint (informational) (°C) Defaultmin_value
: -40 Defaultmax_value
: 127t_room_set_ch2
: Current room temperature setpoint on CH2 (informational) (°C) Defaultmin_value
: -40 Defaultmax_value
: 127t_room
: Current sensed room temperature (informational) (°C) Defaultmin_value
: -40 Defaultmax_value
: 127max_rel_mod_level
: Maximum relative modulation level (%) Defaultmin_value
: 0 Defaultmax_value
: 127 Supportsauto_min_value
For five status codes, switches are available to toggle them manually. The same values can be set in the hub configuration, like so:
opentherm:
ch_enable: true
dhw_enable: true
This can be used to set the value without the need for a switch if you'd never want to toggle it after the initial configuration. The default values for these configuration options are listed below.
For enabling of central heating and cooling, the enable-flag is only sent to the boiler if the following conditions are met:
- the flag is set to true in the hub configuration,
- the switch is on, if it is configured,
- the setpoint or cooling control value is not 0, if it is configured.
For domestic hot water and outside temperature compensation, only the first two conditions are necessary.
The last point ensures that central heating is not enabled if no heating is requested as indicated by a setpoint of 0. If you use a number as the setpoint input and use a minimum value higher than 0, you NEED to use the ch_enable switch to turn off your central heating. In that case the flag will be set to true in the hub configuration, and setpoint is always larger than 0, so including a switch is the only way you can turn off central heating. (This also holds for cooling and CH2.)
The following switches are available:
ch_enable
: Central Heating enabled Defaults to Truedhw_enable
: Domestic Hot Water enabled Defaults to Truecooling_enable
: Cooling enabled Defaults to Falseotc_active
: Outside temperature compensation active Defaults to Falsech2_active
: Central Heating 2 active Defaults to Falsesm_active
: Summer mode active Defaults to Falsedhw_block
: DHW Blocking Defaults to Falselock_out_reset
: Boiler Lock-out Reset Defaults to False
The component can report boiler status on several binary sensors. The Status sensors are updated in each message cycle, while the others are only set during initialization, as they are unlikely to change without restarting the boiler.
fault_indication
: Status: Fault indicationch_active
: Status: Central Heating activedhw_active
: Status: Domestic Hot Water activeflame_on
: Status: Flame oncooling_active
: Status: Cooling activech2_active
: Status: Central Heating 2 activediagnostic_indication
: Status: Diagnostic eventdhw_present
: Configuration: DHW presentcontrol_type_on_off
: Configuration: Control type is on/offcooling_supported
: Configuration: Cooling supporteddhw_storage_tank
: Configuration: DHW storage tankcontroller_pump_control_allowed
: Configuration: Master pump control allowedch2_present
: Configuration: CH2 presentdhw_setpoint_transfer_enabled
: Remote boiler parameters: DHW setpoint transfer enabledmax_ch_setpoint_transfer_enabled
: Remote boiler parameters: CH maximum setpoint transfer enableddhw_setpoint_rw
: Remote boiler parameters: DHW setpoint read/writemax_ch_setpoint_rw
: Remote boiler parameters: CH maximum setpoint read/writeservice_request
: Service Requestlockout_reset
: Lockout Resetlow_water_pressure
: Low Water Pressureflame_fault
: Gas/Flame Faultair_pressure_fault
: Air Pressure Faultwater_over_temperature
: Water Over Temperature
The boiler can also report several numerical values, which are available through sensors. Your boiler may not support all of these values, in which case there won't be any value published to that sensor. The following sensors are available:
rel_mod_level
: Relative modulation level (%)ch_pressure
: Water pressure in CH circuit (bar)dhw_flow_rate
: Water flow rate in DHW circuit (l/min)t_boiler
: Boiler water temperature (°C)t_dhw
: DHW temperature (°C)t_outside
: Outside temperature (°C)t_ret
: Return water temperature (°C)t_storage
: Solar storage temperature (°C)t_collector
: Solar collector temperature (°C)t_flow_ch2
: Flow water temperature CH2 circuit (°C)t_dhw2
: Domestic hot water temperature 2 (°C)t_exhaust
: Boiler exhaust temperature (°C)burner_starts
: Number of starts burnerch_pump_starts
: Number of starts CH pumpdhw_pump_valve_starts
: Number of starts DHW pump/valvedhw_burner_starts
: Number of starts burner during DHW modeburner_operation_hours
: Number of hours that burner is in operationch_pump_operation_hours
: Number of hours that CH pump has been runningdhw_pump_valve_operation_hours
: Number of hours that DHW pump has been running or DHW valve has been openeddhw_burner_operation_hours
: Number of hours that burner is in operation during DHW modet_dhw_set_ub
: Upper bound for adjustment of DHW setpoint (°C)t_dhw_set_lb
: Lower bound for adjustment of DHW setpoint (°C)max_t_set_ub
: Upper bound for adjustment of max CH setpoint (°C)max_t_set_lb
: Lower bound for adjustment of max CH setpoint (°C)otc_ratio_ub
: Upper bound of OTC curve ()otc_ratio_lb
: Lower bound of OTC curve ()t_dhw_set
: Domestic hot water temperature setpoint (°C)max_t_set
: Maximum allowable CH water setpoint (°C)otc_hc_ratio
: OTC heat curve ratio (°C)oem_fault_code
: OEM fault code ()t_heat_exchanger
: Boiler heat exchanger temperature (°C)fan_speed
: Boiler fan speed ()boiler_flame_current
: Boiler flame current (uA) ()oem_diagnostic_code
: OEM diagnostic code ()max_capacity
: Maximum boiler capacity (KW) (kW)min_mod_level
: Minimum modulation level (%)opentherm_version_device
: Version of OpenTherm implemented by slave ()device_type
: Slave product type ()device_version
: Slave product version ()device_id
: Slave ID code ()
If ESPHome reports that it is unable to find the component, this might be due to the use of an older version of Python. It should work on version 3.9 (which is what runs in CI) and higher, but older versions may not support all typing features used in this project. You can update to a newer Python version, or install the backported typing library with pip install typing-extensions
. (Thanks to @Arise for figuring this out!)