ESPHome script: how to pass switch id as a parameter?

I want a series of ten template (virtual) switches, which are exposed to HA, to call a series of ten gpio (real) switches, which are internal, using a single script. They therefore need to pass the id of the internal switch as a parameter.

Take 1

I tried the following, but the compiler tells me that the ids for switch.turn_on: and switch.turn_off: are “not templatable”. So how should I do it?

# Script to operate one flag at a time (to avoid power overload)
script:
  - id: operate_flag 
    mode: queued
    parameters:
      flag_id: string 
    then:
      - switch.turn_on: !lambda return flag_id
      - delay: ${flag_pulse_length}
      - switch.turn_off: !lambda return flag_id

Take 2

I tried doing the switch on and off actions in lambdas, but the compiler tells me
“expected primary-expression before ‘return’” – so how do you use a script parameter within a lambda?


# Script to operate one flag at a time (to avoid power overload)
script:
  - id: operate_flag 
    mode: queued
    parameters:
      flag_id: string 
    then:
      - lambda: "id( return flag_id ).turn_on();"
      - delay: ${flag_pulse_length}
      - lambda: "id( return flag_id ).turn_off();"

Take 3?

The ids all form the same pattern “flag_nn_relay”, where nn is 01, 02, … 10, so It would be acceptable to pass the flag number as an integer parameter and construct the id, but I could not figure out how to do that!

Take 4?

As a last resort, in case there really is no way of parameterising an id, I can write out all ten variants and select the appropriate one. This solution WORKS but is clunky …

# Script to operate one flag at a time by forming a queue (to avoid power overload)
script:
  - id: operate_flag 
    mode: queued
    parameters:
      flag_id: string 
    then:
      - if:
          condition:
            lambda: 'return flag_id == "flag_01";'
          then:
            - switch.turn_on: flag_01_relay
            - delay: ${flag_pulse_length}
            - switch.turn_off: flag_01_relay
      - if:
          condition:
            lambda: 'return flag_id == "flag_02";'
          then:
            - switch.turn_on: flag_02_relay
            - delay: ${flag_pulse_length}
            - switch.turn_off: flag_02_relay
      - if:
          condition:
            lambda: 'return flag_id == "flag_03";'
          then:
            - switch.turn_on: flag_03_relay
            - delay: ${flag_pulse_length}
            - switch.turn_off: flag_03_relay
      - if:
          condition:
            lambda: 'return flag_id == "flag_04";'
          then:
            - switch.turn_on: flag_04_relay
            - delay: ${flag_pulse_length}
            - switch.turn_off: flag_04_relay
      - if:
          condition:
            lambda: 'return flag_id == "flag_05";'
          then:
            - switch.turn_on: flag_05_relay
            - delay: ${flag_pulse_length}
            - switch.turn_off: flag_05_relay
      - if:
          condition:
            lambda: 'return flag_id == "flag_06";'
          then:
            - switch.turn_on: flag_06_relay
            - delay: ${flag_pulse_length}
            - switch.turn_off: flag_06_relay
      - if:
          condition:
            lambda: 'return flag_id == "flag_07";'
          then:
            - switch.turn_on: flag_07_relay
            - delay: ${flag_pulse_length}
            - switch.turn_off: flag_07_relay
      - if:
          condition:
            lambda: 'return flag_id == "flag_08";'
          then:
            - switch.turn_on: flag_08_relay
            - delay: ${flag_pulse_length}
            - switch.turn_off: flag_08_relay
      - if:
          condition:
            lambda: 'return flag_id == "flag_09";'
          then:
            - switch.turn_on: flag_09_relay
            - delay: ${flag_pulse_length}
            - switch.turn_off: flag_09_relay
      - if:
          condition:
            lambda: 'return flag_id == "flag_10";'
          then:
            - switch.turn_on: flag_10_relay
            - delay: ${flag_pulse_length}
            - switch.turn_off: flag_10_relay
      - delay: 100ms # just to make the sequence visible for testing
1 Like