Template Switch - help needed with advanced jinja2 magic

Hi,

I have a Hue system with a couple of lights and a few switchable power plugs.
Unfortunately the power plugs to Hue are also just “lights” that can only be turned on and off.

I want to create an “all lights” template switch that activates when any of the actual lights are on and deactivates when no lights are lit - regardless of the state of the power plugs.
If switched on manually, nothing should happen; if switched off manually, all the actual lights should be turned off - again, ignoring the power plugs.

I think I have the value_template for the switch figured out, but I’m struggling supplying the list of entities to the light.turn_off service that should be called for the turn_off command.
So this is where I am now:

platform: template
switches:
  all_lights:
    value_template: >
      {% set ns = namespace(turned_on=[]) %}
      {%- for i in states.light | selectattr('state','eq','on') | map(attribute='entity_id') -%}
      {%- if state_attr(i, 'color_mode') != 'onoff' and state_attr(i, 'is_hue_group') != True %}
      {%- set ns.turned_on = ns.turned_on + [i] %}
      {{ ns.turned_on | count > 0}}
      {%- endif -%}
      {%- endfor -%}
    unique_id: 187b2fff-5d5d-4ae5-9a37-bb1e9f44f976
    turn_on:
      service: shell_command.nop
    turn_off:
      service: light.turn_off
      data:
        entity_id: all

After the template is evaluated {{ ns.turned_on }} contains a list of light entities or it’s just an empty list.
My original idea was to use it like this:

[...]
    turn_off:
      service: light.turn_off
      data:
        entity_id: {{ ns.turned_on }}

Which is failing the syntax check:

Failed config
  General Errors:
    - Error loading /config/configuration.yaml: invalid key: "OrderedDict([('ns.turned_on', None)])"
  in "/config/switches/all_lights.yaml", line 18, column 0

For now, I’m not sure if the namespace object is even existing/accessible at the light.turn_off service specification.
Or if it’s even possible to supply a dynamic entity list in the service configuration.

Is there anyone with more insights who could help?

Sebastian

If it doesn’t necessarily have to be a switch:


script:

  auto_aus_lampen:
    alias: Auto-Aus Lampen
    description: |-
      Schaltet alle Lampen aus, die an sind
      ——> /packages/skripte/auto_aus_lampen.yaml
    icon: mdi:lightbulb-off-outline

    variables:
      lan: |-
        {{- states.light
        |selectattr('attributes.is_hue_group', 'undefined')
        |selectattr('state', 'eq', 'on')
        |reject('search', 'onoff')
        |map(attribute='entity_id')
        |list
        -}}

    sequence:

      - if:
          - condition: template
            value_template: "{{ lan |count > 0 }}"
        then:
          - service: homeassistant.turn_off
            target:
              entity_id: "{{ lan }}"
        else:
          - stop: Alle Lampen sind bereits aus


1 Like

I wanted to have something like a group or a switch so I could have a visual representation in the UI that allows me to quickly check if any of the lights are still on.
Thanks a lot for that example, though. That was very helpful!

It helped me to improve my switch, so it now looks like this:

platform: template
switches:
  all_lights:
    value_template: >
      {% set ns = namespace(turned_on=[]) %}
      {% set ns.turned_on =  states.light
        | selectattr('state','eq','on')
        | selectattr('attributes.is_hue_group', 'undefined')
        | reject('search', 'onoff')
        | map(attribute='entity_id')
        | list
      %}
      {{ ns.turned_on | count > 0 }}
    unique_id: 187b2fff-5d5d-4ae5-9a37-bb1e9f44f976
    turn_on:
      service: shell_command.nop
    turn_off:
      service: homeassistant.turn_off
      target:
        entity_id: "{{ ns.turned_on }}"

This version is passing the syntax check and the value_template seems to work as expected.
Unfortunately, turning the switch off gives me an “UndefinedError: ‘ns’ is undefined” in the UI.
So apparently it’s not possible to pass a variable from one block to another.

I will go forward and create an additional script and duplicate the template within the script.
I then can call the script for the turn_off: action of my switch.
I wanted to avoid duplicating the template, but apparently there is no other way…

Sebastian

Well, same with template sensors. I would love to be able using one universal variable for multiple attributes, but…

So, to wrap this up, this is how it looks (and works) now:

Switch:

platform: template
switches:
  all_lights:
    value_template: >
      {{ states.light
        | selectattr('state','eq','on')
        | selectattr('attributes.is_hue_group', 'undefined')
        | reject('search', 'onoff')
        | map(attribute='entity_id')
        | list
        | count > 0
      }}
    unique_id: 187b2fff-5d5d-4ae5-9a37-bb1e9f44f976
    turn_on:
      service: shell_command.nop
    turn_off:
      service: script.turn_on
      target:
        entity_id: script.all_lights_off

And the corresponding script:

all_lights_off:
  alias: Turn Off All Lights
  variables:
    mylights: >
      {{ states.light
        | selectattr('state','eq','on')
        | selectattr('attributes.is_hue_group', 'undefined')
        | reject('search', 'onoff')
        | map(attribute='entity_id')
        | list
      }}
  sequence:
    - service: light.turn_off
      target:
        entity_id: "{{mylights}}"

Sebastian