feat: Add support for inbound "calls" from triggers (#2500)

This commit is contained in:
Dermot Duffy
2026-06-30 17:45:13 -07:00
committed by dermotduffy
parent f4c686c298
commit 15e335a647
39 changed files with 2915 additions and 133 deletions
+34 -4
View File
@@ -55,10 +55,36 @@ live:
# [...]
```
| Option | Default | Description |
| ------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `button_size` | `40` | The size of the call control buttons in pixels. Must be >= `20`. |
| `lock` | `true` | Whether to lock the rest of the card controls/actions while a call is in progress. Prevents an accidental tap, swipe or action mid-call. Set to `false` to allow interactions regardless of call state. |
| Option | Default | Description |
| ---------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `button_size` | `40` | The size of the call control buttons in pixels. Must be >= `20`. |
| `lock` | `true` | Whether to lock the rest of the card controls/actions while a call is in progress. Prevents an accidental tap, swipe or action mid-call. Set to `false` to allow interactions regardless of call state. |
| `ringtone` | | The audible chime played while an inbound call (e.g. one started by [`view.triggers.actions.trigger: call`](./view.md?id=trigger-action-configuration)) is ringing. Stops as soon as the microphone is un-muted (the "answer" gesture) or the call ends. Manual calls never ring. See [`ringtone`](#ringtone). |
| `unanswered_timeout_seconds` | `60` | The number of seconds an inbound call may ring unanswered before it is automatically ended. The timer is cancelled the moment the microphone is un-muted. Set to `0` to disable the timeout. |
> [!NOTE] Browser autoplay restrictions may prevent the ringtone from playing
> until the page has received a user gesture (e.g. a tap or click). When that
> happens no sound is produced and no error is shown. The underlying behavior is
> documented in [MDN's Autoplay
> guide](https://developer.mozilla.org/en-US/docs/Web/Media/Autoplay_guide).
#### `ringtone`
Configures the chime played while an inbound call is ringing.
```yaml
live:
controls:
call:
ringtone:
# [...]
```
| Option | Default | Description |
| -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `type` | `chime` | Which ringtone to play. `chime` is the default two-note doorbell. `westminster` plays the four-note Westminster Quarters phrase. `arpeggio` plays three quick descending plucks. `melody` plays a I-V-I chord cadence. `custom` plays an audio file at `url` (e.g. an `.mp3` or any browser-supported URL). `none` disables the ringtone entirely (equivalent to leaving the call silent until answered). |
| `url` | | Path to an audio file to use as the ringtone. Only honored when `type` is `custom`; ignored otherwise. If `type` is `custom` but no `url` is provided, no ringtone plays. |
| `repeat` | `0` | Number of times the ringtone is played per inbound call. `0` loops indefinitely until the call is answered or ended. |
### `next_previous`
@@ -234,6 +260,10 @@ live:
call:
button_size: 40
lock: true
ringtone:
type: chime
repeat: 0
unanswered_timeout_seconds: 60
next_previous:
auto_hide:
- call
+5 -5
View File
@@ -162,11 +162,11 @@ human interaction with the card; this behavior can be configured via the
### Trigger action configuration
| Option | Default | Description |
| ------------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `interaction_mode` | `inactive` | Whether actions should be taken when the card is being interacted with. If `all`, actions will always left be taken regardless. If `inactive` actions will only be taken if the card has _not_ had human interaction recently (as defined by `view.interaction_seconds`). If `active` actions will only be taken if the card _has_ had human interaction recently. This does not stop triggering itself (i.e. border will still pulse if `show_trigger_status` is true) but rather just prevents the actions being performed. |
| `trigger` | `update` | If set to `update` the current view is updated in place. If set to `default` the default view of the card will be reloaded. If set to `live` the triggered camera will be selected in `live` view. If set to `media` the appropriate media view (e.g. `clip`, `snapshot`, `review`) will be chosen to match a newly available media item (please note that only some [camera engines](cameras/engine.md) support new media detection, e.g. `frigate`). If set to `none` no action is taken. |
| `untrigger` | `none` | If set to `default` the the default view of the card will be reloaded. If set to `none` no action will be taken. |
| Option | Default | Description |
| ------------------ | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `interaction_mode` | `inactive` | Whether actions should be taken when the card is being interacted with. If `all`, actions will always left be taken regardless. If `inactive` actions will only be taken if the card has _not_ had human interaction recently (as defined by `view.interaction_seconds`). If `active` actions will only be taken if the card _has_ had human interaction recently. This does not stop triggering itself (i.e. border will still pulse if `show_trigger_status` is true) but rather just prevents the actions being performed. |
| `trigger` | `update` | If set to `update` the current view is updated in place. If set to `default` the default view of the card will be reloaded. If set to `live` the triggered camera will be selected in `live` view. If set to `media` the appropriate media view (e.g. `clip`, `snapshot`, `review`) will be chosen to match a newly available media item (please note that only some [camera engines](cameras/engine.md) support new media detection, e.g. `frigate`). If set to `call` a two-way-audio call is automatically started on the triggered camera. If set to `none` no action is taken. |
| `untrigger` | `none` | If set to `default` the default view of the card will be reloaded. If set to `call` any unanswered inbound call started by the matching `call` trigger action is ended (calls already answered persist and must be ended manually). If set to `none` no action will be taken. |
## Supported views
+40
View File
@@ -359,6 +359,46 @@ elements:
![Doorbell example](images/doorbell-example.gif 'Doorbell example :size=400')
### Inbound call on doorbell press
This example uses [`view.triggers.actions.trigger: call`](configuration/view.md?id=triggers) to turn an dashboard into a phone-like ringer when somebody presses the doorbell. The intended deployment is a wall-mounted tablet sitting on the dashboard.
The Frigate camera's stock event triggers (`occupancy`, `motion`, `events`) are explicitly turned off so casual motion doesn't make the card ring — only an actual doorbell press does.
```yaml
type: custom:advanced-camera-card
cameras:
- camera_entity: camera.front_door
live_provider: go2rtc
go2rtc:
modes:
- webrtc
triggers:
occupancy: false
motion: false
events: []
entities:
- switch.door_bell
view:
default: live
triggers:
show_trigger_status: true
# Keeps the trigger "active" this long after the switch goes off.
# A doorbell button typically gives a brief ON pulse, so the chime
# would stop almost immediately if this were small -- this value
# is effectively how long the chime keeps ringing after the press.
untrigger_delay_seconds: 30
actions:
# Call when triggered.
trigger: call
# On release (after the untrigger_delay): end the call if it is
# still ringing. An answered call survives this and must be ended
# manually.
untrigger: call
# Ring even when somebody is actively using the card.
interaction_mode: all
```
## Events from other cameras
`dependencies.cameras` allows events/recordings for other cameras to be shown