工業控制系統(ICS)的軟體開發有一個長期存在的鴻溝: 現場設備的資料已經能精確反映機組狀態,但上層應用層的監控能力與軟體品質卻遠遠跟不上。 這不是硬體的問題,而是歷史包袱——傳統 SCADA HMI 往往缺乏現代軟體工程實踐, 沒有單元測試、沒有稽核機制、監控視圖也不夠靈活。
DOF Lab 的 Z72 SCADA 系統(Bachmann M1 14 台風機群監控)在最近一輪衝刺(PR #76–#80) 集中解決了這三個面向:新增振動健康點擊趨勢與 CSV 批量匯出、 支援多標籤同步比對趨勢、實作管理員強制登出安全指令, 並為 Java WebSocket Bridge 核心補上了獨立單元測試套件。 每一項改動都在同一天被整合進 CI,並作為 PR #80 的 squash merge 送上 main。
一、振動健康監控:從「知道有問題」到「看得到趨勢」
風機主軸承、齒輪箱、發電機端的振動訊號是預測性維護中最關鍵的指標之一。 Z72 系統的 Bachmann PLC 本來就持續採集這些訊號,但舊有介面只能靜態顯示數值, 無法讓維運人員快速判斷「這個值是在上升還是下降?短時間內的趨勢是什麼?」
PR #76 引入了「點擊即趨勢(click-to-trend)」功能: 操作員在儀表板上點擊任何 PLC tag,系統即時繪製該標籤的時序折線圖, 不需要切換頁面、不需要手動選取時段。 同一個 PR 也實作了振動健康 CSV 匯出功能—— 以機組 ID、時間戳記、振動量值為欄位,一鍵匯出結構化資料, 直接可用於後續的頻域分析或機器學習模型訓練。
💡 設計哲學:資料主權歸現場維運人員
CSV 匯出格式採用「per-mode 多模態導出」設計(PR #77): 當使用者選取多個標籤進行比對趨勢時,系統可以依模式分別匯出(各標籤獨立檔) 或合併匯出(wide-table,每欄一個標籤)。 這個設計對維運工程師來說極其實用——他們習慣在 Excel 裡用兩種不同的方式 處理「多機比較」與「單機多項」分析場景。
PR #77 更進一步支援多標籤同步趨勢選取: 操作員可以同時選定多個 PLC 變數(例如主軸方位加速度 + 齒輪箱輸入端加速度 + 環境溫度), 在同一張圖上比較它們的時序走勢。 這個能力對於排查「是振動源頭問題還是環境耦合問題」的分析至關重要。
二、Bridge 核心安全:強制登出指令與稽核日誌
Z72 系統的 Java WebSocket Bridge 是整個架構的核心中介層—— 它負責連接 Bachmann M1 PLC(透過 OPC UA / Modbus 協議) 與瀏覽器端的 React Dashboard,並管理所有使用者的連線與身分驗證。 當多位維運人員同時使用系統時,會話管理安全就成為不可忽視的議題。
這次新增的強制登出(kick_user)管理指令 允許持有 admin 角色 JWT Token 的管理員, 透過 WebSocket 訊息強制斷開指定使用者的所有 active 連線。 整個流程設計嚴謹:
- 雙層驗證:先驗 JWT Token 有效性,再驗角色必須為 admin,兩關都過才執行
- 無縫稽核日誌:操作自動寫入 Bridge 稽核日誌,記錄操作者、被踢使用者名稱、斷線連線總數,格式與 AuditReview CLI 工具 100% 相容
- 邊界行為測試:單元測試驗證「一般使用者無法執行管理指令」、「管理員正確斷開目標使用者」、「連線確實從列表清除」三個關鍵場景
🔍 為什麼工業 SCADA 特別需要強制登出?
工業現場有個常見情境:一位值班工程師使用現場電腦登入系統後離開, 但因為忘記登出,導致會話一直保持。 另一位工程師需要以更高權限操作(例如修改 PLC 設定點), 卻因為系統顯示「已有工程師登入」而被鎖定。 在一般 Web 應用裡,這個問題不大;但在直連 PLC 的 SCADA 環境, 會話狀態直接影響到對物理設備的控制能力——管理員強制登出功能因此是生產安全的必要保障。
三、Java Bridge 單元測試:把「現場驗證」前推到 CI
Z72 Bridge 的 Java 程式碼一直有一個隱憂: 核心邏輯(資料切片、歷史彙總、WebSocket 訊息格式)從未有過系統性的自動化測試保護。 一旦重構某個 RollupTier 的邊界計算或修改 Z72Slice 的 schema, 開發者必須現場連上真實 PLC 才能驗證行為是否正確——這在開發環境中幾乎不可行。
PR #80 引入了獨立的橋接核心單元測試套件(TestBridgeComponents.java):
- Mock WebSocket 連線:不需要真實 PLC,完整模擬連線生命週期
- RollupTier 重構:引入 enum 型別消除 Z72Slice schema 重複定義,同時修復 baseTime 邊界計算的不穩定問題
- AuditReview CLI 測試:對稽核日誌查詢工具補上完整 unit test,並同步重構 AuditReview.java 使其可測性(testability)提升
- CI 整合:make_release.bat 現在在打包前會強制執行一次完整測試套件,測試失敗直接中止建置
研究室行動項目與工程啟示
✅ 下一步:Phase 3b Backend ADR
Z72 SCADA 系統的 STATUS.yaml 顯示 progress: 92%, next_milestone 指向「Phase 3b backend ADR」——這意味著下一個重大決策點 是後端架構的進化方向:是否引入更成熟的時序資料庫(InfluxDB / TimescaleDB) 取代現有的 SQLite 三層 historian?還是先在現有架構上把 E2E 測試補完? ADR(Architecture Decision Record)的撰寫將會是這個決策的正式起點。
這一輪的工作揭示了一個普遍適用於工業 AI 研究的原則: 軟體品質本身就是研究成果的一部分。 一套沒有測試保護、無法被可靠重現的 SCADA 系統, 即使採集了再多真實機組資料,也很難建立學術上可信的實驗環境。 當 Z72 Bridge 的核心邏輯開始受到單元測試保護, 它就從「一個能跑的工具」晉升為「一個可以信任的研究平台基礎設施」。
對於有意將工業資料整合進 AI 研究的學術團隊, 這個案例提供的最重要建議是:在資料採集管道的每一個關鍵節點, 都要補上確定性的測試保護——不只是因為它能防止 bug, 更因為它迫使你把每一個隱性假設(邊界條件、資料格式、狀態機轉換) 明確地寫成可驗證的規格,而這本身就是科學研究的精髓。