diff --git a/docs/configuration/actions/custom/README.md b/docs/configuration/actions/custom/README.md index 4f7d1b67..c269922d 100644 --- a/docs/configuration/actions/custom/README.md +++ b/docs/configuration/actions/custom/README.md @@ -248,6 +248,15 @@ action: custom:frigate-card-action frigate_card_action: menu_toggle ``` +## `microphone_disconnect` + +Disconnect the microphone during [2-way audio](../../../usage/2-way-audio.md). + +```yaml +action: custom:frigate-card-action +frigate_card_action: microphone_disconnect +``` + ## `microphone_mute` Mute the microphone during [2-way audio](../../../usage/2-way-audio.md). diff --git a/docs/usage/url-actions.md b/docs/usage/url-actions.md index fa5a5ea0..8595d030 100644 --- a/docs/usage/url-actions.md +++ b/docs/usage/url-actions.md @@ -46,31 +46,31 @@ unless the action is targeted with a `CARD_ID` as shown above. Only a subset of all [actions](../configuration/actions/README.md) are supported in URL form. -| Action | Supported in URL | Explanation | -| -------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------- | -| `camera_select` | :white_check_mark: | | -| `camera_ui` | :white_check_mark: | | -| `clip` | :white_check_mark: | | -| `clips` | :white_check_mark: | | -| `default` | :white_check_mark: | | -| `download` | :heavy_multiplication_x: | Latest media information is not available on initial render. | -| `expand` | :white_check_mark: | | -| `fullscreen` | :heavy_multiplication_x: | Javascript does not support activating fullscreen without direct human interaction. Use `expand` as an alternative. | -| `image` | :white_check_mark: | | -| `live_substream_select` | :white_check_mark: | | -| `live` | :white_check_mark: | | -| `media_player` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this. | -| `menu_toggle` | :white_check_mark: | | -| `microphone_mute`, `microphone_unmute` | :heavy_multiplication_x: | | -| `mute`, `unmute` | :heavy_multiplication_x: | | -| `play`, `pause` | :heavy_multiplication_x: | | -| `ptz` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this. | -| `recording` | :white_check_mark: | | -| `recordings` | :white_check_mark: | | -| `screenshot` | :heavy_multiplication_x: | Latest media information is not available on initial render. | -| `ptz_controls` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this. | -| `snapshot` | :white_check_mark: | | -| `snapshots` | :white_check_mark: | | +| Action | Supported in URL | Explanation | +| --------------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------- | +| `camera_select` | :white_check_mark: | | +| `camera_ui` | :white_check_mark: | | +| `clip` | :white_check_mark: | | +| `clips` | :white_check_mark: | | +| `default` | :white_check_mark: | | +| `download` | :heavy_multiplication_x: | Latest media information is not available on initial render. | +| `expand` | :white_check_mark: | | +| `fullscreen` | :heavy_multiplication_x: | Javascript does not support activating fullscreen without direct human interaction. Use `expand` as an alternative. | +| `image` | :white_check_mark: | | +| `live_substream_select` | :white_check_mark: | | +| `live` | :white_check_mark: | | +| `media_player` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this. | +| `menu_toggle` | :white_check_mark: | | +| `microphone_disconnect`, `microphone_mute`, `microphone_unmute` | :heavy_multiplication_x: | | +| `mute`, `unmute` | :heavy_multiplication_x: | | +| `play`, `pause` | :heavy_multiplication_x: | | +| `ptz` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this. | +| `recording` | :white_check_mark: | | +| `recordings` | :white_check_mark: | | +| `screenshot` | :heavy_multiplication_x: | Latest media information is not available on initial render. | +| `ptz_controls` | :heavy_multiplication_x: | Please [request](https://github.com/dermotduffy/frigate-hass-card/issues) if you need this. | +| `snapshot` | :white_check_mark: | | +| `snapshots` | :white_check_mark: | | ## Examples diff --git a/src/card-controller/actions/actions/microphone-disconnect.ts b/src/card-controller/actions/actions/microphone-disconnect.ts new file mode 100644 index 00000000..f6771a60 --- /dev/null +++ b/src/card-controller/actions/actions/microphone-disconnect.ts @@ -0,0 +1,9 @@ +import { GeneralActionConfig } from '../../../config/types'; +import { CardActionsAPI } from '../../types'; +import { FrigateCardAction } from './base'; + +export class MicrophoneDisconnectAction extends FrigateCardAction { + public async execute(api: CardActionsAPI): Promise { + api.getMicrophoneManager().disconnect(); + } +} diff --git a/src/card-controller/actions/factory.ts b/src/card-controller/actions/factory.ts index 21d36c77..e67d831b 100644 --- a/src/card-controller/actions/factory.ts +++ b/src/card-controller/actions/factory.ts @@ -13,6 +13,7 @@ import { GenericAction } from './actions/generic'; import { LogAction } from './actions/log'; import { MediaPlayerAction } from './actions/media-player'; import { MenuToggleAction } from './actions/menu-toggle'; +import { MicrophoneDisconnectAction } from './actions/microphone-disconnect'; import { MicrophoneMuteAction } from './actions/microphone-mute'; import { MicrophoneUnmuteAction } from './actions/microphone-unmute'; import { MuteAction } from './actions/mute'; @@ -96,6 +97,12 @@ export class ActionFactory { return new SubstreamOnAction(context, frigateCardAction, options?.config); case 'media_player': return new MediaPlayerAction(context, frigateCardAction, options?.config); + case 'microphone_disconnect': + return new MicrophoneDisconnectAction( + context, + frigateCardAction, + options?.config, + ); case 'microphone_mute': return new MicrophoneMuteAction(context, frigateCardAction, options?.config); case 'microphone_unmute': diff --git a/src/config/types.ts b/src/config/types.ts index 4a6f3056..a87afa0d 100644 --- a/src/config/types.ts +++ b/src/config/types.ts @@ -270,6 +270,7 @@ const FRIGATE_CARD_GENERAL_ACTIONS = [ 'live_substream_off', 'live_substream_on', 'menu_toggle', + 'microphone_disconnect', 'microphone_mute', 'microphone_unmute', 'mute', diff --git a/tests/card-controller/actions/actions/microphone-disconnect.test.ts b/tests/card-controller/actions/actions/microphone-disconnect.test.ts new file mode 100644 index 00000000..fe0d20e1 --- /dev/null +++ b/tests/card-controller/actions/actions/microphone-disconnect.test.ts @@ -0,0 +1,18 @@ +import { expect, it } from 'vitest'; +import { MicrophoneDisconnectAction } from '../../../../src/card-controller/actions/actions/microphone-disconnect'; +import { createCardAPI } from '../../../test-utils'; + +it('should handle microphone_disconnect action', async () => { + const api = createCardAPI(); + const action = new MicrophoneDisconnectAction( + {}, + { + action: 'fire-dom-event', + frigate_card_action: 'microphone_disconnect', + }, + ); + + await action.execute(api); + + expect(api.getMicrophoneManager().disconnect).toBeCalled(); +}); diff --git a/tests/card-controller/actions/factory.test.ts b/tests/card-controller/actions/factory.test.ts index 7352cd05..9b2cc022 100644 --- a/tests/card-controller/actions/factory.test.ts +++ b/tests/card-controller/actions/factory.test.ts @@ -10,6 +10,7 @@ import { GenericAction } from '../../../src/card-controller/actions/actions/gene import { LogAction } from '../../../src/card-controller/actions/actions/log'; import { MediaPlayerAction } from '../../../src/card-controller/actions/actions/media-player'; import { MenuToggleAction } from '../../../src/card-controller/actions/actions/menu-toggle'; +import { MicrophoneDisconnectAction } from '../../../src/card-controller/actions/actions/microphone-disconnect'; import { MicrophoneMuteAction } from '../../../src/card-controller/actions/actions/microphone-mute'; import { MicrophoneUnmuteAction } from '../../../src/card-controller/actions/actions/microphone-unmute'; import { MuteAction } from '../../../src/card-controller/actions/actions/mute'; @@ -103,6 +104,10 @@ describe('ActionFactory', () => { MediaPlayerAction, ], [{ frigate_card_action: 'menu_toggle' as const }, MenuToggleAction], + [ + { frigate_card_action: 'microphone_disconnect' as const }, + MicrophoneDisconnectAction, + ], [{ frigate_card_action: 'microphone_mute' as const }, MicrophoneMuteAction], [{ frigate_card_action: 'microphone_unmute' as const }, MicrophoneUnmuteAction], [{ frigate_card_action: 'mute' as const }, MuteAction],