Files
banban/talkingq-url/services/ota_flow_controller.py
2026-03-24 15:04:36 +08:00

117 lines
5.0 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import asyncio
from typing import Dict, Optional, Any
from utils.logger import session_logger
from services.device_update_manager import device_firmware_update_manager
from services.system_config_manager import system_config_manager
from services.connection_manager import connection_manager
class OTAFlowController:
def __init__(self):
self.active_updates: Dict[str, Dict[str, Any]] = {} # 跟踪活跃的更新流程
def compare_versions(self, current_version: str, latest_version: str) -> bool:
"""
比较版本号,判断是否需要更新
Args:
current_version: 当前版本号 (格式: x.y.z)
latest_version: 最新版本号 (格式: x.y.z)
Returns:
bool: 如果需要更新返回True否则返回False
"""
try:
if not current_version or current_version == "unknown" or current_version == "0.0.0":
return True
current_parts = [int(x) for x in current_version.split('.')]
latest_parts = [int(x) for x in latest_version.split('.')]
while len(current_parts) < len(latest_parts):
current_parts.append(0)
while len(latest_parts) < len(current_parts):
latest_parts.append(0)
for i in range(len(current_parts)):
if latest_parts[i] > current_parts[i]:
return True
elif latest_parts[i] < current_parts[i]:
return False
return False # 版本相同,不需要更新
except Exception as e:
session_logger.error("system", "ota_flow", f"版本比较出错: {str(e)}")
return True # 出错时默认需要更新
async def start_update_flow(self, device_id: str) -> Dict[str, Any]:
"""启动更新流程"""
request_success = await device_firmware_update_manager.request_firmware_version(device_id)
if not request_success:
websocket = await connection_manager.get_connection(device_id)
return {"status": "error", "message": "请求设备固件版本失败"}
for _ in range(10):
await asyncio.sleep(0.5)
latest_version_config = await system_config_manager.get_config('latest_firmware_version')
if not latest_version_config:
return {"status": "error", "message": "未找到最新版本信息"}
latest_version = latest_version_config.config_value
current_version = "0.0.0"
device_update = await device_firmware_update_manager.get_firmware_update(device_id)
if device_update:
current_version = device_update.firmware_version
need_update = self.compare_versions(current_version, latest_version)
self.active_updates[device_id] = {
"need_update": need_update,
"status": "checked",
"current_version": current_version,
"latest_version": latest_version
}
return {
"status": "success",
"need_update": need_update,
"currentVersion": current_version,
"latestVersion": latest_version
}
async def execute_update(self, device_id: str) -> Dict[str, Any]:
"""执行更新"""
update_url_config = await system_config_manager.get_config('update_firmware_url')
if not update_url_config:
return {"status": "error", "message": "未找到更新URL"}
update_url = update_url_config.config_value
websocket = await connection_manager.get_connection(device_id)
if not websocket:
return {"status": "error", "message": "设备未连接"}
try:
await websocket.send_text(f"UPDATE_FIRMWARE:{update_url}")
session_logger.info(device_id, "ota_flow", f"已发送固件URL到设备: {update_url}")
await device_firmware_update_manager.update_firmware_update(
device_id,
firmware_version="updating", # 临时版本标记
update_status="updating"
)
await device_firmware_update_manager.update_firmware_progress(device_id, 0.0)
return {"status": "success", "message": "更新已启动"}
except Exception as e:
session_logger.error(device_id, "ota_flow", f"执行更新过程中出错: {str(e)}")
return {"status": "error", "message": str(e)}
async def get_update_status(self, device_id: str) -> Dict[str, Any]:
"""获取更新状态"""
device_update = await device_firmware_update_manager.get_firmware_update(device_id)
if not device_update:
return {"status": "unknown", "progress": 0, "version": "unknown"}
return {
"status": device_update.update_status,
"progress": device_update.progress or 0.0,
"version": device_update.firmware_version
}
ota_flow_controller = OTAFlowController()