跳转到内容
返回官网

前端实时推送与直接控制

架构总览 里“执行”这一步不仅包括写入点位、发告警、发 MQTT,还包括直接服务前端界面:Edge-EMS Builder 提供两条 WebSocket 通道,让自定义前端既能实时接收数据推送,也能直接向设备下发控制指令,不需要额外开发中间层。

通道 路径 认证方式 定位
前端推送通道 ws://<host>:<port>/front 登录 Token(账号密码 登录后获取) 面向自定义前端界面:按角色权限校验,支持订阅推送 + 直接写入
数据读写通道 ws://<host>:<port>/data/rw 静态 data-rw-token(ems.yaml 中配置) 面向后端集成系统:不依赖登录,低延迟读写,适合系统对系统集成

两条通道的消息格式完全一致,差异只在认证方式和权限校验粒度上。本页以 /front 为主展开,/data/rw 用法可直接类比。

连接时通过 Query 参数传入:

ws://<host>:<port>/front?socketId=<自定义连接ID>&token=<登录Token>
ws://<host>:<port>/data/rw?socketId=<自定义连接ID>&token=<data-rw-token>

请求帧(前端 → Edge-EMS Builder)统一结构:

{
"topic": "read | write | clear",
"messageId": "自定义唯一 ID,用于匹配响应",
"keep": true,
"content": [
{ "dataKey": "pcsActivePower" }
]
}

响应帧(Edge-EMS Builder → 前端),按 messageId 与请求一一对应:

{
"code": "200",
"message": "Processed successfully",
"topic": "read",
"messageId": "...",
"time": "2026-07-23T10:00:00+08:00",
"data": { "...": "..." }
}

三、如何接收实时推送(订阅 = read + keep)

Section titled “三、如何接收实时推送(订阅 = read + keep)”

Edge-EMS Builder 的推送模型不是“发布订阅到某个 Topic”,而是每个连接自己声明一份“推送配置”:

  1. 前端发送 topic: "read",content 里列出要关注的 dataKey(或用 groupCode 关注整个数据分组),并把 keep 设为 true。
  2. Edge-EMS Builder 收到后,把这份 content 记为该连接(socketId)的推送配置,立即回一次当前值。
  3. 此后,Edge-EMS Builder 有一个后台任务,每 1 秒遍历所有仍然连接着的前端 socket,把它们各自推送配置里的最新值主动推送过去——不需要前端反复发请求轮询。
  4. 如果不需要持续推送,keep 设为 false(或不传),Edge-EMS Builder 只推送30s。
  5. 想取消某个连接的推送配置,发送 topic: "clear"。
// 订阅:持续关注 pcsActivePower 和 bmsSOC 的最新值
{
"topic": "read",
"messageId": "sub-001",
"keep": true,
"content": [
{ "dataKey": "pcsActivePower" },
{ "dataKey": "bmsSOC" }
]
}
// 或者按分组订阅(关注整个分组下的所有点位,包含子分组)
{
"topic": "read",
"messageId": "sub-002",
"keep": true,
"content": [
{ "groupCode": "pcs-group-01" }
]
}

同一个连接可以多次发送 read + keep:true 来追加/更新推送配置;dataKey 与 groupCode 二者至少填一个。

前端发送 topic: "write",content 里给出要写入的 dataKey 和 dataValue,不需要指定数据类型——Edge-EMS Builder 会根据 dataKey 自动识别它是原始数据(Collection)、聚合数据(Aggregation)还是分时数据(Customization),路由到对应的写入逻辑:

{
"topic": "write",
"messageId": "ctrl-001",
"content": [
{ "dataKey": "pcsActivePower", "dataValue": "300" }
]
}

写入分时数据(Customization)时可以附带生效区间:

{
"topic": "write",
"messageId": "ctrl-002",
"resetCustomValue": true,
"content": [
{
"dataKey": "import_price",
"dataValue": "0.85",
"availableDate": "2026-06-25T00:00:00+08:00",
"expiredDate": "2026-06-25T08:00:00+08:00"
}
]
}
  • resetCustomValue: true 表示先清空该分时数据现有的值,再写入本次内容——用于“整段计划替换”场景,避免新旧时间段重叠冲突。
  • 写入其他共享设备的点位时,在对应 content 元素上加 deviceCode 字段即可,Edge-EMS Builder 会识别为共享数据写入,路由到目标设备。
  • 通过 /data/rw 用静态 data-rw-token 连接:直接放行,不做角色校验,适合后端系统对系统集成。
  • 通过 /front 用登录 Token 连接:会校验该账号角色是否为超级管理员 / 管理员 / 操作员之一,观察者角色无法写入——与页面端的权限规则一致,不存在“绕过前端权限”的写入路径。

DAILY_REPEAT 使用 availableTime / expiredTime(例如 08:00:00~12:00:00),整体生效日期配置在分时点位上;DAILY_CHANGE 才使用完整日期时间区间。两种参数不能混用,跨午夜时段应拆分。

/front 通过 Ping/Pong 心跳检测连接,客户端需处理关闭 code/message,重连后重新建立订阅。写入请求不要随订阅一起自动重放。

设备写入以 CommBridge 应答或超时结果为准,不能仅凭发送成功判定设备已执行。可结合 设备控制日志 查看处理中、成功和失败。采集写入系数由 CommBridge 反算,调用方不要重复换算。

维护冻结 期间受保护的控制写入会返回 200162,不应自动退出冻结重试。

const ws = new WebSocket(`ws://<host>:<port>/front?socketId=web-ui-01&token=${loginToken}`);
ws.onopen = () => {
// 订阅实时数据:关注 PCS 有功功率与 SOC
ws.send(JSON.stringify({
topic: 'read',
messageId: 'sub-' + Date.now(),
keep: true,
content: [
{ dataKey: 'pcsActivePower' },
{ dataKey: 'bmsSOC' }
]
}));
};
ws.onmessage = (event) => {
const resp = JSON.parse(event.data);
if (resp.topic === 'read') {
// 每秒都会收到一次最新值,更新界面上的仪表盘/图表
renderDashboard(resp.data);
}
if (resp.topic === 'write') {
// 写入结果反馈:resp.successContent / resp.errorContent
showWriteResult(resp);
}
};
// 用户在界面上点击"设置功率为 300kW"按钮时:
function setPower(value) {
ws.send(JSON.stringify({
topic: 'write',
messageId: 'ctrl-' + Date.now(),
content: [{ dataKey: 'pcsActivePower', dataValue: String(value) }]
}));
}

这段代码完整覆盖了“页面加载即订阅实时数据 → 每秒自动刷新界面 → 用户操作直接下发控制指令 → 拿到写入结果反馈”的典型前端交互闭环,中间不需要额外的后端中转服务。

  • 通过 /front 或 /data/rw 写入的数据,和触发方案、表达式引擎读取到的是同一份数据——前端控制的最终结果经设备采集回读后,可以继续参与聚合表达式和触发判断。参见 数据模型。
  • 如果需要把数据同时推给云端看板而不是只在自定义前端展示,两条路径并不冲突:可以一边用 /front 服务自己的前端界面,一边用 MQTT 云边协同 把同样的数据上报云端。
  • aems-write-data AI 配置 Skill 封装了 /data/rw 和 /front 的调用方式,可以直接用自然语言让 AI Agent 帮你调试写入指令。
  • 完整的 HTTP/WebSocket 接口清单:可向 Edge-EMS Builder 技术支持索取《Edge-EMS Builder HTTP 接口文档》
  • 看看写入的数据如何被表达式引擎和触发方案使用:表达式引擎、触发方案
  • 需要跨设备写入时,了解共享目标机制:设备协同与共享目标