Show live camera refresh status
This commit is contained in:
@@ -1500,10 +1500,66 @@ class CameraControlBridge:
|
||||
self.inherit_action_runtime_state(old_actions, new_actions)
|
||||
self.actions = new_actions
|
||||
self.refresh_snapshots()
|
||||
old_ids = set(old_actions)
|
||||
new_ids = set(new_actions)
|
||||
old_cameras = self.camera_keys_from_actions(old_actions.values())
|
||||
new_cameras = self.camera_keys_from_actions(new_actions.values())
|
||||
result = {
|
||||
"ok": True,
|
||||
"added_actions": len(new_ids - old_ids),
|
||||
"removed_actions": len(old_ids - new_ids),
|
||||
"added_cameras": len(new_cameras - old_cameras),
|
||||
"removed_cameras": len(old_cameras - new_cameras),
|
||||
"total_actions": len(new_ids),
|
||||
"total_cameras": len(new_cameras),
|
||||
"mqtt_published": True,
|
||||
}
|
||||
result["changed"] = any(
|
||||
result[key] > 0
|
||||
for key in ("added_actions", "removed_actions", "added_cameras", "removed_cameras")
|
||||
)
|
||||
try:
|
||||
self.publish_discovery()
|
||||
except Exception as exc:
|
||||
result["mqtt_published"] = False
|
||||
LOG.warning("Frigate refresh could not publish MQTT discovery: %s", exc)
|
||||
return result
|
||||
|
||||
@staticmethod
|
||||
def camera_keys_from_actions(actions):
|
||||
keys = set()
|
||||
for action in actions:
|
||||
if action.kind == "all_off":
|
||||
continue
|
||||
snapshot = action.cfg.get("snapshot") or {}
|
||||
camera = snapshot.get("camera") or action.cfg.get("camera_name")
|
||||
if camera:
|
||||
keys.add((snapshot.get("frigate_url"), camera))
|
||||
return keys
|
||||
|
||||
@staticmethod
|
||||
def refresh_message(lang, result):
|
||||
if result.get("added_cameras") or result.get("removed_cameras"):
|
||||
return text_for(
|
||||
lang,
|
||||
"refresh.cameras_changed",
|
||||
added=result.get("added_cameras", 0),
|
||||
removed=result.get("removed_cameras", 0),
|
||||
)
|
||||
if result.get("added_actions") or result.get("removed_actions"):
|
||||
return text_for(
|
||||
lang,
|
||||
"refresh.controls_changed",
|
||||
added=result.get("added_actions", 0),
|
||||
removed=result.get("removed_actions", 0),
|
||||
)
|
||||
return text_for(lang, "refresh.no_changes")
|
||||
|
||||
def refresh_payload(self, lang, result, redirect_url):
|
||||
payload = dict(result)
|
||||
payload["message"] = self.refresh_message(lang, result)
|
||||
payload["redirect_url"] = redirect_url
|
||||
return payload
|
||||
|
||||
def frigate_refresh_loop(self):
|
||||
interval = int(self.config.get("defaults", {}).get("frigate_refresh_seconds", 300))
|
||||
@@ -1661,17 +1717,33 @@ class CameraControlBridge:
|
||||
self.end_headers()
|
||||
return
|
||||
if parsed.path == "/refresh":
|
||||
token_param = urllib.parse.parse_qs(parsed.query).get("token", [None])[0]
|
||||
token_query = f"&token={urllib.parse.quote(token_param)}" if token_param else ""
|
||||
redirect_url = f"/?lang={urllib.parse.quote(lang)}{token_query}"
|
||||
wants_json = "application/json" in self.headers.get("Accept", "").lower()
|
||||
try:
|
||||
bridge.refresh_frigate_inventory()
|
||||
token_param = urllib.parse.parse_qs(parsed.query).get("token", [None])[0]
|
||||
token_query = f"&token={urllib.parse.quote(token_param)}" if token_param else ""
|
||||
self.send_response(303)
|
||||
self.send_header("Location", f"/?lang={urllib.parse.quote(lang)}{token_query}")
|
||||
self.end_headers()
|
||||
result = bridge.refresh_frigate_inventory()
|
||||
if wants_json:
|
||||
self.send_json(bridge.refresh_payload(lang, result, redirect_url))
|
||||
else:
|
||||
self.send_response(303)
|
||||
self.send_header("Location", redirect_url)
|
||||
self.end_headers()
|
||||
except Exception as exc:
|
||||
self.send_response(500)
|
||||
self.end_headers()
|
||||
self.wfile.write(str(exc).encode("utf-8"))
|
||||
if wants_json:
|
||||
self.send_json(
|
||||
{
|
||||
"ok": False,
|
||||
"changed": False,
|
||||
"message": text_for(lang, "refresh.failed", error=str(exc)),
|
||||
"redirect_url": redirect_url,
|
||||
},
|
||||
status=500,
|
||||
)
|
||||
else:
|
||||
self.send_response(500)
|
||||
self.end_headers()
|
||||
self.wfile.write(str(exc).encode("utf-8"))
|
||||
return
|
||||
parts = parsed.path.strip("/").split("/")
|
||||
if len(parts) == 3 and parts[0] == "action":
|
||||
@@ -1692,9 +1764,9 @@ class CameraControlBridge:
|
||||
self.send_response(404)
|
||||
self.end_headers()
|
||||
|
||||
def send_json(self, payload):
|
||||
def send_json(self, payload, status=200):
|
||||
data = json.dumps(payload, indent=2).encode("utf-8")
|
||||
self.send_response(200)
|
||||
self.send_response(status)
|
||||
self.send_header("Content-Type", "application/json")
|
||||
self.send_header("Content-Length", str(len(data)))
|
||||
self.end_headers()
|
||||
|
||||
Reference in New Issue
Block a user