""" AI Box Sophon Adapter — 设备心跳数据 Pydantic 模型(手动定义) 定义 BoardPingRequest 及其嵌套子结构。 这些模型无法通过 gen_models 自动生成(嵌套层次过深),需要手动维护。 对应 MQTT 主题 /board_ping 的上报数据结构。 命名约定: - Pydantic 模型类名以 Info 结尾(如 HostDiskInfo),避免与 JSON 字段名冲突 - 字段名直接对应 JSON key,无需 alias """ from typing import Optional from pydantic import BaseModel, Field # ============================================================ # 心跳数据子结构 # ============================================================ class HostDiskInfo(BaseModel): """设备硬盘使用情况""" Available: int = Field(..., description="可用空间 (kB)") Total: int = Field(..., description="总空间 (kB)") Used: int = Field(..., description="已用空间 (kB)") class MediaStatusInfo(BaseModel): """通道状态描述""" label: str = Field(..., description="状态标签,如 '正常'") type: int = Field(..., description="状态类型码") class MediaInfo(BaseModel): """设备通道信息""" MediaName: str = Field(..., description="通道名称") MediaStatus: MediaStatusInfo = Field(..., description="通道状态") MediaUrl: str = Field(..., description="通道视频流地址") SubId: str = Field(default="", description="关联 GB28181 通道号") class AlgItemInfo(BaseModel): """算法配置信息""" lineDesc: str = Field(default="", description="线描述") lineRequired: bool = Field(default=False, description="是否需要线") majorId: int = Field(..., description="主 ID") majorOnly: bool = Field(default=False, description="仅主算法") minorId: int = Field(default=0, description="副 ID(majorOnly=true 时可能不传)") name: str = Field(..., description="算法名称") zoneDesc: str = Field(default="", description="区域描述") zoneRequired: bool = Field(default=False, description="是否需要区域") class AlgTaskStatusInfo(BaseModel): """任务状态描述""" label: str = Field(..., description="状态标签,如 '运行中'") type: int = Field(..., description="状态类型码") class TaskInfo(BaseModel): """设备任务信息""" AlgItem: list[AlgItemInfo] = Field(default_factory=list, description="算法配置列表") AlgTaskSession: str = Field(..., description="任务号") AlgTaskStatus: AlgTaskStatusInfo = Field(..., description="任务状态") class TpuInfo(BaseModel): """TPU 算力资源使用情况""" mem_total: int = Field(..., description="内存总量") mem_usage: int = Field(..., description="内存使用量") tpu_usage: int = Field(..., description="TPU 使用率") # ============================================================ # 心跳请求体(MQTT 上报的完整数据结构) # ============================================================ class BoardPingRequest(BaseModel): """ AI Box 设备心跳上报数据 设备通过 MQTT 主题 /board_ping 定期上报。 上报间隔默认 5 秒。 包含字段:设备标识、IP、温度、硬盘、内存、GPS、 通道列表、任务列表、TPU 算力等。 """ BoardId: str = Field(..., description="当前盒子唯一标识") BoardIp: str = Field(..., description="设备 IP 地址") BoardPlatform: str = Field(..., description="当前设备硬件类型,如 'BM-BOX'") BoardTemp: str = Field(..., description="当前设备芯片温度,如 '44 (C)'") BoardType: str = Field(..., description="当前设备接入方式 WAN/4G") GBClientId: str = Field(default="", description="GB28181 设备号,配置后透传") GrantCode: int = Field(..., description="授权码") GrantDesc: str = Field(..., description="授权描述,如 '已授权'") HostDisk: HostDiskInfo = Field(..., description="当前设备硬盘情况") HostMemory: list[float] = Field(..., description="当前设备内存使用 [已使用(kB), 总利用率]") Key: str = Field(..., description="运行状态关键字,如 '运行中'") Latitude: float = Field(default=0.0, description="GPS 纬度") Longitude: float = Field(default=0.0, description="GPS 经度") Malloc: int = Field(..., description="当前应用 VmRSS 信息 (kB)") Medias: list[MediaInfo] = Field(default_factory=list, description="当前设备通道信息") Pid: int = Field(..., description="本次应用 PID") Se6ip: str = Field(default="", description="特定设备时透传主控端 IP") Status: str = Field(..., description="设备状态,如 '在线'") System: str = Field(..., description="当前设备系统版本") Tasks: list[TaskInfo] = Field(default_factory=list, description="当前设备任务信息") Time: int = Field(..., description="当前时间戳(毫秒)") Tpu: list[TpuInfo] = Field(default_factory=list, description="当前设备算力资源使用情况") Version: str = Field(..., description="软件版本") angleCourse: float = Field(default=0.0, description="GPS 角度") kSpeed: float = Field(default=0.0, description="GPS 速度 (km/h)") nSpeed: float = Field(default=0.0, description="GPS 速度 (m/s)") # ============================================================ # 设备状态摘要(API 响应用) # ============================================================ class DeviceSummary(BaseModel): """设备状态摘要(用于列表 API 响应)""" board_id: str = Field(..., description="设备唯一标识") board_ip: str = Field(..., description="设备 IP") board_platform: str = Field(..., description="硬件类型") board_type: str = Field(..., description="接入方式") board_temp: str = Field(..., description="芯片温度") status: str = Field(..., description="设备状态") version: str = Field(..., description="软件版本") is_online: bool = Field(..., description="是否在线") last_ping_time: Optional[str] = Field(default=None, description="最后心跳时间") grant_code: int = Field(..., description="授权码") grant_desc: str = Field(..., description="授权描述")