Merge pull request #655 from dermotduffy/dependent-camera-all
Add a new convenience option for a camera to depend on all others
This commit is contained in:
@@ -113,7 +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. |
|
||||||
| `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.|
|
||||||
@@ -146,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
|
||||||
|
|
||||||
@@ -1011,8 +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
|
||||||
|
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:
|
||||||
@@ -1035,6 +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
|
||||||
|
dependencies:
|
||||||
|
all_cameras: false
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
@@ -2452,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>
|
||||||
@@ -2465,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 for naming all other cameras.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
[...]
|
||||||
|
cameras:
|
||||||
|
- camera_entity: camera.kitchen
|
||||||
|
- camera_entity: camera.sitting_room
|
||||||
|
- camera_name: birdseye
|
||||||
|
dependencies:
|
||||||
|
all_cameras: true
|
||||||
```
|
```
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|||||||
+11
-9
@@ -5,7 +5,7 @@ import {
|
|||||||
LitElement,
|
LitElement,
|
||||||
PropertyValues,
|
PropertyValues,
|
||||||
TemplateResult,
|
TemplateResult,
|
||||||
unsafeCSS,
|
unsafeCSS
|
||||||
} from 'lit';
|
} from 'lit';
|
||||||
import { customElement, property, state } from 'lit/decorators.js';
|
import { customElement, property, state } from 'lit/decorators.js';
|
||||||
import { classMap } from 'lit/directives/class-map.js';
|
import { classMap } from 'lit/directives/class-map.js';
|
||||||
@@ -20,7 +20,7 @@ import {
|
|||||||
ConditionState,
|
ConditionState,
|
||||||
conditionStateRequestHandler,
|
conditionStateRequestHandler,
|
||||||
getOverriddenConfig,
|
getOverriddenConfig,
|
||||||
getOverridesByKey,
|
getOverridesByKey
|
||||||
} from './card-condition.js';
|
} from './card-condition.js';
|
||||||
import './components/elements.js';
|
import './components/elements.js';
|
||||||
import { FrigateCardElements } from './components/elements.js';
|
import { FrigateCardElements } from './components/elements.js';
|
||||||
@@ -40,7 +40,7 @@ import {
|
|||||||
CAMERA_BIRDSEYE,
|
CAMERA_BIRDSEYE,
|
||||||
CARD_VERSION,
|
CARD_VERSION,
|
||||||
MEDIA_PLAYER_SUPPORT_BROWSE_MEDIA,
|
MEDIA_PLAYER_SUPPORT_BROWSE_MEDIA,
|
||||||
REPO_URL,
|
REPO_URL
|
||||||
} from './const.js';
|
} from './const.js';
|
||||||
import './editor.js';
|
import './editor.js';
|
||||||
import { localize } from './localize/localize.js';
|
import { localize } from './localize/localize.js';
|
||||||
@@ -63,14 +63,14 @@ import {
|
|||||||
MediaShowInfo,
|
MediaShowInfo,
|
||||||
MenuButton,
|
MenuButton,
|
||||||
Message,
|
Message,
|
||||||
RawFrigateCardConfig,
|
RawFrigateCardConfig
|
||||||
} from './types.js';
|
} from './types.js';
|
||||||
import {
|
import {
|
||||||
convertActionToFrigateCardCustomAction,
|
convertActionToFrigateCardCustomAction,
|
||||||
createFrigateCardCustomAction,
|
createFrigateCardCustomAction,
|
||||||
frigateCardHandleAction,
|
frigateCardHandleAction,
|
||||||
frigateCardHasAction,
|
frigateCardHasAction,
|
||||||
getActionConfigGivenAction,
|
getActionConfigGivenAction
|
||||||
} from './utils/action.js';
|
} from './utils/action.js';
|
||||||
import { contentsChanged } from './utils/basic.js';
|
import { contentsChanged } from './utils/basic.js';
|
||||||
import { getCameraIcon, getCameraID, getCameraTitle } from './utils/camera.js';
|
import { getCameraIcon, getCameraID, getCameraTitle } from './utils/camera.js';
|
||||||
@@ -81,7 +81,7 @@ import {
|
|||||||
homeAssistantSignPath,
|
homeAssistantSignPath,
|
||||||
isHassDifferent,
|
isHassDifferent,
|
||||||
isTriggeredState,
|
isTriggeredState,
|
||||||
sideLoadHomeAssistantElements,
|
sideLoadHomeAssistantElements
|
||||||
} from './utils/ha';
|
} from './utils/ha';
|
||||||
import { getEventID } from './utils/ha/browse-media.js';
|
import { getEventID } from './utils/ha/browse-media.js';
|
||||||
import { DeviceList, getAllDevices } from './utils/ha/device-registry.js';
|
import { DeviceList, getAllDevices } from './utils/ha/device-registry.js';
|
||||||
@@ -89,7 +89,7 @@ import {
|
|||||||
ExtendedEntityCache,
|
ExtendedEntityCache,
|
||||||
getAllEntities,
|
getAllEntities,
|
||||||
getExtendedEntities,
|
getExtendedEntities,
|
||||||
getExtendedEntity,
|
getExtendedEntity
|
||||||
} from './utils/ha/entity-registry.js';
|
} from './utils/ha/entity-registry.js';
|
||||||
import { ResolvedMediaCache } from './utils/ha/resolved-media.js';
|
import { ResolvedMediaCache } from './utils/ha/resolved-media.js';
|
||||||
import { supportsFeature } from './utils/ha/update.js';
|
import { supportsFeature } from './utils/ha/update.js';
|
||||||
@@ -398,7 +398,8 @@ export class FrigateCard extends LitElement {
|
|||||||
if (
|
if (
|
||||||
cameraConfig?.camera_name &&
|
cameraConfig?.camera_name &&
|
||||||
(cameraConfig?.camera_name !== CAMERA_BIRDSEYE ||
|
(cameraConfig?.camera_name !== CAMERA_BIRDSEYE ||
|
||||||
cameraConfig?.dependent_cameras?.length)
|
cameraConfig.dependencies.cameras.length ||
|
||||||
|
cameraConfig.dependencies.all_cameras)
|
||||||
) {
|
) {
|
||||||
buttons.push({
|
buttons.push({
|
||||||
icon: 'mdi:filmstrip',
|
icon: 'mdi:filmstrip',
|
||||||
@@ -416,7 +417,8 @@ export class FrigateCard extends LitElement {
|
|||||||
if (
|
if (
|
||||||
cameraConfig?.camera_name &&
|
cameraConfig?.camera_name &&
|
||||||
(cameraConfig?.camera_name !== CAMERA_BIRDSEYE ||
|
(cameraConfig?.camera_name !== CAMERA_BIRDSEYE ||
|
||||||
cameraConfig?.dependent_cameras?.length)
|
cameraConfig?.dependencies.cameras.length ||
|
||||||
|
cameraConfig?.dependencies.all_cameras)
|
||||||
) {
|
) {
|
||||||
buttons.push({
|
buttons.push({
|
||||||
icon: 'mdi:camera',
|
icon: 'mdi:camera',
|
||||||
|
|||||||
+4
-2
@@ -21,8 +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_DEPENDENCIES_ALL_CAMERAS =
|
||||||
|
`${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 =
|
||||||
|
|||||||
+10
-2
@@ -16,7 +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_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,
|
||||||
@@ -882,8 +883,15 @@ export class FrigateCardEditor extends LitElement implements LovelaceCardEditor
|
|||||||
${this._renderStringInput(
|
${this._renderStringInput(
|
||||||
getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, cameraIndex),
|
getArrayConfigPath(CONF_CAMERAS_ARRAY_WEBRTC_CARD_URL, cameraIndex),
|
||||||
)}
|
)}
|
||||||
|
${this._renderSwitch(
|
||||||
|
getArrayConfigPath(
|
||||||
|
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,
|
||||||
|
|||||||
@@ -15,7 +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": "Dependent cameras to also show events for",
|
"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",
|
"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",
|
||||||
|
|||||||
+14
-3
@@ -375,6 +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: [],
|
||||||
|
dependencies: {
|
||||||
|
all_cameras: false,
|
||||||
|
cameras: [],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
const webrtcCardCameraConfigSchema = z.object({
|
const webrtcCardCameraConfigSchema = z.object({
|
||||||
entity: z.string().optional(),
|
entity: z.string().optional(),
|
||||||
@@ -403,8 +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({
|
||||||
|
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_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),
|
||||||
@@ -1015,7 +1023,10 @@ const timelineConfigSchema = z
|
|||||||
.max(24 * 60 * 60)
|
.max(24 * 60 * 60)
|
||||||
.optional()
|
.optional()
|
||||||
.default(timelineConfigDefault.window_seconds),
|
.default(timelineConfigDefault.window_seconds),
|
||||||
show_recordings: z.boolean().optional().default(timelineConfigDefault.show_recordings),
|
show_recordings: z
|
||||||
|
.boolean()
|
||||||
|
.optional()
|
||||||
|
.default(timelineConfigDefault.show_recordings),
|
||||||
controls: z
|
controls: z
|
||||||
.object({
|
.object({
|
||||||
thumbnails: thumbnailsControlSchema
|
thumbnails: thumbnailsControlSchema
|
||||||
|
|||||||
@@ -264,7 +264,14 @@ export const getFullDependentBrowseMediaQueryParameters = (
|
|||||||
const cameraConfig = cameras.get(camera);
|
const cameraConfig = cameras.get(camera);
|
||||||
if (cameraConfig) {
|
if (cameraConfig) {
|
||||||
cameraIDs.add(camera);
|
cameraIDs.add(camera);
|
||||||
for (const eventCameraID of cameraConfig.dependent_cameras || []) {
|
const dependentCameras: Set<string> = new Set();
|
||||||
|
(cameraConfig.dependencies.cameras || []).forEach((item) =>
|
||||||
|
dependentCameras.add(item),
|
||||||
|
);
|
||||||
|
if (cameraConfig.dependencies.all_cameras) {
|
||||||
|
cameras.forEach((_, key) => dependentCameras.add(key));
|
||||||
|
}
|
||||||
|
for (const eventCameraID of dependentCameras) {
|
||||||
if (!cameraIDs.has(eventCameraID)) {
|
if (!cameraIDs.has(eventCameraID)) {
|
||||||
getDependentCameras(eventCameraID);
|
getDependentCameras(eventCameraID);
|
||||||
}
|
}
|
||||||
@@ -281,12 +288,9 @@ export const getFullDependentBrowseMediaQueryParameters = (
|
|||||||
cameras.get(cameraID),
|
cameras.get(cameraID),
|
||||||
mediaType ? { mediaType: mediaType } : {},
|
mediaType ? { mediaType: mediaType } : {},
|
||||||
);
|
);
|
||||||
// Fail on a single bad camera, as it's almost certainly a user error that
|
if (param) {
|
||||||
// should be fixed rather than hidden.
|
params.push(param);
|
||||||
if (!param) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
params.push(param);
|
|
||||||
}
|
}
|
||||||
return params.length ? params : null;
|
return params.length ? params : null;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user