Add support back for setting record via MQTT and WS

This commit is contained in:
Nick Mowen 2023-04-25 10:07:58 -06:00
parent bab1e502a8
commit 04655f0bc4
5 changed files with 32 additions and 9 deletions

View File

@ -35,7 +35,7 @@ from frigate.timeline import TimelineProcessor
from frigate.version import VERSION from frigate.version import VERSION
from frigate.video import capture_camera, track_camera from frigate.video import capture_camera, track_camera
from frigate.watchdog import FrigateWatchdog from frigate.watchdog import FrigateWatchdog
from frigate.types import CameraMetricsTypes from frigate.types import CameraMetricsTypes, RecordMetricsTypes
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -50,6 +50,7 @@ class FrigateApp:
self.log_queue: Queue = mp.Queue() self.log_queue: Queue = mp.Queue()
self.plus_api = PlusApi() self.plus_api = PlusApi()
self.camera_metrics: dict[str, CameraMetricsTypes] = {} self.camera_metrics: dict[str, CameraMetricsTypes] = {}
self.record_metrics: dict[str, RecordMetricsTypes] = {}
def set_environment_vars(self) -> None: def set_environment_vars(self) -> None:
for key, value in self.config.environment_vars.items(): for key, value in self.config.environment_vars.items():
@ -109,6 +110,11 @@ class FrigateApp:
"capture_process": None, "capture_process": None,
"process": None, "process": None,
} }
self.record_metrics[camera_name] = {
"record_enabled": mp.Value(
"i", self.config.cameras[camera_name].record.enabled
)
}
def set_log_levels(self) -> None: def set_log_levels(self) -> None:
logging.getLogger().setLevel(self.config.logger.default.value.upper()) logging.getLogger().setLevel(self.config.logger.default.value.upper())
@ -162,7 +168,7 @@ class FrigateApp:
recording_process = mp.Process( recording_process = mp.Process(
target=manage_recordings, target=manage_recordings,
name="recording_manager", name="recording_manager",
args=(self.config, self.recordings_info_queue), args=(self.config, self.recordings_info_queue, self.record_metrics),
) )
recording_process.daemon = True recording_process.daemon = True
self.recording_process = recording_process self.recording_process = recording_process
@ -203,7 +209,7 @@ class FrigateApp:
comms.append(WebSocketClient(self.config)) comms.append(WebSocketClient(self.config))
self.dispatcher = Dispatcher( self.dispatcher = Dispatcher(
self.config, self.onvif_controller, self.camera_metrics, comms self.config, self.onvif_controller, self.camera_metrics, self.record_metrics, comms
) )
def start_detectors(self) -> None: def start_detectors(self) -> None:

View File

@ -7,8 +7,12 @@ from typing import Any, Callable
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from frigate.config import FrigateConfig from frigate.config import FrigateConfig
<<<<<<< HEAD
from frigate.ptz import OnvifController, OnvifCommandEnum from frigate.ptz import OnvifController, OnvifCommandEnum
from frigate.types import CameraMetricsTypes from frigate.types import CameraMetricsTypes
=======
from frigate.types import CameraMetricsTypes, RecordMetricsTypes
>>>>>>> ab49f2f7 (Add support back for setting record via MQTT and WS)
from frigate.util import restart_frigate from frigate.util import restart_frigate
@ -42,11 +46,13 @@ class Dispatcher:
config: FrigateConfig, config: FrigateConfig,
onvif: OnvifController, onvif: OnvifController,
camera_metrics: dict[str, CameraMetricsTypes], camera_metrics: dict[str, CameraMetricsTypes],
record_metrics: dict[str, RecordMetricsTypes],
communicators: list[Communicator], communicators: list[Communicator],
) -> None: ) -> None:
self.config = config self.config = config
self.onvif = onvif self.onvif = onvif
self.camera_metrics = camera_metrics self.camera_metrics = camera_metrics
self.record_metrics = record_metrics
self.comms = communicators self.comms = communicators
for comm in self.comms: for comm in self.comms:
@ -192,13 +198,15 @@ class Dispatcher:
record_settings = self.config.cameras[camera_name].record record_settings = self.config.cameras[camera_name].record
if payload == "ON": if payload == "ON":
if not record_settings.enabled: if not self.record_metrics[camera_name]["record_enabled"].value:
logger.info(f"Turning on recordings for {camera_name}") logger.info(f"Turning on recordings for {camera_name}")
record_settings.enabled = True record_settings.enabled = True
self.record_metrics[camera_name]["record_enabled"].value = True
elif payload == "OFF": elif payload == "OFF":
if record_settings.enabled: if self.record_metrics[camera_name]["record_enabled"].value:
logger.info(f"Turning off recordings for {camera_name}") logger.info(f"Turning off recordings for {camera_name}")
record_settings.enabled = False record_settings.enabled = False
self.record_metrics[camera_name]["record_enabled"].value = False
self.publish(f"{camera_name}/recordings/state", payload, retain=True) self.publish(f"{camera_name}/recordings/state", payload, retain=True)

View File

@ -19,6 +19,7 @@ from typing import Any, Tuple
from frigate.config import RetainModeEnum, FrigateConfig from frigate.config import RetainModeEnum, FrigateConfig
from frigate.const import CACHE_DIR, MAX_SEGMENT_DURATION, RECORD_DIR from frigate.const import CACHE_DIR, MAX_SEGMENT_DURATION, RECORD_DIR
from frigate.models import Event, Recordings from frigate.models import Event, Recordings
from frigate.types import RecordMetricsTypes
from frigate.util import area from frigate.util import area
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -29,12 +30,14 @@ class RecordingMaintainer(threading.Thread):
self, self,
config: FrigateConfig, config: FrigateConfig,
recordings_info_queue: mp.Queue, recordings_info_queue: mp.Queue,
process_info: dict[str, RecordMetricsTypes],
stop_event: MpEvent, stop_event: MpEvent,
): ):
threading.Thread.__init__(self) threading.Thread.__init__(self)
self.name = "recording_maint" self.name = "recording_maintainer"
self.config = config self.config = config
self.recordings_info_queue = recordings_info_queue self.recordings_info_queue = recordings_info_queue
self.process_info = process_info
self.stop_event = stop_event self.stop_event = stop_event
self.recordings_info: dict[str, Any] = defaultdict(list) self.recordings_info: dict[str, Any] = defaultdict(list)
self.end_time_cache: dict[str, Tuple[datetime.datetime, float]] = {} self.end_time_cache: dict[str, Tuple[datetime.datetime, float]] = {}
@ -125,7 +128,7 @@ class RecordingMaintainer(threading.Thread):
# Just delete files if recordings are turned off # Just delete files if recordings are turned off
if ( if (
not camera in self.config.cameras not camera in self.config.cameras
or not self.config.cameras[camera].record.enabled or not self.process_info[camera]["record_enabled"].value
): ):
Path(cache_path).unlink(missing_ok=True) Path(cache_path).unlink(missing_ok=True)
self.end_time_cache.pop(cache_path, None) self.end_time_cache.pop(cache_path, None)
@ -369,7 +372,7 @@ class RecordingMaintainer(threading.Thread):
regions, regions,
) = self.recordings_info_queue.get(False) ) = self.recordings_info_queue.get(False)
if self.config.cameras[camera].record.enabled: if self.process_info[camera]["record_enabled"].value:
self.recordings_info[camera].append( self.recordings_info[camera].append(
( (
frame_time, frame_time,

View File

@ -15,6 +15,7 @@ from frigate.config import FrigateConfig
from frigate.models import Event, Recordings, Timeline from frigate.models import Event, Recordings, Timeline
from frigate.record.cleanup import RecordingCleanup from frigate.record.cleanup import RecordingCleanup
from frigate.record.maintainer import RecordingMaintainer from frigate.record.maintainer import RecordingMaintainer
from frigate.types import RecordMetricsTypes
from frigate.util import listen from frigate.util import listen
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -23,6 +24,7 @@ logger = logging.getLogger(__name__)
def manage_recordings( def manage_recordings(
config: FrigateConfig, config: FrigateConfig,
recordings_info_queue: mp.Queue, recordings_info_queue: mp.Queue,
process_info: dict[str, RecordMetricsTypes],
) -> None: ) -> None:
stop_event = mp.Event() stop_event = mp.Event()
@ -40,7 +42,7 @@ def manage_recordings(
models = [Event, Recordings, Timeline] models = [Event, Recordings, Timeline]
db.bind(models) db.bind(models)
maintainer = RecordingMaintainer(config, recordings_info_queue, stop_event) maintainer = RecordingMaintainer(config, recordings_info_queue, process_info, stop_event)
maintainer.start() maintainer.start()
cleanup = RecordingCleanup(config, stop_event) cleanup = RecordingCleanup(config, stop_event)

View File

@ -24,6 +24,10 @@ class CameraMetricsTypes(TypedDict):
skipped_fps: Synchronized skipped_fps: Synchronized
class RecordMetricsTypes(TypedDict):
record_enabled: Synchronized
class StatsTrackingTypes(TypedDict): class StatsTrackingTypes(TypedDict):
camera_metrics: dict[str, CameraMetricsTypes] camera_metrics: dict[str, CameraMetricsTypes]
detectors: dict[str, ObjectDetectProcess] detectors: dict[str, ObjectDetectProcess]