Variables in a script

doesn’t seem to turn them off again

Check the automation’s trace.

  1. The automation State Trigger triggers when the binary_sensor’s state changes from on to off.
  2. The condition will pass if the binary_sensor’s object_id exists as one of the keys in the detectors dictionary (it should pass).
  3. Because the binary_sensor is off, the value of trigger.to_state.state will be off. Therefore it will serve to fulfill the second choice in the choose which turns off the associated light and input_boolean.

detectors is simply the name I chose for the variable containing the dictionary. It’s an abbreviation of Motion Detectors.

Okay I did a review, and I think this is where the problem was:

entity_id: ‘{{ light }}’ which I replaced with entity_id: “{{ detector.light }}” as you had used further op.

1 Like

Good catch! I missed that one.

I have corrected the example posted above.

Yes, I am trying to understand how it actually works, as I think your method is really neat, so I could see myself use that other places also.

This part: value_template: “{{ trigger.to_state.object_id in detectors.keys() }}” what does that actually do? It goes to the trigger part and then afterward to the detector part and the corrosponding key?

So for the first example it goes to this trigger: “- binary_sensor.gang_sensor_home_security_motion_detection” and then the corrosponding key in detector part is “gang_sensor_home_security_motion_detection”?

Is this a bit the same under action: " detector: “{{ detectors.get(trigger.to_state.object_id, none) }}” does that go to the correct variable and then get the ID of each of the variables ready for use further on?

Last question, what does the “100” do in this one? brightness_pct: “{{ detector.modes.get(states(‘sensor.day_interval’), 100) }}”

Sorry for the many questions, and once again thanks for the support :slight_smile:

An entity’s entity_id is composed of a domain and an object_id separated by a period.

binary_sensor.kitchen_occupancy
^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
   domain        object_id

The following Template Condition checks if the object_id of the entity that triggered the State Trigger exists as one of the keys in the detectors dictionary.

{{ trigger.to_state.object_id in detectors.keys() }}

It serves as a safeguard to prevent errors in case you add another binary_sensor to the State Trigger but forget to add a corresponding key (and other information) for that new entity in the dictionary.

The detector variable is set to the dictionary key, in the detectors dictionary, that corresponds to the binary_sensor that triggered the State Trigger. It does that using the following template:

{{ detectors.get(trigger.to_state.object_id, none) }}

If there’s no matching key, the value of detector is set to the default value none (which is a null object). It’s unlikely it will ever be set to none because the automation’s condition has already confirmed there’s a matching key. However, it’s good practice to specify a default value.

The 100 in the following template represents the default value that will be reported if there’s no matching key found in the modes dictionary. In this case, if the value of sensor.day_interval can’t be found, the light’s brightness is set to 100. Feel free to change the default value to whatever brightness level you think is best for your needs.

{{ detector.modes.get(states('sensor.day_interval'), 100) }}

You’re welcome!

Please consider marking my post above (the one containing the automation example) with the Solution tag. As the author of this topic, you get to choose one post that best answers/solves your original question/problem. By marking the post, it will automatically place a check-mark next to the topic’s title which signals to other users that this topic has been resolved. It helps users find answers to similar questions.

For more information about the Solution tag, refer to guideline 21 in the FAQ.

Thanks again also for the thorough explanation :+1:t2: I have set your answer as solution.

1 Like

I have tried to extend the automation a bit, since one of the rooms should only react if an input boolean is on, but for the others it should always work. I then tried to add this boolean to the variables as a “dummy”, but that doesn’t seem to work, any inputs?

alias: Lys - Alle
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.gang_sensor_home_security_motion_detection
      - binary_sensor.hue_motion_1_occupancy
      - binary_sensor.bedroom_sensor_home_security_motion_detection_3
    from:
      - "off"
      - "on"
    to:
      - "on"
      - "off"
condition:
  - "{{ trigger.to_state.object_id in detectors.keys() }}"
action:
  - variables:
      detector: "{{ detectors.get(trigger.to_state.object_id, none) }}"
  - choose:
      - conditions:
          - "{{ trigger.to_state.state == 'on' }}"
          - "{{ states(detector.illuminance) | int(250) < 200 }}"
          - "{{ states(detector.rooms_aut) == 'on' }}"
        sequence:
          - service: light.turn_on
            data:
              brightness_pct: "{{ detector.modes.get(states('sensor.day_interval'), 100) }}"
            target:
              entity_id: "{{ detector.light }}"
          - service: input_boolean.turn_on
            target:
              entity_id: "{{ detector.flag }}"
      - conditions:
          - "{{ trigger.to_state.state == 'off' }}"
        sequence:
          - service: light.turn_off
            target:
              entity_id: "{{ detector.light }}"
          - service: input_boolean.turn_off
            target:
              entity_id: "{{ detector.flag }}"
    default: []
variables:
  detectors:
    gang_sensor_home_security_motion_detection:
      light: light.gang_dimmer_3
      flag: input_boolean.aut_gang
      illuminance: sensor.gang_sensor_illuminance
      rooms_aut: "on"
      modes:
        morgen1: 40
        morgen2: 50
        dag1: 100
        aften1: 80
        aften2: 70
        aften3: 50
        aften4: 40
        nat1: 10
    hue_motion_1_occupancy:
      light: light.bath_small
      flag: input_boolean.aut_badl
      illuminance: sensor.hue_motion_1_illuminance_lux
      rooms_aut: "on"
      modes:
        morgen1: 40
        morgen2: 60
        dag1: 100
        aften1: 100
        aften2: 100
        aften3: 85
        aften4: 65
        nat1: 30
    bedroom_sensor_home_security_motion_detection_3:
      light: light.sovevaerelse_lys
      flag: input_boolean.aut_bed
      illuminance: sensor.bedroom_sensor_illuminance_3
      rooms_aut: input_boolean.aut_rooms
      modes:
        morgen1: 40
        morgen2: 50
        dag1: 90
        aften1: 80
        aften2: 70
        aften3: 0
        aften4: 0
        nat1: 0
mode: queued

It works just fine for the one using the actual input boolean, but the ones with

rooms_aut: "on"

does not work.

Is it possible to make it work, or alternatively in the condition define it to check the condition if valid in the dictionary and if not set it to “on” as default?

For the one room room that uses an input_boolean, the variable rooms_aut uses a template like this:

rooms_aut: "{{ is_state('input_boolean.aut_rooms', 'on') }}"

For the other two rooms, it’s simply this:

rooms_aut: true

The condition for choose now only needs to check if the value of rooms_aut is true and that can be done with this simple template (EDIT - corrected):

          - "{{ detector.rooms_aut }}"

Here’s the revised automation:

alias: Lys - Alle
description: ""
trigger:
  - platform: state
    entity_id:
      - binary_sensor.gang_sensor_home_security_motion_detection
      - binary_sensor.hue_motion_1_occupancy
      - binary_sensor.bedroom_sensor_home_security_motion_detection_3
    from:
      - "off"
      - "on"
    to:
      - "on"
      - "off"
condition:
  - "{{ trigger.to_state.object_id in detectors.keys() }}"
action:
  - variables:
      detector: "{{ detectors.get(trigger.to_state.object_id, none) }}"
  - choose:
      - conditions:
          - "{{ trigger.to_state.state == 'on' }}"
          - "{{ states(detector.illuminance) | int(250) < 200 }}"
          - "{{ detector.rooms_aut }}"
        sequence:
          - service: light.turn_on
            data:
              brightness_pct: "{{ detector.modes.get(states('sensor.day_interval'), 100) }}"
            target:
              entity_id: "{{ detector.light }}"
          - service: input_boolean.turn_on
            target:
              entity_id: "{{ detector.flag }}"
      - conditions:
          - "{{ trigger.to_state.state == 'off' }}"
        sequence:
          - service: light.turn_off
            target:
              entity_id: "{{ detector.light }}"
          - service: input_boolean.turn_off
            target:
              entity_id: "{{ detector.flag }}"
    default: []
variables:
  detectors:
    gang_sensor_home_security_motion_detection:
      light: light.gang_dimmer_3
      flag: input_boolean.aut_gang
      illuminance: sensor.gang_sensor_illuminance
      rooms_aut: true
      modes:
        morgen1: 40
        morgen2: 50
        dag1: 100
        aften1: 80
        aften2: 70
        aften3: 50
        aften4: 40
        nat1: 10
    hue_motion_1_occupancy:
      light: light.bath_small
      flag: input_boolean.aut_badl
      illuminance: sensor.hue_motion_1_illuminance_lux
      rooms_aut: true
      modes:
        morgen1: 40
        morgen2: 60
        dag1: 100
        aften1: 100
        aften2: 100
        aften3: 85
        aften4: 65
        nat1: 30
    bedroom_sensor_home_security_motion_detection_3:
      light: light.sovevaerelse_lys
      flag: input_boolean.aut_bed
      illuminance: sensor.bedroom_sensor_illuminance_3
      rooms_aut: "{{ is_state('input_boolean.aut_rooms', 'on') }}"
      modes:
        morgen1: 40
        morgen2: 50
        dag1: 90
        aften1: 80
        aften2: 70
        aften3: 0
        aften4: 0
        nat1: 0
mode: queued

EDIT

Correction. The template should reference detector.rooms_aut not rooms_aut which is not a standalone variable but a part of the detector variable.

Thanks! I can’t get it to trigger, it seems like the variable is evaluated to true, but that the condition does not respond to it?

Did you use the Automation Editor to create/modify the automation? It has a habit of changing boolean values to strings. In other words, it can change rooms: true to rooms: 'true' which will then fail to work properly in the Template Condition. Check the automation and confirm the boolean value is still boolean and not string.

I did, but if I check the automation in VS code it seems like true is correct:

- id: '1672399219544'
  alias: Lys - Alle
  description: ''
  trigger:
  - platform: state
    entity_id:
    - binary_sensor.gang_sensor_home_security_motion_detection
    - binary_sensor.hue_motion_1_occupancy
    - binary_sensor.bedroom_sensor_home_security_motion_detection_3
    from:
    - 'off'
    - 'on'
    to:
    - 'on'
    - 'off'
  condition:
  - '{{ trigger.to_state.object_id in detectors.keys() }}'
  action:
  - variables:
      detector: '{{ detectors.get(trigger.to_state.object_id, none) }}'
  - choose:
    - conditions:
      - '{{ trigger.to_state.state == ''on'' }}'
      - '{{ states(detector.illuminance) | int(250) < 200 }}'
      - '{{ rooms_aut }}'
      sequence:
      - service: light.turn_on
        data:
          brightness_pct: '{{ detector.modes.get(states(''sensor.day_interval''),
            100) }}'
        target:
          entity_id: '{{ detector.light }}'
      - service: input_boolean.turn_on
        target:
          entity_id: '{{ detector.flag }}'
    - conditions:
      - '{{ trigger.to_state.state == ''off'' }}'
      sequence:
      - service: light.turn_off
        target:
          entity_id: '{{ detector.light }}'
      - service: input_boolean.turn_off
        target:
          entity_id: '{{ detector.flag }}'
    default: []
  variables:
    detectors:
      gang_sensor_home_security_motion_detection:
        light: light.gang_dimmer_3
        flag: input_boolean.aut_gang
        illuminance: sensor.gang_sensor_illuminance
        rooms_aut: true
        modes:
          morgen1: 40
          morgen2: 50
          dag1: 100
          aften1: 80
          aften2: 70
          aften3: 50
          aften4: 40
          nat1: 10
      hue_motion_1_occupancy:
        light: light.bath_small
        flag: input_boolean.aut_badl
        illuminance: sensor.hue_motion_1_illuminance_lux
        rooms_aut: true
        modes:
          morgen1: 40
          morgen2: 60
          dag1: 100
          aften1: 100
          aften2: 100
          aften3: 85
          aften4: 65
          nat1: 30
      bedroom_sensor_home_security_motion_detection_3:
        light: light.sovevaerelse_lys
        flag: input_boolean.aut_bed
        illuminance: sensor.bedroom_sensor_illuminance_3
        rooms_aut: '{{ is_state(''input_boolean.aut_rooms'', ''on'') }}'
        modes:
          morgen1: 40
          morgen2: 50
          dag1: 90
          aften1: 80
          aften2: 70
          aften3: 0
          aften4: 0
          nat1: 0
  mode: queued

What does the automation’s trace report?

At the choose:

Executed: 11. januar 2023 kl. 19.24.49
Result:
choice: default

detector:
  light: light.gang_dimmer_3
  flag: input_boolean.aut_gang
  illuminance: sensor.gang_sensor_illuminance
  rooms_aut: true
  modes:
    morgen1: 40
    morgen2: 50
    dag1: 100
    aften1: 80
    aften2: 70
    aften3: 50
    aften4: 40
    nat1: 10

Which means it does nothin as “default” choice is empty.

But in addition to above, I get an error in the log, perhaps that is helpful?

Template variable warning: ‘rooms_aut’ is undefined when rendering ‘{{ rooms_aut }}’

That’s a very helpful message and explains why it didn’t work. I made a mistake; I forgot that rooms_aut is part of the detector variable! :man_facepalming:

Change this:

- "{{ rooms_aut }}"

to this:

- "{{ detector.rooms_aut }}"

I will correct the example posted above.

Perfect, that was it! Thanks.

The automation continues to work great, but since then I have made a helper called “input_number.luxgraense” which is just a slider that provides a number (for instance 180) to be used as a threshold for when the light should trigger or not.

conditions:
          - "{{ trigger.to_state.state == 'on' }}"
          - >-
            {{ states(detector.illuminance) | int(250) < states(input_number.luxgraense) }}
          - "{{ detector.rooms_aut }}"

The above doesn’t work this is what is in the log: “Error in ‘choose[1]’ evaluation: In ‘template’ condition: UndefinedError: ‘input_number’ is undefined”. Any ideas?

Your entity IDs need to be in single quotes.

{{ states(detector.illuminance) | int(250) < states('input_number.luxgraense') }}

Thanks a lot, that worked :slight_smile: