feat: untangle add charging station op from start charging station op
[e-mobility-charging-stations-simulator.git] / src / charging-station / ChargingStation.ts
index 2c683058491b713019c10472a8f5c42fe2a45a7c..c8eaf5e44bc70e18844a37ac79390db7a8b845bc 100644 (file)
@@ -3,7 +3,7 @@
 import { createHash } from 'node:crypto'
 import { EventEmitter } from 'node:events'
 import { type FSWatcher, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
-import { dirname, join } from 'node:path'
+import { dirname, join, parse } from 'node:path'
 import { URL } from 'node:url'
 import { parentPort } from 'node:worker_threads'
 
@@ -123,6 +123,7 @@ import {
   Configuration,
   Constants,
   DCElectricUtils,
+  buildAddedMessage,
   buildChargingStationAutomaticTransactionGeneratorConfiguration,
   buildConnectorsStatus,
   buildEvsesStatus,
@@ -206,6 +207,9 @@ export class ChargingStation extends EventEmitter {
     this.idTagsCache = IdTagsCache.getInstance()
     this.chargingStationWorkerBroadcastChannel = new ChargingStationWorkerBroadcastChannel(this)
 
+    this.on(ChargingStationEvents.added, () => {
+      parentPort?.postMessage(buildAddedMessage(this))
+    })
     this.on(ChargingStationEvents.started, () => {
       parentPort?.postMessage(buildStartedMessage(this))
     })
@@ -225,6 +229,9 @@ export class ChargingStation extends EventEmitter {
       })
       this.wsConnectionRetried = false
     })
+    this.on(ChargingStationEvents.rejected, () => {
+      this.wsConnectionRetried = false
+    })
     this.on(ChargingStationEvents.disconnected, () => {
       try {
         this.internalStopMessageSequence()
@@ -237,6 +244,8 @@ export class ChargingStation extends EventEmitter {
     })
 
     this.initialize()
+
+    this.stationInfo?.autoStart === true && this.start()
   }
 
   public get hasEvses (): boolean {
@@ -643,6 +652,10 @@ export class ChargingStation extends EventEmitter {
     }
   }
 
+  public add (): void {
+    this.emit(ChargingStationEvents.added)
+  }
+
   public start (): void {
     if (!this.started) {
       if (!this.starting) {
@@ -708,7 +721,10 @@ export class ChargingStation extends EventEmitter {
     }
   }
 
-  public async stop (reason?: StopTransactionReason, stopTransactions?: boolean): Promise<void> {
+  public async stop (
+    reason?: StopTransactionReason,
+    stopTransactions = this.stationInfo?.stopTransactionsOnStopped
+  ): Promise<void> {
     if (this.started) {
       if (!this.stopping) {
         this.stopping = true
@@ -1123,6 +1139,8 @@ export class ChargingStation extends EventEmitter {
     }
     const stationInfo = stationTemplateToStationInfo(stationTemplate)
     stationInfo.hashId = getHashId(this.index, stationTemplate)
+    stationInfo.autoStart = stationTemplate.autoStart ?? true
+    stationInfo.templateName = parse(this.templateFile).name
     stationInfo.chargingStationId = getChargingStationId(this.index, stationTemplate)
     stationInfo.ocppVersion = stationTemplate.ocppVersion ?? OCPPVersion.VERSION_16
     createSerialNumber(stationTemplate, stationInfo)
@@ -1165,7 +1183,7 @@ export class ChargingStation extends EventEmitter {
     stationInfo.resetTime =
       stationTemplate.resetTime != null
         ? secondsToMilliseconds(stationTemplate.resetTime)
-        : Constants.CHARGING_STATION_DEFAULT_RESET_TIME
+        : Constants.DEFAULT_CHARGING_STATION_RESET_TIME
     return stationInfo
   }
 
@@ -1177,6 +1195,13 @@ export class ChargingStation extends EventEmitter {
       stationInfo = this.getConfigurationFromFile()?.stationInfo
       if (stationInfo != null) {
         delete stationInfo.infoHash
+        // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+        if (stationInfo.templateName == null) {
+          stationInfo.templateName = parse(this.templateFile).name
+        }
+        if (stationInfo.autoStart == null) {
+          stationInfo.autoStart = true
+        }
       }
     }
     return stationInfo
@@ -1857,7 +1882,10 @@ export class ChargingStation extends EventEmitter {
     this.emit(ChargingStationEvents.updated)
   }
 
-  private getCachedRequest (messageType: MessageType, messageId: string): CachedRequest | undefined {
+  private getCachedRequest (
+    messageType: MessageType | undefined,
+    messageId: string
+  ): CachedRequest | undefined {
     const cachedRequest = this.requests.get(messageId)
     if (Array.isArray(cachedRequest)) {
       return cachedRequest
@@ -2020,8 +2048,8 @@ export class ChargingStation extends EventEmitter {
           commandName ?? requestCommandName ?? Constants.UNKNOWN_COMMAND
           // eslint-disable-next-line @typescript-eslint/no-base-to-string
         }' message '${data.toString()}'${
-          messageType !== MessageType.CALL_MESSAGE
-            ? ` matching cached request '${JSON.stringify(this.requests.get(messageId))}'`
+          this.requests.has(messageId)
+            ? ` matching cached request '${JSON.stringify(this.getCachedRequest(messageType, messageId))}'`
             : ''
         } processing error:`,
         error
@@ -2214,7 +2242,7 @@ export class ChargingStation extends EventEmitter {
 
   private async stopMessageSequence (
     reason?: StopTransactionReason,
-    stopTransactions = this.stationInfo?.stopTransactionsOnStopped
+    stopTransactions?: boolean
   ): Promise<void> {
     this.internalStopMessageSequence()
     // Stop ongoing transactions