- Jelina 概覽
- EMS Builder
- 整合與協同
前端即時推送與直接控制
架構總覽 裡“執行”這一步不僅包括寫入點位、發告警、發 MQTT,還包括直接服務前端介面:Edge-EMS Builder 提供兩條 WebSocket 通道,讓自訂前端既能即時接收資料推送,也能直接向裝置下發控制指令,不需要額外開發中間層。
一、兩條 WebSocket 通道
Section titled “一、兩條 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>二、訊息格式
Section titled “二、訊息格式”請求訊框(前端 → 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”,而是每個連線自己宣告一份“推送設定”:
- 前端傳送
topic: "read",content裡列出要關注的dataKey(或用groupCode關注整個資料分組),並把keep設為true。 - Edge-EMS Builder 收到後,把這份
content記為該連線(socketId)的推送設定,立即回一次目前值。 - 此後,Edge-EMS Builder 有一個後端任務,每 1 秒遍歷所有仍然連線著的前端 socket,把它們各自推送設定裡的最新值主動推送過去——不需要前端反覆發請求輪詢。
- 如果不需要持續推送,
keep設為false(或不傳),Edge-EMS Builder 只推送30s。 - 想取消某個連線的推送設定,傳送
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二者至少填一個。
四、如何直接控制裝置(write)
Section titled “四、如何直接控制裝置(write)”前端傳送 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 連線:會檢查該帳號角色是否為超級管理員 / 管理員 / 操作員之一,觀察者角色無法寫入——與頁面端的權限規則一致,不存在“繞過前端權限”的寫入路徑。
每日重複計畫
Section titled “每日重複計畫”DAILY_REPEAT 使用 availableTime / expiredTime(例如 08:00:00~12:00:00),整體生效日期設定在分時點位上;DAILY_CHANGE 才使用完整日期時間區間。兩種參數不能混用,跨午夜時段應拆分。
連線與執行結果
Section titled “連線與執行結果”/front 透過 Ping/Pong 心跳檢測連線,用戶端需處理關閉 code/message,重連後重建立立訂閱。寫入請求不要隨訂閱一起自動重放。
裝置寫入以 CommBridge 應答或超時結果為準,不能僅憑傳送成功判定裝置已執行。可結合 裝置控制記錄 檢視處理中、成功和失敗。擷取寫入係數由 CommBridge 反算,呼叫方不要重複換算。
維護凍結 期間受保護的控制寫入會回傳 200162,不應自動退出凍結重試。
五、一個完整的前端整合示例
Section titled “五、一個完整的前端整合示例”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) }] }));}這段程式碼完整覆蓋了“頁面載入即訂閱即時資料 → 每秒自動重新整理介面 → 使用者操作直接下發控制指令 → 拿到寫入結果回饋”的典型前端互動閉迴路,中間不需要額外的後端中轉服務。
六、與其他能力的關係
Section titled “六、與其他能力的關係”- 透過
/front或/data/rw寫入的資料,和觸發方案、運算式引擎讀取到的是同一份資料——前端控制的最終結果經裝置擷取回讀後,可以繼續參與聚合運算式和觸發判斷。參見 資料模型。 - 如果需要把資料同時推給雲端看板而不是隻在自訂前端展示,兩條路徑並不衝突:可以一邊用
/front服務自己的前端介面,一邊用 MQTT 雲端與邊緣協作 把同樣的資料回報雲端。 aems-write-dataAI 設定 Skill 封裝了/data/rw和/front的呼叫方式,可以直接用自然語言讓 AI Agent 幫你除錯寫入指令。