新增兩個欄位前 先找出誰在使用這份資料
工站狀態原本只有State、Ready與Value,現在想加入Quality與Timestamp。把欄位加在最後,看起來沒有動到舊資料,但接收端可能依固定長度、記憶體偏移或舊型別讀取。本篇帶你先寫介面契約,再建立新舊轉接層,最後用五組資料驗證。完成後,你要能指出哪些舊功能仍可用,哪些資訊已經無法表達。
先列出所有使用者:同一PLC內的功能塊、另一個任務、HMI、通訊閘道及歷史資料庫。這些介面可能使用名稱、結構型別或原始位元組,各自的相容條件不同。本文用邏輯欄位表教學,不指定實際暫存器偏移;若現有系統直接搬移記憶體,必須另外保存布局及序列化規格。
| 版本 | 欄位 | 本篇約定 |
|---|---|---|
| V1 | State | 0待命 1執行 2故障 |
| V1 | Ready | 布林 表示可接受新工作 |
| V1 | Value | 有限工程數值 單位EU |
| V2新增 | Quality | GOOD BAD UNKNOWN |
| V2新增 | Timestamp | UTC毫秒時間戳及獨立TimeValid |
Timestamp只是欄位名稱,不應隨手宣告成表示持續時間的TIME,再當成日期使用。本篇約定它表示自1970年起的UTC毫秒整數,實際寬度、符號與序列化方式應在目標介面中明訂。TimeValid為假時不能把零當成真實的1970年事件。這個額外有效旗標屬時間欄的契約,不能省略語意。
分清型別相容 布局相容與語意相容
型別能通過編譯,不代表資料在通訊上就相容。編譯器可能在BOOL與較寬型別之間加入對齊空隙,也可能在結構陣列尾端補齊間距。CODESYS官方pack_mode說明顯示結構布局會受到對齊設定影響。因此不能只把各欄位位元組數加總,就猜下一個結構或欄位的起點。
| 變更 | 可能影響 | 本篇處理規則 |
|---|---|---|
| 尾端新增欄位 | 封包長度及舊解析器 | 先經明確轉接 不直接搬整塊 |
| REAL改成INT | 表示方式與小數精度 | 提升契約版本並定義轉換 |
| EU改成bar | 數字的工程意義 | 視為語意變更 不偷偷改單位 |
| 改欄位順序 | 原始位元組偏移 | 重新發布布局並測解析 |
| UNKNOWN改成GOOD預設 | 資料可信度 | 禁止未有證據就提升品質 |
若資料以命名欄位傳輸,新增欄位是否可忽略仍取決於解析器規則。某些讀者拒絕未知欄位,某些讀者接受;你需要實測舊版,而不是用新程式成功解析來推論舊程式也可以。若以固定封包傳輸,則先檢查版本、長度和型別,再依那個版本解碼,不能先套舊偏移讀完才發現長度不對。
工程值的單位與品質也要一起版本化。Value為12.5本身無法說明是壓力、溫度或任意EU。把單位改成bar卻維持舊版本,可能讓畫面數值看起來正常,判斷門檻卻完全錯誤。本篇V1與V2的前三欄語意保持一致;若改單位,就超出這次相容擴充的範圍。
新讀者接受舊資料時保留未知狀態
V2讀者取得V1資料時,可以經轉接層複製State、Ready與Value,但Quality必須設為UNKNOWN,TimeValid設為假。這不是推定舊設備故障,而是承認舊契約沒有提供這些資訊。只有另有可信的外部證據並明定組合規則,才可產生不同的品質判定,不能因數字落在範圍內就標GOOD。
| 來源 | 轉接後欄位 | 預期使用結果 |
|---|---|---|
| V1 State0 Ready1 Value12.5 | 原值保留 QualityUNKNOWN TimeValid0 | 可依需求顯示 不能假定可作控制依據 |
| V2 QualityGOOD且TimeValid1 | 保存全部有效資訊 | 仍要檢查新鮮度與範圍 |
| V2 QualityBAD | 保留原值但標示無效 | 不得作有效測量使用 |
| V99 | 不解析未知欄位布局 | 回報UNSUPPORTED_VERSION |
版本號應由資料來源提供,能力旗標則描述該版本允許的可選資訊是否存在。能力旗標不是任意拼裝型別的通行證;接收端仍需先確認版本,再依已知規格解析。若版本為V1卻聲稱帶有V2時間欄,應回報契約不一致,而不是猜它可能漏改版本號。
轉接層應輸出清楚的診斷,例如來源版本、採用的目標版本、缺少欄位與是否降級。不要讓畫面只剩一個無意義的錯誤數字。維護者應能直接分辨資料不支援、品質無效與只是缺少時間戳,這三種情況的處置不同,也會影響報表是否能排序。
舊讀者不能自動理解新品質
V2向V1降級時最容易犯的錯,是丟掉Quality後仍宣稱舊讀者會拒絕BAD。舊讀者根本沒有這個欄位,除非原介面已有可代表整筆無效的通道,否則它無從知道剛收到的是失效值。本篇規定:Quality不是GOOD時,轉接層拒絕發布為可用V1資料,並透過已建立的外部連線品質或錯誤通道回報。
如果舊系統沒有無效訊號,也沒有資料逾時判斷,就不能安全地靜默降級。你必須先升級舊讀者的有效性處理,或明確限制只能在不依賴品質的離線顯示用途使用。把Value改零不是解法,因為零可能是合法量測;把Ready改假也未必足夠,除非原契約明定Ready假時所有量測都不可用。
同樣地,Timestamp被移除後,舊報表不能再宣稱知道事件發生時間。可以保存轉接器的接收時間,但欄位應命名為接收時間並標示來源,不能拿它冒充設備時間。若事件排序依賴原始時間,這個舊讀者就不具備所需能力,應在相容矩陣中列為不支援。
建立相容矩陣時,將V1來源到V2讀者、V2來源到V1讀者與V2到V2分成三列。每列都寫接受條件、遺失資訊、拒絕行為及使用限制。不要只填一個勾號;「可顯示舊值」與「可作當前有效控制輸入」的相容程度不同,需要讓接手的人看得出來。
操作步驟與完成後應看到的結果
先保存V1與V2各一份固定樣本,建立獨立轉接測試,不連接實體輸出。逐一跑V1轉V2、V2 GOOD轉V1、V2 BAD轉V1、未知版本與單位不符五組案例。每組記錄輸入、解析版本、轉接結果、有效旗標及拒絕原因。再用真正的舊版解析器讀轉接結果,才能證明相容性,而不是只測新版。
完成後,V1轉V2應保留三個舊欄,新增品質為UNKNOWN且時間無效。V2 GOOD只有符合既有V1契約及外部品質處理時才可降級;BAD不得被轉成看似正常的舊值。V99與單位不符應在使用資料之前被拒絕。請依表列驗收值核對介面轉換結果。
失敗時先查哪裡
數值固定偏移先查布局、對齊與欄位寬度;數字合理但判定錯誤先查單位與版本;新讀舊成功而舊讀新失敗,查固定長度及未知欄位規則;BAD被當成GOOD則查轉接時是否丟掉品質。每次只修一層,保留原始樣本,避免錯誤資料被轉型後失去證據。
常見問題與適用限制
一、只把欄位加在最後就相容嗎?不保證,仍受布局與解析契約影響。二、大小一樣的型別可直接互換嗎?不可,有號性、浮點表示及單位可能不同。三、沒有品質欄可預設GOOD嗎?不可,應標UNKNOWN並限制用途。四、版本號增加就完成改版嗎?還需新舊雙向樣本驗收。本篇適用介面設計;CODESYS布局文件僅說明其對齊機制,三菱Q系列與其他平台需各自核對實際布局。