]> Piment Noir Git Repositories - e-mobility-charging-stations-simulator.git/commitdiff
refactor(ocpp2.0): parameterize requestStopTransaction triggerReason and stoppedReason
authorJérôme Benoit <jerome.benoit@sap.com>
Thu, 19 Mar 2026 17:49:02 +0000 (18:49 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Thu, 19 Mar 2026 17:49:02 +0000 (18:49 +0100)
src/charging-station/ocpp/2.0/OCPP20ServiceUtils.ts
tests/charging-station/ocpp/2.0/OCPP20ServiceUtils-TransactionEvent.test.ts

index 7f1ef3ecd4723aba481f1faca5e3bac0c9afd362..45b234c335ac536b67fd59778e1ced2b730fa3f8 100644 (file)
@@ -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<OCPP20TransactionEventResponse> {
     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,
         }
       )
 
index 1ec7853262535ef70c81b9c980c3a3ff8063100a..676ee713e03755edcb6f1700ee88247a630b817c 100644 (file)
@@ -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)
+    })
+  })
 })