From 8163afce79f33d7da465cfabce9b68f761e68f90 Mon Sep 17 00:00:00 2001 From: banthungprong <59219161+banthungprong@users.noreply.github.com> Date: Wed, 2 Nov 2022 12:41:44 +0100 Subject: [PATCH] Allow cameras to be disabled in config (#4162) * add option enabled for each camera in config * Simplified If-block and removed wrong Optional * Update Docs enabling/disabling camera in config * correct format for option * Disabling Camera for processes, no config changes * Describe effects of disabled cam in documentation * change if-logic, obsolete copy, info disabled cam * changed color to white, added top padding in disabled camera info * changed indentation --- docs/docs/configuration/cameras.md | 5 ++++- docs/docs/configuration/index.md | 4 ++++ frigate/app.py | 8 ++++++++ frigate/config.py | 6 +++--- web/src/components/CameraImage.jsx | 21 ++++++++++++++------- 5 files changed, 33 insertions(+), 11 deletions(-) diff --git a/docs/docs/configuration/cameras.md b/docs/docs/configuration/cameras.md index 9784d44e4..cbd03d541 100644 --- a/docs/docs/configuration/cameras.md +++ b/docs/docs/configuration/cameras.md @@ -7,6 +7,8 @@ title: Cameras Several inputs can be configured for each camera and the role of each input can be mixed and matched based on your needs. This allows you to use a lower resolution stream for object detection, but create recordings from a higher resolution stream, or vice versa. +A camera is enabled by default but can be temporarily disabled by using `enabled: False`. Existing events and recordings can still be accessed. Live streams, recording and detecting are not working. Camera specific configurations will be used. + Each role can only be assigned to one input per camera. The options for roles are as follows: | Role | Description | @@ -21,6 +23,7 @@ mqtt: host: mqtt.server.com cameras: back: + enabled: True ffmpeg: inputs: - path: rtsp://viewer:{FRIGATE_RTSP_PASSWORD}@10.0.10.10:554/cam/realmonitor?channel=1&subtype=2 @@ -45,4 +48,4 @@ cameras: side: ... ``` -For camera model specific settings check the [camera specific](/configuration/camera_specific) infos. \ No newline at end of file +For camera model specific settings check the [camera specific](/configuration/camera_specific) infos. diff --git a/docs/docs/configuration/index.md b/docs/docs/configuration/index.md index 6a401bb1e..97f276232 100644 --- a/docs/docs/configuration/index.md +++ b/docs/docs/configuration/index.md @@ -387,6 +387,10 @@ timestamp_style: cameras: # Required: name of the camera back: + # Optional: Enable/Disable the camera (default: shown below). + # If disabled: config is used but no live stream and no capture etc. + # Events/Recordings are still viewable. + enabled: True # Required: ffmpeg settings for the camera ffmpeg: # Required: A list of input streams for the camera. See documentation for more information. diff --git a/frigate/app.py b/frigate/app.py index 1ea64ef3b..2ea4769c1 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -255,6 +255,10 @@ class FrigateApp: def start_camera_processors(self) -> None: model_shape = (self.config.model.height, self.config.model.width) for name, config in self.config.cameras.items(): + if not self.config.cameras[name].enabled: + logger.info(f"Camera processor not started for disabled camera {name}") + continue + camera_process = mp.Process( target=track_camera, name=f"camera_processor:{name}", @@ -276,6 +280,10 @@ class FrigateApp: def start_camera_capture_processes(self) -> None: for name, config in self.config.cameras.items(): + if not self.config.cameras[name].enabled: + logger.info(f"Capture process not started for disabled camera {name}") + continue + capture_process = mp.Process( target=capture_camera, name=f"camera_capture:{name}", diff --git a/frigate/config.py b/frigate/config.py index 9c551892f..39fa60224 100644 --- a/frigate/config.py +++ b/frigate/config.py @@ -541,6 +541,7 @@ class CameraUiConfig(FrigateBaseModel): class CameraConfig(FrigateBaseModel): name: Optional[str] = Field(title="Camera name.", regex="^[a-zA-Z0-9_-]+$") + enabled: bool = Field(default=True, title="Enable camera.") ffmpeg: CameraFfmpegConfig = Field(title="FFmpeg configuration for the camera.") best_image_timeout: int = Field( default=60, @@ -819,7 +820,7 @@ class FrigateConfig(FrigateBaseModel): if config.mqtt.password: config.mqtt.password = config.mqtt.password.format(**FRIGATE_ENV_VARS) - # Global config to propegate down to camera level + # Global config to propagate down to camera level global_config = config.dict( include={ "birdseye": ..., @@ -940,10 +941,9 @@ class FrigateConfig(FrigateBaseModel): logger.warning( f"{name}: Recording retention is configured for {camera_config.record.retain.mode} and event retention is configured for {camera_config.record.events.retain.mode}. The more restrictive retention policy will be applied." ) - # generage the ffmpeg commands + # generate the ffmpeg commands camera_config.create_ffmpeg_cmds() config.cameras[name] = camera_config - return config @validator("cameras") diff --git a/web/src/components/CameraImage.jsx b/web/src/components/CameraImage.jsx index 6da88f218..d11054db9 100644 --- a/web/src/components/CameraImage.jsx +++ b/web/src/components/CameraImage.jsx @@ -14,6 +14,7 @@ export default function CameraImage({ camera, onload, searchParams = '', stretch const [{ width: availableWidth }] = useResizeObserver(containerRef); const { name } = config ? config.cameras[camera] : ''; + const enabled = config ? config.cameras[camera].enabled : 'True'; const { width, height } = config ? config.cameras[camera].detect : { width: 1, height: 1 }; const aspectRatio = width / height; @@ -45,12 +46,18 @@ export default function CameraImage({ camera, onload, searchParams = '', stretch return (