Compare commits

...

4 Commits

Author SHA1 Message Date
GuoQing Liu
0c0b93b03f
Merge 9fe9345263 into ef5608a970 2026-02-18 13:39:01 -08:00
Nicolas Mowen
ef5608a970
Imporove attributes handling (#22035)
Some checks failed
CI / AMD64 Build (push) Has been cancelled
CI / ARM Build (push) Has been cancelled
CI / Jetson Jetpack 6 (push) Has been cancelled
CI / AMD64 Extra Build (push) Has been cancelled
CI / ARM Extra Build (push) Has been cancelled
CI / Synaptics Build (push) Has been cancelled
CI / Assemble and push default build (push) Has been cancelled
* Revert "Fix saving attributes for object to DB (#22000)"

This reverts commit 73c1e12faf.

* Automatically handle attributes by obj data parsing
2026-02-18 10:48:45 -07:00
ZhaiSoul
9fe9345263 feat: explore audio type display icon 2026-02-04 05:26:54 +00:00
ZhaiSoul
7f172ca2c6 fix: audio don't need download snapshot 2026-02-04 05:26:05 +00:00
5 changed files with 24 additions and 23 deletions

View File

@ -33,7 +33,6 @@ from frigate.config.camera.updater import (
CameraConfigUpdateEnum,
CameraConfigUpdateSubscriber,
)
from frigate.config.classification import ObjectClassificationType
from frigate.const import (
FAST_QUEUE_TIMEOUT,
UPDATE_CAMERA_ACTIVITY,
@ -760,16 +759,8 @@ class TrackedObjectProcessor(threading.Thread):
self.update_mqtt_motion(camera, frame_time, motion_boxes)
attribute_model_names = [
name
for name, model_config in self.config.classification.custom.items()
if model_config.object_config
and model_config.object_config.classification_type
== ObjectClassificationType.attribute
]
tracked_objects = [
o.to_dict(attribute_model_names=attribute_model_names)
for o in camera_state.tracked_objects.values()
o.to_dict() for o in camera_state.tracked_objects.values()
]
# publish info on this frame

View File

@ -376,11 +376,15 @@ class TrackedObject:
)
return (thumb_update, significant_change, path_update, autotracker_update)
def to_dict(
self,
attribute_model_names: list[str] | None = None,
) -> dict[str, Any]:
event = {
def to_dict(self) -> dict[str, Any]:
# 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"],
@ -414,11 +418,11 @@ class TrackedObject:
"path_data": self.path_data.copy(),
"recognized_license_plate": self.obj_data.get("recognized_license_plate"),
}
if attribute_model_names is not None:
for name in attribute_model_names:
value = self.obj_data.get(name)
if value is not None:
event[name] = value
# 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

View File

@ -99,7 +99,7 @@ export default function SearchResultActions({
</a>
</MenuItem>
)}
{searchResult.has_snapshot && (
{searchResult.has_snapshot && searchResult?.data?.type === "object" && (
<MenuItem aria-label={t("itemMenu.downloadSnapshot.aria")}>
<a
className="flex items-center"
@ -111,6 +111,7 @@ export default function SearchResultActions({
</MenuItem>
)}
{searchResult.has_snapshot &&
searchResult?.data?.type === "object" &&
config?.cameras[searchResult.camera].snapshots.clean_copy && (
<MenuItem aria-label={t("itemMenu.downloadCleanSnapshot.aria")}>
<a

View File

@ -81,7 +81,7 @@ export default function DetailActionsMenu({
</DropdownMenuTrigger>
<DropdownMenuPortal>
<DropdownMenuContent align="end">
{search.has_snapshot && (
{search.has_snapshot && search?.data?.type === "object" && (
<DropdownMenuItem>
<a
className="w-full"
@ -95,7 +95,8 @@ export default function DetailActionsMenu({
</DropdownMenuItem>
)}
{search.has_snapshot &&
config?.cameras[search.camera].snapshots.clean_copy && (
config?.cameras[search.camera].snapshots.clean_copy &&
search?.data?.type === "object" && (
<DropdownMenuItem>
<a
className="w-full"

View File

@ -23,6 +23,7 @@ import { FrigateConfig } from "@/types/frigateConfig";
import { useTranslation } from "react-i18next";
import { getTranslatedLabel } from "@/utils/i18n";
import { LuSearchX } from "react-icons/lu";
import { getIconForLabel } from "@/utils/iconUtil";
type ExploreViewProps = {
setSearchDetail: (search: SearchResult | undefined) => void;
@ -149,6 +150,9 @@ function ThumbnailRow({
return (
<div className="rounded-lg bg-background_alt p-2 md:px-4">
<div className="flex flex-row items-center text-lg smart-capitalize">
{labelType === "audio"
? getIconForLabel("", labelType, "size-4 mr-1")
: null}
{getTranslatedLabel(label, labelType)}
{searchResults && (
<span className="ml-3 text-sm text-secondary-foreground">