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>
This commit is contained in:
Dermot Duffy
2026-06-30 17:45:13 -07:00
committed by dermotduffy
co-authored by Claude Opus 4.8
parent 209c873c58
commit b701366762
354 changed files with 11386 additions and 3020 deletions
+4 -4
View File
@@ -53,7 +53,7 @@ render and can operate in `image` or `folders` views depending on configuration.
#### Common configuration blocks
| Option | Description |
| ------------------------------ | --------------------- |
| [`actions`](actions/README.md) | Configure actions. |
| [`conditions`](conditions.md) | Configure conditions. |
| Option | Description |
| -------------------------------------- | --------------------- |
| [`actions`](actions/README.md) | Configure actions. |
| [`conditions`](conditions-triggers.md) | Configure conditions. |
+1 -1
View File
@@ -3,7 +3,7 @@
- [`actions`](actions/README.md)
- [`automations`](automations.md)
- [`cameras`](cameras/README.md)
- [`conditions`](conditions.md)
- [`conditions` / `triggers`](conditions-triggers.md)
- [`dimensions`](dimensions.md)
- [`elements`](elements/README.md)
- [`folders`](folders.md)
+1 -1
View File
@@ -5,7 +5,7 @@
- [Stock Actions](./stock/README.md)
- [`automations`](../automations.md)
- [`cameras`](../cameras/README.md)
- [`conditions`](../conditions.md)
- [`conditions` / `triggers`](../conditions-triggers.md)
- [`dimensions`](../dimensions.md)
- [`elements`](../elements/README.md)
- [`folders`](../folders.md)
@@ -5,7 +5,7 @@
- [Stock Actions](../stock/README.md)
- [`automations`](../../automations.md)
- [`cameras`](../../cameras/README.md)
- [`conditions`](../../conditions.md)
- [`conditions` / `triggers`](../../conditions-triggers.md)
- [`dimensions`](../../dimensions.md)
- [`elements`](../../elements/README.md)
- [`folders`](../../folders.md)
@@ -1,5 +1,33 @@
# Stock Actions
## `if` / `then` / `else`
Run one sequence of actions or another depending on a set of
[conditions](../../conditions-triggers.md). This action has no `action:` key: it
is identified by the presence of an `if` key, exactly as in [Home Assistant
script syntax](https://www.home-assistant.io/docs/scripts/#if-then). The `then`
sequence runs when all `if` conditions hold; the optional `else` sequence runs
otherwise.
```yaml
if:
- condition: state
entity_id: input_boolean.notify_enabled
state: 'on'
then:
- action: fire-dom-event
advanced_camera_card_action: live_substream_on
else:
- action: fire-dom-event
advanced_camera_card_action: live_substream_off
```
| Parameter | Description |
| --------- | ----------------------------------------------------------------- |
| `if` | A list of [conditions](../../conditions-triggers.md) to evaluate. |
| `then` | A list of actions to run when all `if` conditions hold. |
| `else` | An optional list of actions to run when the `if` conditions fail. |
## `more-info`
Open the "more-info" dialog for an entity. See [Home Assistant actions documentation](https://www.home-assistant.io/dashboards/actions/).
@@ -117,4 +145,21 @@ elements:
tap_action:
action: fire-dom-event
key: value
- type: icon
icon: mdi:numeric-8-box
title: If / then / else action
style:
left: 200px
top: 400px
tap_action:
if:
- condition: state
entity_id: light.office_main_lights
state: 'on'
then:
- action: fire-dom-event
advanced_camera_card_action: live_substream_on
else:
- action: fire-dom-event
advanced_camera_card_action: live_substream_off
```
+1 -1
View File
@@ -5,7 +5,7 @@
- [Stock Actions](README.md)
- [`automations`](../../automations.md)
- [`cameras`](../../cameras/README.md)
- [`conditions`](../../conditions.md)
- [`conditions` / `triggers`](../../conditions-triggers.md)
- [`dimensions`](../../dimensions.md)
- [`elements`](../../elements/README.md)
- [`folders`](../../folders.md)
+26 -14
View File
@@ -1,25 +1,36 @@
# `automations`
Automatically take [actions](actions/README.md) based on [conditions](conditions.md) being met.
Automatically run [actions](actions/README.md) in response to
[triggers](conditions-triggers.md), optionally gated by [conditions](conditions-triggers.md).
> [!TIP]
> To change configuration conditionally use [overrides](overrides.md).
> To change configuration conditionally, use [overrides](overrides.md) instead.
An automation has three parts, mirroring a Home Assistant automation:
- **`triggers:`** are the momentary occurrences that start the automation
(required). Multiple triggers are independent: any one firing runs the
automation (an implicit "or").
- **`conditions:`** are ongoing predicates checked the instant a trigger fires;
they must _all_ hold for `actions` to run (optional).
- **`actions:`** are what runs when a trigger fires and the conditions hold
(required).
```yaml
automations:
- conditions:
- triggers:
- [trigger]
conditions:
- [condition]
actions:
- [action]
actions_not:
- [action]
```
| Option | Default | Description |
| ------------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
| `conditions` | | A list of [conditions](conditions.md) that must evaluate to `true` in order to trigger the automation. |
| `actions` | | An optional list of [actions](actions/README.md) that will be run when the [conditions](conditions.md) evaluate `true`. |
| `actions_not` | | An optional list of [actions](actions/README.md) that will be run when the [conditions](conditions.md) evaluate `false`. |
| Option | Default | Description |
| ------------ | ------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `triggers` | | A list of [triggers](conditions-triggers.md) that initiate the automation. At least one is required. |
| `conditions` | | An optional list of [conditions](conditions-triggers.md) that must _all_ evaluate `true` at the instant a trigger fires for `actions` to run. |
| `actions` | | A list of [actions](actions/README.md) run when a trigger fires and the conditions hold (or no conditions are configured). |
# Fully expanded reference
@@ -27,13 +38,14 @@ automations:
```yaml
automations:
- conditions:
- triggers:
- trigger: state
entity_id: binary_sensor.front_door
to: 'on'
conditions:
- condition: fullscreen
fullscreen: true
actions:
- action: custom:advanced-camera-card-action
advanced_camera_card_action: substream_on
actions_not:
- action: custom:advanced-camera-card-action
advanced_camera_card_action: substream_off
```
+25 -18
View File
@@ -16,24 +16,24 @@ cameras_global:
# [...]
```
| Option | Default | Description |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `always_error_if_entity_unavailable` | `false` | When `true` and when `camera_entity` is specified, attempting to live stream this camera will always error out if the entity state is `unavailable`, even if the `live_provider` does not actually need the `camera_entity`. |
| `camera_entity` | | The Home Assistant camera entity. Used by most live providers for live stream data, and to auto-detect other camera metadata (e.g. Frigate camera name, camera title/icon). |
| `capabilities` | | Allows selective disabling of camera capabilities. See [`capabilities`](#capabilities). |
| `cast` | | Configuration that controls how this camera is "casted" / sent to media players. See [`cast`](#cast). |
| `dependencies` | | Other cameras that this camera should depend upon. See [`dependencies`](#dependencies). |
| `dimensions` | | Controls the dimensions and layout for media from this camera. See [`dimensions`](#dimensions). |
| `engine` | `auto` | The camera engine to use. If `auto` the card will attempt to choose the correct engine from the specified options. See [Engine](engine.md). |
| `frigate` | | Options for Frigate cameras. See [Frigate camera engine configuration](engine.md?id=frigate). |
| `icon` | Autodetected from `camera_entity` if that is specified. | The icon to use for this camera in the camera menu and in the next & previous controls when using the `icon` style. |
| `id` | `camera_entity`, `webrtc_card.entity` or `frigate.camera_name` if set (in that preference order). If none of these are set, the camera has no `id` and cannot be referenced by name in conditions or actions. | An optional identifier to use throughout the card configuration to refer unambiguously to this camera. This `id` may be used in [conditions](../conditions.md), dependencies or custom [actions](../actions/README.md) to refer to a given camera unambiguously. |
| `live_provider` | `auto` | The choice of live stream provider. See [Live Provider](live-provider.md). |
| `media` | | Controls the default media configuration (e.g. thumbnails) for this camera. See [`media`](#media). |
| `proxy` | | Controls whether/how content is proxied via [hass-web-proxy-integration](https://github.com/dermotduffy/hass-web-proxy-integration) (must be installed separately). See [`proxy`](#proxy). |
| `title` | Autodetected from `camera_entity` if that is specified. | A friendly name for this camera to use in the card. |
| `triggers` | | Define what should cause this camera to update/trigger. See [`triggers`](#triggers). |
| `webrtc_card` | | The WebRTC entity/URL to use for this camera with the `webrtc-card` live provider. See [Live Provider](live-provider.md?id=webrtc_card). |
| Option | Default | Description |
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `always_error_if_entity_unavailable` | `false` | When `true` and when `camera_entity` is specified, attempting to live stream this camera will always error out if the entity state is `unavailable`, even if the `live_provider` does not actually need the `camera_entity`. |
| `camera_entity` | | The Home Assistant camera entity. Used by most live providers for live stream data, and to auto-detect other camera metadata (e.g. Frigate camera name, camera title/icon). |
| `capabilities` | | Allows selective disabling of camera capabilities. See [`capabilities`](#capabilities). |
| `cast` | | Configuration that controls how this camera is "casted" / sent to media players. See [`cast`](#cast). |
| `dependencies` | | Other cameras that this camera should depend upon. See [`dependencies`](#dependencies). |
| `dimensions` | | Controls the dimensions and layout for media from this camera. See [`dimensions`](#dimensions). |
| `engine` | `auto` | The camera engine to use. If `auto` the card will attempt to choose the correct engine from the specified options. See [Engine](engine.md). |
| `frigate` | | Options for Frigate cameras. See [Frigate camera engine configuration](engine.md?id=frigate). |
| `icon` | Autodetected from `camera_entity` if that is specified. | The icon to use for this camera in the camera menu and in the next & previous controls when using the `icon` style. |
| `id` | `camera_entity`, `webrtc_card.entity` or `frigate.camera_name` if set (in that preference order). If none of these are set, the camera has no `id` and cannot be referenced by name in conditions or actions. | An optional identifier to use throughout the card configuration to refer unambiguously to this camera. This `id` may be used in [conditions](../conditions-triggers.md), dependencies or custom [actions](../actions/README.md) to refer to a given camera unambiguously. |
| `live_provider` | `auto` | The choice of live stream provider. See [Live Provider](live-provider.md). |
| `media` | | Controls the default media configuration (e.g. thumbnails) for this camera. See [`media`](#media). |
| `proxy` | | Controls whether/how content is proxied via [hass-web-proxy-integration](https://github.com/dermotduffy/hass-web-proxy-integration) (must be installed separately). See [`proxy`](#proxy). |
| `title` | Autodetected from `camera_entity` if that is specified. | A friendly name for this camera to use in the card. |
| `triggers` | | Define what should cause this camera to update/trigger. See [`triggers`](#triggers). |
| `webrtc_card` | | The WebRTC entity/URL to use for this camera with the `webrtc-card` live provider. See [Live Provider](live-provider.md?id=webrtc_card). |
## `capabilities`
@@ -374,6 +374,13 @@ to activate an action (e.g. view a camera in live, reset the card to the default
view). See [`view.triggers`](../view.md?id=triggers) to control what happens when a
camera is triggered.
> [!TIP]
> A camera's `triggers` are not the same as an
> [automation's](../automations.md) [`triggers`](../conditions-triggers.md). Camera
> triggers take action on per-camera events such as motion; automation triggers
> _initiate [automations](../automations.md)_. They share only the word
> "trigger".
```yaml
cameras:
- camera_entity: camera.office
+1 -1
View File
@@ -5,7 +5,7 @@
- [`cameras`](README.md)
- [`live_provider`](live-provider.md)
- [`engine`](engine.md)
- [`conditions`](../conditions.md)
- [`conditions` / `triggers`](../conditions-triggers.md)
- [`dimensions`](../dimensions.md)
- [`folders`](../folders.md)
- [`elements`](../elements/README.md)
+793
View File
@@ -0,0 +1,793 @@
# Conditions & triggers
Conditions and triggers are designed to mirror Home Assistant's own
[conditions](https://www.home-assistant.io/docs/scripts/conditions/) and
[triggers](https://www.home-assistant.io/docs/automation/trigger/) as closely as
possible: for the standard types Home Assistant's own documentation applies, and
you can copy conditions and triggers straight out of an existing Home Assistant
automation. The card adds a number of card-specific types, and is a little more
permissive in places; any differences are noted per type below.
A **trigger** is what wakes an [automation](automations.md) up. The moment a
trigger fires, the card checks any **conditions** you have set, and if they all
pass it runs the [actions](actions/README.md). The two therefore play different
roles:
- A **trigger** is a _momentary_ occurrence. Used only under `triggers:`, and
only in automations.
- A **condition** is an _ongoing_ predicate, true or false at a point in time.
Besides gating automations (checked the instant a trigger fires), conditions
also drive [overrides](overrides.md) and [picture elements](elements/README.md).
The same type can usually be used either way, but the meaning differs: as a
**condition** it asks _"is this true right now?"_; as a **trigger** it fires
_"when this becomes true"_. A few types are restricted to one role (`config` is
trigger-only; the composites and `user` / `user_agent` are condition-only), as
noted at the top of each type below.
For the card-state types (`camera`, `view`, `fullscreen`, `expand`, `call`,
`display_mode`, `media_loaded`, `microphone`, `interaction`, `triggered`) a
trigger's value is **optional**: give it a value to fire only when the state
changes _to_ that value, or **omit it to fire on any change**. (The stock `state`
trigger behaves the same way when `from`/`to` are omitted). As a condition the
value keeps its usual per-type meaning, as described below.
```yaml
# A trigger initiates an automation; conditions are then checked.
triggers:
- [trigger_1]
conditions:
- [condition_1]
```
> [!TIP]
> Automation `triggers` are not the same as a camera's
> [`triggers`](cameras/README.md?id=triggers). Automation triggers _initiate
> [automations](automations.md)_; camera triggers take action on per-camera
> events such as motion. They share only the word "trigger".
## Universal fields <!-- {docsify-ignore} -->
Every condition and trigger accepts an optional `enabled` field, mirroring Home
Assistant.
| Parameter | Description |
| --------- | ----------------------------------------------------------------------------------------------------------- |
| `enabled` | `true` (the default) keeps it active; `false`, or a [template](templates.md) that renders falsey, skips it. |
> [!NOTE]
> An `enabled` template can turn a condition or trigger on or off at runtime:
> point it at an `input_boolean` (or any live value) and the change takes effect
> immediately, because the card re-evaluates `enabled` every time the condition
> is evaluated or trigger fires. This is an intentional extension: Home Assistant
> fixes `enabled` once when the automation loads, for both conditions and
> triggers.
Home Assistant's `id`, `alias` and `variables` keys are also _accepted_ on any
condition or trigger (so automations pasted from Home Assistant will validate),
but will have no effect.
## `and`
_Condition only._
Evaluates to `true` if _all_ embedded conditions evaluate to `true`. At least one condition is required.
```yaml
conditions:
- condition: and
# [...]
```
Or, in shorthand form:
```yaml
conditions:
- and:
# [...]
```
| Parameter | Description |
| ------------ | -------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `and`. |
| `conditions` | A list of other conditions _all_ of which must evaluate `true` in order for this condition to evaluate `true`. |
## `call`
Matches whether a [two-way audio](../usage/2-way-audio.md) call is in progress.
As a **condition**, true while the call state matches; as a **trigger**, fires
when it becomes a match (e.g. `call: true` fires when a call starts).
```yaml
# As a condition:
conditions:
- condition: call
call: true
# As a trigger:
triggers:
- trigger: call
call: true
```
| Parameter | Description |
| ----------------------- | ---------------------------------------------------------------------------------------------- |
| `condition` / `trigger` | Must be `call`. |
| `call` | If `true` or `false`, matches when a two-way audio call is or is not in progress respectively. |
## `camera`
Matches the selected camera. As a **condition**, true while the selection
matches; as a **trigger**, fires when the selection changes to a match. Does not
match other cameras (whether visible or not).
```yaml
# As a condition:
conditions:
- condition: camera
cameras: [front_door]
# As a trigger:
triggers:
- trigger: camera
cameras: [front_door]
```
| Parameter | Description |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` / `trigger` | Must be `camera`. |
| `cameras` | An optional list of camera IDs. **A list** matches one of those cameras; **omitted** matches the presence of any selected camera (as a trigger: any selected camera change); **`[]`** matches when no camera is selected. See the camera [id](cameras/README.md) parameter. |
## `config`
_Trigger only._
Fires when the card configuration changes (e.g. on startup, or when [overrides](./overrides.md) are applied).
```yaml
triggers:
- trigger: config
# [...]
```
| Parameter | Description |
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `trigger` | Must be `config`. |
| `paths` | An optional list of configuration paths (e.g. `menu.style`). If provided, fires only when _any_ of those paths changes; otherwise fires on any configuration change. |
## `display_mode`
Matches the card display mode (`single` or `grid`). As a **condition**, true
while in that mode; as a **trigger**, fires when the display mode changes to it.
See the display settings for [`live`](live.md?id=display) or
[`media_viewer`](media-viewer.md?id=display).
```yaml
# As a condition:
conditions:
- condition: display_mode
display_mode: single
# As a trigger:
triggers:
- trigger: display_mode
display_mode: single
```
| Parameter | Description |
| ----------------------- | --------------------------- |
| `condition` / `trigger` | Must be `display_mode`. |
| `display_mode` | Must be `single` or `grid`. |
## `expand`
Matches whether the card is in "expanded" mode (in a dialog/popup). As a
**condition**, true while the mode matches; as a **trigger**, fires when it
becomes a match.
```yaml
# As a condition:
conditions:
- condition: expand
expand: true
# As a trigger:
triggers:
- trigger: expand
expand: true
```
| Parameter | Description |
| ----------------------- | ----------------------------------------------------------------------------------------------------------- |
| `condition` / `trigger` | Must be `expand`. |
| `expand` | If `true` or `false`, matches when the card is or is not in expanded mode (in a dialog/popup) respectively. |
## `fullscreen`
Matches whether the card (or media within it) is in fullscreen mode. As a
**condition**, true while the mode matches; as a **trigger**, fires when it
becomes a match.
> [!WARNING]
> When fullscreen is entered via a video player's built-in controls (rather than
> the card's own fullscreen [action](actions/custom/README.md) or menu button),
> the browser fullscreens the video element itself rather than the card. Any
> automation action that replaces that video element (e.g. switching substreams)
> will immediately exit fullscreen. A partial workaround may be to use the
> card's fullscreen action instead. See [Fullscreen with HD substream
> switching](../examples.md?id=fullscreen-with-hd-substream-switching) for an
> approach that combines substream switching with the card's fullscreen.
```yaml
# As a condition:
conditions:
- condition: fullscreen
fullscreen: true
# As a trigger, on entering fullscreen:
triggers:
- trigger: fullscreen
fullscreen: true
# As a trigger, on any fullscreen change:
triggers:
- trigger: fullscreen
```
| Parameter | Description |
| ----------------------- | ----------------------------------------------------------------------------------------- |
| `condition` / `trigger` | Must be `fullscreen`. |
| `fullscreen` | If `true` or `false`, matches when the card is or is not in fullscreen mode respectively. |
## `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).
```yaml
# As a condition:
conditions:
- condition: initialized
# As a trigger:
triggers:
- trigger: initialized
```
| Parameter | Description |
| ----------------------- | ---------------------- |
| `condition` / `trigger` | Must be `initialized`. |
## `interaction`
Matches whether the card has recently been interacted with. As a **condition**,
true while the interaction state matches; as a **trigger**, fires when it becomes
a match.
```yaml
# As a condition:
conditions:
- condition: interaction
interaction: true
# As a trigger:
triggers:
- trigger: interaction
interaction: true
```
| Parameter | Description |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `condition` / `trigger` | Must be `interaction`. |
| `interaction` | If `true` or `false`, matches when the card has or has not had human interaction within `view.interaction_seconds` elapsed seconds respectively. |
## `key`
Matches a keyboard key. As a **condition**, true while the key matches the given
state; as a **trigger**, fires on the matching key event.
```yaml
# As a condition:
conditions:
- condition: key
key: ArrowLeft
# As a trigger:
triggers:
- trigger: key
key: ArrowLeft
```
| Parameter | Default | Description |
| ----------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `condition` / `trigger` | - | Must be `key`. |
| `alt` | `false` | An optional value to match whether the `alt` key is being held. |
| `ctrl` | `false` | An optional value to match whether the `ctrl` key is being held. |
| `key` | | Any [keyboard key value](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values), e.g. `ArrowLeft`. |
| `meta` | `false` | An optional value to match whether the `meta` key is being held. |
| `shift` | `false` | An optional value to match whether the `shift` key is being held. |
| `state` | `down` | An optional value to match the state of the key. Must be one of `down` or `up`. |
## `media_loaded`
Matches whether the selected live or media stream has loaded. As a **condition**,
true while the load state matches; as a **trigger**, fires when it becomes a
match.
```yaml
# As a condition:
conditions:
- condition: media_loaded
media_loaded: true
# As a trigger:
triggers:
- trigger: media_loaded
media_loaded: true
```
| Parameter | Description |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` / `trigger` | Must be `media_loaded`. |
| `media_loaded` | If `true` or `false`, matches when there is or is not media load**ED** (not load**ING**) in the card (e.g. a clip, snapshot or live view). This may be used to hide controls during media loading or when a message (not media) is being displayed. |
> [!NOTE]
> Toggling a substream on or off does not cause this condition to transition.
> Substream is treated as a playback-layer detail of the same logical camera, so
> the condition remains satisfied while any stream of the camera continues to
> render.
## `microphone`
Matches the microphone state. As a **condition**, true while the mute state
matches; as a **trigger**, fires when it becomes a match.
```yaml
# As a condition:
conditions:
- condition: microphone
muted: true
# As a trigger:
triggers:
- trigger: microphone
muted: true
```
| Parameter | Description |
| ----------------------- | ----------------------------------------------------------------------------------- |
| `condition` / `trigger` | Must be `microphone`. |
| `muted` | If `true` or `false`, matches when the microphone is muted or unmuted respectively. |
## `not`
_Condition only._
Evaluates to `true` if every embedded condition is `false`. At least one
condition is required.
> [!IMPORTANT] > `not` is a **NOR** operation, not a **NAND**. If _any_ sub-condition is `true`,
> the `not` condition evaluates to `false` -- even if other sub-conditions are
> `false`. To pass, _all_ sub-conditions must be `false`. This behavior matches
> the [Home Assistant equivalent](https://www.home-assistant.io/docs/scripts/conditions/#not-condition).
```yaml
conditions:
- condition: not
# [...]
```
Or, in shorthand form:
```yaml
conditions:
- not:
# [...]
```
| Parameter | Description |
| ------------ | --------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `not`. |
| `conditions` | A list of other conditions _none_ of which must evaluate `true` in order for this condition to evaluate `true`. |
## `numeric_state`
Matches a numeric Home Assistant value (an entity's state or attribute, or a
template). As a **condition**, true while the value is within range; as a
**trigger**, fires when the value crosses into range. At least one of `above` /
`below` is required.
```yaml
# As a condition:
conditions:
- condition: numeric_state
entity: sensor.office_temperature
above: 10
below: 20
# As a trigger:
triggers:
- trigger: numeric_state
entity_id: sensor.office_temperature
above: 10
below: 20
```
| Parameter | Description |
| ----------------------- | ------------------------------------------------------------------------------------------------- |
| `condition` / `trigger` | Must be `numeric_state`. |
| `entity` / `entity_id` | The entity (or list of entities) to read. |
| `above` | Match when the value is above this: a number, or an entity ID whose state supplies the threshold. |
| `below` | Match when the value is below this: a number, or an entity ID whose state supplies the threshold. |
| `value_template` | A template whose rendered numeric value is compared instead of the entity's state. |
| `attribute` | Compare this attribute instead of the entity's state. |
| `for` | _Trigger only._ A duration (`hh:mm:ss` or a template) the value must stay in range before firing. |
See the [Home Assistant numeric_state condition](https://www.home-assistant.io/docs/scripts/conditions/#numeric-state-condition) and [numeric_state trigger](https://www.home-assistant.io/docs/automation/trigger/#numeric-state-trigger).
## `or`
_Condition only._
Evaluates to `true` if _any_ embedded condition evaluates to `true`. At least one condition is required.
```yaml
conditions:
- condition: or
# [...]
```
Or, in shorthand form:
```yaml
conditions:
- or:
# [...]
```
| Parameter | Description |
| ------------ | -------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `or`. |
| `conditions` | A list of conditions _any_ of which must evaluate `true` in order for this condition to evaluate `true`. |
## `screen`
Matches a CSS [media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Media_queries/Using).
As a **condition**, true while the query matches; as a **trigger**, fires when
the match changes (e.g. on a change of orientation or viewport size).
```yaml
# As a condition:
conditions:
- condition: screen
media_query: '(orientation: landscape)'
# As a trigger:
triggers:
- trigger: screen
media_query: '(orientation: landscape)'
```
| Parameter | Description |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` / `trigger` | Must be `screen`. |
| `media_query` | Any valid [media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Media_queries/Using) string. Media queries must start and end with parentheses. This may be used to alter card configuration based on device/media properties (e.g. viewport width, orientation). Please note that `width` and `height` refer to the entire viewport not just the card. |
See the [screen conditions examples](../examples.md?id=screen-conditions).
## `state`
Matches a Home Assistant entity's state. Unlike most types, the **condition** and
**trigger** forms take different fields: a condition compares the _current_ value
(requiring `state` or `state_not`), while a trigger matches the _transition_
(`from` / `to`, both optional).
Both forms accept `entity` (or its `entity_id` alias) as a single entity or a
list.
### As a condition
```yaml
conditions:
- condition: state
entity: binary_sensor.door
state: 'on'
```
| Parameter | Description |
| ---------------------- | --------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `state`. |
| `entity` / `entity_id` | The entity (or list of entities) to check. |
| `state` | A state, or list of states, the entity must match. |
| `state_not` | A state, or list of states, the entity must not match. |
| `match` | With a list of entities: `all` (the default) requires every entity to match, `any` requires at least one. |
| `for` | A duration (`hh:mm:ss` or a template) the match must have held. |
| `attribute` | Compare this attribute instead of the entity's state. |
See the [Home Assistant state condition](https://www.home-assistant.io/docs/scripts/conditions/#state-condition).
### As a trigger
```yaml
triggers:
- trigger: state
entity_id: binary_sensor.door
to: 'on'
```
| Parameter | Description |
| ---------------------- | ---------------------------------------------------------------------------- |
| `trigger` | Must be `state`. |
| `entity` / `entity_id` | The entity (or list of entities) to watch. |
| `from` / `not_from` | Match (or exclude) the prior state. A single value, a list, or `null` (any). |
| `to` / `not_to` | Match (or exclude) the new state. A single value, a list, or `null` (any). |
| `for` | A duration (`hh:mm:ss` or a template) the new state must hold before firing. |
| `attribute` | Watch this attribute instead of the entity's state. |
See the [Home Assistant state trigger](https://www.home-assistant.io/docs/automation/trigger/#state-trigger).
## `template`
Matches a Home Assistant template. As a **condition**, true while the template
renders `true`; as a **trigger**, fires when it changes from non-true to true.
```yaml
# As a condition:
conditions:
- condition: template
value_template: "{{ states('switch.office') == 'on' }}"
# As a trigger:
triggers:
- trigger: template
value_template: "{{ states('switch.office') == 'on' }}"
```
| Parameter | Description |
| ----------------------- | ------------------------------------------------------------------------------------------------ |
| `condition` / `trigger` | Must be `template`. |
| `value_template` | The Home Assistant template to evaluate, e.g. `{{ states('switch.office') == 'on' }}`. |
| `for` | _Trigger only._ A duration (`hh:mm:ss` or a template) the template must stay true before firing. |
See the [Home Assistant template condition](https://www.home-assistant.io/docs/scripts/conditions/#template-condition) and [template trigger](https://www.home-assistant.io/docs/automation/trigger/#template-trigger).
> [!NOTE]
> In order to match native Home Assistant behavior, condition and trigger
> truthiness differ: a **condition** passes only when the template renders
> `true` (case-insensitive), whereas a **trigger** also accepts broader truthy
> values (`1`, `yes`, `on`, `enable`).
> [!NOTE]
> A **trigger** is re-evaluated when card or Home Assistant state changes, not on
> a timer, so a template that depends only on time (e.g. `{{ now().hour == 8 }}`)
> will not fire on its own.
> [!TIP]
> The Advanced Camera Card uses
> [ha-nunjucks](https://github.com/Nerwyn/ha-nunjucks) to process templates.
> Consult its documentation for the wide variety of different template values
> supported.
## `triggered`
Matches the set of cameras currently [triggered](cameras/README.md?id=triggers).
As a **condition**, true while the set matches; as a **trigger**, fires when it
becomes a match.
```yaml
# As a condition:
conditions:
- condition: triggered
triggered: [camera.office]
# As a trigger:
triggers:
- trigger: triggered
triggered: [camera.office]
```
| Parameter | Description |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` / `trigger` | Must be `triggered`. |
| `triggered` | An optional list of camera IDs. Matches when one of them is triggered. **Omit** to match while _any_ camera is triggered; use an empty list `[]` to match while _none_ is. |
## `user`
_Condition only._
Matches the logged-in Home Assistant user. See the [Home Assistant user condition](https://www.home-assistant.io/dashboards/conditional/#user).
```yaml
conditions:
- condition: user
users:
- 581fca7fdc014b8b894519cc531f9a04
```
| Parameter | Description |
| ----------- | ------------------------------------------- |
| `condition` | Must be `user`. |
| `users` | A list of Home Assistant user IDs to match. |
## `user_agent`
_Condition only._
Matches the [User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/User-Agent).
```yaml
conditions:
- condition: user_agent
# [...]
```
| Parameter | Description |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `user_agent`. |
| `user_agent` | Exactly matches a user-agent, e.g. `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36` |
| `user_agent_re` | Matches a user-agent based on a regular expression, e.g. `Chrome/`. |
| `casting` | If `true` matches if the card is being cast to a Chromecast / TV device, if `false` matches if the card is _NOT_ being cast. |
| `companion` | If `true` matches if the user-agent is the Home Assistant companion app, if `false` matches if the user-agent is _NOT_ the Home Assistant companion app. |
At least one of these parameters is required. When multiple are specified they
must all match for the condition to match.
See the [user-agent overrides example](../examples.md?id=disable-ptz-controls-in-the-home-assistant-companion-app).
## `view`
Matches the selected view. As a **condition**, true while a matching view is
selected; as a **trigger**, fires when the selected view changes to a matching
one.
```yaml
# As a condition:
conditions:
- condition: view
views: [live]
# As a trigger:
triggers:
- trigger: view
views: [live]
```
| Parameter | Description |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `condition` / `trigger` | Must be `view`. |
| `views` | A list of [views](view.md?id=supported-views) to match (e.g. `clips`). **Required** as a condition; optional as a trigger (omit to fire on any view change). |
> [!IMPORTANT]
> Internally, views associated with the media viewer (e.g. `clip`, `snapshot`,
> `review`, `recording`) are translated to the `media` view after the relevant
> media is fetched. When naming views in a condition or trigger, you may need to
> refer to the `media` view.
## Unsupported Home Assistant conditions and triggers
Several Home Assistant condition types are **not** currently supported: `time`,
`zone`, `sun`, `location`, `device`, and `condition: trigger` (matching on the
`id` of the trigger that fired).
On the trigger side, only the stock `state`, `numeric_state` and `template`
platforms are supported, alongside the card-specific triggers listed above.
Other Home Assistant trigger platforms -- including `event`, `time`,
`time_pattern`, `sun`, `zone`, `calendar`, `webhook`, `tag`, `device` and
`mqtt` -- are **not** supported.
If you need any of these, please [open an
issue](https://github.com/dermotduffy/advanced-camera-card/issues).
## Fully expanded reference
[](common/expanded-warning.md ':include')
### Conditions
```yaml
conditions:
- and:
- condition: camera
cameras: [front_door]
- condition: view
views: [live]
- condition: call
call: true
- condition: camera
cameras:
- camera.office
- condition: display_mode
display_mode: single
- condition: expand
expand: true
- condition: fullscreen
fullscreen: true
- condition: initialized
- condition: interaction
interaction: true
- condition: key
alt: false
ctrl: false
key: F
meta: false
shift: false
state: down
- condition: media_loaded
media_loaded: true
- condition: microphone
muted: true
- not:
- condition: fullscreen
fullscreen: true
- condition: numeric_state
entity: sensor.office_temperature
above: 10
below: 20
- or:
- condition: camera
cameras: [front_door]
- condition: view
views: [live]
- condition: screen
media_query: '(orientation: landscape)'
- condition: state
entity: climate.office
state: heat
state_not: 'off'
- condition: template
value_template: "{{ is_state('switch.office', 'on') }}"
- condition: triggered
triggered:
- camera.office
- condition: user
users:
- 581fca7fdc014b8b894519cc531f9a04
- condition: user_agent
user_agent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
user_agent_re: 'Chrome/'
casting: true
companion: true
- condition: view
views:
- live
```
### Triggers
```yaml
triggers:
- trigger: call
call: true
- trigger: camera
cameras:
- camera.office
- trigger: config
paths:
- 'menu.style'
- trigger: display_mode
display_mode: single
- trigger: expand
expand: true
- trigger: fullscreen
fullscreen: true
- trigger: initialized
- trigger: interaction
interaction: true
- trigger: key
alt: false
ctrl: false
key: F
meta: false
shift: false
state: down
- trigger: media_loaded
media_loaded: true
- trigger: microphone
muted: true
- trigger: numeric_state
entity_id: sensor.office_temperature
above: 10
below: 20
for: '00:00:05'
- trigger: screen
media_query: '(orientation: landscape)'
- trigger: state
entity_id: climate.office
from: 'off'
to: heat
for: '00:00:05'
- trigger: template
value_template: "{{ is_state('switch.office', 'on') }}"
for: '00:00:05'
- trigger: triggered
triggered:
- camera.office
- trigger: view
views:
- live
```
-457
View File
@@ -1,457 +0,0 @@
# `conditions`
`conditions` is not a top-level configuration block, but can be used as part of
multiple other blocks.
Conditions are used to conditionally take action (in `automations`), to apply
certain configurations (in `overrides`) or to display "picture elements" (in
`elements`) depending on runtime evaluation.
```yaml
[used as part of other configuration]
conditions:
- [condition_1]
- [condition_2]
```
## `and`
Evaluates to `true` if _all_ embedded conditions evaluate to `true`. At least one condition is required.
```yaml
conditions:
- condition: and
# [...]
```
| Parameter | Description |
| ------------ | -------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `and`. |
| `conditions` | A list of other conditions _all_ of which must evaluate `true` in order for this condition to evaluate `true`. |
## `call`
Matches based on whether a [two-way audio](../usage/2-way-audio.md) call is in progress.
```yaml
conditions:
- condition: call
# [...]
```
| Parameter | Description |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `call`. |
| `call` | If `true` (the default) or `false`, the condition is satisfied when a two-way audio call is or is not in progress respectively. |
## `camera`
Matches based on the selected camera. Does not match other cameras (whether
visible or not).
```yaml
conditions:
- condition: camera
# [...]
```
| Parameter | Description |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `camera`. |
| `cameras` | An optional list of camera IDs in which this condition is satisfied. If not specified, any camera change will satisy the condition. See the camera [id](cameras/README.md) parameter. |
## `config`
Matches when card configuration changes (e.g. on startup, or when [Configuration Overrides](./overrides.md) are applied).
```yaml
conditions:
- condition: config
# [...]
```
| Parameter | Description |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `config`. |
| `paths` | An optional array of configuration paths (e.g. `menu.style`). If provided condition matches if _ANY_ of the provided configuration paths has changed. |
## `display_mode`
Matches when card display mode changes (e.g. `single` or `grid` mode). See the display settings for [`live`](live.md?id=display) or [`media_viewer`](media-viewer.md?id=display).
```yaml
conditions:
- condition: display_mode
# [...]
```
| Parameter | Description |
| -------------- | --------------------------- |
| `condition` | Must be `display_mode`. |
| `display_mode` | Must be `single` or `grid`. |
## `expand`
Matches based on whether the card is in "expanded" mode.
```yaml
conditions:
- condition: expand
# [...]
```
| Parameter | Description |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `expand`. |
| `expand` | If `true` the condition is satisfied if the card is in expanded mode (in a dialog/popup). If `false` the condition is satisfied if the card is **NOT** in expanded mode (in a dialog/popup). |
## `fullscreen`
Matches based on whether the card (or media within it) is in fullscreen mode.
> [!WARNING]
> When fullscreen is entered via a video player's built-in controls (rather than
> the card's own fullscreen [action](actions/custom/README.md) or menu button),
> the browser fullscreens the video element itself rather than the card. Any
> automation action that replaces that video element (e.g. switching substreams)
> will immediately exit fullscreen. A partial workaround may be to use the
> card's fullscreen action instead. See [Fullscreen with HD substream
> switching](../examples.md?id=fullscreen-with-hd-substream-switching) for an
> approach that combines substream switching with the card's fullscreen.
```yaml
conditions:
- condition: fullscreen
# [...]
```
| Parameter | Description |
| ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `fullscreen`. |
| `fullscreen` | If `true` the condition is satisfied if the card is in fullscreen mode. If `false` the condition is satisfied if the card is **NOT** in fullscreen mode. |
## `initialized`
Matches when the card is first initialized.
```yaml
conditions:
- condition: initialized
```
| Parameter | Description |
| ----------- | ---------------------- |
| `condition` | Must be `initialized`. |
> [!NOTE]
> This is exclusively useful for running [automations](./automations.md) on card start.
## `interaction`
Matches based on whether the card has been interacted with.
```yaml
conditions:
- condition: interaction
# [...]
```
| Parameter | Description |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `interaction`. |
| `interaction` | If `true` the condition is satisfied if the card has had human interaction within `view.interaction_seconds` elapsed seconds. If `false` the condition is satisfied if the card has **NOT** had human interaction in that time. |
## `key`
Matches based on key state.
```yaml
conditions:
- condition: key
# [...]
```
| Parameter | Default | Description |
| ----------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | - | Must be `key`. |
| `alt` | `false` | An optional value to match whether the `alt` key is being held. |
| `ctrl` | `false` | An optional value to match whether the `ctrl` key is being held. |
| `key` | | Any [keyboard key value](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values), e.g. `ArrowLeft`. |
| `meta` | `false` | An optional value to match whether the `meta` key is being held. |
| `shift` | `false` | An optional value to match whether the `shift` key is being held. |
| `state` | `down` | An optional value to match the state of the key. Must be one of `down` or `up`. |
## `media_loaded`
Matches based on whether the selected live or media stream has loaded.
```yaml
conditions:
- condition: media_loaded
# [...]
```
| Parameter | Description |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `media_loaded`. |
| `media_loaded` | If `true` the condition is satisfied if there is media load**ED** (not load**ING**) in the card (e.g. a clip, snapshot or live view). This may be used to hide controls during media loading or when a message (not media) is being displayed. |
> [!NOTE]
> Toggling a substream on or off does not cause this condition to transition.
> Substream is treated as a playback-layer detail of the same logical camera, so
> the condition remains satisfied while any stream of the camera continues to
> render.
## `microphone`
Matches based on microphone state.
```yaml
conditions:
- condition: microphone
# [...]
```
| Parameter | Description |
| ----------- | ------------------------------------------------------------------------------------------------------ |
| `condition` | Must be `microphone`. |
| `muted` | If `true` or `false`, the condition is satisfied when the microphone is muted or unmuted respectively. |
## `not`
Evaluates to `true` if every embedded condition is `false`. At least one
condition is required.
> [!IMPORTANT] > `not` is a **NOR** operation, not a **NAND**. If _any_ sub-condition is `true`, the `not` condition evaluates to `false` — even if other sub-conditions are `false`. To pass, _all_ sub-conditions must be `false`. This behavior matches the [Home Assistant equivalent](https://www.home-assistant.io/docs/scripts/conditions/#not-condition).
```yaml
conditions:
- condition: not
# [...]
```
| Parameter | Description |
| ------------ | --------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `not`. |
| `conditions` | A list of other conditions _none_ of which must evaluate `true` in order for this condition to evaluate `true`. |
## `numeric_state`
Matches based on numeric Home Assistant state.
```yaml
conditions:
- condition: numeric_state
# [...]
```
See [Home Assistant conditions documentation](https://www.home-assistant.io/dashboards/conditional/#numeric-state).
## `or`
Evaluates to `true` if _any_ embedded condition evaluates to `true`. At least one condition is required.
```yaml
conditions:
- condition: or
# [...]
```
| Parameter | Description |
| ------------ | -------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `or`. |
| `conditions` | A list of conditions _any_ of which must evaluate `true` in order for this condition to evaluate `true`. |
## `screen`
Matches based on [media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Media_queries/Using).
```yaml
conditions:
- condition: screen
# [...]
```
| Parameter | Description |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `screen`. |
| `media_query` | Any valid [media query](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Media_queries/Using) string. Media queries must start and end with parentheses. This may be used to alter card configuration based on device/media properties (e.g. viewport width, orientation). Please note that `width` and `height` refer to the entire viewport not just the card. |
See the [screen conditions examples](../examples.md?id=screen-conditions).
## `state`
Matches based on Home Assistant state.
```yaml
conditions:
- condition: state
# [...]
```
| Parameter | Description |
| ----------- | ------------------------------------------------------------------------------------------------------ |
| `condition` | Must be `state`. |
| `entity` | The entity to check the state of. |
| `state` | A single entity state, or list of entity states, against which the entity state is compared. |
| `state_not` | A single entity state, or list of entity states, against which the entity state is inversely compared. |
> [!NOTE]
> If multiple state conditions are used together with neither `state` nor
> `state_not` specified, this effectively means the state for multiple entities
> needs to _change_ simultaneously. This is unlikely to happen in reality, and
> almost certainly not useful / reliable as a condition.
See [Home Assistant conditions documentation](https://www.home-assistant.io/dashboards/conditional/#state).
## `template`
Matches based on a template.
```yaml
conditions:
- condition: template
# [...]
```
| Parameter | Description |
| ---------------- | ---------------------------------------------------------------------------------- |
| `condition` | Must be `template`. |
| `value_template` | The Home Assistant template to check, e.g. `{{ states('switch.office') == 'on' }}` |
See [Home Assistant conditions documentation](https://www.home-assistant.io/docs/scripts/conditions/#template-condition).
> [!TIP]
> The Advanced Camera Card uses
> [ha-nunjucks](https://github.com/Nerwyn/ha-nunjucks) to process templates.
> Consult its documentation for the wide variety of different template values
> supported.
## `triggered`
Matches based on whether the selected camera has been triggered.
```yaml
conditions:
- condition: triggered
# [...]
```
| Parameter | Description |
| ----------- | ------------------------------------------------------------------------------------------------- |
| `condition` | Must be `triggered`. |
| `triggered` | A list of camera IDs which, if [triggered](cameras/README.md?id=triggers), satisfy the condition. |
## `user`
Matches based on the Home Assistant user that is logged in. See [Home Assistant conditions documentation](https://www.home-assistant.io/dashboards/conditional/#user).
```yaml
conditions:
- condition: user
# [...]
```
## `user_agent`
Matches based on the [User-Agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/User-Agent).
```yaml
conditions:
- condition: user_agent
# [...]
```
| Parameter | Description |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `condition` | Must be `user_agent`. |
| `user_agent` | Exactly matches a user-agent, e.g. `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36` |
| `user_agent_re` | Matches a user-agent based on a regular expression, e.g. `Chrome/`. |
| `casting` | If `true` matches if the card is being cast to a Chromecast / TV device, if `false` matches if the card is _NOT_ being cast. |
| `companion` | If `true` matches if the user-agent is the Home Assistant companion app, if `false` matches if the user-agent is _NOT_ the Home Assistant companion app. |
When multiple parameters are specified they must all match for the condition to
match.
See the [user-agent overrides example](../examples.md?id=disable-ptz-controls-in-the-home-assistant-companion-app).
## `view`
Matches based on the selected view.
```yaml
conditions:
- condition: view
# [...]
```
| Parameter | Description |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `condition` | Must be `view`. |
| `views` | An optional list of [views](view.md?id=supported-views) in which this condition is satified (e.g. `clips`). If not specified, any view change will satisy the condition. |
> [!IMPORTANT]
> Internally, views associated with the media viewer (e.g. `clip`, `snapshot`,
> `review` `recording`) are translated to the `media` view after the relevant
> media is fetched. When including views as part of a
> [condition](conditions.md), you may need to refer to the `media` view.
## Fully expanded reference
[](common/expanded-warning.md ':include')
```yaml
conditions:
- condition: call
call: true
- condition: camera
cameras:
- camera.office
- condition: config
paths:
- 'menu.style'
- condition: display_mode
display_mode: single
- condition: expand
expand: true
- condition: fullscreen
fullscreen: true
- condition: initialized
- condition: interaction
interaction: true
- condition: key
alt: false
ctrl: false
key: F
meta: false
shift: false
state: down
- condition: media_loaded
media_loaded: true
- condition: microphone
muted: true
- condition: numeric_state
entity: sensor.office_temperature
above: 10
below: 20
- condition: screen
media_query: '(orientation: landscape)'
- condition: state
entity: climate.office
state: heat
state_not: off
- condition: triggered
triggered:
- camera.office
- condition: user
users:
- 581fca7fdc014b8b894519cc531f9a04
- condition: user_agent
user_agent: 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
user_agent_re: 'Chrome/'
casting: true
companion: true
- condition: view
views:
- live
```
+1 -1
View File
@@ -3,7 +3,7 @@
- [`actions`](../actions/README.md)
- [`automations`](../automations.md)
- [`cameras`](../cameras/README.md)
- [`conditions`](../conditions.md)
- [`conditions` / `triggers`](../conditions-triggers.md)
- [`dimensions`](../dimensions.md)
- [`elements`](README.md)
- [Custom Elements](./custom/README.md)
+6 -6
View File
@@ -2,7 +2,7 @@
## `conditional`
Restrict a set of elements to only render when the card is matches a set of [conditions](../../conditions.md). This is analogous to the stock [`conditional`](../stock/README.md?id=conditional) element except supporting a rich set of Advanced Camera Card [conditions](../../conditions.md).
Restrict a set of elements to only render when the card is matches a set of [conditions](../../conditions-triggers.md). This is analogous to the stock [`conditional`](../stock/README.md?id=conditional) element except supporting a rich set of Advanced Camera Card [conditions](../../conditions-triggers.md).
```yaml
elements:
@@ -12,11 +12,11 @@ elements:
Parameters for the `custom:advanced-camera-card-conditional` element:
| Parameter | Description |
| ------------ | ---------------------------------------------------------------------------------------------------------------- |
| `type` | Must be `custom:advanced-camera-card-conditional`. |
| `conditions` | A list of [conditions](../../conditions.md) that must evaluate to true in order for the elements to be rendered. |
| `elements` | The elements to render. Can be any supported element. |
| Parameter | Description |
| ------------ | ------------------------------------------------------------------------------------------------------------------------- |
| `type` | Must be `custom:advanced-camera-card-conditional`. |
| `conditions` | A list of [conditions](../../conditions-triggers.md) that must evaluate to true in order for the elements to be rendered. |
| `elements` | The elements to render. Can be any supported element. |
See the [conditional elements example](../../../examples.md?id=conditional-elements).
@@ -3,7 +3,7 @@
- [`actions`](../README.md)
- [`automations`](../../automations.md)
- [`cameras`](../../cameras/README.md)
- [`conditions`](../../conditions.md)
- [`conditions` / `triggers`](../../conditions-triggers.md)
- [`dimensions`](../../dimensions.md)
- [`elements`](../../elements/README.md)
- [Custom Actions](README.md)
@@ -3,7 +3,7 @@
- [`actions`](../README.md)
- [`automations`](../../automations.md)
- [`cameras`](../../cameras/README.md)
- [`conditions`](../../conditions.md)
- [`conditions` / `triggers`](../../conditions-triggers.md)
- [`dimensions`](../../dimensions.md)
- [`elements`](../../elements/README.md)
- [Custom Actions](../custom/README.md)
+7 -7
View File
@@ -1,6 +1,6 @@
# `overrides`
The card configuration may [conditionally](conditions.md) be overridden (e.g. to
The card configuration may [conditionally](conditions-triggers.md) be overridden (e.g. to
hide the menu in fullscreen mode).
```yaml
@@ -16,12 +16,12 @@ overrides:
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.
| Option | Default | Description |
| ------------ | ------- | ------------------------------------------------------------------------------------------------------------ |
| `conditions` | | A list of [conditions](conditions.md) that must evaluate to `true` in order for the overrides to be applied. |
| `delete` | | An array of configuration paths to delete. See [`delete`](#delete). |
| `merge` | | A dictionary of configuration paths to merge. See [`merge`](#merge). |
| `set` | | A dictionary of configuration paths to set. See [`set`](#set). |
| Option | Default | Description |
| ------------ | ------- | --------------------------------------------------------------------------------------------------------------------- |
| `conditions` | | A list of [conditions](conditions-triggers.md) that must evaluate to `true` in order for the overrides to be applied. |
| `delete` | | An array of configuration paths to delete. See [`delete`](#delete). |
| `merge` | | A dictionary of configuration paths to merge. See [`merge`](#merge). |
| `set` | | A dictionary of configuration paths to set. See [`set`](#set). |
## Configuration Paths
+34 -28
View File
@@ -7,6 +7,12 @@ Advanced Camera Card data, to be accessible. Templates may be used in:
- [Actions / Automations](./actions/README.md)
- [Folder Media Matchers](./folders.md?id=matchers)
> [!NOTE]
> Templates substitute into action _values_ (e.g. a `camera` or `message`), not
> into the action _type_. The type discriminator (`action` and
> `advanced_camera_card_action`) must be a literal (as in Home Assistant
> itself).
## Stock Templates
The Advanced Camera Card uses
@@ -19,13 +25,13 @@ accesses Home Assistant state.
## Custom Templates
Custom template values must be proceeded by `advanced_camera_card` (or `acc` for
short).
Custom template values must be prefixed with `acc`.
| Template | Replaced with |
| -------- | ------------------------------------------------- |
| `camera` | The currently selected camera. |
| `view` | The current [view](./view.md?id=supported-views). |
| `config` | The current card configuration. |
See [an example](../examples.md?id=accessing-advanced-camera-card-state) that
accesses Advanced Camera Card state.
@@ -35,8 +41,7 @@ accesses Advanced Camera Card state.
If templates are used for [Folder Media Matching](./folders.md?id=matchers) an
additional `media` variable is available with these properties:
Media template values must be proceeded by `advanced_camera_card.media` (or
`acc.media` for short).
Media template values must be prefixed with `acc.media`.
| Template | Replaced with |
| ----------- | --------------------------------------------------------------------------------- |
@@ -45,34 +50,35 @@ Media template values must be proceeded by `advanced_camera_card.media` (or
### Triggers
If the action is called by an [Advanced Camera Card
Automation](./automations.md), additional data is available representing the
current and prior state of whatever triggered the action.
When an action runs from an [automation](./automations.md), a top-level
`trigger` variable describes what fired it (as in native Home Assistant
actions), including the state before and after the change. Its fields depend on
the kind of trigger.
Trigger template values must be proceeded by `advanced_camera_card.trigger` (or
`acc.trigger` for short).
The stock `state` and `numeric_state` [triggers](./conditions-triggers.md) carry
Home-Assistant-faithful entity data (a subset of Home Assistant's own [trigger
data](https://www.home-assistant.io/docs/automation/templating/#available-trigger-data):
the card does not currently surface `id`, `idx`, `for`, `attribute`, `above` /
`below` or `alias`, so [request](https://github.com/dermotduffy/advanced-camera-card/issues)
if you need more). The `template` trigger has no entity, so it carries only
`trigger.platform` (`template`).
| Template | Replaced with |
| -------------- | ------------------------------------------------------------------------------------------------ |
| `camera.to` | For [camera conditions](./conditions.md?id=camera), the currently selected camera. |
| `camera.from` | For [camera conditions](./conditions.md?id=camera), the previously selected camera. |
| `view.to` | For [view conditions](./conditions.md?id=view), the currently selected view. |
| `view.from` | For [view conditions](./conditions.md?id=view), the previously selected view. |
| `state.entity` | For [state conditions](./conditions.md?id=state), the entity state that triggered the condition. |
| `state.to` | For [state conditions](./conditions.md?id=state), the current state of the entity. |
| `state.from` | For [state conditions](./conditions.md?id=state), the previous state of the entity. |
| Template | Replaced with |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `trigger.platform` | The trigger platform (`state` or `numeric_state`). |
| `trigger.entity_id` | The entity that triggered (also available as `trigger.entity`). |
| `trigger.from_state` | The full Home Assistant [state object](https://www.home-assistant.io/docs/configuration/state_object/) before the change, e.g. `trigger.from_state.state`. |
| `trigger.to_state` | The full Home Assistant state object after the change, e.g. `trigger.to_state.state` or `trigger.to_state.attributes.<name>`. |
> [!NOTE]
> If an action is triggered with multiple [state
> conditions](./conditions.md?id=state), only data from the last listed state
> condition is available.
The card-specific [triggers](./conditions-triggers.md) (e.g. `camera`, `view`, `config`)
carry the card state before and after the change:
> [!NOTE]
> If you use an [`or`](./conditions.md?id=or) condition, only the trigger data
> for the first matching trigger will be included.
Please [request](https://github.com/dermotduffy/advanced-camera-card/issues) if
you need data from additional conditions.
| Template | Replaced with |
| ------------------ | ------------------------------------------------------------------------------------------------------ |
| `trigger.platform` | `acc` for card-specific triggers. |
| `trigger.type` | The card trigger kind (e.g. `camera`, `view`, `config`). |
| `trigger.from_acc` | The card state before the change, with `camera`, `view` and `config` (e.g. `trigger.from_acc.camera`). |
| `trigger.to_acc` | The card state after the change, with `camera`, `view` and `config` (e.g. `trigger.to_acc.camera`). |
See [an example](../examples.md?id=accessing-trigger-state) that accesses
trigger state.
+2 -2
View File
@@ -14,7 +14,7 @@ view:
| `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](view.md?id=supported-views). |
| `default_reset` | | The circumstances and behavior that cause the card to reset to the default view. See [`default_reset`](#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](conditions.md?id=interaction) or with `default_reset.after_interaction` to reset the view after the interaction is complete. |
| `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](conditions-triggers.md?id=interaction) 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`](#issues). |
| `keyboard_shortcuts` | See [usage](../usage/keyboard-shortcuts.md) for defaults. | Configure keyboard shortcuts. See [`keyboard_shortcuts`](#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](https://github.com/dermotduffy/advanced-camera-card/issues/343)). |
@@ -201,7 +201,7 @@ This card supports several different views.
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](conditions.md?id=view), 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.
> When using views in a [`view` condition](conditions-triggers.md?id=view), 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