Automation for multiple devices, reference the appropriate device in action?

I have an automation that brightens and dims my light when you hold the button up or down and it works really well.

I would like to use the same automation across the other light switches I have in the house and reading through the documentation on Automation and variables it looks like it can be done, just not sure how to code the action.

Now I know I can add extra triggers easy enough and I believe I have the right code to reference the appropriate trigger in the action, however I have NO clue how to reference the appropriate light. Here is my code with the multiple triggers and reference to the trigger.event_id where appropriate, how do I determine the right light to make the adjustments on:

alias: Shelly Dimming
description: This allows the shelly to dim the lights
trigger:
  - platform: state
    entity_id:
      - binary_sensor.waiting_channel_1_input
      - binary_sensor.hallway_channel_1_input
      - binary_sensor.media_channel_1_input
    to: "on"
    for:
      hours: 0
      minutes: 0
      seconds: 0.25
  - platform: state
    entity_id:
      - binary_sensor.waiting_channel_2_input
      - binary_sensor.hallway_channel_2_input
      - binary_sensor.media_channel_2_input
    to: "on"
    for:
      hours: 0
      minutes: 0
      seconds: 1
condition: []
action:
  - choose:
      - conditions:
          - condition: state
            entity_id: trigger.entity_id
            state: "on"
        sequence:
          - repeat:
              while:
                - condition: state
                  entity_id: light.waiting
                  state: "off"
              sequence:
                - service: light.turn_on
                  data: {}
                  target:
                    entity_id: light.waiting
            alias: Turn on light
          - alias: Increase light
            repeat:
              while:
                - condition: state
                  entity_id: trigger.entity_id
                  state: "on"
              sequence:
                - service: light.turn_on
                  data:
                    brightness_step: 10
                    transition: 1
                  target:
                    entity_id: light.waiting
                - delay:
                    hours: 0
                    minutes: 0
                    seconds: 0
                    milliseconds: 250
      - conditions:
          - condition: state
            entity_id: trigger.entity_id
            state: "on"
        sequence:
          - repeat:
              while:
                - condition: state
                  entity_id: trigger.entity_id
                  state: "on"
              sequence:
                - service: light.turn_on
                  data:
                    brightness_step: -10
                    transition: 1
                  target:
                    entity_id: light.waiting
                - delay:
                    hours: 0
                    minutes: 0
                    seconds: 0
                    milliseconds: 250
    default:
      - stop: Nothing to do
mode: single

How do the binary sensors correlate with the lights?

Is there something in the object_id that matches in all cases?
e.g.

domain.object_id
light.my_lamp

-> domain = light
-> object_id = my_lamp
binary_sensor.my_lamp_waiting_channel_1_input

-> domain = light
-> object_id = my_lamp_waiting_channel_1_input

If so you can create a template to match the object id of the binary sensor with the object id of the light. In the case of my example above if binary_sensor.my_lamp_waiting_channel_1_input triggered the automation then the template to get the right associated light entity id would be:

target:
  entity_id: "light.{{ trigger.to_state.object_id|replace('_waiting_channel_1_input','') }}"

This will replace _waiting_channel_1_input from the binary sensor object_id with nothing leaving my_lamp which is then concatenated to the end of the string “light.” to give you the entity_id light.my_lamp

You can make it even easier on yourself by setting the object ids to be as similar as possible. e.g. these entity ids:

light.my_lamp

and

binary_sensor.my_lamp

Would only require the template:

target:
  entity_id: "light.{{ trigger.to_state.object_id }}"

My objects are named as you suggested, i.e.:

binary_sensor.waiting_channel_2_input

works in conjunction with

light.waiting

However I don’t know how to implement your suggestion.

Could you provide some context as to where I put your code? I don’t have a clue where to put it.

Nor, means ‘not or’.

Do you actually mean both of these entities:

binary_sensor.waiting_channel_2_input

or

binary_sensor.waiting_channel_1_input

could reference this light:

light.waiting

?

If so this should do it:

              sequence:
                - service: light.turn_on
                  data: {}
                  target:
                    entity_id: "light.{{ trigger.to_state.object_id|replace('_channel_1_input','')|replace('_channel_2_input','') }}"

I originally tried with a string slicing method but that would require all your light object ids to be the same length. I then tried with a string split method but that would require your lights to not have underscores in the object ids. So I rejected both of those ideas. I think the solution above using two replace() functions is best. They don’t generate errors if they cant find one of the strings to replace, they work with any length light object id and do allow underscores in the light object id.

@tom_l

That is awesome.

This is now working for my entity_id for addressing the light and turning it on an off etc, however I cannot use this to check the state of the light.

No matter what format I use I cannot use this same method to check the state of the light, here is what I am trying:

                - condition: template
                  value_template: >-
                    {{
                    is_state(light.trigger.to_state.object_id|replace('_channel_1_input','')|replace('_channel_2_input',''),
                    'on') }}

How do I test the state of the light that I am targetting?

Also as a side note, is it possible to set this code as a variable, so that I can simply refer to the variable instead of this lengthy code each time?

Thanks

You were close. Try this:

                - condition: template
                  value_template: >
                    {{
                    is_state('light.' ~ trigger.to_state.object_id|replace('_channel_1_input','')|replace('_channel_2_input',''),
                    'on') }}

~ concatenates two strings together.

As for variables. That’s what they are already: Automation trigger variables - Home Assistant :smile:

But I get what you mean, set the entity id in a variable so you don’t have to keep repeating the template. Yes that is possible, put this at the top of your action block:

action:
  - variables:
      light_entity_id: "light.{{ trigger.to_state.object_id|replace('_channel_1_input','')|replace('_channel_2_input','') }}"

Then just use light_entity_id wherever you need it in the actions. Do take not of the scope of this variable though: https://www.home-assistant.io/docs/scripts/#scope-of-variables If you change it inside a choose or if action the change wont be visible outside this block. You don’t need to worry about it in your application above, just something to be aware of for the future.

Man, just keep coming with the hits, I love it.

Putting in the variable just isn’t working though. I had tried something similar to what you proposed, but I always get an error when I try and reference the variable in the entity_id, here is what I have:

              sequence:
                - service: light.turn_on
                  data: {}
                  target:
                    entity_id: light_entity_id

But it doesn’t like it. How do I reference the entity_id variable correctly?

Cheers

See if it works when you put it here:

alias: Shelly Dimming
description: This allows the shelly to dim the lights
trigger:
  - platform: state
    entity_id:
      - binary_sensor.waiting_channel_1_input
      - binary_sensor.hallway_channel_1_input
      - binary_sensor.media_channel_1_input
    to: "on"
    for:
      hours: 0
      minutes: 0
      seconds: 0.25
  - platform: state
    entity_id:
      - binary_sensor.waiting_channel_2_input
      - binary_sensor.hallway_channel_2_input
      - binary_sensor.media_channel_2_input
    to: "on"
    for:
      hours: 0
      minutes: 0
      seconds: 1
variables:
  light_entity_id: "light.{{ trigger.to_state.object_id|replace('_channel_1_input','')|replace('_channel_2_input','') }}"
condition: []
action:
  - choose: etc...

No good, get this error:

Message malformed: not a valid value for dictionary value @ data['action'][0]['choose'][0]['sequence'][0]['repeat']['sequence'][0]['target']['entity_id'

Ok I overlooked how you were using it.

Should be:

              sequence:
                - service: light.turn_on
                  data: {}
                  target:
                    entity_id: "{{ light_entity_id }}"

Thanks so much for your help, I learnt way heaps from this and I have my code working as I would like. I have posted the full code here: https://community.home-assistant.io/t/terrific-way-to-use-a-shelly-dimmer-2-in-a-thorny-situation/604513/10?u=girkers

1 Like