Herewith I share my implementation for the Atlantic Aurea hybride heatpump. Feedback and suggestions are welcome!
Atlantic Aurea is a hybride heatpump that switches between traditional gas a and heatpump heating. It comes with the Plugwise Smile Opentherm module and a Plugwise Anna thermostat. (see Aurea Hybride add-on - Atlantic Therefore, it can be integrated in Home Assistant using the Plugwise integration.
Unfortunately, there is no direct way to set it to gas or heatpump operation. I experimented with some parameters to influence this. I use an automation that manipulates the Anna thermostat between certain limits to ‘force’ the heatpump mode instead of gas where possible. As long as the outside temperature is higher than 4.5 degrees, it keeps the heatpump running when there is a heat request.
The Anna thermostat is only used to controll the Atlantic aurea, and is in my case located near the gas heater. Instead I use zwave radiator thermostats, so the user can set the temperature there, but couls also be done using a seperate wall thermostat that sets the input helper.
I use multiple temperature sensors in the house and an input_number helper that can be set to enter the desired temperature per room. finally I calculate the difference between de desired temperature and the measured average temperature. This is called the temperature_request.
front end for the users
Settings front end
Stuff for the nerd
Code below is my package (see Packages - Home Assistant) that defines both helpers and the automation.
it defines these entities:
entity | description |
---|---|
input_number.heatpump_setpoint | temperature that the controller wil set the Anna to in order to manipulate it |
input_number.temperature_target | desired home temperature |
sensor.temperature_avg | Average temperature for a room when multiple temperature sensors are used |
sensor.temperature_req_generic | ultimate heat request from all rooms |
sensor.temperature_req | calculated hear request (difference between measured and requested temperature) |
sensor.heatpump_status | indicator if the heatpump is in heatpump or hybrid mode |
sensor.delta_water_heat | actual amount of degrees the unit feeds into the house |
sensor.delta_setpoint | difference between actual Anna setpoint and anna temperature |
sensor.heating_capacity | Percesntage heating power used, for both gas or electric |
sensor.heatpump_capacity | percentage power used for heatpump only (based on electricity usage measurement) |
binary_sensor.heatpump_active | indicating if the heatpump is on |
Note: the capacity of the heatpump is measured using a power plug meter the heatpump is connected to. (in my case sensor.heatpump_electric_consumption_w)
Additionally, it requires the following sensors:
sensor | description |
---|---|
input_boolean.heatpump_force | helper entity to enable or disabling the manipulation |
sensor.smile_anna_outdoor_temperature | provded by Plugwise Anna thermostat |
sensor.opentherm_modulation_level | provded through Plugwise Smile by you gas heater using OpenTherm |
sensor.opentherm_water_temperature | provded through Plugwise Smile by you gas heater using OpenTherm |
sensor.opentherm_intended_boiler_temperature | provded by Plugwise Smile |
sensor.opentherm_return_temperature | provded through Plugwise Smile by you gas heater using OpenTherm |
binary_sensor.opentherm_tap_water | provded through Plugwise Smile by you gas heater using OpenTherm |
climate.anna | provded by Plugwise Anna thermostat |
The Package
heatpump_controler_automation:
# -- COMPONENTS --
# specific components are defined here
input_number:
heatpump_setpoint:
name: doeltemperatuur warmtepomp
icon: mdi:thermometer
unit_of_measurement: '°C'
min: -10
max: 55
mode: box
temperature_target:
name: Thermostaat doeltemperatuur
min: 10
max: 28
step: 0.5
mode: box
unit_of_measurement: '°C'
icon: mdi:home-thermometer-outline
sensor:
- unique_id: S9875243095876324
name: temperature_avg
platform: min_max
type: median
round_digits: 1
entity_ids:
- sensor.temperature_1
- sensor.temperature_2
- sensor.temperature_3
- unique_id: B003874B41197742D5AC2D1552F5630B0
name: temperature_req_generic
unit_of_measurement: '°C'
platform: group
type: max
entities:
- sensor.temperature_req
# - sensor.temperature_req_living
# - sensor.temperature_req_office
template:
- unique_id: C09323445876
sensor:
- name: "temperature_req"
icon: mdi:thermometer-plus
device_class: temperature
unit_of_measurement: '°C'
state: >
{%- set raw_req=(states("input_number.temperature_target") | float(0) - states("sensor.temperature_avg") | float(0)) | round(1)-%}
{%- if raw_req > 0 -%}{{raw_req}}{%- else -%}0{%- endif -%}
- sensor:
unique_id: 01618CE9-A658-4140-87C5-7B597B9BC13C
name: heatpump_status
icon: mdi:heat-pump-outline
state: >
{% set current = this.state |default("", 1)%}
{% if trigger.platform == 'state' or trigger.event.data.value is not defined %}
{{ current }}
{% else %}
{{ trigger.event.data.value }}
{% endif %}
trigger:
- platform: event
event_type: heatpump_status_value
- sensor:
unique_id: c127cd2a-3112-b574-32ab-92c6dd8a322a
name: delta_water_heat
icon: mdi:thermometer
unit_of_measurement: '°C'
state: >
{% set delta= (states("sensor.opentherm_water_temperature") | float(0) - states("sensor.opentherm_return_temperature") | float(0)) | round(2) %}
{%- if delta > 0-%}
{%- if delta < 30-%}{{ delta }}
{%- else -%} 30 {%- endif -%}
{%- else -%} 0 {%- endif -%}
- sensor:
unique_id: c234ab1b-3112-b574-32ab-92c6aaba88311b
name: delta_setpoint
icon: mdi:thermometer
unit_of_measurement: '°C'
state: >
{{ (states("sensor.anna_setpoint") | float(0) - states("sensor.anna_temperature") | float(0)) | round(2) }}
- sensor:
unique_id: c321122a-127cd-b574-32ab-92c6dd8b113
name: heating_capacity
unit_of_measurement: '%'
state: >
{% if states("sensor.opentherm_modulation_level") | float(0) > 0 %}
{{ states("sensor.opentherm_modulation_level") | float(0) }}
{%- else -%}
{% set cap = (((states('sensor.heatpump_electric_consumption_w') | float(0) - 12 ) / 2500 ) * 100) | float(0) | round(1) %}
{% if cap < 0 -%}{% set cap = 0 %}{%- endif %}{{ cap | float(0) }}
{%- endif %}
- sensor:
unique_id: A321122a-127cd-b574-32ab-92c6dd8b111
name: heatpump_capacity
unit_of_measurement: '%'
state: >
{% set cap = ((states('sensor.heatpump_electric_consumption_w') | float(0) - 12 ) / 25) | float(0) | round(1) %}
{% if cap < 0 -%}{% set cap = 0 %}{%- endif %}{{ cap | float(0) }}
- binary_sensor:
unique_id: bb2bcf8e-692b-4cbe-b1ee-7c60a87b212
name: heatpump_active
icon: mdi:heat-pump-outline
state: >
{{ ((states('sensor.heatpump_electric_consumption_w') | float(0) - 12 ) / 25) | float(0) | round(0) > 10 }}
# -- AUTOMATIONS --
# actual magic happens here
automation:
# -- Heatpump Controler --
- id: '1663864767086'
alias: Heatpump Controler
mode: restart
variables:
setpoint_max: 30
water_temp_max: 52
water_temp_delta_max: 8
trigger:
- platform: state
entity_id:
- sensor.temperature_req_generic
- sensor.opentherm_modulation_level
- sensor.opentherm_intended_boiler_temperature
- sensor.heatpump_capacity
for: '00:00:10'
action:
# No heat request
- if:
- condition: template
value_template: '{{ states("sensor.temperature_req_generic") |float(0) <= 0 }}'
then:
- condition: template
value_template: '{{ states("input_number.heatpump_setpoint") |float(0) >= 0 }}'
- service: input_number.set_value
data:
value: -1
target:
entity_id: input_number.heatpump_setpoint
# Heat request (Heatpump or Gas)
else:
- if:
# Heatpump only mode (when outside temp > 4.5)
- condition: state
entity_id: input_boolean.heatpump_force
state: 'on'
- condition: template
value_template: >-
{{
states("sensor.smile_anna_outdoor_temperature") |float(0) > 4.5
}}
then:
# Gas heating is on, try to stop it
- if:
- condition: template
value_template: >
{{
states("binary_sensor.opentherm_tap_water") == "off"
and states("sensor.opentherm_modulation_level") |float(0) > 0
and states("sensor.opentherm_return_temperature") |float(0) > 35
}}
then:
- service: input_number.set_value
target:
entity_id: input_number.heatpump_setpoint
data:
value: -1
# Heatpump control
else:
- if:
# throttle to 0 to keep heatpump active
- condition: template
value_template: >
{% set boiler_temp = states("sensor.opentherm_intended_boiler_temperature") | float(0) %}
{% set water_temp = states("sensor.opentherm_water_temperature") | float(0) %}
{% set heatpump_capacity = states("sensor.heatpump_capacity") | float(0) %}
{{ (boiler_temp - water_temp > water_temp_delta_max | float(0)) or (heatpump_capacity > 80) }}
then:
- service: input_number.set_value
target:
entity_id: input_number.heatpump_setpoint
data:
value: 0
else:
- if:
# ease on when we have a large gap because it tends to switch to Gas
- condition: template
value_template: >
{{ (states("sensor.opentherm_intended_boiler_temperature") | float(0) - states("sensor.opentherm_water_temperature") | float(0)) | abs > 4.5 }}
then:
- service: input_number.set_value
target:
entity_id: input_number.heatpump_setpoint
data:
value: 0.1
# nu issues, just set the setpoint for faster heating
else:
- service: input_number.set_value
target:
entity_id: input_number.heatpump_setpoint
data:
value: '{{ states("sensor.temperature_req_generic") |float(0)}}'
# Don't care about the heatpump, just set the setpoint
else:
- service: input_number.set_value
target:
entity_id: input_number.heatpump_setpoint
data:
value: '{{ states("sensor.temperature_req_generic") |float(0)}}'
# Status update
- event: heatpump_status_value
event_data:
value: >-
{% if is_state("binary_sensor.heatpump_active", "on") %}
Warmtepomp
{% elif states("sensor.heating_capacity") | int(0) > 0 %}
Hybride
{% else %}
Inactief
{% endif %}
# Max setpoint regulation
- if:
- condition: template
value_template: >-
{{ (state_attr("climate.anna","current_temperature") |float(0) + states("input_number.heatpump_setpoint") |float(0))
> setpoint_max |float(0) }}
then:
- service: input_number.set_value
data:
value: '{{ setpoint_max |float(0) - state_attr("climate.anna","current_temperature") |float(0) }}'
target:
entity_id: input_number.heatpump_setpoint
# Heatpump Controler: Apply Setpoint (if it is not set yet)
- if:
- condition: template
value_template: >-
{{ state_attr("climate.anna","temperature") |float(0) |round(1) != (state_attr("climate.anna","current_temperature") |float(0) + states("input_number.heatpump_setpoint") |float(0)) |round(1) }}
then:
- service: climate.set_temperature
data:
temperature: '{{ state_attr("climate.anna","current_temperature") |float(0) + states("input_number.heatpump_setpoint") |float(0) |round(1) }}'
#target_temp_high: 30
#target_temp_low: 10
target:
entity_id: climate.anna
- service: logbook.log
data:
name: Verwarming
message: >-
TEMP SET ( {{ state_attr("climate.anna","current_temperature") |float(0) + states("input_number.heatpump_setpoint") |float(0) |round(1) }}°C ->
{{ state_attr("climate.anna","temperature") |float(0) }} /
{{ state_attr("climate.anna","current_temperature") |float(0) }}°C )