Add a new convenience option to depend on all other cameras.

This commit is contained in:
Dermot Duffy
2022-06-10 09:10:42 -07:00
parent 40be446c69
commit 14bbb26e95
6 changed files with 73 additions and 30 deletions
+45 -11
View File
@@ -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. | | `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. | | `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). | | `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.| | `dependencies` | | :heavy_multiplication_x: | Other cameras that this camera should depend upon. See [camera dependencies](#camera-dependency-configuration) below. |
| `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_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_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.| | `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. See [Using the WebRTC Card](#webrtc) below for more details on how to use the WebRTC Card live provider.
<a name="camera-dependencies"></a>
#### 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.|
<a name="camera-ids"></a> <a name="camera-ids"></a>
#### Camera IDs: Refering to cameras in card configuration #### 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 #### Example
@@ -1012,9 +1027,10 @@ cameras:
camera_entity: camera.front_Door camera_entity: camera.front_Door
live_provider: ha live_provider: ha
# Show events for camera-2 when this camera is viewed. # Show events for camera-2 when this camera is viewed.
dependent_cameras: dependencies:
- camera-2 all_cameras: false
dependent_cameras_all: false cameras:
- camera-2
trigger_by_motion: false trigger_by_motion: false
trigger_by_occupancy: true trigger_by_occupancy: true
trigger_by_entities: trigger_by_entities:
@@ -1037,7 +1053,8 @@ cameras:
trigger_by_occupancy: true trigger_by_occupancy: true
trigger_by_entities: trigger_by_entities:
- binary_sensor.entrance_sensor - binary_sensor.entrance_sensor
dependent_cameras_all: false dependencies:
all_cameras: false
``` ```
</details> </details>
@@ -2455,7 +2472,7 @@ menu:
### Using a dependent camera ### 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).
<details> <details>
<summary>Expand: Using dependent cameras with birdseye</summary> <summary>Expand: Using dependent cameras with birdseye</summary>
@@ -2468,9 +2485,26 @@ cameras:
- camera_entity: camera.kitchen - camera_entity: camera.kitchen
- camera_entity: camera.sitting_room - camera_entity: camera.sitting_room
- camera_name: birdseye - camera_name: birdseye
dependent_cameras: dependencies:
- camera.kitchen cameras:
- camera.sitting_room - camera.kitchen
- camera.sitting_room
```
</details>
<details>
<summary>Expand: Using all dependent cameras with birdseye</summary>
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
``` ```
</details> </details>
+4 -4
View File
@@ -21,10 +21,10 @@ export const CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL =
`${CONF_CAMERAS}.#.webrtc_card.url` as const; `${CONF_CAMERAS}.#.webrtc_card.url` as const;
export const CONF_CAMERAS_ARRAY_LIVE_PROVIDER = export const CONF_CAMERAS_ARRAY_LIVE_PROVIDER =
`${CONF_CAMERAS}.#.live_provider` as const; `${CONF_CAMERAS}.#.live_provider` as const;
export const CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS = export const CONF_CAMERAS_ARRAY_DEPENDENCIES_CAMERAS =
`${CONF_CAMERAS}.#.dependent_cameras` as const; `${CONF_CAMERAS}.#.dependencies.cameras` as const;
export const CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS_ALL = export const CONF_CAMERAS_ARRAY_DEPENDENCIES_ALL_CAMERAS =
`${CONF_CAMERAS}.#.dependent_cameras_all` as const; `${CONF_CAMERAS}.#.dependencies.all_cameras` as const;
export const CONF_CAMERAS_ARRAY_TRIGGER_BY_MOTION = export const CONF_CAMERAS_ARRAY_TRIGGER_BY_MOTION =
`${CONF_CAMERAS}.#.trigger_by_motion` as const; `${CONF_CAMERAS}.#.trigger_by_motion` as const;
export const CONF_CAMERAS_ARRAY_TRIGGER_BY_OCCUPANCY = export const CONF_CAMERAS_ARRAY_TRIGGER_BY_OCCUPANCY =
+8 -5
View File
@@ -16,8 +16,8 @@ import {
CONF_CAMERAS_ARRAY_CAMERA_ENTITY, CONF_CAMERAS_ARRAY_CAMERA_ENTITY,
CONF_CAMERAS_ARRAY_CAMERA_NAME, CONF_CAMERAS_ARRAY_CAMERA_NAME,
CONF_CAMERAS_ARRAY_CLIENT_ID, CONF_CAMERAS_ARRAY_CLIENT_ID,
CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS, CONF_CAMERAS_ARRAY_DEPENDENCIES_ALL_CAMERAS,
CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS_ALL, CONF_CAMERAS_ARRAY_DEPENDENCIES_CAMERAS,
CONF_CAMERAS_ARRAY_ICON, CONF_CAMERAS_ARRAY_ICON,
CONF_CAMERAS_ARRAY_ID, CONF_CAMERAS_ARRAY_ID,
CONF_CAMERAS_ARRAY_LABEL, CONF_CAMERAS_ARRAY_LABEL,
@@ -884,11 +884,14 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, cameraIndex), getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, cameraIndex),
)} )}
${this._renderSwitch( ${this._renderSwitch(
getArrayConfigPath(CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS_ALL, cameraIndex), getArrayConfigPath(
frigateCardConfigDefaults.cameras.dependent_cameras_all, CONF_CAMERAS_ARRAY_DEPENDENCIES_ALL_CAMERAS,
cameraIndex,
),
frigateCardConfigDefaults.cameras.dependencies.all_cameras,
)} )}
${this._renderOptionSelector( ${this._renderOptionSelector(
getArrayConfigPath(CONF_CAMERAS_ARRAY_DEPENDENT_CAMERAS, cameraIndex), getArrayConfigPath(CONF_CAMERAS_ARRAY_DEPENDENCIES_CAMERAS, cameraIndex),
dependentCameras, dependentCameras,
{ {
multiple: true, multiple: true,
+4 -2
View File
@@ -15,8 +15,10 @@
"camera_entity": "Camera Entity", "camera_entity": "Camera Entity",
"camera_name": "Frigate camera name (Autodetected from entity)", "camera_name": "Frigate camera name (Autodetected from entity)",
"client_id": "Frigate client id (For >1 Frigate server)", "client_id": "Frigate client id (For >1 Frigate server)",
"dependent_cameras": "Show events for specific cameras with this camera", "dependencies": {
"dependent_cameras_all": "Show events for all cameras with this camera", "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", "id": "Unique id for this camera in this card",
"label": "Frigate label/object filter", "label": "Frigate label/object filter",
"frigate_url": "Frigate server URL", "frigate_url": "Frigate server URL",
+10 -6
View File
@@ -375,7 +375,10 @@ export const cameraConfigDefault = {
trigger_by_motion: false, trigger_by_motion: false,
trigger_by_occupancy: true, trigger_by_occupancy: true,
trigger_by_entities: [], trigger_by_entities: [],
dependent_cameras_all: false, dependencies: {
all_cameras: false,
cameras: [],
},
}; };
const webrtcCardCameraConfigSchema = z.object({ const webrtcCardCameraConfigSchema = z.object({
entity: z.string().optional(), entity: z.string().optional(),
@@ -404,11 +407,12 @@ const cameraConfigSchema = z
// Camera identifiers for WebRTC. // Camera identifiers for WebRTC.
webrtc_card: webrtcCardCameraConfigSchema.optional(), webrtc_card: webrtcCardCameraConfigSchema.optional(),
// Set of cameras IDs upon which this camera depends. dependencies: z
dependent_cameras: z.string().array().optional(), .object({
dependent_cameras_all: z all_cameras: z.boolean().default(cameraConfigDefault.dependencies.all_cameras),
.boolean() cameras: z.string().array().default(cameraConfigDefault.dependencies.cameras),
.default(cameraConfigDefault.dependent_cameras_all), })
.default(cameraConfigDefault.dependencies),
trigger_by_motion: z.boolean().default(cameraConfigDefault.trigger_by_motion), trigger_by_motion: z.boolean().default(cameraConfigDefault.trigger_by_motion),
trigger_by_occupancy: z.boolean().default(cameraConfigDefault.trigger_by_occupancy), trigger_by_occupancy: z.boolean().default(cameraConfigDefault.trigger_by_occupancy),
+2 -2
View File
@@ -265,10 +265,10 @@ export const getFullDependentBrowseMediaQueryParameters = (
if (cameraConfig) { if (cameraConfig) {
cameraIDs.add(camera); cameraIDs.add(camera);
const dependentCameras: Set<string> = new Set(); const dependentCameras: Set<string> = new Set();
(cameraConfig.dependent_cameras || []).forEach((item) => (cameraConfig.dependencies.cameras || []).forEach((item) =>
dependentCameras.add(item), dependentCameras.add(item),
); );
if (cameraConfig.dependent_cameras_all) { if (cameraConfig.dependencies.all_cameras) {
cameras.forEach((_, key) => dependentCameras.add(key)); cameras.forEach((_, key) => dependentCameras.add(key));
} }
for (const eventCameraID of dependentCameras) { for (const eventCameraID of dependentCameras) {