feat: Add hardened error handling and retries (#2451)

- Closes #1830
 - Closes #2099
This commit is contained in:
Dermot Duffy
2026-06-30 17:45:12 -07:00
committed by dermotduffy
parent 4bc787e2b7
commit 47bcce93d3
182 changed files with 7877 additions and 4043 deletions
+17 -7
View File
@@ -361,14 +361,17 @@ advanced_camera_card_action: notification
### `notification`
| Parameter | Description |
| ---------- | ------------------------------------------------------------------------------------- |
| `heading` | An optional heading. Uses the same format as [`details`](README.md?id=details) below. |
| `text` | An optional text string to display as the notification body. |
| `details` | An optional list of metadata. See [`details`](README.md?id=details) below. |
| `controls` | An optional list of controls. See [`controls`](README.md?id=controls) below. |
| Parameter | Description |
| ------------- | ---------------------------------------------------------------------------------------------------------- |
| `heading` | An optional heading. Uses the same format as [`metadata`](README.md?id=metadata) below. |
| `body` | An optional body. Uses the same format as [`metadata`](README.md?id=metadata) below. |
| `metadata` | An optional list of metadata to show with the notification. See [`metadata`](README.md?id=metadata) below. |
| `context` | An optional list of preformatted text strings shown as a technical detail block (e.g. YAML). |
| `link` | An optional link displayed below the body. See [`link`](#link) below. |
| `in_progress` | If `true`, shows a loading indicator. |
| `controls` | An optional list of controls. See [`controls`](README.md?id=controls) below. |
### Details
### Metadata
| Parameter | Description |
| ---------- | ------------------------------------------------------------- |
@@ -377,6 +380,13 @@ advanced_camera_card_action: notification
| `tooltip` | An optional tooltip string (shown on hover). |
| `severity` | An optional severity level, one of `low`, `medium` or `high`. |
### Link
| Parameter | Description |
| --------- | ------------------------------------ |
| `url` | The link URL. |
| `title` | The link text displayed to the user. |
### Controls
| Parameter | Default | Description |
+26 -21
View File
@@ -28,23 +28,28 @@ status_bar:
### Available Items
| Button name | Description |
| ---------------------------- | ------------------------------------------------------------------------------------------- |
| `engine` | The icon of the camera engine for the relevant camera. |
| `problem_config_upgrade` | An indicator that appears when a configuration upgrade is available. |
| `problem_legacy_resource` | An indicator that appears when a legacy `frigate-hass-card` resource is still registered. |
| `problem_stream_not_loading` | An indicator that appears when a live stream has not loaded within 10 seconds. |
| `resolution` | The detected media resolution (if any). |
| `severity` | The media severity indicator (if any) for review severity (e.g. Frigate alerts/detections). |
| `technology` | The detected media technology (if any). |
| `title` | The media title. |
| Button name | Description |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `engine` | The icon of the camera engine for the relevant camera. |
| `issues` | Indicator icons that appear while any card issue is active — e.g. configuration error, configuration upgrade available, Home Assistant connection lost, camera initialization failed, legacy `frigate-hass-card` resource detected, media (live/recorded/image) not loading, media query failed, or view cannot be resolved. See the warning below about disabling this item. |
| `resolution` | The detected media resolution (if any). |
| `severity` | The media severity indicator (if any) for review severity (e.g. Frigate alerts/detections). |
| `technology` | The detected media technology (if any). |
| `title` | The media title. |
### Options for each item
| Option | Default | Description |
| ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `enabled` | `true` | Whether or not to show the item. |
| `priority` | `50` | The item priority. Higher priority items are ordered closer to the start of the status bar (i.e. an item with priority `70` will order further to the left than an item with priority `60`). Minimum `0`, maximum `100`. |
| Option | Default | Description |
| ----------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `enabled` | `true` | Whether or not to show the item. |
| `permanent` | `true` for `issues`, `false` otherwise | When `true`, the status bar stays visible in `popup` mode as long as this item is present (instead of auto-hiding after `popup_seconds`). The `issues` item defaults to `true` so errors remain visible. |
| `priority` | `50` | The item priority. Higher priority items are ordered closer to the start of the status bar (i.e. an item with priority `70` will order further to the left than an item with priority `60`). Minimum `0`, maximum `100`. |
> [!WARNING]
> The status bar is the only UI surface for minor issues (i.e. that don't render
> the card entirely inoperable). If you set `status_bar.style: none` or
> `status_bar.items.issues.enabled: false`, these issues will not be visible to
> you, except through card diagnostics.
## `style`
@@ -75,26 +80,26 @@ status_bar:
items:
engine:
enabled: true
permanent: false
priority: 50
problem_config_upgrade:
enabled: true
priority: 50
problem_legacy_resource:
enabled: true
priority: 50
problem_stream_not_loading:
issues:
enabled: true
permanent: true
priority: 50
resolution:
enabled: true
permanent: false
priority: 50
severity:
enabled: true
permanent: false
priority: 50
technology:
enabled: true
permanent: false
priority: 50
title:
enabled: true
permanent: false
priority: 50
```
+21
View File
@@ -15,6 +15,7 @@ view:
| `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. |
| `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)). |
| `theme` | | How the card is themed. See [`theme`](#theme-🎨). |
@@ -37,6 +38,23 @@ view:
| `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:
```yaml
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:
@@ -193,6 +211,9 @@ view:
interaction_mode: inactive
render_entities:
- switch.render_card
issues:
interaction_mode: all
retry_seconds: auto
dim: false
triggers:
show_trigger_status: false
+9 -8
View File
@@ -43,26 +43,27 @@ To upgrade:
If the automatic upgrade button is not visible, your configuration may already
be up to date. Try clearing your browser cache and reloading.
### Stream does not load
### Media does not load
Stream not loading? Permanent "loading circle"?
Media not loading? Permanent "loading circle"?
A stream not loading is a relatively common error, but can be caused by any
Media failing to load is a relatively common error, but can be caused by any
number of issues (e.g. installation problems, networking problems, video/codec
problems, a Home Assistant bug or card bug).
problems, a Home Assistant bug or card bug). This applies to live streams,
recorded media in the viewer, and image views.
During the stream load, the card will show a "loading circle" icon and, for
During a live stream load, the card will show a "loading circle" icon and, for
cameras with a `camera_entity` configured, will show images refreshing once per
second until the stream has fully loaded (unless `live.show_image_during_load`
is set to false).
Debugging broken streams:
Debugging steps:
1. If you're using the default `auto` live provider, or explicitly setting the
`ha` live provider, try opening the `camera_entity` in Home Assistant and
verifying whether the stream loads there. You can press the `e` key on any
Home Assistant dashboard, choose the relevant entity, and see if the stream
loads. If it does not, you have a upstream installation issue with your
loads. If it does not, you have an upstream installation issue with your
camera / the integration for the camera, and need to resolve that first.
Your issue is not related to the card itself.
1. Check whether any URLs specified in your card configuration are accessible
@@ -81,7 +82,7 @@ Debugging broken streams:
you find any prior relevant discussions.
If you're happy with just using an image stream but want the small circle to go
away, use the [`image live provider`](./configuration/cameras/live-provider.md?id=image) .
away, use the [`image live provider`](./configuration/cameras/live-provider.md?id=image).
### Unknown Command