@@ -55,12 +55,13 @@ 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. |
|
||||
| `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 call is answered or ended. 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 call is answered. Set to `0` to disable the timeout. |
|
||||
| Option | Default | Description |
|
||||
| ---------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `button_size` | `40` | The size of the call control buttons in pixels. Must be >= `20`. |
|
||||
| `enabled` | `true` | Whether the on-screen call controls are shown during a call. Set to `false` to hide them and drive calls from the [`menu`](./menu.md) instead. When hiding the controls, be sure to also remove `call` from `menu.auto_hide` so the menu stays visible allowing the call to be controlled. See [Driving calls from the menu](../examples.md?id=driving-calls-from-the-menu) for a complete example. |
|
||||
| `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 call is answered or ended. 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 call is answered. 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
|
||||
|
||||
@@ -563,6 +563,64 @@ profiles:
|
||||
> the view-only camera to `live_provider: ha` (HLS / receive-only WebRTC, which
|
||||
> never offers a backchannel) instead.
|
||||
|
||||
### Driving calls from the menu
|
||||
|
||||
By default on-screen controls will appear mid-card to handle a call. Setting
|
||||
[`live.controls.call.enabled: false`](configuration/live.md?id=call) hides those
|
||||
controls so the call can be driven via some other mechanism. In this example,
|
||||
the card is configured to allow calls to be driven from the menu instead.
|
||||
|
||||
This wires up the menu equivalents of every overlay control. The menu `call`
|
||||
button starts, ends, and (while ringing) rejects calls, but it cannot _answer_
|
||||
an inbound ring -- so a conditional answer button is added that appears only
|
||||
while ringing.
|
||||
|
||||
```yaml
|
||||
type: custom:advanced-camera-card
|
||||
cameras:
|
||||
- camera_entity: camera.front_door
|
||||
live_provider: go2rtc
|
||||
go2rtc:
|
||||
modes:
|
||||
- webrtc
|
||||
profiles:
|
||||
- doorbell
|
||||
live:
|
||||
controls:
|
||||
call:
|
||||
# Hide the on-screen call controls overlay -- the menu drives the call.
|
||||
enabled: false
|
||||
menu:
|
||||
# The menu hides during a call by default; keep it visible so its call
|
||||
# controls stay reachable.
|
||||
auto_hide: []
|
||||
buttons:
|
||||
# Starts a call, and becomes a hang-up button for the duration of a call.
|
||||
call:
|
||||
enabled: true
|
||||
# Mutes/unmutes your outbound microphone during a call.
|
||||
microphone:
|
||||
enabled: true
|
||||
type: toggle
|
||||
# Mutes/unmutes the inbound (caller's) audio during a call.
|
||||
mute:
|
||||
enabled: true
|
||||
elements:
|
||||
# The menu `call` button cannot answer an inbound (ringing) call, so this
|
||||
# answer button is shown only while ringing to provide that control.
|
||||
- type: custom:advanced-camera-card-conditional
|
||||
conditions:
|
||||
- condition: call
|
||||
call: ringing
|
||||
elements:
|
||||
- type: custom:advanced-camera-card-menu-icon
|
||||
icon: mdi:phone
|
||||
title: Answer call
|
||||
tap_action:
|
||||
action: custom:advanced-camera-card-action
|
||||
advanced_camera_card_action: call_answer
|
||||
```
|
||||
|
||||
## Events from other cameras
|
||||
|
||||
`dependencies.cameras` allows events/recordings for other cameras to be shown
|
||||
|
||||
@@ -25,6 +25,7 @@ const getCallSchema = (): HAFormExpandableSchema => ({
|
||||
title: localize('config.live.controls.call.editor_label'),
|
||||
icon: 'mdi:phone',
|
||||
schema: [
|
||||
{ name: 'enabled', selector: { boolean: {} } },
|
||||
{ name: 'lock', selector: { boolean: {} } },
|
||||
{
|
||||
name: 'ringtone',
|
||||
|
||||
@@ -435,7 +435,8 @@ export class AdvancedCameraCardLiveCarousel extends LitElement {
|
||||
!gesturesPTZActive &&
|
||||
!this.locked;
|
||||
|
||||
const isCallActive = this.call?.cameraID === carouselCameraID;
|
||||
const isCallControlsActive =
|
||||
this.liveConfig.controls.call.enabled && this.call?.cameraID === carouselCameraID;
|
||||
const callMediaPlayerController =
|
||||
this._mediaLoadedInfoSinkController.get()?.mediaPlayerController ?? null;
|
||||
|
||||
@@ -470,7 +471,7 @@ export class AdvancedCameraCardLiveCarousel extends LitElement {
|
||||
>
|
||||
</advanced-camera-card-ptz>
|
||||
<advanced-camera-card-call-controls
|
||||
.active=${isCallActive}
|
||||
.active=${isCallControlsActive}
|
||||
.answered=${this.call?.answered ?? true}
|
||||
.microphoneState=${this.microphoneState}
|
||||
.muted=${callMediaPlayerController?.isMuted()}
|
||||
|
||||
@@ -50,6 +50,7 @@ export type RingtoneConfig = z.infer<typeof ringtoneConfigSchema>;
|
||||
|
||||
const callConfigDefault = {
|
||||
button_size: 40,
|
||||
enabled: true,
|
||||
lock: true,
|
||||
ringtone: { ...ringtoneConfigDefault },
|
||||
unanswered_timeout_seconds: 60,
|
||||
@@ -57,6 +58,7 @@ const callConfigDefault = {
|
||||
|
||||
const callConfigSchema = z.object({
|
||||
button_size: z.number().min(BUTTON_SIZE_MIN).default(callConfigDefault.button_size),
|
||||
enabled: z.boolean().default(callConfigDefault.enabled),
|
||||
lock: z.boolean().default(callConfigDefault.lock),
|
||||
ringtone: ringtoneConfigSchema.default(callConfigDefault.ringtone),
|
||||
|
||||
|
||||
@@ -459,6 +459,7 @@
|
||||
"answer": "Answer call",
|
||||
"button_size": "Call control button size",
|
||||
"editor_label": "Two-way audio call",
|
||||
"enabled": "Show on-screen call controls",
|
||||
"end": "End 2-way audio call",
|
||||
"lock": "Lock UI during an active call",
|
||||
"mute_audio": "Mute audio",
|
||||
|
||||
@@ -99,6 +99,7 @@ describe('config defaults', () => {
|
||||
builtin: true,
|
||||
call: {
|
||||
button_size: 40,
|
||||
enabled: true,
|
||||
lock: true,
|
||||
ringtone: { type: 'chime', repeat: 0 },
|
||||
unanswered_timeout_seconds: 60,
|
||||
@@ -1848,6 +1849,20 @@ it('should not require title controls to specify all options', () => {
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should allow the on-screen call controls overlay to be disabled', () => {
|
||||
const config = createConfig({
|
||||
cameras: [{}],
|
||||
live: {
|
||||
controls: {
|
||||
call: {
|
||||
enabled: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(config.live.controls.call.enabled).toBe(false);
|
||||
});
|
||||
|
||||
it('should strip trailing slashes from go2rtc url', () => {
|
||||
const config = createConfig({
|
||||
cameras: [
|
||||
|
||||
Reference in New Issue
Block a user