Organize data more effictively and ensure data is not overwritten

This commit is contained in:
Nick Mowen 2023-12-19 15:08:11 -07:00
parent 8d143dc655
commit a35dfd0e69
2 changed files with 37 additions and 22 deletions

View File

@ -10,7 +10,7 @@ import axios from "axios";
import TimelinePlayerCard from "@/components/card/TimelinePlayerCard";
import { getHourlyTimelineData } from "@/utils/historyUtil";
const API_LIMIT = 120;
const API_LIMIT = 200;
function History() {
const { data: config } = useSWR<FrigateConfig>("config");

View File

@ -1,3 +1,6 @@
// group history cards by 60 seconds of activity
const GROUP_SECONDS = 60;
export function getHourlyTimelineData(
timelinePages: HourlyTimeline[],
detailLevel: string
@ -10,26 +13,42 @@ export function getHourlyTimelineData(
const day = new Date(parseInt(hour) * 1000);
day.setHours(0, 0, 0, 0);
const dayKey = (day.getTime() / 1000).toString();
// build a map of course to the types that are included in this hour
// which allows us to know what items to keep depending on detail level
const source_to_types: { [key: string]: string[] } = {};
let cardTypeStart: { [camera: string]: number } = {};
Object.values(hourlyTimeline["hours"][hour]).forEach((i) => {
const time = new Date(i.timestamp * 1000);
time.setSeconds(0);
time.setMilliseconds(0);
const key = `${i.source_id}-${time.getMinutes()}`;
if (key in source_to_types) {
source_to_types[key].push(i.class_type);
if (i.timestamp > (cardTypeStart[i.camera] ?? 0) + GROUP_SECONDS) {
cardTypeStart[i.camera] = i.timestamp;
}
const groupKey = `${i.source_id}-${cardTypeStart[i.camera]}`;
if (groupKey in source_to_types) {
source_to_types[groupKey].push(i.class_type);
} else {
source_to_types[key] = [i.class_type];
source_to_types[groupKey] = [i.class_type];
}
});
if (!Object.keys(cards).includes(dayKey)) {
if (!(dayKey in cards)) {
cards[dayKey] = {};
}
cards[dayKey][hour] = {};
if (!(hour in cards[dayKey])) {
cards[dayKey][hour] = {};
}
let cardStart: { [camera: string]: number } = {};
Object.values(hourlyTimeline["hours"][hour]).forEach((i) => {
if (i.timestamp > (cardStart[i.camera] ?? 0) + GROUP_SECONDS) {
cardStart[i.camera] = i.timestamp;
}
const time = new Date(i.timestamp * 1000);
const minuteKey = `${i.camera}-${time.getMinutes()}`;
const groupKey = `${i.camera}-${cardStart[i.camera]}`;
const sourceKey = `${i.source_id}-${cardStart[i.camera]}`;
const uniqueKey = `${i.source_id}-${i.class_type}`;
// detail level for saving items
@ -42,8 +61,7 @@ export function getHourlyTimelineData(
let add = true;
if (detailLevel == "normal") {
if (
source_to_types[`${i.source_id}-${time.getMinutes()}`].length >
1 &&
source_to_types[sourceKey].length > 1 &&
["active", "attribute", "gone", "stationary", "visible"].includes(
i.class_type
)
@ -52,8 +70,7 @@ export function getHourlyTimelineData(
}
} else if (detailLevel == "extra") {
if (
source_to_types[`${i.source_id}-${time.getMinutes()}`].length >
1 &&
source_to_types[sourceKey].length > 1 &&
i.class_type in ["attribute", "gone", "visible"]
) {
add = false;
@ -61,18 +78,16 @@ export function getHourlyTimelineData(
}
if (add) {
if (minuteKey in cards[dayKey][hour]) {
if (groupKey in cards[dayKey][hour]) {
if (
!cards[dayKey][hour][minuteKey].uniqueKeys.includes(
uniqueKey
) ||
!cards[dayKey][hour][groupKey].uniqueKeys.includes(uniqueKey) ||
detailLevel == "full"
) {
cards[dayKey][hour][minuteKey].entries.push(i);
cards[dayKey][hour][minuteKey].uniqueKeys.push(uniqueKey);
cards[dayKey][hour][groupKey].entries.push(i);
cards[dayKey][hour][groupKey].uniqueKeys.push(uniqueKey);
}
} else {
cards[dayKey][hour][minuteKey] = {
cards[dayKey][hour][groupKey] = {
camera: i.camera,
time: time.getTime() / 1000,
entries: [i],