Files
advanced-camera-card/docs/configuration/view.md
T
Dermot DuffyandClaude Opus 4.8 b701366762 feat: Align automations with Home Assistant triggers and conditions (#2527)
Split automations into HA-style `triggers`, ongoing `conditions`, and
`actions`, with compatibility migrations for existing Advanced Camera
Card configs.

## Summary

At a glance (details below):

- **Added** `triggers:` -- a required, HA-shaped block: stock `state` /
`numeric_state` / `template` plus card-specific triggers (`camera`,
`view`, `fullscreen`, ...).
- **Added** the HA-native `if` / `then` / `else` action.
- **Removed** `actions_not` (replaced by `if` / `then` / `else`).
- **Removed** the ambient `advanced_camera_card` template namespace (use
`acc` instead).
- **Changed** the trigger template surface to a top-level `trigger.*`
variable (as in HA); the nested `acc.trigger.*` paths are removed.
- **Changed** `conditions:` to ongoing gates only -- they no longer wake
an automation, and change-only forms (`config`, valueless `camera` /
`view` / `state`) become triggers, not conditions.
- **Changed** action templates to render per step, so a later action
sees state an earlier one changed.
- **Compatibility:** HA-shaped YAML is accepted (singular keys,
single-or-list, `and` / `or` / `not` shorthand, `entity` / `entity_id`).
- **Migration:** existing configs upgrade automatically; anything that
cannot be converted faithfully is recorded under `__UPGRADE_FAILURE__`
for manual fixup.

## Breaking Changes

### 1. Automations now require triggers

Before this PR, `automations[].conditions` served two roles:

- They decided whether the automation should run.
- They also acted as the thing that woke the automation up.

After this PR:

- `triggers` wake the automation.
- `conditions` only gate it at the instant a trigger fires.

Most existing automations are migrated automatically from `conditions:`
to `triggers:`.

### 2. `actions_not` is retired

Legacy `actions_not` is replaced by an HA-style `if` action with `then`
/ `else`.

Faithful conversions are automatic. Cases that cannot be faithfully
converted are recorded under `__UPGRADE_FAILURE__.automations` and must
be migrated manually.

### 3. Template surface aligned with Home Assistant

Two related template changes, both auto-migrated:

- **Top-level `trigger.*`.** Automation actions now receive a top-level
`trigger` template variable, like Home Assistant. Legacy nested paths
such as `acc.trigger.state.to` and
`advanced_camera_card.trigger.camera.to` are migrated automatically when
they appear inside template strings.
- **The ambient `advanced_camera_card` template namespace is removed.**
The long-form ambient namespace (`advanced_camera_card.camera`,
`advanced_camera_card.view`, `advanced_camera_card.config`) is retired
in favour of its shorter `acc` alias -- supported since v7.1.0, and the
only spelling the new trigger surface uses. Existing templates are
migrated automatically by rewriting the `advanced_camera_card.` prefix
to `acc.`.

### 4. Trigger-only condition forms are no longer valid conditions

Some legacy "conditions" were really change detectors. These are now
triggers only:

- `condition: config`
- valueless `camera`
- valueless `view`
- valueless `state` / picture-elements state condition with neither
`state` nor `state_not`

These are automatically promoted in automations and stripped from
overrides/elements where they would no longer be meaningful as ongoing
conditions.

### 5. Template truthiness now follows Home Assistant behavior

Template conditions and template triggers intentionally use different
truthiness rules, matching HA:

- A template condition passes only when the rendered value is `true`
(case-insensitive), matching HA's `condition.py`.
- A template trigger uses HA's broader `result_as_boolean` coercion: a
non-zero number, or `1` / `true` / `yes` / `on` / `enable`
(case-insensitive), counts as true.

### 6. Action templates render when each action executes

Action templates are now rendered per action step, not once for the
whole sequence. This means a later action can see card-local state
changed by an earlier action in the same sequence.

The `trigger` context is fixed for the automation run. HA entity state
updates still depend on the frontend receiving updated HASS state over
the websocket.

## Automatic Migrations

### Automation `conditions:` to `triggers:`

Simple legacy automation:

```yaml
# Before
automations:
  - conditions:
      - condition: fullscreen
        fullscreen: true
    actions:
      - action: custom:advanced-camera-card-action
        advanced_camera_card_action: substream_on
```

```yaml
# After, automatic
automations:
  - triggers:
      - trigger: fullscreen
        fullscreen: true
    actions:
      - action: custom:advanced-camera-card-action
        advanced_camera_card_action: substream_on
```

State conditions become HA-style state triggers:

```yaml
# Before
automations:
  - conditions:
      - condition: state
        entity_id: binary_sensor.front_door
        state: 'on'
    actions:
      - action: custom:advanced-camera-card-action
        advanced_camera_card_action: live
```

```yaml
# After, automatic
automations:
  - triggers:
      - trigger: state
        entity_id: binary_sensor.front_door
        to: 'on'
    actions:
      - action: custom:advanced-camera-card-action
        advanced_camera_card_action: live
```

Multiple conditions become both triggers and ongoing conditions:

```yaml
# Before
automations:
  - conditions:
      - condition: camera
        cameras: [front_door]
      - condition: fullscreen
        fullscreen: true
    actions:
      - action: custom:advanced-camera-card-action
        advanced_camera_card_action: substream_on
```

```yaml
# After, automatic
automations:
  - triggers:
      - trigger: camera
        cameras: [front_door]
      - trigger: fullscreen
        fullscreen: true
    conditions:
      - condition: camera
        cameras: [front_door]
      - condition: fullscreen
        fullscreen: true
    actions:
      - action: custom:advanced-camera-card-action
        advanced_camera_card_action: substream_on
```

The flattened trigger list is an implicit OR. The retained `conditions:`
list is an implicit AND checked when any trigger fires.

### Trigger-only legacy conditions

Legacy `config` conditions become `config` triggers:

```yaml
# Before
automations:
  - conditions:
      - condition: config
        paths: [menu.style]
    actions:
      - action: custom:advanced-camera-card-action
        advanced_camera_card_action: status_bar
```

```yaml
# After, automatic
automations:
  - triggers:
      - trigger: config
        paths: [menu.style]
    actions:
      - action: custom:advanced-camera-card-action
        advanced_camera_card_action: status_bar
```

Trigger-only leaves are removed from retained `conditions:` blocks
because they no longer describe an ongoing state.

### `actions_not` to `if` / `then` / `else`

```yaml
# Before
automations:
  - conditions:
      - condition: state
        entity_id: input_boolean.camera_alerts
        state: 'on'
    actions:
      - action: custom:advanced-camera-card-action
        advanced_camera_card_action: live
    actions_not:
      - action: none
```

```yaml
# After, automatic
automations:
  - triggers:
      - trigger: state
        entity_id: input_boolean.camera_alerts
    actions:
      - if:
          - condition: state
            entity_id: input_boolean.camera_alerts
            state: 'on'
        then:
          - action: custom:advanced-camera-card-action
            advanced_camera_card_action: live
        else:
          - action: none
```

If the legacy automation had no conditions, or only trigger-only
conditions, `actions_not` is dropped because the old `else` branch could
not be reproduced as an ongoing predicate.

### Trigger template paths

```yaml
# Before
message: 'Door is {{ acc.trigger.state.to }} from {{ acc.trigger.state.from }}'
```

```yaml
# After, automatic
message: 'Door is {{ trigger.to_state.state }} from {{ trigger.from_state.state }}'
```

Path rewrites performed automatically:

| Old path                   | New path                   |
| -------------------------- | -------------------------- |
| `acc.trigger.state.entity` | `trigger.entity_id`        |
| `acc.trigger.state.from`   | `trigger.from_state.state` |
| `acc.trigger.state.to`     | `trigger.to_state.state`   |
| `acc.trigger.camera.from`  | `trigger.from_acc.camera`  |
| `acc.trigger.camera.to`    | `trigger.to_acc.camera`    |
| `acc.trigger.view.from`    | `trigger.from_acc.view`    |
| `acc.trigger.view.to`      | `trigger.to_acc.view`      |
| `acc.trigger.config.from`  | `trigger.from_acc.config`  |
| `acc.trigger.config.to`    | `trigger.to_acc.config`    |

The same rewrites are applied for the older
`advanced_camera_card.trigger.*` namespace.

### Ambient template namespace

Any remaining long-form ambient `advanced_camera_card.*` references
(outside the trigger surface) are rewritten to the `acc.*` alias:

```yaml
# Before
title: 'Now viewing {{ advanced_camera_card.camera }}'
```

```yaml
# After, automatic
title: 'Now viewing {{ acc.camera }}'
```

## Manual Migration Cases

### `__UPGRADE_FAILURE__.automations`

If a legacy automation cannot be converted faithfully, the original
automation is recorded under:

```yaml
__UPGRADE_FAILURE__:
  automations:
    - ...
```

These entries require manual migration.

The main known case is legacy `actions_not` with a condition whose
trigger can only fire on a rising edge, such as:

- `condition: template`
- `condition: screen`
- `condition: numeric_state` without an entity-backed state to watch

Those conditions can start the `then` branch, but cannot reliably start
the `else` branch when they stop matching.

### Unsupported HA conditions and triggers

This PR aligns the card with HA where supported, but it is not a full HA
automation engine.

Unsupported HA condition families include:

- `time`
- `zone`
- `sun`
- `location`
- `device`
- `condition: trigger`

Unsupported HA trigger platforms include:

- `event`
- `time`
- `time_pattern`
- `sun`
- `zone`
- `calendar`
- `webhook`
- `tag`
- `device`
- `mqtt`

The card-specific camera `triggers:` feature (which auto-selects and
wakes the card on camera events such as motion) is a separate feature
from automation `triggers:`, despite the shared word.

### Trigger IDs and variables

HA keys such as `id`, `alias`, and `variables` are accepted so pasted HA
YAML validates, but they are ignored by the card. There is no
`trigger.id` support in this PR.

## New Compatibility Features

This PR also makes card config more forgiving for HA-style YAML:

- `trigger`, `condition`, and `action` singular keys are accepted and
normalized to `triggers`, `conditions`, and `actions`.
- Single trigger, condition, and action objects are accepted where lists
are expected.
- `if`, `then`, and `else` accept a single item or a list.
- Composite condition shorthand is accepted:
  - `{ and: [...] }`
  - `{ or: [...] }`
  - `{ not: [...] }`
  - `{ condition: [...] }` as an implicit AND
- State conditions resolve expected state values that name another
entity, matching HA/Lovelace behavior.
- Both `entity` and `entity_id` are accepted on state and numeric
conditions and triggers (a superset of HA's two dialects), so there is
no forced rename.
- `state_not` remains supported as a card/Lovelace-friendly extension.

## Trigger Payloads

Automation action templates receive a top-level `trigger` object.

For stock `state` and `numeric_state` triggers:

```yaml
trigger.platform
trigger.entity_id
trigger.entity
trigger.from_state
trigger.to_state
```

For template triggers:

```yaml
trigger.platform
```

For card-specific triggers:

```yaml
trigger.platform # "acc"
trigger.type
trigger.from_acc
trigger.to_acc
```

The card does not currently expose HA's `id`, `idx`, `for`, `attribute`,
`above`, `below`, or `alias` trigger fields.

BREAKING CHANGE: Automations now follow Home Assistant's `triggers:` /
`conditions:` / `actions:` model. Automations require a `triggers:`
block and `conditions:` no longer wake an automation; `actions_not` is
removed in favour of an `if` / `then` / `else` action; the nested
`acc.trigger.*` template paths and the ambient `advanced_camera_card`
template namespace are removed (use the top-level `trigger.*` surface
and the `acc` alias); trigger-only condition forms (`config`, valueless
`camera` / `view` / `state`) are no longer valid conditions; and
template-condition vs template-trigger truthiness now follow HA.
Existing configs are upgraded automatically where a faithful conversion
exists; anything that cannot be converted is recorded under
`__UPGRADE_FAILURE__` for manual migration.

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 17:45:13 -07:00

30 KiB

view

The view configuration options control how the default view of the card behaves.

view:
  # [...]
Option Default Description
actions Actions to use for all views, individual actions may be overriden by view-specific actions.
camera_select current The view to show when a new camera is selected (e.g. in the camera menu). If current the view is unchanged when a new camera is selected.
dim false Whether or not to 'dim' the brightness of the card (by 25%) if the card interaction_seconds has expired (i.e. card has been left unattended for that period of time).
default auto The view to show in the card by default. If auto, the card will choose live when cameras are configured, folders when folders are configured, or image otherwise (default embedded image). The default camera is the first one listed. See Supported Views.
default_reset The circumstances and behavior that cause the card to reset to the default view. See default_reset.
interaction_seconds 300 After a mouse/touch interaction with the card, it will be considered "interacted with" until this number of seconds elapses without further interaction. May be used as part of an interaction condition or with default_reset.after_interaction to reset the view after the interaction is complete.
issues How the card handles issues and retries. See issues.
keyboard_shortcuts See usage for defaults. Configure keyboard shortcuts. See keyboard_shortcuts.
render_entities YAML only: A list of entity ids that should cause the card to re-render 'in-place'. The view/camera is not changed. This should very rarely be needed, but could be useful if the card is both setting and changing HA state of the same object as could be the case for some complex card_mod scenarios (example).
theme How the card is themed. See theme.
triggers How to react when a camera is triggered.
default_cycle_camera false When set to true the selected camera is cycled on each default view change.

default_reset

Configure the circumstances and behavior that cause the card to reset to the default view. All configuration is under:

view:
  default_reset: [...]
Option Default Description
after_interaction false If true the card will reset to the default configured view (i.e. 'screensaver' functionality) after interaction_seconds has elapsed after user interaction.
entities A list of entities that should cause the view to reset to the default (if the entity only pertains to a particular camera use triggers for the selected camera instead).
interaction_mode inactive Whether the default reset should happen when the card is being interacted with. If all, the reset will always happen regardless. If inactive the reset will only be taken if the card has not had human interaction recently (as defined by view.interaction_seconds). If active the reset will only be happen if the card has had human interaction recently. This controls resets triggered by entities and every_seconds, but not after_interaction which by definition requires no interaction.
every_seconds 0 A number of seconds after which to automatically reset to the default view. 0 disables this functionality.

issues

Configure how the card handles errors/issues and automatic retries.

All configuration is under:

view:
  issues:
    # [...]
Option Default Description
interaction_mode all Whether scheduled retries should happen when the card is being interacted with. If all, retries will always happen regardless. If inactive retries will only happen if the card has not had human interaction recently (as defined by view.interaction_seconds). If active retries will only happen if the card has had human interaction recently. User-initiated retries are always allowed.
retry_seconds auto Controls automatic retry attempts when an issue is detected (e.g. media not loading, query error). When auto, the card uses an exponential backoff schedule starting at ~30 seconds and capped at 10 minutes, with jitter to avoid multiple cards retrying in lockstep. A positive number sets a fixed retry interval in seconds. 0 disables automatic retries entirely. User-initiated retries (e.g. clicking a notification) always run regardless.

keyboard_shortcuts

All configuration is under:

view:
  keyboard_shortcuts: [...]

Configure the key-bindings for the builtin keyboard shortcuts. See usage information for defaults on keyboard shortcuts.

Option Default Description
enabled true If true, keyboard shortcuts are enabled. If false, they are disabled.
ptz_left, ptz_right, ptz_up, ptz_down, ptz_zoom_in, ptz_zoom_out, ptz_home See usage for defaults. An object that configures the key binding for a given pre-configured action. See Keyboard Shortcut Configuration.

Keyboard Shortcut Configuration

Option Default Description
key Any keyboard key value, e.g. ArrowLeft
ctrl false If true requires the ctrl key to be held.
shift false If true requires the shift key to be held.
alt false If true requires the alt key to be held.
meta false If true requires the meta key to be held.

theme 🎨

All configuration is under:

view:
  theme: [...]

Configure the theming/colors applied to the card.

Option Default Description
themes [traditional] A list of themes that are applied sequentially. Valid themes are shown below. Usually only a single value is needed. An empty list is treated the same as the default.
overrides A list of CSS keys that can be used to tweak the theming.

themes

Theme Description
dark Use a dark theme that is identical to the HA dark theme.
ha Uses HA-prescribed theming. Respects HA choice of dark or light colors.
light Use a light theme that is similar to the HA light theme (there are some differences if you do not use the standard choices of primary color).
traditional A theme based on the default Advanced Camera Card theme before full theming support was added. Respects HA color theme choices.

overrides

Allows overriding of any CSS value, can be used to tweak theming parameters.

Option Description
Any CSS key. Overriding the Advanced Camera Card CSS variables allows changing individual theming parameters, e.g. --advanced-camera-card-menu-override-background Any CSS value, e.g. red or rgba(10, 11, 12, 0.64).

[!WARNING] Changes to CSS keys are not considered breaking changes and may not have an associated major version change.

triggers

The triggers block controls how the card reacts when a camera is triggered (note that what triggers the camera is controlled by the triggers block within the config for a given camera). This can be used for a variety of purposes, such as allowing the card to automatically change to live for a camera that triggers.

All configuration is under:

view:
  triggers:
    # [...]

When all trigger sources for a camera end (e.g. an entity state returns to something other than on or open), an untrigger action can be taken.

The triggered state can be extended by a number of seconds after the source ends (see untrigger_delay_seconds). Alternatively, a camera can be forcibly untriggered after a fixed duration regardless of the state of the trigger sources (see untrigger_force_seconds).

By default, trigger/untrigger actions are only taken when there is no ongoing human interaction with the card; this behavior can be configured via the interaction_mode parameter.

[!TIP] If a camera is already in a triggered state when the card starts, the trigger action is taken immediately. If multiple cameras are triggered at startup, they are all marked as triggered, but the action is only taken for the first one.

Option Default Description
actions The actions to take when a camera is triggered. See Trigger action configuration.
filter_selected_camera true If set to true will only trigger on the currently selected camera.
show_trigger_status false Whether or not the live view should show a visual indication that it is triggered (a pulsing border around the camera edge).
event_hold_seconds 30 The synthesized on-period for momentary trigger sources that have no native on/off state (e.g. HA event.* entities or anything that fires as a single signal). For a doorbell press paired with trigger: call, this is effectively the ring window during which the call can be answered. Added on top of untrigger_delay_seconds. Ignored for stateful sources (binary_sensor, switch, etc.).
untrigger_delay_seconds 0 The number of seconds to continue to consider the camera triggered after the source ends, before taking the configured untrigger action.
untrigger_force_seconds 0 The number of seconds after a camera first triggers before force untriggering that camera. Set to 0 to disable.

[!WARNING] If untrigger_force_seconds is used to untrigger a camera, the state will need to 'reset' (e.g. an entity would need to change state to off) before it will trigger again.

[!TIP] When pairing trigger: call with untrigger: call (the "ring-then-end-if-unanswered" pattern), the ring lasts until the source ends plus untrigger_delay_seconds. For momentary sources (HA event.* entities, a doorbell press), the source ends instantly so the ring window is event_hold_seconds (default 30s) plus untrigger_delay_seconds (default 0s).

Trigger action configuration

Option Default Description
interaction_mode inactive Whether actions should be taken when the card is being interacted with. If all, actions will always left be taken regardless. If inactive actions will only be taken if the card has not had human interaction recently (as defined by view.interaction_seconds). If active actions will only be taken if the card has had human interaction recently. This does not stop triggering itself (i.e. border will still pulse if show_trigger_status is true) but rather just prevents the actions being performed.
trigger update If set to update the current view is updated in place. If set to default the default view of the card will be reloaded. If set to live the triggered camera will be selected in live view. If set to media the appropriate media view (e.g. clip, snapshot, review) will be chosen to match a newly available media item (please note that only some camera engines support new media detection, e.g. frigate). If set to call a two-way-audio call is automatically started on the triggered camera. If set to none no action is taken.
untrigger none If set to default the default view of the card will be reloaded. If set to call any unanswered inbound call started by the matching call trigger action is ended (calls already answered persist and must be ended manually). If set to none no action will be taken.

Supported views

This card supports several different views.

Key Description
clip Shows a viewer for the most recent clip for this camera. Can also be accessed by holding down the clips menu icon.
clips Shows a gallery of clips for this camera.
folder Shows a viewer for the media from the default folder.
folders Shows a gallery of media and subfolders from the default folder.
gallery Shows a gallery of media for this camera's default media type.
image Shows a static image specified by the image parameter, can be used as a discrete default view or a screensaver (via view.interaction_seconds).
live Shows the live camera view with the configured live provider.
media Shows a viewer for the most recent media for this camera.
recording Shows a viewer for the most recent recording for this camera. Can also be accessed by holding down the recordings menu icon.
recordings Shows a gallery of recent (last day) recordings for this camera and its dependents.
review Shows a viewer for the most recent unreviewed review item (e.g. alerts/detections in Frigate).
reviews Shows a gallery of reviews for this camera and its dependents.
snapshot Shows a viewer for the most recent snapshot for this camera. Can also be accessed by holding down the snapshots menu icon.
snapshots Shows a gallery of snapshots for this camera.
timeline Shows an event timeline.

The default view is auto. It will select live when cameras are configured, folders when folders are configured, or image otherwise (default embedded image). You can override this with view.default.

Note

When using views in a view condition, the single-item viewer views (clip, snapshot, review, recording) are translated internally to media once the relevant media is fetched. You may need to match on media rather than the original view name in your condition.

Fully expanded reference

view:
  default: auto
  camera_select: current
  interaction_seconds: 300
  default_cycle_camera: false
  default_reset:
    after_interaction: false
    entities:
      - binary_sensor.my_motion_sensor
    every_seconds: 0
    interaction_mode: inactive
  render_entities:
    - switch.render_card
  issues:
    interaction_mode: all
    retry_seconds: auto
  dim: false
  triggers:
    show_trigger_status: false
    filter_selected_camera: true
    untrigger_delay_seconds: 0
    untrigger_force_seconds: 0
    actions:
      interaction_mode: inactive
      trigger: update
      untrigger: none
  keyboard_shortcuts:
    enabled: true
    ptz_left:
      key: 'ArrowLeft'
    ptz_right:
      key: 'ArrowRight'
    ptz_up:
      key: 'ArrowUp'
    ptz_down:
      key: 'ArrowDown'
    ptz_zoom_in:
      key: '+'
    ptz_zoom_out:
      key: '-'
    ptz_home:
      key: 'h'
  theme:
    themes:
      - ha
    overrides:
      '--advanced-camera-card-menu-button-active-color': red
      '--advanced-camera-card-menu-position-left-style-overlay-alignment-left-background': pink
  actions:
    entity: light.office_main_lights
    tap_action:
      action: none
    hold_action:
      action: none
    double_tap_action:
      action: none
    start_tap_action:
      action: none
    end_tap_action:
      action: none