From 8212b66ee0f19e1e393b784884abdff6d644b889 Mon Sep 17 00:00:00 2001 From: Nicolas Mowen Date: Tue, 6 Aug 2024 09:08:43 -0600 Subject: [PATCH] Use camera status to get state of camera config (#12787) * Use camera status to get state of camera config * Fix spelling --- frigate/comms/dispatcher.py | 15 ++++++++++++- web/src/api/ws.tsx | 44 ++++++++++++++++++++++--------------- 2 files changed, 40 insertions(+), 19 deletions(-) diff --git a/frigate/comms/dispatcher.py b/frigate/comms/dispatcher.py index db6c44c11..26922f284 100644 --- a/frigate/comms/dispatcher.py +++ b/frigate/comms/dispatcher.py @@ -129,7 +129,20 @@ class Dispatcher: elif topic == UPDATE_CAMERA_ACTIVITY: self.camera_activity = payload elif topic == "onConnect": - self.publish("camera_activity", json.dumps(self.camera_activity)) + camera_status = self.camera_activity.copy() + + for camera in camera_status.keys(): + camera_status[camera]["config"] = { + "detect": self.config.cameras[camera].detect.enabled, + "snapshots": self.config.cameras[camera].snapshots.enabled, + "record": self.config.cameras[camera].record.enabled, + "audio": self.config.cameras[camera].audio.enabled, + "autotracking": self.config.cameras[ + camera + ].onvif.autotracking.enabled, + } + + self.publish("camera_activity", json.dumps(camera_status)) else: self.publish(topic, payload, retain=False) diff --git a/web/src/api/ws.tsx b/web/src/api/ws.tsx index afcbaa0c0..94f381ada 100644 --- a/web/src/api/ws.tsx +++ b/web/src/api/ws.tsx @@ -1,7 +1,6 @@ import { baseUrl } from "./baseUrl"; import { useCallback, useEffect, useState } from "react"; import useWebSocket, { ReadyState } from "react-use-websocket"; -import { FrigateConfig } from "@/types/frigateConfig"; import { FrigateCameraState, FrigateEvent, @@ -9,7 +8,6 @@ import { ToggleableSetting, } from "@/types/ws"; import { FrigateStats } from "@/types/stats"; -import useSWR from "swr"; import { createContainer } from "react-tracked"; import useDeepMemo from "@/hooks/use-deep-memo"; @@ -26,40 +24,50 @@ type WsState = { type useValueReturn = [WsState, (update: Update) => void]; function useValue(): useValueReturn { - // basic config - const { data: config } = useSWR("config", { - revalidateOnFocus: false, - }); const wsUrl = `${baseUrl.replace(/^http/, "ws")}ws`; // main state + + const [hasCameraState, setHasCameraState] = useState(false); const [wsState, setWsState] = useState({}); useEffect(() => { - if (!config) { + if (hasCameraState) { + return; + } + + const activityValue: string = wsState["camera_activity"] as string; + + if (!activityValue) { + return; + } + + const cameraActivity: { [key: string]: object } = JSON.parse(activityValue); + + if (!cameraActivity) { return; } const cameraStates: WsState = {}; - Object.keys(config.cameras).forEach((camera) => { - const { name, record, detect, snapshots, audio, onvif } = - config.cameras[camera]; - cameraStates[`${name}/recordings/state`] = record.enabled ? "ON" : "OFF"; - cameraStates[`${name}/detect/state`] = detect.enabled ? "ON" : "OFF"; - cameraStates[`${name}/snapshots/state`] = snapshots.enabled - ? "ON" - : "OFF"; - cameraStates[`${name}/audio/state`] = audio.enabled ? "ON" : "OFF"; - cameraStates[`${name}/ptz_autotracker/state`] = onvif.autotracking.enabled + Object.entries(cameraActivity).forEach(([name, state]) => { + const { record, detect, snapshots, audio, autotracking } = + // @ts-expect-error we know this is correct + state["config"]; + cameraStates[`${name}/recordings/state`] = record ? "ON" : "OFF"; + cameraStates[`${name}/detect/state`] = detect ? "ON" : "OFF"; + cameraStates[`${name}/snapshots/state`] = snapshots ? "ON" : "OFF"; + cameraStates[`${name}/audio/state`] = audio ? "ON" : "OFF"; + cameraStates[`${name}/ptz_autotracker/state`] = autotracking ? "ON" : "OFF"; }); setWsState({ ...wsState, ...cameraStates }); + setHasCameraState(true); // we only want this to run initially when the config is loaded // eslint-disable-next-line react-hooks/exhaustive-deps - }, [config]); + }, [wsState]); // ws handler const { sendJsonMessage, readyState } = useWebSocket(wsUrl, {