專案

一般

配置概況

動作

Bug #1343

進行中

[Branch] 華城充電樁 FINISHING 後未送 StatusNotification(Available),導致 connector 卡住無法充電 (FINISHING timeout fallback 修補)

是由 陳國瑋約 2 個月 前加入. 於 21 天 前更新.

狀態:
New
優先權:
Normal
被分派者:
開始日期:
2026-06-18
完成日期:
預估工時:

概述

問題描述

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:

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)

-- 手動把卡在 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 20:35 重新整理 Bug 1(5 小時觀察 + 程式碼分析)

重大發現:Bug 1 真正本質不是「卡 Finishing」,而是「先插槍 EMS 自動送電」

從 5 小時的 6 次充電觀察(tx #507~#512),卡 Finishing 只發生 1 次(#507,28 分鐘),其他 5 次都是 8~24 秒正常補送。所以「卡 Finishing」是衍生症狀(低機率),不是核心 bug。

真正 100% 重現的主症狀:Fortune / Tesla / Unknown 充電樁在「先插槍、未按開始充電」時,EMS 會自動送電。

程式碼根本原因

FortuneConnectorTypeRotationStrategy.onPreparingWithoutRotation() (line 25-27) 永遠回傳 SEND_REMOTE_START

@Override
public ConnectorTypeActionResult onPreparingWithoutRotation(ConnectorTypeActionContext ctx) {
    return ConnectorTypeActionResult.of(ConnectorTypeAction.SEND_REMOTE_START);  // ← 自動送電
}

對照組 CloudLinkConnectorTypeRotationStrategy.onPreparingWithoutRotation() (line 25-27) 回傳 noAction() — 不自動送電。

觸發鏈

  • 樁送 StatusNotification: PREPARING
  • ChargingOrchestrator.onStatusNotification() (line 598)
  • handleStatusNotificationForRotation() (line 776)
  • strategy.onPreparingWithoutRotation(ctx) (line 851)
  • → Fortune 回傳 SEND_REMOTE_START
  • → 自動送 RemoteStartTransaction → 樁充電

影響範圍

  • OtherConnectorTypeRotationStrategy extends FortuneConnectorTypeRotationStrategy (line 6) — DEFAULT/TESLA/UNKNOWN 都受影響
  • ChargingOrchestrator.buildConnectorTypeRotationStrategies() (line 252-254) 註冊:DEFAULT/TESLA/UNKNOWN → OtherConnectorTypeRotationStrategy

觀察資料(5 小時內,6 次充電完整記錄)

tx 觸發模式 Finishing → Available reason 備註
#507 (前次,先插再開) 28 分鐘才補送 EVDisconnected 14:28 異常,DataTransfer txId=0, errorCode=1000
#509 (前次,正常) 24 秒 EVDisconnected 用戶手動按 Start → 插槍 → 充 → Stop → 拔槍
#510 先插槍 EMS 自動送電 14 秒 Remote 15:23 測試
#511 先插槍 EMS 自動送電 8 秒 Remote 15:33 測試
#512 先插槍 EMS 自動送電 9 秒 Remote 15:55 測試

正常 Finishing 持續時間:8~24 秒(平均 ~14 秒)

「卡 Finishing」只發生在 txId=0 的特殊情境

從 5 小時觀察:

  • 6 次充電中只有 #507 那次卡 Finishing 28 分鐘
  • 原因:DataTransfer transactionId=0, errorCode=1000(EV 不配合充電)
  • 其他 5 次都是 8~24 秒正常補送 Available
  • 重現條件:EV 端要求暫停充電(華城 vendor-specific)

樁重開機行為

華城樁在以下時間點都自己重開機(BootNotification):

  • 14:56:04(卡 Finishing 28 分鐘後)
  • 15:25:03(充電中)
  • 15:31:47(充電中)
  • 15:49:08, 15:53:48, 16:03:02(空檔重連)

這是 vendor-specific 行為,EMS 端目前沒對應處理(但目前沒造成壞處)。

Bug 1 重新分層(取代原本 ticket 描述)

#1343 Bug 1
├── 主症狀 (重現率 100%)
│   └── Fortune / Tesla / Unknown 充電樁「先插槍、未按開始充電」時 EMS 自動送電
│       ├── 觸發:StatusNotification: PREPARING → onPreparingWithoutRotation → SEND_REMOTE_START
│       ├── 對照組:CloudLink 是 noAction()(行為不一致)
│       └── 影響:用戶未授權就被充電(體驗差 + 安全疑慮)
│
├── 衍生症狀 (低機率,特定條件才觸發)
│   └── Finishing 狀態卡住不送 Available
│       ├── 觸發:txId=0(華城樁 EV 不配合充電 → vendorErrorCode=1000)
│       ├── 正常 Finishing:8~24 秒補送 Available
│       └── 異常 Finishing:8~28+ 分鐘才補送(甚至完全不送,要靠樁 BootNotification 觸發)
│
└── 旁支發現 (與 Bug 1 共因)
    └── StopTransaction 帶 transactionId=0 → EMS 拋 ERROR
        └── TransactionService.stopTransaction() 沒容錯 txId=0

修法方向(已大幅簡化)

原本 ticket 列的 A (timeout fallback) 跟 B (user-triggered reset) 主要處理「卡 Finishing」這個衍生症狀。但從 5 小時觀察,「卡 Finishing」重現率極低(1/6),且 8 分鐘以上 timeout 仍會自動恢復。

真正要修的是「自動送電」這個主症狀

方案 改動 影響範圍 適用情境
方案 X(推薦):把 Fortune 的 onPreparingWithoutRotation 改成 noAction() 1 個 class,3 行 改變 Fortune/Tesla/Unknown 行為,跟 CloudLink 一致 如果用戶體驗(不該自動送電)是首選
方案 Y:加 flag enableAutoStartOnPlugin,default false 多個 class(config + strategy + ChargingOrchestrator) 較複雜但保留彈性 如果部分場景需要自動送電(例如離峰自動充電)
方案 Z:保留自動送電,但加「需要 user 授權」檢查 多個 class 最複雜 如果要兼顧自動 + 授權

對於衍生症狀(卡 Finishing)

  • 觀察顯示實際上 8~24 秒就恢復,影響很小
  • 如果仍要做 fallback,建議 timeout 設 2 分鐘(遠大於正常 8~24 秒)
  • 觸發條件:status=FINISHING AND current_transaction_id IS NULL AND last_status_change < NOW() - 2min

影響範圍重新評估

案場 / 樁類型 主症狀(自動送電) 衍生症狀(卡 Finishing) 修法方案 X 影響
ct1 華城 (FORTUNE) ✅ 100% 重現 ✅ 1/6 機率 改 noAction(),行為跟 CloudLink 一致
a17 華城 (FORTUNE) ✅ 100% 重現 ✅ 1/6 機率 同上
a17 CloudLink (CLOUDLINK) ❌ 已是 noAction() ⚠️ 見 #1342 不受影響
任何 TESLA / UNKNOWN ✅ 100% 重現(extends Fortune) 機率同華城 同 Fortune 修法
其他公版 (DEFAULT) ✅ 100% 重現 機率同華城 同 Fortune 修法

待釐清問題(重新評估)

  • ✅ Q1: 華城樁 txId=0 的 Finishing 是不是 100% 重現?→ ,5 小時觀察只 1/6 機率
  • ⚠️ Q2: EMS retry 機制對「FINISHING 狀態」會不會自動重試?→ 從程式碼看不會
  • ✅ Q3: 「txId=0 → Finishing 卡住」是不是華城所有樁都這樣?→ 從 ct1 + a17 log 都有類似行為,但重現率低
  • ✅ Q4: 華城樁 24 秒 Finishing 是否所有情境都 24 秒?→ 8~24 秒範圍
  • ❌ Q5: EV 不同狀態會不會影響 Finishing 持續時間?→ 還沒測過
  • ⚠️ Q6: StopTransaction 帶 txId=0 的 ERROR 會不會影響 connector 狀態?→ 從 #1342 ticket 看會

實作進度更新

  • 2026-06-18 14:55 建立 Feature Branch feature/redmine-1343-finishing-timeout-fallback
  • 2026-06-18 15:21 Ken 指示 暫停實作,進入純觀察模式
  • 2026-06-18 20:35 Ken 要求 重新整理 Bug 1
  • 重大發現:Bug 1 真正本質是「自動送電」不是「卡 Finishing」

旁支發現詳細記錄

  • 2026-06-18 15:05:20、15:06:57:兩次 StopTransactiontransactionId=0 → EMS 拋 ERROR
    • 推測:EM 對 transactionId=0 的 StopTransaction 沒容錯
    • #1343 共因(華城樁 EV 不配合充電導致 txId=0)
    • 建議併案處理(同個 onStatusNotification / StatusNotification 流程)
  • 華城樁反覆重開機:14:56, 15:25, 15:31, 15:49, 15:53, 16:03
    • vendor-specific 行為
    • 目前無實質影響,但建議追蹤

觀察 log 時間區間

  • 觀察 log 來源:ems_branch.e_ocpp_message_log table, charge_point_id=CBDAX50A-25L-A6-A072
  • 觀察時間:2026-06-18 14:21 ~ 20:25(將近 6 小時)
  • 觀察 connector:CBDAX50A-25L-A6-A072-001(華城 FORTUNE, B1 群組, private)

2026-06-18 21:41 重大更新(#1345 已修前置 bug)

Redmine #1345 已經實作完成並 push

  • Commit: 27e7d76 fix(#1345): StatusNotificationHandler 改用 Connector.updateStatus(),同步更新 last_status_change
  • Branch: feature/redmine-1345-status-notification-last-status-change (pushed to origin)
  • 改動:StatusNotificationHandler 改用 Connector.updateStatus(),所有 StatusNotification 事件都會更新 e_connectors.last_status_change

#1343 修法方向(方案 A)的影響

之前

  • 方案 A 的 Finishing timeout 判斷依賴 e_connectors.last_status_change 欄位
  • 但欄位不可靠(只有 DataTransfer 觸發才會更新),會誤判

現在(#1345 修好後)

  • e_connectors.last_status_change 變成可靠的「status 真正變更時間」依據
  • 方案 A 的 trigger 條件 status=FINISHING AND last_status_change < NOW() - 2min 可以正確運作
  • 任何依賴 last_status_change 判斷 connector 卡死情境的邏輯都會更可靠

對修法方向的影響

方案 之前狀態 現在狀態
方案 A (Finishing timeout fallback 2min) 判斷邏輯不可靠 判斷邏輯可靠,可實作
方案 X (Fortune onPreparingWithoutRotation 改 noAction) 仍是主症狀修法 仍是主症狀修法(不受 #1345 影響)

觀察資料補充

從 5 小時觀察(6 次充電 tx #507~#512),正常 Finishing 持續時間 8~24 秒。8 分鐘以上的卡 Finishing 重現率只有 1/6,且該次由 OCPP StatusNotification 自然恢復(15:04:26)

重要發現:14:28 那次卡 Finishing 28 分鐘後,確實是樁送 OCPP StatusNotification 訊息自然恢復(e_ocpp_message_log 有完整 REQUEST + RESPONSE 記錄,CP timestamp=15:04:24.977Z),不是 Ken 手動改 DB。但 Ken 14:28~15:04 期間可能手動介入過(無法驗證因手動改 DB 不留痕跡)。

重現率評估(修訂)

  • 「卡 Finishing」重現率:5 小時觀察 1/6 ≈ 17%
  • 每次都有 OCPP 訊息證據支持「自然恢復」(最長 33 分鐘)
  • 加上 #1345 修好後,方案 A 的 2 分鐘 timeout 仍可作為「保險」
  • 仍建議實作方案 A(修 #1345 後變可行)

Ticket 狀態

  • #1345: In Progress (commit 跟 test 已完成,等 Ken merge + 部署)
  • #1343: 持續觀察中(主症狀修法方案 X 仍在評估)

參考連結

  • 相關 ticket: #1345 (StatusNotificationHandler last_status_change bug)
  • Branch: feature/redmine-1345-status-notification-last-status-change
  • Commit: 27e7d76

2026-06-19 00:06 重大更新(SS3A framework 治本影響 #1343 修法)

sylksoft/sylksoft-framework 6.9.5-SNAPSHOT build 45 已 deploy。

Framework 改動

PrefixDateSequenceIdGenerator.java build 45 完全重寫:

  • 移除所有 IdGeneratorUtil.nextIdFromSequence()currentIdFromSequence() 呼叫
  • 新邏輯:JVM 內部 ConcurrentHashMap counter + DB max(id)
  • 完全不需要 hibernate_sequence table

#1343 修法的影響

修法 之前評估 現在評估(framework 治本後)
方案 A (Finishing timeout fallback) 方案 A 判斷依賴 last_status_change,需 #1345 修好 仍可做(#1345 已修)但需求降低(卡 Finishing 重現率 1/6)
方案 B (user-triggered reset) 仍可做 仍可做(不受 framework 影響)
方案 X (Fortune.onPreparingWithoutRotation 改 noAction) 治本修法,跟 framework 無關 仍推薦(主症狀 Fortune 自動送電)

#1343#1344 的關係釐清

  • #1343 (華城充電樁 Finishing 卡住 + Fortune 自動送電) — 跟 framework 無關,仍需繼續處理
  • #1344 (hibernate_sequence 缺 e_connector_priority) — 由 framework build 45 治本,Status 改為 Resolved

重申 #1343 仍需做的核心工作

  1. 方案 X (改 Fortune.onPreparingWithoutRotationnoAction()) — Fortune 自動送電主症狀治本修法
  2. 方案 A (ScheduledTask 自動 reset Finishing connector) — 防禦性 fallback,可選
  3. 方案 B (user-triggered reset) — 可選

Ticket 狀態

  • #1343: New (仍需處理 Fortune 自動送電 + Finishing 卡住)
  • #1344: Resolved (framework 已治本)
  • #1345: In Progress (commit 跟 test 已完成,等 Ken merge to private)

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

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

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

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

是由 陳國瑋21 天 前更新

2026-07-13 A17 實機部署查核更新:

已確認 A17 ems-branch-api 容器實際執行的 /app.jar 與主機 /opt/ems/ems_branch/api/api.jar 雜湊一致,檢查結果如下:

  1. #1344 已在 A17 生效:ss3a-kernel 6.9.5-SNAPSHOT 的 PrefixDateSequenceIdGenerator 已改為 DB max(id) + JVM counter,不再依賴 hibernate_sequence。
  2. #1345 已在 A17 生效:StatusNotificationHandler 已在新增/更新 connector 時呼叫 Connector.updateStatus(...),last_status_change 會隨 StatusNotification 更新。
  3. #1343 本體尚未實作/部署:FortuneConnectorTypeRotationStrategy.onPreparingWithoutRotation() 目前仍回傳 SEND_REMOTE_START,表示 Fortune/Tesla/Unknown 在未輪充且收到 PREPARING 時仍可能自動 RemoteStart。
  4. #1343 的 FINISHING fallback 也尚未看到:RemoteChargingSupport.isConnectorAvailableForCharging() 目前仍只接受 AVAILABLE / PREPARING;未看到 FINISHING 超時自動 reset AVAILABLE,或使用者再次開始充電時的被動 reset 邏輯。

結論:#1344、#1345 可視為 #1343 的前置/旁支修補且已部署;#1343 仍需補本體業務邏輯,至少包含「Fortune 未輪充 PREPARING 不自動送電」以及是否要做 FINISHING timeout/user-triggered fallback 的決策與實作。

動作

匯出至 Atom PDF