Guru needed please:- multi-zone , multi-temp heating automation

Problem:

  • I have smart TRVs across the home , 1 in every room.
  • Each TRV is controlled over mqtt integration and can send/receive target and actual temps.
  • Each TRV controlled via UI Generic Thermostat
  • I have a boiler controlled by a Z-wave 2-channel (Hot Water and Central Heating) switch (a Danfoss RX)
  • Boiler switches are binary_switch components in the UI
  • I wish to control the Central Heating channel by determining if any of the TRVs are demanding heat (i.e. actual temp <> target temp)
  • If there is a demand for heat , turn the Heating channel on. Otherwise, turn it off.

Current config:

Issues:

Issue 1 - Boiler kettling

I have to set the thermostats to off on the UI to prevent them running the heating on and off and on and off and ā€¦ all through the night. Then in the morning I have to set the thermostats on the UI to heating. - PITA. Is there a better way? Iā€™d prefer to have some controlling switch that I can set to AUTO, OFF and ON, such as:-

AUTO = use thermostats
ON = set heat demand permanently on irrespective of thermostats.
OFF = cancel heat demand permanently on irrespective of thermostats

I cannot turn the system on or off permanently. Once i can do this, then I can automate the setting of ON/OFF/AUTOMATE. Small steps first though. Ideally, Iā€™d like this to be integrated as a single entity rather than using the simple two switch entities (Hot Water and Central Heating) as above. But if thatā€™s not possible then whatā€™s the best way? Not sure what integration / component / platform / services to use? Dont need a config.yaml from you, just the design model I should use and Iā€™ll google it in HA docs.

Issue 2 - Multizone not working

The automation isnt working correctly to my mind.
Currently , each generic therms seem to be ā€œpolledā€ , in order. Whichever is the last to be polled seems to control the heat demand on the Boiler settings. For example, if the heating is on and the ā€œlastā€ therm to be polled has an actual temp that is greater than the user demand (the orange circle) then the heating is switched off , despite what the other two thermostats are doing - for example one might still be calling for heat but is disregarded.
What I actually want is:-

IF Central Heating switch is On 
   AND
   all 3 thermostats have reached target temperature 
THEN
   turn off Central Heating Boiler Switch
ELSE
   IF Central Heating is Off 
      AND
      any one of the thermostats actual is less than desired temp
   THEN
      turn Central Heating Switch On
   END IF
END IF

It is all probably working according to my config; the issue is I am not sure what design model I need to use to achieve my intents above:-

My config is below:-

# configuration.yaml 

climate:
  - platform: generic_thermostat
    name: lounge
    heater: switch.danfoss_rxz3_rf_relay_switching_unit_switch_2
    target_sensor: sensor.lounge_temperature
    min_temp: 10
    max_temp: 23
    cold_tolerance: 0.3
    hot_tolerance: 0.3
    initial_hvac_mode: "heat"
    precision: 0.5
  - platform: generic_thermostat
    name: summer
    heater: switch.danfoss_rxz3_rf_relay_switching_unit_switch_2
    target_sensor: sensor.summer_temperature
    min_temp: 10
    max_temp: 23
    cold_tolerance: 0.3
    hot_tolerance: 0.3
    initial_hvac_mode: "heat"
    precision: 0.5
  - platform: generic_thermostat
    name: dad
    heater: switch.danfoss_rxz3_rf_relay_switching_unit_switch_2
    target_sensor: sensor.dad_temperature
    min_temp: 10
    max_temp: 23
    cold_tolerance: 0.3
    hot_tolerance: 0.3
    initial_hvac_mode: "heat"
    precision: 0.5

# automations.yaml

- alias: 'Dad temp automate'
  trigger:
    platform: state
    entity_id: climate.dad
  action:
    service: input_number.set_value
    entity_id: input_number.dad_temp
    data_template:
       value: "{{ trigger.to_state.attributes.temperature | float }}"
- alias: 'Lounge temp automate'
  trigger:
    platform: state
    entity_id: climate.lounge
  action:
    service: input_number.set_value
    entity_id: input_number.lounge_temp
    data_template:
       value: "{{ trigger.to_state.attributes.temperature | float }}"
- alias: 'Summer temp automate'
  trigger:
    platform: state
    entity_id: climate.summer
  action:
    service: input_number.set_value
    entity_id: input_number.summer_temp
    data_template:
       value: "{{ trigger.to_state.attributes.temperature | float }}"

Help!

Many thanks

EDIT 1:

Found this: Auto heating control - not easy :)
May be this would help with Issue 2; I would have a binary sensor that is moded On/Off according to the On/Off state of the 3x therms. I will look into this.
UPDATE: Nope. That wonā€™t work because the Generic Thermostats all require the heating variable to be defined. I dont want that. I want a binary_sensor template sensor to be set something like this, and for the Central Heating switch to be set accordingly:-

# Switch to set CH On or Off depending on thermostat heat demands
binary_sensor:
  platform: template
  sensors:
    auto_ch_switch
      value_template: >
        {{ is_state('climate.dad' , 'on')
           or is_state('climate.summer , 'on' )
           or is_state('climate.lounge' , 'on') }}

1 Like

Make a binary sensor that looks for the state of all 3 thermostats. You can add any logic to this binary sensor. Like verifying that the heat is below temp or if you arenā€™t at target temp etc. If you take a screenshot of the climate devices in the states page, I can help you out with that. Iā€™d also need to know the main desired state. So take a screenshot of the states page when one of the climate devices is ā€˜onā€™ and one of the climate devices is ā€˜offā€™.

Then your logic is pretty easy, but you have to build it differently than you are thinking about it. There is no if else in automation flow. You can emulate that with the proper triggers, which is what we will do.

Hi thanks. However, the three therms have a heater variable that is mandatory. I kind of see where youā€™re coming from but it would require another thermostat entity that doesnt require the heater parameter, i.e. sensing only, no actioning.

Can you please just post what I asked for? I know this can work. You do not need to create any action in order to grab the current state. Please, take a screenshot of the device in developer tools / states page with all the attributes. 1 screenshot when on & heating, 1 screenshot when off.

Understood, i will defer to your wisdom, thank you and apologies for my ignorance. I will do this when home in about 5 hrs.

When ā€œheatā€

When ā€œoffā€

When ā€œidleā€

As I alluded to above,
Without the heater variable , HA will throw an error. With it, the function is not what I want and as per above.
But - I guess you have that one covered?

Mar 03 18:01:54 pi hass[4755]: 2020-03-03 18:01:54 ERROR (MainThread) [homeassistant.config] Invalid config for [climate.generic_thermostat]: required key not provided @ data['heater']. Got None. (See /home/homeassistant/.homeassistant/configuration.yaml, line 22). Please check the docs at https://www.home-assistant.io/integrations/generic_thermostat

Yes, so you build it with automations. So to clarify, you want the following automations:

central heating turned on, and all 3 thermostats are at target temp
ā†’ Turn off boiler switch

central heating turned off, and any one of the thermostats is below target temp
ā†’ turn on boiler switch.

Are you still trying to get a ā€˜masterā€™ thermostat?

Correct!

no, no master thermostat, just the three moded as you correctly state.

1 more thing, this ā€˜central heatingā€™, is this going to just be an input boolean? Or is this an existing device?

at the moment
it is just a binary switch mapped to a z-wave channel
and is provided as the heater parameter value on the thermostats

but if thereā€™s a better way then by all means educate me.

where you gone?

Sorry, busy night. What do you mean binary switch mapped to a z-wave channel? Can you use home assistant lingo and provide entity idā€™s?

Central Heating is the friendly name for switch.danfoss_rxz3_rf_relay_switch_2 that was auto discovered.

switch.danfoss_rxz3_rf_relay_switch_2 is the entity name assigned to all the heater variables on the climate.generic_thermostat* entity which is on the cards.

Ok, all you need is 2 automationsā€¦ I donā€™t know your other climate devices so iā€™ll just give them fake names. You can replace the entity idā€™s for climate.room1 and climate.room2. Just replace the portion after the last period only. Do not touch the states.climate.

automation 1

This turns off the switch if all the thermostats are above the target temperature.

- alias: Turn off heater if all climates are equal or above target.
  trigger:
  - platform: template
    value_template: >
      {% set therms = [
        states.climate.lounge,
        states.climate.room1,
        states.climate.room2,
        ] %}
      {% set climates = namespace(at_target=[]) %}
      {% for therm in therms %}
      {% if therm.attributes.current_temperature >= therm.attributes.temperature %}
      {% set climates.at_target = climates.at_target + [ therm.entity_id ] %}
      {% endif %}
      {% endfor %}
      {{ climates.at_target | length == therms | length }}
  condition:
  - condition: state
    entity_id: switch.danfoss_rxz3_rf_relay_switch_2
    state: 'on'
  action:
    service: switch.turn_off
    entity_id: switch.danfoss_rxz3_rf_relay_switch_2

automation 2

This turns on the switch if one or more are below temperature.

- alias: Turn on heaters that are under temp
  trigger:
  - platform: template
    value_template: >
      {% set therms = [
        states.climate.lounge,
        states.climate.room1,
        states.climate.room2,
        ] %}
      {% set climates = namespace(under=[]) %}
      {% for therm in therms %}
      {% if therm.attributes.current_temperature < therm.attributes.temperature %}
      {% set climates.under = climates.under + [ therm.entity_id ] %}
      {% endif %}
      {% endfor %}
      {{ climates.under | length > 0 }}
  condition:
  - condition: state
    entity_id: switch.danfoss_rxz3_rf_relay_switch_2
    state: 'off'
  action:
    service: switch.turn_on
    entity_id: switch.danfoss_rxz3_rf_relay_switch_2
2 Likes

ā€¦and what about the heater mandatory variable on the generic thermostat (GT) which I mentioned twice but was assured not to worry. The GTs cards require this variable and use it to mode switch.danfoss_rxz3_rf_relay_switch_2

Just make an input boolean for them. It can be the same one used in all places. I was under the impression that you needed one of these for

Not the individual thermostats.

Either way. Just make a fake input_boolean and use that as the heater.

Right
I will set about this later when Iā€™m home.
thank you in advance.
I also looked at your GitHub to get a few ideas . Iā€™m a Software Developer for a bluechip UK company here , 35yrs, Python is in my CV and I note I can use it here. Cool. I see youā€™re quite a guru on HA architecture and system modelling.
Will feedback in due course with screenshots

Many thanks
Daz

Thereā€™s about 100 ways to skin this cat, so this solution is not 100% full proof. If you know python, I recommend moving to appdaemon for this.

Python - I wrote a lot of code for Enigma2 if you know what that is?
AppDaemon; thatā€™s a new one. Another area to explore. Iā€™ve just searched in HA and bookmarked a page. Now that looks more my kind of thing than yaml based modelling, granted some will still be required to configure the apps. Is this a suitable learning base? https://appdaemon.readthedocs.io/en/stable/

Yep, thatā€™s the docs. It suits me better too. While I know the automation system very well, Iā€™m still more comfortable with appdaemon. You can do all sorts of logic and itā€™s easier to manage 1 app than it is to manage 10 separate yaml automations.