Esphome Package included 3 times but only last button is created, multiple switches created

I am attempting to create a device with 6 solenoids connected to it

I want to ensure that if HA goes down - the esp32 still turns off the solenoid - so I tried to create a button , which runs a script which turns the output on and then 1 minute later off
At the moment I have only included the file 3 times

When I use the package with parameters I get a switch for each package - but only one button is created - the last one also the button turns all three switches on and then off after the one minute
The three switches operate independently but I have not checked if the GPIO pin is being correctly configured yet
I don’t know enough to see if there are three scripts ,
However I don’t understand how the package include works fine with the substitution work for both the switch and button - but only the last button gets created when all the Switches get created
I tried adding a space into the Button name before the $ - that does not help
I tried adding spaces before the $ in everything - but spaces are now allowed in IDs

Here is the screen shot of the ESPHome device - showing the three switches and the single button

Is this a bug, expected behaviour or am I just not doing something right.

I have enclosed the full file and template exactly as is

File esphome-web-5fec28.yaml

substitutions:
  mac_suffix: "5fec28"

esphome:
  name: esphome-web-$mac_suffix
  friendly_name: Orchard6

esp32:
  board: esp32dev
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret api_encryptionkey

ota:
  - platform: esphome
    password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${mac_suffix}"
    password: !secret wifi_password

captive_portal:

packages:
  VegetableGarden: !include
    file: .solenoidboardwithparams.yaml
    vars:
      solenoidname : 'vegetablegarden'
      solenoidpin : 15

  GumTrees : !include
    file: .solenoidboardwithparams.yaml
    vars:
      solenoidname : 'gumtrees'
      solenoidpin : 14

  Chickens : !include
    file: .solenoidboardwithparams.yaml
    vars:
      solenoidname : 'chickens'
      solenoidpin : 13

File esphome/.solenoidboardwithparams.yaml

api:
  services:
    - service: openvalvefor1min$solenoidname
      variables: {}
      then:
        - script.execute: Watertimer$solenoidname

button:
  platform: template
  name: RunWaterTimer$solenoidname
  id: my_button$solenoidname
  on_press:
  - script.execute: Watertimer$solenoidname


switch:
  - platform: gpio
    name:  "Water Solenoid $solenoidname"
    pin: GPIO$solenoidpin
    id: WaterSolenoid$solenoidname
#    inverted: yes
script:
  - id: Watertimer$solenoidname
    mode: restart # allow the script to be extended
    then:
    - switch.turn_on: WaterSolenoid$solenoidname
    - delay: 60sec
    - switch.turn_off: WaterSolenoid$solenoidname
  • Installation methodHome Assistant OS
  • Core2025.12.5
  • Supervisor2025.12.3
  • Operating System16.3
  • Frontend20251203.3

ESPHome Device Builder
Current version: 2025.12.5

You have to use the ${} notation in your packages, not just $

I was so hopeful - but there is no change with all substitutions having had the ${ syntax added

  • I have also done all 5 solenoids so there are more now

I also find it strange that the button - coded to only affect one switch affects all five switches

This is the copy and past from the Activity log in esphome

Orchard6 Water Solenoid greenhouse turned on
9:26:41 PM - Now
Orchard6 Water Solenoid nursery turned on
9:26:41 PM - Now
Orchard6 Water Solenoid chickens turned on
9:26:41 PM - Now
Orchard6 Water Solenoid gumtrees turned on
9:26:41 PM - Now
Orchard6 Water Solenoid vegetablegarden turned on
9:26:41 PM - Now
Orchard6 RunWaterTimer greenhouse changed to January 7, 2026 at 9:26 PM triggered by action Button: Press
9:26:41 PM - Now - Ross

The solenoid pin does seem to work as it shows up in the log

[21:23:47.795][C][switch.gpio:092]: GPIO Switch ‘Water Solenoid vegetablegarden’
[21:23:47.795][C][switch.gpio:092]: Restore Mode: always OFF
[21:23:47.798][C][switch.gpio:029]: Pin: GPIO15
[21:23:47.805][C][switch.gpio:092]: GPIO Switch ‘Water Solenoid gumtrees’
[21:23:47.805][C][switch.gpio:092]: Restore Mode: always OFF
[21:23:47.806][C][switch.gpio:029]: Pin: GPIO14
[21:23:47.810][D][api.connection:1398]: Home Assistant 2025.12.5 (192.168.33.224) connected
[21:23:47.820][C][switch.gpio:092]: GPIO Switch ‘Water Solenoid chickens’
[21:23:47.820][C][switch.gpio:092]: Restore Mode: always OFF
[21:23:47.821][C][switch.gpio:029]: Pin: GPIO13
[21:23:47.832][C][switch.gpio:092]: GPIO Switch ‘Water Solenoid nursery’
[21:23:47.832][C][switch.gpio:092]: Restore Mode: always OFF
[21:23:47.832][C][switch.gpio:029]: Pin: GPIO12
[21:23:47.856][C][switch.gpio:092]: GPIO Switch ‘Water Solenoid greenhouse’
[21:23:47.856][C][switch.gpio:092]: Restore Mode: always OFF
[21:23:47.856][C][switch.gpio:029]: Pin: GPIO16

/homeassistant/esphome/.solenoidboardwithparams.yaml

api:
  services:
    - service: openvalvefor1min${solenoidname}
      then:
        - script.execute: Watertimer${solenoidname}

button:
  platform: template
  name: "RunWaterTimer ${solenoidname}"
  id: my_button${solenoidname}
  on_press:
  - script.execute: Watertimer${solenoidname}


switch:
  - platform: gpio
    name:  "Water Solenoid ${solenoidname}"
    pin: GPIO${solenoidpin}
    id: WaterSolenoid${solenoidname}
#    inverted: yes
script:
  - id: Watertimer${solenoidname}
    mode: restart # allow the script to be extended
    then:
    - switch.turn_on: WaterSolenoid${solenoidname}
    - delay: 60sec
    - switch.turn_off: WaterSolenoid${solenoidname}

** esphome-web-5fec28.yaml**
(three ticks is not working )


substitutions:
  mac_suffix: "5fec28"

esphome:
  name: esphome-web-${mac_suffix}
  friendly_name: Orchard6

esp32:
  board: esp32dev
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: !secret api_encryptionkey

ota:
  - platform: esphome
    password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "${mac_suffix}"
    password: !secret wifi_password

captive_portal:

packages:
  VegetableGarden: !include
    file: .solenoidboardwithparams.yaml
    vars:
      solenoidname : 'vegetablegarden'
      solenoidpin : 15

  GumTrees : !include
    file: .solenoidboardwithparams.yaml
    vars:
      solenoidname : 'gumtrees'
      solenoidpin : 14

  Chickens : !include
    file: .solenoidboardwithparams.yaml
    vars:
      solenoidname : 'chickens'
      solenoidpin : 13

  Nursery : !include
    file: .solenoidboardwithparams.yaml
    vars:
      solenoidname : 'nursery'
      solenoidpin : 12

  GreenHouse : !include
    file: .solenoidboardwithparams.yaml
    vars:
      solenoidname : 'greenhouse'
      solenoidpin : 16


I missed the - on the button

button:
   platform: template
  ...

sgould be

button:
  - platform: template
    ...

and even better the helpful person who told me this also said - the “validate” button in ESPHome gives you the expanded full yaml , so it shows all the YASML AFTER the includes, expansions and substitutions

  • it was pretty obvious what was happening when I looked at that

That makes no difference for lists with only one member. It was something else.

Tom , First - That was the one change I made, just the single “-” added on to that one line , So it was not "something else " it was the “-”

I assume what it is is that I have five items in the list due to the way packages work -

1 Like