專案

一般

配置概況

Bug #1517

是由 陳國瑋 於 6 天 前更新

## 1. 本單要解決什麼問題 

 寶台 問題摘要 
 A17 的充電樁列表中,`CP003-001`、`CP003-004`、`CP003-008` 持續顯示「無法使用」。然而,2026-09-26 凌晨查核時,CP003 已經與 Branch 恢復通訊,設備端記錄這三支 Connector 的狀態都是 `AVAILABLE`(可用),而且仍持續成功讀取電表。 

 本次已確認的問題是: 

 **CP 曾經主動把「可用」狀態送給 Branch,Branch 也已成功收到;但 Branch 後來只根據過舊的心跳時間,將三支 Connector 改成「無法使用」。心跳恢復後,Branch 沒有重新取得並更新 Connector 狀態,導致列表長時間保留錯誤的不可用狀態。** 

 本單需要同時處理兩件事: 

 1. **避免誤判離線:** CP 還在傳送有效 CP003-001、CP003-004、CP003-008 在充電樁列表持續顯示「無法使用」。2026-09-26 唯讀查核確認:Branch 保存 UNAVAILABLE / OCPP 訊息時,Branch 應將這些訊息納入「設備仍有通訊」的判斷,不能只看最後一筆 Heartbeat。 
 2. **讓狀態可以恢復:** 若 Branch 已經因離線把 Connector 標成不可用,通訊恢復後應重新取得 CP 的實際狀態,避免永久停留在舊的不可用狀態。 

 目前的證據可以確認「後台狀態與設備端狀態不一致」,但本次沒有操作實機開始充電,不能把電表通訊正常直接當成「實際充電功能已驗證正常」。 

 ## 2. 系統角色與名詞 

 本單使用的名詞如下,避免把「通訊在線」和「可以充電」混為一談。 

 | 名稱 | 在本案中的意思 | 
 | --- | --- | 
 | CP(Charge Point) | 設備端。本案是 CP003,由它與實體設備通訊,再透過 heartbeat stale,CP edge 三支均 AVAILABLE、無 current transaction,電表讀取持續更新,CP003 OCPP 回報給 Branch。 | 
 | Connector | 個別充電連接器。本案 CP003 底下有 001、004、005、008。 | 
 | Branch/CS | 接收 OCPP 的後台服務。Branch 在本系統扮演 OCPP 的 Central System(CS),充電樁列表所使用的狀態也由它提供。 | 
 | Heartbeat | CP 傳給 Branch 的心跳訊息,用來表示仍有通訊。它不包含每一支 Connector 的充電狀態。 | 
 | StatusNotification | CP 主動回報設備或 Connector 狀態的訊息,例如 Available、Charging、Faulted、Unavailable。 | 
 | BootNotification | CP 啟動註冊時使用的訊息。現行 CP 程式在部分重連流程也會嘗試發送,但有冷卻時間,短時間內不一定再次發送。 | 
 | Watchdog | Branch 定時執行的離線檢查程式。若判定通訊已逾時,會把 CP 標成離線,並依交易保護規則處理其 Connectors。 | 
 | TriggerMessage | Branch 請 CP 重新送出某類 OCPP 訊息的標準指令。本案可用來請 CP 回報目前的 StatusNotification。 | 連線 ONLINE。 

 **CP 為 ONLINE,只能證明通訊狀態;某支 Connector 究竟是可用、故障或正在充電,仍須依該支的實際狀態判斷。** 因此不能在收到 Heartbeat 時,把所有 Connector 一律改成 AVAILABLE。 

 ## 3. 現場症狀與查核結果 

 以下是 2026-09-26 約 01:19(台灣時間)的查核快照,並非持續即時監控結果。 

 | 項目 | 查核結果 | 代表的意義 | 已確認時序(Asia/Taipei) 
 | --- | --- | --- | 
 | CP003 的 Branch 連線狀態 | ONLINE;最近 Heartbeat 為 01:18:01 | CP 與 Branch 當時已恢復通訊。 | 
 | Branch 的 CP003-001 | UNAVAILABLE;原因為 `OCPP heartbeat stale` | 後台仍保存「心跳逾時造成的不可用」。 | 
 | Branch 的 CP003-004 | 同上 | 同上。 | 
 | Branch 的 CP003-008 | 同上 | 同上。 | 
 | 三支 Connector 的 Branch 狀態變更時間 | 均為 - 2026-09-25 06:11:57 | 三支是同一輪離線判定一起被改寫。 | 
 | CP 設備端的三支 Connector | 均為 AVAILABLE,`current_transaction_id` 均為 NULL | 設備端記錄與 Branch 不一致。 | 
 | 三支 Connector 的電表讀取 | 持續更新;當時可讀到約 230V、0A,polling log 顯示繼電器斷開 | 當時仍能取得設備量測,但尚未做實際充電測試。 | 
 | 06:11:57 之後的 CP003 StatusNotification | 截至查核時,OCPP audit 中 request 共 0 筆 | Branch 改成不可用後,沒有再收到可用來恢復狀態的通知。 | 

 使用者看到的直接影響,是這三支在列表中長時間顯示「無法使用」,無法正確判斷設備是否可用。本次未實際送出啟動充電指令,因此不以此查核宣稱已驗證每一個啟動入口的阻擋結果。 

 ## 4. 事件經過:CP 有回報,Branch 後來又改掉狀態 

 以下時間均為 2026-09-25,時區為 Asia/Taipei。 

 | 時間 | 發生的事 | 與問題的關係 | 
 | --- | --- | --- | 
 | 05:59:47 | Branch 保存的上一筆 Heartbeat 時間。 | 後續離線檢查仍使用這個舊時間。 | 
 | 06:06:02 | Branch 收到 BootNotification 並接受。 | 這是當時最後一次 BootNotification 時間。 | 
 | 06:08:01 | CP003 的 06:08:01:CP003 WebSocket 因未及時收到 因 pong 而關閉。 | 觸發本次重連;為何未收到 timeout 關閉;最底層 pong 的底層原因尚未查明。 | timeout 原因尚未確認。 
 | 06:08:31 | WebSocket 重連成功。CP 因 BootNotification 冷卻時間尚餘約 - 06:08:31:重連成功,BootNotification 因尚有約 150 秒,略過再次發送 BootNotification。 | Branch 的 Boot 時間仍停在 06:06:02。 | 秒 cooldown 而跳過。 
 | 06:08:42~06:08:50 | CP - 06:08:42–06:08:50:CP 主動送出各 Connector 的 AVAILABLE StatusNotification;Branch 收到並回覆成功。 | 這證明 CP 有主動回報,而且 Branch 已經收到最新狀態。 | StatusNotification,Branch 已收到並回覆成功。 
 | 06:11:56~06:11:57 | Branch - 06:11:56–57:Branch watchdog 判定 Heartbeat 使用舊 lastHeartbeat=05:59:47 與 BootNotification 均已過期,將 CP003 標成離線,並將 001、004、008 改成 lastBootNotification=06:06:02,將上述三支投影 UNAVAILABLE。 | 問題發生點:近期收到的 StatusNotification 沒有被納入存活判定,剛恢復的可用狀態又被覆寫。 | 
 | 06:13:01 | CP 下一筆 Heartbeat 成功,其後每五分鐘持續成功。 | CP 的連線狀態恢復,但 Heartbeat 本身不包含 Connector 狀態。 | 
 | 至 9/26 約 01:19 | 沒有再收到新的 StatusNotification,三支仍是 UNAVAILABLE。 | 設備端維持 AVAILABLE,沒有新的狀態變化可自然觸發通知;後台也沒有完成重新同步。 | 

 為什麼 - CP003-005 沒有一起變成「無法使用」? 

 Branch log 明確記錄:005 當時的 `currentTransactionId=865`,觸發既有交易保護,因此略過不可用狀態的覆寫。這可以解釋為什麼同屬 CP003,只有 001、004、008 受到本次覆寫影響;但單靠這個交易指標,不能推論 005 當時一定有實際供電。 

 ## 5. 原因分析:目前有兩個缺口 

 ### 5.1 缺口一:Branch 沒有把其他有效 OCPP 訊息納入存活判斷 

 現行 watchdog 主要查看: 

 - 最後 Heartbeat:`lastHeartbeat`。 因 currentTransactionId=865 保護而未覆寫;本單不把該指標直接視為實際正在充電。 
 - 最後 BootNotification:`lastBootNotification`。 06:13:01:Heartbeat 成功,其後每五分鐘持續成功。 
 - 兩者是否都超過離線門檻;現場門檻為 330 秒。 

 這個判斷會漏掉一種情況:**CP 沒有新 Heartbeat,但剛剛確實透過同一條連線送來 至 2026-09-26 01:19:06:11:57 後 StatusNotification 或 MeterValues。** request 共 0 筆,三支仍殘留 UNAVAILABLE;CP edge 三支 AVAILABLE,meter read 持續更新。 

 本案在 06:08:42~50 收到狀態,06:11:56 就判離線,中間約三分鐘,仍在 330 秒範圍內。Branch 卻沒有使用這份新的通訊證據,而是依較舊的 Heartbeat/Boot 時間執行離線處理。 

 ### 5.2 缺口二:連線恢復後,Connector 狀態沒有重新同步 

 Branch 將 Connector 改成 UNAVAILABLE,是後台自行做的離線處理,並不代表 這次是「CP 已回報,Branch 後續因存活判定覆寫,且缺少重新同步」,不能描述為 CP 設備端也把自己的狀態改成 UNAVAILABLE。 

 因此,可能出現: 

 - CP 自己一直是 AVAILABLE。 從未主動回報。 
 - Branch 保存的是 UNAVAILABLE。 
 - CP 後來繼續送 Heartbeat,但 Heartbeat 沒有 Connector 狀態。 
 - CP 沒有發生新的設備狀態變化,也就沒有再次自然送出 StatusNotification。 
 - Branch 的舊狀態因此一直保留。 查核報告:test_report/20260926_001_a17_cp003_unavailable_readonly.md。 

 所以本單所說的「補送設備狀態」,是**重新請 CP 回報目前狀態,讓 Branch 有實際依據更新紀錄**,並不是認定 CP 在 06:08 沒有回報過。 

 ### 5.3 已確認與尚未確認的界線 

 已確認:狀態回報成功、Branch 後續以 heartbeat stale 覆寫、心跳恢復後狀態仍未同步。 

 尚未確認: 

 - 造成 WebSocket pong timeout 的最底層原因,例如通訊延遲或程式處理阻塞。 ## 規格依據 
 - A17 CP003 當時實際執行的 JAR 是否包含 #1456 全部修正;本次尚未比對正式 artifact。 
 - 三支實際啟動充電後的物理行為;本次僅唯讀查核。 

 這些待查項目不能先寫成已證實的根因。 

 ## 6. OCPP 1.6 規格如何要求 

 本單以專案保存的 OCPP 1.6 Edition 2 與 Errata 為依據。SHALL 表示規格要求必須遵守;SHOULD 表示原則上應遵守的建議;MAY 表示允許。 

 ### 6.1 CP 要主動回報 Connector 狀態 

 依 §4.9 與 Errata §3.19,狀態變更時,CP 必須主動送出 StatusNotification,並考慮最短狀態持續時間。 

 依 Errata §3.22,BootNotification 被 CS 接受後,CP 必須回報 connectorId 0 及所有 Connectors 的目前狀態;connectorId 0 代表 CP 本體。 

 依 §4.9,若離線期間狀態有改變,重連後應回報目前狀態。但規格沒有要求在狀態完全不變時,每隔固定時間重送所有 Connector 狀態。因此不能只因 06:13 後沒有新通知,就判定 CP 違反「固定週期回報 Connector 狀態」的義務。 

 ### 6.2 Branch 不應只靠 §4.6:在 Heartbeat 判定是否仍有通訊 

 依 §4.6,若 CP 已在 Heartbeat interval 內送出其他 OCPP 訊息,允許省略該次 內已送其他 PDU,CP MAY 省略 Heartbeat;CS 應將收到其他訊息視為仍有通訊的證據。 

 套用到本案,Branch 剛收到 StatusNotification,這也是一份有效通訊證據。修正時應另外保存「最後有效 OCPP 通訊時間」,而不是把它冒充成真正收到 Heartbeat 的時間。 

 ### 6.3 Branch 可以主動要求最新狀態 

 依 §5.17,CS 可透過 TriggerMessage,要求 CP 送出 StatusNotification。但必須區分: 

 - CP 回覆 Accepted:只表示接受這次要求。 SHOULD 將收到 PDU 視為存活證據。 
 - Branch 收到後續 StatusNotification:才取得該 Connector 的實際狀態。 

 設備可能不支援、拒絕或逾時,不能在沒有實際通知時直接把 Connector 改成可用。 

 原始文件位置: 

 - `documents/OCPP_1.6_documentation/ocpp-1.6 edition 2.pdf`。 §4.9 與 Errata §3.19:狀態變化時 SHALL 主動 StatusNotification(考慮最短狀態持續時間)。 
 - `documents/OCPP_1.6_documentation/ocpp-1.6-errata-sheet.pdf`。 

 ## 7. 本次要怎麼修改 

 以下為待確認的實作設計;本單尚未完成程式修改或部署。 

 ### 7.1 增加「最後有效 OCPP 通訊時間」 

 建議在 `e_charge_points` 新增可為空的 `last_ocpp_message_at` 欄位。 

 用途是保存 Branch 實際收到有效 OCPP 訊息的時間。例如收到 StatusNotification、MeterValues 或有效的指令回覆時,都能建立新的通訊證據。Heartbeat 欄位仍只記錄真正的 Heartbeat,避免日後查 log 時無法分辨訊息來源。 

 必須限制證據來源: 

 - 訊息必須來自該 CP 目前有效的連線。 
 - 使用 Branch 的接收時間,不使用設備 payload 裡可能過舊或錯誤的時間。 
 - 舊連線延遲送達的事件、格式錯誤訊息,以及 Branch 自己送出的指令,不能拿來延長 CP 的在線時間。 
 - 不因收到未知 CP 的訊息而任意建立設備資料。 

 資料庫變更需提供可重複執行的 migration。既有資料不以部署當下時間回填,避免把離線設備假裝成剛有通訊。 

 ### 7.2 修改 watchdog,防止把新狀態覆寫成不可用 

 Watchdog 應一起檢查最後 Heartbeat、BootNotification,以及有效 OCPP 通訊時間。 

 例如:最後 Heartbeat 已超過 330 秒,但兩分鐘前有收到有效 MeterValues,則不能只因 Heartbeat 過舊就判定設備離線。 

 另外,檢查與寫入之間可能剛好收到新訊息。因此必須保留現有加鎖後重查機制:準備寫入 OFFLINE 前,再確認最新通訊時間,避免使用數秒前的舊查詢結果覆寫新狀態。 

 真正沒有通訊、或目前連線確實關閉時,仍要正常執行離線處理;既有未完成交易的保護也要保留。 

 ### 7.3 通訊恢復後,重新取得 Connector 的真實狀態 

 對因離線而被 Branch 標成 UNAVAILABLE 的 Connector,通訊恢復後安排狀態同步。也要涵蓋本次已經卡住的情況:CP 已 ONLINE,但仍有離線處理留下的 UNAVAILABLE。 

 建議使用標準 TriggerMessage(StatusNotification),請 CP 重新回報。同步動作必須在背景執行,不能卡住接收 OCPP 訊息的執行緒,否則可能連 CP 的回覆都收不到。 

 收到實際通知後,依原本的狀態處理流程更新: 

 - CP Errata §3.22:BootNotification Accepted 後 SHALL 回報 AVAILABLE,就更新為可用。 connectorId 0 與所有 connectors。 
 - CP 回報 FAULTED,就保留實際故障。 §4.9:離線期間狀態改變,重連後 SHOULD 回報目前狀態;沒有要求狀態不变時固定週期重送所有 Connector。 
 - CP 回報 CHARGING,就依既有充電/交易規則處理。 §5.17:CS 可透過 TriggerMessage(StatusNotification) 要求目前狀態,須處理不支援/拒絕/逾時。 
 - CP 回報 UNAVAILABLE,也應視為設備真的回報不可用,不能為了讓列表恢復而強制改成 AVAILABLE。 本地原始規格:documents/OCPP_1.6_documentation/。 

 此同步只處理狀態,不應開關繼電器、啟停充電、清除交易,或呼叫具有這些副作用的完整設備 Recovery 流程。 

 ### 7.4 同步失敗要有明確結果,不能無限重試 

 同一 CP/連線只能有一組進行中的同步工作,避免每收到一筆 MeterValues 就再發一次要求。 

 需要處理: 

 - CP 不支援 TriggerMessage。 ## 與既有議題的界線 
 - CP 回覆 Rejected。 #1436:Branch Heartbeat + BootNotification grace。 
 - 指令沒有回覆。 #1456(Closed):CP reconnect immediate Heartbeat 及成功後 connector-only 強制同步;當時明確不改 Branch。 
 - CP 回覆 Accepted,但後續沒有送出 StatusNotification。 
 - 同步途中再次斷線,之後由新連線接手。 

 每種情況都要有可追查的 log、逾時與重試上限。尚未取得真實狀態時保留未同步的事實,不假造成功。 

 ## 8. 與 #1436、#1456 的關係,以及本單範圍 

 | 議題 | 已處理的內容 | 與本單的差別 | 
 | --- | --- | --- | 
 | #1436 | 本單主軸為 Branch 除 Heartbeat 外,也考慮近期 BootNotification,提供重連後的寬限。 | 本案重連時 Boot 被冷卻機制略過,且有效 StatusNotification 尚未納入判斷。 | 
 | #1456(已關閉) | CP 重連後立即送 Heartbeat,成功後重新回報 Connector 實際狀態。 | 該次明確未修改 Branch watchdog;本單補 Branch 對其他有效 對有效入站 OCPP 通訊的判斷與恢復同步。 | 
 | 本單 #1517 | 修正 Branch 存活判定與 通訊的存活判定,以及 offline recovery 的 Connector 狀態恢復,補上本次事故的回歸驗證。 | 同時盤點 狀態收斂;另核對 A17 各 CP instance CP001/002/003 的 #1456 修正版是否確實部署。 | 

 本單主要修改 `java/ems_branch`。A17 有 CP001、CP002、CP003 多個 instance,部署驗收時要逐一核對,不能只因 CP001 已更新,就推定 CP003 也是同一版本。 

 本單不包含重寫 rollout。尚未比對本次正式 JAR hash,不預先認定漏部署或既有修正失效。 
 - 不重寫 MeterValues 佇列,也不承諾解決尚未查明的 queue,也不以本單直接宣稱解決 pong timeout 底層原因。正式環境的即時復原、服務重啟與部署,要依後續核准的步驟執行;本次診斷尚未做這些操作。 timeout。 

 ## 9. 修改後應如何驗收 

 每個案例都要同時核對 修正需求 
 1. 以目前有效 session 收到的有效 OCPP 訊息與後台保存的狀態,不能只看到 HTTP 200、容器執行中,或 CP 為 ONLINE 就算通過。 

 | 案例 | 測試情境 | 預期結果 | 
 | --- | --- | --- | 
 | 近期有狀態回報 | Heartbeat/Boot 已舊,但在離線門檻內收到 StatusNotification。 | 不誤判離線,也不把剛回報的狀態覆寫為 UNAVAILABLE。 | 
 | 近期有電表回報 | Heartbeat/Boot 已舊,但仍持續收到有效 MeterValues。 | 通訊被視為仍有活動;Connector 狀態不因舊 訊息建立獨立存活時間,保留 lastHeartbeat 的真實 Heartbeat 被改成不可用。 | 語意;不得用伺服器出站訊息、舊 session、無效封包刷新存活。 
 | 真正通訊逾時 | 所有存活證據都超過門檻,或目前連線確實關閉。 | 正常執行離線處理,保留既有交易保護。 | 
 | 查詢與寫入交錯 | 2. Watchdog 先查到候選設備,但寫入前剛收到新訊息。 | 加鎖後重查可看到新證據,取消過時的離線寫入。 | 掃描與加鎖後重查均納入新存活證據;保留 Boot grace、真實斷線處理與 active transaction 保護。 
 | 舊連線或無效訊息 | 重連後舊連線仍有延遲事件,或收到格式錯誤內容。 | 不延長目前連線的存活時間,不污染設備狀態。 | 
 | 離線後恢復可用 | Branch 已因離線標成 UNAVAILABLE,CP 恢復後回報 AVAILABLE。 | Branch 根據實際回報恢復為可用。 | 
 | 離線後恢復但仍故障/充電 | 3. 由離線恢復後要求 CP 恢復後回報 FAULTED 或 CHARGING。 | 真實狀態原樣處理,不一律改成 AVAILABLE,交易不被誤清除。 | 回報實際 Connector 狀態;優先沿用標準 TriggerMessage/StatusNotification 能力。不得直接改 AVAILABLE,不得觸發 relay、RemoteStart/Stop、完整 Recovery 或交易清理。 
 | 設備明確回報不可用 | CP 回報 UNAVAILABLE。 | 保留設備真實不可用,不與後台殘留的離線狀態混淆。 | 4. 同步請求須有去重、timeout、重試上限及不支援處理;僅收到 Accepted 不算狀態已恢復,需收到實際 StatusNotification。 
 | 接受指令但未回報 | TriggerMessage 回覆 Accepted,卻一直沒有後續狀態通知。 | 到期記錄同步未完成,不假裝已恢復。 | 
 | 不支援、拒絕或無回覆 | NotImplemented、Rejected、timeout。 | 有明確紀錄及有界處理,不無限重試或產生指令風暴。 | 
 | 同步途中再次重連 | 前一批要求尚未完成,CP 已換新連線。 | 舊連線的回覆/排程不影響新連線,同一時間不重複發起多批同步。 | 
 | 5. 核對 A17 原事故重播 | 重現 Boot cooldown、先回報 AVAILABLE、watchdog 判定、較晚 Heartbeat 的先後順序。 | 修正前能重現問題;修正後不誤覆寫,已離線者也能依實際通知恢復。 | 各 CP instance 既有修正版本並列逐台驗收,正式部署與現場復原另依流程進行。 

 現場驗收另需確認 A17 CP001/002/003 的版本與行為,並確認狀態同步過程沒有造成繼電器操作、充電啟停或交易異動。 

 ## 10. 測試目錄與執行安排 

 既有案例需更新: 

 驗收條件 
 - `OCP-001`:離線判定及交易保護。 舊 Heartbeat/Boot,但近期有效 StatusNotification 或 MeterValues:不誤判 OFFLINE,不覆寫 Connector。 
 - `OCP-007`:watchdog 存活證據與加鎖後重查。 所有存活證據皆逾時、或目前 session 關閉:正常離線判定;未完成交易保護不退化。 
 - `OCP-008`:新舊連線交錯。 Watchdog 先選出候選,寫入前新訊息到達:加鎖後重查阻止 stale overwrite。 
 - `REL-005`:部署後 OCPP 通訊與狀態驗證。 

 新增回歸重點: 

 - P0:Heartbeat 過舊,但近期其他 OCPP 訊息仍能防止誤判。 舊 session callback、格式錯誤訊息、純出站送訊不能延長存活。 
 - P0:watchdog 已先標成離線後,恢復真實 Connector 狀態且不改變供電或交易。 Offline→Online 後,AVAILABLE/FAULTED/CHARGING 等真實狀態原樣同步;不偽造可用,不影響充電及交易。 
 - P1:舊連線/無效訊息不能刷新存活。 TriggerMessage 不支援/Rejected/timeout/Accepted 但無後續通知均可觀察,且不產生重試風暴。 
 - P1:狀態同步不支援、拒絕、逾時或只有 Accepted 時,不假成功也不無限重試。 重播 A17 9/25 時序可重現修正前失敗、證明修正後通過。 

 案例在 OCPP 訊息處理、watchdog、session、重連、恢復同步、資料庫欄位或相關部署變更時執行。發版測試採 Major/OCPP 範圍:所有適用 P0、P1,以及受影響 P2。 

 目前分支的 `OCP-018` 已用於 #1459 的 Fortune 案例,與 #1456 歷史文件的編號有差異。新增時必須取目前目錄未使用的 ID,不得覆寫既有案例。需要實機或特定廠商的案例,在完成前保留 Gap/Conditional,不以單元測試通過替代。 

 ## 11. 目前進度與交付資料 

 已完成: 

 - A17 正式環境唯讀查核與事件時序整理。 E2E impact 與流程 
 - 比對本地 OCPP 1.6 原始規格與 Errata。 Update:OCP-001、OCP-007、OCP-008、REL-005;參考 #1456 的 reconnect/watchdog-first 案例。 
 - 建立本 ticket,優先級 High。 Add:近期非 Heartbeat PDU 維持存活、offline recovery 真實狀態同步等 P0/P1 案例;新 ID 以目標分支目錄實際空號為準,避免沿用歷史已占用 ID。 
 - 從最新 `origin/main`(`4b0e412`)建立獨立分支 `feature/redmine-1517-ocpp-liveness`。 Trigger:OCPP 入站處理、session、watchdog、reconnect、schema、status recovery 或相關部署變更。 
 - 完成實作規劃,列出預計變動檔案、migration、風險及測試設計。 Release pack:Major / OCPP(所有適用 P0 + P1 + 受影響 P2);實體與第三方相容性未執行前保留 Gap/Conditional。 
 - 既有 E2E 目錄格式檢核通過;這僅表示目錄格式正確,不代表本單修正或測試已通過。 

 相關文件: 

 - 查核報告:`test_report/20260926_001_a17_cp003_unavailable_readonly.md`。 
 - 實作規劃:`documents/20260926/redmine-1517-implementation-plan.md`。 
 - Ticket 快照:`redmine-tickets/1517.md`。 

 **尚未完成程式修改、整批測試或部署,A17 現場也尚未由本次工作執行復原。** 目前待確認上述實作規劃;依專案流程,確認後進入程式修改,整批測試與正式部署另依各自的啟動條件進行。 使用者已指示建單並進行修改;先完成可審閱的程式碼實作規劃,依專案 SOP 取得規劃確認後實作。整批測試需 Ken 明確啟動;未授權自動部署、PR 或 merge。 

返回