]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commit
refactor: build version-agnostic OCPP transaction primitives in service layer (#1741)
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 20 Mar 2026 17:07:17 +0000 (18:07 +0100)
committerGitHub <noreply@github.com>
Fri, 20 Mar 2026 17:07:17 +0000 (18:07 +0100)
commit72993ba65aad25297b5a98a9802704661099be32
treedd72598372f9cfd2cef8ed0c9ea48b618b8a82bf
parentede4205df134de4df4de088f82a80090742029ea
refactor: build version-agnostic OCPP transaction primitives in service layer (#1741)

* refactor: add StopTransactionResult type and OCPP 2.0 reason mapping

* refactor: extract OCPP 1.6 stopTransactionOnConnector to OCPP16ServiceUtils

* refactor: add unified stopTransactionOnConnector and stopRunningTransactions to OCPPServiceUtils

Add two version-dispatching functions to OCPPServiceUtils:

- stopTransactionOnConnector: dispatches to OCPP16ServiceUtils or
  OCPP20ServiceUtils via dynamic import, returns StopTransactionResult
- stopRunningTransactions: sequential for OCPP 1.6, parallel (Promise.all)
  for OCPP 2.0, includes transactionPending check for OCPP 2.0

Both use dynamic imports to avoid circular dependencies. stopRunningTransactions
is exposed as OCPPServiceUtils.stopRunningTransactions class member.
stopTransactionOnConnector is exported as standalone function only (class member
omitted due to OCPP16ServiceUtils override type conflict).

Includes 6 tests covering both OCPP versions and error cases.

* refactor: simplify ChargingStation and ATG to use OCPPServiceUtils unified methods

- ChargingStation.stopRunningTransactions: delegate to standalone function from OCPPServiceUtils
- Remove ChargingStation.stopRunningTransactionsOCPP20 private method (logic now in standalone function)
- Remove OCPP20ReasonEnumType import from ChargingStation (no longer needed)
- AutomaticTransactionGenerator.stopTransaction: call stopTransactionOnConnector standalone function
- Update ATG return type to Promise<StopTransactionResult | undefined>
- Use result.accepted instead of stopResponse.idTagInfo?.status === AuthorizationStatus.ACCEPTED
- Remove TODO comment from ATG.stopTransaction

* refactor: remove stopTransactionOnConnector from ChargingStation public API

* refactor: remove stopTransactionOnConnector from ChargingStation public API

- Remove ChargingStation.stopTransactionOnConnector public method
- Remove unused StopTransactionRequest, StopTransactionResponse, buildTransactionEndMeterValue, OCPP16ServiceUtils imports from ChargingStation
- Update OCPP16IncomingRequestService.handleRequestUnlockConnector to call OCPP16ServiceUtils.stopTransactionOnConnector directly
- Update test mocks in RemoteStopUnlock tests to target OCPP16ServiceUtils
- Fix OCPPServiceUtils-StopTransaction test: use args-based pattern for command detection, add proper JSDoc, fix type issues

* refactor(ocpp2.0): deduplicate stop pattern via stopAllTransactions

- Add OCPP20ServiceUtils.stopAllTransactions() — single factored function for parallel
  EVSE iteration + requestStopTransaction, supports optional evseId for single-EVSE scope
- terminateAllTransactions delegates to stopAllTransactions(station, ResetCommand, reason)
- terminateEvseTransactions delegates to stopAllTransactions(station, ResetCommand, reason, evseId)
- stopRunningTransactions OCPP 2.0 path delegates to stopAllTransactions(station, trigger, stopped)
- Eliminates 3x duplicated iteration+parallel-stop pattern

* refactor: add startTransactionOnConnector and flushQueuedTransactionMessages abstractions

- Add startTransactionOnConnector to OCPPServiceUtils (version dispatch via dynamic imports)
  OCPP 1.6: sends START_TRANSACTION via new OCPP16ServiceUtils.startTransactionOnConnector
  OCPP 2.0: sends TransactionEvent(Started) via OCPP20ServiceUtils.sendTransactionEvent
  Returns StartTransactionResult { accepted: boolean }
- Add flushQueuedTransactionMessages to OCPPServiceUtils (OCPP 1.6: no-op, OCPP 2.0: flushes queue)
- Migrate ATG startTransaction to use startTransactionOnConnector (fixes OCPP 2.0 ATG start)
- Migrate ATG handleStartTransactionResponse to handleStartTransactionResult (uses unified type)
- Remove ATG dependency on AuthorizationStatus, RequestCommand, StartTransactionRequest/Response
- Remove ChargingStation.flushQueuedTransactionEvents private method
- Remove version check in ChargingStation boot handler (line 2304)
- Add StartTransactionResult type to types barrel

* refactor: extract periodic meter values to OCPP service layer

- Add OCPP16ServiceUtils.startPeriodicMeterValues/stopPeriodicMeterValues
- Add OCPP20ServiceUtils.startPeriodicMeterValues/stopPeriodicMeterValues
- Add OCPPServiceUtils.startPeriodicMeterValues/stopPeriodicMeterValues (version dispatch)
- Remove startMeterValues, stopMeterValues, startTxUpdatedInterval, stopTxUpdatedInterval,
  restartMeterValues from ChargingStation.ts
- Migrate all callers to use versioned ServiceUtils methods
- Fix test referencing removed startTxUpdatedInterval method
- ChargingStation.ts: -130 lines of version-specific meter values logic removed

* fix: update tests for renamed APIs and removed ChargingStation methods

- AutomaticTransactionGenerator.test.ts: handleStartTransactionResponse -> handleStartTransactionResult, use StartTransactionResult { accepted } instead of StartTransactionResponse
- ChargingStation-Transactions.test.ts: test already uses OCPP16ServiceUtils.stopPeriodicMeterValues
- OCPP20ServiceUtils-TransactionEvent.test.ts: startTxUpdatedInterval -> startPeriodicMeterValues
- StationHelpers.ts: remove stopMeterValues, startMeterValues, startTxUpdatedInterval, stopTxUpdatedInterval, restartMeterValues from mock (no longer on ChargingStation)
- OCPP16ServiceUtils.stopPeriodicMeterValues: add missing delete after clearInterval

* fix: correct startPeriodicMeterValues test to verify no-transaction guard instead of version guard

* fix: guard undefined evseId and avoid throw in shutdown paths

- stopTransactionOnConnector: guard getEvseIdByConnectorId returning undefined, return { accepted: false } with warn log
- stopRunningTransactions: replace throw with warn log in default branch (shutdown path must not crash)

* fix: deduplicate test coverage and address review findings

- Remove ChargingStation-StopRunningTransactions.test.ts (duplicated coverage with OCPPServiceUtils-StopTransaction.test.ts)
- Move error handling test to OCPPServiceUtils-StopTransaction.test.ts
- Guard undefined evseId in stopTransactionOnConnector (review finding)
- Replace throw with warn in stopRunningTransactions default branch (review finding)

* fix: generate transactionId for OCPP 2.0 start and align offline stop acceptance

- startTransactionOnConnector OCPP 2.0: generate UUID transactionId and reset seqNo when
  connector has no transactionId (ATG path)
- stopTransactionOnConnector OCPP 2.0: treat missing idTokenInfo as accepted (offline queued
  events return undefined idTokenInfo, consistent with startTransactionOnConnector)

* fix: map Other reason correctly and use static generateUUID import

- mapStopReasonToOCPP20: add explicit Other -> Other/AbnormalCondition mapping
  instead of falling through to Local/StopAuthorized
- startTransactionOnConnector: use statically imported generateUUID instead of
  unnecessary dynamic import (utils/index.js already imported at top of file)

* test: add coverage for startTransactionOnConnector, flushQueuedTransactionMessages, and mapStopReasonToOCPP20

- startTransactionOnConnector: OCPP 1.6 accepted, OCPP 2.0 accepted, OCPP 2.0 UUID generation
- flushQueuedTransactionMessages: OCPP 1.6 no-op, OCPP 2.0 flush queued events
- mapStopReasonToOCPP20: Other, undefined, Remote mappings

* refactor: remove stopRunningTransactions indirection in ChargingStation

Call stopRunningTransactions(this, reason) directly instead of through
a private method that only delegates.
21 files changed:
src/charging-station/AutomaticTransactionGenerator.ts
src/charging-station/ChargingStation.ts
src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts
src/charging-station/ocpp/1.6/OCPP16ResponseService.ts
src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts
src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts
src/charging-station/ocpp/2.0/OCPP20ResponseService.ts
src/charging-station/ocpp/2.0/OCPP20ServiceUtils.ts
src/charging-station/ocpp/OCPPServiceUtils.ts
src/charging-station/ocpp/index.ts
src/types/index.ts
src/types/ocpp/Transaction.ts
tests/charging-station/AutomaticTransactionGenerator.test.ts
tests/charging-station/ChargingStation-StopRunningTransactions.test.ts [deleted file]
tests/charging-station/ChargingStation-Transactions.test.ts
tests/charging-station/helpers/StationHelpers.ts
tests/charging-station/ocpp/1.6/OCPP16IncomingRequestService-RemoteStopUnlock.test.ts
tests/charging-station/ocpp/1.6/OCPP16Integration-Transactions.test.ts
tests/charging-station/ocpp/1.6/OCPP16ResponseService-Transactions.test.ts
tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts
tests/charging-station/ocpp/OCPPServiceUtils-StopTransaction.test.ts [new file with mode: 0644]