Implement UI for managing multiple models (#24023)

* Implement hardware detection and UI management

* Cleanup Frigate+ detection

* Don't count model as changed

* Fixes for audio map error

* Add descriptions

* Enforce that all model must exist

* Fix hardware picking

* Docs fixes

* WebUI cleanup

* Cleanup handling of scenes

* UI refinement

* Cleanup recommended UI

* test fixews
This commit is contained in:
Nicolas Mowen
2026-09-12 07:30:04 -06:00
parent 3f20209339
commit 27a40a507b
59 changed files with 2554 additions and 2587 deletions
+3 -3
View File
@@ -62,10 +62,10 @@ class DetectConfig(FrigateBaseModel):
title="Detect width",
description="Width (pixels) of frames used for the detect stream; leave empty to use the native stream resolution.",
)
scene: SceneEnum | None = Field(
default=None,
scene: SceneEnum = Field(
default=SceneEnum.all,
title="Detect scene",
description="The environment this camera looks at, used to pick which of the configured models runs on it. Defaults to the model with a scene of 'all'.",
description="The environment this camera looks at, used to pick which of the configured models runs on it. Cameras left on 'all' run the model configured with a scene of 'all'.",
)
fps: int = Field(
default=5,
+14 -14
View File
@@ -807,37 +807,37 @@ class FrigateConfig(FrigateBaseModel):
}
self._all_labels = labels
def _resolve_camera_model(self, name: str, scene: SceneEnum | None) -> ModelConfig:
def _resolve_camera_model(self, name: str, scene: SceneEnum) -> ModelConfig:
"""Resolve which model a camera runs on.
A camera may name a scene no model is configured for, which is valid as
long as an 'all' model is there to fall back to.
Args:
name: Name of the camera
scene: The camera's configured detect scene, if any
scene: The camera's detect scene, which defaults to 'all'
Returns:
The model the camera runs on
"""
by_scene = {model.scene: model for model in self.models}
model = by_scene.get(scene)
if scene is not None:
model = by_scene.get(scene)
if model is None:
raise ValueError(
f"Camera '{name}' has a detect scene of '{scene.value}', but no model is configured for that scene."
)
if model is not None:
return model
default = by_scene.get(SceneEnum.all) or (
self.models[0] if len(self.models) == 1 else None
)
default = by_scene.get(SceneEnum.all)
if default is None:
raise ValueError(
f"Camera '{name}' must set detect -> scene, because more than one model is configured and none of them uses a scene of 'all'."
f"Camera '{name}' has a detect scene of '{scene.value}', but no model is configured for that scene or for 'all'."
)
logger.warning(
"Camera '%s' has a detect scene of '%s', but no model is configured for that scene, so the 'all' model is used",
name,
scene.value,
)
return default
@model_validator(mode="after")