mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-12-19 19:06:16 +01:00
Use config attribute map instead of hard coded (#14387)
This commit is contained in:
parent
eda52a3b82
commit
06f47f262f
@ -1,3 +1,4 @@
|
||||
|
||||
#!/bin/bash
|
||||
|
||||
set -euxo pipefail
|
||||
|
@ -20,7 +20,7 @@ import {
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { useCallback, useEffect, useMemo } from "react";
|
||||
import { ATTRIBUTE_LABELS, FrigateConfig } from "@/types/frigateConfig";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import useSWR from "swr";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
@ -37,6 +37,7 @@ import axios from "axios";
|
||||
import { toast } from "sonner";
|
||||
import { Toaster } from "../ui/sonner";
|
||||
import ActivityIndicator from "../indicators/activity-indicator";
|
||||
import { getAttributeLabels } from "@/utils/iconUtil";
|
||||
|
||||
type ObjectMaskEditPaneProps = {
|
||||
polygons?: Polygon[];
|
||||
@ -367,6 +368,14 @@ type ZoneObjectSelectorProps = {
|
||||
export function ZoneObjectSelector({ camera }: ZoneObjectSelectorProps) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
|
||||
const attributeLabels = useMemo(() => {
|
||||
if (!config) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return getAttributeLabels(config);
|
||||
}, [config]);
|
||||
|
||||
const cameraConfig = useMemo(() => {
|
||||
if (config && camera) {
|
||||
return config.cameras[camera];
|
||||
@ -382,20 +391,20 @@ export function ZoneObjectSelector({ camera }: ZoneObjectSelectorProps) {
|
||||
|
||||
Object.values(config.cameras).forEach((camera) => {
|
||||
camera.objects.track.forEach((label) => {
|
||||
if (!ATTRIBUTE_LABELS.includes(label)) {
|
||||
if (!attributeLabels.includes(label)) {
|
||||
labels.add(label);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
cameraConfig.objects.track.forEach((label) => {
|
||||
if (!ATTRIBUTE_LABELS.includes(label)) {
|
||||
if (!attributeLabels.includes(label)) {
|
||||
labels.add(label);
|
||||
}
|
||||
});
|
||||
|
||||
return [...labels].sort();
|
||||
}, [config, cameraConfig]);
|
||||
}, [config, cameraConfig, attributeLabels]);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { ATTRIBUTE_LABELS, FrigateConfig } from "@/types/frigateConfig";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import useSWR from "swr";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { useForm } from "react-hook-form";
|
||||
@ -28,6 +28,7 @@ import { Toaster } from "@/components/ui/sonner";
|
||||
import { toast } from "sonner";
|
||||
import { flattenPoints, interpolatePoints } from "@/utils/canvasUtil";
|
||||
import ActivityIndicator from "../indicators/activity-indicator";
|
||||
import { getAttributeLabels } from "@/utils/iconUtil";
|
||||
|
||||
type ZoneEditPaneProps = {
|
||||
polygons?: Polygon[];
|
||||
@ -505,6 +506,14 @@ export function ZoneObjectSelector({
|
||||
}: ZoneObjectSelectorProps) {
|
||||
const { data: config } = useSWR<FrigateConfig>("config");
|
||||
|
||||
const attributeLabels = useMemo(() => {
|
||||
if (!config) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return getAttributeLabels(config);
|
||||
}, [config]);
|
||||
|
||||
const cameraConfig = useMemo(() => {
|
||||
if (config && camera) {
|
||||
return config.cameras[camera];
|
||||
@ -519,7 +528,7 @@ export function ZoneObjectSelector({
|
||||
const labels = new Set<string>();
|
||||
|
||||
cameraConfig.objects.track.forEach((label) => {
|
||||
if (!ATTRIBUTE_LABELS.includes(label)) {
|
||||
if (!attributeLabels.includes(label)) {
|
||||
labels.add(label);
|
||||
}
|
||||
});
|
||||
@ -527,7 +536,7 @@ export function ZoneObjectSelector({
|
||||
if (zoneName) {
|
||||
if (cameraConfig.zones[zoneName]) {
|
||||
cameraConfig.zones[zoneName].objects.forEach((label) => {
|
||||
if (!ATTRIBUTE_LABELS.includes(label)) {
|
||||
if (!attributeLabels.includes(label)) {
|
||||
labels.add(label);
|
||||
}
|
||||
});
|
||||
@ -535,7 +544,7 @@ export function ZoneObjectSelector({
|
||||
}
|
||||
|
||||
return [...labels].sort() || [];
|
||||
}, [config, cameraConfig, zoneName]);
|
||||
}, [config, cameraConfig, attributeLabels, zoneName]);
|
||||
|
||||
const [currentLabels, setCurrentLabels] = useState<string[] | undefined>(
|
||||
selectedLabels,
|
||||
|
@ -3,7 +3,7 @@ import {
|
||||
useInitialCameraState,
|
||||
useMotionActivity,
|
||||
} from "@/api/ws";
|
||||
import { ATTRIBUTE_LABELS, CameraConfig } from "@/types/frigateConfig";
|
||||
import { CameraConfig, FrigateConfig } from "@/types/frigateConfig";
|
||||
import { MotionData, ReviewSegment } from "@/types/review";
|
||||
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||
import { useTimelineUtils } from "./use-timeline-utils";
|
||||
@ -11,6 +11,8 @@ import { ObjectType } from "@/types/ws";
|
||||
import useDeepMemo from "./use-deep-memo";
|
||||
import { isEqual } from "lodash";
|
||||
import { useAutoFrigateStats } from "./use-stats";
|
||||
import useSWR from "swr";
|
||||
import { getAttributeLabels } from "@/utils/iconUtil";
|
||||
|
||||
type useCameraActivityReturn = {
|
||||
activeTracking: boolean;
|
||||
@ -23,6 +25,16 @@ export function useCameraActivity(
|
||||
camera: CameraConfig,
|
||||
revalidateOnFocus: boolean = true,
|
||||
): useCameraActivityReturn {
|
||||
const { data: config } = useSWR<FrigateConfig>("config", {
|
||||
revalidateOnFocus: false,
|
||||
});
|
||||
const attributeLabels = useMemo(() => {
|
||||
if (!config) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return getAttributeLabels(config);
|
||||
}, [config]);
|
||||
const [objects, setObjects] = useState<ObjectType[]>([]);
|
||||
|
||||
// init camera activity
|
||||
@ -99,7 +111,7 @@ export function useCameraActivity(
|
||||
if (updatedEvent.after.sub_label) {
|
||||
const sub_label = updatedEvent.after.sub_label[0];
|
||||
|
||||
if (ATTRIBUTE_LABELS.includes(sub_label)) {
|
||||
if (attributeLabels.includes(sub_label)) {
|
||||
label = sub_label;
|
||||
} else {
|
||||
label = `${label}-verified`;
|
||||
@ -113,7 +125,7 @@ export function useCameraActivity(
|
||||
}
|
||||
|
||||
handleSetObjects(newObjects);
|
||||
}, [camera, updatedEvent, objects, handleSetObjects]);
|
||||
}, [attributeLabels, camera, updatedEvent, objects, handleSetObjects]);
|
||||
|
||||
// determine if camera is offline
|
||||
|
||||
|
@ -19,14 +19,6 @@ export interface BirdseyeConfig {
|
||||
width: number;
|
||||
}
|
||||
|
||||
export const ATTRIBUTE_LABELS = [
|
||||
"amazon",
|
||||
"face",
|
||||
"fedex",
|
||||
"license_plate",
|
||||
"ups",
|
||||
];
|
||||
|
||||
export type SearchModelSize = "small" | "large";
|
||||
|
||||
export interface CameraConfig {
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { IconName } from "@/components/icons/IconPicker";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { BsPersonWalking } from "react-icons/bs";
|
||||
import {
|
||||
FaAmazon,
|
||||
@ -36,6 +37,19 @@ import { LuBox, LuLassoSelect } from "react-icons/lu";
|
||||
import * as LuIcons from "react-icons/lu";
|
||||
import { MdRecordVoiceOver } from "react-icons/md";
|
||||
|
||||
export function getAttributeLabels(config?: FrigateConfig) {
|
||||
if (!config) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const labels = new Set();
|
||||
|
||||
Object.values(config.model.attributes_map).forEach((values) =>
|
||||
values.forEach((label) => labels.add(label)),
|
||||
);
|
||||
return [...labels];
|
||||
}
|
||||
|
||||
export function isValidIconName(value: string): value is IconName {
|
||||
return Object.keys(LuIcons).includes(value as IconName);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user