三端物联网平台初步搭建(MCP-ready 架构)
三端物联网平台初步搭建(MCP-ready 架构)
项目地址
https://mcp-server.fuufhjn.link
一、阶段性概述
目前已完成一个前端—云端—终端三端稳定通信的物联网平台原型,支持:
- 前端与终端双向通信(控制 / 状态上报)
- 多终端同时在线
- 设备状态可视化与基础控制
现阶段的系统已经具备完整的工程闭环。后续工作的重点不是继续堆功能,而是对现有通信与控制逻辑进行抽象升级,使其满足 MCP(Model Context Protocol)对“可调用工具”的结构化要求,为后续引入大模型提供下层支撑。
二、技术栈说明
1. 前端
- 框架:React + TypeScript
- UI:Mantine 组件库
- 部署:Cloudflare Pages
- 访问地址:https://mcp-server.fuufhjn.link
前端当前定位为设备控制与状态展示界面。 每个设备拥有独立的功能页面,用于验证通信可靠性与控制正确性,后续将作为 MCP 上层的“人类交互入口”。
2. 后端(云端)
- 框架:Hono
- 部署:Cloudflare Workers
- 数据库:Cloudflare D1
- API Base:https://mcp-server.fuufhjn.link/api
后端按功能对接口与路由进行模块化封装。当前设计中,每新增一种设备类型,只需:
- 定义对应的 TypeScript 接口
- 注册对应路由即可完成扩展,具备良好的可维护性。
后续该层将演进为 MCP Server,用于向上暴露标准化的“设备控制工具”。
3. 终端
- 硬件:ESP32 / ESP32-C3(混合测试)
- 在 WS2812 灯珠测试中,ESP32 老板子存在电压倒灌现象,临时使用 Seeed Studio ESP32-C3 替代
- 软件框架:Arduino
终端代码采用逻辑分离设计:
- WiFi 连接
- 心跳与通信
- 硬件驱动(屏幕 / 灯珠 / 传感器)
均封装为独立服务模块,主程序仅负责任务调度,便于后续扩展新硬件或统一控制接口。
三、已实现功能
目前接入了 3 个 ESP32 终端(主要用于通信与架构验证,非最终硬件选型):
1. 温湿度采集终端
https://mcp-server.fuufhjn.link/function/telemetry
- 终端上电后每 5 秒上传一次温湿度数据
- 前端可实时显示当前值
- 支持查看历史趋势图(近一段时间的温湿度变化)
2. 屏幕显示终端
https://mcp-server.fuufhjn.link/function/screen
- 终端上下线状态可在前端实时显示
- 当前端输入字符串并发送后,终端 OLED 屏幕实时显示对应内容
3. LED 灯珠控制终端
https://mcp-server.fuufhjn.link/function/led
- 终端在线状态实时同步
- 前端通过色盘与亮度滑块输入参数
- 终端 LED 灯珠按输入值显示颜色与亮度
四、系统通信设计
1. 终端 → 云端(数据上报)
终端内部定义统一的 tick() 服务,用于:
- 检查 WiFi 联通性
- 校验时间戳
- 按固定周期向云端上传数据
以温湿度设备为例,上传数据格式如下:
export interface TelemetryData {
deviceId: string;
temperature: number;
humidity: number;
}后端通过 POST 接口接收数据并存入数据库。前端通过 /api/telemetry/latest 获取最新数据(时间字段在后端统一做 UTC → 本地时间修正)。
2. 云端 → 终端(控制与下发)
由于后端部署在云端而非局域网,采用终端主动轮询 + 云端缓冲的方式实现可靠通信。
(1)设备注册
终端在 setup 阶段连接 WiFi 后,调用注册接口,上传设备标识(当前使用 deviceId,后续可替换为 UUID):
- 若设备不存在,则写入设备表并返回注册成功
- 若设备已存在,直接返回成功
(2)心跳与消息获取
终端按固定时间间隔向对应接口发送心跳请求,例如屏幕设备:
export interface ScreenHeartbeatRequest {
deviceId: string;
}后端处理逻辑:
- 更新设备表中的
last_heartbeat - 查询“待发消息表”
- 若存在待发消息,则返回最早一条
前端判断设备是否在线的标准为:60 秒内是否收到心跳。
(3)缓冲区设计说明
当前端向设备发送控制指令时,该指令不会直接推送到终端,而是:
- 写入“待发消息表”
- 等待终端下次心跳轮询获取
这种设计的优势:
- 降低前端、后端、终端之间的耦合度
- 避免依赖云端内存状态
- 适合 Cloudflare Workers 这类无状态运行环境
当终端成功取走消息后,该消息即从表中删除。
(4)终端执行
终端收到待发消息后,调用本地显示或控制服务执行操作;若心跳响应为空,则维持当前状态不变。
五、面向 MCP 的设计思路(下层功能)
当前系统已经具备清晰的 “设备注册 → 状态上报 → 控制下发” 闭环。下一阶段的核心工作是:
将现有设备控制接口抽象为“语义明确、参数规范、可被模型调用的工具(Tool)”,以符合 MCP 协议对下层系统的要求。
重点包括:
- 将设备能力抽象为统一的 action + params 形式
- 在云端集中管理设备能力与状态
- 为 MCP Server 提供稳定、确定性的工具接口(本课题不涉及 agent、规划或自主决策层)
六、升级计划
当前问题
现有系统中,终端设备通过 HTTP 轮询方式与云端后端进行通信,其本质是一种设备主动拉取(pull-based)模型。终端需要周期性发送请求,即使无新指令也会产生大量空请求;指令下发存在由轮询周期决定的不确定延迟(如果刚好在轮询周期开始时发请求,会立即得到响应,而如果在一个周期刚结束时发,就要等一个周期的时间。为了得到快速响应,需要减小轮询时间,这对设备来说压力很大)。
而且从系统架构来说,设备在线状态维护、指令缓冲这些功能本质上属于通信层或会话层职责,但被迫由业务代码(现在的后端)实现,增加了系统复杂度和维护成本。
引入mqtt协议层
MQTT 是一种基于发布–订阅(publish–subscribe)模型的轻量级消息协议。esp设备订阅一个topic(特定api)。服务端往这个api发送指令时,它会主动转交给设备,而不需要被动接受设备轮询。
现有系统架构:
Agent / Frontend
│
▼
┌────────────────┐
│ Backend API │
│ (HTTP Server) │
└───────┬────────┘
│ 轮询
▼
┌────────────────┐
│ ESP32 │
└────────────────┘加入mqtt协议层后:
Agent / LLM
│ MCP
▼
┌────────────────┐
│ MCP Server │
│ (Capability) │
└───────┬────────┘
│ MQTT publish / subscribe
▼
┌────────────────┐
│ MQTT Broker │
│ (Mosquitto) │
└───────┬────────┘
│
▼
┌────────────────┐
│ ESP32 │
└────────────────┘通过在现有三端物联网平台中引入 MQTT,并结合 MCP 协议对设备能力进行统一抽象,系统在通信效率、架构清晰度以及可扩展性方面均得到显著提升。该设计不仅解决了传统 HTTP 轮询模型的固有缺陷,也在整体架构思想上与主流智能家居系统保持一致,同时为后续智能化能力的叠加提供了良好的基础。
与目前主流的商业级架构对比
| 维度 | 传统 DIY 系统 | 主流智能家居 | 本课题系统 |
|---|---|---|---|
| 控制方式 | 直连设备协议 | 中心控制层 | MCP Server |
| 通信协议 | HTTP 轮询 | MQTT / Matter | MQTT |
| 能力抽象 | 无 | 私有模型 | MCP Tool |
| AI 接入 | 强耦合 | 间接 | 解耦 |
其实这是与MCP+mqtt的设计比较一致的,只是商家把开源的协议、中控等换成了私有的。
