Refactor Notices and System Health pane (#24243)

* refactor notices

* show startup message for enrichments in health pane

* tweaks
This commit is contained in:
Josh Hawkins
2026-09-12 07:30:04 -06:00
committed by Nicolas Mowen
parent 5cef6823a6
commit 7bc32fd4c9
50 changed files with 2471 additions and 898 deletions
+3 -1
View File
@@ -180,13 +180,15 @@ export function evaluateConfigHealth(
cameraMessages
.filter((message) => isActive(message, ctx))
.forEach((message) => {
// camera names have no dots, so the backend can tell this suffix
// from global and modelN when the camera is deleted
const problem = toProblem(
message,
section,
ctx,
camera.name,
true,
camera.name,
`camera.${camera.name}`,
t,
);
+28 -6
View File
@@ -8,8 +8,8 @@ import type {
DetectionModelConfig,
FrigateConfig,
} from "@/types/frigateConfig";
import type { FrigateStats, GpuVendor } from "@/types/stats";
import { InferenceThreshold } from "@/types/graph";
import type { EmbeddingsStats, FrigateStats, GpuVendor } from "@/types/stats";
import { EmbeddingThreshold, InferenceThreshold } from "@/types/graph";
import { summarizeDevices } from "@/utils/detectionHardware";
import { isReplayCamera } from "@/utils/cameraUtil";
import { resolveCameraName } from "@/hooks/use-camera-friendly-name";
@@ -527,6 +527,26 @@ type EnrichmentSpec = {
presenceOnly: boolean;
};
type SpeedKey = Exclude<keyof EmbeddingsStats, "devices">;
// the stats that time each enrichment's inference
const SPEED_KEYS: Record<EnrichmentSpec["id"], SpeedKey[]> = {
semantic_search: ["image_embedding_speed", "text_embedding_speed"],
face_recognition: ["face_recognition_speed"],
lpr: ["plate_recognition_speed", "yolov9_plate_detection_speed"],
audio_transcription: [],
};
/** Whether an enrichment's inference is past the warning line its chart draws. */
function inferenceIsSlow(
stats: FrigateStats | undefined,
id: EnrichmentSpec["id"],
): boolean {
return SPEED_KEYS[id].some(
(key) => (stats?.embeddings?.[key] ?? 0) > EmbeddingThreshold.warning,
);
}
function enrichmentSpecs(config: FrigateConfig): EnrichmentSpec[] {
const ss = config.semantic_search;
const anyCameraTranscribes = Object.values(config.cameras).some(
@@ -682,9 +702,10 @@ export function enrichmentRows({
id,
state: "unknown",
label,
message: t("health.hardware.modelNotRunYet", {
ns: "views/system",
}),
message:
startup || !stats
? t("health.hardware.justStarted", { ns: "views/system" })
: t("health.hardware.modelNotRunYet", { ns: "views/system" }),
};
}
@@ -706,7 +727,8 @@ export function enrichmentRows({
};
}
if (runtimeIsCpu && present) {
// a model that keeps up on the CPU needs no accelerator
if (runtimeIsCpu && present && inferenceIsSlow(stats, spec.id)) {
return {
id,
state: "warning",
+1 -1
View File
@@ -1,7 +1,7 @@
import type { HealthProblem } from "@/types/health";
const SEVERITY_ORDER = { error: 0, warning: 1, info: 2 } as const;
const SOURCE_ORDER = { registry: 0, live: 1, config: 2, stream: 3 } as const;
const SOURCE_ORDER = { registry: 0, config: 1, stream: 2 } as const;
/** errors first, then warnings, then info; within a severity by source, then scope */
export function sortHealthProblems(problems: HealthProblem[]): HealthProblem[] {
-4
View File
@@ -1,4 +0,0 @@
/** GitHub release page for a Frigate version such as "0.19.0". */
export function releaseUrl(version: string): string {
return `https://github.com/blakeblackshear/frigate/releases/tag/v${version}`;
}