Refactor detector and model management (#23995)

* Refactor detector and model management

* Fix model resolution field
This commit is contained in:
Nicolas Mowen
2026-09-12 07:30:04 -06:00
parent fd76eb6c6f
commit 8fe35ace3b
63 changed files with 2052 additions and 1152 deletions
+2 -1
View File
@@ -493,6 +493,7 @@ export interface SectionSavePayload {
// ---------------------------------------------------------------------------
import { resolveAndCleanSchema } from "@/lib/config-schema";
import { getAllAttributes } from "@/utils/modelUtil";
type SchemaWithDefinitions = RJSFSchema & {
$defs?: Record<string, RJSFSchema>;
@@ -796,7 +797,7 @@ export function getEffectiveAttributeLabels(
fullCameraConfig: CameraConfig | undefined,
level: "global" | "camera" | "replay" | undefined,
): string[] {
const all = fullConfig?.model?.all_attributes ?? [];
const all = getAllAttributes(fullConfig);
if (level !== "global" && fullCameraConfig?.type === "lpr") {
return all.filter((attr) => attr !== "license_plate");
}
+4 -2
View File
@@ -56,8 +56,10 @@ export function getAttributeLabels(config?: FrigateConfig) {
const labels = new Set();
Object.values(config.model.attributes_map).forEach((values) =>
values.forEach((label) => labels.add(label)),
config.models?.forEach((model) =>
Object.values(model.attributes_map ?? {}).forEach((values) =>
values.forEach((label) => labels.add(label)),
),
);
return [...labels];
}
+69
View File
@@ -0,0 +1,69 @@
import { DetectionModelConfig, FrigateConfig } from "@/types/frigateConfig";
/**
* The model a camera runs on, matched by the camera's detect scene.
*
* Falls back to the model for every scene, then to the only configured model,
* which is what the backend does when a camera does not name a scene.
*/
export function getModelForCamera(
config?: FrigateConfig,
camera?: string,
): DetectionModelConfig | undefined {
const models = config?.models;
if (!models?.length) {
return undefined;
}
const scene = camera ? config?.cameras?.[camera]?.detect?.scene : undefined;
if (scene) {
const match = models.find((model) => model.scene == scene);
if (match) {
return match;
}
}
return models.find((model) => model.scene == "all") ?? models[0];
}
/** The model used when the question is not about a specific camera. */
export function getPrimaryModel(
config?: FrigateConfig,
): DetectionModelConfig | undefined {
return getModelForCamera(config);
}
/** Every object attribute across all configured models. */
export function getAllAttributes(config?: FrigateConfig): string[] {
const attributes = new Set<string>();
config?.models?.forEach((model) =>
model.all_attributes?.forEach((attribute) => attributes.add(attribute)),
);
return [...attributes];
}
/** Whether a label is an attribute of any configured model. */
export function isAttributeLabel(
config: FrigateConfig | undefined,
label: string,
): boolean {
return !!config?.models?.some((model) =>
model.all_attributes?.includes(label),
);
}
/** Whether an attribute belongs to a parent label in any configured model. */
export function isAttributeOfLabel(
config: FrigateConfig | undefined,
label: string,
attribute: string,
): boolean {
return !!config?.models?.some((model) =>
model.attributes_map?.[label]?.includes(attribute),
);
}