From f02284dec4afe8fcdc19b04133212867cfe94043 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Wed, 18 Feb 2026 09:16:44 -0700 Subject: [PATCH] Automatically handle attributes by obj data parsing --- frigate/events/maintainer.py | 13 +++++++++++++ frigate/track/tracked_object.py | 14 +++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/frigate/events/maintainer.py b/frigate/events/maintainer.py index 67d8cf2e8..f6ab777c1 100644 --- a/frigate/events/maintainer.py +++ b/frigate/events/maintainer.py @@ -6,6 +6,7 @@ from typing import Dict from frigate.comms.events_updater import EventEndPublisher, EventUpdateSubscriber from frigate.config import FrigateConfig +from frigate.config.classification import ObjectClassificationType from frigate.events.types import EventStateEnum, EventTypeEnum from frigate.models import Event from frigate.util.builtin import to_relative_box @@ -247,6 +248,18 @@ class EventProcessor(threading.Thread): "recognized_license_plate" ][1] + # only overwrite attribute-type custom model fields in the database if they're set + for name, model_config in self.config.classification.custom.items(): + if ( + model_config.object_config + and model_config.object_config.classification_type + == ObjectClassificationType.attribute + ): + value = event_data.get(name) + if value is not None: + event[Event.data][name] = value[0] + event[Event.data][f"{name}_score"] = value[1] + ( Event.insert(event) .on_conflict( diff --git a/frigate/track/tracked_object.py b/frigate/track/tracked_object.py index 453798651..a95221bbd 100644 --- a/frigate/track/tracked_object.py +++ b/frigate/track/tracked_object.py @@ -377,7 +377,14 @@ class TrackedObject: return (thumb_update, significant_change, path_update, autotracker_update) def to_dict(self) -> dict[str, Any]: - event = { + # Tracking internals excluded from output (centroid, estimate, estimate_velocity) + _EXCLUDED_OBJ_DATA_KEYS = { + "centroid", + "estimate", + "estimate_velocity", + } + + event: dict[str, Any] = { "id": self.obj_data["id"], "camera": self.camera_config.name, "frame_time": self.obj_data["frame_time"], @@ -412,6 +419,11 @@ class TrackedObject: "recognized_license_plate": self.obj_data.get("recognized_license_plate"), } + # Add any other obj_data keys (e.g. custom attribute fields) not yet included + for key, value in self.obj_data.items(): + if key not in _EXCLUDED_OBJ_DATA_KEYS and key not in event: + event[key] = value + return event def is_active(self) -> bool: