How to set up your Hive heating system with Home Assistant

Edit: 14/12/24 to include step for Hive Local Thermostat
Edit: 22/12/24 The same principles should apply to the Danfoss Ally TRVs. The Hive TRVs are detected as Danfoss by Z2M. Not sure if the Danfoss boiler control/ thermostat operate the same way though

How to move from Hive to Home Assistant

Please note that I am not an expert in HA in any way whatsoever. This post is to detail my own observations on using Hive with HA via ZIgbee2MQTT and I’m happy to be corrected if anything is wrong

I’ve been having issues in the past month with my Hive heating system not working correctly in Home Assistant. I don’t know why, will likely never find out and don’t particularly care as it gave me a final push to move wholesale over to Home Assistant controlled heating. In case it’s pertinent, I have a gas boiler for my heating with a separate hot water tank.

What I’m moving
11 Hive TRVs
1 Hive Thermostat
1 Hive Heating and Hot Water Receiver

I’ve already got a Zigbee2MQTT network set up so all devices were added to this same network. The first thing I did was turn off the Hive hub. Then I followed the pairing instructions from here - Hive SLR2 control via MQTT | Zigbee2MQTT - to add the Receiver and then quickly after, the Thermostat.

Apparently the quick way to put Hive TRVs into pairing mode is to remove them from the Hive app. As I mentioned earlier the first thing I did was turn off the Hub so I couldn’t do that. I manually put each TRV into pairing mode by removing a battery then holding the button below the temperature screen while popping the battery back in. It didn’t take long and worked out for the best as it meant I was adding each TRV individually so could keep track of which one was which.

Setting up the TRVs
There’s a lot of entities and switches for each TRV. Be careful not click on anything you don’t want to! I don’t claim to be anywhere near an expert and admit to being a bit flummoxed over some of the settings available however I only found a few settings need changed -

Mounted Mode Control - false
Programmed Operation Mode - setpoint

And for my particular case, the following were set
Thermostat vertical orientation - true
Viewing Direction - true

For each TRV, set Adaption Run Control to initiate_adaption. This tells the TRVs to find the points when the valve is fully closed and open and allows them to more accurately determine flow rate into the radiators.

I didn’t change any settings for the Thermostat. A brief note on the Thermostat, as you may wonder why only one entity is exposed (Battery). The Thermostat is necessary to send a command to the Receiver to turn on the boiler and that seems to be the only function I can find for it. In Zigbee2MQTT the Receiver Exposes are split into two - one for the heating, the bottom one for the hot water. I set System Mode to Heat for both of them and changed nothing else.

Setting up Home Assistant
This first step is important and is NOT optional. In HACS, download Hive Local Thermostat and take your time to set it up correctly. If this step is skipped or not set up correctly then your heating system will not respond correctly to commands. As the maintainer states, the Hive Heating and Boiler Receiver requires a series of MQTT commands to be issued in a certain order to work. Once Hive Local Thermostat is set up, you don’t have to worry about it.

I use another HACS custom component called Better Thermostat to create a meta TRV for each physical TRV. I have various temperature and humidity sensors in each room as well as a weather station outside all hooked into HA. Better Thermostat allows me to use these external sensors and in my opinon provides a warmer house without any spikes in temperature which happened with Hive. You don’t need to use Better Thermostat but I recommend it. From now on when I talk about thermostats I’ll mean the Better Thermostat ones.

I used two types of Helper - the first one is a Binary Sensor Group of all the Hive TRVs. This will be used in an automation later. The second helper used is Schedule which I used to create schedules (shockingly enough) for each Better Thermostat TRV and also the Hot Water.

One thing that really bothered me moving from Hive to HA is how to turn the boiler on and off when the TRVs required heat. Thankfully, Hive TRVs expose a sensor called Heat Required which does exactly what it says on the tin. When heat is needed by the TRV, the sensor turns On, when it’s not, the sensor is Off. The Binary Group Sensor created in the previous paragraph turns On when ANY TRV is On and Off when ALL TRVs are Off. I created two Automations (which should probably be just one) to set the Target Temperature on my Receiver to 25 which turns on the boiler and hot water starts being pumped out to any radiators that require it.

Turning on the hot water took me a bit of figuring out as the Controls exposed don’t tally with what I expected and seem to be redundant. At this moment I’m still not sure that everything is 100% working here but the hot water was turned on and the hot water tank got hot which is a good start. My hot water tank has a thermostat on it so all I needed was a way to turn the hot water tank on via the Receiver. This was achieved using Climate.Turn_on. “Hive Boiler Control” is my name for the Receiver.

Automations
In all cases remember to change the entity_id to your own

alias: House - Call for heat action ON
description: ""
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.hive_trvs
    to: "on"
conditions: []
actions:
  - action: climate.set_temperature
    metadata: {}
    data:
      temperature: 25
      hvac_mode: heat
    target:
      entity_id: climate.hive_boiler_control_heat
mode: single
alias: House - Call for heat action OFF
description: ""
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.hive_trvs
    to: "off"
conditions: []
actions:
  - action: climate.set_temperature
    metadata: {}
    data:
      temperature: 15
    target:
      entity_id: climate.hive_local_boiler_control_climate
  - delay:
      hours: 0
      minutes: 0
      seconds: 10
      milliseconds: 0
  - action: climate.turn_off
    metadata: {}
    data: {}
    target:
      entity_id: climate.hive_local_boiler_control_climate
mode: single

Hot Water - on/ off

alias: Schedule - Hot Water
description: ""
triggers:
  - entity_id:
      - schedule.schedule_hot_water
    trigger: state
conditions:
  - condition: template
    value_template: "{{ trigger.to_state.state in ['on', 'off'] }}"
actions:
  - alias: Off? - turn hot water off. On? - turn it on!
    if:
      - condition: state
        entity_id: schedule.schedule_hot_water
        state: "on"
    then:
      - action: climate.turn_on
        metadata: {}
        data: {}
        target:
          entity_id: climate.hive_boiler_control_water
# below, the "button" pressed is the Hot Water Boost on the Hive Local Thermostat
      - device_id: 31f09acfcca5ef40e3ad727e51810a85
        domain: button
        entity_id: 94878aaf86b8ae356033ad75134088da
        type: press
    else:
      - action: climate.turn_off
        metadata: {}
        data: {}
        target:
          entity_id: climate.hive_boiler_control_water
mode: restart

Schedule Run - note I have different temps for Off, Morning and Evening. These are variables in my own set up which I replaced for clarity

alias: Schedule - Temperature Kitchen
triggers:
  - entity_id:
      - schedule.schedule_kitchen_hive
    trigger: state
conditions:
  - condition: template
    value_template: "{{ trigger.to_state.state in ['on', 'off'] }}"
actions:
  - if:
      - condition: state
        entity_id: schedule.schedule_kitchen_hive
        state: "off"
    then:
      - data:
          temperature: 14
        target:
          entity_id: climate.kitchen_hive_bt
        action: climate.set_temperature
    else:
      - if:
          - condition: time
            before: "10:00:00"
        then:
          - data:
              temperature: 18
            target:
              entity_id: climate.kitchen_hive_bt
            action: climate.set_temperature
        else:
          - data:
              temperature: 20
            target:
              entity_id: climate.kitchen_hive_bt
            action: climate.set_temperature
2 Likes

Nice write up! I’ve just derived my Hive over to Z2M so am going through this. I have the Hive Local installed and configured to my receivers topic but I’m not sure if it’s doing anything, it’s not detecting any temperatures or anything. I can control the boiler though from it’s Z2M entry so maybe it is!

I assume for the group for your trvs that’s set to any? Also, any reason you have the on/off in 2 separate blueprints rather than using trigger IDs and a choose action?

Yes, the Hive TRV group is set to Any ie Group Options/ All Entities is disabled.

The reason for two separate Automations for on/ off is that I don’t have the necessary knowledge to set trigger IDs. If you do then please post your Automation as I’d like to use it!

With Hive Local you need to add the boiler controller in using Add Device. You’ll be asked for the MQTT name which in my case was zigbee2mqtt/HiveBoilerControl - HiveBoilerControl being the name I gave it in MQTT

I’ve created a simple one for my underfloor heating with a button on a dashboard for choosing how long the timer should be set for and then use a choose to set the temp:

alias: Heating - Underfloor Boost
description: ""
triggers:
  - event_type: timer.started
    event_data:
      entity_id: timer.underfloor_boost_timer
    trigger: event
    id: Timer Started
  - event_type: timer.finished
    event_data:
      entity_id: timer.underfloor_boost_timer
    id: Timer Finished
    trigger: event
conditions:
  - condition: not
    conditions:
      - condition: time
        after: "06:30:00"
        before: "09:00:00"
      - condition: time
        after: "16:00:00"
        before: "21:30:00"
actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - Timer Started
        sequence:
          - action: climate.set_temperature
            metadata: {}
            data:
              temperature: 23
              hvac_mode: heat
            target:
              entity_id: climate.underfloor_heating
      - conditions:
          - condition: trigger
            id:
              - Timer Finished
        sequence:
          - action: climate.turn_off
            metadata: {}
            data: {}
            target:
              entity_id: climate.underfloor_heating
mode: single

The one for my TRVs is a bit of a mess, but I have created this dashboard where I can choose how long to boost for, and which radiator to turn on:

Then my automation looks at toggle and timer helpers to control turning the TRVs on and off, outside of the normal sheduled hours, and as those hours depend on the schedules for each TRV, that check is built into each TRV statement. I’m sure there’s a much cleaner way to do it!

alias: Heating - Upstairs boost
description: ""
triggers:
  - event_type: timer.started
    event_data:
      entity_id: timer.heating_boost_timer
    trigger: event
    id: Timer Started
  - event_type: timer.finished
    event_data:
      entity_id: timer.heating_boost_timer
    id: Timer Finished
    trigger: event
  - trigger: state
    entity_id:
      - input_boolean.b....._radiator_toggle
    to: "on"
    id: B..... On
  - trigger: state
    entity_id:
      - input_boolean.b....._radiator_toggle
    to: "off"
    id: B..... Off
  - trigger: state
    entity_id:
      - input_boolean.bedroom_radiator_toggle
    to: "on"
    id: Bedroom On
  - trigger: state
    entity_id:
      - input_boolean.bedroom_radiator_toggle
    to: "off"
    id: Bedroom Off
  - trigger: state
    entity_id:
      - input_boolean.office_radiator_toggle
    to: "on"
    id: Office On
  - trigger: state
    entity_id:
      - input_boolean.office_radiator_toggle
    to: "off"
    id: Office Off
  - trigger: state
    entity_id:
      - input_boolean.end_bathroom_radiator_toggle
    to: "on"
    id: End Bathroom On
  - trigger: state
    entity_id:
      - input_boolean.end_bathroom_radiator_toggle
    to: "off"
    id: End Bathroom Off
conditions: []
actions:
  - choose:
      - conditions:
          - condition: trigger
            id:
              - Timer Started
        sequence:
          - action: climate.set_temperature
            metadata: {}
            data:
              temperature: 21
            target:
              entity_id: climate.hivecontroller
        alias: Boost heating on timer start
      - conditions:
          - condition: trigger
            id:
              - Timer Finished
        sequence:
          - if:
              - condition: and
                conditions:
                  - condition: not
                    conditions:
                      - condition: time
                        after: "06:30:00"
                        before: "08:30:00"
                  - condition: not
                    conditions:
                      - condition: time
                        after: "16:00:00"
                        before: "22:00:00"
            then:
              - action: climate.set_temperature
                metadata: {}
                data:
                  temperature: 5
                target:
                  entity_id: climate.hivecontroller
            alias: Turn off Hive outside of schedule
          - if:
              - condition: and
                conditions:
                  - condition: and
                    conditions:
                      - condition: not
                        conditions:
                          - condition: time
                            after: "06:30:00"
                            before: "08:30:00"
                      - condition: not
                        conditions:
                          - condition: time
                            after: "16:00:00"
                            before: "21:00:00"
                  - condition: state
                    entity_id: input_boolean.b....._radiator_toggle
                    state: "on"
            then:
              - action: input_boolean.turn_off
                target:
                  entity_id: input_boolean.b....._radiator_toggle
                data: {}
            alias: Turn off B..... Radiator outside of schedule
          - if:
              - condition: and
                conditions:
                  - condition: and
                    conditions:
                      - condition: not
                        conditions:
                          - condition: time
                            after: "06:30:00"
                            before: "08:30:00"
                      - condition: not
                        conditions:
                          - condition: time
                            after: "18:00:00"
                            before: "22:00:00"
                  - condition: state
                    entity_id: input_boolean.bedroom_radiator_toggle
                    state: "on"
            then:
              - action: input_boolean.turn_off
                target:
                  entity_id:
                    - input_boolean.bedroom_radiator_toggle
                data: {}
            alias: Turn off Bedroom Radiator outside of schedule
          - alias: Turn off Office Radiator outside of schedule
            if:
              - condition: and
                conditions:
                  - condition: and
                    conditions:
                      - condition: not
                        conditions:
                          - condition: time
                            after: "06:30:00"
                            before: "08:30:00"
                      - condition: not
                        conditions:
                          - condition: time
                            after: "18:00:00"
                            before: "22:00:00"
                  - condition: state
                    entity_id: input_boolean.office_radiator_toggle
                    state: "on"
            then:
              - action: input_boolean.turn_off
                target:
                  entity_id:
                    - input_boolean.office_radiator_toggle
                data: {}
          - alias: Turn off End Bathroom Radiator outside of schedule
            if:
              - condition: and
                conditions:
                  - condition: and
                    conditions:
                      - condition: not
                        conditions:
                          - condition: time
                            after: "06:30:00"
                            before: "08:30:00"
                      - condition: not
                        conditions:
                          - condition: time
                            after: "16:00:00"
                            before: "22:00:00"
                  - condition: state
                    entity_id: input_boolean.end_bathroom_radiator_toggle
                    state: "on"
            then:
              - action: input_boolean.turn_off
                target:
                  entity_id:
                    - input_boolean.end_bathroom_radiator_toggle
                data: {}
          - alias: Turn off Office Radiator outside of schedule
            if:
              - condition: and
                conditions:
                  - condition: and
                    conditions:
                      - condition: not
                        conditions:
                          - condition: time
                            after: "06:30:00"
                            before: "08:30:00"
                      - condition: not
                        conditions:
                          - condition: time
                            after: "18:00:00"
                            before: "22:00:00"
                  - condition: state
                    entity_id: input_boolean.office_radiator_toggle
                    state: "on"
            then:
              - action: input_boolean.turn_off
                target:
                  entity_id:
                    - input_boolean.office_radiator_toggle
                data: {}
        alias: Turn off heating and radiators on timer stop
      - conditions:
          - condition: trigger
            id:
              - B..... On
        sequence:
          - action: climate.set_temperature
            metadata: {}
            data:
              temperature: 20
            target:
              entity_id: climate.b.....s_heating
        alias: Turn on B.....s radiator on trigger
      - conditions:
          - condition: trigger
            id:
              - Bedroom On
        sequence:
          - action: climate.set_temperature
            metadata: {}
            data:
              temperature: 21
            target:
              entity_id: climate.bedroom_heating_bedroom_heating
        alias: Turn on Beroom radiator on trigger
      - conditions:
          - condition: trigger
            id:
              - Office On
        sequence:
          - action: climate.set_temperature
            metadata: {}
            data:
              temperature: 20
            target:
              entity_id:
                - climate.office_heating
        alias: Turn on Office radiator on trigger
      - conditions:
          - condition: trigger
            id:
              - End Bathroom On
        sequence:
          - action: climate.set_temperature
            metadata: {}
            data:
              temperature: 21
            target:
              entity_id:
                - climate.end_bathroom_heating
        alias: Turn on End Bathroom radiator on trigger
      - conditions:
          - condition: trigger
            id:
              - B..... Off
        sequence:
          - action: climate.set_temperature
            metadata: {}
            data:
              temperature: 15
            target:
              entity_id: climate.b.....s_heating
        alias: Turn off B.....s radiator on trigger
      - conditions:
          - condition: trigger
            id:
              - Bedroom Off
        sequence:
          - action: climate.set_temperature
            metadata: {}
            data:
              temperature: 15
            target:
              entity_id: climate.bedroom_heating_bedroom_heating
        alias: Turn off Beroom radiator on trigger
      - conditions:
          - condition: trigger
            id:
              - Office Off
        sequence:
          - action: climate.set_temperature
            metadata: {}
            data:
              temperature: 15
            target:
              entity_id:
                - climate.office_heating
        alias: Turn off Office radiator on trigger
      - conditions:
          - condition: trigger
            id:
              - End Bathroom Off
        sequence:
          - action: climate.set_temperature
            metadata: {}
            data:
              temperature: 15
            target:
              entity_id:
                - climate.end_bathroom_heating
        alias: Turn off End Bathroom radiator on trigger
mode: queued
max: 10