運算式引擎
運算式引擎是 Edge-EMS Builder “計算”能力的核心,聚合點位的取值、觸發方案的判斷條件、MQTT 訊息封包的組裝,本質上都是運算式引擎執行一段指令碼的結果。指令碼語法為 Lua。
一、變數引用規則
Section titled “一、變數引用規則”運算式指令碼執行前,Edge-EMS Builder 會先把指令碼中形如 ${...} 的預留位置替換為實際資料值,再執行指令碼主體。預留位置支援以下寫法,可以組合使用:
| 寫法 | 說明 | 示例 |
|---|---|---|
${dataKey} |
引用某點位的目前值 | ${PCS1_有功功率} |
${dataKey[-NTimeUnit]} |
引用 N 個時間單位之前的歷史值 | ${PCS1_有功功率[-5s]} 表示 5 秒前的值 |
${dataKey[#N]} |
引用倒數第 N 條歷史取樣值 | ${PCS1_有功功率[#3]} 表示倒數第 3 條值 |
${dataKey[raw]} |
原樣輸入,不做自動型別轉換。數值 1000 與二進位 1000 等難以區分的場景,用 raw 強制原樣注入;只能且必須放在最後 |
${设备状态[raw]} |
${[deviceCode]dataKey} |
引用共享裝置(Share)點位的最新值 | ${[DeviceA]PCS1_有功功率} |
| 混合使用 | 上述規則可自由組合 | ${[DeviceA]PCS1_有功功率[-1s][#3]} |
缺失值:目標點位暫時無值時,引擎注入字串
__Null__。可顯式比較或使用isNull/isNotNull;數值計算先用tonumber,不要依靠or 0判斷該字串。
時間偏移支援的單位:
| 單位 | 可用簡寫 |
|---|---|
| 毫秒 | ms / millisecond |
| 秒 | s / sec / second / seconds |
| 分鐘 | m / min / minute / minutes |
| 小時 | h / hour / hours |
| 天 | d / day / days |
| 周 | w / week / weeks |
| 月 | M / month |
二、指令碼主體:標準 Lua 語法
Section titled “二、指令碼主體:標準 Lua 語法”預留位置替換完成後,剩餘的指令碼主體按標準 Lua 5.1 語法執行,最後透過 return 回傳計算結果。這意味著你可以使用 Lua 原生的變數、條件、迴圈、函式等能力:
-- 計算總視在功率(簡化示例)local ua, ub, uc = tonumber(${Meter1_Ua}), tonumber(${Meter1_Ub}), tonumber(${Meter1_Uc})local ia, ib, ic = tonumber(${Meter1_Ia}), tonumber(${Meter1_Ib}), tonumber(${Meter1_Ic})if not (ua and ub and uc and ia and ib and ic) then return "__Null__" end
local s = ua * ia + ub * ib + uc * icreturn s三、內建函式與模組
Section titled “三、內建函式與模組”除標準 Lua 語法(含原生 string/table/math 庫)外,Edge-EMS Builder 在指令碼環境中預置了一批全域函式與可 require 的模組,覆蓋資料讀取、寫入構造、字串/時間/正則處理等常見需求,無需編寫底層程式碼即可完成複雜邏輯:
| 分類 | 說明 | 示例 |
|---|---|---|
| 資料讀取(全域函式) | getLatestDataValue、getHistoryData、getDeviceShareValue,以及按前綴/後綴/模糊批次查詢的函式族 |
動態掃描一批命名規則相同的點位(見 觸發方案 中的動態裝置發現示例) |
| 寫入構造(全域函式) | buildCommonWriteMap、buildCustomizationWriteMap、buildDailyRepeatWriteMap、buildCommonAlarmMap、buildMqttAlarmMap、buildAlarmObservationMap、buildSlaveWriteMap |
構造要寫入的目標資料結構,供觸發動作/MQTT 動作統一執行 |
| 時間轉換 | cp56Time2aToOffsetDateTime、offsetDateTimeToCP56Time2a,支援 AB/BA |
對接 IEC 時間暫存器 |
| 時間模組 | require("OffsetDateTime")、require("LocalTime") |
取得目前時間戳(限頻判斷)、比較時間區間 |
| 通用工具模組 | require("Logger")、require("JSON")、require("Regex")、require("String")、require("Math")、require("TableUtils") |
記錄輸出、JSON 深度操作、正則、字串/數值/表處理 |
| JSON 轉換(全域函式) | jsonToMap、jsonToList、toJsonString |
與外部系統交換結構化資料(常用於 MQTT 訊息封包) |
| HTTP | require("http") |
指令碼內直接發起 HTTP 請求,對接第三方介面,需自行控制頻率與超時 |
完整的函式簽章、模組方法清單可參考 Lua 指令碼完整參考;變數引用的詳細規則可參考 資料變數解析規則。
聚合點位運算式的回傳值約定:
return單個值(數字/字串等),作為該聚合點位的最新值;不要在這裡回傳buildCommonWriteMap這類寫入描述陣列——那是觸發動作、MQTT 動作等場景的回傳值格式,詳見 Lua 指令碼完整參考 · 回傳值約定。
四、設定示例:剩餘可用容量計算
Section titled “四、設定示例:剩餘可用容量計算”以負載平衡類場景中常見的“剩餘可用功率”為例:
-- 額定電流 × 電壓 = 額定功率上限(kW)local rated_kw = tonumber(${Grid_current} or 0) * tonumber(${Grid_voltage} or 0) * 0.001
-- 已用功率(電網側實測總功率,kW)local used_kw = tonumber(${Grid_total_power} or 0)
-- 預留 10% 安全裕量local avail_kw = (rated_kw - used_kw) * 0.9
return avail_kw把這段指令碼設定為聚合點位 avail_kw 的運算式後,任何觸發方案或其他聚合點位都可以直接透過 ${avail_kw} 引用這個計算結果,無需重複計算邏輯——這正是“邏輯重複使用”的體現。
五、試算功能
Section titled “五、試算功能”新增或修改聚合點位運算式後,可以在儲存前使用試算功能驗證運算式語法與計算結果是否符合預期,避免上線後才發現指令碼錯誤。
- 查閱完整的內建函式簽章、模組清單與更多示例:Lua 指令碼完整參考
- 學習如何用觸發方案把運算式的計算結果轉化為實際動作:觸發方案