From b13fa77edd52b311a33f652dd71987a815ca546a Mon Sep 17 00:00:00 2001 From: Eric W Date: Thu, 12 Mar 2026 19:06:51 -0400 Subject: [PATCH] expose thresholds in ms for detectors to warn or error --- docs/docs/configuration/reference.md | 6 ++++++ frigate/config/ui.py | 26 ++++++++++++++++++++++++- web/src/hooks/use-stats.ts | 10 ++++++++-- web/src/types/frigateConfig.ts | 4 ++++ web/src/views/system/GeneralMetrics.tsx | 9 ++++++++- 5 files changed, 51 insertions(+), 4 deletions(-) diff --git a/docs/docs/configuration/reference.md b/docs/docs/configuration/reference.md index cac508195..fc5877036 100644 --- a/docs/docs/configuration/reference.md +++ b/docs/docs/configuration/reference.md @@ -1052,6 +1052,12 @@ ui: # Optional: Set the unit system to either "imperial" or "metric" (default: metric) # Used in the UI and in MQTT topics unit_system: metric + # Optional: Thresholds in ms for detector inference speed warnings in the UI + inference_threshold: + # Optional: Inference speed in ms above which a warning is shown (default: shown below) + warning: 50 + # Optional: Inference speed in ms above which an error is shown (default: shown below) + error: 100 # Optional: Telemetry configuration telemetry: diff --git a/frigate/config/ui.py b/frigate/config/ui.py index 2c3104bbc..4129944a4 100644 --- a/frigate/config/ui.py +++ b/frigate/config/ui.py @@ -5,7 +5,13 @@ from pydantic import Field from .base import FrigateBaseModel -__all__ = ["TimeFormatEnum", "DateTimeStyleEnum", "UnitSystemEnum", "UIConfig"] +__all__ = [ + "TimeFormatEnum", + "DateTimeStyleEnum", + "UnitSystemEnum", + "InferenceThresholdConfig", + "UIConfig", +] class TimeFormatEnum(str, Enum): @@ -26,6 +32,19 @@ class UnitSystemEnum(str, Enum): metric = "metric" +class InferenceThresholdConfig(FrigateBaseModel): + warning: int = Field( + default=50, + title="Warning threshold (ms)", + description="Inference speed in ms above which a warning is shown in the UI.", + ) + error: int = Field( + default=100, + title="Error threshold (ms)", + description="Inference speed in ms above which an error is shown in the UI.", + ) + + class UIConfig(FrigateBaseModel): timezone: Optional[str] = Field( default=None, @@ -52,3 +71,8 @@ class UIConfig(FrigateBaseModel): title="Unit system", description="Unit system for display (metric or imperial) used in the UI and MQTT.", ) + inference_threshold: InferenceThresholdConfig = Field( + default_factory=InferenceThresholdConfig, + title="Inference threshold", + description="Thresholds for detector inference speed warnings in the UI.", + ) diff --git a/web/src/hooks/use-stats.ts b/web/src/hooks/use-stats.ts index 5bddb75ac..f2075543c 100644 --- a/web/src/hooks/use-stats.ts +++ b/web/src/hooks/use-stats.ts @@ -50,8 +50,14 @@ export default function useStats(stats: FrigateStats | undefined) { } // check detectors for high inference speeds + const inferenceThreshold = { + warning: + config?.ui?.inference_threshold?.warning ?? InferenceThreshold.warning, + error: + config?.ui?.inference_threshold?.error ?? InferenceThreshold.error, + }; Object.entries(memoizedStats["detectors"]).forEach(([key, det]) => { - if (det["inference_speed"] > InferenceThreshold.error) { + if (det["inference_speed"] > inferenceThreshold.error) { problems.push({ text: t("stats.detectIsVerySlow", { detect: capitalizeFirstLetter(key), @@ -60,7 +66,7 @@ export default function useStats(stats: FrigateStats | undefined) { color: "text-danger", relevantLink: "/system#general", }); - } else if (det["inference_speed"] > InferenceThreshold.warning) { + } else if (det["inference_speed"] > inferenceThreshold.warning) { problems.push({ text: t("stats.detectIsSlow", { detect: capitalizeFirstLetter(key), diff --git a/web/src/types/frigateConfig.ts b/web/src/types/frigateConfig.ts index dcf3c312f..a45bfa31e 100644 --- a/web/src/types/frigateConfig.ts +++ b/web/src/types/frigateConfig.ts @@ -9,6 +9,10 @@ export interface UiConfig { dashboard: boolean; order: number; unit_system?: "metric" | "imperial"; + inference_threshold?: { + warning: number; + error: number; + }; } export interface BirdseyeConfig { diff --git a/web/src/views/system/GeneralMetrics.tsx b/web/src/views/system/GeneralMetrics.tsx index cdf35c28b..389c37365 100644 --- a/web/src/views/system/GeneralMetrics.tsx +++ b/web/src/views/system/GeneralMetrics.tsx @@ -1,4 +1,5 @@ import useSWR from "swr"; +import { FrigateConfig } from "@/types/frigateConfig"; import { FrigateStats, GpuInfo } from "@/types/stats"; import { useEffect, useMemo, useState } from "react"; import { useFrigateStats } from "@/api/ws"; @@ -34,6 +35,12 @@ export default function GeneralMetrics({ // extra info const { t } = useTranslation(["views/system"]); const [showVainfo, setShowVainfo] = useState(false); + const { data: config } = useSWR("config"); + const inferenceThreshold = { + warning: + config?.ui?.inference_threshold?.warning ?? InferenceThreshold.warning, + error: config?.ui?.inference_threshold?.error ?? InferenceThreshold.error, + }; // stats @@ -626,7 +633,7 @@ export default function GeneralMetrics({ graphId={`${series.name}-inference`} name={series.name} unit="ms" - threshold={InferenceThreshold} + threshold={inferenceThreshold} updateTimes={updateTimes} data={[series]} />