from pydantic import BaseModel, Field from typing import Optional, List, Dict, Any from datetime import datetime class DeviceBase(BaseModel): name: str = Field(..., description="设备名称") device_type: str = Field(..., description="设备类型") location: Optional[str] = Field(None, description="设备位置") ip_address: Optional[str] = Field(None, description="IP地址") port: Optional[int] = Field(None, description="端口号") username: Optional[str] = Field(None, description="用户名") password: Optional[str] = Field(None, description="密码") rtsp_url: Optional[str] = Field(None, description="RTSP流地址") status: str = Field("offline", description="设备状态") resolution: Optional[str] = Field(None, description="分辨率") fps: Optional[int] = Field(None, description="帧率") algorithm_id: Optional[int] = Field(None, description="关联的算法ID") is_enabled: bool = Field(True, description="是否启用") latitude: Optional[float] = Field(None, description="纬度") longitude: Optional[float] = Field(None, description="经度") description: Optional[str] = Field(None, description="设备描述") manufacturer: Optional[str] = Field(None, description="制造商") model: Optional[str] = Field(None, description="设备型号") serial_number: Optional[str] = Field(None, description="序列号") class DeviceCreate(DeviceBase): pass class DeviceUpdate(BaseModel): name: Optional[str] = None device_type: Optional[str] = None location: Optional[str] = None ip_address: Optional[str] = None port: Optional[int] = None username: Optional[str] = None password: Optional[str] = None rtsp_url: Optional[str] = None status: Optional[str] = None resolution: Optional[str] = None fps: Optional[int] = None algorithm_id: Optional[int] = None is_enabled: Optional[bool] = None latitude: Optional[float] = None longitude: Optional[float] = None description: Optional[str] = None manufacturer: Optional[str] = None model: Optional[str] = None serial_number: Optional[str] = None class DeviceResponse(DeviceBase): id: int created_at: datetime updated_at: datetime last_heartbeat: Optional[datetime] = None class Config: from_attributes = True class DeviceListResponse(BaseModel): devices: List[DeviceResponse] total: int page: int size: int