from uuid import UUID from fastapi import APIRouter from fastapi import Depends from config.redis import RedisClient from db.postgres.iot import * from models.BaseResponse import BaseResponse from models.EMQXWebhook import EMQXWebhook from routers.WS import ws_manager iot_router = APIRouter() redis_client = RedisClient() from config.security import get_user_id_from_token # -------------------- 设备接口 -------------------- @iot_router.post("/common/webhook") async def emqx_webhook(data: EMQXWebhook): device_id = data.clientid event = data.event if event == "client.connected": redis_client.set_online(device_id) await ws_manager.broadcast({"deviceId": device_id, "online": True}) print(f"[ONLINE] {device_id}") elif event == "client.disconnected": redis_client.set_offline(device_id) await ws_manager.broadcast({"deviceId": device_id, "online": False}) print(f"[OFFLINE] {device_id}") else: # 其他事件直接忽略 print(f"[IGNORE] {event}") return {"ok": True} @iot_router.get("/common/device/list") async def get_device_list( page: int = 1, pageSize: int = 10, id: str | None = None, name: str | None = None, status: int | None = None, is_superuser: int | None = None, dept_id: str | None = None, startTime: str | None = None, endTime: str | None = None, user_id: UUID = Depends(get_user_id_from_token), ): if not user_id: return {"error": "userId is required"} devices, total = get_device_list_db_page( page, pageSize, id, name, status, is_superuser, dept_id, startTime, endTime ) # ===== 👇 核心:补在线状态 ===== for d in devices: device_id = d["name"] # 账号 d["online"] = redis_client.is_device_online(device_id) == 1 return BaseResponse(data={"list": devices, "total": total}) @iot_router.post("/common/device") async def create_device(data: dict, user_id: UUID = Depends(get_user_id_from_token)): if not user_id: return {"error": "userId is required"} new_id = insert_device(data) return BaseResponse(data={"id": new_id}) @iot_router.put("/common/device/{id}") async def update_device( id: str, data: dict, user_id: UUID = Depends(get_user_id_from_token), ): if not user_id: return {"error": "userId is required"} count = update_device_db(id, data) if count == 0: return BaseResponse(status=False, message="设备不存在", data=None) return BaseResponse(data=True) @iot_router.patch("/common/device/{id}") async def patch_device( id: str, data: dict, user_id: UUID = Depends(get_user_id_from_token), ): if not user_id: return {"error": "userId is required"} count = patch_device_db(id, data) if count == 0: return BaseResponse(status=False, message="设备不存在", data=None) return BaseResponse(data=True) @iot_router.delete("/common/device/{id}") async def delete_device( id: str, user_id: UUID = Depends(get_user_id_from_token), ): if not user_id: return {"error": "userId is required"} deleted = delete_device_db(id) if deleted == 0: return BaseResponse(status=False, message="设备不存在", data=None) return BaseResponse(data=True)