專案

一般

配置概況

Bug #1343

是由 陳國瑋約 2 個月 前更新

## 問題描述 

 ct1 (寶台 A17) 案場的華城充電樁 (CBDAX50A-25L-A6-A072-001) 在「先插充電槍、再執行開始充電」的流程中,connector status 會卡在 FINISHING 狀態,導致後續完全無法充電。問題持續超過 10 分鐘無人值守恢復,必須手動 SQL 干預。 

 ## 復現時序 (2026-06-18 14:28~14:38, ct1 log) 

 | 時間 | 方向 | 事件 | 說明 | 
 |------|------|------|------| 
 | 14:21:51 | ←樁 | StatusNotification: Preparing | 前次充電開始 (tx #507) | 
 | 14:21:56 | ←樁 | StartTransaction (tx #507, meter=3362) | | 
 | 14:26:52 | ←樁 | StatusNotification: SuspendedEV (vendorErrorCode=1000) | | 
 | 14:26:54 | 樁→ | DataTransfer | `車端要求暫停充電,220 斷開,停止發送電錶值,交易尚未結束,車端隨時會再要求充電` | 
 | 14:26:54 | ←樁 | StatusNotification: Finishing | | 
 | 14:26:57 | ←樁 | StopTransaction (tx #507, reason=EVDisconnected, meterStop=3938) | | 
 | 14:27:19 | ←樁 | StatusNotification: **Available** | EV 拔槍後正常 ✓ | 
 | **14:28:15** | ←樁 | StatusNotification: **Preparing** | **用戶插槍** | 
 | 14:28:17 | EMS→ | RemoteStartTransaction | 用戶點開始充電 | 
 | 14:28:18 | ←樁 | RemoteStartTransaction Response: Accepted | | 
 | 14:28:20 | 樁→ | DataTransfer | `transactionId=0, errorCode=1000` ← 根本沒開新 transaction | 
 | 14:28:21 | ←樁 | StatusNotification: **SuspendedEV + Finishing** | 1 秒內連送兩個 | 
 | 14:28:21 ~ 14:44:09 | | 完全沒有 StatusNotification,只有 Heartbeat | 充電樁送完 Finishing 後就斷了 | 
 | 14:38:16 | EMS | GET /api/cp/hq/user/connectors | 用戶查 connector (Ken 給的 log 起點) | 
 | 14:38:17 | EMS | GET /api/cp/hq/connector/info | status 仍為 FINISHING | 

 ## 根本原因 

 ### Bug 1(主因):華城 (FE-EVI) 充電樁在「先插槍再開機」流程下的 OCPP 行為異常 

 從 vendorErrorCode=1000 + DataTransfer 的中文訊息看,**充電樁判定 EV 端要求暫停充電**: 
 1. 收到用戶「插槍」→ 送 Preparing 
 2. EMS 送 RemoteStart → 充電樁回 Accepted 
 3. **但充電樁 1 秒後立刻送 SuspendedEV → Finishing**,且 DataTransfer 帶 `transactionId=0` 表示根本沒開始交易 
 4. 送完 Finishing 之後**再也沒有送 StatusNotification(Available)**,EMS 不知道它已經「準備好」 

 OCPP 1.6 規範下 StatusNotification 是單向通知,**充電樁不送 EMS 也沒轍**。這是華城充電樁 firmware 的問題。 

 ### Bug 2:EMS 對 FINISHING 狀態沒有 timeout fallback 

 `RemoteChargingSupport.isConnectorAvailableForCharging` (line 145-156) 只接受 AVAILABLE 或 PREPARING: 

 ```java 
 boolean available = status == ConnectorStatus.AVAILABLE  
                  || status == ConnectorStatus.PREPARING; 
 ``` 

 所以 FINISHING 的 connector 永久被擋。即使 EMS 再收到 RemoteStart,POST 進來會被擋掉回 400。 
 而且就算用戶重插槍觸發新的 Preparing StatusNotification,由於 connector 還卡在 FINISHING,新事件進來後雖然 StatusNotification handler 會 update status=Preparing,但中間可能會有 race condition / 排程 race。 

 ## 影響範圍 

 - **影響案場**:ct1 (寶台 A17),所有華城 (FORTUNE, FE-EVI) 充電樁 
 - **影響場景**: 
   - 先插槍再點開始充電 (主要) 
   - 任何 EV 拔槍後充電樁不送 StatusNotification(Available) 的情境 
 - **使用者體驗**:車主完全無法充電,必須人工介入 
 - **錯誤代碼**:`isConnectorAvailableForCharging=false` → 400 Bad Request 

 ## 修法方向(待 Ken 確認) 

 ### 方案 A(推薦):EMS 加 FINISHING 狀態 timeout fallback 
 - 監測 FINISHING 狀態超過 N 分鐘(例如 5 分鐘)自動 reset AVAILABLE 
 - 並釋放對應 slot 
 - 觸發 `ConnectorForHqDto` 重新 query 
 - 同時 log 警告 + 觸發事件供後續追蹤 

 ### 方案 B:被動等待 + 加重試 
 - 當用戶點開始充電時,若 connector 是 FINISHING 狀態超過 1 分鐘,強制 reset AVAILABLE 
 - 適用於「使用者已經想用」的情境 

 ### 方案 C:華城充電樁 firmware 修 
 - 聯絡華城 (FORTUNE) 修正 firmware,確保 EV 拔槍後一定送 StatusNotification(Available) 
 - 中長期建議 

 ## 建議採用:A + B 並行 + 開案追 C 

 ## 暫時補救(已記錄於此 ticket) 

 ```sql 
 -- 手動把卡在 FINISHING 的 connector 救回 AVAILABLE 
 UPDATE e_connectors  
 SET status='AVAILABLE', last_status_change=NOW(), update_time=NOW() 
 WHERE id='CBDAX50A-25L-A6-A072-001'; 
 ``` 

 ## 參考資訊 

 - 受影響 connector:CBDAX50A-25L-A6-A072-001 (FORTUNE 華城,B1 群組,private) 
 - 案場:ct1 
 - Charge Point:CBDAX50A-25L-A6-A072 (FE-EVI, FEEVC-3-32A-CNS) 
 - 案場 log 檔名:a17_0618_3---48ce5901-8336-4d6b-a7de-016b61287a66.txt 
 - 相關 ticket:#1342 (華城 TYPE_B/D stop 完全沒作用,FINISHING 後卡 PREPARING) 
 - Branch:private 


 --- 

 ## 2026-06-18 補充觀察資料(Ken 要求) 

 ### 觀察 1:異常流程(先插槍再開機)— 14:21 ~ 15:07 

 | 時間 | 事件 | 
 |------|------| 
 | 14:21:56 | StartTransaction (tx #507, meterStart=3362) | 
 | 14:26:52 | StatusNotification: SuspendedEV (vendorErrorCode=1000) | 
 | 14:26:54 | DataTransfer `車端要求暫停充電,220 斷開,交易尚未結束` | 
 | 14:26:54 | StatusNotification: Finishing | 
 | 14:26:57 | StopTransaction (tx #507, reason=EVDisconnected, meterStop=3938) | 
 | 14:27:19 | StatusNotification: **Available** ✓ | 
 | 14:28:15 | StatusNotification: **Preparing** ← 用戶再插槍 | 
 | 14:28:17 | RemoteStartTransaction (EMS→樁) | 
 | 14:28:18 | Accepted | 
 | 14:28:20 | DataTransfer `transactionId=0, errorCode=1000` ← **EV 沒拉到電** | 
 | 14:28:21 | SuspendedEV + Finishing | 
 | 14:28:21 ~ 14:56:04(**28 分鐘**) | 完全沒有 StatusNotification,只有 Heartbeat | 
 | 14:56:04 | BootNotification(**樁自己重開機**)firmware V_0.09.43.00 | 
 | 14:56:13 | StatusNotification: Finishing(重開機後又送一次) | 
 | 15:01:44 ~ 15:04:38 | EMS 連送 5 次 RemoteStartTransaction(4 Rejected + 1 Accepted→Rejected) | 
 | **15:04:26** | StatusNotification: **Available** ← 距第二次 Finishing **8 分鐘** | 

 ### 觀察 2:正常流程(先按 Start → 插槍 → 充 → 按 Stop → 拔槍)— 15:12 ~ 15:14 

 | 時間 | 事件 | 
 |------|------| 
 | 15:12:24 | RemoteStartTransaction (EMS→樁) ← 用戶按「開始充電」 | 
 | 15:12:25 | Accepted | 
 | 15:12:28 | Rejected + StatusNotification: **Preparing** ← 用戶此時插槍 | 
 | 15:12:28 | Rejected (第 2 次) | 
 | 15:12:40 | RemoteStartTransaction (EMS retry) | 
 | 15:12:41 | Accepted | 
 | 15:12:44 | StatusNotification: **Charging** | 
 | 15:12:48 | StartTransaction (tx #509, meterStart=3940) | 
 | 15:13:15 | SuspendedEV + DataTransfer `txId=509, errorCode=1000`(vendor-specific 訊息,這次 txId 有效) | 
 | 15:13:35 | Finishing | 
 | 15:13:37 | **用戶按結束充電 + 拔槍** → StopTransaction (tx #509, meterStop=3973, reason=EVDisconnected) | 
 | **15:14:01** | StatusNotification: **Available** ← 距 Finishing **24 秒** ✓ | 

 `e_transactions` 確認:tx #509, energy_consumed=33 Wh(充了約 52 秒),status=COMPLETED 

 ### 對照表 

 | 情境 | Finishing → Available 間隔 | EV 是否拉電 | 
 |------|---------------------------|------------| 
 | 華城樁 — 正常流程 | **24 秒** | ✓ 是(tx #509, energy=33 Wh) | 
 | 華城樁 — 先插槍再開機 | **8 ~ 28+ 分鐘**(重開機後)| ✗ 否(DataTransfer `transactionId=0, errorCode=1000`) | 
 | CloudLink(昨日 a17 log) | 1~3 秒 | — | 

 ### 推論更新 

 #### 1. 異常觸發條件更明確 

 從兩次觀察比對: 

 - **正常流程**下,EV 真的有充電(有效 txId + energy > 0)→ Finishing 後 24 秒正常送 Available 
 - **異常流程**下,EV 沒真的拉到電(DataTransfer `transactionId=0, errorCode=1000`)→ Finishing 後卡住不送 

 **推測**:華城樁在「沒真的開始交易(transactionId=0)」時,Finishing 狀態會卡住不送 Available。**真正有效的判斷標準**可能是「transactionId != 0 的 FINISHING」才需要 EMS 主動監測。 

 #### 2. EMS retry 機制對 FINISHING 不觸發 

 從 #1342 ticket 描述的 `onStatusNotification` 觸發第二次 remoteStart 機制(用於「先按 Start → 插槍」情境),對「FINISHING 狀態」**不會**自動重試 RemoteStart,因為 status=FINISHING 不算 Preparing/Charging。 

 **重點**:Bug 不是 RemoteStart 沒送,而是「FINISHING 後沒送 Available」讓 connector 永遠被擋,方案 A 的「timeout 自動 reset」是必要的。 

 #### 3. 方案 A 的 timeout 重新建議 

 | 設定 | 原建議 | 觀察後更新 | 
 |------|--------|----------| 
 | 華城正常 Finishing | 預估 1~3 秒 | 實測 **24 秒** | 
 | 華城異常 Finishing | 預估永遠不送 | 實測 **8 ~ 28+ 分鐘** | 
 | A 建議 timeout | 5 分鐘 | **2 分鐘**(24s 正常 << 2min A << 8min 異常) | 

 #### 4. 方案 B 維持 1 分鐘 

 - 24 秒遠小於 1 分鐘,正常流程不會被 B 誤觸發 

 ### 實作進度 

 - 2026-06-18 14:55 建立 Feature Branch `feature/redmine-1343-finishing-timeout-fallback` 
 - 2026-06-18 15:21 Ken 指示 **暫停實作,進入純觀察模式** 
 - 待釐清問題(待觀察方向): 
   - Q1: 華城樁 txId=0 的 Finishing 是不是**重現率 100%**? 
   - Q2: EMS retry 機制對「FINISHING 狀態」會不會自動重試?目前看是不會(需驗證) 
   - Q3: 「txId=0 → Finishing 卡住」是不是華城**所有樁**都這樣?還是只有 ct1 這台? 
   - Q4: 華城樁 24 秒 Finishing 是否**所有情境都 24 秒**?還是會更長? 
   - Q5: EV 不同狀態(充到 80% / 剛開始)會不會影響 Finishing 持續時間? 
   - Q6: StopTransaction 帶 txId=0 的 ERROR 會不會影響 connector 狀態? 

 ### 旁支發現(相關但獨立 bug) 

 - **2026-06-18 15:05:20、15:06:57**:兩次 `StopTransaction` 帶 `transactionId=0` → EMS 拋 ERROR 
   - 推測:EM 對 transactionId=0 的 StopTransaction 沒容錯 
   - 與 #1343 共因(華城樁 EV 不配合充電導致 txId=0) 
   - 暫不併案處理,待觀察後決定

返回