一 先分開採集與畫面繪製
大量標籤畫面變慢,第一個要問的是採集是否過密,還是繪製與排版過重。把資料流程拆成採集、整理、傳送、render四段,分別記錄開始時間、完成時間、批次編號與可見標籤數。採集可依控制需要維持較快頻率,畫面則依人眼閱讀與操作需求更新;兩者不要綁成每收到一筆就重畫一次。這只是介面設計,不能推定任何特定PLC或HMI有相同排程API。
例如一百個溫度標籤每秒採集十次,但畫面每秒繪製兩次。每個標籤保留最新值、來源時間、品質與序號,render只取同一批次的快照。正常結果是數值接近最新而畫面穩定;失敗結果是採集執行緒直接逐筆觸發元件,CPU升高、畫面閃爍,甚至新值排在舊值後面。驗收時分別量採集延遲、佇列等待與繪製耗時,不能只看畫面是否「看起來有更新」。
更新週期要寫成可審查的規格,例如採集目標100毫秒、一般畫面500毫秒、警報事件立即入列。目標是上限與可接受延遲,不是保證每次都準時;系統忙碌時要顯示實際延遲與最後快照時間。
實務上可先用小型壓力表建立基準:標籤數、來源更新率、快照大小、每秒render次數、主執行緒佔用與畫面延遲都要同時記錄。把可見區從一頁擴到十頁,再逐步縮回,觀察取消訂閱是否真的降低來源與傳輸筆數。若只量CPU而不量事件等待,可能把事件遺失誤判成效能改善;若只量平均延遲,也可能掩蓋高峰時的長尾。
二 可見區訂閱與分組批次
畫面通常只展示一個區域,卻同時訂閱整座設備的所有標籤,這會浪費傳輸、解碼和元件更新。進入頁面時建立可見區集合,離開或捲動出視窗時取消一般值訂閱;重要狀態與连線狀態列為常駐集合;畫面退訂不得停止控制、歷史保存或警報判斷所需採集。可見區不是權限,後端仍須按使用者與設備規則授權,介面隱藏也不能當成保護。
分組時依功能與更新性質組成批次,例如馬達狀態一組、能源趨勢一組、設定摘要一組。批次內保留標籤識別、值、品質、來源時間與讀取序號;不要把不同時間取得的值假裝成同一時刻。若一組快照不完整,畫面標示本次資料不完整,保留前一完整快照時另標其時間與過期狀態,避免操作者把混合時間的數字當成同一設備狀態。
可見區切換要有退訂確認與逾時清理。若舊頁面的回覆晚到,依訂閱世代丟棄一般值;警報事件不能用這條規則丟掉,必須進入事件佇列並以事件識別、發生時間和處理狀態保存。測試快速切換三個頁面,確認舊值不覆蓋新頁,事件仍各出現一次。
三 最新值合併但事件不可遺失
連續類比值可合併:在下一次繪製前,標籤只保留最新一筆,並增加被合併筆數與最早來源時間供診斷。這種策略適合溫度、轉速等「目前狀態」,不適合警報開始、確認、復歸或命令結果。事件若只放在同一個最新值欄位,短時間內的開始與復歸可能互相覆蓋,操作人員就無法還原順序。
實作上可分兩條資料路徑:狀態表按標籤鍵合併,事件表按事件識別追加。render在一個一致快照邊界讀取兩者,先更新狀態,再依事件時間與序號顯示新增事件;事件處理要有去重鍵,不以畫面重畫次數判斷是否已處理。正常結果是十筆溫度只畫最新值,但三筆警報仍顯示三列。若事件佇列滿,回報背壓或丟失風險,不能靜默覆寫。
品質Bad、來源時間倒退或序號跳號時,狀態表照樣保存原始證據並標示品質,不能以零補洞。Bad時不能把附帶值當有效量測;可另顯示最後良好值及其時間,同時保留目前失效狀態。驗收案例同時送入二十筆狀態和開始、確認、復歸事件,檢查事件數、順序、重複數與最後狀態。
事件資料還要處理重複與重啟。每筆事件帶來源識別、事件序號或明確去重鍵,快照只保存已知狀態,不刪除尚未確認的事件。服務重啟後先載入事件游標,再恢復可見區狀態;若游標無法恢復,畫面應報告事件歷史不完整,要求重新同步,而不是悄悄從目前最新值開始。這樣才能在負載優化後仍保有可稽核性。
四 一致快照 背壓與延遲量測
採集速度長期高於消費速度時,無界佇列只會把問題延後,最後造成記憶體成長。設定有界佇列與水位:一般狀態超過高水位就合併最新值,事件則保留空間或觸發明確告警;低水位後再恢復正常。背壓要讓上游知道目前狀態,必要時降低非關鍵採集頻率,但不能用刪事件來換取漂亮的畫面。
一致快照可用遞增世代表示:採集完成後以受保護的引用發布不可變世代42,render持有該快照到讀取結束,才能安全沿用;僅前後檢查世代而沒有鎖、原子或物件生命週期保證,不能防止並行讀寫問題。每個標籤記錄source_time、receive_time、render_time,量測端到端延遲與各段分布。時鐘來源要先定義;不同機器時鐘未校準時,不要把差值宣稱成設備實際延遲。
排查先看每段計數:採集筆數、合併筆數、事件筆數、快照世代、佇列峰值、render耗時與丟棄原因。若只看到畫面卡頓,不能立即增加輪詢;先找出是來源慢、傳送塞住、快照鎖住或元件重排太久。這套方法可用於一般桌面或網頁監控,但是否能在特定HMI實作,仍須查該產品的訂閱、執行緒與診斷能力。
最後以高峰與恢復兩種情境重跑,確認背壓解除後更新可追上且警報仍完整。
五 常見問題與官方參考
FAQ1:採集與畫面必須同頻嗎?答:不必;先定義控制資料的新鮮度與畫面可接受延遲,再分別設定頻率並用快照對齊。
FAQ2:可見區外的標籤能否停止取得?答:一般值可以依訂閱規則停止或降頻,但權限、連線與重要警報須另定常駐策略。
FAQ3:最新值合併會不會漏警報?答:若事件和狀態分流、事件佇列有界且滿載會告警,可避免狀態合併覆蓋事件,但滿載告警本身不保證零遺失,還需持久化、流控或可恢復重取契約。
FAQ4:延遲用哪個時間相減?答:保存來源、接收與繪製時間,先確認時鐘可信;未校時只能報告本機段落耗時。
參考:Python time 官方文件:monotonic 時鐘適合量測不受系統時間調整影響的經過時間。
參考:W3C Page Visibility:可見狀態可作為一般介面更新策略的設計參考,不代表任何PLC訂閱API。