SOLVED (?) Pls help improve heating control

Hi everybody,

I am using SPZB0001 zigbee thermostats on my radiators and Xiaomi Door Sensors (also zigbee) for my doors and windows.

As temperatures changed rather quick from too hot to too cold (located in Northern Germany), I had to quickly set this up in Home Assistant (switched to HA a few months ago and used a different solution before, so I had to start fresh with my automations for this).

Below is one example from my heating package, which includes a similar code for each thermostat, door, and window, but to make it easier to read I stripped it down to this one specific radiator.

# input slider so that I can set each radiator manually
input_number:
  slider01:
    name: Arbeitszimmer
    initial: 17.5
    <<: &heizung_template
        min: 5
        max: 25
        step: 1
        icon: mdi:radiator
        unit_of_measurement: "°C"

# automations for
# 1. setting temperature
# 2. automatically turning off when window open
# 3. because of time_pattern (see below) automatically set temperature to previous value when window has been closed

automation:
  - id: 'heizung_az_set'
    alias: "[Heizung] AZ Set"
    trigger: 
      - platform: time_pattern # pretty sure there is a MUCH better way to do this; previously I had used "state", which worked, but it'd ONLY set temperature after I changed the slider; nothing would happen after a restart of Home Assistant, so I switched to time_pattern
        seconds: "/10"
     condition:
       - condition: state
         entity_id: binary_sensor.window_az_contact
         state: "off"
      action:
        - service: mqtt.publish
          data_template:
            topic: "zigbee2mqtt/Heizung_Arbeitszimmer/set"
            payload: '{"current_heating_setpoint": {{ states.input_number.slider01.state | float }}}' 
            qos: 2
            retain: false


  - id: 'heizung_az_autooff'
    alias: "[Heizung] AZ Auto Off"
    trigger:
      - platform: state
        entity_id: binary_sensor.fenster_az_contact
        to: "on"
    action: 
       - service: mqtt.publish
         data_template:  # using template so that I could change the (currently hardcoded) payload value of 5 to something variable
           topic: "zigbee2mqtt/Heizung_Arbeitszimmer/set"
           payload: '{"current_heating_setpoint": 5}'
           qos: 2
           retain: false  

This works! I change the temperature via Home Assistant on my smartphone and it will almost instantly (max. 9 seconds delay due to time_pattern of 10 seconds) set the thermostat accordingly. So far, so good.

However, I have some ideas on how to improve this; are those good, or should I stick with my current solution:

  1. have one single automation for both
    => I am sure this will be possible somehow; I haven’t used jinja2 for templates much, but I thought it might be an option to have a single automation that will check whether or not the window is open, and, if so, return the “low” temperature value (currently hard coded to 5), and if not set and/or restore the previously set value. I just don’t know how to do this
  2. use anchors
    => as you can see at the top with input_number:, I am using anchors for some keys/values so that I don’t have to type them over and over again; how would I do this for the entire automation below?

I would have to set anchors for

  • automation:
    • id
    • alias
  • condition:
    • entity_id
  • action:
    • service: mqtt.publish
      • topic
      • payload

If this is doable, I’d just need help with how to write the anchors part… because I don’t know how to use them in this more complex syntax (compared to what I did above, where every key/value for the anchor would be right below each other, without any indents etc. - hope I explained this somewhat understandably, I am not a native English speaker, so sorry if this sounds kinda weird).

Thank you for your ideas :slight_smile:

I added these lines

automation:
#(...)
  - id: 'heizung_az_transfer'
    alias: "[Heizung] AZ Transfer"
    trigger:
      - platform: state
        entity_id: sensor.heizung_az_current
    action:
      - service: input_number.set_value
        data_template:
          entity_id: input_number.slider01
          value: "{{ states('sensor.heizung_az_current') }}"

sensor:
  - platform: mqtt
    name: "[Heizung] AZ Current"
    state_topic: "home/zigbee2mqtt/Heizung_Arbeitszimmer"
    value_template: "{{ value_json.current_heating_setpoint }}"
    qos: 2
    unit_of_measurement: "°C"
    icon: mdi:radiator

This allows me to control the radiator manually. However, due to the time_pattern, sometimes Home Assistant will publish the “old” value before the “new” (=manually set) value has been published via mqtt and sets the radiator back to the old temperature. For now, I will fix this by setting 30 seconds delay instead of 10, but in general I need to find a better solution for this. Any ideas are greatly appreciated :slight_smile:

Anybody? I came up with this as a template:

{% if is_state('binary_sensor.fenster_arbeitszimmer_contact', 'off') + is_state('binary_sensor.tuer_arbeitszimmer_contact', 'off') %}
  {"current_heating_setpoint": {{ states('input_number.slider01') | float }}}
{% else %}
  {"current_heating_setpoint": {{ 5.0 | float }} }
{% endif %}

This will output 5.0 when either the window, or the door are open - but if they are both shut, it will output whatever the slider is set to. So far, so good.

However, I need to trigger this whenever either of these conditions are true

  • window changes status
  • door changes status
  • slider changes value

Also, time_pattern is definitely not an option for a trigger; I have tested this ~2 days now; when I manually change the value at the wrong time (around when time_pattern triggers) directly at the thermostat, my manual change will be overwritten.

I will just do some trial and error with my yaml for now, but if anybody has a concrete solution, please let me know.

I believe I have solved this myself… but if this is not the ideal solution, please let me know what else I might be able to improve.

  - id: 'heizung_az_set'
    alias: "[Heizung] AZ Set"
    trigger:
      - platform: state
        entity_id: input_number.slider01
      - platform: state
        entity_id: binary_sensor.fenster_arbeitszimmer_contact
    action:
      - service: mqtt.publish
        data_template:
          topic: "home/zigbee2mqtt/Heizung_Arbeitszimmer/set"
          payload: >
            {% if is_state('binary_sensor.fenster_arbeitszimmer_contact', 'off') %}
               {"current_heating_setpoint": {{ states('input_number.slider01') | float }}}
            {% else %}
               {"current_heating_setpoint": 5}
            {% endif %}
          qos: 2
          retain: false
  - id: 'heizung_az_transfer'
    alias: "[Heizung] AZ Transfer"
    trigger:
      - platform: state
        entity_id: sensor.heizung_az_current
    action:
      - service: input_number.set_value
        data_template:
          entity_id: input_number.slider01
          value: >
            {% if states('sensor.heizung_az_current') | float > 5 %}
              {{ states('sensor.heizung_az_current') }}
            {% else %}
              {{ states('input_number.slider01') }}
            {% endif %}

The value part in heizung_az_transfer will assure that the slider stays at whatever it was set to when the window opens (and thus turns the heat to 5°C), so as soon as the window gets shut, it will revert to that value :slight_smile: