Templating voodoo - identify a list of switches that are OFF only in order

Hi there;

I can’t remember when I wrote this template but i’m 99% sure I yoinked it from this community, but now I need to modify it.

Currently the below automation works mostly but I need a way to identify if a switch is on or off and excluding the “on” switches from the list. i.e. I need to identify the switch on top of the list that is “off”.

Currently it identifies all switches in order of greatest temperature difference, regardless of switch status.

Does anyone with template knowledge know how to add a line to the second “then” template to only identify & list the switches that are off?

Thanks

- id / alias; "progressive heat zone control"
  triggers:
  - entity_id:
    - sensor.inside_temp_average
  conditions:
  - condition: state
    entity_id: climate.daikin
    state: heat
  actions:
  - if:
    - condition: template
      value_template: '{% set nameslist = expand("sensor.heating_difference_master","sensor.heating_difference_room2","sensor.heating_difference_room3","sensor.heating_difference_bathroom","sensor.heating_difference_office","sensor.heating_difference_kitchen")%}
        {% set nameslist = nameslist | sort(attribute=''state'',reverse = true ) | map ( attribute=''entity_id'' ) | list %}
        {% set nameslist = nameslist | first | string %}
        {% set entity_is = (state_attr(nameslist, ''control_switch'')) %}
        {% if states(entity_is) == ''off'' %}
        true
        {% else %}
        false
        {% endif %}'
    then:
    - data_template:
        entity_id: '{% set nameslist = expand("sensor.heating_difference_master","sensor.heating_difference_room2","sensor.heating_difference_room3","sensor.heating_difference_bathroom","sensor.heating_difference_office","sensor.heating_difference_kitchen")%}
          {% set nameslist = nameslist | sort(attribute=''state'',reverse = true ) | map ( attribute=''entity_id'' ) | list %} {% set nameslist = nameslist | first | string %} {{ (state_attr(nameslist, ''control_switch'')) }}'
      action: switch.turn_on
  mode: single

try this:

- data_template:
    entity_id: >
      {% set nameslist = expand(
        "sensor.heating_difference_master",
        "sensor.heating_difference_room2",
        "sensor.heating_difference_room3",
        "sensor.heating_difference_bathroom",
        "sensor.heating_difference_office",
        "sensor.heating_difference_kitchen"
        )%}
      {% set nameslist = nameslist
        | rejectattr('state','eq','on')
        | sort(attribute=''state'',reverse = true )
        | map ( attribute=''entity_id'' )
        | list
        %}
      {% set nameslist = nameslist
        | first
        | string
        %}
      {{ (state_attr(nameslist, ''control_switch'')) }}

It’s the same (I just put it onto separate lines to make it easier to read) and added | rejectattr('state','eq','on')

If you want to put it back onto a single line, remember to (re)surround it in quotes.

I’m confused why you need this in order or why you want the first one. This here does what you want, but also gives you the option to use just the first or all switches that are off. Keep in mind that this still only turns on the first one.

- id / alias; "progressive heat zone control"
  triggers:
  - entity_id:
    - sensor.inside_temp_average
  conditions:
  - condition: state
    entity_id: climate.daikin
    state: heat
  actions:
  - variables:
      sensors:
      - sensor.heating_difference_master
      - sensor.heating_difference_room2
      - sensor.heating_difference_room3
      - sensor.heating_difference_bathroom
      - sensor.heating_difference_office
      - sensor.heating_difference_kitchen
      information: >
        {% set ns = namespace(items=[]) %}
        {% for sensor in sensors if sensor | has_value %}
          {% set switch = state_attr(sensor, 'control_switch') %}
          {% set ns.items = ns.items + [dict(sensor=sensor, state=states(sensor) | float, switch=switch)] %}
        {% endfor %}
        {{ ns.items | sort(attribute='state', reverse=True) }}
      targets: > 
        {{ information | selectattr('switch', 'is_state', 'off') | list }}
  - condition: template
    value_template: "{{ targets | length > 0 }}"
  - target:
      entity_id: "{{ (targets | first).switch }}"
    action: switch.turn_on
  mode: single

This also allows you to debug the templates when using the trace. You can see your information in order before you use it later on.

Thanks @jchh & @petro for these, I got both working but still need to test and fine tune the overall automation principle.

For future users searching i’ll try to explain why i’m doing all this, and the root issue i’m trying to address.

Issue; my electric house heating has room/zone(switch.daikin_[room_name]) controls that allow if a room receives heating or cooling. The issue is when the house is generally cold (usually the 5am start up) each room is at a difference temperature, and if I turn on all zones at the same time, some rooms get excessively hot while others don’t heat enough. Eventually the overall house temp is hot enough for the system to turn off and some rooms are still too cold and others are too hot. I’ve also managed to cook my kids rooms to, which wakes them up.

Goal; the goal of this automation is to turn on each zone (switch) of the coldest room in order. This allows for the heater to heat that room to a setpoint ( input_number.setpoint_heating_[room_name] ) before this automation determines the next coldest room, and turns on it’s zone (switch).

Function; This set up requires the following;

  • Individual room temperature sensors (I use the Hue motion sensors, they have lag from real temp to reported temp due to their physical structure)
  • Individual room heating zone control (via Daikin integration)
  • A temperature Setpoint number for each room (input_number, user defined).
  • A Difference in temperature sensor (config.yaml) - this is the difference between room temp and the setpoint number temp; negative if the room is cold, positive if the room is hot.

The Setpoints are used to determine at what minimum temperature a room must be before the above automation considers the next room/zone to turn on. The setpoint is used to create a difference value. The room with the greatest difference is then turned on by the automation above. The end state is all rooms are a similar temperature and all zones are turned on. This allows the heater to warm the house uniformly before reaching the overall target temperature and turning off.

The reason for setpoints is the lag in the hue temperature sensors, I’ve compared them side-by-side with the xiomi ones, and they lag by about 20-30 minutes, as their sensor is located inside solid plastic. Therefore the entire unit must reach thermal equilibrium before reporting the exact state. (yes in hindsight, I would not not purchase these again for temp sensors).

Therefore, I can tweak the setpoint numbers slightly to ensure rooms don’t get to hot (before other zones turn on) or stay to cold (…before other zones turn on).

This all seems rather excessive I understand, however my Daikin unit was intentionally oversized when I brought it, as my house is nearly 79yrs old and had zero insulation before we reno’d and when we brought the daikin. It should also be noted if the Daikin runs with only one room zone on, it can bake that room within 20minutes - I’ve had my kids rooms up to 28degC degrees when the target was 20 and outside is 5degC.

So yes, a complex automation in an attempt to follow my ideals about automations in general; if they are working correctly; I shouldn’t even have to engage with HA - just let it do it’s thing.

Thanks all for your help - I still need to fine tune this one, in parallel with other automations that watchdog the zones overall. This morning’s test had two automations basically turning one room zone on/off repeatedly. Might need a timer of some form to block this automation from turning it back on if it was recently turned off by another.

why don’t you just turn on all that are cold and turn off each one when each room hits the set point? You could make a single automation for each room and be done with it. No need to worry about average temp if you know each room will hit their target temp.

I have, they are watchdog automations as such. However once I turn off one bedroom, the others bake in record time. What I haven’t explained is the Daikin needs a minimum number of zones on based on air volume movement, each room has a different value etc, I’m also balancing having a minimum amount open also.

I’ve used the watchdog automations solely, and they just don’t work well enough. What does work is once all rooms are a similar temp, running the daikin with all zones/room open/on works well to overall heat the house at once.

Trust me, i’ve been battling this for years now.

Can’t you just always have the minimum going though? Instead of what I said above, just turn them all on and remove the highest each time one room hits it setpoint. Then when you hit the minimum, decide what to do at that point based on the delta in each room that’s not at it’s set point.

Yep, that’s exactly what happens in the Progressive automation; it heats the rooms up until they all come up to a similar temp.

Usually in the morning;

  • Kitchen; 12-14
  • Kids rooms; anywhere from 16-19
  • Master room; 17-18
  • Bathroom; 17
  • Office; 19 (servers create heat hey)

When the progressive automation works, they all roughly hit 19-20 at the same time, then there is no issue until the house is around 21 and I turn off the heating.

Turning off the kids room’s or master at the wrong time results in baking of the other kids rooms that are still on. It’s a design flaw in the daikin ducting sizes and airflow dynamics. I’m trying to correct it without spending money swapping out the zone and controller system for it.

Another piece to the equation; the rooms behave differently when cooling - that’s another story.

I also have a woodfire heater, with fan that pulls hot air off it, and injects it into these same zones - and it’s effects on the rooms are different again.

Currently I have around 120 automations just to manage heating/cooling alone. :confused: