From 9b2f84d3e92fea9ff2564b9fb4094f11355746d6 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Fri, 8 Aug 2025 08:14:59 -0600 Subject: [PATCH] Adjust loitering behavior based on object type (#19433) * Adjust loitering behavior based on object * Update docs * Grammar --- docs/docs/configuration/zones.md | 4 +++- frigate/track/tracked_object.py | 20 ++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/docs/docs/configuration/zones.md b/docs/docs/configuration/zones.md index d2a1083e6..025384a8b 100644 --- a/docs/docs/configuration/zones.md +++ b/docs/docs/configuration/zones.md @@ -88,7 +88,9 @@ Sometimes objects are expected to be passing through a zone, but an object loite :::note -When using loitering zones, a review item will remain active until the object leaves. Loitering zones are only meant to be used in areas where loitering is not expected behavior. +When using loitering zones, a review item will behave in the following way: +- When a person is in a loitering zone, the review item will remain active until the person leaves the loitering zone, regardless of if they are stationary. +- When any other object is in a loitering zone, the review item will remain active until the loitering time is met. Then if the object is stationary the review item will end. ::: diff --git a/frigate/track/tracked_object.py b/frigate/track/tracked_object.py index 2cb028a9a..afe85228e 100644 --- a/frigate/track/tracked_object.py +++ b/frigate/track/tracked_object.py @@ -32,6 +32,14 @@ from frigate.util.velocity import calculate_real_world_speed logger = logging.getLogger(__name__) +# In most cases objects that loiter in a loitering zone should alert, +# but can still be expected to stay stationary for extended periods of time +# (ex: car loitering on the street vs when a known person parks on the street) +# person is the main object that should keep alerts going as long as they loiter +# even if they are stationary. +EXTENDED_LOITERING_OBJECTS = ["person"] + + class TrackedObject: def __init__( self, @@ -247,8 +255,12 @@ class TrackedObject: if zone.distances and not in_speed_zone: continue # Skip zone entry for speed zones until speed threshold met - # if the zone has loitering time, update loitering status - if zone.loitering_time > 0: + # if the zone has loitering time, and the object is an extended loiter object + # always mark it as loitering actively + if ( + self.obj_data["label"] in EXTENDED_LOITERING_OBJECTS + and zone.loitering_time > 0 + ): in_loitering_zone = True loitering_score = self.zone_loitering.get(name, 0) + 1 @@ -264,6 +276,10 @@ class TrackedObject: self.entered_zones.append(name) else: self.zone_loitering[name] = loitering_score + + # this object is pending loitering but has not entered the zone yet + if zone.loitering_time > 0: + in_loitering_zone = True else: self.zone_presence[name] = zone_score else: