Same automation for different pairs of trigger and action - best way to do

Hi,
i’ve got serval rooms with a shelly 1mini (deatached) behind a wall switch and an esphome deive controlling the cover in that specific room.
I created an automation for each room, with the same code. Just the device_id of the triger and the entity_id of the cover differs. It works fine, but maintaining is horrible…
Is there a good way to deal with that in homeassistant?
Thanks a lot,
Markus

There are multiple ways to combine similar automations, most will incorporate Templating to pass variable values to scripts or service calls.

Script Variables
Trigger-attached Variables
Automation Trigger Variables

The method you use really depends on how you prefer to structure your automations and the specific details of the automation.

Based on the limited information you have given it seems like you might be using Device triggers and/or actions which are “easy” to use when you start out, but are less useful than other options when you start making more advanced automations.

If you need help, please provide an example of a couple of your automations so we can give specific advice.

Post two of the automations as correctly-formatted YAML.

Also include the entity_id of the trigger device, as entity triggers are much easier to work with than opaque device triggers.

@Didgeridrew Thank’s for your input. I’ll see the point, just got do develope my skills further. But sounds like fun actually.

@Troon: here is the full automation as yaml:

entity_id of the trigger device would be “event.noah_button_input_0” (that’s a shelly 1 mini). Guess there I come to the suggestions of @Didgeridrew and I’ll have to use event based trigger instead of the device…

the “pairs” would be:
event.noah_button_input_0 → cover.veluxcontrol_rolladen_noah
event.joha_button_input_0 → cover.veluxcontrol_rolladen_joha
and so on

alias: Dachfenster Noah
description: ""
trigger:
  - platform: device
    device_id: 3ec90af93fe5ca3973d2770ecab7482d
    domain: shelly
    type: btn_down
    subtype: button1
condition: []
action:
  - choose:
      - conditions:
          - condition: state
            entity_id: cover.veluxcontrol_rolladen_noah
            state: closed
        sequence:
          - service: cover.open_cover
            metadata: {}
            data: {}
            target:
              entity_id:
                - cover.veluxcontrol_rolladen_noah
      - conditions:
          - condition: state
            entity_id: cover.veluxcontrol_rolladen_noah
            state: open
        sequence:
          - service: cover.close_cover
            metadata: {}
            data: {}
            target:
              entity_id: cover.veluxcontrol_rolladen_noah
      - conditions:
          - condition: state
            entity_id: cover.veluxcontrol_rolladen_noah
            state: closing
        sequence:
          - service: cover.stop_cover
            metadata: {}
            data: {}
            target:
              entity_id: cover.veluxcontrol_rolladen_noah
      - conditions:
          - condition: state
            entity_id: cover.veluxcontrol_rolladen_noah
            state: opening
        sequence:
          - service: cover.stop_cover
            metadata: {}
            data: {}
            target:
              entity_id: cover.veluxcontrol_rolladen_noah
    default:
      - service: cover.close_cover
        metadata: {}
        data: {}
        target:
          entity_id: cover.veluxcontrol_rolladen_noah
mode: single

Thanks a lot for your support,
Markus

One way to approach that would be as follows, you just need to add a trigger for each button and attaching a variable with the cover entity ID:

alias: Alle Dachfenster
description: ""
trigger:
  - platform: device
    device_id: 3ec90af93fe5ca3973d2770ecab7482d
    domain: shelly
    type: btn_down
    subtype: button1
    variables:
      cover: cover.veluxcontrol_rolladen_noah

  - platform: device
    device_id: some_other_device
    domain: shelly
    type: btn_down
    subtype: button1
    variables:
      cover: cover.veluxcontrol_rolladen_example
condition: []
action:
  - variables:
      cover_state: "{{ states(cover) }}"
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ cover_state == 'closed' }}"
        sequence:
          - service: cover.open_cover
            metadata: {}
            data: {}
            target:
              entity_id: "{{ cover }}"
      - conditions:
          - condition: template
            value_template: "{{ cover_state == 'open' }}"
        sequence:
          - service: cover.close_cover
            metadata: {}
            data: {}
            target:
             entity_id: "{{ cover }}"
      - conditions:
          - condition: template
            value_template: "{{ cover_state in ['opening', 'closing'] }}"
        sequence:
          - service: cover.stop_cover
            metadata: {}
            data: {}
            target:
             entity_id: "{{ cover }}"
    default:
      - service: cover.close_cover
        metadata: {}
        data: {}
        target:
         entity_id: "{{ cover }}"
mode: parallel

This could be compacted even more by templating the service instead of using a Choose action.

Compacted Action Block
action:
  - variables:
      cover_state: "{{ states(cover) }}"
      cover_services:
        closed: open
        open: close
      c_service: "{{ 'stop' if cover_state in ['closing','opening'] else cover_services.get(cover_state, 'close') }}"
  - service: "cover.{{- c_service -}}_cover"
     target:
       entity_id: "{{ cover }}"
mode: parallel

Thanks @Didgeridrew that’s what I was looking for. And the “compact” block is showing how much more is possible and makes the automation much cleaner. Really like it and for sure going to adapt it to other automations I’m using.

As I understood by reading the links @Troon posted, it would be better not using the device_id and avoiding the platform:device. I could go for the event, but if I use the event trigger, I’m still with the device:

  - platform: event
    event_type: shelly.click
    event_data:
      device: shelly1mini-6055f99b5aa4
      channel: 1
      click_type: single_push    
    variables:
      cover: cover.veluxcontrol_rolladen_joha

Edit: guess I have to go for the platform state. Something like that. Couldn’t test it yet

trigger:
  - platform: state
    entity_id:
      - event.joha_button_input_0
    attribute: event_type
    from: single_push

When it comes to these type of button event triggers, there really isn’t any benefit to using an Event trigger over a Device trigger.

The real place it makes a huge difference is when your options are between using entity-based triggers like State or Numeric State triggers versus Device triggers. If your device’s integration has added the new event entity (as shown in your edit), use that with a State trigger.

In my use case the real benefit is the readability. Entity_id is just more straightforward…

I rewrote the automation. Really short in the first part as well. And if I’d like to use another event type (f.e. long_press) in future, it’s easy to implement.

alias: Dachfenster Rollläden NEU
description: ""
trigger:
  - platform: state
    entity_id:
      - event.joha_button
      - event.noah_button
      - event.eltern_button
    attribute: event_type
    variables:
      cover:
        event.joha_button: cover.veluxcontrol_rolladen_joha
        event.noah_button: cover.veluxcontrol_rolladen_noah
        event.eltern_button: cover.veluxcontrol_rolladen_eltern
condition:
  - condition: template
    value_template: |
      {{ trigger.to_state.attributes.event_type == 'single_push' }}
action:
  - variables:
      cover_state: "{{ states(cover.get(trigger.entity_id)) }}"
      cover_services:
        closed: open
        open: close
      c_service: >-
        {{ 'stop' if cover_state in ['closing','opening'] else
        cover_services.get(cover_state, 'close') }}
  - service: cover.{{- c_service -}}_cover
    target:
      entity_id: "{{ cover.get(trigger.entity_id) }}"
mode: parallel