mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-03 09:45:22 +03:00
Have a dispatcher which is responsible for handling and sending messages
This commit is contained in:
parent
407ed24d36
commit
f9eafb98ed
@ -1,21 +1,27 @@
|
||||
"""Handle communication between frigate and other applications."""
|
||||
|
||||
import logging
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
|
||||
from frigate.config import FrigateConfig
|
||||
from frigate.types import CameraMetricsTypes
|
||||
from frigate.util import restart_frigate
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Communicator(ABC):
|
||||
"""pub/sub model via specific protocol."""
|
||||
|
||||
@abstractmethod
|
||||
def publish(topic: str, payload, retain: bool = False):
|
||||
def publish(self, topic: str, payload, retain: bool = False):
|
||||
"""Send data via specific protocol."""
|
||||
pass
|
||||
|
||||
@abstractmethod
|
||||
def subscribe(receiver):
|
||||
def subscribe(self, receiver):
|
||||
pass
|
||||
|
||||
|
||||
@ -31,3 +37,163 @@ class Dispatcher:
|
||||
self.config = config
|
||||
self.camera_metrics = camera_metrics
|
||||
self.comms = communicators
|
||||
|
||||
for comm in self.comms:
|
||||
comm.subscribe(self._receive)
|
||||
|
||||
def _receive(self, topic: str, payload: str) -> None:
|
||||
"""Handle receiving of payload from communicators."""
|
||||
if "detect/set" in topic:
|
||||
camera_name = topic.split("/")[-3]
|
||||
self._on_detect_command(camera_name, payload)
|
||||
elif "improve_contrast/set" in topic:
|
||||
camera_name = topic.split("/")[-3]
|
||||
self._on_motion_improve_contrast_command(camera_name, payload)
|
||||
elif "motion/set" in topic:
|
||||
camera_name = topic.split("/")[-3]
|
||||
self._on_motion_command(camera_name, payload)
|
||||
elif "motion_contour_area/set":
|
||||
camera_name = topic.split("/")[-3]
|
||||
|
||||
try:
|
||||
value = int(payload)
|
||||
except ValueError:
|
||||
f"Received unsupported value at {topic}: {payload}"
|
||||
return
|
||||
|
||||
self._on_motion_contour_area_command(camera_name, value)
|
||||
elif "motion_threshold/set":
|
||||
camera_name = topic.split("/")[-3]
|
||||
|
||||
try:
|
||||
value = int(payload)
|
||||
except ValueError:
|
||||
f"Received unsupported value at {topic}: {payload}"
|
||||
return
|
||||
|
||||
self._on_motion_threshold_command(camera_name, value)
|
||||
elif "recordings/set" in topic:
|
||||
camera_name = topic.split("/")[-3]
|
||||
self._on_recordings_command(camera_name, payload)
|
||||
elif "snapshots/set" in topic:
|
||||
camera_name = topic.split("/")[-3]
|
||||
self._on_snapshots_command(camera_name, payload)
|
||||
elif topic == "restart":
|
||||
restart_frigate()
|
||||
|
||||
def publish(self, topic: str, payload, retain: bool = False) -> None:
|
||||
"""Handle publishing to communicators."""
|
||||
for comm in self.comms:
|
||||
comm.publish(topic, payload, retain)
|
||||
|
||||
def _on_detect_command(self, camera_name: str, payload: str) -> None:
|
||||
"""Callback for detect topic."""
|
||||
detect_settings = self.config.cameras[camera_name].detect
|
||||
|
||||
if payload == "ON":
|
||||
if not self.camera_metrics[camera_name]["detection_enabled"].value:
|
||||
logger.info(f"Turning on detection for {camera_name}")
|
||||
self.camera_metrics[camera_name]["detection_enabled"].value = True
|
||||
detect_settings.enabled = True
|
||||
|
||||
if not self.camera_metrics[camera_name]["motion_enabled"].value:
|
||||
logger.info(
|
||||
f"Turning on motion for {camera_name} due to detection being enabled."
|
||||
)
|
||||
self.camera_metrics[camera_name]["motion_enabled"].value = True
|
||||
self.publish(f"{camera_name}/motion/state", payload, retain=True)
|
||||
elif payload == "OFF":
|
||||
if self.camera_metrics[camera_name]["detection_enabled"].value:
|
||||
logger.info(f"Turning off detection for {camera_name} via mqtt")
|
||||
self.camera_metrics[camera_name]["detection_enabled"].value = False
|
||||
detect_settings.enabled = False
|
||||
|
||||
self.publish(f"{camera_name}/detect/state", payload, retain=True)
|
||||
|
||||
def _on_motion_command(self, camera_name: str, payload: str) -> None:
|
||||
"""Callback for motion topic."""
|
||||
if payload == "ON":
|
||||
if not self.camera_metrics[camera_name]["motion_enabled"].value:
|
||||
logger.info(f"Turning on motion for {camera_name} via mqtt")
|
||||
self.camera_metrics[camera_name]["motion_enabled"].value = True
|
||||
elif payload == "OFF":
|
||||
if self.camera_metrics[camera_name]["detection_enabled"].value:
|
||||
logger.error(
|
||||
f"Turning off motion is not allowed when detection is enabled."
|
||||
)
|
||||
return
|
||||
|
||||
if self.camera_metrics[camera_name]["motion_enabled"].value:
|
||||
logger.info(f"Turning off motion for {camera_name} via mqtt")
|
||||
self.camera_metrics[camera_name]["motion_enabled"].value = False
|
||||
|
||||
self.publish(f"{camera_name}/motion/state", payload, retain=True)
|
||||
|
||||
def _on_motion_improve_contrast_command(
|
||||
self, camera_name: str, payload: str
|
||||
) -> None:
|
||||
"""Callback for improve_contrast topic."""
|
||||
motion_settings = self.config.cameras[camera_name].motion
|
||||
|
||||
if payload == "ON":
|
||||
if not self.camera_metrics[camera_name]["improve_contrast_enabled"].value:
|
||||
logger.info(f"Turning on improve contrast for {camera_name}")
|
||||
self.camera_metrics[camera_name][
|
||||
"improve_contrast_enabled"
|
||||
].value = True
|
||||
motion_settings.improve_contrast = True
|
||||
elif payload == "OFF":
|
||||
if self.camera_metrics[camera_name]["improve_contrast_enabled"].value:
|
||||
logger.info(f"Turning off improve contrast for {camera_name}")
|
||||
self.camera_metrics[camera_name][
|
||||
"improve_contrast_enabled"
|
||||
].value = False
|
||||
motion_settings.improve_contrast = False
|
||||
|
||||
self.publish(f"{camera_name}/improve_contrast/state", payload, retain=True)
|
||||
|
||||
def _on_motion_contour_area_command(self, camera_name: str, payload: int) -> None:
|
||||
"""Callback for motion contour topic."""
|
||||
motion_settings = self.config.cameras[camera_name].motion
|
||||
logger.info(f"Setting motion contour area for {camera_name}: {payload}")
|
||||
self.camera_metrics[camera_name]["motion_contour_area"].value = payload
|
||||
motion_settings.contour_area = payload
|
||||
self.publish(f"{camera_name}/motion_contour_area/state", payload, retain=True)
|
||||
|
||||
def _on_motion_threshold_command(self, camera_name: str, payload: int) -> None:
|
||||
"""Callback for motion threshold topic."""
|
||||
motion_settings = self.config.cameras[camera_name].motion
|
||||
logger.info(f"Setting motion threshold for {camera_name}: {payload}")
|
||||
self.camera_metrics[camera_name]["motion_threshold"].value = payload
|
||||
motion_settings.threshold = payload
|
||||
self.publish(f"{camera_name}/motion_threshold/state", payload, retain=True)
|
||||
|
||||
def _on_recordings_command(self, camera_name: str, payload: str) -> None:
|
||||
"""Callback for recordings topic."""
|
||||
record_settings = self.config.cameras[camera_name].record
|
||||
|
||||
if payload == "ON":
|
||||
if not record_settings.enabled:
|
||||
logger.info(f"Turning on recordings for {camera_name}")
|
||||
record_settings.enabled = True
|
||||
elif payload == "OFF":
|
||||
if record_settings.enabled:
|
||||
logger.info(f"Turning off recordings for {camera_name}")
|
||||
record_settings.enabled = False
|
||||
|
||||
self.publish(f"{camera_name}/recordings/state", payload, retain=True)
|
||||
|
||||
def _on_snapshots_command(self, camera_name: str, payload: str) -> None:
|
||||
"""Callback for snapshots topic."""
|
||||
snapshots_settings = self.config.cameras[camera_name].snapshots
|
||||
|
||||
if payload == "ON":
|
||||
if not snapshots_settings.enabled:
|
||||
logger.info(f"Turning on snapshots for {camera_name}")
|
||||
snapshots_settings.enabled = True
|
||||
elif payload == "OFF":
|
||||
if snapshots_settings.enabled:
|
||||
logger.info(f"Turning off snapshots for {camera_name}")
|
||||
snapshots_settings.enabled = False
|
||||
|
||||
self.publish(f"{camera_name}/snapshots/state", payload, retain=True)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user