Automatic Backup Power automation not working as expected

I am making an esp32 device that does multiple functions controlling backup power with my network and home assistant, as well as a few security controls. Some of the functions I am automating to work when the esp32 is not connected to home assistant.

I want the esp32 to start a script that makes sure 5 external devices are powered on when the esp32 detects grid power restored. The esp32 remains continuously powered by battery. The binary sensor, shore_power_detect, detects the grid power. The devices are powered on by switches named modem, mcp23008_pin_1, networkpi, mcp23008_pin_0, and ups_power. ups_power is a template switch that combines a binary sensor (ups_power_detect) and a switch (ups_cycle). ups_cycle is a switch that is automated to act like a momentary button mimicking the ups device factory button. It is hardwired (hacked) directly into the ups device and running parallel with and how the factory button is operated.

The “while:” automation with long delay is to basically de-bounce any erratic grid power as it comes back on.

Everything in the config works as expected except my automation in question. When I test the esp32 and watch the logger it, if the ups_power is already on, it then turns it off and on again to instead of remaining in the on state, thus hard shutting down anything plugged into the ups. I’m assuming this might be because turning on the template switch (ups_power) that is already in “on” state is bound to the automated ups_cycle.
It gets even weirder. The script then tries to run again, but can’t because its a single only. And when I turn the ups_ back on manually, it is automatically turned off after about a couple minute delay.

Here’s the config. The automation (bellow shore_power_detect) and script (bottom of config, turn_on_full_network) in question are commented out.

Thanks!
Blake

esphome:
  name: "top-mechroom-control"

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:

ethernet:
  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO0_IN
  phy_addr: 1
  power_pin: GPIO16
  
i2c:
  sda: 5
  scl: 17
  
web_server:
  port: 10001
  ota: false 

mcp23008:
  - id: 'mcp23008_hub'
    address: 0x20

################################# Outputs ############################################

switch:
  - platform: restart
    name: "Restart Top Mechroom Control Module"

  - platform: gpio
    pin: 12
    name: "UPS Cycle"
    internal: True
    id: ups_cycle
    restore_mode: ALWAYS_OFF
    on_turn_on:
    - delay: 2000ms
    - switch.turn_off: ups_cycle

  - platform: template
    name: "UPS Power"
    id: ups_power
    lambda: |-
      if (id(ups_power_detect).state) {
        return true;
      } else {
        return false;
      }
    turn_on_action:
      - switch.turn_on: ups_cycle
    turn_off_action:
      - switch.turn_on: ups_cycle


  - platform: gpio
    pin: 4
    name: "Modem"
    id: modem
    restore_mode: ALWAYS_On
    inverted: true

  - platform: gpio
    pin: 2
    name: "NetworkPi"
    id: networkpi
    restore_mode: ALWAYS_On
    inverted: true

  - platform: template
    name: "Alarm Armed Switch"
    id: alarm_armed_switch
    optimistic: True
    turn_off_action:
      - switch.turn_off: top_mechroom_strobe

########### Expansion Hub Power Mosfets ################

  - platform: gpio
    name: "Top Mechroom Siren"
    pin:
      mcp23xxx: mcp23008_hub
      number: 5
      mode:
        output: true
      inverted: false
    restore_mode: ALWAYS_off
    id: mcp23008_pin_5

  - platform: gpio
    name: "Strobe Lamp"
    internal: true
    pin:
      mcp23xxx: mcp23008_hub
      number: 4
      mode:
        output: true
      inverted: false
    restore_mode: ALWAYS_off
    id: mcp23008_pin_4

  - platform: template
    name: "Top Mechroom Strobe"
    optimistic: true
    id: top_mechroom_strobe
    on_turn_on:
      - while:
          condition:
            switch.is_on: top_mechroom_strobe
          then:
          - switch.turn_on: mcp23008_pin_4
          - delay: 50ms
          - switch.turn_off: mcp23008_pin_4
          - delay: 175ms
    on_turn_off:
      - delay: 10ms
      - switch.turn_off: mcp23008_pin_4

  - platform: gpio
    name: "Aux Output 12v"
    pin:
      mcp23xxx: mcp23008_hub
      number: 3
      mode:
        output: true
      inverted: true
    restore_mode: ALWAYS_OFF
    id: mcp23008_pin_3

  - platform: gpio
    name: "Odroid Home Assistant"
    pin:
      mcp23xxx: mcp23008_hub
      number: 0
      mode:
        output: true
      inverted: true
    restore_mode: ALWAYS_on
    id: mcp23008_pin_0

  - platform: gpio
    name: "Top Mechroom Router and Switch"
    pin:
      mcp23xxx: mcp23008_hub
      number: 1
      mode:
        output: true
      inverted: true
    restore_mode: ALWAYS_on
    id: mcp23008_pin_1
    
  - platform: gpio
    name: "Top Mechroom Sensor Module"
    pin:
      mcp23xxx: mcp23008_hub
      number: 2
      mode:
        output: true
      inverted: true
    restore_mode: ALWAYS_OFF
    id: mcp23008_pin_2


############# Expansion Hub Opto Switch #########################

  - platform: gpio
    name: "Gate Cycle"
    pin:
      mcp23xxx: mcp23008_hub
      number: 7
      mode:
        output: true
      inverted: false
    restore_mode: ALWAYS_Off
    id: gate_cycle
    icon: "mdi:gate"
    on_turn_on:
    - delay: 500ms
    - switch.turn_off: gate_cycle
    
  - platform: gpio
    name: "Inverter Power"
    pin:
      mcp23xxx: mcp23008_hub
      number: 6
      mode:
        output: true
      inverted: false
    restore_mode: ALWAYS_on
    id: inverter_power

############################## Buttons #################################################

button:
  - platform: template
    name: "Restart Top Mechroom Router and Switch"
    on_press:
      then:
      - switch.turn_off: mcp23008_pin_1
      - delay: 10s
      - switch.turn_on: mcp23008_pin_1

  - platform: template
    name: "Restart Modem"
    on_press:
      then:
      - switch.turn_off: modem
      - delay: 10s
      - switch.turn_on: modem

############################### Inputs ###############################################

binary_sensor:

  - platform: gpio
    pin:
      number: 36
      mode: input
      inverted: true
    name: "Shore Power Detect"
    id: shore_power_detect
    device_class: power
#    on_press:
#      - while:
#          condition: 
#            binary_sensor.is_on: shore_power_detect
#          then: 
#          - delay: 240s
#          - switch.turn_off: inverter_power
#          - script.execute: turn_on_full_network
#    on_release:
#      then:
#         - switch.turn_on: inverter_power

  - platform: gpio
    pin:
      number: 32
      mode: input
      inverted: true
    name: "UPS Power Detect"
    id: ups_power_detect
    filters:
      - delayed_off: 500ms # capacitor on pin further delays off
    device_class: power

  - platform: gpio
    pin:
      number: 33
      mode: input
      inverted: true
    name: "VRelay 3"
    filters:
      - delayed_off: 50ms
    on_press:
      then:
        - script.execute: cycle_gate_script

  - platform: gpio
    pin:
      number: 14
      mode: input
      inverted: true
    name: "VRelay 4"
    filters:
      - delayed_off: 50ms
    on_press:
      then:
        - switch.turn_off: alarm_armed_switch

  - platform: gpio
    pin:
      number: 39
      mode: input
      inverted: false
    name: "Top Mechroom Door"
    filters:
      - delayed_off: 50ms
    device_class: door
    on_press:
      if:
        condition:
          and:
            - switch.is_on: alarm_armed_switch
            - binary_sensor.is_off: top_mechroom_control_module_status
        then:
          - switch.turn_on: top_mechroom_strobe
    on_release:
      if:
        condition:
          - binary_sensor.is_off: top_mechroom_control_module_status
        then:
          - delay: 10s
          - switch.turn_off: top_mechroom_strobe

  - platform: gpio
    pin:
      number: 15
      mode: input
      inverted: false
    name: "Gate"
    filters:
      - delayed_off: 50ms
    device_class: door
    icon: "mdi:gate"

  - platform: template
    name: "Alarm Armed Sensor"
    id: alarm_armed_sensor
    lambda: |-
      if (id(home_assistant_alarm_state).state == "armed_away" || id(home_assistant_alarm_state).state == "armed_home") {
        return true;
      } else {
        return false;
      }
    on_press:
      then:
        - switch.turn_on: alarm_armed_switch
    on_release:
      then:
        - switch.turn_off: alarm_armed_switch

  - platform: status
    name: "Top Mechroom Control Module Status"
    id: top_mechroom_control_module_status

################ HA Sensors ######################

  - platform: homeassistant
    name: "Low Battery Shut Off Home Assistant"
    entity_id: input_boolean.low_battery_shutoff_ha
    on_press:
      then:
        - switch.turn_off: mcp23008_pin_0
        - delay: 30s
        - switch.turn_off: mcp23008_pin_1

text_sensor:
  - platform: homeassistant
    name: "Home Assistant Alarm state"
    id: home_assistant_alarm_state
    entity_id: alarm_control_panel.alarm
    internal: True

################ Analog Sensor ###################

sensor:
  - platform: adc
    pin: 35
    name: "Battery Bank Voltage"
    update_interval: 3s
    attenuation: 6db
    accuracy_decimals: 1
    filters:
    - offset: 0
    - multiply: 12
    - sliding_window_moving_average:
        window_size: 10
        send_every: 10

##################### scripts #####################

script:
  - id: cycle_gate_script
    then:
      - switch.turn_on: gate_cycle
      - delay: 2000ms

#  - id: turn_on_full_network
#    then:
#      - switch.turn_on: modem
#      - delay: 60s
#      - switch.turn_on: mcp23008_pin_1 # switch and router
#      - delay: 180s
#      - switch.turn_on: networkpi
#      - switch.turn_on: mcp23008_pin_0 # odroid
#      - switch.turn_on: ups_power

  - id: turn_on_ha_network
    then:
      - switch.turn_on: modem
      - switch.turn_on: mcp23008_pin_1 # switch and router
      - switch.turn_on: networkpi
      - switch.turn_on: mcp23008_pin_0 # odroid

  - id: strobe
    then:
      - switch.turn_on: mcp23008_pin_3
      - delay: 100ms
      - switch.turn_off: mcp23008_pin_3
      - delay: 100ms