Bug #1295
已結束[Bug] 離峰時段輪充排程錯誤調度「未啟用離峰充電」的連接器(CP003-001 為例)
概述
問題描述¶
當充電樁連接器在資料庫中設定 enable_off_peak = 0(未啟用離峰充電),但在 e_connector_priority 表有 charge_status = 'eligible' 記錄時,系統會在離峰時段錯誤地將該連接器納入輪充 dispatch,導致車主在「未啟用離峰充電」的情況下被排程離峰充電。
受影響實例: 寶台A17(ct1-ssh.cloudlinkems.com),CP003-001(enable_off_peak=0,B3 群組)
觸發條件¶
-
e_connectors.enable_off_peak = 0(FALSE,非 NULL) e_connector_priority.charge_status = 'eligible'- 離峰時段到來,
ChargingOrchestrator.rotationDispatchTick觸發
證據(寶台A17,2026-05-12 00:00)¶
資料庫狀態¶
connector_id = CP003-001
charge_point_id= CP003
enable_off_peak= \0 (0x00, FALSE,非 NULL)
charge_group = B3
charge_status = eligible
status_reason = NULL
priority = 15
API Log(ems_branch api-2026-05-12-1.log.gz)¶
00:00:00.018 離峰起點時重新亂數排序完成 - chargeGroupId=B3, connectorIds=[CP003-005, CP003-001, CP003-004]
00:00:00.045 rotationDispatchTick 輪充調度,佔用 slot 完成 - connectorId=CP003-001, userId=U2510220002, priority=2
00:00:00.046 不經過輪充檢查的RemoteStart - connectorId=CP003-001, userId=U2510220002, chargePointId=CP003
00:00:00.047 收到遠端啟動充電請求 - connectorId=CP003-001, chargePointId=CP003, userId=U2510220002
...
00:02:14.230 開始交易,交易ID: 239, 連接器ID: CP003-001, 住戶ID: TAG20251022000000002
cp_transactions 記錄¶
transaction_id = 239
connector_id = CP003-001
start_time = 2026-05-12 00:02:14
end_time = 2026-05-12 03:09:42
energy_consumed = 22870 Wh
is_offline = 0
reason = EVDisconnected
根本原因(Root Cause)¶
問題程式碼位置¶
ChargingOrchestrator.rotationDispatchTick → dispatchEligibleConnectors → loadEligiblePriorities
原因說明¶
1. OffPeakEnqueuePolicy.enqueueForOffPeak 有正確的 enable_off_peak 檢查:
if (enabledOffPeak == null || enabledOffPeak.equals(Boolean.FALSE)) {
log.warn("enqueueForOffPeak skipped - connectorId={}, reason={}, enableOffPeak={}, msg=off-peak not enabled");
return OffPeakEnqueueResult.SKIPPED;
}
當 enable_off_peak=0 時,enqueueForOffPeak 正確 Skip,不更新 DB 記錄。
2. dispatchEligibleConnectors(或 loadEligiblePriorities)缺少 enable_off_peak 過濾:
從 e_connector_priority 表篩選 charge_status = ELIGIBLE 時,沒有 JOIN e_connectors 確認 enable_off_peak 是否為 true。
因此 enable_off_peak=0 的 CP003-001(當時 charge_status=eligible)仍然通過 filter。
3. 排程繞過了 OffPeakEnqueuePolicy 的檢查:dispatchEligibleConnectors 直接 dispatch,沒有再次確認 enable_off_peak。
修復方向¶
在 dispatchEligibleConnectors 或 loadEligiblePriorities 的查詢邏輯中,加入 e_connectors.enable_off_peak = TRUE 的過濾條件。
-
選項A(推薦): 在
loadEligiblePriorities的 SQL JOINe_connectors表時加WHERE c.enable_off_peak = TRUE -
選項B: 在
dispatchEligibleConnectors的 Predicate filter 中加connector.getEnableOffPeak() == Boolean.TRUE
受影響範圍¶
所有 enable_off_peak=0 但 e_connector_priority 有 charge_status=eligible 記錄的連接器,在離峰時段都有被錯誤 dispatch 的風險。
查閱的 Log 檔案¶
| 檔案路徑 | 內容 |
|---|---|
/opt/ems/ems_branch/api/logs/api-2026-05-12-1.log.gz |
寶台A17 ems_branch API 全日行為(含 ChargingOrchestrator) |
/opt/ems/ems_branch/api/logs/scheduler-2026-05-12-1.log.gz |
ems_branch scheduler 排程 Log |
/opt/ems/ems_cp3/api/logs/ocpp-modbus-2026-05-12-1.log.gz |
CP003 充電樁 Modbus/OCPP Log |
查閱的 Database Table¶
| Table | 用途 |
|---|---|
e_connectors |
連接器設定(enable_off_peak, charge_group) |
e_connector_priority |
排程優先順序(charge_status=eligible, priority) |
cp_transactions |
充電交易記錄(is_offline, energy_consumed) |
cp_connectors |
連接器狀態 |
e_charge_group |
充電群組設定 |
s_user |
車主帳號 |
相關程式碼(反編譯自 api.jar)¶
-
ChargingOrchestrator.rotationDispatchTick(行 2157, 2724, 341, 374) ChargingOrchestrator.dispatchEligibleConnectors-
OffPeakEnqueuePolicy.enqueueForOffPeak(有正確檢查但未被 dispatchEligibleConnectors 呼叫) ConnectorPriorityRepository.findByChargeGroupAndChargeStatusOrderByPriorityAsc