Miscellaneous fixes (#23373)

* republish MQTT switch states when a profile is activated or deactivated

* fix object mask default name when created from Explore tracking details

* tweak annotation offset max in UI

* optimize recordings/unavailable gap detection and drop empty motion activity buckets

* add tests
This commit is contained in:
Josh Hawkins
2026-06-01 13:55:52 -06:00
committed by GitHub
parent 8073174c20
commit 570e21340a
8 changed files with 185 additions and 16 deletions
+49 -1
View File
@@ -5,7 +5,7 @@ import json
import logging
from datetime import datetime, timezone
from pathlib import Path
from typing import Optional
from typing import Any, Callable, Optional
from frigate.config.camera.updater import (
CameraConfigUpdateEnum,
@@ -34,6 +34,45 @@ PROFILE_SECTION_UPDATES: dict[str, CameraConfigUpdateEnum] = {
"zones": CameraConfigUpdateEnum.zones,
}
# Retained MQTT switch topics per profile section, with a payload getter.
# Republished on profile change so MQTT/HA don't show a stale toggle.
SECTION_STATE_TOPICS: dict[str, list[tuple[str, Callable[[Any], Any]]]] = {
"audio": [("audio", lambda c: "ON" if c.audio.enabled else "OFF")],
"birdseye": [
("birdseye", lambda c: "ON" if c.birdseye.enabled else "OFF"),
(
"birdseye_mode",
lambda c: c.birdseye.mode.value.upper() if c.birdseye.enabled else "OFF",
),
],
"detect": [("detect", lambda c: "ON" if c.detect.enabled else "OFF")],
"motion": [
("motion", lambda c: "ON" if c.motion.enabled else "OFF"),
("improve_contrast", lambda c: "ON" if c.motion.improve_contrast else "OFF"),
("motion_threshold", lambda c: c.motion.threshold),
("motion_contour_area", lambda c: c.motion.contour_area),
],
"notifications": [
("notifications", lambda c: "ON" if c.notifications.enabled else "OFF"),
],
"objects": [
("object_descriptions", lambda c: "ON" if c.objects.genai.enabled else "OFF"),
],
"record": [("recordings", lambda c: "ON" if c.record.enabled else "OFF")],
"review": [
("review_alerts", lambda c: "ON" if c.review.alerts.enabled else "OFF"),
(
"review_detections",
lambda c: "ON" if c.review.detections.enabled else "OFF",
),
(
"review_descriptions",
lambda c: "ON" if c.review.genai.enabled else "OFF",
),
],
"snapshots": [("snapshots", lambda c: "ON" if c.snapshots.enabled else "OFF")],
}
PERSISTENCE_FILE = Path(CONFIG_DIR) / ".profiles"
@@ -310,6 +349,15 @@ class ProfileManager:
settings,
)
# republish MQTT switch states
if self.dispatcher is not None:
for suffix, get_payload in SECTION_STATE_TOPICS.get(section, ()):
self.dispatcher.publish(
f"{cam_name}/{suffix}/state",
get_payload(cam_config),
retain=True,
)
def _persist_active_profile(self, profile_name: Optional[str]) -> None:
"""Persist the active profile state to disk as JSON."""
try: