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)
- 暫不併案處理,待觀察後決定
返回