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