Hi everyone,
I’ve run into a strange behavior while setting up two mutually exclusive Template Switches for network routing (switching an Apple TV between a US and a UK VPN/DNS setup via OPNsense REST commands).
The goal is simple: when turning Switch A on, it should turn Switch B off, wait for Switch B to officially report its state as off, and then execute a corresponding script containing startup API calls.
I tested the logic in two different ways. One fails (the switch flips on and snaps back off), while the other works flawlessly. I’m trying to understand if this is an inherent architectural limitation of template entities or an unintended bug in the state engine/event loop.
The Setup
I have two template switches: switch.appletv_usa and switch.appletv_uk.
Scenario A: Configuring logic directly in the Template Switch (FAILS)
When I paste the sequence directly into the turn_on action block of the UI Helper/YAML configuration for the switch, the switch turns on in the UI but then snaps back off after a few seconds. Crucially, looking at the execution, the switch.turn_off works as expected, but the subsequent script after the wait_template is never executed. This happens even if switch.appletv_uk was already completely off before clicking the toggle.
# Configured directly inside switch.appletv_usa "Actions on turn on"
sequence:
- action: switch.turn_off
target:
entity_id: switch.appletv_uk
- wait_template: "{{ is_state('switch.appletv_uk', 'off') }}"
continue_on_timeout: false
- action: script.turn_on_apple_tv_over_us
*Note: {{ is_state('switch.appletv_uk', 'off') }} syntax is valid and returns True, tested with Developer Tools -> Templates.
Scenario B: Moving the exact same logic to a Standalone Script (WORKS)
If I take the exact same YAML sequence block, move it into a standalone script (script.turn_on_apple_tv_usa), it works perfectly every single time without a hitch. The switch stays on, and all routing actions complete.
Why?
So why does the sequence engine choke on a state evaluation wait_template (causing the switch to fail validation and snap back off) when it is running inline within a template switch's own action domain, but evaluates it cleanly when decoupled into the script domain?
Is there some state-lock that prevents a template switch from successfully evaluating a wait_template condition during its own execution phase? Or is it becuase the entity I am checking in wait_template is in itself defined by a template?
Would love some help here. Did I miss something obvious here?