From a488b9265e632d6af204b85bb82ee5ac9c72571b Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Thu, 19 Mar 2026 18:49:02 +0100 Subject: [PATCH] refactor(ocpp2.0): parameterize requestStopTransaction triggerReason and stoppedReason --- .../ocpp/2.0/OCPP20ServiceUtils.ts | 8 ++- ...CPP20ServiceUtils-TransactionEvent.test.ts | 71 +++++++++++++++++++ 2 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/charging-station/ocpp/2.0/OCPP20ServiceUtils.ts b/src/charging-station/ocpp/2.0/OCPP20ServiceUtils.ts index 7f1ef3ec..45b234c3 100644 --- a/src/charging-station/ocpp/2.0/OCPP20ServiceUtils.ts +++ b/src/charging-station/ocpp/2.0/OCPP20ServiceUtils.ts @@ -347,7 +347,9 @@ export class OCPP20ServiceUtils extends OCPPServiceUtils { public static async requestStopTransaction ( chargingStation: ChargingStation, connectorId: number, - evseId?: number + evseId?: number, + triggerReason: OCPP20TriggerReasonEnumType = OCPP20TriggerReasonEnumType.RemoteStop, + stoppedReason: OCPP20ReasonEnumType = OCPP20ReasonEnumType.Remote ): Promise { const connectorStatus = chargingStation.getConnectorStatus(connectorId) if ( @@ -371,13 +373,13 @@ export class OCPP20ServiceUtils extends OCPPServiceUtils { const response = await this.sendTransactionEvent( chargingStation, OCPP20TransactionEventEnumType.Ended, - OCPP20TriggerReasonEnumType.RemoteStop, + triggerReason, connectorId, transactionId, { evseId, meterValue: finalMeterValues.length > 0 ? finalMeterValues : undefined, - stoppedReason: OCPP20ReasonEnumType.Remote, + stoppedReason, } ) diff --git a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts index 1ec78532..676ee713 100644 --- a/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts +++ b/tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts @@ -2578,4 +2578,75 @@ await describe('OCPP20 TransactionEvent ServiceUtils', async () => { } }) }) + + await describe('requestStopTransaction', async () => { + let mockTracking: MockStationWithTracking + + beforeEach(() => { + mockTracking = createMockStationWithRequestTracking() + resetConnectorTransactionState(mockTracking.station) + }) + + afterEach(() => { + standardCleanup() + }) + + await it('should default to RemoteStop triggerReason and Remote stoppedReason', async () => { + // Arrange + const connectorId = 1 + const transactionId = generateUUID() + const connectorStatus = mockTracking.station.getConnectorStatus(connectorId) + assert.notStrictEqual(connectorStatus, undefined) + if (connectorStatus != null) { + connectorStatus.transactionStarted = true + connectorStatus.transactionId = transactionId + connectorStatus.transactionEnergyActiveImportRegisterValue = 0 + } + + // Act + await OCPP20ServiceUtils.requestStopTransaction(mockTracking.station, connectorId, 1) + + // Assert + const txEvents = mockTracking.sentRequests.filter(r => r.command === 'TransactionEvent') + assert.strictEqual(txEvents.length, 1) + + const endedEvent = txEvents[0].payload + assert.strictEqual(endedEvent.eventType, OCPP20TransactionEventEnumType.Ended) + assert.strictEqual(endedEvent.triggerReason, OCPP20TriggerReasonEnumType.RemoteStop) + assert.strictEqual(endedEvent.stoppedReason, OCPP20ReasonEnumType.Remote) + }) + + await it('should use custom triggerReason and stoppedReason when provided', async () => { + // Arrange + const connectorId = 2 + const transactionId = generateUUID() + const customTriggerReason = OCPP20TriggerReasonEnumType.Authorized + const customStoppedReason = OCPP20ReasonEnumType.DeAuthorized + const connectorStatus = mockTracking.station.getConnectorStatus(connectorId) + assert.notStrictEqual(connectorStatus, undefined) + if (connectorStatus != null) { + connectorStatus.transactionStarted = true + connectorStatus.transactionId = transactionId + connectorStatus.transactionEnergyActiveImportRegisterValue = 0 + } + + // Act + await OCPP20ServiceUtils.requestStopTransaction( + mockTracking.station, + connectorId, + 2, + customTriggerReason, + customStoppedReason + ) + + // Assert + const txEvents = mockTracking.sentRequests.filter(r => r.command === 'TransactionEvent') + assert.strictEqual(txEvents.length, 1) + + const endedEvent = txEvents[0].payload + assert.strictEqual(endedEvent.eventType, OCPP20TransactionEventEnumType.Ended) + assert.strictEqual(endedEvent.triggerReason, customTriggerReason) + assert.strictEqual(endedEvent.stoppedReason, customStoppedReason) + }) + }) }) -- 2.43.0