Hey folks,
I usually don’t post much (first message actually) but I stumbled upon this thread and it looks exactly like what I succesfully did in my house (if it’s not, it might still help for some parts). Apologies for resurecting a quite old thread.
Also sorry for the long post.
My initial setup was a Hive SLR2 +
SLT3B that were already there when I bought the house 18 months ago.
My problem with that was there was only 1 sensor (presumably on the SLR2) for the whole house and obviously this was install next to the boiler in a tiny laundry room so the room would get warm enough way quicker than the rest of the 2 storey house.
I connected both the SLR2 and SLT3b to MQTT bought a number of TRV (enough Tuya TV02 to cover the ground floor rooms + main one I cared about upstairs) and same amount of external temperature sensors (Sonoff SNZB02)(because my TRVs internal temp sensor are biased since very close to the radiator.
I quickly ditched the SLT3b cause it kept messing with the connection (I’m not sure you can have it controlling the hvac without the hvac losing the connection to your zigbee network, it kinda goes through the SLT3b).
For the pairing of SLR2 to z2MQTT either follow this Hive SLR2 control via MQTT | Zigbee2MQTT or there’s plenty of videos on youtube.
Then for HA config, I have:
- 1 mqtt climate for the SLR2b (actually not sure that is required, this should be autodiscovered but can’t remember why I’ve overriden that )
- 1 simple switch to turn on/off the hvac for temperature
- 1 simple switch to turn on/off the hvac for water heating (not posted here but it’s basically the same as the heater but for the water endpoint)
- 1 switch to control having several thermostat querying hvac to turn on/off (used in the generic_thernostat integration)
- 2 scripts:
- 1 that checks if boiler needs to start (remember there’s loads of thermostats)
- 1 that checks if boiler needs to stop
- couple automation to sync TRV and external sensor temperature (so the TRV don’t cut the heat too early) + heating setpoint (so I can change the wanted temperature for a room from either HA or the valve itself).
Note that I also have 2 radiators with each a TRV in my living room and both are sync to each other through either HA living room thermostat or each of the TRV itself (changing one change the other automatically).
You can then add a generic_thermostat for each room, the sensor needs to be the room external sensor (not the TRV one) and the heater switch you previously setup (the one controlling several thermostats).
Simple heater switch look like this.
# switch.heater
- platform: template
switches:
heater:
icon_template: >-
{% if is_state_attr('climate.slr2', 'running_state_heat', 'heat')%}
mdi:radiator
{% else %}
mdi:radiator-off
{% endif %}
value_template: "{{ 'on' if is_state_attr('climate.slr2', 'running_state_heat', 'heat') else 'off' }}"
turn_on:
- service: mqtt.publish
data:
topic: "zigbee2mqtt/Boiler - Laundry Room/heat/set"
payload: "{ \"system_mode_heat\":\"heat\", \"temperature_setpoint_hold_heat\":\"1\", \"occupied_heating_setpoint_heat\":\"25\" }"
- service: mqtt.publish
data:
topic: "zigbee2mqtt/Boiler - Laundry Room/get"
payload: "{ \"running_state_heat\":\"\" }"
turn_off:
- service: mqtt.publish
data:
topic: "zigbee2mqtt/Boiler - Laundry Room/heat/set"
payload: "{ \"system_mode_heat\": \"off\", \"temperature_setpoint_hold_heat\": \"0\" }"
- service: mqtt.publish
data:
topic: "zigbee2mqtt/Boiler - Laundry Room/get"
payload: "{ \"running_state_heat\":\"\" }"
Turning on arbitrarily set the target temp to 25 as we only care for the temperature to be above the current room temperature where the SLR2 is (so it doesn’t auto turn off). It will be turn off by the generic_thermostat when the room sensor actually reach the “real” target temperature that you set on the thermostat.
Obviously this will not work with several rooms because the thermostats will conflict between each other with such a simple switch. So we need another one:
# switch.heater_therms
- platform: template
switches:
heater_therms:
value_template: "{{ 'on' if is_state_attr('climate.slr2', 'running_state_heat', 'heat') else 'off' }}"
turn_on:
service: script.turn_on
target:
entity_id: script.check_boiler_needs_start
turn_off:
service: script.turn_on
target:
entity_id: script.check_boiler_needs_stop
You could merge those 2 above switches but I like to keep them simple. Also you could use the 1st one as a “force on/off”.
Notice that it calls the 2 scripts that will checks if we actually need to do anything (in case another room is already heating or if all the room reached the target temperature).
The start is simple, we only need to check if it’s already on or not.
# script.check_boiler_needs_start
# script to be called when multiple thermostats try to start the boiler
check_boiler_needs_start:
alias: "Check Boiler Needs Start"
sequence:
- choose:
- conditions:
- not:
- condition: state
entity_id: climate.slr2
attribute: running_state_heat
state: "heat"
sequence:
- service: switch.turn_on
target:
entity_id: switch.heater
default: []
mode: single
The stop is a bit more involved as we need to check every room
# script.check_boiler_needs_stop
## Script to be called when multiple thermostat tries to stop the boiler
check_boiler_needs_stop:
alias: "Check Boiler Needs Stop"
sequence:
- choose:
- conditions:
- alias: "If boiler is heating"
condition: state
entity_id: climate.slr2
attribute: running_state_heat
state: "heat"
- alias: "If all thermostats reached their target temperature"
condition: template
value_template: >-
{% set climates_to_filter = "climate.boiler_*|climate.slr2|climate.trv_*" %}
{% set ns = namespace(found_at_least_one_not_reach_temp = false) %}
{%- for state in states.climate | rejectattr("entity_id", "match", climates_to_filter) | selectattr('state', '!=', 'off') -%}
{%- set ns.found_at_least_one_not_reach_temp = ns.found_at_least_one_not_reach_temp or state_attr(state.entity_id, "temperature") > state_attr(state.entity_id, "current_temperature") -%}
{#{ state.entity_id + "\n" if state_attr(state.entity_id, "temperature") > state_attr(state.entity_id, "current_temperature") }#}
{%- endfor -%}
{{not ns.found_at_least_one_not_reach_temp}}
sequence:
- service: switch.turn_off
target:
entity_id: switch.heater
default: []
mode: single
The value_template part goes through all climates, you need to filter out any climate you want to check using the climates_to_filter variable. Here I filter anything starting with “boiler” “slr2” or “trv_” as I only want the generic_thermostat that I manually setup for each room.
I can post my SLR2 mqtt climate override script if needed but tbh it looks like the default HA MQTT discovery payload so probably not needed if you auto-discover MQTT devices. Let me know if you want me to share te blueprints for the automation scripts to sync external sensor/virtual thermostat/trvs, there’s also plenty of already existing blueprint on this forum.
Here is an example of a virtual room thermostat that ties it all together:
# climate.living_room
# this is your virtual thermostat that you should expose in your UI
- platform: awesome_thermostat
name: living_room
unique_id: climate_living_room
heater: switch.heater_therms
target_sensor: sensor.sensor_livingroom_temperature
cold_tolerance: 0.3
hot_tolerance: 0
min_cycle_duration:
seconds: 5
precision: 0.1
#window_sensor: binary_sensor.livingroom_windows
#motion_sensor: input_boolean.livingroom_motion_sensor
#motion_mode: comfort
#no_motion_mode: eco
#motion_delay:
# minutes: 5
eco_temp: 16
away_temp: 12
boost_temp: 22
comfort_temp: 20
sleep_temp: 18
Pretty standard. I use awesome_thermostat but you can replace it with generic_thermostat and that should work fine.
Of course in all those scripts you should replace the “Boiler - Laundry Room” with the friendly name of your SLR2.
climate.slr2 refers to the mqtt integration of your SLR2 in HA (should be auto discovered from z2mqtt).
Hopefully that is exhaustive enough but feel free to ask for more info.