From 8102f070ee43db7aa97b2ac087ba7fa55730071f Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Mon, 30 Jun 2025 16:39:01 -0500 Subject: [PATCH] add switch to frontend --- web/public/locales/en/views/settings.json | 4 ++ web/src/api/ws.tsx | 13 ++++++ web/src/types/ws.ts | 1 + web/src/views/settings/CameraSettingsView.tsx | 40 ++++++++++++++++++- 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/web/public/locales/en/views/settings.json b/web/public/locales/en/views/settings.json index ffdfe6d1a..8fa2451a4 100644 --- a/web/public/locales/en/views/settings.json +++ b/web/public/locales/en/views/settings.json @@ -150,6 +150,10 @@ "title": "Streams", "desc": "Disabling a camera completely stops Frigate's processing of this camera's streams. Detection, recording, and debugging will be unavailable.
Note: This does not disable go2rtc restreams." }, + "genai": { + "title": "Generative AI", + "desc": "Temporarily enable/disable Generative AI for this camera. When disabled, AI generated descriptions will not be requested for tracked objects on this camera." + }, "review": { "title": "Review", "desc": "Enable/disable alerts and detections for this camera. When disabled, no new review items will be generated.", diff --git a/web/src/api/ws.tsx b/web/src/api/ws.tsx index cc3ea05bf..af25e6a51 100644 --- a/web/src/api/ws.tsx +++ b/web/src/api/ws.tsx @@ -68,6 +68,7 @@ function useValue(): useValueReturn { autotracking, alerts, detections, + genai, } = state["config"]; cameraStates[`${name}/recordings/state`] = record ? "ON" : "OFF"; cameraStates[`${name}/enabled/state`] = enabled ? "ON" : "OFF"; @@ -89,6 +90,7 @@ function useValue(): useValueReturn { cameraStates[`${name}/review_detections/state`] = detections ? "ON" : "OFF"; + cameraStates[`${name}/genai/state`] = genai ? "ON" : "OFF"; }); setWsState((prevState) => ({ @@ -276,6 +278,17 @@ export function useDetectionsState(camera: string): { return { payload: payload as ToggleableSetting, send }; } +export function useGenAIState(camera: string): { + payload: ToggleableSetting; + send: (payload: ToggleableSetting, retain?: boolean) => void; +} { + const { + value: { payload }, + send, + } = useWs(`${camera}/genai/state`, `${camera}/genai/set`); + return { payload: payload as ToggleableSetting, send }; +} + export function usePtzCommand(camera: string): { payload: string; send: (payload: string, retain?: boolean) => void; diff --git a/web/src/types/ws.ts b/web/src/types/ws.ts index 7fad6e953..9ecb9cc6f 100644 --- a/web/src/types/ws.ts +++ b/web/src/types/ws.ts @@ -64,6 +64,7 @@ export interface FrigateCameraState { autotracking: boolean; alerts: boolean; detections: boolean; + genai: boolean; }; motion: boolean; objects: ObjectType[]; diff --git a/web/src/views/settings/CameraSettingsView.tsx b/web/src/views/settings/CameraSettingsView.tsx index db2490f53..ea0e2854f 100644 --- a/web/src/views/settings/CameraSettingsView.tsx +++ b/web/src/views/settings/CameraSettingsView.tsx @@ -29,7 +29,12 @@ import { cn } from "@/lib/utils"; import { Trans, useTranslation } from "react-i18next"; import { Switch } from "@/components/ui/switch"; import { Label } from "@/components/ui/label"; -import { useAlertsState, useDetectionsState, useEnabledState } from "@/api/ws"; +import { + useAlertsState, + useDetectionsState, + useEnabledState, + useGenAIState, +} from "@/api/ws"; import CameraEditForm from "@/components/settings/CameraEditForm"; import { LuPlus } from "react-icons/lu"; import { @@ -142,6 +147,9 @@ export default function CameraSettingsView({ const { payload: detectionsState, send: sendDetections } = useDetectionsState(selectedCamera); + const { payload: genAIState, send: sendGenAI } = + useGenAIState(selectedCamera); + const handleCheckedChange = useCallback( (isChecked: boolean) => { if (!isChecked) { @@ -402,6 +410,36 @@ export default function CameraSettingsView({ + {config?.genai?.enabled && ( + <> + + + + camera.genai.title + + +
+
+ { + sendGenAI(isChecked ? "ON" : "OFF"); + }} + /> +
+ +
+
+
+ camera.genai.desc +
+
+ + )}