from fastapi import APIRouter, HTTPException, Depends, Path, Query from pydantic import BaseModel from typing import Dict, Any, Optional from api.auth import api_auth, client_auth from api.response import Response from services.ota_flow_controller import ota_flow_controller from utils.logger import session_logger from services.connection_manager import connection_manager from services.system_config_manager import system_config_manager router = APIRouter(prefix="/api/ota", tags=["OTA"]) class OTAStatusResponse(BaseModel): status: str progress: float version: str class FirmwareUpdateSettings(BaseModel): version: str url: str @router.get("/check/{device_id}", response_model=Response) async def check_update( device_id: str = Path(..., description="设备ID"), authenticated: bool = Depends(api_auth) ): """检查设备是否需要更新 (APP调用)""" try: result = await ota_flow_controller.start_update_flow(device_id) if result["status"] == "error": return Response(code=-1, msg=result["message"], data={}) return Response(code=0, msg="success", data=result) except Exception as e: session_logger.error(device_id, "ota", f"检查更新失败: {str(e)}") return Response(code=-1, msg=f"检查更新失败: {str(e)}", data={}) @router.post("/start/{device_id}", response_model=Response) async def start_update( device_id: str = Path(..., description="设备ID"), authenticated: bool = Depends(api_auth) ): """启动设备更新 (APP调用)""" try: result = await ota_flow_controller.execute_update(device_id) if result["status"] == "error": return Response(code=-1, msg=result["message"], data={}) return Response(code=0, msg="success", data={"updating": True}) except Exception as e: session_logger.error(device_id, "ota", f"启动更新失败: {str(e)}") return Response(code=-1, msg=f"启动更新失败: {str(e)}", data={"updating": False}) @router.get("/status/{device_id}", response_model=Response) async def get_update_status( device_id: str = Path(..., description="设备ID"), authenticated: bool = Depends(api_auth) ): """获取设备更新状态 (APP调用)""" try: status = await ota_flow_controller.get_update_status(device_id) websocket = await connection_manager.get_connection(device_id) status["device_online"] = websocket is not None return Response(code=0, msg="success", data=status) except Exception as e: session_logger.error(device_id, "ota", f"获取更新状态失败: {str(e)}") return Response(code=-1, msg=f"获取更新状态失败: {str(e)}", data={ "status": "error", "progress": 0, "version": "unknown", "device_online": False }) @router.post("/config/firmware", response_model=Response) async def update_firmware_settings( settings: FirmwareUpdateSettings, admin_api_key: str = Depends(api_auth) ): """更新固件配置信息(版本和URL)""" try: await system_config_manager.update_config('latest_firmware_version', settings.version) await system_config_manager.update_config('update_firmware_url', settings.url) return Response(code=0, msg="固件配置已更新", data={ "version": settings.version, "url": settings.url }) except Exception as e: session_logger.error("system", "ota", f"更新固件配置失败: {str(e)}") return Response(code=-1, msg=f"更新固件配置失败: {str(e)}", data={}) @router.get("/config/firmware", response_model=Response) async def get_firmware_settings( admin_api_key: str = Depends(api_auth) ): """获取当前固件配置信息""" try: version_config = await system_config_manager.get_config('latest_firmware_version') url_config = await system_config_manager.get_config('update_firmware_url') return Response(code=0, msg="success", data={ "version": version_config.config_value if version_config else "", "url": url_config.config_value if url_config else "" }) except Exception as e: session_logger.error("system", "ota", f"获取固件配置失败: {str(e)}") return Response(code=-1, msg=f"获取固件配置失败: {str(e)}", data={})