fix: Clear the initialized condition state when the card is not usable (#2646)

The `initialized` state (used in conditions/triggers) was written once
and never cleared, so it meant "has this card ever been initialized"
while everything reading it took it as "is this card usable now". Home
Assistant takes a card off the page and puts it back whenever its
dashboard tab is left and returned to, so the card initialized again
while the state claimed it was initialized throughout: `trigger:
initialized` fired once per card rather than once per startup, and
automations were dropped in between.

The card lifecycle is now an explicit state machine (`SessionManager`),
the only writer of `initialized`, which separates a card that is
starting up from one initializing part of itself again while it runs. A
new `ever` parameter (conditions/triggers) selects the old latched
behaviour.

`remote_control` uses that parameter to keep its two camera priorities
correct under repeated starts. With `camera_priority: entity` the card
now re-reads the entity every time it starts, so a camera selected while
the card was away is picked up on return. With `camera_priority: card`
the card writes the entity on its first start only, unchanged, since
repeating that write would overwrite a camera the user had selected.

Closes: #2642


BREAKING CHANGE: `condition: initialized` is now `false` whenever the
card is not usable, and `trigger: initialized` fires each time the card
starts up rather than only the first time. Set `ever: true` on either to
keep the previous behaviour.
This commit is contained in:
Dermot Duffy
2026-08-02 12:52:58 -07:00
committed by GitHub
parent e590f72783
commit 17146c8ca6
44 changed files with 1967 additions and 654 deletions
+16 -6
View File
@@ -295,9 +295,16 @@ triggers:
## `initialized`
Matches whether the card has finished initializing. As a **condition**, true
once the card is initialized; as a **trigger**, fires when the card initializes
(useful for running an [automation](./automations.md) on card start).
Matches whether the card is up and usable.
A card starts more than once: returning to its dashboard tab, restarting Home
Assistant, and recovering from an error all start it again. It stops being
started when it is taken off the page, when the Home Assistant connection is
lost, or when starting up fails.
As a **condition**, `true` while the card has finished starting up -- usable,
not merely present. As a **trigger**, fires each time the card finishes starting
up, useful for running an [automation](./automations.md) on card start.
```yaml
# As a condition:
@@ -308,9 +315,10 @@ triggers:
- trigger: initialized
```
| Parameter | Description |
| ----------------------- | ---------------------- |
| `condition` / `trigger` | Must be `initialized`. |
| Parameter | Default | Description |
| ----------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` / `trigger` | | Must be `initialized`. |
| `ever` | `false` | Match whether the card is started now (`false`), or whether it has _ever_ finished starting up (`true`). A trigger using `true` fires on a card's first start only, and not on later ones (e.g. returning to a dashboard tab previously visited). Reloading the page, a Home Assistant restart or changing the card config (excluding [overrides](./overrides.md)) will cause a brand new card to be (unavoidably) built. |
## `interaction`
@@ -785,6 +793,7 @@ conditions:
- condition: fullscreen
fullscreen: true
- condition: initialized
ever: false
- condition: interaction
interaction: true
- condition: key
@@ -863,6 +872,7 @@ triggers:
- trigger: fullscreen
fullscreen: true
- trigger: initialized
ever: false
- trigger: interaction
interaction: true
- trigger: key
+8
View File
@@ -13,6 +13,14 @@ overrides:
> [!WARNING]
> Whilst all configuration parameters are theoretically overridable, in some instances a configuration variable may only be consulted on startup or changing its value may negatively impact behavior -- override results may vary!
> [!WARNING]
> Avoid an override whose `conditions` depend on a value that the override itself
> changes. Applying it changes what its own conditions were matching, so it may
> turn itself on and off repeatedly, or undo the very change that applied it. Examples: a [`camera`](conditions-triggers.md?id=camera) condition that sets
> `cameras`, an
> [`initialized`](conditions-triggers.md?id=initialized) condition that sets
> anything the card must start up again to use.
The top-level `overrides` configuration block expects a list, with each list
item containing `conditions` and at least one of `merge`, `delete` or `set` specified.
+1 -1
View File
@@ -20,7 +20,7 @@ remote_control:
| Option | Default | Description |
| ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `camera` | | An `input_select` entity that the card will use for bidirectional control. When the selected camera on the card changes the entity will be updated to match. Likewise, when the entity state changes, the selected camera on the card will be updated to match. When the card is first started, the `input_select` entity will be updated to only have valid camera IDs from this card and the selected camera on the card will be updated to the existing entity value. Entities used for camera remote control must start with `input_select.`. |
| `camera_priority` | `card` | Controls whether the `card` or the `entity` has priority on initial card load. If `card`, the entity state is updated to match the camera shown on load. If `entity`, the card will select the camera shown by the entity on load. |
| `camera_priority` | `card` | Controls whether the `card` or the `entity` has priority when the card starts up. If `card`, the entity state is updated to match the camera shown, once, when the card first starts. If `entity`, the card selects the camera named by the entity every time the card starts up -- including on a return to its dashboard tab and after Home Assistant restarts -- so a change made to the entity while the card was away is picked up. |
> [!NOTE]
> To create an `input_select` entity to use in this manner, in the visual card editor, under `Remote Control -> Remote Control Entities`, choose `Create a new Dropdown helper`. Give the new entity an entity name (e.g. `my_selected_camera`) and an optional icon. You must specify at least one option -- you can use any placeholder value (e.g. `camera`) then choose `Add` (the card will automatically reset the allowable options on start). Finally, click `Create`.