Template Select - Select an entity from a dropdown list to run in an automation script

I’ve tried looking through previous posts to see if any could solve my issue but with no success. Any help would be greatly appreciated, thanks.

I essentially want to calibrate a bunch of pumps and I do this by defining the pump I want to calibrate in a dropdown. That way I can select from a list of available entity’s and test and calibrate. I don’t want to create the list in a input select.

I originally wrote the select like this - but of course, it only worked for the first pump in the list and would always run for the first pump regardless of what pump was select in the dropdown

- select:
  - name: test_dropdown
    unique_id: bob_1234
    icon: mdi:lightbulb
    state: >
      {{ states.fan | map(attribute='entity_id') | list | first }}
    options: >
        {{ states.fan | map(attribute='entity_id') | list }}
    select_option:
      - action: select.select_option
        target:
          entity_id: select.test_dropdown
        data: 
          option: "{{ option }}"

I tried this but then the state is always unknown

-Select:
  - name: test_dropdown
    unique_id: bob_1234
    icon: mdi:lightbulb
    state: "{{ option }}"
    options: "{{ states.fan | map(attribute='entity_id') | list }}"
    select_option:
      - action: select.select_option
        target:
          entity_id: select.test_dropdown
        data: 
          option: "{{ option }}"

I can share the automation but it does work based on the first snippet of code so I don’t think that is the problem.

There is a primer on Template Select Entities in the Community Cookbook.

Can you clarify how you are trying to use this?

A Template Select creates an entity that acts like an Input Select Helper in the front end, but more like an automation behind the scenes.

The actions sequence defined in select_option is what should happen when a new option is selected from the Dashboard or by a script or automation. If you don’t want it to do anything it would be better to use a short delay or have it call a script that doesn’t do anything than to have it call select.select_option on itself.

IIRC, the variable option doesn’t exist there, it only exists within the select_option sequence.

EDIT:

After reading your post a few times I think what you want is to use the select in optimistic mode.

- select:
    - name: test_dropdown
      unique_id: bob_1234
      icon: mdi:lightbulb
      optimistic: true
      options: >
        {{ states.fan | map(attribute='entity_id') | list }}
      select_option:
        - delay: 1

Hi @Didgeridrew thanks for sending the info. I hadn’t seen the Template Select Entities (hyperlink didn’t seem to work :thinking:) but you were spot on, I wasn’t trying it. I have update my code below and works almost** perfectly

- select:
  - name: test_dropdown
    unique_id: bob_1234
    icon: mdi:lightbulb
    state: "{{ states('input_text.nutrient_pumps') }}"
    options: "{{ states.fan | map(attribute='entity_id') | list }}"
    select_option:
      - action: input_text.set_value
        target:
          entity_id: input_text.nutrient_pumps
        data: 
          value: "{{ option }}"

input_text.yaml:

  nutrient_pumps:
    name: Pump Selected

I tried using your optimistic code (assuming to add in the state: “{{option”} part) and it also worked

  - name: test_dropdown
    unique_id: bob_1234
    icon: mdi:lightbulb
    state: "{{ option }}"
    optimistic: true
    options: >
      {{ states.fan | map(attribute='entity_id') | list }}
    select_option:
      - delay: 1

**Both snippets of code work in exactly the same way where by I am getting a weird result where two pumps are triggered. I have 10 all together. I select pump1 and both pumps 1 and 5 run. I select pump 2 and both pumps 2 and 6 run and so on😂

just for clarity, my wiring is all good and of course my esp32 code is good too. As you hopefully will have guessed.

That’s not needed… state is an optional variable, so I would leave it out:

image

Post the automation so we can see how they might be interacting.

Oh interesting. I wouldn’t have questioned it had studio code not complained that state was missing.

I did have a look over it but no doubt I’ve done something dodgy:

blueprint:
  name: Nutrient Pump Time Calibration
  description: "This automation allows you to calculate the number of ml or L per second for a chosen pump or sensor"
  domain: automation
  input:
    add_nutrients_complete_event:
      name: "Title"
      description: "Add Title"
      selector:
        text:

triggers:
  - trigger: state
    entity_id: input_button.start_pump_calibration_test

actions:
  # Priming pump
  - action: fan.set_direction
    data:
      direction: forward
    target:
      entity_id: "{{ states('select.test_dropdown') }}"
  - action: fan.set_percentage
    data:
      percentage: "{{ states('input_number.test_priming_speed') | int(0) }}"
    target:
      entity_id: "{{ states('select.test_dropdown') }}"
  - action: fan.turn_on
    data: {}
    target:
      entity_id: "{{ states('select.test_dropdown') }}"
  - delay:
      seconds: "{{ states('input_number.test_priming_time') }}"
  - action: fan.turn_off
    data: {}
    target:
      entity_id: "{{ states('select.test_dropdown') }}"

  # Starting pump to feed
  - action: fan.turn_on
    data:
      percentage: "{{ states('input_number.test_pump_feed_speed') | int(0) }}"
    target:
      entity_id: "{{ states('select.test_dropdown') }}"
  - delay:
      seconds: "{{ states('sensor.test_pump_dosing_time') }}"
  - action: fan.turn_off
    data: {}
    target:
      entity_id: "{{ states('select.test_dropdown') }}"

  # Clearing pump of remaining nutrients
  - action: fan.set_direction
    data:
      direction: reverse
    target:
      entity_id: "{{ states('select.test_dropdown') }}"
  - action: fan.turn_on
    data:
      percentage: "{{ states('input_number.clear_nutrient_speed') | float }}"
    target:
      entity_id: "{{ states('select.test_dropdown') }}"
  - delay:
      seconds: "{{ states('input_number.clear_nutrient_time') | float }}"
  - action: fan.turn_off
    data: {}
    target:
      entity_id: "{{ states('select.test_dropdown') }}"

mode: single

The Studio Code extension is quite a bit behind right now so it throws a lot of false positives.

Overall it looks fine… but I’m a little confused. Why set it up as a blueprint if you aren’t using any inputs?

The one thing I would suggest is to DRY your templates so that state changes can’t cause the targets or values to change mid-run. At a minimum, do it for {{ states('select.test_dropdown') }}:

blueprint:
  name: Nutrient Pump Time Calibration
  description: "This automation allows you to calculate the number of ml or L per second for a chosen pump or sensor"
  domain: automation
  input:
    add_nutrients_complete_event:
      name: "Title"
      description: "Add Title"
      selector:
        text:

triggers:
  - trigger: state
    entity_id: input_button.start_pump_calibration_test
variables:
  dropdown: "{{ states('select.test_dropdown') }}" 
actions:
  # Priming pump
  - action: fan.set_direction
    data:
      direction: forward
    target:
      entity_id: "{{ dropdown }}"
  - action: fan.set_percentage
    data:
      percentage: "{{ states('input_number.test_priming_speed') | int(0) }}"
    target:
      entity_id: "{{ dropdown }}"
  - action: fan.turn_on
    data: {}
    target:
      entity_id: "{{ dropdown }}"
  - delay:
      seconds: "{{ states('input_number.test_priming_time') }}"
  - action: fan.turn_off
    data: {}
    target:
      entity_id: "{{ dropdown }}"

  # Starting pump to feed
  - action: fan.turn_on
    data:
      percentage: "{{ states('input_number.test_pump_feed_speed') | int(0) }}"
    target:
      entity_id: "{{ dropdown }}"
  - delay:
      seconds: "{{ states('sensor.test_pump_dosing_time') }}"
  - action: fan.turn_off
    data: {}
    target:
      entity_id: "{{ dropdown }}"

  # Clearing pump of remaining nutrients
  - action: fan.set_direction
    data:
      direction: reverse
    target:
      entity_id: "{{ dropdown }}"
  - action: fan.turn_on
    data:
      percentage: "{{ states('input_number.clear_nutrient_speed') | float }}"
    target:
      entity_id: "{{ dropdown }}"
  - delay:
      seconds: "{{ states('input_number.clear_nutrient_time') | float }}"
  - action: fan.turn_off
    data: {}
    target:
      entity_id: "{{ dropdown }}"
mode: single

Good question! I don’t know. I seem to have gotten into the habit of writing everything as a blueprint but I do see that in this case there is no point.

It is quite odd. I did try and google what you meant but is that want you meant by “Dry my templates”, by adding a variable for the dropdown, so that the entity is only set once?

Sorry… DRY = Don’t Repeat Yourself.

Instead of running the states() function multiple times to get what should be the same information, run it once and save that value to a variable. It’s a little bit more efficient, but in this case it’s mainly to prevent a situation where Priming is performed on pump 1, then during the delay someone changes the Select, and Feeding gets performed on pump 3… By saving it to a variable you guarantee the target pump stays the same throughout. Consider doing the same for your other templates if warranted.

1 Like

Thanks for clarifying. DRY now makes sense and will certainly apply it where necessary.

It turns out there is nothing wrong with the code and it’s something to do with the esp32-s3 controller I am using. I have two and installed everything on my spare controller and the same thing happens. When I trigger the L298N motor driver module for pins 6 and 7, it also triggers pins 4 and 5. Strange behaviour and I’ll need to do some research into why that is. My esphome(esp32) code below for reference:

output:
  # Pump 1
  - platform: ledc
    id: pump_1_forward
    pin: GPIO6
    inverted: false
  - platform: ledc
    id: pump_1_reverse
    pin: GPIO7
    inverted: true
  # Pump 2
  - platform: ledc
    id: pump_2_forward
    pin: GPIO15
    inverted: true
  - platform: ledc
    id: pump_2_reverse
    pin: GPIO16
    inverted: true
  # Pump 3
  - platform: ledc
    id: pump_3_forward
    pin: GPIO13
    inverted: true
  - platform: ledc
    id: pump_3_reverse
    pin: GPIO14
    inverted: true
  # Pump 4
  - platform: ledc
    id: pump_4_forward
    pin: GPIO12
    inverted: false
  - platform: ledc
    id: pump_4_reverse
    pin: GPIO11
    inverted: true
   # Pump 5
  - platform: ledc
    id: pump_5_forward
    pin: GPIO5
    inverted: true
  - platform: ledc
    id: pump_5_reverse
    pin: GPIO4
    inverted: true
  # Pump 6
  - platform: ledc
    id: pump_6_forward
    pin: GPIO42
    inverted: true
  - platform: ledc
    id: pump_6_reverse
    pin: GPIO41
    inverted: true
  # Pump 7
  - platform: ledc
    id: pump_7_forward
    pin: 37
    inverted: true
  - platform: ledc
    id: pump_7_reverse
    pin: 38
    inverted: true
  # Pump 8
  - platform: ledc
    id: pump_8_forward
    pin: 35
    inverted: true
  - platform: ledc
    id: pump_8_reverse
    pin: 36
    inverted: true
  # Pump 9
  - platform: ledc
    id: pump_9_forward
    pin: 48
    inverted: true
  - platform: ledc
    id: pump_9_reverse
    pin: 45
    inverted: true
  # Pump 10 - Spare
  # - platform: ledc
  #   id: pump_10_forward
  #   pin: 47 - PH switch
  # - platform: ledc
  #   id: pump_10_reverse
  #   pin: 21

fan:
  - platform: hbridge
    id: pump_1
    name: "pump 1"
    pin_a: pump_1_forward
    pin_b: pump_1_reverse
    decay_mode: SLOW
    speed_count: 100

  - platform: hbridge
    id: pump_2
    name: "pump 2"
    pin_a: pump_2_forward
    pin_b: pump_2_reverse
    decay_mode: SLOW
    speed_count: 100

  - platform: hbridge
    id: pump_3
    name: "pump 3"
    pin_a: pump_3_forward
    pin_b: pump_3_reverse
    decay_mode: SLOW
    speed_count: 100

  - platform: hbridge
    id: pump_4
    name: "pump 4"
    pin_a: pump_4_forward
    pin_b: pump_4_reverse
    decay_mode: SLOW
    speed_count: 100

  - platform: hbridge
    id: pump_5
    name: "pump 5"
    pin_a: pump_5_forward
    pin_b: pump_5_reverse
    decay_mode: SLOW
    speed_count: 100

  - platform: hbridge
    id: pump_6
    name: "pump 6"
    pin_a: pump_6_forward
    pin_b: pump_6_reverse
    decay_mode: SLOW
    speed_count: 100

  - platform: hbridge
    id: pump_7
    name: "pump 7"
    pin_a: pump_7_forward
    pin_b: pump_7_reverse
    decay_mode: SLOW
    speed_count: 100

  - platform: hbridge
    id: pump_8
    name: "pump 8"
    pin_a: pump_8_forward
    pin_b: pump_8_reverse
    decay_mode: SLOW
    speed_count: 100

  - platform: hbridge
    id: pump_9
    name: "pump 9"
    pin_a: pump_9_forward
    pin_b: pump_9_reverse
    decay_mode: SLOW
    speed_count: 100

  # - platform: hbridge
  #   id: pump_10
  #   name: "pump spare"
  #   pin_a: pump_10_forward
  #   pin_b: pump_10_reverse
  #   decay_mode: SLOW
  #   speed_count: 100