diff --git a/core/config_sync.py b/core/config_sync.py index efc3a77..542625e 100644 --- a/core/config_sync.py +++ b/core/config_sync.py @@ -212,18 +212,24 @@ class ConfigSyncManager: update_type = data.get("type", "full") affected_items = data.get("affected_items", []) version = data.get("version", self._config_version) - + logger.info(f"收到配置更新通知: type={update_type}, items={affected_items}") - + + # 从Redis同步最新配置到SQLite(主推理管线从SQLite读取) + self._sync_redis_to_sqlite(affected_items) + if "camera" in affected_items or "all" in affected_items: self._cache.delete("cameras") - + if "roi" in affected_items or "all" in affected_items: self._cache.delete("rois") - + + # 清除所有带 camera_id 前缀的 rois_bindings 缓存 + self._cache.clear() + self._config_version = version self._notify_callbacks("config_update", data) - + self._version_control.record_update( version=version, update_type="配置更新", @@ -232,6 +238,88 @@ class ConfigSyncManager: affected_items=affected_items, details=data ) + + def _sync_redis_to_sqlite(self, affected_items: List[str]): + """从Redis同步配置到SQLite,使主推理管线能读取最新配置""" + self._init_database() + if not self._redis_client or not self._db_manager: + logger.warning("Redis或SQLite不可用,跳过同步") + return + + try: + sync_cameras = "camera" in affected_items or "all" in affected_items + sync_rois = "roi" in affected_items or "all" in affected_items + + count = 0 + + if sync_cameras: + camera_keys = self._redis_client.keys("config:camera:*") + for key in (camera_keys or []): + try: + data = self._redis_client.hgetall(key) + if not data or not data.get("camera_id"): + continue + enabled = data.get("enabled", "True") == "True" + self._db_manager.save_camera_config( + camera_id=data["camera_id"], + rtsp_url=data.get("rtsp_url", ""), + camera_name=data.get("camera_name", ""), + enabled=enabled, + location=data.get("location", ""), + ) + count += 1 + except Exception as e: + logger.error(f"同步摄像头配置到SQLite失败: key={key}, error={e}") + + if sync_rois: + # 同步ROI配置 + roi_keys = self._redis_client.keys("config:roi:*") + for key in (roi_keys or []): + try: + data = self._redis_client.hgetall(key) + if not data or not data.get("roi_id"): + continue + coordinates = eval(data["coordinates"]) if data.get("coordinates") else [] + enabled = data.get("enabled", "True") == "True" + priority = int(data.get("priority", 0)) + self._db_manager.save_roi_config( + roi_id=data["roi_id"], + camera_id=data.get("camera_id", ""), + roi_type=data.get("roi_type", "polygon"), + coordinates=coordinates, + enabled=enabled, + priority=priority, + ) + count += 1 + except Exception as e: + logger.error(f"同步ROI配置到SQLite失败: key={key}, error={e}") + + # 同步绑定配置 + bind_keys = self._redis_client.keys("config:bind:*") + for key in (bind_keys or []): + try: + data = self._redis_client.hgetall(key) + if not data or not data.get("bind_id"): + continue + params = eval(data["params"]) if data.get("params") else {} + enabled = data.get("enabled", "True") == "True" + priority = int(data.get("priority", 0)) + self._db_manager.save_roi_algo_bind( + bind_id=data["bind_id"], + roi_id=data.get("roi_id", ""), + algo_code=data.get("algo_code", ""), + params=params, + priority=priority, + enabled=enabled, + ) + count += 1 + except Exception as e: + logger.error(f"同步绑定配置到SQLite失败: key={key}, error={e}") + + logger.info(f"Redis→SQLite同步完成: {count} 条配置已更新") + + except Exception as e: + logger.error(f"Redis→SQLite同步失败: {e}") def start_config_subscription(self): """启动配置订阅线程"""