safe changes for birdseye dynamic config

This commit is contained in:
Josh Hawkins 2026-02-25 08:23:12 -06:00
parent 15bca564f2
commit bf2741e979
3 changed files with 19 additions and 9 deletions

View File

@ -273,17 +273,13 @@ class BirdsEyeFrameManager:
stop_event: mp.Event, stop_event: mp.Event,
): ):
self.config = config self.config = config
self.mode = config.birdseye.mode
width, height = get_canvas_shape(config.birdseye.width, config.birdseye.height) width, height = get_canvas_shape(config.birdseye.width, config.birdseye.height)
self.frame_shape = (height, width) self.frame_shape = (height, width)
self.yuv_shape = (height * 3 // 2, width) self.yuv_shape = (height * 3 // 2, width)
self.frame = np.ndarray(self.yuv_shape, dtype=np.uint8) self.frame = np.ndarray(self.yuv_shape, dtype=np.uint8)
self.canvas = Canvas(width, height, config.birdseye.layout.scaling_factor) self.canvas = Canvas(width, height, config.birdseye.layout.scaling_factor)
self.stop_event = stop_event self.stop_event = stop_event
self.inactivity_threshold = config.birdseye.inactivity_threshold self.last_refresh_time = 0
if config.birdseye.layout.max_cameras:
self.last_refresh_time = 0
# initialize the frame as black and with the Frigate logo # initialize the frame as black and with the Frigate logo
self.blank_frame = np.zeros(self.yuv_shape, np.uint8) self.blank_frame = np.zeros(self.yuv_shape, np.uint8)
@ -426,7 +422,7 @@ class BirdsEyeFrameManager:
and self.config.cameras[cam].enabled and self.config.cameras[cam].enabled
and cam_data["last_active_frame"] > 0 and cam_data["last_active_frame"] > 0
and cam_data["current_frame_time"] - cam_data["last_active_frame"] and cam_data["current_frame_time"] - cam_data["last_active_frame"]
< self.inactivity_threshold < self.config.birdseye.inactivity_threshold
] ]
) )
logger.debug(f"Active cameras: {active_cameras}") logger.debug(f"Active cameras: {active_cameras}")

View File

@ -15,6 +15,7 @@ from ws4py.server.wsgirefserver import (
) )
from ws4py.server.wsgiutils import WebSocketWSGIApplication from ws4py.server.wsgiutils import WebSocketWSGIApplication
from frigate.comms.config_updater import ConfigSubscriber
from frigate.comms.detections_updater import DetectionSubscriber, DetectionTypeEnum from frigate.comms.detections_updater import DetectionSubscriber, DetectionTypeEnum
from frigate.comms.ws import WebSocket from frigate.comms.ws import WebSocket
from frigate.config import FrigateConfig from frigate.config import FrigateConfig
@ -138,6 +139,7 @@ class OutputProcess(FrigateProcess):
CameraConfigUpdateEnum.record, CameraConfigUpdateEnum.record,
], ],
) )
birdseye_config_subscriber = ConfigSubscriber("config/birdseye", exact=True)
jsmpeg_cameras: dict[str, JsmpegCamera] = {} jsmpeg_cameras: dict[str, JsmpegCamera] = {}
birdseye: Birdseye | None = None birdseye: Birdseye | None = None
@ -167,6 +169,20 @@ class OutputProcess(FrigateProcess):
websocket_thread.start() websocket_thread.start()
while not self.stop_event.is_set(): while not self.stop_event.is_set():
update_topic, birdseye_config = (
birdseye_config_subscriber.check_for_update()
)
if update_topic is not None:
previous_global_mode = self.config.birdseye.mode
self.config.birdseye = birdseye_config
for camera_config in self.config.cameras.values():
if camera_config.birdseye.mode == previous_global_mode:
camera_config.birdseye.mode = birdseye_config.mode
logger.debug("Applied dynamic birdseye config update")
# check if there is an updated config # check if there is an updated config
updates = config_subscriber.check_for_updates() updates = config_subscriber.check_for_updates()
@ -297,6 +313,7 @@ class OutputProcess(FrigateProcess):
birdseye.stop() birdseye.stop()
config_subscriber.stop() config_subscriber.stop()
birdseye_config_subscriber.stop()
websocket_server.manager.close_all() websocket_server.manager.close_all()
websocket_server.manager.stop() websocket_server.manager.stop()
websocket_server.manager.join() websocket_server.manager.join()

View File

@ -28,10 +28,7 @@ const birdseye: SectionConfigOverrides = {
"width", "width",
"height", "height",
"quality", "quality",
"mode",
"layout.scaling_factor", "layout.scaling_factor",
"inactivity_threshold",
"layout.max_cameras",
"idle_heartbeat_fps", "idle_heartbeat_fps",
], ],
uiSchema: { uiSchema: {