diff --git a/frigate/timeline.py b/frigate/timeline.py index cca0b24b7..c058e0437 100644 --- a/frigate/timeline.py +++ b/frigate/timeline.py @@ -7,6 +7,7 @@ from multiprocessing import Queue from multiprocessing.synchronize import Event as MpEvent from frigate.config import FrigateConfig +from frigate.const import ALL_ATTRIBUTE_LABELS from frigate.events.maintainer import EventTypeEnum from frigate.models import Timeline from frigate.util.builtin import to_relative_box @@ -101,6 +102,13 @@ class TimelineProcessor(threading.Thread): event_data["attributes"].keys() )[0] Timeline.insert(timeline_entry).execute() + elif not prev_event_data.get("sub_label") and event_data.get("sub_label"): + sub_label = event_data["sub_label"][0] + + if sub_label not in ALL_ATTRIBUTE_LABELS: + timeline_entry[Timeline.class_type] = "sub_label" + timeline_entry[Timeline.data]["sub_label"] = sub_label + Timeline.insert(timeline_entry).execute() elif event_type == "end": if event_data["has_clip"] or event_data["has_snapshot"]: timeline_entry[Timeline.class_type] = "gone" diff --git a/web/src/components/TimelineSummary.jsx b/web/src/components/TimelineSummary.jsx index 89b8914c3..62e3b4cb6 100644 --- a/web/src/components/TimelineSummary.jsx +++ b/web/src/components/TimelineSummary.jsx @@ -145,6 +145,13 @@ function getTimelineIcon(timelineItem) { default: return ; } + case 'sub_label': + switch (timelineItem.data.label) { + case 'person': + return ; + case 'car': + return ; + } } } @@ -176,8 +183,24 @@ function getTimelineItemDescription(config, timelineItem, event) { time_style: 'medium', time_format: config.ui.time_format, })}`; - case 'attribute': - return `${timelineItem.data.attribute.replaceAll("_", " ")} detected for ${event.label} at ${formatUnixTimestampToDateTime( + case 'attribute': { + let title = ""; + if (timelineItem.data.attribute == 'face' || timelineItem.data.attribute == 'license_plate') { + title = `${timelineItem.data.attribute.replaceAll("_", " ")} detected for ${event.label}`; + } else { + title = `${event.label} recognized as ${timelineItem.data.attribute.replaceAll("_", " ")}` + } + return `${title} at ${formatUnixTimestampToDateTime( + timelineItem.timestamp, + { + date_style: 'short', + time_style: 'medium', + time_format: config.ui.time_format, + } + )}`; + } + case 'sub_label': + return `${event.label} recognized as ${timelineItem.data.sub_label} at ${formatUnixTimestampToDateTime( timelineItem.timestamp, { date_style: 'short',