Files
workphone-sdk/sdk/app/routers/projects.py

148 lines
3.8 KiB
Python
Raw 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.

"""
项目管理路由
管理设备与项目的绑定关系
"""
from fastapi import APIRouter
from pydantic import BaseModel
from typing import Optional, Dict, Any
from services.ws_hub import ws_hub
import uuid
from datetime import datetime
router = APIRouter(prefix="/projects", tags=["项目管理"])
class ExecuteCommand(BaseModel):
"""执行命令请求"""
action: str
params: Optional[Dict[str, Any]] = {}
# ========== 项目列表 ==========
@router.get("")
async def list_projects():
"""获取所有项目列表"""
projects = ws_hub.get_all_projects()
return {
"success": True,
"projects": list(projects.values()),
"total": len(projects)
}
@router.get("/{project_id}")
async def get_project(project_id: str):
"""获取项目详情"""
devices = ws_hub.get_project_devices(project_id)
return {
"success": True,
"project_id": project_id,
"devices": devices,
"online_count": len(devices)
}
@router.get("/{project_id}/devices")
async def get_project_devices(project_id: str):
"""获取项目下所有在线设备"""
devices = ws_hub.get_project_devices(project_id)
return {
"success": True,
"project_id": project_id,
"devices": devices,
"total": len(devices)
}
# ========== 批量执行命令 ==========
@router.post("/{project_id}/broadcast")
async def broadcast_command(project_id: str, command: ExecuteCommand):
"""
向项目下所有设备广播命令(不等待响应)
适用于打开APP、发送通知等不需要等待结果的操作
"""
msg = {
"type": "execute",
"command_id": f"cmd_{uuid.uuid4().hex[:8]}",
"action": command.action,
"params": command.params,
"timestamp": int(datetime.now().timestamp())
}
results = await ws_hub.broadcast_to_project(project_id, msg)
return {
"success": True,
"project_id": project_id,
"command": command.action,
"sent": results["success"],
"failed": results["failed"],
"details": results["devices"]
}
@router.post("/{project_id}/execute")
async def execute_command(project_id: str, command: ExecuteCommand, timeout: int = 30):
"""
在项目下所有设备执行命令(等待响应)
适用于:需要获取执行结果的操作
"""
msg = {
"type": "execute",
"action": command.action,
"params": command.params
}
results = await ws_hub.execute_on_project(project_id, msg, timeout)
success_count = sum(1 for r in results if r.get("result", {}).get("code", 500) == 200)
return {
"success": True,
"project_id": project_id,
"command": command.action,
"total_devices": len(results),
"success_count": success_count,
"results": results
}
# ========== 单设备操作 ==========
@router.post("/{project_id}/devices/{device_id}/execute")
async def execute_on_device(
project_id: str,
device_id: str,
command: ExecuteCommand,
timeout: int = 30
):
"""在指定设备上执行命令"""
# 检查设备是否属于该项目
device_info = ws_hub.get_device_info(device_id)
if not device_info:
return {"success": False, "message": "设备不存在或离线"}
if device_info.get("project_id") != project_id:
return {"success": False, "message": "设备不属于该项目"}
# 发送命令
msg = {
"type": "execute",
"action": command.action,
"params": command.params
}
result = await ws_hub.send_command(device_id, msg, timeout)
return {
"success": result.get("code", 500) == 200,
"device_id": device_id,
"result": result
}