Skip to content

Commit

Permalink
Ability to enable / disable motion detection via MQTT (blakeblackshea…
Browse files Browse the repository at this point in the history
…r#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
  • Loading branch information
NickM-27 committed Apr 26, 2022
1 parent b75929a commit 0a4d658
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 2 deletions.
9 changes: 9 additions & 0 deletions docs/docs/integrations/mqtt.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

### `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`

Topic to turn improve_contrast for a camera on and off. Expected values are `ON` and `OFF`.
Expand Down
1 change: 1 addition & 0 deletions frigate/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ def init_config(self) -> None:
"detection_enabled": mp.Value(
"i", self.config.cameras[camera_name].detect.enabled
),
"motion_enabled": mp.Value("i", True),
"improve_contrast_enabled": mp.Value(
"i", self.config.cameras[camera_name].motion.improve_contrast
),
Expand Down
35 changes: 35 additions & 0 deletions frigate/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ def on_detect_command(client, userdata, message):
logger.info(f"Turning on detection for {camera_name} via mqtt")
camera_metrics[camera_name]["detection_enabled"].value = 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":
if camera_metrics[camera_name]["detection_enabled"].value:
logger.info(f"Turning off detection for {camera_name} via mqtt")
Expand All @@ -89,6 +95,32 @@ def on_detect_command(client, userdata, message):
state_topic = f"{message.topic[:-4]}/state"
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):
payload = message.payload.decode()
logger.debug(f"on_improve_contrast_toggle: {message.topic} {payload}")
Expand Down Expand Up @@ -156,6 +188,9 @@ def on_connect(client, userdata, flags, rc):
client.message_callback_add(
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(
f"{mqtt_config.topic_prefix}/{name}/improve_contrast/set",
on_improve_contrast_command,
Expand Down
1 change: 1 addition & 0 deletions frigate/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class CameraMetricsTypes(TypedDict):
detection_frame: Synchronized
ffmpeg_pid: Synchronized
frame_queue: Queue
motion_enabled: Synchronized
improve_contrast_enabled: Synchronized
process: Optional[Process]
process_fps: Synchronized
Expand Down
7 changes: 5 additions & 2 deletions frigate/video.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ def receiveSignal(signalNumber, frame):

frame_queue = process_info["frame_queue"]
detection_enabled = process_info["detection_enabled"]
motion_enabled = process_info["motion_enabled"]
improve_contrast_enabled = process_info["improve_contrast_enabled"]

frame_shape = config.frame_shape
Expand Down Expand Up @@ -393,6 +394,7 @@ def receiveSignal(signalNumber, frame):
objects_to_track,
object_filters,
detection_enabled,
motion_enabled,
stop_event,
)

Expand Down Expand Up @@ -479,6 +481,7 @@ def process_frames(
objects_to_track: list[str],
object_filters,
detection_enabled: mp.Value,
motion_enabled: mp.Value,
stop_event,
exit_on_empty: bool = False,
):
Expand Down Expand Up @@ -512,8 +515,8 @@ def process_frames(
logger.info(f"{camera_name}: frame {frame_time} is not in memory store.")
continue

# look for motion
motion_boxes = motion_detector.detect(frame)
# look for motion if enabled
motion_boxes = motion_detector.detect(frame) if motion_enabled.value else []

regions = []

Expand Down
2 changes: 2 additions & 0 deletions process_clip.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ def process_frames(
}

detection_enabled = mp.Value("d", 1)
motion_enabled = mp.Value("d", True)
stop_event = mp.Event()
model_shape = (self.config.model.height, self.config.model.width)

Expand All @@ -133,6 +134,7 @@ def process_frames(
objects_to_track,
object_filters,
detection_enabled,
motion_enabled,
stop_event,
exit_on_empty=True,
)
Expand Down

0 comments on commit 0a4d658

Please sign in to comment.