diff --git a/README.md b/README.md index beb77517..53ecfb13 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,7 @@ view: | `actions` | | :heavy_multiplication_x: | Actions to use for all views, individual actions may be overriden by view-specific actions. See [actions](#actions) below.| | `update_force` | `false` | :heavy_multiplication_x: | Whether card updates/refreshes should ignore playing media and human interaction. See [card updates](#card-updates) below for behavior and usecases.| | `update_entities` | | :heavy_multiplication_x: | **YAML only**: A list of entity ids that should cause the view to reset to the default. See [card updates](#card-updates) below for behavior and usecases.| +| `update_cycle_camera` | `false` | :heavy_multiplication_x: | When set to `true` the selected camera is cycled on each default view change. | ### Menu Options diff --git a/src/card.ts b/src/card.ts index 32a5b6ed..05e5e336 100644 --- a/src/card.ts +++ b/src/card.ts @@ -641,8 +641,15 @@ export class FrigateCard extends LitElement { if (args?.view === undefined) { let camera = this._view?.camera; - if (!camera && this._cameras?.size) { - camera = this._cameras.keys().next().value; + if (this._cameras?.size) { + if (!camera) { + camera = this._cameras.keys().next().value; + } else if (this._getConfig().view.update_cycle_camera) { + const keys = Array.from(this._cameras.keys()); + const currentIndex = keys.indexOf(camera); + const targetIndex = currentIndex + 1 >= keys.length ? 0 : currentIndex + 1; + camera = keys[targetIndex]; + } } if (camera) { diff --git a/src/const.ts b/src/const.ts index 97a0ab88..da48e0ee 100644 --- a/src/const.ts +++ b/src/const.ts @@ -21,6 +21,7 @@ export const CONF_CAMERAS_ARRAY_LIVE_PROVIDER = `${CONF_CAMERAS}.#.live_provider export const CONF_VIEW = 'view' as const; export const CONF_VIEW_DEFAULT = `${CONF_VIEW}.default` as const; export const CONF_VIEW_TIMEOUT_SECONDS = `${CONF_VIEW}.timeout_seconds` as const; +export const CONF_VIEW_UPDATE_CYCLE_CAMERA = `${CONF_VIEW}.update_cycle_camera` as const; export const CONF_VIEW_UPDATE_FORCE = `${CONF_VIEW}.update_force` as const; export const CONF_VIEW_UPDATE_ENTITIES = `${CONF_VIEW}.update_entities` as const; diff --git a/src/editor.ts b/src/editor.ts index 339600a2..dfd75cd9 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -57,6 +57,7 @@ import { CONF_MENU_MODE, CONF_VIEW_DEFAULT, CONF_VIEW_TIMEOUT_SECONDS, + CONF_VIEW_UPDATE_CYCLE_CAMERA, CONF_VIEW_UPDATE_FORCE, } from './const.js'; import { arrayMove, getEntityTitle, prettifyFrigateName } from './common.js'; @@ -659,6 +660,7 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor ${this._renderDropdown(CONF_VIEW_DEFAULT, viewModes)} ${this._renderStringInput(CONF_VIEW_TIMEOUT_SECONDS, 'number')} ${this._renderSwitch(CONF_VIEW_UPDATE_FORCE, defaults.view.update_force)} + ${this._renderSwitch(CONF_VIEW_UPDATE_CYCLE_CAMERA, defaults.view.update_cycle_camera)} ` : ''} diff --git a/src/localize/languages/en.json b/src/localize/languages/en.json index 9002c31f..78dce17f 100644 --- a/src/localize/languages/en.json +++ b/src/localize/languages/en.json @@ -42,6 +42,7 @@ "image": "Static image" }, "timeout_seconds": "View timeout seconds (before returning to default, 0=never)", + "update_cycle_camera": "Cycle through cameras when default view updates", "update_force": "Force card updates (ignore media playing / interaction)" }, "event_gallery": { diff --git a/src/types.ts b/src/types.ts index c16a77b3..c428d4a4 100644 --- a/src/types.ts +++ b/src/types.ts @@ -372,6 +372,7 @@ const viewConfigDefault = { default: 'live' as const, timeout: 180, update_force: false, + update_cycle_camera: false, }; const viewConfigSchema = z .object({ @@ -381,6 +382,7 @@ const viewConfigSchema = z .default(viewConfigDefault.default), timeout_seconds: z.number().default(viewConfigDefault.timeout), update_force: z.boolean().default(viewConfigDefault.update_force), + update_cycle_camera: z.boolean().default(viewConfigDefault.update_cycle_camera), update_entities: z.string().array().optional(), }) .merge(actionsSchema)