Merge pull request #921 from SAP/combined-prs-branch
[e-mobility-charging-stations-simulator.git] / src / charging-station / ChargingStation.ts
index a1bb33a9c3fcca906d65a3fb8027dc4200a7e141..a6721c5332ab09d7e1e4adf95ae627141653c6f2 100644 (file)
@@ -143,7 +143,6 @@ import {
   handleFileException,
   isNotEmptyArray,
   isNotEmptyString,
-  isUndefined,
   logPrefix,
   logger,
   min,
@@ -157,7 +156,7 @@ import {
 export class ChargingStation extends EventEmitter {
   public readonly index: number
   public readonly templateFile: string
-  public stationInfo!: ChargingStationInfo
+  public stationInfo?: ChargingStationInfo
   public started: boolean
   public starting: boolean
   public idTagsCache: IdTagsCache
@@ -172,7 +171,7 @@ export class ChargingStation extends EventEmitter {
   public ocppRequestService!: OCPPRequestService
   public bootNotificationRequest!: BootNotificationRequest
   public bootNotificationResponse!: BootNotificationResponse | undefined
-  public powerDivider!: number
+  public powerDivider?: number
   private stopping: boolean
   private configurationFile!: string
   private configurationFileHash!: string
@@ -228,19 +227,23 @@ export class ChargingStation extends EventEmitter {
     return new URL(
       `${
         this.stationInfo?.supervisionUrlOcppConfiguration === true &&
-        isNotEmptyString(this.stationInfo?.supervisionUrlOcppKey) &&
+        isNotEmptyString(this.stationInfo.supervisionUrlOcppKey) &&
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         isNotEmptyString(getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey!)?.value)
           ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
             getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey!)!.value
           : this.configuredSupervisionUrl.href
-      }/${this.stationInfo.chargingStationId}`
+      }/${this.stationInfo?.chargingStationId}`
     )
   }
 
   public logPrefix = (): string => {
-    if (isNotEmptyString(this?.stationInfo?.chargingStationId)) {
-      return logPrefix(` ${this?.stationInfo?.chargingStationId} |`)
+    if (
+      this instanceof ChargingStation &&
+      this.stationInfo != null &&
+      isNotEmptyString(this.stationInfo.chargingStationId)
+    ) {
+      return logPrefix(` ${this.stationInfo.chargingStationId} |`)
     }
     let stationTemplate: ChargingStationTemplate | undefined
     try {
@@ -255,11 +258,12 @@ export class ChargingStation extends EventEmitter {
 
   public hasIdTags (): boolean {
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    return isNotEmptyArray(this.idTagsCache.getIdTags(getIdTagsFile(this.stationInfo)!))
+    return isNotEmptyArray(this.idTagsCache.getIdTags(getIdTagsFile(this.stationInfo!)!))
   }
 
   public getNumberOfPhases (stationInfo?: ChargingStationInfo): number {
-    const localStationInfo: ChargingStationInfo = stationInfo ?? this.stationInfo
+    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+    const localStationInfo = stationInfo ?? this.stationInfo!
     switch (this.getCurrentOutType(stationInfo)) {
       case CurrentType.AC:
         return localStationInfo.numberOfPhases ?? 3
@@ -269,23 +273,23 @@ export class ChargingStation extends EventEmitter {
   }
 
   public isWebSocketConnectionOpened (): boolean {
-    return this?.wsConnection?.readyState === WebSocket.OPEN
+    return this.wsConnection?.readyState === WebSocket.OPEN
   }
 
   public inUnknownState (): boolean {
-    return this?.bootNotificationResponse?.status == null
+    return this.bootNotificationResponse?.status == null
   }
 
   public inPendingState (): boolean {
-    return this?.bootNotificationResponse?.status === RegistrationStatusEnumType.PENDING
+    return this.bootNotificationResponse?.status === RegistrationStatusEnumType.PENDING
   }
 
   public inAcceptedState (): boolean {
-    return this?.bootNotificationResponse?.status === RegistrationStatusEnumType.ACCEPTED
+    return this.bootNotificationResponse?.status === RegistrationStatusEnumType.ACCEPTED
   }
 
   public inRejectedState (): boolean {
-    return this?.bootNotificationResponse?.status === RegistrationStatusEnumType.REJECTED
+    return this.bootNotificationResponse?.status === RegistrationStatusEnumType.REJECTED
   }
 
   public isRegistered (): boolean {
@@ -346,10 +350,11 @@ export class ChargingStation extends EventEmitter {
 
   public getConnectorMaximumAvailablePower (connectorId: number): number {
     let connectorAmperageLimitationPowerLimit: number | undefined
+    const amperageLimitation = this.getAmperageLimitation()
     if (
-      this.getAmperageLimitation() != null &&
+      amperageLimitation != null &&
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      this.getAmperageLimitation()! < this.stationInfo.maximumAmperage!
+      amperageLimitation < this.stationInfo!.maximumAmperage!
     ) {
       connectorAmperageLimitationPowerLimit =
         (this.stationInfo?.currentOutType === CurrentType.AC
@@ -357,16 +362,16 @@ export class ChargingStation extends EventEmitter {
             this.getNumberOfPhases(),
             // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
             this.stationInfo.voltageOut!,
-            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-            this.getAmperageLimitation()! *
+            amperageLimitation *
                 (this.hasEvses ? this.getNumberOfEvses() : this.getNumberOfConnectors())
           )
           : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-          DCElectricUtils.power(this.stationInfo.voltageOut!, this.getAmperageLimitation()!)) /
-        this.powerDivider
+          DCElectricUtils.power(this.stationInfo!.voltageOut!, amperageLimitation)) /
+        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        this.powerDivider!
     }
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    const connectorMaximumPower = this.stationInfo.maximumPower! / this.powerDivider
+    const connectorMaximumPower = this.stationInfo!.maximumPower! / this.powerDivider!
     const connectorChargingProfilesPowerLimit =
       getChargingStationConnectorChargingProfilesPowerLimit(this, connectorId)
     return min(
@@ -495,12 +500,13 @@ export class ChargingStation extends EventEmitter {
   public setSupervisionUrl (url: string): void {
     if (
       this.stationInfo?.supervisionUrlOcppConfiguration === true &&
-      isNotEmptyString(this.stationInfo?.supervisionUrlOcppKey)
+      isNotEmptyString(this.stationInfo.supervisionUrlOcppKey)
     ) {
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       setConfigurationKeyValue(this, this.stationInfo.supervisionUrlOcppKey!, url)
     } else {
-      this.stationInfo.supervisionUrls = url
+      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+      this.stationInfo!.supervisionUrls = url
       this.saveStationInfo()
       this.configuredSupervisionUrl = this.getConfiguredSupervisionUrl()
     }
@@ -644,11 +650,11 @@ export class ChargingStation extends EventEmitter {
                 // Initialize
                 this.initialize()
                 // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-                this.idTagsCache.deleteIdTags(getIdTagsFile(this.stationInfo)!)
+                this.idTagsCache.deleteIdTags(getIdTagsFile(this.stationInfo!)!)
                 // Restart the ATG
                 this.stopAutomaticTransactionGenerator()
                 delete this.automaticTransactionGeneratorConfiguration
-                if (this.getAutomaticTransactionGeneratorConfiguration().enable) {
+                if (this.getAutomaticTransactionGeneratorConfiguration()?.enable === true) {
                   this.startAutomaticTransactionGenerator()
                 }
                 if (this.stationInfo?.enableStatistics === true) {
@@ -705,7 +711,7 @@ export class ChargingStation extends EventEmitter {
   public async reset (reason?: StopTransactionReason): Promise<void> {
     await this.stop(reason)
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    await sleep(this.stationInfo.resetTime!)
+    await sleep(this.stationInfo!.resetTime!)
     this.initialize()
     this.start()
   }
@@ -734,13 +740,13 @@ export class ChargingStation extends EventEmitter {
     if (!checkChargingStation(this, this.logPrefix())) {
       return
     }
-    if (this.stationInfo.supervisionUser != null && this.stationInfo.supervisionPassword != null) {
+    if (this.stationInfo?.supervisionUser != null && this.stationInfo.supervisionPassword != null) {
       options.auth = `${this.stationInfo.supervisionUser}:${this.stationInfo.supervisionPassword}`
     }
-    if (params?.closeOpened === true) {
+    if (params.closeOpened === true) {
       this.closeWSConnection()
     }
-    if (params?.terminateOpened === true) {
+    if (params.terminateOpened === true) {
       this.terminateWSConnection()
     }
 
@@ -791,7 +797,9 @@ export class ChargingStation extends EventEmitter {
     }
   }
 
-  public getAutomaticTransactionGeneratorConfiguration (): AutomaticTransactionGeneratorConfiguration {
+  public getAutomaticTransactionGeneratorConfiguration ():
+  | AutomaticTransactionGeneratorConfiguration
+  | undefined {
     if (this.automaticTransactionGeneratorConfiguration == null) {
       let automaticTransactionGeneratorConfiguration:
       | AutomaticTransactionGeneratorConfiguration
@@ -804,7 +812,7 @@ export class ChargingStation extends EventEmitter {
         stationConfiguration?.automaticTransactionGenerator != null
       ) {
         automaticTransactionGeneratorConfiguration =
-          stationConfiguration?.automaticTransactionGenerator
+          stationConfiguration.automaticTransactionGenerator
       } else {
         automaticTransactionGeneratorConfiguration = stationTemplate?.AutomaticTransactionGenerator
       }
@@ -851,17 +859,17 @@ export class ChargingStation extends EventEmitter {
     connectorId: number,
     reason?: StopTransactionReason
   ): Promise<StopTransactionResponse> {
-    const transactionId = this.getConnectorStatus(connectorId)?.transactionId
+    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+    const transactionId = this.getConnectorStatus(connectorId)!.transactionId!
     if (
       this.stationInfo?.beginEndMeterValues === true &&
-      this.stationInfo?.ocppStrictCompliance === true &&
-      this.stationInfo?.outOfOrderEndMeterValues === false
+      this.stationInfo.ocppStrictCompliance === true &&
+      this.stationInfo.outOfOrderEndMeterValues === false
     ) {
       const transactionEndMeterValue = buildTransactionEndMeterValue(
         this,
         connectorId,
-        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        this.getEnergyActiveImportRegisterByTransactionId(transactionId!)
+        this.getEnergyActiveImportRegisterByTransactionId(transactionId)
       )
       await this.ocppRequestService.requestHandler<MeterValuesRequest, MeterValuesResponse>(
         this,
@@ -878,8 +886,7 @@ export class ChargingStation extends EventEmitter {
     StopTransactionResponse
     >(this, RequestCommand.STOP_TRANSACTION, {
       transactionId,
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      meterStop: this.getEnergyActiveImportRegisterByTransactionId(transactionId!, true),
+      meterStop: this.getEnergyActiveImportRegisterByTransactionId(transactionId, true),
       ...(reason != null && { reason })
     })
   }
@@ -943,14 +950,14 @@ export class ChargingStation extends EventEmitter {
     if (this.hasEvses) {
       for (const evseStatus of this.evses.values()) {
         for (const connectorStatus of evseStatus.connectors.values()) {
-          if (connectorStatus?.reservation?.[filterKey] === value) {
+          if (connectorStatus.reservation?.[filterKey] === value) {
             return connectorStatus.reservation
           }
         }
       }
     } else {
       for (const connectorStatus of this.connectors.values()) {
-        if (connectorStatus?.reservation?.[filterKey] === value) {
+        if (connectorStatus.reservation?.[filterKey] === value) {
           return connectorStatus.reservation
         }
       }
@@ -963,20 +970,15 @@ export class ChargingStation extends EventEmitter {
     connectorId?: number
   ): boolean {
     const reservation = this.getReservationBy('reservationId', reservationId)
-    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    const reservationExists = !isUndefined(reservation) && !hasReservationExpired(reservation!)
+    const reservationExists = reservation !== undefined && !hasReservationExpired(reservation)
     if (arguments.length === 1) {
       return !reservationExists
     } else if (arguments.length > 1) {
-      const userReservation = !isUndefined(idTag)
-        ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        this.getReservationBy('idTag', idTag!)
-        : undefined
+      const userReservation =
+        idTag !== undefined ? this.getReservationBy('idTag', idTag) : undefined
       const userReservationExists =
-        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        !isUndefined(userReservation) && !hasReservationExpired(userReservation!)
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      const notConnectorZero = isUndefined(connectorId) ? true : connectorId! > 0
+        userReservation !== undefined && !hasReservationExpired(userReservation)
+      const notConnectorZero = connectorId === undefined ? true : connectorId > 0
       const freeConnectorsAvailable = this.getNumberOfReservableConnectors() > 0
       return (
         !reservationExists && !userReservationExists && notConnectorZero && freeConnectorsAvailable
@@ -1090,36 +1092,36 @@ export class ChargingStation extends EventEmitter {
 
   private getStationInfoFromTemplate (): ChargingStationInfo {
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    const stationTemplate: ChargingStationTemplate = this.getTemplateFromFile()!
+    const stationTemplate = this.getTemplateFromFile()!
     checkTemplate(stationTemplate, this.logPrefix(), this.templateFile)
     const warnTemplateKeysDeprecationOnce = once(warnTemplateKeysDeprecation, this)
     warnTemplateKeysDeprecationOnce(stationTemplate, this.logPrefix(), this.templateFile)
-    if (stationTemplate?.Connectors != null) {
+    if (stationTemplate.Connectors != null) {
       checkConnectorsConfiguration(stationTemplate, this.logPrefix(), this.templateFile)
     }
-    const stationInfo: ChargingStationInfo = stationTemplateToStationInfo(stationTemplate)
+    const stationInfo = stationTemplateToStationInfo(stationTemplate)
     stationInfo.hashId = getHashId(this.index, stationTemplate)
     stationInfo.chargingStationId = getChargingStationId(this.index, stationTemplate)
-    stationInfo.ocppVersion = stationTemplate?.ocppVersion ?? OCPPVersion.VERSION_16
+    stationInfo.ocppVersion = stationTemplate.ocppVersion ?? OCPPVersion.VERSION_16
     createSerialNumber(stationTemplate, stationInfo)
     stationInfo.voltageOut = this.getVoltageOut(stationInfo)
-    if (isNotEmptyArray(stationTemplate?.power)) {
+    if (isNotEmptyArray(stationTemplate.power)) {
       stationTemplate.power = stationTemplate.power as number[]
       const powerArrayRandomIndex = Math.floor(secureRandom() * stationTemplate.power.length)
       stationInfo.maximumPower =
-        stationTemplate?.powerUnit === PowerUnits.KILO_WATT
+        stationTemplate.powerUnit === PowerUnits.KILO_WATT
           ? stationTemplate.power[powerArrayRandomIndex] * 1000
           : stationTemplate.power[powerArrayRandomIndex]
     } else {
-      stationTemplate.power = stationTemplate?.power as number
+      stationTemplate.power = stationTemplate.power as number
       stationInfo.maximumPower =
-        stationTemplate?.powerUnit === PowerUnits.KILO_WATT
+        stationTemplate.powerUnit === PowerUnits.KILO_WATT
           ? stationTemplate.power * 1000
           : stationTemplate.power
     }
     stationInfo.maximumAmperage = this.getMaximumAmperage(stationInfo)
     stationInfo.firmwareVersionPattern =
-      stationTemplate?.firmwareVersionPattern ?? Constants.SEMVER_PATTERN
+      stationTemplate.firmwareVersionPattern ?? Constants.SEMVER_PATTERN
     if (
       isNotEmptyString(stationInfo.firmwareVersion) &&
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
@@ -1138,10 +1140,10 @@ export class ChargingStation extends EventEmitter {
         },
         reset: true
       },
-      stationTemplate?.firmwareUpgrade ?? {}
+      stationTemplate.firmwareUpgrade ?? {}
     )
     stationInfo.resetTime =
-      stationTemplate?.resetTime != null
+      stationTemplate.resetTime != null
         ? secondsToMilliseconds(stationTemplate.resetTime)
         : Constants.CHARGING_STATION_DEFAULT_RESET_TIME
     return stationInfo
@@ -1154,7 +1156,7 @@ export class ChargingStation extends EventEmitter {
     if (stationInfoPersistentConfiguration) {
       stationInfo = this.getConfigurationFromFile()?.stationInfo
       if (stationInfo != null) {
-        delete stationInfo?.infoHash
+        delete stationInfo.infoHash
       }
     }
     return stationInfo
@@ -1162,21 +1164,22 @@ export class ChargingStation extends EventEmitter {
 
   private getStationInfo (): ChargingStationInfo {
     const defaultStationInfo = Constants.DEFAULT_STATION_INFO
-    const stationInfoFromTemplate: ChargingStationInfo = this.getStationInfoFromTemplate()
-    const stationInfoFromFile: ChargingStationInfo | undefined = this.getStationInfoFromFile(
-      stationInfoFromTemplate?.stationInfoPersistentConfiguration
+    const stationInfoFromTemplate = this.getStationInfoFromTemplate()
+    const stationInfoFromFile = this.getStationInfoFromFile(
+      stationInfoFromTemplate.stationInfoPersistentConfiguration
     )
     // Priority:
     // 1. charging station info from template
     // 2. charging station info from configuration file
-    if (stationInfoFromFile?.templateHash === stationInfoFromTemplate.templateHash) {
-      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      return { ...defaultStationInfo, ...stationInfoFromFile! }
+    if (
+      stationInfoFromFile != null &&
+      stationInfoFromFile.templateHash === stationInfoFromTemplate.templateHash
+    ) {
+      return { ...defaultStationInfo, ...stationInfoFromFile }
     }
     stationInfoFromFile != null &&
       propagateSerialNumber(
-        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        this.getTemplateFromFile()!,
+        this.getTemplateFromFile(),
         stationInfoFromFile,
         stationInfoFromTemplate
       )
@@ -1205,8 +1208,7 @@ export class ChargingStation extends EventEmitter {
     )
     const stationConfiguration = this.getConfigurationFromFile()
     if (
-      stationConfiguration?.stationInfo?.templateHash === stationTemplate?.templateHash &&
-      // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
+      stationConfiguration?.stationInfo?.templateHash === stationTemplate.templateHash &&
       (stationConfiguration?.connectorsStatus != null || stationConfiguration?.evsesStatus != null)
     ) {
       checkConfiguration(stationConfiguration, this.logPrefix(), this.configurationFile)
@@ -1220,7 +1222,7 @@ export class ChargingStation extends EventEmitter {
       isNotEmptyString(this.stationInfo.firmwareVersion) &&
       isNotEmptyString(this.stationInfo.firmwareVersionPattern)
     ) {
-      const patternGroup: number | undefined =
+      const patternGroup =
         this.stationInfo.firmwareUpgrade?.versionUpgrade?.patternGroup ??
         this.stationInfo.firmwareVersion?.split('.').length
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
@@ -1241,15 +1243,20 @@ export class ChargingStation extends EventEmitter {
     }
     this.saveStationInfo()
     this.configuredSupervisionUrl = this.getConfiguredSupervisionUrl()
-    if (this.stationInfo?.enableStatistics === true) {
+    if (this.stationInfo.enableStatistics === true) {
       this.performanceStatistics = PerformanceStatistics.getInstance(
         this.stationInfo.hashId,
-        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        this.stationInfo.chargingStationId!,
+        this.stationInfo.chargingStationId,
         this.configuredSupervisionUrl
       )
     }
-    this.bootNotificationRequest = createBootNotificationRequest(this.stationInfo)
+    const bootNotificationRequest = createBootNotificationRequest(this.stationInfo)
+    if (bootNotificationRequest == null) {
+      const errorMsg = 'Error while creating boot notification request'
+      logger.error(`${this.logPrefix()} ${errorMsg}`)
+      throw new BaseError(errorMsg)
+    }
+    this.bootNotificationRequest = bootNotificationRequest
     this.powerDivider = this.getPowerDivider()
     // OCPP configuration
     this.ocppConfiguration = this.getOcppConfiguration()
@@ -1260,7 +1267,7 @@ export class ChargingStation extends EventEmitter {
         logger.error(`${this.logPrefix()} Error while starting the message sequence:`, error)
       })
     })
-    if (this.stationInfo?.autoRegister === true) {
+    if (this.stationInfo.autoRegister === true) {
       this.bootNotificationResponse = {
         currentTime: new Date(),
         interval: millisecondsToSeconds(this.getHeartbeatInterval()),
@@ -1302,7 +1309,7 @@ export class ChargingStation extends EventEmitter {
     }
     if (
       this.stationInfo?.supervisionUrlOcppConfiguration === true &&
-      isNotEmptyString(this.stationInfo?.supervisionUrlOcppKey) &&
+      isNotEmptyString(this.stationInfo.supervisionUrlOcppKey) &&
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey!) == null
     ) {
@@ -1315,7 +1322,7 @@ export class ChargingStation extends EventEmitter {
       )
     } else if (
       this.stationInfo?.supervisionUrlOcppConfiguration === false &&
-      isNotEmptyString(this.stationInfo?.supervisionUrlOcppKey) &&
+      isNotEmptyString(this.stationInfo.supervisionUrlOcppKey) &&
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       getConfigurationKey(this, this.stationInfo.supervisionUrlOcppKey!) != null
     ) {
@@ -1330,10 +1337,10 @@ export class ChargingStation extends EventEmitter {
       addConfigurationKey(
         this,
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        this.stationInfo.amperageLimitationOcppKey!,
+        this.stationInfo!.amperageLimitationOcppKey!,
         // prettier-ignore
         // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        (this.stationInfo.maximumAmperage! * getAmperageLimitationUnitDivider(this.stationInfo)).toString()
+        (this.stationInfo!.maximumAmperage! * getAmperageLimitationUnitDivider(this.stationInfo)).toString()
       )
     }
     if (getConfigurationKey(this, StandardParametersKey.SupportedFeatureProfiles) == null) {
@@ -1402,11 +1409,11 @@ export class ChargingStation extends EventEmitter {
   }
 
   private initializeConnectorsOrEvsesFromFile (configuration: ChargingStationConfiguration): void {
-    if (configuration?.connectorsStatus != null && configuration?.evsesStatus == null) {
+    if (configuration.connectorsStatus != null && configuration.evsesStatus == null) {
       for (const [connectorId, connectorStatus] of configuration.connectorsStatus.entries()) {
         this.connectors.set(connectorId, cloneObject<ConnectorStatus>(connectorStatus))
       }
-    } else if (configuration?.evsesStatus != null && configuration?.connectorsStatus == null) {
+    } else if (configuration.evsesStatus != null && configuration.connectorsStatus == null) {
       for (const [evseId, evseStatusConfiguration] of configuration.evsesStatus.entries()) {
         const evseStatus = cloneObject<EvseStatusConfiguration>(evseStatusConfiguration)
         delete evseStatus.connectorsStatus
@@ -1421,7 +1428,7 @@ export class ChargingStation extends EventEmitter {
           )
         })
       }
-    } else if (configuration?.evsesStatus != null && configuration?.connectorsStatus != null) {
+    } else if (configuration.evsesStatus != null && configuration.connectorsStatus != null) {
       const errorMsg = `Connectors and evses defined at the same time in configuration file ${this.configurationFile}`
       logger.error(`${this.logPrefix()} ${errorMsg}`)
       throw new BaseError(errorMsg)
@@ -1433,11 +1440,11 @@ export class ChargingStation extends EventEmitter {
   }
 
   private initializeConnectorsOrEvsesFromTemplate (stationTemplate: ChargingStationTemplate): void {
-    if (stationTemplate?.Connectors != null && stationTemplate?.Evses == null) {
+    if (stationTemplate.Connectors != null && stationTemplate.Evses == null) {
       this.initializeConnectorsFromTemplate(stationTemplate)
-    } else if (stationTemplate?.Evses != null && stationTemplate?.Connectors == null) {
+    } else if (stationTemplate.Evses != null && stationTemplate.Connectors == null) {
       this.initializeEvsesFromTemplate(stationTemplate)
-    } else if (stationTemplate?.Evses != null && stationTemplate?.Connectors != null) {
+    } else if (stationTemplate.Evses != null && stationTemplate.Connectors != null) {
       const errorMsg = `Connectors and evses defined at the same time in template file ${this.templateFile}`
       logger.error(`${this.logPrefix()} ${errorMsg}`)
       throw new BaseError(errorMsg)
@@ -1449,45 +1456,46 @@ export class ChargingStation extends EventEmitter {
   }
 
   private initializeConnectorsFromTemplate (stationTemplate: ChargingStationTemplate): void {
-    if (stationTemplate?.Connectors == null && this.connectors.size === 0) {
+    if (stationTemplate.Connectors == null && this.connectors.size === 0) {
       const errorMsg = `No already defined connectors and charging station information from template ${this.templateFile} with no connectors configuration defined`
       logger.error(`${this.logPrefix()} ${errorMsg}`)
       throw new BaseError(errorMsg)
     }
-    if (stationTemplate?.Connectors?.[0] == null) {
+    if (stationTemplate.Connectors?.[0] == null) {
       logger.warn(
         `${this.logPrefix()} Charging station information from template ${
           this.templateFile
         } with no connector id 0 configuration`
       )
     }
-    if (stationTemplate?.Connectors != null) {
+    if (stationTemplate.Connectors != null) {
       const { configuredMaxConnectors, templateMaxConnectors, templateMaxAvailableConnectors } =
         checkConnectorsConfiguration(stationTemplate, this.logPrefix(), this.templateFile)
       const connectorsConfigHash = createHash(Constants.DEFAULT_HASH_ALGORITHM)
         .update(
-          `${JSON.stringify(stationTemplate?.Connectors)}${configuredMaxConnectors.toString()}`
+          `${JSON.stringify(stationTemplate.Connectors)}${configuredMaxConnectors.toString()}`
         )
         .digest('hex')
       const connectorsConfigChanged =
-        this.connectors?.size !== 0 && this.connectorsConfigurationHash !== connectorsConfigHash
-      if (this.connectors?.size === 0 || connectorsConfigChanged) {
+        this.connectors.size !== 0 && this.connectorsConfigurationHash !== connectorsConfigHash
+      if (this.connectors.size === 0 || connectorsConfigChanged) {
         connectorsConfigChanged && this.connectors.clear()
         this.connectorsConfigurationHash = connectorsConfigHash
         if (templateMaxConnectors > 0) {
           for (let connectorId = 0; connectorId <= configuredMaxConnectors; connectorId++) {
             if (
               connectorId === 0 &&
-              (stationTemplate?.Connectors?.[connectorId] == null ||
+              // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+              (stationTemplate.Connectors[connectorId] == null ||
                 !this.getUseConnectorId0(stationTemplate))
             ) {
               continue
             }
             const templateConnectorId =
-              connectorId > 0 && stationTemplate?.randomConnectors === true
+              connectorId > 0 && stationTemplate.randomConnectors === true
                 ? getRandomInteger(templateMaxAvailableConnectors, 1)
                 : connectorId
-            const connectorStatus = stationTemplate?.Connectors[templateConnectorId]
+            const connectorStatus = stationTemplate.Connectors[templateConnectorId]
             checkStationInfoConnectorStatus(
               templateConnectorId,
               connectorStatus,
@@ -1516,48 +1524,48 @@ export class ChargingStation extends EventEmitter {
   }
 
   private initializeEvsesFromTemplate (stationTemplate: ChargingStationTemplate): void {
-    if (stationTemplate?.Evses == null && this.evses.size === 0) {
+    if (stationTemplate.Evses == null && this.evses.size === 0) {
       const errorMsg = `No already defined evses and charging station information from template ${this.templateFile} with no evses configuration defined`
       logger.error(`${this.logPrefix()} ${errorMsg}`)
       throw new BaseError(errorMsg)
     }
-    if (stationTemplate?.Evses?.[0] == null) {
+    if (stationTemplate.Evses?.[0] == null) {
       logger.warn(
         `${this.logPrefix()} Charging station information from template ${
           this.templateFile
         } with no evse id 0 configuration`
       )
     }
-    if (stationTemplate?.Evses?.[0]?.Connectors?.[0] == null) {
+    if (stationTemplate.Evses?.[0]?.Connectors[0] == null) {
       logger.warn(
         `${this.logPrefix()} Charging station information from template ${
           this.templateFile
         } with evse id 0 with no connector id 0 configuration`
       )
     }
-    if (Object.keys(stationTemplate?.Evses?.[0]?.Connectors as object).length > 1) {
+    if (Object.keys(stationTemplate.Evses?.[0]?.Connectors as object).length > 1) {
       logger.warn(
         `${this.logPrefix()} Charging station information from template ${
           this.templateFile
         } with evse id 0 with more than one connector configuration, only connector id 0 configuration will be used`
       )
     }
-    if (stationTemplate?.Evses != null) {
+    if (stationTemplate.Evses != null) {
       const evsesConfigHash = createHash(Constants.DEFAULT_HASH_ALGORITHM)
-        .update(JSON.stringify(stationTemplate?.Evses))
+        .update(JSON.stringify(stationTemplate.Evses))
         .digest('hex')
       const evsesConfigChanged =
-        this.evses?.size !== 0 && this.evsesConfigurationHash !== evsesConfigHash
-      if (this.evses?.size === 0 || evsesConfigChanged) {
+        this.evses.size !== 0 && this.evsesConfigurationHash !== evsesConfigHash
+      if (this.evses.size === 0 || evsesConfigChanged) {
         evsesConfigChanged && this.evses.clear()
         this.evsesConfigurationHash = evsesConfigHash
-        const templateMaxEvses = getMaxNumberOfEvses(stationTemplate?.Evses)
+        const templateMaxEvses = getMaxNumberOfEvses(stationTemplate.Evses)
         if (templateMaxEvses > 0) {
           for (const evseKey in stationTemplate.Evses) {
             const evseId = convertToInt(evseKey)
             this.evses.set(evseId, {
               connectors: buildConnectorsMap(
-                stationTemplate?.Evses[evseKey]?.Connectors,
+                stationTemplate.Evses[evseKey].Connectors,
                 this.logPrefix(),
                 this.templateFile
               ),
@@ -1635,15 +1643,12 @@ export class ChargingStation extends EventEmitter {
         if (!existsSync(dirname(this.configurationFile))) {
           mkdirSync(dirname(this.configurationFile), { recursive: true })
         }
+        const configurationFromFile = this.getConfigurationFromFile()
         let configurationData: ChargingStationConfiguration =
-          this.getConfigurationFromFile() != null
-            ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-            cloneObject<ChargingStationConfiguration>(this.getConfigurationFromFile()!)
+          configurationFromFile != null
+            ? cloneObject<ChargingStationConfiguration>(configurationFromFile)
             : {}
-        if (
-          this.stationInfo?.stationInfoPersistentConfiguration === true &&
-          this.stationInfo != null
-        ) {
+        if (this.stationInfo?.stationInfoPersistentConfiguration === true) {
           configurationData.stationInfo = this.stationInfo
         } else {
           delete configurationData.stationInfo
@@ -1652,7 +1657,7 @@ export class ChargingStation extends EventEmitter {
           this.stationInfo?.ocppPersistentConfiguration === true &&
           Array.isArray(this.ocppConfiguration?.configurationKey)
         ) {
-          configurationData.configurationKey = this.ocppConfiguration?.configurationKey
+          configurationData.configurationKey = this.ocppConfiguration.configurationKey
         } else {
           delete configurationData.configurationKey
         }
@@ -1773,7 +1778,8 @@ export class ChargingStation extends EventEmitter {
           if (!this.isRegistered()) {
             this.stationInfo?.registrationMaxRetries !== -1 && ++registrationRetryCount
             await sleep(
-              this?.bootNotificationResponse?.interval != null
+              // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
+              this.bootNotificationResponse.interval != null
                 ? secondsToMilliseconds(this.bootNotificationResponse.interval)
                 : Constants.DEFAULT_BOOT_NOTIFICATION_INTERVAL
             )
@@ -1781,7 +1787,7 @@ export class ChargingStation extends EventEmitter {
         } while (
           !this.isRegistered() &&
           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-          (registrationRetryCount <= this.stationInfo.registrationMaxRetries! ||
+          (registrationRetryCount <= this.stationInfo!.registrationMaxRetries! ||
             this.stationInfo?.registrationMaxRetries === -1)
         )
       }
@@ -1883,9 +1889,9 @@ export class ChargingStation extends EventEmitter {
       messageId
     )!
     logger.debug(
-      `${this.logPrefix()} << Command '${
-        requestCommandName ?? Constants.UNKNOWN_COMMAND
-      }' received response payload: ${JSON.stringify(response)}`
+      `${this.logPrefix()} << Command '${requestCommandName}' received response payload: ${JSON.stringify(
+        response
+      )}`
     )
     responseCallback(commandPayload, requestPayload)
   }
@@ -1904,9 +1910,9 @@ export class ChargingStation extends EventEmitter {
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
     const [, errorCallback, requestCommandName] = this.getCachedRequest(messageType, messageId)!
     logger.debug(
-      `${this.logPrefix()} << Command '${
-        requestCommandName ?? Constants.UNKNOWN_COMMAND
-      }' received error response payload: ${JSON.stringify(errorResponse)}`
+      `${this.logPrefix()} << Command '${requestCommandName}' received error response payload: ${JSON.stringify(
+        errorResponse
+      )}`
     )
     errorCallback(new OCPPError(errorType, errorMessage, requestCommandName, errorDetails))
   }
@@ -2018,14 +2024,14 @@ export class ChargingStation extends EventEmitter {
         (rounded
           ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
           Math.round(connectorStatus.transactionEnergyActiveImportRegisterValue!)
-          : connectorStatus?.transactionEnergyActiveImportRegisterValue) ?? 0
+          : connectorStatus.transactionEnergyActiveImportRegisterValue) ?? 0
       )
     }
     return (
       (rounded
         ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
         Math.round(connectorStatus.energyActiveImportRegisterValue!)
-        : connectorStatus?.energyActiveImportRegisterValue) ?? 0
+        : connectorStatus.energyActiveImportRegisterValue) ?? 0
     )
   }
 
@@ -2058,8 +2064,7 @@ export class ChargingStation extends EventEmitter {
   private getConnectionTimeout (): number {
     if (getConfigurationKey(this, StandardParametersKey.ConnectionTimeOut) != null) {
       return convertToInt(
-        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-        getConfigurationKey(this, StandardParametersKey.ConnectionTimeOut)!.value! ??
+        getConfigurationKey(this, StandardParametersKey.ConnectionTimeOut)?.value ??
           Constants.DEFAULT_CONNECTION_TIMEOUT
       )
     }
@@ -2076,7 +2081,7 @@ export class ChargingStation extends EventEmitter {
 
   private getMaximumAmperage (stationInfo?: ChargingStationInfo): number | undefined {
     // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-    const maximumPower = (stationInfo ?? this.stationInfo).maximumPower!
+    const maximumPower = (stationInfo ?? this.stationInfo!).maximumPower!
     switch (this.getCurrentOutType(stationInfo)) {
       case CurrentType.AC:
         return ACElectricUtils.amperagePerPhaseFromPower(
@@ -2090,12 +2095,14 @@ export class ChargingStation extends EventEmitter {
   }
 
   private getCurrentOutType (stationInfo?: ChargingStationInfo): CurrentType {
-    return (stationInfo ?? this.stationInfo).currentOutType ?? CurrentType.AC
+    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+    return (stationInfo ?? this.stationInfo!).currentOutType ?? CurrentType.AC
   }
 
   private getVoltageOut (stationInfo?: ChargingStationInfo): Voltage {
     return (
-      (stationInfo ?? this.stationInfo).voltageOut ??
+      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+      (stationInfo ?? this.stationInfo!).voltageOut ??
       getDefaultVoltageOut(this.getCurrentOutType(stationInfo), this.logPrefix(), this.templateFile)
     )
   }
@@ -2104,13 +2111,14 @@ export class ChargingStation extends EventEmitter {
     if (
       isNotEmptyString(this.stationInfo?.amperageLimitationOcppKey) &&
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      getConfigurationKey(this, this.stationInfo.amperageLimitationOcppKey!) != null
+      getConfigurationKey(this, this.stationInfo!.amperageLimitationOcppKey!) != null
     ) {
       return (
         convertToInt(
           // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-          getConfigurationKey(this, this.stationInfo.amperageLimitationOcppKey!)?.value
-        ) / getAmperageLimitationUnitDivider(this.stationInfo)
+          getConfigurationKey(this, this.stationInfo!.amperageLimitationOcppKey!)!.value
+          // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+        ) / getAmperageLimitationUnitDivider(this.stationInfo!)
       )
     }
   }
@@ -2151,7 +2159,7 @@ export class ChargingStation extends EventEmitter {
         }
       }
     }
-    if (this.stationInfo.firmwareStatus === FirmwareStatus.Installing) {
+    if (this.stationInfo?.firmwareStatus === FirmwareStatus.Installing) {
       await this.ocppRequestService.requestHandler<
       FirmwareStatusNotificationRequest,
       FirmwareStatusNotificationResponse
@@ -2162,7 +2170,7 @@ export class ChargingStation extends EventEmitter {
     }
 
     // Start the ATG
-    if (this.getAutomaticTransactionGeneratorConfiguration().enable) {
+    if (this.getAutomaticTransactionGeneratorConfiguration()?.enable === true) {
       this.startAutomaticTransactionGenerator()
     }
     this.flushMessageBuffer()
@@ -2199,7 +2207,7 @@ export class ChargingStation extends EventEmitter {
                 evseId
               )
             )
-            delete connectorStatus?.status
+            delete connectorStatus.status
           }
         }
       }
@@ -2221,7 +2229,7 @@ export class ChargingStation extends EventEmitter {
   }
 
   private startWebSocketPing (): void {
-    const webSocketPingInterval: number =
+    const webSocketPingInterval =
       getConfigurationKey(this, StandardParametersKey.WebSocketPingInterval) != null
         ? convertToInt(
           getConfigurationKey(this, StandardParametersKey.WebSocketPingInterval)?.value
@@ -2294,7 +2302,7 @@ export class ChargingStation extends EventEmitter {
     }
     const errorMsg = 'No supervision url(s) configured'
     logger.error(`${this.logPrefix()} ${errorMsg}`)
-    throw new BaseError(`${errorMsg}`)
+    throw new BaseError(errorMsg)
   }
 
   private stopHeartbeat (): void {
@@ -2317,12 +2325,12 @@ export class ChargingStation extends EventEmitter {
     // Stop heartbeat
     this.stopHeartbeat()
     // Stop the ATG if needed
-    if (this.getAutomaticTransactionGeneratorConfiguration().stopOnConnectionFailure) {
+    if (this.getAutomaticTransactionGeneratorConfiguration()?.stopOnConnectionFailure === true) {
       this.stopAutomaticTransactionGenerator()
     }
     if (
       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
-      this.autoReconnectRetryCount < this.stationInfo.autoReconnectMaxRetries! ||
+      this.autoReconnectRetryCount < this.stationInfo!.autoReconnectMaxRetries! ||
       this.stationInfo?.autoReconnectMaxRetries === -1
     ) {
       ++this.autoReconnectRetryCount
@@ -2332,9 +2340,7 @@ export class ChargingStation extends EventEmitter {
           : secondsToMilliseconds(this.getConnectionTimeout())
       const reconnectDelayWithdraw = 1000
       const reconnectTimeout =
-        reconnectDelay != null && reconnectDelay - reconnectDelayWithdraw > 0
-          ? reconnectDelay - reconnectDelayWithdraw
-          : 0
+        reconnectDelay - reconnectDelayWithdraw > 0 ? reconnectDelay - reconnectDelayWithdraw : 0
       logger.error(
         `${this.logPrefix()} WebSocket connection retry in ${roundTo(
           reconnectDelay,