Files
DPM/backend
Pine 856ff88440 feat: 拆出 FastAPI 独立后端 + MQTT 控制 + 阿里云 AI
后端(backend/,FastAPI :10085):
- 全部数据 REST 接口:dashboard 快照 / 企业分区 / 播放列表 / 媒体 / 设置
- MQTT 控制通道:opc/display/command(切页/播放/卡片/通知),
  管理端 POST /api/display/command → MQTT 广播 → 所有大屏同步响应
- 阿里云 DashScope:通义千问 LLM + 函数调用(工具经 MQTT 广播),
  paraformer-realtime-v2 语音识别 /api/ai/asr
- 媒体资源统一由后端存储返回(上传/列表/静态服务)
- SSE /api/events 保留作 MQTT 不可用时的兼容回退

前端:
- config.js + .env.local 配置后端地址与 MQTT 账号(前端 dpm / 服务端 dpmserver)
- mqtt.js 客户端 + useMqttControl(MQTT 驱动切页/媒体/卡片/通知)
- DpmOverlays 全局覆盖层(通知 toast + 企业/分区/总览卡片)
- useParkSim 改为后端 API 数据源(离线回退本地模拟)
- AiChatPanel:对话走后端 LLM(工具调用),语音走本地录音 + 后端 ASR
- MediaScreen:媒体控制走 MQTT(保留 SSE 回退),修复 useEffect TDZ

Rust:lib.rs 移除内嵌 HTTP 服务器,只保留薄壳(窗口/权限/自启/npc 隧道)
安全:backend/.env、.env.local、media、data.json 已 gitignore
2026-08-17 21:26:16 +08:00
..

OPC 智能园区后端(FastAPI + MQTT

独立后端服务:所有数据通过 REST API 提供页面/媒体控制通过 MQTT 下发,媒体资源由后端统一存储与返回。

架构

┌──────────────┐   REST(全部数据/媒体/设置)   ┌────────────────┐
│  Tauri 大屏    │ ◄────────────────────────── │  FastAPI :10085 │
│  (React 前端)  │                             └───────┬────────┘
│               │  MQTT 订阅 opc/display/command       │ MQTT 发布
│  账号: dpm     │ ◄────────────────────────────────────│ 账号: dpmserver
└──────┬───────┘          MQTT Broker (EMQX)           │
       │                     192.168.1.3:1883          │
       └───────────────────────────────────────────────┘
  • 数据GET /api/dashboard/snapshot(每 2.2s 刷新,模拟引擎在后端运行)等
  • 控制POST /api/display/command → MQTT opc/display/command → 所有大屏订阅同步响应
  • 媒体:上传/列表/播放列表//file 静态返回(图片/视频统一由后端托管)
  • AI:通义千问(DashScope)+ 工具调用(切页/控制/卡片/通知,经 MQTT 广播);语音识别用阿里云 paraformer

启动

cd backend
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp .env.example .env   # 按需修改(含 DashScope Key、MQTT 账号)
.venv/bin/python main.py

启动后:API 与前端页面均在 http://0.0.0.0:10085(浏览器直接打开即大屏)。

环境变量(backend/.env

变量 说明
DPM_HOST / DPM_PORT(或 FASTAPI_HOST/FASTAPI_PORT 监听地址,默认 0.0.0.0:10085
DPM_MQTT_HOST / DPM_MQTT_PORT MQTT broker 地址,默认读 MQTT_BROKER_HOST/PORT
MQTT_USERNAME / MQTT_PASSWORD 服务端发布账号:dpmserver / 123456
DASHSCOPE_API_KEY 阿里云 DashScopeLLM + 语音识别)
DPM_LLM_MODEL 默认 qwen-plus
DPM_ASR_MODEL 默认 paraformer-realtime-v2

前端连接配置在项目根 .env.local(已 gitignore):VITE_API_BASEVITE_MQTT_URLVITE_MQTT_USERNAME=dpmVITE_MQTT_PASSWORD=123456

MQTT 主题

主题 方向 说明
opc/display/command 后端→前端 {cmd_id, ts, action, params}action: navigate / navigate_rel / play / pause / next / prev / alert / show_card / set_mode
opc/dashboard/tick 后端→前端 数据快照({ts, snapshot}
opc/display/ack 前端→后端 指令回执(预留)

控制示例

# 切换页面(数据大屏 / 数字孪生 / AI 助手 / 媒体轮播)
curl -X POST http://localhost:10085/api/display/command \
  -H "Content-Type: application/json" \
  -d '{"action":"navigate","params":{"page":"/twin"}}'

# 媒体控制
curl -X POST http://localhost:10085/api/display/command \
  -d '{"action":"next","params":{}}'

# 大屏通知
curl -X POST http://localhost:10085/api/display/command \
  -d '{"action":"alert","params":{"title":"园区通知","content":"..."}}'

关键接口

  • GET /api/dashboard/snapshot — 大屏全量数据快照
  • GET /api/park/companies · GET /api/park/zones — 企业分布
  • POST /api/ai/chat — AI 对话({messages:[{role,content}]}{reply, tools, mqtt_published}
  • POST /api/ai/asr — 语音识别(multipart 上传录音 + format 参数)
  • GET/POST /api/playlist · POST /upload · GET /media — 媒体与播放列表
  • POST /api/display/command — 管理端控制指令(转 MQTT 广播)
  • GET /api/events — SSE 兼容通道(MQTT 不可用时的前端回退)

说明

  • 大屏数据由后端模拟引擎产生(sim_engine.py,与原前端 parkData.js 逻辑一致);前端离线时也有本地兜底
  • 媒体文件存放于 backend/media//file/... 直接返回
  • 安全:backend/.env 与根 .env.local 已加入 .gitignore,含阿里云密钥与 MQTT 凭据,勿提交