Tracked object metadata changes (#15055)

* add enum and change topic name

* frontend renaming

* docs

* only display sublabel score if it it exists

* remove debug print
This commit is contained in:
Josh Hawkins 2024-11-18 12:26:44 -06:00 committed by GitHub
parent 66f71aecf7
commit 9ae839ad72
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 41 additions and 14 deletions

View File

@ -94,6 +94,18 @@ Message published for each changed tracked object. The first message is publishe
} }
``` ```
### `frigate/tracked_object_update`
Message published for updates to tracked object metadata, for example when GenAI runs and returns a tracked object description.
```json
{
"type": "description",
"id": "1607123955.475377-mxklsc",
"description": "The car is a red sedan moving away from the camera."
}
```
### `frigate/reviews` ### `frigate/reviews`
Message published for each changed review item. The first message is published when the `detection` or `alert` is initiated. When additional objects are detected or when a zone change occurs, it will publish a, `update` message with the same id. When the review activity has ended a final `end` message is published. Message published for each changed review item. The first message is published when the `detection` or `alert` is initiated. When additional objects are detected or when a zone change occurs, it will publish a, `update` message with the same id. When the review activity has ended a final `end` message is published.

View File

@ -22,7 +22,7 @@ from frigate.const import (
) )
from frigate.models import Event, Previews, Recordings, ReviewSegment from frigate.models import Event, Previews, Recordings, ReviewSegment
from frigate.ptz.onvif import OnvifCommandEnum, OnvifController from frigate.ptz.onvif import OnvifCommandEnum, OnvifController
from frigate.types import ModelStatusTypesEnum from frigate.types import ModelStatusTypesEnum, TrackedObjectUpdateTypesEnum
from frigate.util.object import get_camera_regions_grid from frigate.util.object import get_camera_regions_grid
from frigate.util.services import restart_frigate from frigate.util.services import restart_frigate
@ -137,8 +137,14 @@ class Dispatcher:
event.data["description"] = payload["description"] event.data["description"] = payload["description"]
event.save() event.save()
self.publish( self.publish(
"event_update", "tracked_object_update",
json.dumps({"id": event.id, "description": event.data["description"]}), json.dumps(
{
"type": TrackedObjectUpdateTypesEnum.description,
"id": event.id,
"description": event.data["description"],
}
),
) )
def handle_update_model_state(): def handle_update_model_state():

View File

@ -24,6 +24,7 @@ from frigate.const import CLIPS_DIR, UPDATE_EVENT_DESCRIPTION
from frigate.events.types import EventTypeEnum from frigate.events.types import EventTypeEnum
from frigate.genai import get_genai_client from frigate.genai import get_genai_client
from frigate.models import Event from frigate.models import Event
from frigate.types import TrackedObjectUpdateTypesEnum
from frigate.util.builtin import serialize from frigate.util.builtin import serialize
from frigate.util.image import SharedMemoryFrameManager, calculate_region from frigate.util.image import SharedMemoryFrameManager, calculate_region
@ -287,7 +288,11 @@ class EmbeddingMaintainer(threading.Thread):
# fire and forget description update # fire and forget description update
self.requestor.send_data( self.requestor.send_data(
UPDATE_EVENT_DESCRIPTION, UPDATE_EVENT_DESCRIPTION,
{"id": event.id, "description": description}, {
"type": TrackedObjectUpdateTypesEnum.description,
"id": event.id,
"description": description,
},
) )
# Embed the description # Embed the description

View File

@ -19,3 +19,7 @@ class ModelStatusTypesEnum(str, Enum):
downloading = "downloading" downloading = "downloading"
downloaded = "downloaded" downloaded = "downloaded"
error = "error" error = "error"
class TrackedObjectUpdateTypesEnum(str, Enum):
description = "description"

View File

@ -407,9 +407,9 @@ export function useImproveContrast(camera: string): {
return { payload: payload as ToggleableSetting, send }; return { payload: payload as ToggleableSetting, send };
} }
export function useEventUpdate(): { payload: string } { export function useTrackedObjectUpdate(): { payload: string } {
const { const {
value: { payload }, value: { payload },
} = useWs("event_update", ""); } = useWs("tracked_object_update", "");
return useDeepMemo(JSON.parse(payload as string)); return useDeepMemo(JSON.parse(payload as string));
} }

View File

@ -309,7 +309,7 @@ function ObjectDetailsTab({
return undefined; return undefined;
} }
if (search.sub_label) { if (search.sub_label && search.data?.sub_label_score) {
return Math.round((search.data?.sub_label_score ?? 0) * 100); return Math.round((search.data?.sub_label_score ?? 0) * 100);
} else { } else {
return undefined; return undefined;

View File

@ -1,6 +1,6 @@
import { import {
useEmbeddingsReindexProgress, useEmbeddingsReindexProgress,
useEventUpdate, useTrackedObjectUpdate,
useModelState, useModelState,
} from "@/api/ws"; } from "@/api/ws";
import ActivityIndicator from "@/components/indicators/activity-indicator"; import ActivityIndicator from "@/components/indicators/activity-indicator";
@ -227,15 +227,15 @@ export default function Explore() {
// mutation and revalidation // mutation and revalidation
const eventUpdate = useEventUpdate(); const trackedObjectUpdate = useTrackedObjectUpdate();
useEffect(() => { useEffect(() => {
if (eventUpdate) { if (trackedObjectUpdate) {
mutate(); mutate();
} }
// mutate / revalidate when event description updates come in // mutate / revalidate when event description updates come in
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [eventUpdate]); }, [trackedObjectUpdate]);
// embeddings reindex progress // embeddings reindex progress

View File

@ -15,7 +15,7 @@ import { SearchResult } from "@/types/search";
import ImageLoadingIndicator from "@/components/indicators/ImageLoadingIndicator"; import ImageLoadingIndicator from "@/components/indicators/ImageLoadingIndicator";
import useImageLoaded from "@/hooks/use-image-loaded"; import useImageLoaded from "@/hooks/use-image-loaded";
import ActivityIndicator from "@/components/indicators/activity-indicator"; import ActivityIndicator from "@/components/indicators/activity-indicator";
import { useEventUpdate } from "@/api/ws"; import { useTrackedObjectUpdate } from "@/api/ws";
import { isEqual } from "lodash"; import { isEqual } from "lodash";
import TimeAgo from "@/components/dynamic/TimeAgo"; import TimeAgo from "@/components/dynamic/TimeAgo";
import SearchResultActions from "@/components/menu/SearchResultActions"; import SearchResultActions from "@/components/menu/SearchResultActions";
@ -72,13 +72,13 @@ export default function ExploreView({
}, {}); }, {});
}, [events]); }, [events]);
const eventUpdate = useEventUpdate(); const trackedObjectUpdate = useTrackedObjectUpdate();
useEffect(() => { useEffect(() => {
mutate(); mutate();
// mutate / revalidate when event description updates come in // mutate / revalidate when event description updates come in
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps
}, [eventUpdate]); }, [trackedObjectUpdate]);
// update search detail when results change // update search detail when results change