From 40be446c69e358ea0e8b1ad8691cc0581ab6766c Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Wed, 8 Jun 2022 21:45:11 -0700 Subject: [PATCH 1/3] Add shortcut for a camera to depend on all others. --- README.md | 3 +++ src/card.ts | 20 +++++++++++--------- src/const.ts | 2 ++ src/editor.ts | 5 +++++ src/localize/languages/en.json | 3 ++- src/types.ts | 9 ++++++++- src/utils/ha/browse-media.ts | 16 ++++++++++------ 7 files changed, 41 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 34933643..b4be0844 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ See the [fully expanded cameras configuration example](#config-expanded-cameras) | `webrtc_card` | | :heavy_multiplication_x: | The WebRTC entity/URL to use for this camera with the `webrtc-card` live provider. See below. | | `id` | `camera_entity`, `webrtc_card.entity` or `camera_name` if set (in that preference order). | :heavy_multiplication_x: | An optional identifier to use throughout the card configuration to refer unambiguously to this camera. See [camera IDs](#camera-ids). | | `dependent_cameras` | | :heavy_multiplication_x: | An optional array of other camera identifiers (see [camera IDs](#camera-ids)). If specified the card will fetch events for this camera and *also* recursively events for the named `dependent_cameras`. All `dependent_cameras` must themselves be a configured camera in the card. This can be useful to group events for cameras that are close together, or to show events for the `birdseye` camera that otherwise would not have events itself.| +| `dependent_cameras_all` | `false` | :heavy_multiplication_x: | Shortcut to specify all other cameras as dependent cameras (see `dependent_cameras` above).| | `trigger_by_motion` | `false` | :heavy_multiplication_x: | Whether to not to trigger the camera (used to trigger [scan mode](#scan-mode) or reseting the default view) by automatically detecting and using the motion `binary_sensor` for this camera. This autodetection only works for Frigate cameras, and only when the motion `binary_sensor` entity has been enabled in Home Assistant.| | `trigger_by_occupancy` | `true` | :heavy_multiplication_x: | Whether to not to trigger the camera (used to trigger [scan mode](#scan-mode) or reseting the default view) by automatically detecting and using the occupancy `binary_sensor` for this camera. This autodetection only works for Frigate cameras, and only when the occupancy `binary_sensor` entity has been enabled in Home Assistant.| | `trigger_by_entities` | | :heavy_multiplication_x: | Whether to not to trigger the camera (used to trigger [scan mode](#scan-mode) or reseting the default view) when the state of any Home Assistant entity becomes active (i.e. state becomes `on` or `open`). This works for Frigate or non-Frigate cameras.| @@ -1013,6 +1014,7 @@ cameras: # Show events for camera-2 when this camera is viewed. dependent_cameras: - camera-2 + dependent_cameras_all: false trigger_by_motion: false trigger_by_occupancy: true trigger_by_entities: @@ -1035,6 +1037,7 @@ cameras: trigger_by_occupancy: true trigger_by_entities: - binary_sensor.entrance_sensor + dependent_cameras_all: false ``` diff --git a/src/card.ts b/src/card.ts index 2d84821c..d56b09f3 100644 --- a/src/card.ts +++ b/src/card.ts @@ -5,7 +5,7 @@ import { LitElement, PropertyValues, TemplateResult, - unsafeCSS, + unsafeCSS } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { classMap } from 'lit/directives/class-map.js'; @@ -20,7 +20,7 @@ import { ConditionState, conditionStateRequestHandler, getOverriddenConfig, - getOverridesByKey, + getOverridesByKey } from './card-condition.js'; import './components/elements.js'; import { FrigateCardElements } from './components/elements.js'; @@ -40,7 +40,7 @@ import { CAMERA_BIRDSEYE, CARD_VERSION, MEDIA_PLAYER_SUPPORT_BROWSE_MEDIA, - REPO_URL, + REPO_URL } from './const.js'; import './editor.js'; import { localize } from './localize/localize.js'; @@ -63,14 +63,14 @@ import { MediaShowInfo, MenuButton, Message, - RawFrigateCardConfig, + RawFrigateCardConfig } from './types.js'; import { convertActionToFrigateCardCustomAction, createFrigateCardCustomAction, frigateCardHandleAction, frigateCardHasAction, - getActionConfigGivenAction, + getActionConfigGivenAction } from './utils/action.js'; import { contentsChanged } from './utils/basic.js'; import { getCameraIcon, getCameraID, getCameraTitle } from './utils/camera.js'; @@ -81,7 +81,7 @@ import { homeAssistantSignPath, isHassDifferent, isTriggeredState, - sideLoadHomeAssistantElements, + sideLoadHomeAssistantElements } from './utils/ha'; import { getEventID } from './utils/ha/browse-media.js'; import { DeviceList, getAllDevices } from './utils/ha/device-registry.js'; @@ -89,7 +89,7 @@ import { ExtendedEntityCache, getAllEntities, getExtendedEntities, - getExtendedEntity, + getExtendedEntity } from './utils/ha/entity-registry.js'; import { ResolvedMediaCache } from './utils/ha/resolved-media.js'; import { supportsFeature } from './utils/ha/update.js'; @@ -398,7 +398,8 @@ export class FrigateCard extends LitElement { if ( cameraConfig?.camera_name && (cameraConfig?.camera_name !== CAMERA_BIRDSEYE || - cameraConfig?.dependent_cameras?.length) + cameraConfig?.dependent_cameras?.length || + cameraConfig?.dependent_cameras_all) ) { buttons.push({ icon: 'mdi:filmstrip', @@ -416,7 +417,8 @@ export class FrigateCard extends LitElement { if ( cameraConfig?.camera_name && (cameraConfig?.camera_name !== CAMERA_BIRDSEYE || - cameraConfig?.dependent_cameras?.length) + cameraConfig?.dependent_cameras?.length || + cameraConfig?.dependent_cameras_all) ) { buttons.push({ icon: 'mdi:camera', diff --git a/src/const.ts b/src/const.ts index fad0d643..816104db 100644 --- a/src/const.ts +++ b/src/const.ts @@ -23,6 +23,8 @@ export const CONF_CAMERAS_ARRAY_LIVE_PROVIDER = `${CONF_CAMERAS}.#.live_provider` as const; export const CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS = `${CONF_CAMERAS}.#.dependent_cameras` as const; + export const CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS_ALL = + `${CONF_CAMERAS}.#.dependent_cameras_all` as const; export const CONF_CAMERAS_ARRAY_TRIGGER_BY_MOTION = `${CONF_CAMERAS}.#.trigger_by_motion` as const; export const CONF_CAMERAS_ARRAY_TRIGGER_BY_OCCUPANCY = diff --git a/src/editor.ts b/src/editor.ts index 9eb6fc24..af0f3df2 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -17,6 +17,7 @@ import { CONF_CAMERAS_ARRAY_CAMERA_NAME, CONF_CAMERAS_ARRAY_CLIENT_ID, CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS, + CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS_ALL, CONF_CAMERAS_ARRAY_ICON, CONF_CAMERAS_ARRAY_ID, CONF_CAMERAS_ARRAY_LABEL, @@ -882,6 +883,10 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor ${this._renderStringInput( getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, cameraIndex), )} + ${this._renderSwitch( + getArrayConfigPath(CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS_ALL, cameraIndex), + frigateCardConfigDefaults.cameras.dependent_cameras_all, + )} ${this._renderOptionSelector( getArrayConfigPath(CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS, cameraIndex), dependentCameras, diff --git a/src/localize/languages/en.json b/src/localize/languages/en.json index 428e3fd2..484ade11 100644 --- a/src/localize/languages/en.json +++ b/src/localize/languages/en.json @@ -15,7 +15,8 @@ "camera_entity": "Camera Entity", "camera_name": "Frigate camera name (Autodetected from entity)", "client_id": "Frigate client id (For >1 Frigate server)", - "dependent_cameras": "Dependent cameras to also show events for", + "dependent_cameras": "Show events for specific cameras with this camera", + "dependent_cameras_all": "Show events for all cameras with this camera", "id": "Unique id for this camera in this card", "label": "Frigate label/object filter", "frigate_url": "Frigate server URL", diff --git a/src/types.ts b/src/types.ts index 6e56c48d..9a21b5fa 100644 --- a/src/types.ts +++ b/src/types.ts @@ -375,6 +375,7 @@ export const cameraConfigDefault = { trigger_by_motion: false, trigger_by_occupancy: true, trigger_by_entities: [], + dependent_cameras_all: false, }; const webrtcCardCameraConfigSchema = z.object({ entity: z.string().optional(), @@ -405,6 +406,9 @@ const cameraConfigSchema = z // Set of cameras IDs upon which this camera depends. dependent_cameras: z.string().array().optional(), + dependent_cameras_all: z + .boolean() + .default(cameraConfigDefault.dependent_cameras_all), trigger_by_motion: z.boolean().default(cameraConfigDefault.trigger_by_motion), trigger_by_occupancy: z.boolean().default(cameraConfigDefault.trigger_by_occupancy), @@ -1015,7 +1019,10 @@ const timelineConfigSchema = z .max(24 * 60 * 60) .optional() .default(timelineConfigDefault.window_seconds), - show_recordings: z.boolean().optional().default(timelineConfigDefault.show_recordings), + show_recordings: z + .boolean() + .optional() + .default(timelineConfigDefault.show_recordings), controls: z .object({ thumbnails: thumbnailsControlSchema diff --git a/src/utils/ha/browse-media.ts b/src/utils/ha/browse-media.ts index 5bb03d4f..497fdb7b 100644 --- a/src/utils/ha/browse-media.ts +++ b/src/utils/ha/browse-media.ts @@ -264,7 +264,14 @@ export const getFullDependentBrowseMediaQueryParameters = ( const cameraConfig = cameras.get(camera); if (cameraConfig) { cameraIDs.add(camera); - for (const eventCameraID of cameraConfig.dependent_cameras || []) { + const dependentCameras: Set = new Set(); + (cameraConfig.dependent_cameras || []).forEach((item) => + dependentCameras.add(item), + ); + if (cameraConfig.dependent_cameras_all) { + cameras.forEach((_, key) => dependentCameras.add(key)); + } + for (const eventCameraID of dependentCameras) { if (!cameraIDs.has(eventCameraID)) { getDependentCameras(eventCameraID); } @@ -281,12 +288,9 @@ export const getFullDependentBrowseMediaQueryParameters = ( cameras.get(cameraID), mediaType ? { mediaType: mediaType } : {}, ); - // Fail on a single bad camera, as it's almost certainly a user error that - // should be fixed rather than hidden. - if (!param) { - return null; + if (param) { + params.push(param); } - params.push(param); } return params.length ? params : null; }; From 14bbb26e95980fe7f0e29354f41fa1e5eaaf9ac3 Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Fri, 10 Jun 2022 09:10:42 -0700 Subject: [PATCH 2/3] Add a new convenience option to depend on all other cameras. --- README.md | 56 +++++++++++++++++++++++++++------- src/const.ts | 8 ++--- src/editor.ts | 13 +++++--- src/localize/languages/en.json | 6 ++-- src/types.ts | 16 ++++++---- src/utils/ha/browse-media.ts | 4 +-- 6 files changed, 73 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index b4be0844..f2b2b63e 100644 --- a/README.md +++ b/README.md @@ -113,8 +113,7 @@ See the [fully expanded cameras configuration example](#config-expanded-cameras) | `icon` | Autodetected from `camera_entity` if that is specified. | :heavy_multiplication_x: | The icon to use for this camera in the camera menu and in the next & previous controls when using the `icon` style. | | `webrtc_card` | | :heavy_multiplication_x: | The WebRTC entity/URL to use for this camera with the `webrtc-card` live provider. See below. | | `id` | `camera_entity`, `webrtc_card.entity` or `camera_name` if set (in that preference order). | :heavy_multiplication_x: | An optional identifier to use throughout the card configuration to refer unambiguously to this camera. See [camera IDs](#camera-ids). | -| `dependent_cameras` | | :heavy_multiplication_x: | An optional array of other camera identifiers (see [camera IDs](#camera-ids)). If specified the card will fetch events for this camera and *also* recursively events for the named `dependent_cameras`. All `dependent_cameras` must themselves be a configured camera in the card. This can be useful to group events for cameras that are close together, or to show events for the `birdseye` camera that otherwise would not have events itself.| -| `dependent_cameras_all` | `false` | :heavy_multiplication_x: | Shortcut to specify all other cameras as dependent cameras (see `dependent_cameras` above).| +| `dependencies` | | :heavy_multiplication_x: | Other cameras that this camera should depend upon. See [camera dependencies](#camera-dependency-configuration) below. | | `trigger_by_motion` | `false` | :heavy_multiplication_x: | Whether to not to trigger the camera (used to trigger [scan mode](#scan-mode) or reseting the default view) by automatically detecting and using the motion `binary_sensor` for this camera. This autodetection only works for Frigate cameras, and only when the motion `binary_sensor` entity has been enabled in Home Assistant.| | `trigger_by_occupancy` | `true` | :heavy_multiplication_x: | Whether to not to trigger the camera (used to trigger [scan mode](#scan-mode) or reseting the default view) by automatically detecting and using the occupancy `binary_sensor` for this camera. This autodetection only works for Frigate cameras, and only when the occupancy `binary_sensor` entity has been enabled in Home Assistant.| | `trigger_by_entities` | | :heavy_multiplication_x: | Whether to not to trigger the camera (used to trigger [scan mode](#scan-mode) or reseting the default view) when the state of any Home Assistant entity becomes active (i.e. state becomes `on` or `open`). This works for Frigate or non-Frigate cameras.| @@ -147,11 +146,27 @@ cameras: See [Using the WebRTC Card](#webrtc) below for more details on how to use the WebRTC Card live provider. + + +#### Camera Dependency Configuration + +The `dependencies` block configures other cameras as dependents of this camera. Dependent cameras have their events fetched and merged with this camera. Configuration is under: + +```yaml +cameras: + - dependencies: +``` + +| Option | Default | Overridable | Description | +| - | - | - | - | +| `cameras` | | :heavy_multiplication_x: | An optional array of other camera identifiers (see [camera IDs](#camera-ids)). If specified the card will fetch events for this camera and *also* recursively events for the named cameras. All dependent cameras must themselves be a configured camera in the card. This can be useful to group events for cameras that are close together, to always have clips/snapshots show fully merged events across all cameras or to show events for the `birdseye` camera that otherwise would not have events itself.| +| `all_cameras` | `false` | :heavy_multiplication_x: | Shortcut to specify all other cameras as dependent cameras.| + #### Camera IDs: Refering to cameras in card configuration -Each camera configured in the card has a single identifier (`id`). For a given camera, this will be one of the camera {`id`, `camera_entity`, `webrtc_card.entity` or `camera_name`} parameters for that camera -- in that order of precedence. These ids may be used in conditions or custom actions to refer to a given camera unambiguously. | +Each camera configured in the card has a single identifier (`id`). For a given camera, this will be one of the camera {`id`, `camera_entity`, `webrtc_card.entity` or `camera_name`} parameters for that camera -- in that order of precedence. These ids may be used in conditions, dependencies or custom actions to refer to a given camera unambiguously. | #### Example @@ -1012,9 +1027,10 @@ cameras: camera_entity: camera.front_Door live_provider: ha # Show events for camera-2 when this camera is viewed. - dependent_cameras: - - camera-2 - dependent_cameras_all: false + dependencies: + all_cameras: false + cameras: + - camera-2 trigger_by_motion: false trigger_by_occupancy: true trigger_by_entities: @@ -1037,7 +1053,8 @@ cameras: trigger_by_occupancy: true trigger_by_entities: - binary_sensor.entrance_sensor - dependent_cameras_all: false + dependencies: + all_cameras: false ``` @@ -2455,7 +2472,7 @@ menu: ### Using a dependent camera -`dependent_cameras` allows events for other cameras to be shown along with the currently selected camera. For example, this can be used to show events with the `birdseye` camera (since it will not have events of its own). +`dependencies.cameras` allows events for other cameras to be shown along with the currently selected camera. For example, this can be used to show events with the `birdseye` camera (since it will not have events of its own).
Expand: Using dependent cameras with birdseye @@ -2468,9 +2485,26 @@ cameras: - camera_entity: camera.kitchen - camera_entity: camera.sitting_room - camera_name: birdseye - dependent_cameras: - - camera.kitchen - - camera.sitting_room + dependencies: + cameras: + - camera.kitchen + - camera.sitting_room +``` +
+ +
+ Expand: Using all dependent cameras with birdseye + +This example shows events for all other cameras when `birdseye` is selected. This is just a shortcut to naming all other cameras. + +```yaml +[...] +cameras: + - camera_entity: camera.kitchen + - camera_entity: camera.sitting_room + - camera_name: birdseye + dependencies: + all_cameras: true ```
diff --git a/src/const.ts b/src/const.ts index 816104db..ca6d8e9d 100644 --- a/src/const.ts +++ b/src/const.ts @@ -21,10 +21,10 @@ export const CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL = `${CONF_CAMERAS}.#.webrtc_card.url` as const; export const CONF_CAMERAS_ARRAY_LIVE_PROVIDER = `${CONF_CAMERAS}.#.live_provider` as const; -export const CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS = - `${CONF_CAMERAS}.#.dependent_cameras` as const; - export const CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS_ALL = - `${CONF_CAMERAS}.#.dependent_cameras_all` as const; +export const CONF_CAMERAS_ARRAY_DEPENDENCIES_CAMERAS = + `${CONF_CAMERAS}.#.dependencies.cameras` as const; + export const CONF_CAMERAS_ARRAY_DEPENDENCIES_ALL_CAMERAS = + `${CONF_CAMERAS}.#.dependencies.all_cameras` as const; export const CONF_CAMERAS_ARRAY_TRIGGER_BY_MOTION = `${CONF_CAMERAS}.#.trigger_by_motion` as const; export const CONF_CAMERAS_ARRAY_TRIGGER_BY_OCCUPANCY = diff --git a/src/editor.ts b/src/editor.ts index af0f3df2..7fe3457f 100644 --- a/src/editor.ts +++ b/src/editor.ts @@ -16,8 +16,8 @@ import { CONF_CAMERAS_ARRAY_CAMERA_ENTITY, CONF_CAMERAS_ARRAY_CAMERA_NAME, CONF_CAMERAS_ARRAY_CLIENT_ID, - CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS, - CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS_ALL, + CONF_CAMERAS_ARRAY_DEPENDENCIES_ALL_CAMERAS, + CONF_CAMERAS_ARRAY_DEPENDENCIES_CAMERAS, CONF_CAMERAS_ARRAY_ICON, CONF_CAMERAS_ARRAY_ID, CONF_CAMERAS_ARRAY_LABEL, @@ -884,11 +884,14 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, cameraIndex), )} ${this._renderSwitch( - getArrayConfigPath(CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS_ALL, cameraIndex), - frigateCardConfigDefaults.cameras.dependent_cameras_all, + getArrayConfigPath( + CONF_CAMERAS_ARRAY_DEPENDENCIES_ALL_CAMERAS, + cameraIndex, + ), + frigateCardConfigDefaults.cameras.dependencies.all_cameras, )} ${this._renderOptionSelector( - getArrayConfigPath(CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS, cameraIndex), + getArrayConfigPath(CONF_CAMERAS_ARRAY_DEPENDENCIES_CAMERAS, cameraIndex), dependentCameras, { multiple: true, diff --git a/src/localize/languages/en.json b/src/localize/languages/en.json index 484ade11..6d261706 100644 --- a/src/localize/languages/en.json +++ b/src/localize/languages/en.json @@ -15,8 +15,10 @@ "camera_entity": "Camera Entity", "camera_name": "Frigate camera name (Autodetected from entity)", "client_id": "Frigate client id (For >1 Frigate server)", - "dependent_cameras": "Show events for specific cameras with this camera", - "dependent_cameras_all": "Show events for all cameras with this camera", + "dependencies": { + "cameras": "Show events for specific cameras with this camera", + "all_cameras": "Show events for all cameras with this camera" + }, "id": "Unique id for this camera in this card", "label": "Frigate label/object filter", "frigate_url": "Frigate server URL", diff --git a/src/types.ts b/src/types.ts index 9a21b5fa..0443c8b9 100644 --- a/src/types.ts +++ b/src/types.ts @@ -375,7 +375,10 @@ export const cameraConfigDefault = { trigger_by_motion: false, trigger_by_occupancy: true, trigger_by_entities: [], - dependent_cameras_all: false, + dependencies: { + all_cameras: false, + cameras: [], + }, }; const webrtcCardCameraConfigSchema = z.object({ entity: z.string().optional(), @@ -404,11 +407,12 @@ const cameraConfigSchema = z // Camera identifiers for WebRTC. webrtc_card: webrtcCardCameraConfigSchema.optional(), - // Set of cameras IDs upon which this camera depends. - dependent_cameras: z.string().array().optional(), - dependent_cameras_all: z - .boolean() - .default(cameraConfigDefault.dependent_cameras_all), + dependencies: z + .object({ + all_cameras: z.boolean().default(cameraConfigDefault.dependencies.all_cameras), + cameras: z.string().array().default(cameraConfigDefault.dependencies.cameras), + }) + .default(cameraConfigDefault.dependencies), trigger_by_motion: z.boolean().default(cameraConfigDefault.trigger_by_motion), trigger_by_occupancy: z.boolean().default(cameraConfigDefault.trigger_by_occupancy), diff --git a/src/utils/ha/browse-media.ts b/src/utils/ha/browse-media.ts index 497fdb7b..95fc561c 100644 --- a/src/utils/ha/browse-media.ts +++ b/src/utils/ha/browse-media.ts @@ -265,10 +265,10 @@ export const getFullDependentBrowseMediaQueryParameters = ( if (cameraConfig) { cameraIDs.add(camera); const dependentCameras: Set = new Set(); - (cameraConfig.dependent_cameras || []).forEach((item) => + (cameraConfig.dependencies.cameras || []).forEach((item) => dependentCameras.add(item), ); - if (cameraConfig.dependent_cameras_all) { + if (cameraConfig.dependencies.all_cameras) { cameras.forEach((_, key) => dependentCameras.add(key)); } for (const eventCameraID of dependentCameras) { From 6213e6d417a99ded43f00b13639afb1fa113380a Mon Sep 17 00:00:00 2001 From: Dermot Duffy Date: Fri, 10 Jun 2022 09:16:20 -0700 Subject: [PATCH 3/3] Fix missed reference. --- README.md | 2 +- src/card.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index f2b2b63e..cdf38f2f 100644 --- a/README.md +++ b/README.md @@ -2495,7 +2495,7 @@ cameras:
Expand: Using all dependent cameras with birdseye -This example shows events for all other cameras when `birdseye` is selected. This is just a shortcut to naming all other cameras. +This example shows events for all other cameras when `birdseye` is selected. This is just a shortcut for naming all other cameras. ```yaml [...] diff --git a/src/card.ts b/src/card.ts index d56b09f3..33252401 100644 --- a/src/card.ts +++ b/src/card.ts @@ -398,8 +398,8 @@ export class FrigateCard extends LitElement { if ( cameraConfig?.camera_name && (cameraConfig?.camera_name !== CAMERA_BIRDSEYE || - cameraConfig?.dependent_cameras?.length || - cameraConfig?.dependent_cameras_all) + cameraConfig.dependencies.cameras.length || + cameraConfig.dependencies.all_cameras) ) { buttons.push({ icon: 'mdi:filmstrip', @@ -417,8 +417,8 @@ export class FrigateCard extends LitElement { if ( cameraConfig?.camera_name && (cameraConfig?.camera_name !== CAMERA_BIRDSEYE || - cameraConfig?.dependent_cameras?.length || - cameraConfig?.dependent_cameras_all) + cameraConfig?.dependencies.cameras.length || + cameraConfig?.dependencies.all_cameras) ) { buttons.push({ icon: 'mdi:camera',