mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Ability to enable / disable motion detection via MQTT (#3117)
* Starting working on adding motion toggle * Add all info to mqtt command * Send motion to correct funs * Update mqtt docs * Fixes for contingencies * format * mypy * Tweak behavior * Fix motion breaking frames * Fix bad logic in detect set * Always set value for motion boxes
This commit is contained in:
parent
b75929a846
commit
0a4d658c7f
@ -118,6 +118,15 @@ Topic to turn snapshots for a camera on and off. Expected values are `ON` and `O
|
|||||||
|
|
||||||
Topic with current state of snapshots for a camera. Published values are `ON` and `OFF`.
|
Topic with current state of snapshots for a camera. Published values are `ON` and `OFF`.
|
||||||
|
|
||||||
|
### `frigate/<camera_name>/motion/set`
|
||||||
|
|
||||||
|
Topic to turn motion detection for a camera on and off. Expected values are `ON` and `OFF`.
|
||||||
|
NOTE: Turning off motion detection will fail if detection is not disabled.
|
||||||
|
|
||||||
|
### `frigate/<camera_name>/motion/state`
|
||||||
|
|
||||||
|
Topic with current state of motion detection for a camera. Published values are `ON` and `OFF`.
|
||||||
|
|
||||||
### `frigate/<camera_name>/improve_contrast/set`
|
### `frigate/<camera_name>/improve_contrast/set`
|
||||||
|
|
||||||
Topic to turn improve_contrast for a camera on and off. Expected values are `ON` and `OFF`.
|
Topic to turn improve_contrast for a camera on and off. Expected values are `ON` and `OFF`.
|
||||||
|
@ -91,6 +91,7 @@ class FrigateApp:
|
|||||||
"detection_enabled": mp.Value(
|
"detection_enabled": mp.Value(
|
||||||
"i", self.config.cameras[camera_name].detect.enabled
|
"i", self.config.cameras[camera_name].detect.enabled
|
||||||
),
|
),
|
||||||
|
"motion_enabled": mp.Value("i", True),
|
||||||
"improve_contrast_enabled": mp.Value(
|
"improve_contrast_enabled": mp.Value(
|
||||||
"i", self.config.cameras[camera_name].motion.improve_contrast
|
"i", self.config.cameras[camera_name].motion.improve_contrast
|
||||||
),
|
),
|
||||||
|
@ -78,6 +78,12 @@ def create_mqtt_client(config: FrigateConfig, camera_metrics):
|
|||||||
logger.info(f"Turning on detection for {camera_name} via mqtt")
|
logger.info(f"Turning on detection for {camera_name} via mqtt")
|
||||||
camera_metrics[camera_name]["detection_enabled"].value = True
|
camera_metrics[camera_name]["detection_enabled"].value = True
|
||||||
detect_settings.enabled = True
|
detect_settings.enabled = True
|
||||||
|
|
||||||
|
if not camera_metrics[camera_name]["motion_enabled"].value:
|
||||||
|
logger.info(
|
||||||
|
f"Turning on motion for {camera_name} due to detection being enabled."
|
||||||
|
)
|
||||||
|
camera_metrics[camera_name]["motion_enabled"].value = True
|
||||||
elif payload == "OFF":
|
elif payload == "OFF":
|
||||||
if camera_metrics[camera_name]["detection_enabled"].value:
|
if camera_metrics[camera_name]["detection_enabled"].value:
|
||||||
logger.info(f"Turning off detection for {camera_name} via mqtt")
|
logger.info(f"Turning off detection for {camera_name} via mqtt")
|
||||||
@ -89,6 +95,32 @@ def create_mqtt_client(config: FrigateConfig, camera_metrics):
|
|||||||
state_topic = f"{message.topic[:-4]}/state"
|
state_topic = f"{message.topic[:-4]}/state"
|
||||||
client.publish(state_topic, payload, retain=True)
|
client.publish(state_topic, payload, retain=True)
|
||||||
|
|
||||||
|
def on_motion_command(client, userdata, message):
|
||||||
|
payload = message.payload.decode()
|
||||||
|
logger.debug(f"on_motion_toggle: {message.topic} {payload}")
|
||||||
|
|
||||||
|
camera_name = message.topic.split("/")[-3]
|
||||||
|
|
||||||
|
if payload == "ON":
|
||||||
|
if not camera_metrics[camera_name]["motion_enabled"].value:
|
||||||
|
logger.info(f"Turning on motion for {camera_name} via mqtt")
|
||||||
|
camera_metrics[camera_name]["motion_enabled"].value = True
|
||||||
|
elif payload == "OFF":
|
||||||
|
if camera_metrics[camera_name]["detection_enabled"].value:
|
||||||
|
logger.error(
|
||||||
|
f"Turning off motion is not allowed when detection is enabled."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
if camera_metrics[camera_name]["motion_enabled"].value:
|
||||||
|
logger.info(f"Turning off motion for {camera_name} via mqtt")
|
||||||
|
camera_metrics[camera_name]["motion_enabled"].value = False
|
||||||
|
else:
|
||||||
|
logger.warning(f"Received unsupported value at {message.topic}: {payload}")
|
||||||
|
|
||||||
|
state_topic = f"{message.topic[:-4]}/state"
|
||||||
|
client.publish(state_topic, payload, retain=True)
|
||||||
|
|
||||||
def on_improve_contrast_command(client, userdata, message):
|
def on_improve_contrast_command(client, userdata, message):
|
||||||
payload = message.payload.decode()
|
payload = message.payload.decode()
|
||||||
logger.debug(f"on_improve_contrast_toggle: {message.topic} {payload}")
|
logger.debug(f"on_improve_contrast_toggle: {message.topic} {payload}")
|
||||||
@ -156,6 +188,9 @@ def create_mqtt_client(config: FrigateConfig, camera_metrics):
|
|||||||
client.message_callback_add(
|
client.message_callback_add(
|
||||||
f"{mqtt_config.topic_prefix}/{name}/detect/set", on_detect_command
|
f"{mqtt_config.topic_prefix}/{name}/detect/set", on_detect_command
|
||||||
)
|
)
|
||||||
|
client.message_callback_add(
|
||||||
|
f"{mqtt_config.topic_prefix}/{name}/motion/set", on_motion_command
|
||||||
|
)
|
||||||
client.message_callback_add(
|
client.message_callback_add(
|
||||||
f"{mqtt_config.topic_prefix}/{name}/improve_contrast/set",
|
f"{mqtt_config.topic_prefix}/{name}/improve_contrast/set",
|
||||||
on_improve_contrast_command,
|
on_improve_contrast_command,
|
||||||
|
@ -14,6 +14,7 @@ class CameraMetricsTypes(TypedDict):
|
|||||||
detection_frame: Synchronized
|
detection_frame: Synchronized
|
||||||
ffmpeg_pid: Synchronized
|
ffmpeg_pid: Synchronized
|
||||||
frame_queue: Queue
|
frame_queue: Queue
|
||||||
|
motion_enabled: Synchronized
|
||||||
improve_contrast_enabled: Synchronized
|
improve_contrast_enabled: Synchronized
|
||||||
process: Optional[Process]
|
process: Optional[Process]
|
||||||
process_fps: Synchronized
|
process_fps: Synchronized
|
||||||
|
@ -361,6 +361,7 @@ def track_camera(
|
|||||||
|
|
||||||
frame_queue = process_info["frame_queue"]
|
frame_queue = process_info["frame_queue"]
|
||||||
detection_enabled = process_info["detection_enabled"]
|
detection_enabled = process_info["detection_enabled"]
|
||||||
|
motion_enabled = process_info["motion_enabled"]
|
||||||
improve_contrast_enabled = process_info["improve_contrast_enabled"]
|
improve_contrast_enabled = process_info["improve_contrast_enabled"]
|
||||||
|
|
||||||
frame_shape = config.frame_shape
|
frame_shape = config.frame_shape
|
||||||
@ -393,6 +394,7 @@ def track_camera(
|
|||||||
objects_to_track,
|
objects_to_track,
|
||||||
object_filters,
|
object_filters,
|
||||||
detection_enabled,
|
detection_enabled,
|
||||||
|
motion_enabled,
|
||||||
stop_event,
|
stop_event,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -479,6 +481,7 @@ def process_frames(
|
|||||||
objects_to_track: list[str],
|
objects_to_track: list[str],
|
||||||
object_filters,
|
object_filters,
|
||||||
detection_enabled: mp.Value,
|
detection_enabled: mp.Value,
|
||||||
|
motion_enabled: mp.Value,
|
||||||
stop_event,
|
stop_event,
|
||||||
exit_on_empty: bool = False,
|
exit_on_empty: bool = False,
|
||||||
):
|
):
|
||||||
@ -512,8 +515,8 @@ def process_frames(
|
|||||||
logger.info(f"{camera_name}: frame {frame_time} is not in memory store.")
|
logger.info(f"{camera_name}: frame {frame_time} is not in memory store.")
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# look for motion
|
# look for motion if enabled
|
||||||
motion_boxes = motion_detector.detect(frame)
|
motion_boxes = motion_detector.detect(frame) if motion_enabled.value else []
|
||||||
|
|
||||||
regions = []
|
regions = []
|
||||||
|
|
||||||
|
@ -115,6 +115,7 @@ class ProcessClip:
|
|||||||
}
|
}
|
||||||
|
|
||||||
detection_enabled = mp.Value("d", 1)
|
detection_enabled = mp.Value("d", 1)
|
||||||
|
motion_enabled = mp.Value("d", True)
|
||||||
stop_event = mp.Event()
|
stop_event = mp.Event()
|
||||||
model_shape = (self.config.model.height, self.config.model.width)
|
model_shape = (self.config.model.height, self.config.model.width)
|
||||||
|
|
||||||
@ -133,6 +134,7 @@ class ProcessClip:
|
|||||||
objects_to_track,
|
objects_to_track,
|
||||||
object_filters,
|
object_filters,
|
||||||
detection_enabled,
|
detection_enabled,
|
||||||
|
motion_enabled,
|
||||||
stop_event,
|
stop_event,
|
||||||
exit_on_empty=True,
|
exit_on_empty=True,
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user