Automation "choose" not working?

I’m trying to use a “choose” automation to improve readability of a somewhat complex set of variables. Unfortunately when its triggered it is not selecting anything and I get no errors in the HA logfile.

Anyone have suggestions?

The purpose of this is to take min/max temps and push them to a thermostat which does not support automatic changeover (just heat/cool/off) and has a max-min that is more narrow than some of my set-points so I had to get creative.

YAML:

automation:

  - alias: "Whynter Portable Heatpump HVAC Set Temperatures"
    id: "Whynter Portable Heatpump HVAC Set Temperatures"
    trigger:
      - platform: state
        entity_id:
          - sensor.whynter_portable_heatpump_hvac_requested_heat_computed
          - sensor.whynter_portable_heatpump_hvac_requested_cool_computed
        for: '00:00:05'
      - platform: state
        entity_id: climate.whynter_portable_heatpump
        from: 'off'
        for: '00:00:05'
    mode: queued
    condition:
      - condition: not
        conditions:
          - condition: state
            entity_id: climate.whynter_portable_heatpump
            state: 'off'
    action:
      - variables:
          cool_set: "[states('sensor.whynter_portable_heatpump_hvac_requested_heat_computed') | int(0),states('sensor.whynter_portable_heatpump_hvac_requested_cool_computed') | int(0)]|max"
          heat_set: "[states('sensor.whynter_portable_heatpump_hvac_requested_heat_computed') | int(0),states('sensor.whynter_portable_heatpump_hvac_requested_cool_computed') | int(0)]|min"
          max_set: "86"
          min_set: "61"
          room_temp: "states('sensor.whynter_portable_heatpump_temperature') | int(0) "

          cool_set_too_low: "cool_set < min_set"
          cool_set_too_high: "cool_set > max_set"
          cool_set_in_range: "cool_set >= min_set and cool_set <= max_set"
          heat_set_too_low: "heat_set < min_set"
          heat_set_too_high: "heat_set > max_set"
          heat_set_in_range: "heat_set >= min_set and heat_set <= max_set"

          room_below_cool_set: "room_temp < cool_set"
          room_above_cool_set: "room_temp > cool_set"
          room_below_heat_set: "room_temp < heat_set"
          room_above_heat_set: "room_temp > heat_set"


          room_below_cool_max: "room_temp < max_set"
          room_above_heat_min: "room_temp > min_set"

          do_cool: >-
            (cool_set_too_low) or
            (cool_set_in_range) or
            (cool_set_too_high and room_below_cool_set and room_below_cool_max) or
            (cool_set_too_high and room_above_cool_set)


          do_heat: >-
            (heat_set_too_low and room_below_heat_set) or
            (heat_set_too_low and room_above_heat_set and room_above_heat_min) or
            (heat_set_in_range) or
            (heat_set_too_high)

          do_max_cool: >-
            (heat_set_too_low and room_above_heat_set and room_below_heat_min and room_below_cool_max)

          do_min_heat: >-
            (cool_set_too_high and room_below_cool_set and room_aboce_cool_max and room_above_heat_min)

          #cool_set_too_low and room_below_cool_set -> do_cooling
          #cool_set_too_low and room_above_cool_set -> do_cooling
          #cool_set_in_range and room_below_cool_set -> do_cooling
          #cool_set_in_range and room_above_cool_set -> do_cooling
          #cool_set_too_high and room_below_cool_set and room_below_cool_max -> do_cooling
          #cool_set_too_high and room_below_cool_set and room_aboce_cool_max and room_above_heat_min -> set_heat_min
          #cool_set_too_high and room_above_cool_set -> do_cooling
          #
          #heat_set_too_low and room_below_heat_set -> do_heating
          #heat_set_too_low and room_above_heat_set and room_above_heat_min -> do_heating
          #heat_set_too_low and room_above_heat_set and room_below_heat_min and room_below_cool_max -> set_cool_max
          #heat_set_in_range and room_below_heat_set -> do_heating
          #heat_set_in_range and room_above_heat_set -> do_heating
          #heat_set_too_high and room_below_heat_set -> do_heating
          #heat_set_too_high and room_above_heat_set -> do_heating

      - choose:
          # do_cooling
          - conditions:
              condition: template
              value_template: >
                {{ do_cool }}
            sequence:
              # Set cool mode
              - service: climate.set_temperature
                data:
                  entity_id: climate.whynter_portable_heatpump
                  hvac_mode: cool
                  temperature: "{{ [cool_set,max_set] | min }}"
          # do_heating
          - conditions:
              condition: template
              value_template: >
                {{ do_heat }}
            sequence:
              # Set heat mode
              - service: climate.set_temperature
                data:
                  entity_id: climate.whynter_portable_heatpump
                  hvac_mode: heat
                  temperature: "{{ [heat_set,min_set] | max }}"
          # do_max_cool
          - conditions:
              condition: template
              value_template: >
                {{ do_max_cool }}
            sequence:
              # Set heat mode
              - service: climate.set_temperature
                data:
                  entity_id: climate.whynter_portable_heatpump
                  hvac_mode: cool
                  temperature: "{{ max_set }}"
          # do_min_heat
          - conditions:
              condition: template
              value_template: >
                {{ do_min_heat }}
            sequence:
              # Set heat mode
              - service: climate.set_temperature
                data:
                  entity_id: climate.whynter_portable_heatpump
                  hvac_mode: heat
                  temperature: "{{ min_set }}"                                                                                                                                                                                                                      

If I put it in the template-dev-panel after doing some find-replace to refactor the variables syntax without changing the strings, it looks like it should be finding a match:

   {% set cool_set = [states('sensor.whynter_portable_heatpump_hvac_requested_heat_computed') | int(0),states('sensor.whynter_portable_heatpump_hvac_requested_cool_computed') | int(0)]|max  %}
   {% set heat_set = [states('sensor.whynter_portable_heatpump_hvac_requested_heat_computed') | int(0),states('sensor.whynter_portable_heatpump_hvac_requested_cool_computed') | int(0)]|min  %}
   {% set max_set = 86  %}
   {% set min_set = 61  %}
   {% set room_temp = states('sensor.whynter_portable_heatpump_temperature') | int(0)   %}

   {% set cool_set_too_low = cool_set < min_set  %}
   {% set cool_set_too_high = cool_set > max_set  %}
   {% set cool_set_in_range = cool_set >= min_set and cool_set <= max_set  %}
   {% set heat_set_too_low = heat_set < min_set  %}
   {% set heat_set_too_high = heat_set > max_set  %}
   {% set heat_set_in_range = heat_set >= min_set and heat_set <= max_set  %}

   {% set room_below_cool_set = room_temp < cool_set  %}
   {% set room_above_cool_set = room_temp > cool_set  %}
   {% set room_below_heat_set = room_temp < heat_set  %}
   {% set room_above_heat_set = room_temp > heat_set  %}


   {% set room_below_cool_max = room_temp < max_set  %}
   {% set room_above_heat_min = room_temp > min_set  %}


   {% set do_cool = 
            (cool_set_too_low) or
            (cool_set_in_range) or
            (cool_set_too_high and room_below_cool_set and room_below_cool_max) or
            (cool_set_too_high and room_above_cool_set)
			%}


   {% set do_heat = 
            (heat_set_too_low and room_below_heat_set) or
            (heat_set_too_low and room_above_heat_set and room_above_heat_min) or
            (heat_set_in_range) or
            (heat_set_too_high)
			%}

   {% set do_max_cool = 
          (heat_set_too_low and room_above_heat_set and room_below_heat_min and room_below_cool_max)
		  %}

   {% set do_min_heat = 
            (cool_set_too_high and room_below_cool_set and room_aboce_cool_max and room_above_heat_min)
			%}

do_cool: {{ do_cool }}
do_heat: {{ do_heat }}
do_max_cool: {{ do_max_cool }}
do_min_heat: {{ do_min_heat }}

Dev template output:

do_cool: True
do_heat: True
do_max_cool: False
do_min_heat: False

But if I look at the traces, it isn’t matching:

Your variable definitions in the action block are all missing their Jinja expression delimiters… {{ }}

Without delimiters, the YAML interpreter thinks you’re just assigning string values to those variables. If you scroll down in the Trace and click “Changed Variables” you will see that all of your variables are just the strings, not template-rendered values.

1 Like

Ah, ok - I was unsure what it should be showing (this is my first try using variable in an automation).

Once I got my {{ and matching }} in all the variable assignments it worked the first try!

EDIT: And although I have more “enhancements” like ensuring it can’t flip-flop between heat/cool, I’ll share this intermediate solution in case someone else gets stuck and wants to see the “corrected” relevant YAML:

# **SNIP**
    action:
      - variables:
          cool_set: "{{ [states('sensor.whynter_portable_heatpump_hvac_requested_heat_computed') | int(0),states('sensor.whynter_portable_heatpump_hvac_requested_cool_computed') | int(0)]|max }}"
          heat_set: "{{ [states('sensor.whynter_portable_heatpump_hvac_requested_heat_computed') | int(0),states('sensor.whynter_portable_heatpump_hvac_requested_cool_computed') | int(0)]|min }}"
          max_set: "{{ 86 }}"
          min_set: "{{ 61 }}"
          room_temp: "{{ states('sensor.whynter_portable_heatpump_temperature') | int(0) }}"

          cool_set_too_low: "{{ cool_set < min_set }}"
          cool_set_too_high: "{{ cool_set > max_set }}"
          cool_set_in_range: "{{ cool_set >= min_set and cool_set <= max_set }}"
          heat_set_too_low: "{{ heat_set < min_set }}"
          heat_set_too_high: "{{ heat_set > max_set }}"
          heat_set_in_range: "{{ heat_set >= min_set and heat_set <= max_set }}"

          room_below_cool_set: "{{ room_temp < cool_set }}"
          room_above_cool_set: "{{ room_temp > cool_set }}"
          room_below_heat_set: "{{ room_temp < heat_set }}"
          room_above_heat_set: "{{ room_temp > heat_set }}"


          room_below_cool_max: "{{ room_temp < max_set }}"
          room_above_heat_min: "{{ room_temp > min_set }}"


          do_cool: >-
            {{
              (cool_set_too_low) or
              (cool_set_in_range) or
              (cool_set_too_high and room_below_cool_set and room_below_cool_max) or
              (cool_set_too_high and room_above_cool_set)
            }}


          do_heat: >-
            {{
              (heat_set_too_low and room_below_heat_set) or
              (heat_set_too_low and room_above_heat_set and room_above_heat_min) or
              (heat_set_in_range) or
              (heat_set_too_high)
            }}

          do_max_cool: >-
            {{
              (heat_set_too_low and room_above_heat_set and room_below_heat_min and room_below_cool_max)
            }}

          do_min_heat: >-
            {{
              (cool_set_too_high and room_below_cool_set and room_aboce_cool_max and room_above_heat_min)
            }}
# **SNIP**

And it took me a few tries to find, but the trace now shows if I click on the [(x)] icon and pick the “Changed Variables” tab:

1 Like