Fixes (#23130)
CI / AMD64 Build (push) Has been cancelled
CI / ARM Build (push) Has been cancelled
CI / Jetson Jetpack 6 (push) Has been cancelled
CI / AMD64 Extra Build (push) Has been cancelled
CI / ARM Extra Build (push) Has been cancelled
CI / Synaptics Build (push) Has been cancelled
CI / Assemble and push default build (push) Has been cancelled

* respect section hiddenFields when detecting config overrides

* change audio events to audio detection to match docs

* add field messages for object and review genai

* add more config messages

* more messages

* add guard to prevent race when adding camera dynamically

* fix duplicate websocket messages from zombie connection under react strict mode

detach ws event handlers before close() in WsProvider cleanup so a CONNECTING socket's deferred onclose can't schedule a reconnect after the next mount resets the unmounted guard, which was spawning a second live ws and duplicating every message

* fix double event publishes for stationary objects with attributes
This commit is contained in:
Josh Hawkins
2026-05-07 12:23:02 -06:00
committed by GitHub
parent d0f44de6bc
commit 4ff7ab96dc
17 changed files with 205 additions and 41 deletions
@@ -3,6 +3,15 @@ import type { SectionConfigOverrides } from "./types";
const detect: SectionConfigOverrides = {
base: {
sectionDocs: "/configuration/camera_specific",
messages: [
{
key: "detect-disabled",
messageKey: "configMessages.detect.disabled",
severity: "info",
condition: (ctx) =>
ctx.level === "camera" && ctx.formData?.enabled === false,
},
],
fieldMessages: [
{
key: "fps-greater-than-five",
@@ -53,6 +53,16 @@ const faceRecognition: SectionConfigOverrides = {
"device",
],
restartRequired: ["enabled", "model_size", "device"],
fieldMessages: [
{
key: "model-size-large",
field: "model_size",
messageKey: "configMessages.faceRecognition.modelSizeLarge",
severity: "info",
position: "after",
condition: (ctx) => ctx.formData?.model_size === "large",
},
],
uiSchema: {
model_size: {
"ui:options": { size: "xs" },
@@ -65,6 +65,16 @@ const lpr: SectionConfigOverrides = {
"replace_rules",
],
restartRequired: ["model_size", "enhancement", "device"],
fieldMessages: [
{
key: "model-size-large",
field: "model_size",
messageKey: "configMessages.lpr.modelSizeLarge",
severity: "info",
position: "after",
condition: (ctx) => ctx.formData?.model_size === "large",
},
],
uiSchema: {
format: {
"ui:options": { size: "md" },
@@ -11,6 +11,32 @@ const hideAttributeFilters = (config: FrigateConfig): string[] =>
const objects: SectionConfigOverrides = {
base: {
sectionDocs: "/configuration/object_filters",
messages: [
{
key: "detect-disabled",
messageKey: "configMessages.detect.disabled",
severity: "info",
condition: (ctx) =>
ctx.level === "camera" &&
ctx.fullCameraConfig?.detect?.enabled === false,
},
],
fieldMessages: [
{
key: "genai-no-descriptions-provider",
field: "genai.enabled",
messageKey: "configMessages.objects.genaiNoDescriptionsProvider",
severity: "warning",
position: "before",
condition: (ctx) => {
const providers = ctx.fullConfig.genai;
if (!providers || Object.keys(providers).length === 0) return true;
return !Object.values(providers).some((agent) =>
agent.roles?.includes("descriptions"),
);
},
},
],
fieldDocs: {
"filters.min_area": "/configuration/object_filters#object-area",
"filters.max_area": "/configuration/object_filters#object-area",
@@ -41,6 +41,38 @@ const review: SectionConfigOverrides = {
return !Array.isArray(labels) || labels.length === 0;
},
},
{
key: "genai-no-descriptions-provider",
field: "genai.enabled",
messageKey: "configMessages.objects.genaiNoDescriptionsProvider",
severity: "warning",
position: "before",
condition: (ctx) => {
const providers = ctx.fullConfig.genai;
if (!providers || Object.keys(providers).length === 0) return true;
return !Object.values(providers).some((agent) =>
agent.roles?.includes("descriptions"),
);
},
},
{
key: "genai-image-source-recordings-record-disabled",
field: "genai.image_source",
messageKey:
"configMessages.review.genaiImageSourceRecordingsRecordDisabled",
severity: "warning",
position: "after",
condition: (ctx) => {
const genai = ctx.formData?.genai as
| Record<string, unknown>
| undefined;
if (genai?.image_source !== "recordings") return false;
if (ctx.level === "camera" && ctx.fullCameraConfig) {
return ctx.fullCameraConfig.record?.enabled === false;
}
return ctx.fullConfig.record?.enabled === false;
},
},
],
fieldDocs: {
"alerts.labels": "/configuration/review/#alerts-and-detections",
@@ -18,6 +18,18 @@ const semanticSearch: SectionConfigOverrides = {
advancedFields: ["reindex", "device"],
restartRequired: ["enabled", "model", "model_size", "device"],
hiddenFields: ["reindex"],
fieldMessages: [
{
key: "jinav2-small-model-size",
field: "model_size",
messageKey: "configMessages.semanticSearch.jinav2SmallModelSize",
severity: "warning",
position: "after",
condition: (ctx) =>
ctx.formData?.model === "jinav2" &&
ctx.formData?.model_size === "small",
},
],
uiSchema: {
model: {
"ui:widget": "semanticSearchModel",