From 5199f9fdf202eb534948f165a0994e1993675aa8 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Thu, 4 Jan 2024 12:16:07 +0100 Subject: [PATCH] refactor: switch eslint configuration to strict type checking recommended rules MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- .eslintrc.cjs | 2 +- bundle.js | 1 - .../AutomaticTransactionGenerator.ts | 61 ++--- src/charging-station/Bootstrap.ts | 10 +- src/charging-station/ChargingStation.ts | 221 +++++++++--------- src/charging-station/ConfigurationKeyUtils.ts | 8 +- src/charging-station/Helpers.ts | 114 +++++---- src/charging-station/IdTagsCache.ts | 10 +- src/charging-station/SharedLRUCache.ts | 12 +- .../ChargingStationWorkerBroadcastChannel.ts | 17 +- .../UIServiceWorkerBroadcastChannel.ts | 2 +- .../ocpp/1.6/OCPP16IncomingRequestService.ts | 90 ++++--- .../ocpp/1.6/OCPP16RequestService.ts | 18 +- .../ocpp/1.6/OCPP16ResponseService.ts | 78 ++++--- .../ocpp/1.6/OCPP16ServiceUtils.ts | 32 +-- .../ocpp/2.0/OCPP20IncomingRequestService.ts | 4 +- .../ocpp/2.0/OCPP20RequestService.ts | 4 +- .../ocpp/2.0/OCPP20ResponseService.ts | 4 +- .../ocpp/OCPPIncomingRequestService.ts | 12 +- .../ocpp/OCPPRequestService.ts | 4 +- src/charging-station/ocpp/OCPPServiceUtils.ts | 88 +++---- .../ui-server/AbstractUIServer.ts | 3 +- .../ui-server/UIHttpServer.ts | 8 +- .../ui-server/UIWebSocketServer.ts | 15 +- .../ui-services/AbstractUIService.ts | 2 +- src/performance/PerformanceStatistics.ts | 18 +- src/performance/storage/JsonFileStorage.ts | 8 +- src/performance/storage/MikroOrmStorage.ts | 23 +- src/performance/storage/MongoDBStorage.ts | 10 +- src/performance/storage/Storage.ts | 2 +- src/types/WorkerBroadcastChannel.ts | 2 +- src/utils/Configuration.ts | 7 +- src/utils/ErrorUtils.ts | 12 +- src/utils/MessageChannelUtils.ts | 5 +- src/utils/StatisticUtils.ts | 1 + src/utils/Utils.ts | 11 +- src/worker/WorkerAbstract.ts | 2 +- src/worker/WorkerDynamicPool.ts | 2 +- src/worker/WorkerFixedPool.ts | 2 +- src/worker/WorkerSet.ts | 3 - 40 files changed, 454 insertions(+), 474 deletions(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 659ebd99..a9d87cf3 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -61,7 +61,7 @@ module.exports = defineConfig({ }, plugins: ['@typescript-eslint', 'eslint-plugin-tsdoc'], extends: [ - 'plugin:@typescript-eslint/recommended-type-checked', + 'plugin:@typescript-eslint/strict-type-checked', 'plugin:@typescript-eslint/stylistic-type-checked', 'plugin:import/typescript', 'standard-with-typescript' diff --git a/bundle.js b/bundle.js index 455da66f..5543d9cb 100644 --- a/bundle.js +++ b/bundle.js @@ -5,7 +5,6 @@ import chalk from 'chalk' import { build } from 'esbuild' import { clean } from 'esbuild-plugin-clean' import { copy } from 'esbuild-plugin-copy' - ;(async () => { const isDevelopmentBuild = env.BUILD === 'development' const sourcemap = !!isDevelopmentBuild diff --git a/src/charging-station/AutomaticTransactionGenerator.ts b/src/charging-station/AutomaticTransactionGenerator.ts index 94198ac6..38efbf51 100644 --- a/src/charging-station/AutomaticTransactionGenerator.ts +++ b/src/charging-station/AutomaticTransactionGenerator.ts @@ -52,13 +52,16 @@ export class AutomaticTransactionGenerator { public static getInstance ( chargingStation: ChargingStation ): AutomaticTransactionGenerator | undefined { - if (!AutomaticTransactionGenerator.instances.has(chargingStation.stationInfo.hashId)) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + if (!AutomaticTransactionGenerator.instances.has(chargingStation.stationInfo!.hashId)) { AutomaticTransactionGenerator.instances.set( - chargingStation.stationInfo.hashId, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + chargingStation.stationInfo!.hashId, new AutomaticTransactionGenerator(chargingStation) ) } - return AutomaticTransactionGenerator.instances.get(chargingStation.stationInfo.hashId) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return AutomaticTransactionGenerator.instances.get(chargingStation.stationInfo!.hashId) } public start (): void { @@ -124,7 +127,7 @@ export class AutomaticTransactionGenerator { private startConnectors (): void { if ( - this.connectorsStatus?.size > 0 && + this.connectorsStatus.size > 0 && this.connectorsStatus.size !== this.chargingStation.getNumberOfConnectors() ) { this.connectorsStatus.clear() @@ -178,7 +181,6 @@ export class AutomaticTransactionGenerator { )}` ) while (this.connectorsStatus.get(connectorId)?.start === true) { - await this.waitChargingStationServiceInitialization(connectorId) await this.waitChargingStationAvailable(connectorId) await this.waitConnectorAvailable(connectorId) if (!this.canStartConnector(connectorId)) { @@ -188,9 +190,9 @@ export class AutomaticTransactionGenerator { const wait = secondsToMilliseconds( getRandomInteger( this.chargingStation.getAutomaticTransactionGeneratorConfiguration() - .maxDelayBetweenTwoTransactions, + ?.maxDelayBetweenTwoTransactions, this.chargingStation.getAutomaticTransactionGeneratorConfiguration() - .minDelayBetweenTwoTransactions + ?.minDelayBetweenTwoTransactions ) ) logger.info(`${this.logPrefix(connectorId)} waiting for ${formatDurationMilliSeconds(wait)}`) @@ -198,18 +200,19 @@ export class AutomaticTransactionGenerator { const start = secureRandom() if ( start < - this.chargingStation.getAutomaticTransactionGeneratorConfiguration().probabilityOfStart + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + this.chargingStation.getAutomaticTransactionGeneratorConfiguration()!.probabilityOfStart ) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.connectorsStatus.get(connectorId)!.skippedConsecutiveTransactions = 0 // Start transaction const startResponse = await this.startTransaction(connectorId) - if (startResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) { + if (startResponse?.idTagInfo.status === AuthorizationStatus.ACCEPTED) { // Wait until end of transaction const waitTrxEnd = secondsToMilliseconds( getRandomInteger( - this.chargingStation.getAutomaticTransactionGeneratorConfiguration().maxDuration, - this.chargingStation.getAutomaticTransactionGeneratorConfiguration().minDuration + this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.maxDuration, + this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.minDuration ) ) logger.info( @@ -272,7 +275,8 @@ export class AutomaticTransactionGenerator { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion this.connectorsStatus.get(connectorId)!.startDate!.getTime() + hoursToMilliseconds( - this.chargingStation.getAutomaticTransactionGeneratorConfiguration().stopAfterHours + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + this.chargingStation.getAutomaticTransactionGeneratorConfiguration()!.stopAfterHours ) - previousRunDuration ) @@ -312,21 +316,6 @@ export class AutomaticTransactionGenerator { return true } - private async waitChargingStationServiceInitialization (connectorId: number): Promise { - let logged = false - while (this.chargingStation?.ocppRequestService == null) { - if (!logged) { - logger.info( - `${this.logPrefix( - connectorId - )} transaction loop waiting for charging station service to be initialized` - ) - logged = true - } - await sleep(Constants.CHARGING_STATION_ATG_INITIALIZATION_TIME) - } - } - private async waitChargingStationAvailable (connectorId: number): Promise { let logged = false while (!this.chargingStation.isChargingStationAvailable()) { @@ -406,14 +395,14 @@ export class AutomaticTransactionGenerator { if (connectorStatus == null) { return } - delete connectorStatus?.startDate - delete connectorStatus?.lastRunDate - delete connectorStatus?.stopDate - delete connectorStatus?.stoppedDate + delete connectorStatus.startDate + delete connectorStatus.lastRunDate + delete connectorStatus.stopDate + delete connectorStatus.stoppedDate if ( !this.started && (connectorStatus.start || - !this.chargingStation.getAutomaticTransactionGeneratorConfiguration().enable) + this.chargingStation.getAutomaticTransactionGeneratorConfiguration()?.enable !== true) ) { connectorStatus.start = false } @@ -428,7 +417,7 @@ export class AutomaticTransactionGenerator { if (this.chargingStation.hasIdTags()) { const idTag = IdTagsCache.getInstance().getIdTag( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.chargingStation.getAutomaticTransactionGeneratorConfiguration().idTagDistribution!, + this.chargingStation.getAutomaticTransactionGeneratorConfiguration()!.idTagDistribution!, this.chargingStation, connectorId ) @@ -499,7 +488,7 @@ export class AutomaticTransactionGenerator { stopResponse = await this.chargingStation.stopTransactionOnConnector(connectorId, reason) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion ++this.connectorsStatus.get(connectorId)!.stopTransactionRequests! - if (stopResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) { + if (stopResponse.idTagInfo?.status === AuthorizationStatus.ACCEPTED) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion ++this.connectorsStatus.get(connectorId)!.acceptedStopTransactionRequests! } else { @@ -526,7 +515,7 @@ export class AutomaticTransactionGenerator { private readonly logPrefix = (connectorId?: number): string => { return logPrefix( - ` ${this.chargingStation.stationInfo.chargingStationId} | ATG${ + ` ${this.chargingStation.stationInfo?.chargingStationId} | ATG${ connectorId != null ? ` on connector #${connectorId}` : '' }:` ) @@ -538,7 +527,7 @@ export class AutomaticTransactionGenerator { ): void { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion ++this.connectorsStatus.get(connectorId)!.startTransactionRequests! - if (startResponse?.idTagInfo?.status === AuthorizationStatus.ACCEPTED) { + if (startResponse.idTagInfo.status === AuthorizationStatus.ACCEPTED) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion ++this.connectorsStatus.get(connectorId)!.acceptedStartTransactionRequests! } else { diff --git a/src/charging-station/Bootstrap.ts b/src/charging-station/Bootstrap.ts index 5b23676f..3993437b 100644 --- a/src/charging-station/Bootstrap.ts +++ b/src/charging-station/Bootstrap.ts @@ -129,7 +129,7 @@ export class Bootstrap extends EventEmitter { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion for (const stationTemplateUrl of Configuration.getStationTemplateUrls()!) { try { - const nbStations = stationTemplateUrl.numberOfStations ?? 0 + const nbStations = stationTemplateUrl.numberOfStations for (let index = 1; index <= nbStations; index++) { await this.startChargingStation(index, stationTemplateUrl) } @@ -156,7 +156,7 @@ export class Bootstrap extends EventEmitter { : '' } worker(s) concurrently running in '${workerConfiguration.processType}' mode${ this.workerImplementation?.maxElementsPerWorker != null - ? ` (${this.workerImplementation?.maxElementsPerWorker} charging station(s) per worker)` + ? ` (${this.workerImplementation.maxElementsPerWorker} charging station(s) per worker)` : '' }` ) @@ -246,7 +246,7 @@ export class Bootstrap extends EventEmitter { private initializeWorkerImplementation (workerConfiguration: WorkerConfiguration): void { let elementsPerWorker: number | undefined - switch (workerConfiguration?.elementsPerWorker) { + switch (workerConfiguration.elementsPerWorker) { case 'auto': elementsPerWorker = this.numberOfChargingStations > availableParallelism() @@ -373,7 +373,7 @@ export class Bootstrap extends EventEmitter { if (isNotEmptyArray(stationTemplateUrls)) { this.numberOfChargingStationTemplates = stationTemplateUrls.length for (const stationTemplateUrl of stationTemplateUrls) { - this.numberOfChargingStations += stationTemplateUrl.numberOfStations ?? 0 + this.numberOfChargingStations += stationTemplateUrl.numberOfStations } } else { console.warn( @@ -413,7 +413,7 @@ export class Bootstrap extends EventEmitter { private gracefulShutdown (): void { this.stop() .then(() => { - console.info(`${chalk.green('Graceful shutdown')}`) + console.info(chalk.green('Graceful shutdown')) this.uiServer?.stop() // stop() asks for charging stations to stop by default this.waitChargingStationsStopped() diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index 7c4b098d..6513f68b 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -156,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 @@ -171,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 @@ -227,19 +227,19 @@ 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 (isNotEmptyString(this.stationInfo?.chargingStationId)) { + return logPrefix(` ${this.stationInfo?.chargingStationId} |`) } let stationTemplate: ChargingStationTemplate | undefined try { @@ -254,11 +254,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: ChargingStationInfo = stationInfo ?? this.stationInfo! switch (this.getCurrentOutType(stationInfo)) { case CurrentType.AC: return localStationInfo.numberOfPhases ?? 3 @@ -268,23 +269,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 { @@ -348,7 +349,7 @@ export class ChargingStation extends EventEmitter { if ( this.getAmperageLimitation() != null && // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.getAmperageLimitation()! < this.stationInfo.maximumAmperage! + this.getAmperageLimitation()! < this.stationInfo!.maximumAmperage! ) { connectorAmperageLimitationPowerLimit = (this.stationInfo?.currentOutType === CurrentType.AC @@ -361,11 +362,12 @@ export class ChargingStation extends EventEmitter { (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!, this.getAmperageLimitation()!)) / + // 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( @@ -494,12 +496,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() } @@ -643,11 +646,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) { @@ -704,7 +707,7 @@ export class ChargingStation extends EventEmitter { public async reset (reason?: StopTransactionReason): Promise { 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() } @@ -733,13 +736,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() } @@ -790,7 +793,9 @@ export class ChargingStation extends EventEmitter { } } - public getAutomaticTransactionGeneratorConfiguration (): AutomaticTransactionGeneratorConfiguration { + public getAutomaticTransactionGeneratorConfiguration (): + | AutomaticTransactionGeneratorConfiguration + | undefined { if (this.automaticTransactionGeneratorConfiguration == null) { let automaticTransactionGeneratorConfiguration: | AutomaticTransactionGeneratorConfiguration @@ -803,7 +808,7 @@ export class ChargingStation extends EventEmitter { stationConfiguration?.automaticTransactionGenerator != null ) { automaticTransactionGeneratorConfiguration = - stationConfiguration?.automaticTransactionGenerator + stationConfiguration.automaticTransactionGenerator } else { automaticTransactionGeneratorConfiguration = stationTemplate?.AutomaticTransactionGenerator } @@ -853,8 +858,8 @@ export class ChargingStation extends EventEmitter { 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, @@ -942,14 +947,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 } } @@ -1088,32 +1093,32 @@ export class ChargingStation extends EventEmitter { 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) 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 @@ -1132,10 +1137,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 @@ -1148,7 +1153,7 @@ export class ChargingStation extends EventEmitter { if (stationInfoPersistentConfiguration) { stationInfo = this.getConfigurationFromFile()?.stationInfo if (stationInfo != null) { - delete stationInfo?.infoHash + delete stationInfo.infoHash } } return stationInfo @@ -1158,7 +1163,7 @@ export class ChargingStation extends EventEmitter { const defaultStationInfo = Constants.DEFAULT_STATION_INFO const stationInfoFromTemplate: ChargingStationInfo = this.getStationInfoFromTemplate() const stationInfoFromFile: ChargingStationInfo | undefined = this.getStationInfoFromFile( - stationInfoFromTemplate?.stationInfoPersistentConfiguration + stationInfoFromTemplate.stationInfoPersistentConfiguration ) // Priority: // 1. charging station info from template @@ -1169,8 +1174,7 @@ export class ChargingStation extends EventEmitter { } stationInfoFromFile != null && propagateSerialNumber( - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - this.getTemplateFromFile()!, + this.getTemplateFromFile(), stationInfoFromFile, stationInfoFromTemplate ) @@ -1199,7 +1203,7 @@ export class ChargingStation extends EventEmitter { ) const stationConfiguration = this.getConfigurationFromFile() if ( - stationConfiguration?.stationInfo?.templateHash === stationTemplate?.templateHash && + stationConfiguration?.stationInfo?.templateHash === stationTemplate.templateHash && (stationConfiguration?.connectorsStatus != null || stationConfiguration?.evsesStatus != null) ) { checkConfiguration(stationConfiguration, this.logPrefix(), this.configurationFile) @@ -1234,7 +1238,7 @@ 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 @@ -1253,7 +1257,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()), @@ -1295,7 +1299,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 ) { @@ -1308,7 +1312,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 ) { @@ -1318,15 +1322,15 @@ 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 ) { 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) { @@ -1395,11 +1399,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)) } - } 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) delete evseStatus.connectorsStatus @@ -1414,7 +1418,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) @@ -1426,11 +1430,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) @@ -1442,45 +1446,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, @@ -1509,48 +1514,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 ), @@ -1633,10 +1638,7 @@ export class ChargingStation extends EventEmitter { ? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion cloneObject(this.getConfigurationFromFile()!) : {} - if ( - this.stationInfo?.stationInfoPersistentConfiguration === true && - this.stationInfo != null - ) { + if (this.stationInfo?.stationInfoPersistentConfiguration === true) { configurationData.stationInfo = this.stationInfo } else { delete configurationData.stationInfo @@ -1645,7 +1647,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 } @@ -1766,7 +1768,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 ) @@ -1774,7 +1777,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) ) } @@ -1876,9 +1879,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) } @@ -1897,9 +1900,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)) } @@ -2011,14 +2014,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 ) } @@ -2051,8 +2054,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 ) } @@ -2069,7 +2071,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( @@ -2083,12 +2085,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) ) } @@ -2097,13 +2101,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!) ) } } @@ -2144,7 +2149,7 @@ export class ChargingStation extends EventEmitter { } } } - if (this.stationInfo.firmwareStatus === FirmwareStatus.Installing) { + if (this.stationInfo?.firmwareStatus === FirmwareStatus.Installing) { await this.ocppRequestService.requestHandler< FirmwareStatusNotificationRequest, FirmwareStatusNotificationResponse @@ -2155,7 +2160,7 @@ export class ChargingStation extends EventEmitter { } // Start the ATG - if (this.getAutomaticTransactionGeneratorConfiguration().enable) { + if (this.getAutomaticTransactionGeneratorConfiguration()?.enable === true) { this.startAutomaticTransactionGenerator() } this.flushMessageBuffer() @@ -2192,7 +2197,7 @@ export class ChargingStation extends EventEmitter { evseId ) ) - delete connectorStatus?.status + delete connectorStatus.status } } } @@ -2287,7 +2292,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 { @@ -2310,12 +2315,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 @@ -2325,9 +2330,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, diff --git a/src/charging-station/ConfigurationKeyUtils.ts b/src/charging-station/ConfigurationKeyUtils.ts index 556cf54a..bb0d9978 100644 --- a/src/charging-station/ConfigurationKeyUtils.ts +++ b/src/charging-station/ConfigurationKeyUtils.ts @@ -46,7 +46,7 @@ export const addConfigurationKey = ( } params = { ...{ overwrite: false, save: false }, ...params } let keyFound = getConfigurationKey(chargingStation, key) - if (keyFound != null && params?.overwrite === true) { + if (keyFound != null && params.overwrite === true) { deleteConfigurationKey(chargingStation, keyFound.key, { save: false }) @@ -61,7 +61,7 @@ export const addConfigurationKey = ( visible: options.visible, reboot: options.reboot }) - params?.save === true && chargingStation.saveOcppConfiguration() + params.save === true && chargingStation.saveOcppConfiguration() } else { logger.error( `${chargingStation.logPrefix()} Trying to add an already existing configuration key: %j`, @@ -99,13 +99,13 @@ export const deleteConfigurationKey = ( params?: DeleteConfigurationKeyParams ): ConfigurationKey[] | undefined => { params = { ...{ save: true, caseInsensitive: false }, ...params } - const keyFound = getConfigurationKey(chargingStation, key, params?.caseInsensitive) + const keyFound = getConfigurationKey(chargingStation, key, params.caseInsensitive) if (keyFound != null) { const deletedConfigurationKey = chargingStation.ocppConfiguration?.configurationKey?.splice( chargingStation.ocppConfiguration.configurationKey.indexOf(keyFound), 1 ) - params?.save === true && chargingStation.saveOcppConfiguration() + params.save === true && chargingStation.saveOcppConfiguration() return deletedConfigurationKey } } diff --git a/src/charging-station/Helpers.ts b/src/charging-station/Helpers.ts index a97a9f5a..9a5eeb6e 100644 --- a/src/charging-station/Helpers.ts +++ b/src/charging-station/Helpers.ts @@ -81,9 +81,9 @@ export const getChargingStationId = ( } // In case of multiple instances: add instance index to charging station id const instanceIndex = env.CF_INSTANCE_INDEX ?? 0 - const idSuffix = stationTemplate?.nameSuffix ?? '' + const idSuffix = stationTemplate.nameSuffix ?? '' const idStr = `000000000${index.toString()}` - return stationTemplate?.fixedName === true + return stationTemplate.fixedName === true ? stationTemplate.baseName : `${stationTemplate.baseName}-${instanceIndex.toString()}${idStr.substring( idStr.length - 4 @@ -191,14 +191,16 @@ export const getPhaseRotationValue = ( } } -export const getMaxNumberOfEvses = (evses: Record): number => { +export const getMaxNumberOfEvses = (evses: Record | undefined): number => { if (evses == null) { return -1 } return Object.keys(evses).length } -const getMaxNumberOfConnectors = (connectors: Record): number => { +const getMaxNumberOfConnectors = ( + connectors: Record | undefined +): number => { if (connectors == null) { return -1 } @@ -212,17 +214,17 @@ export const getBootConnectorStatus = ( ): ConnectorStatusEnum => { let connectorBootStatus: ConnectorStatusEnum if ( - connectorStatus?.status == null && + connectorStatus.status == null && (!chargingStation.isChargingStationAvailable() || !chargingStation.isConnectorAvailable(connectorId)) ) { connectorBootStatus = ConnectorStatusEnum.Unavailable - } else if (connectorStatus?.status == null && connectorStatus?.bootStatus != null) { + } else if (connectorStatus.status == null && connectorStatus.bootStatus != null) { // Set boot status in template at startup - connectorBootStatus = connectorStatus?.bootStatus - } else if (connectorStatus?.status != null) { + connectorBootStatus = connectorStatus.bootStatus + } else if (connectorStatus.status != null) { // Set previous status at startup - connectorBootStatus = connectorStatus?.status + connectorBootStatus = connectorStatus.status } else { // Set default status connectorBootStatus = ConnectorStatusEnum.Available @@ -231,7 +233,7 @@ export const getBootConnectorStatus = ( } export const checkTemplate = ( - stationTemplate: ChargingStationTemplate, + stationTemplate: ChargingStationTemplate | undefined, logPrefix: string, templateFile: string ): void => { @@ -288,14 +290,13 @@ export const checkConnectorsConfiguration = ( } => { const configuredMaxConnectors = getConfiguredMaxNumberOfConnectors(stationTemplate) checkConfiguredMaxConnectors(configuredMaxConnectors, logPrefix, templateFile) - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const templateMaxConnectors = getMaxNumberOfConnectors(stationTemplate.Connectors!) + const templateMaxConnectors = getMaxNumberOfConnectors(stationTemplate.Connectors) checkTemplateMaxConnectors(templateMaxConnectors, logPrefix, templateFile) const templateMaxAvailableConnectors = stationTemplate.Connectors?.[0] != null ? templateMaxConnectors - 1 : templateMaxConnectors if ( configuredMaxConnectors > templateMaxAvailableConnectors && - stationTemplate?.randomConnectors !== true + stationTemplate.randomConnectors !== true ) { logger.warn( `${logPrefix} Number of connectors exceeds the number of connector configurations in template ${templateFile}, forcing random connector configurations affectation` @@ -311,7 +312,7 @@ export const checkStationInfoConnectorStatus = ( logPrefix: string, templateFile: string ): void => { - if (connectorStatus?.status != null) { + if (connectorStatus.status != null) { logger.warn( `${logPrefix} Charging station information from template ${templateFile} with connector id ${connectorId} status configuration defined, undefine it` ) @@ -377,13 +378,13 @@ export const resetConnectorStatus = (connectorStatus: ConnectorStatus): void => connectorStatus.idTagAuthorized = false connectorStatus.transactionRemoteStarted = false connectorStatus.transactionStarted = false - delete connectorStatus?.transactionStart - delete connectorStatus?.transactionId - delete connectorStatus?.localAuthorizeIdTag - delete connectorStatus?.authorizeIdTag - delete connectorStatus?.transactionIdTag + delete connectorStatus.transactionStart + delete connectorStatus.transactionId + delete connectorStatus.localAuthorizeIdTag + delete connectorStatus.authorizeIdTag + delete connectorStatus.transactionIdTag connectorStatus.transactionEnergyActiveImportRegisterValue = 0 - delete connectorStatus?.transactionBeginMeterValue + delete connectorStatus.transactionBeginMeterValue } export const createBootNotificationRequest = ( @@ -488,22 +489,22 @@ export const createSerialNumber = ( ): void => { params = { ...{ randomSerialNumberUpperCase: true, randomSerialNumber: true }, ...params } const serialNumberSuffix = - params?.randomSerialNumber === true + params.randomSerialNumber === true ? getRandomSerialNumberSuffix({ upperCase: params.randomSerialNumberUpperCase }) : '' - isNotEmptyString(stationTemplate?.chargePointSerialNumberPrefix) && + isNotEmptyString(stationTemplate.chargePointSerialNumberPrefix) && (stationInfo.chargePointSerialNumber = `${stationTemplate.chargePointSerialNumberPrefix}${serialNumberSuffix}`) - isNotEmptyString(stationTemplate?.chargeBoxSerialNumberPrefix) && + isNotEmptyString(stationTemplate.chargeBoxSerialNumberPrefix) && (stationInfo.chargeBoxSerialNumber = `${stationTemplate.chargeBoxSerialNumberPrefix}${serialNumberSuffix}`) - isNotEmptyString(stationTemplate?.meterSerialNumberPrefix) && + isNotEmptyString(stationTemplate.meterSerialNumberPrefix) && (stationInfo.meterSerialNumber = `${stationTemplate.meterSerialNumberPrefix}${serialNumberSuffix}`) } export const propagateSerialNumber = ( - stationTemplate: ChargingStationTemplate, - stationInfoSrc: ChargingStationInfo, + stationTemplate: ChargingStationTemplate | undefined, + stationInfoSrc: ChargingStationInfo | undefined, stationInfoDst: ChargingStationInfo ): void => { if (stationInfoSrc == null || stationTemplate == null) { @@ -511,18 +512,18 @@ export const propagateSerialNumber = ( 'Missing charging station template or existing configuration to propagate serial number' ) } - stationTemplate?.chargePointSerialNumberPrefix != null && - stationInfoSrc?.chargePointSerialNumber != null + stationTemplate.chargePointSerialNumberPrefix != null && + stationInfoSrc.chargePointSerialNumber != null ? (stationInfoDst.chargePointSerialNumber = stationInfoSrc.chargePointSerialNumber) - : stationInfoDst?.chargePointSerialNumber != null && + : stationInfoDst.chargePointSerialNumber != null && delete stationInfoDst.chargePointSerialNumber - stationTemplate?.chargeBoxSerialNumberPrefix != null && - stationInfoSrc?.chargeBoxSerialNumber != null + stationTemplate.chargeBoxSerialNumberPrefix != null && + stationInfoSrc.chargeBoxSerialNumber != null ? (stationInfoDst.chargeBoxSerialNumber = stationInfoSrc.chargeBoxSerialNumber) - : stationInfoDst?.chargeBoxSerialNumber != null && delete stationInfoDst.chargeBoxSerialNumber - stationTemplate?.meterSerialNumberPrefix != null && stationInfoSrc?.meterSerialNumber != null + : stationInfoDst.chargeBoxSerialNumber != null && delete stationInfoDst.chargeBoxSerialNumber + stationTemplate.meterSerialNumberPrefix != null && stationInfoSrc.meterSerialNumber != null ? (stationInfoDst.meterSerialNumber = stationInfoSrc.meterSerialNumber) - : stationInfoDst?.meterSerialNumber != null && delete stationInfoDst.meterSerialNumber + : stationInfoDst.meterSerialNumber != null && delete stationInfoDst.meterSerialNumber } export const hasFeatureProfile = ( @@ -589,12 +590,12 @@ export const getChargingStationConnectorChargingProfilesPowerLimit = ( chargingStation.logPrefix() ) if (result != null) { - limit = result?.limit - chargingProfile = result?.chargingProfile + limit = result.limit + chargingProfile = result.chargingProfile switch (chargingStation.stationInfo?.currentOutType) { case CurrentType.AC: limit = - chargingProfile?.chargingSchedule?.chargingRateUnit === ChargingRateUnitType.WATT + chargingProfile.chargingSchedule.chargingRateUnit === ChargingRateUnitType.WATT ? limit : ACElectricUtils.powerTotal( chargingStation.getNumberOfPhases(), @@ -605,17 +606,19 @@ export const getChargingStationConnectorChargingProfilesPowerLimit = ( break case CurrentType.DC: limit = - chargingProfile?.chargingSchedule?.chargingRateUnit === ChargingRateUnitType.WATT + chargingProfile.chargingSchedule.chargingRateUnit === ChargingRateUnitType.WATT ? limit : // eslint-disable-next-line @typescript-eslint/no-non-null-assertion DCElectricUtils.power(chargingStation.stationInfo.voltageOut!, limit) } const connectorMaximumPower = // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - chargingStation.stationInfo.maximumPower! / chargingStation.powerDivider + chargingStation.stationInfo!.maximumPower! / chargingStation.powerDivider! if (limit > connectorMaximumPower) { logger.error( - `${chargingStation.logPrefix()} ${moduleName}.getChargingStationConnectorChargingProfilesPowerLimit: Charging profile id ${chargingProfile?.chargingProfileId} limit ${limit} is greater than connector id ${connectorId} maximum ${connectorMaximumPower}: %j`, + `${chargingStation.logPrefix()} ${moduleName}.getChargingStationConnectorChargingProfilesPowerLimit: Charging profile id ${ + chargingProfile.chargingProfileId + } limit ${limit} is greater than connector id ${connectorId} maximum ${connectorMaximumPower}: %j`, result ) limit = connectorMaximumPower @@ -682,7 +685,8 @@ const getConfiguredMaxNumberOfConnectors = (stationTemplate: ChargingStationTemp configuredMaxNumberOfConnectors = stationTemplate.numberOfConnectors as number } else if (stationTemplate.Connectors != null && stationTemplate.Evses == null) { configuredMaxNumberOfConnectors = - stationTemplate.Connectors?.[0] != null + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + stationTemplate.Connectors[0] != null ? getMaxNumberOfConnectors(stationTemplate.Connectors) - 1 : getMaxNumberOfConnectors(stationTemplate.Connectors) } else if (stationTemplate.Evses != null && stationTemplate.Connectors == null) { @@ -746,7 +750,7 @@ const warnDeprecatedTemplateKey = ( templateFile: string, logMsgToAppend = '' ): void => { - if (template?.[key as keyof ChargingStationTemplate] !== undefined) { + if (template[key as keyof ChargingStationTemplate] !== undefined) { const logMsg = `Deprecated template key '${key}' usage in file '${templateFile}'${ isNotEmptyString(logMsgToAppend) ? `. ${logMsgToAppend}` : '' }` @@ -760,7 +764,7 @@ const convertDeprecatedTemplateKey = ( deprecatedKey: string, key?: string ): void => { - if (template?.[deprecatedKey as keyof ChargingStationTemplate] !== undefined) { + if (template[deprecatedKey as keyof ChargingStationTemplate] !== undefined) { if (key !== undefined) { (template as unknown as Record)[key] = template[deprecatedKey as keyof ChargingStationTemplate] @@ -796,21 +800,21 @@ const getLimitFromChargingProfiles = ( const connectorStatus = chargingStation.getConnectorStatus(connectorId)! for (const chargingProfile of chargingProfiles) { const chargingSchedule = chargingProfile.chargingSchedule - if (chargingSchedule?.startSchedule == null && connectorStatus?.transactionStarted === true) { + if (chargingSchedule.startSchedule == null && connectorStatus.transactionStarted === true) { logger.debug( `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} has no startSchedule defined. Trying to set it to the connector current transaction start date` ) // OCPP specifies that if startSchedule is not defined, it should be relative to start of the connector transaction - chargingSchedule.startSchedule = connectorStatus?.transactionStart + chargingSchedule.startSchedule = connectorStatus.transactionStart } - if (chargingSchedule?.startSchedule != null && !isDate(chargingSchedule?.startSchedule)) { + if (chargingSchedule.startSchedule != null && !isDate(chargingSchedule.startSchedule)) { logger.warn( `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} startSchedule property is not a Date instance. Trying to convert it to a Date instance` ) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - chargingSchedule.startSchedule = convertToDate(chargingSchedule?.startSchedule)! + chargingSchedule.startSchedule = convertToDate(chargingSchedule.startSchedule)! } - if (chargingSchedule?.startSchedule != null && chargingSchedule?.duration == null) { + if (chargingSchedule.startSchedule != null && chargingSchedule.duration == null) { logger.debug( `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Charging profile id ${chargingProfile.chargingProfileId} has no duration defined and will be set to the maximum time allowed` ) @@ -937,8 +941,8 @@ export const prepareChargingProfileKind = ( ) delete chargingProfile.chargingSchedule.startSchedule } - if (connectorStatus?.transactionStarted === true) { - chargingProfile.chargingSchedule.startSchedule = connectorStatus?.transactionStart + if (connectorStatus.transactionStarted === true) { + chargingProfile.chargingSchedule.startSchedule = connectorStatus.transactionStart } // FIXME: Handle relative charging profile duration break @@ -973,19 +977,13 @@ export const canProceedChargingProfile = ( ) return false } - if ( - chargingProfile.chargingSchedule.startSchedule != null && - !isValidTime(chargingProfile.chargingSchedule.startSchedule) - ) { + if (!isValidTime(chargingProfile.chargingSchedule.startSchedule)) { logger.error( `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has an invalid startSchedule date defined` ) return false } - if ( - chargingProfile.chargingSchedule.duration != null && - !Number.isSafeInteger(chargingProfile.chargingSchedule.duration) - ) { + if (!Number.isSafeInteger(chargingProfile.chargingSchedule.duration)) { logger.error( `${logPrefix} ${moduleName}.canProceedChargingProfile: Charging profile id ${chargingProfile.chargingProfileId} has non integer duration defined` ) diff --git a/src/charging-station/IdTagsCache.ts b/src/charging-station/IdTagsCache.ts index b50c0620..f00a5589 100644 --- a/src/charging-station/IdTagsCache.ts +++ b/src/charging-station/IdTagsCache.ts @@ -48,9 +48,10 @@ export class IdTagsCache { chargingStation: ChargingStation, connectorId: number ): string { - const hashId = chargingStation.stationInfo.hashId // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const idTagsFile = getIdTagsFile(chargingStation.stationInfo)! + const hashId = chargingStation.stationInfo!.hashId + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + const idTagsFile = getIdTagsFile(chargingStation.stationInfo!)! switch (distribution) { case IdTagDistribution.RANDOM: return this.getRandomIdTag(hashId, idTagsFile) @@ -108,12 +109,13 @@ export class IdTagsCache { private getConnectorAffinityIdTag (chargingStation: ChargingStation, connectorId: number): string { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - const file = getIdTagsFile(chargingStation.stationInfo)! + const file = getIdTagsFile(chargingStation.stationInfo!)! // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const idTags = this.getIdTags(file)! const addressableKey = this.getIdTagsCacheIndexesAddressableKey( file, - chargingStation.stationInfo.hashId + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + chargingStation.stationInfo!.hashId ) this.idTagsCachesAddressableIndexes.set( addressableKey, diff --git a/src/charging-station/SharedLRUCache.ts b/src/charging-station/SharedLRUCache.ts index ef965b1b..fcda613e 100644 --- a/src/charging-station/SharedLRUCache.ts +++ b/src/charging-station/SharedLRUCache.ts @@ -111,14 +111,14 @@ export class SharedLRUCache { chargingStationConfiguration: ChargingStationConfiguration ): boolean { return ( - chargingStationConfiguration?.configurationKey != null && - chargingStationConfiguration?.stationInfo != null && - chargingStationConfiguration?.automaticTransactionGenerator != null && - chargingStationConfiguration?.configurationHash != null && - isNotEmptyArray(chargingStationConfiguration?.configurationKey) && + chargingStationConfiguration.configurationKey != null && + chargingStationConfiguration.stationInfo != null && + chargingStationConfiguration.automaticTransactionGenerator != null && + chargingStationConfiguration.configurationHash != null && + isNotEmptyArray(chargingStationConfiguration.configurationKey) && !isEmptyObject(chargingStationConfiguration.stationInfo) && !isEmptyObject(chargingStationConfiguration.automaticTransactionGenerator) && - isNotEmptyString(chargingStationConfiguration?.configurationHash) + isNotEmptyString(chargingStationConfiguration.configurationHash) ) } } diff --git a/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts b/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts index 06f847c5..24074186 100644 --- a/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts +++ b/src/charging-station/broadcast-channel/ChargingStationWorkerBroadcastChannel.ts @@ -273,7 +273,8 @@ export class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChanne const [uuid, command, requestPayload] = validatedMessageEvent.data as BroadcastChannelRequest if ( requestPayload.hashIds != null && - !requestPayload.hashIds.includes(this.chargingStation.stationInfo.hashId) + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + !requestPayload.hashIds.includes(this.chargingStation.stationInfo!.hashId) ) { return } @@ -290,7 +291,7 @@ export class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChanne commandResponse = await this.commandHandler(command, requestPayload) if (commandResponse == null || isEmptyObject(commandResponse)) { responsePayload = { - hashId: this.chargingStation.stationInfo.hashId, + hashId: this.chargingStation.stationInfo?.hashId, status: ResponseStatus.SUCCESS } } else { @@ -306,7 +307,7 @@ export class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChanne error ) responsePayload = { - hashId: this.chargingStation.stationInfo.hashId, + hashId: this.chargingStation.stationInfo?.hashId, status: ResponseStatus.FAILURE, command, requestPayload, @@ -362,12 +363,12 @@ export class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChanne const responseStatus = this.commandResponseToResponseStatus(command, commandResponse) if (responseStatus === ResponseStatus.SUCCESS) { return { - hashId: this.chargingStation.stationInfo.hashId, + hashId: this.chargingStation.stationInfo?.hashId, status: responseStatus } } return { - hashId: this.chargingStation.stationInfo.hashId, + hashId: this.chargingStation.stationInfo?.hashId, status: responseStatus, command, requestPayload, @@ -389,18 +390,18 @@ export class ChargingStationWorkerBroadcastChannel extends WorkerBroadcastChanne | StartTransactionResponse | StopTransactionResponse | AuthorizeResponse - )?.idTagInfo?.status === AuthorizationStatus.ACCEPTED + ).idTagInfo?.status === AuthorizationStatus.ACCEPTED ) { return ResponseStatus.SUCCESS } return ResponseStatus.FAILURE case BroadcastChannelProcedureName.BOOT_NOTIFICATION: - if (commandResponse?.status === RegistrationStatusEnumType.ACCEPTED) { + if (commandResponse.status === RegistrationStatusEnumType.ACCEPTED) { return ResponseStatus.SUCCESS } return ResponseStatus.FAILURE case BroadcastChannelProcedureName.DATA_TRANSFER: - if (commandResponse?.status === DataTransferStatus.ACCEPTED) { + if (commandResponse.status === DataTransferStatus.ACCEPTED) { return ResponseStatus.SUCCESS } return ResponseStatus.FAILURE diff --git a/src/charging-station/broadcast-channel/UIServiceWorkerBroadcastChannel.ts b/src/charging-station/broadcast-channel/UIServiceWorkerBroadcastChannel.ts index 11127ec9..3e34782f 100644 --- a/src/charging-station/broadcast-channel/UIServiceWorkerBroadcastChannel.ts +++ b/src/charging-station/broadcast-channel/UIServiceWorkerBroadcastChannel.ts @@ -94,7 +94,7 @@ export class UIServiceWorkerBroadcastChannel extends WorkerBroadcastChannel { responsesFailed: this.responses .get(uuid) ?.responses.map((response) => { - if (response != null && response.status === ResponseStatus.FAILURE) { + if (response.status === ResponseStatus.FAILURE) { return response } return undefined diff --git a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts index e2e8dcba..0cd67647 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -120,8 +120,8 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { > public constructor () { - // if (new.target?.name === moduleName) { - // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`) + // if (new.target.name === moduleName) { + // throw new TypeError(`Cannot construct ${new.target.name} instances directly`) // } super(OCPPVersion.VERSION_16) this.incomingRequestHandlers = new Map([ @@ -454,7 +454,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { logger.info( `${chargingStation.logPrefix()} ${type} reset command received, simulating it. The station will be back online in ${formatDurationMilliSeconds( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - chargingStation.stationInfo.resetTime! + chargingStation.stationInfo!.resetTime! )}` ) return OCPP16Constants.OCPP_RESPONSE_ACCEPTED @@ -643,12 +643,12 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { csChargingProfiles.chargingProfilePurpose === OCPP16ChargingProfilePurposeType.TX_PROFILE && connectorId > 0 && connectorStatus?.transactionStarted === true && - csChargingProfiles.transactionId !== connectorStatus?.transactionId + csChargingProfiles.transactionId !== connectorStatus.transactionId ) { logger.error( `${chargingStation.logPrefix()} Trying to set transaction charging profile(s) on connector ${connectorId} with a different transaction id ${ csChargingProfiles.transactionId - } than the started transaction id ${connectorStatus?.transactionId}` + } than the started transaction id ${connectorStatus.transactionId}` ) return OCPP16Constants.OCPP_SET_CHARGING_PROFILE_RESPONSE_REJECTED } @@ -694,7 +694,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const connectorStatus = chargingStation.getConnectorStatus(connectorId)! if ( - isEmptyArray(connectorStatus?.chargingProfiles) && + isEmptyArray(connectorStatus.chargingProfiles) && isEmptyArray(chargingStation.getConnectorStatus(0)?.chargingProfiles) ) { return OCPP16Constants.OCPP_RESPONSE_REJECTED @@ -713,8 +713,8 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { let compositeSchedule: OCPP16ChargingSchedule | undefined for (const chargingProfile of chargingProfiles) { if ( - chargingProfile.chargingSchedule?.startSchedule == null && - connectorStatus?.transactionStarted === true + chargingProfile.chargingSchedule.startSchedule == null && + connectorStatus.transactionStarted === true ) { logger.debug( `${chargingStation.logPrefix()} ${moduleName}.handleRequestGetCompositeSchedule: Charging profile id ${ @@ -722,11 +722,11 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { } has no startSchedule defined. Trying to set it to the connector current transaction start date` ) // OCPP specifies that if startSchedule is not defined, it should be relative to start of the connector transaction - chargingProfile.chargingSchedule.startSchedule = connectorStatus?.transactionStart + chargingProfile.chargingSchedule.startSchedule = connectorStatus.transactionStart } if ( - chargingProfile.chargingSchedule?.startSchedule != null && - !isDate(chargingProfile.chargingSchedule?.startSchedule) + chargingProfile.chargingSchedule.startSchedule != null && + !isDate(chargingProfile.chargingSchedule.startSchedule) ) { logger.warn( `${chargingStation.logPrefix()} ${moduleName}.handleRequestGetCompositeSchedule: Charging profile id ${ @@ -735,12 +735,12 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { ) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion chargingProfile.chargingSchedule.startSchedule = convertToDate( - chargingProfile.chargingSchedule?.startSchedule + chargingProfile.chargingSchedule.startSchedule )! } if ( - chargingProfile.chargingSchedule?.startSchedule != null && - chargingProfile.chargingSchedule?.duration == null + chargingProfile.chargingSchedule.startSchedule != null && + chargingProfile.chargingSchedule.duration == null ) { logger.debug( `${chargingStation.logPrefix()} ${moduleName}.handleRequestGetCompositeSchedule: Charging profile id ${ @@ -932,9 +932,8 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { ) } const remoteStartTransactionLogMsg = ` - ${chargingStation.logPrefix()} Transaction remotely STARTED on ${ - chargingStation.stationInfo.chargingStationId - }#${transactionConnectorId} for idTag '${idTag}'` + ${chargingStation.logPrefix()} Transaction remotely STARTED on ${chargingStation.stationInfo + ?.chargingStationId}#${transactionConnectorId} for idTag '${idTag}'` await OCPP16ServiceUtils.sendAndSetConnectorStatus( chargingStation, transactionConnectorId, @@ -1046,7 +1045,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { connectorId: number, chargingProfile: OCPP16ChargingProfile ): boolean { - if (chargingProfile?.chargingProfilePurpose === OCPP16ChargingProfilePurposeType.TX_PROFILE) { + if (chargingProfile.chargingProfilePurpose === OCPP16ChargingProfilePurposeType.TX_PROFILE) { OCPP16ServiceUtils.setChargingProfile(chargingStation, connectorId, chargingProfile) logger.debug( `${chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on connector id ${connectorId}: %j`, @@ -1110,10 +1109,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { return OCPP16Constants.OCPP_RESPONSE_EMPTY } let { retrieveDate } = commandPayload - if ( - chargingStation.stationInfo.firmwareStatus != null && - chargingStation.stationInfo.firmwareStatus !== OCPP16FirmwareStatus.Installed - ) { + if (chargingStation.stationInfo?.firmwareStatus !== OCPP16FirmwareStatus.Installed) { logger.warn( `${chargingStation.logPrefix()} ${moduleName}.handleRequestUpdateFirmware: Cannot simulate firmware update: firmware update is already in progress` ) @@ -1122,15 +1118,12 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion retrieveDate = convertToDate(retrieveDate)! const now = Date.now() - if (retrieveDate?.getTime() <= now) { + if (retrieveDate.getTime() <= now) { this.updateFirmwareSimulation(chargingStation).catch(Constants.EMPTY_FUNCTION) } else { - setTimeout( - () => { - this.updateFirmwareSimulation(chargingStation).catch(Constants.EMPTY_FUNCTION) - }, - retrieveDate?.getTime() - now - ) + setTimeout(() => { + this.updateFirmwareSimulation(chargingStation).catch(Constants.EMPTY_FUNCTION) + }, retrieveDate.getTime() - now) } return OCPP16Constants.OCPP_RESPONSE_EMPTY } @@ -1147,7 +1140,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { for (const [evseId, evseStatus] of chargingStation.evses) { if (evseId > 0) { for (const [connectorId, connectorStatus] of evseStatus.connectors) { - if (connectorStatus?.transactionStarted === false) { + if (connectorStatus.transactionStarted === false) { await OCPP16ServiceUtils.sendAndSetConnectorStatus( chargingStation, connectorId, @@ -1177,7 +1170,8 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { status: OCPP16FirmwareStatus.Downloading }) - chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Downloading + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + chargingStation.stationInfo!.firmwareStatus = OCPP16FirmwareStatus.Downloading if ( chargingStation.stationInfo?.firmwareUpgrade?.failureStatus === OCPP16FirmwareStatus.DownloadFailed @@ -1187,10 +1181,10 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { OCPP16FirmwareStatusNotificationRequest, OCPP16FirmwareStatusNotificationResponse >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { - status: chargingStation.stationInfo?.firmwareUpgrade?.failureStatus + status: chargingStation.stationInfo.firmwareUpgrade.failureStatus }) chargingStation.stationInfo.firmwareStatus = - chargingStation.stationInfo?.firmwareUpgrade?.failureStatus + chargingStation.stationInfo.firmwareUpgrade.failureStatus return } await sleep(secondsToMilliseconds(getRandomInteger(maxDelay, minDelay))) @@ -1200,7 +1194,8 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { status: OCPP16FirmwareStatus.Downloaded }) - chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Downloaded + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + chargingStation.stationInfo!.firmwareStatus = OCPP16FirmwareStatus.Downloaded let wasTransactionsStarted = false let transactionsStarted: boolean do { @@ -1220,7 +1215,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { for (const [evseId, evseStatus] of chargingStation.evses) { if (evseId > 0) { for (const [connectorId, connectorStatus] of evseStatus.connectors) { - if (connectorStatus?.status !== OCPP16ChargePointStatus.Unavailable) { + if (connectorStatus.status !== OCPP16ChargePointStatus.Unavailable) { await OCPP16ServiceUtils.sendAndSetConnectorStatus( chargingStation, connectorId, @@ -1259,7 +1254,8 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { status: OCPP16FirmwareStatus.Installing }) - chargingStation.stationInfo.firmwareStatus = OCPP16FirmwareStatus.Installing + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + chargingStation.stationInfo!.firmwareStatus = OCPP16FirmwareStatus.Installing if ( chargingStation.stationInfo?.firmwareUpgrade?.failureStatus === OCPP16FirmwareStatus.InstallationFailed @@ -1269,10 +1265,10 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { OCPP16FirmwareStatusNotificationRequest, OCPP16FirmwareStatusNotificationResponse >(chargingStation, OCPP16RequestCommand.FIRMWARE_STATUS_NOTIFICATION, { - status: chargingStation.stationInfo?.firmwareUpgrade?.failureStatus + status: chargingStation.stationInfo.firmwareUpgrade.failureStatus }) chargingStation.stationInfo.firmwareStatus = - chargingStation.stationInfo?.firmwareUpgrade?.failureStatus + chargingStation.stationInfo.firmwareUpgrade.failureStatus return } if (chargingStation.stationInfo?.firmwareUpgrade?.reset === true) { @@ -1305,7 +1301,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { const logFiles = readdirSync(resolve(dirname(fileURLToPath(import.meta.url)), '../')) .filter((file) => file.endsWith('.log')) .map((file) => join('./', file)) - const diagnosticsArchive = `${chargingStation.stationInfo.chargingStationId}_logs.tar.gz` + const diagnosticsArchive = `${chargingStation.stationInfo?.chargingStationId}_logs.tar.gz` create({ gzip: true }, logFiles).pipe(createWriteStream(diagnosticsArchive)) ftpClient = new Client() const accessResponse = await ftpClient.access({ @@ -1349,24 +1345,18 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, { status: OCPP16DiagnosticsStatus.Uploaded }) - if (ftpClient != null) { - ftpClient.close() - } + ftpClient.close() return { fileName: diagnosticsArchive } } throw new OCPPError( ErrorType.GENERIC_ERROR, - `Diagnostics transfer failed with error code ${accessResponse.code}${ - uploadResponse?.code != null && `|${uploadResponse?.code}` - }`, + `Diagnostics transfer failed with error code ${accessResponse.code}|${uploadResponse.code}`, OCPP16IncomingRequestCommand.GET_DIAGNOSTICS ) } throw new OCPPError( ErrorType.GENERIC_ERROR, - `Diagnostics transfer failed with error code ${accessResponse.code}${ - uploadResponse?.code != null && `|${uploadResponse?.code}` - }`, + `Diagnostics transfer failed with error code ${accessResponse.code}|${uploadResponse?.code}`, OCPP16IncomingRequestCommand.GET_DIAGNOSTICS ) } catch (error) { @@ -1376,9 +1366,7 @@ export class OCPP16IncomingRequestService extends OCPPIncomingRequestService { >(chargingStation, OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION, { status: OCPP16DiagnosticsStatus.UploadFailed }) - if (ftpClient != null) { - ftpClient.close() - } + ftpClient?.close() // eslint-disable-next-line @typescript-eslint/no-non-null-assertion return this.handleIncomingRequestError( chargingStation, diff --git a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts index 37e7019c..124ffba1 100644 --- a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts @@ -35,8 +35,8 @@ export class OCPP16RequestService extends OCPPRequestService { protected jsonSchemas: Map> public constructor (ocppResponseService: OCPPResponseService) { - // if (new.target?.name === moduleName) { - // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`) + // if (new.target.name === moduleName) { + // throw new TypeError(`Cannot construct ${new.target.name} instances directly`) // } super(OCPPVersion.VERSION_16, ocppResponseService) this.jsonSchemas = new Map>([ @@ -180,21 +180,21 @@ export class OCPP16RequestService extends OCPPRequestService { return { idTag: Constants.DEFAULT_IDTAG, meterStart: chargingStation.getEnergyActiveImportRegisterByConnectorId( - commandParams?.connectorId as number, + commandParams.connectorId as number, true ), timestamp: new Date(), ...(OCPP16ServiceUtils.hasReservation( chargingStation, - commandParams?.connectorId as number, - commandParams?.idTag as string + commandParams.connectorId as number, + commandParams.idTag as string ) && { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion reservationId: chargingStation.getReservationBy( 'connectorId', chargingStation.getConnectorStatus(0)?.status === OCPP16ChargePointStatus.Reserved ? 0 - : (commandParams?.connectorId as number) + : (commandParams.connectorId as number) )!.reservationId }), ...commandParams @@ -203,14 +203,14 @@ export class OCPP16RequestService extends OCPPRequestService { chargingStation.stationInfo?.transactionDataMeterValues === true && // eslint-disable-next-line @typescript-eslint/no-non-null-assertion (connectorId = chargingStation.getConnectorIdByTransactionId( - commandParams?.transactionId as number + commandParams.transactionId as number )!) energyActiveImportRegister = chargingStation.getEnergyActiveImportRegisterByTransactionId( - commandParams?.transactionId as number, + commandParams.transactionId as number, true ) return { - idTag: chargingStation.getTransactionIdTag(commandParams?.transactionId as number), + idTag: chargingStation.getTransactionIdTag(commandParams.transactionId as number), meterStop: energyActiveImportRegister, timestamp: new Date(), ...(chargingStation.stationInfo?.transactionDataMeterValues === true && { diff --git a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts index f3855a1a..3f311ba5 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts @@ -66,8 +66,8 @@ export class OCPP16ResponseService extends OCPPResponseService { private readonly jsonSchemas: Map> public constructor () { - // if (new.target?.name === moduleName) { - // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`) + // if (new.target.name === moduleName) { + // throw new TypeError(`Cannot construct ${new.target.name} instances directly`) // } super(OCPPVersion.VERSION_16) this.responseHandlers = new Map([ @@ -442,7 +442,7 @@ export class OCPP16ResponseService extends OCPPResponseService { for (const [evseId, evseStatus] of chargingStation.evses) { if (evseId > 0) { for (const [connectorId, connectorStatus] of evseStatus.connectors) { - if (connectorStatus?.authorizeIdTag === requestPayload.idTag) { + if (connectorStatus.authorizeIdTag === requestPayload.idTag) { authorizeConnectorId = connectorId break } @@ -505,10 +505,12 @@ export class OCPP16ResponseService extends OCPPResponseService { chargingStation.getAuthorizeRemoteTxRequests() && chargingStation.getLocalAuthListEnabled() && chargingStation.hasIdTags() && - connectorStatus?.idTagLocalAuthorized === false + connectorStatus.idTagLocalAuthorized === false ) { logger.error( - `${chargingStation.logPrefix()} Trying to start a transaction with a not local authorized idTag ${connectorStatus?.localAuthorizeIdTag} on connector id ${connectorId}` + `${chargingStation.logPrefix()} Trying to start a transaction with a not local authorized idTag ${ + connectorStatus.localAuthorizeIdTag + } on connector id ${connectorId}` ) await this.resetConnectorOnStartTransactionError(chargingStation, connectorId) return @@ -517,42 +519,50 @@ export class OCPP16ResponseService extends OCPPResponseService { connectorStatus?.transactionRemoteStarted === true && chargingStation.getAuthorizeRemoteTxRequests() && chargingStation.stationInfo?.remoteAuthorization === true && - connectorStatus?.idTagLocalAuthorized === false && - connectorStatus?.idTagAuthorized === false + connectorStatus.idTagLocalAuthorized === false && + connectorStatus.idTagAuthorized === false ) { logger.error( - `${chargingStation.logPrefix()} Trying to start a transaction with a not authorized idTag ${connectorStatus?.authorizeIdTag} on connector id ${connectorId}` + `${chargingStation.logPrefix()} Trying to start a transaction with a not authorized idTag ${ + connectorStatus.authorizeIdTag + } on connector id ${connectorId}` ) await this.resetConnectorOnStartTransactionError(chargingStation, connectorId) return } if ( connectorStatus?.idTagAuthorized === true && - connectorStatus?.authorizeIdTag !== requestPayload.idTag + connectorStatus.authorizeIdTag !== requestPayload.idTag ) { logger.error( `${chargingStation.logPrefix()} Trying to start a transaction with an idTag ${ requestPayload.idTag - } different from the authorize request one ${connectorStatus?.authorizeIdTag} on connector id ${connectorId}` + } different from the authorize request one ${ + connectorStatus.authorizeIdTag + } on connector id ${connectorId}` ) await this.resetConnectorOnStartTransactionError(chargingStation, connectorId) return } if ( connectorStatus?.idTagLocalAuthorized === true && - connectorStatus?.localAuthorizeIdTag !== requestPayload.idTag + connectorStatus.localAuthorizeIdTag !== requestPayload.idTag ) { logger.error( `${chargingStation.logPrefix()} Trying to start a transaction with an idTag ${ requestPayload.idTag - } different from the local authorized one ${connectorStatus?.localAuthorizeIdTag} on connector id ${connectorId}` + } different from the local authorized one ${ + connectorStatus.localAuthorizeIdTag + } on connector id ${connectorId}` ) await this.resetConnectorOnStartTransactionError(chargingStation, connectorId) return } if (connectorStatus?.transactionStarted === true) { logger.error( - `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${connectorId} by idTag ${connectorStatus?.transactionIdTag}` + `${chargingStation.logPrefix()} Trying to start a transaction on an already used connector id ${connectorId} by idTag ${ + connectorStatus.transactionIdTag + }` ) return } @@ -560,9 +570,11 @@ export class OCPP16ResponseService extends OCPPResponseService { for (const [evseId, evseStatus] of chargingStation.evses) { if (evseStatus.connectors.size > 1) { for (const [id, status] of evseStatus.connectors) { - if (id !== connectorId && status?.transactionStarted === true) { + if (id !== connectorId && status.transactionStarted === true) { logger.error( - `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId} by connector id ${id} with idTag ${status?.transactionIdTag}` + `${chargingStation.logPrefix()} Trying to start a transaction on an already used evse id ${evseId} by connector id ${id} with idTag ${ + status.transactionIdTag + }` ) await this.resetConnectorOnStartTransactionError(chargingStation, connectorId) return @@ -589,7 +601,7 @@ export class OCPP16ResponseService extends OCPPResponseService { payload.transactionId = convertToInt(payload.transactionId) } - if (payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED) { + if (payload.idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED) { connectorStatus.transactionStarted = true connectorStatus.transactionStart = requestPayload.timestamp connectorStatus.transactionId = payload.transactionId @@ -645,12 +657,15 @@ export class OCPP16ResponseService extends OCPPResponseService { OCPP16ChargePointStatus.Charging ) logger.info( - `${chargingStation.logPrefix()} Transaction with id ${payload.transactionId} STARTED on ${ - chargingStation.stationInfo.chargingStationId - }#${connectorId} for idTag '${requestPayload.idTag}'` + `${chargingStation.logPrefix()} Transaction with id ${ + payload.transactionId + } STARTED on ${chargingStation.stationInfo?.chargingStationId}#${connectorId} for idTag '${ + requestPayload.idTag + }'` ) - if (chargingStation.stationInfo.powerSharedByConnectors === true) { - ++chargingStation.powerDivider + if (chargingStation.stationInfo?.powerSharedByConnectors === true) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + ++chargingStation.powerDivider! } const configuredMeterValueSampleInterval = getConfigurationKey( chargingStation, @@ -666,9 +681,8 @@ export class OCPP16ResponseService extends OCPPResponseService { logger.warn( `${chargingStation.logPrefix()} Starting transaction with id ${ payload.transactionId - } REJECTED on ${ - chargingStation.stationInfo.chargingStationId - }#${connectorId} with status '${payload.idTagInfo?.status}', idTag '${ + } REJECTED on ${chargingStation.stationInfo + ?.chargingStationId}#${connectorId} with status '${payload.idTagInfo.status}', idTag '${ requestPayload.idTag }'${ OCPP16ServiceUtils.hasReservation(chargingStation, connectorId, requestPayload.idTag) @@ -714,8 +728,8 @@ export class OCPP16ResponseService extends OCPPResponseService { return } chargingStation.stationInfo?.beginEndMeterValues === true && - chargingStation.stationInfo?.ocppStrictCompliance === false && - chargingStation.stationInfo?.outOfOrderEndMeterValues === true && + chargingStation.stationInfo.ocppStrictCompliance === false && + chargingStation.stationInfo.outOfOrderEndMeterValues === true && (await chargingStation.ocppRequestService.requestHandler< OCPP16MeterValuesRequest, OCPP16MeterValuesResponse @@ -746,20 +760,20 @@ export class OCPP16ResponseService extends OCPPResponseService { OCPP16ChargePointStatus.Available ) } - if (chargingStation.stationInfo.powerSharedByConnectors === true) { - chargingStation.powerDivider-- + if (chargingStation.stationInfo?.powerSharedByConnectors === true) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + chargingStation.powerDivider!-- } // eslint-disable-next-line @typescript-eslint/no-non-null-assertion resetConnectorStatus(chargingStation.getConnectorStatus(transactionConnectorId)!) chargingStation.stopMeterValues(transactionConnectorId) const logMsg = `${chargingStation.logPrefix()} Transaction with id ${ requestPayload.transactionId - } STOPPED on ${ - chargingStation.stationInfo.chargingStationId - }#${transactionConnectorId} with status '${payload.idTagInfo?.status}'` + } STOPPED on ${chargingStation.stationInfo + ?.chargingStationId}#${transactionConnectorId} with status '${payload.idTagInfo?.status}'` if ( payload.idTagInfo == null || - payload.idTagInfo?.status === OCPP16AuthorizationStatus.ACCEPTED + payload.idTagInfo.status === OCPP16AuthorizationStatus.ACCEPTED ) { logger.info(logMsg) } else { diff --git a/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts b/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts index bbdf2e51..db964227 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts @@ -61,7 +61,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { public static buildTransactionBeginMeterValue ( chargingStation: ChargingStation, connectorId: number, - meterStart: number + meterStart: number | undefined ): OCPP16MeterValue { const meterValue: OCPP16MeterValue = { timestamp: new Date(), @@ -126,7 +126,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { OCPP16Constants.OCPP_AVAILABILITY_RESPONSE_ACCEPTED // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const connectorStatus = chargingStation.getConnectorStatus(connectorId)! - if (connectorStatus?.transactionStarted === true) { + if (connectorStatus.transactionStarted === true) { response = OCPP16Constants.OCPP_AVAILABILITY_RESPONSE_SCHEDULED } connectorStatus.availability = availabilityType @@ -166,19 +166,19 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { } let cpReplaced = false if (isNotEmptyArray(chargingStation.getConnectorStatus(connectorId)?.chargingProfiles)) { - chargingStation + for (const [index, chargingProfile] of chargingStation .getConnectorStatus(connectorId) - ?.chargingProfiles?.forEach((chargingProfile: OCPP16ChargingProfile, index: number) => { - if ( - chargingProfile.chargingProfileId === cp.chargingProfileId || - (chargingProfile.stackLevel === cp.stackLevel && - chargingProfile.chargingProfilePurpose === cp.chargingProfilePurpose) - ) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - chargingStation.getConnectorStatus(connectorId)!.chargingProfiles![index] = cp - cpReplaced = true - } - }) + ?.chargingProfiles?.entries() ?? []) { + if ( + chargingProfile.chargingProfileId === cp.chargingProfileId || + (chargingProfile.stackLevel === cp.stackLevel && + chargingProfile.chargingProfilePurpose === cp.chargingProfilePurpose) + ) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + chargingStation.getConnectorStatus(connectorId)!.chargingProfiles![index] = cp + cpReplaced = true + } + } } !cpReplaced && chargingStation.getConnectorStatus(connectorId)?.chargingProfiles?.push(cp) } @@ -451,11 +451,11 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { OCPP16ChargePointStatus.Reserved && connectorReservation != null && !hasReservationExpired(connectorReservation) && - connectorReservation?.idTag === idTag) || + connectorReservation.idTag === idTag) || (chargingStation.getConnectorStatus(0)?.status === OCPP16ChargePointStatus.Reserved && chargingStationReservation != null && !hasReservationExpired(chargingStationReservation) && - chargingStationReservation?.idTag === idTag) + chargingStationReservation.idTag === idTag) ) { logger.debug( `${chargingStation.logPrefix()} Connector id ${connectorId} has a valid reservation for idTag ${idTag}: %j`, diff --git a/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts b/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts index e0b8fa54..db509ecd 100644 --- a/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts +++ b/src/charging-station/ocpp/2.0/OCPP20IncomingRequestService.ts @@ -26,8 +26,8 @@ export class OCPP20IncomingRequestService extends OCPPIncomingRequestService { > public constructor () { - // if (new.target?.name === moduleName) { - // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`) + // if (new.target.name === moduleName) { + // throw new TypeError(`Cannot construct ${new.target.name} instances directly`) // } super(OCPPVersion.VERSION_20) this.incomingRequestHandlers = new Map([ diff --git a/src/charging-station/ocpp/2.0/OCPP20RequestService.ts b/src/charging-station/ocpp/2.0/OCPP20RequestService.ts index a9a73028..b54e491a 100644 --- a/src/charging-station/ocpp/2.0/OCPP20RequestService.ts +++ b/src/charging-station/ocpp/2.0/OCPP20RequestService.ts @@ -27,8 +27,8 @@ export class OCPP20RequestService extends OCPPRequestService { protected jsonSchemas: Map> public constructor (ocppResponseService: OCPPResponseService) { - // if (new.target?.name === moduleName) { - // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`) + // if (new.target.name === moduleName) { + // throw new TypeError(`Cannot construct ${new.target.name} instances directly`) // } super(OCPPVersion.VERSION_20, ocppResponseService) this.jsonSchemas = new Map>([ diff --git a/src/charging-station/ocpp/2.0/OCPP20ResponseService.ts b/src/charging-station/ocpp/2.0/OCPP20ResponseService.ts index c8345676..704d3a15 100644 --- a/src/charging-station/ocpp/2.0/OCPP20ResponseService.ts +++ b/src/charging-station/ocpp/2.0/OCPP20ResponseService.ts @@ -34,8 +34,8 @@ export class OCPP20ResponseService extends OCPPResponseService { private readonly jsonSchemas: Map> public constructor () { - // if (new.target?.name === moduleName) { - // throw new TypeError(`Cannot construct ${new.target?.name} instances directly`) + // if (new.target.name === moduleName) { + // throw new TypeError(`Cannot construct ${new.target.name} instances directly`) // } super(OCPPVersion.VERSION_20) this.responseHandlers = new Map([ diff --git a/src/charging-station/ocpp/OCPPIncomingRequestService.ts b/src/charging-station/ocpp/OCPPIncomingRequestService.ts index 62e58661..ea3e7b73 100644 --- a/src/charging-station/ocpp/OCPPIncomingRequestService.ts +++ b/src/charging-station/ocpp/OCPPIncomingRequestService.ts @@ -73,14 +73,14 @@ export abstract class OCPPIncomingRequestService { `${chargingStation.logPrefix()} ${moduleName}.handleIncomingRequestError: Incoming request command '${commandName}' error:`, error ) - if (params?.throwError === false && params?.errorResponse != null) { - return params?.errorResponse + if (params.throwError === false && params.errorResponse != null) { + return params.errorResponse } - if (params?.throwError === true && params?.errorResponse == null) { + if (params.throwError === true && params.errorResponse == null) { throw error } - if (params?.throwError === true && params?.errorResponse != null) { - return params?.errorResponse + if (params.throwError === true && params.errorResponse != null) { + return params.errorResponse } } @@ -111,7 +111,7 @@ export abstract class OCPPIncomingRequestService { protected handleRequestClearCache (chargingStation: ChargingStation): ClearCacheResponse { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - if (chargingStation.idTagsCache.deleteIdTags(getIdTagsFile(chargingStation.stationInfo)!)) { + if (chargingStation.idTagsCache.deleteIdTags(getIdTagsFile(chargingStation.stationInfo!)!)) { return OCPPConstants.OCPP_RESPONSE_ACCEPTED } return OCPPConstants.OCPP_RESPONSE_REJECTED diff --git a/src/charging-station/ocpp/OCPPRequestService.ts b/src/charging-station/ocpp/OCPPRequestService.ts index e78f71c5..1d698bd8 100644 --- a/src/charging-station/ocpp/OCPPRequestService.ts +++ b/src/charging-station/ocpp/OCPPRequestService.ts @@ -454,7 +454,7 @@ export abstract class OCPPRequestService { // Resolve response resolve(messagePayload) } - } else if (error != null) { + } else { handleSendError( new OCPPError( ErrorType.GENERIC_ERROR, @@ -483,7 +483,7 @@ export abstract class OCPPRequestService { } throw new OCPPError( ErrorType.SECURITY_ERROR, - `Cannot send command ${commandName} PDU when the charging station is in ${chargingStation?.bootNotificationResponse?.status} state on the central server`, + `Cannot send command ${commandName} PDU when the charging station is in ${chargingStation.bootNotificationResponse?.status} state on the central server`, commandName ) } diff --git a/src/charging-station/ocpp/OCPPServiceUtils.ts b/src/charging-station/ocpp/OCPPServiceUtils.ts index bd228564..cb802d12 100644 --- a/src/charging-station/ocpp/OCPPServiceUtils.ts +++ b/src/charging-station/ocpp/OCPPServiceUtils.ts @@ -139,7 +139,7 @@ const isIdTagLocalAuthorized = (chargingStation: ChargingStation, idTag: string) isNotEmptyString( chargingStation.idTagsCache // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - .getIdTags(getIdTagsFile(chargingStation.stationInfo)!) + .getIdTags(getIdTagsFile(chargingStation.stationInfo!)!) ?.find((tag) => tag === idTag) ) ) @@ -161,7 +161,7 @@ const isIdTagRemoteAuthorized = async ( idTag } ) - )?.idTagInfo?.status === AuthorizationStatus.ACCEPTED + ).idTagInfo.status === AuthorizationStatus.ACCEPTED ) } @@ -237,8 +237,9 @@ const checkConnectorStatusTransition = ( } if (!transitionAllowed) { logger.warn( - `${chargingStation.logPrefix()} OCPP ${chargingStation.stationInfo - ?.ocppVersion} connector id ${connectorId} status transition from '${ + `${chargingStation.logPrefix()} OCPP ${ + chargingStation.stationInfo.ocppVersion + } connector id ${connectorId} status transition from '${ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion chargingStation.getConnectorStatus(connectorId)!.status }' to '${status}' is not allowed` @@ -323,7 +324,7 @@ export const buildMeterValue = ( if ( chargingStation.getNumberOfPhases() !== 3 || (chargingStation.getNumberOfPhases() === 3 && - chargingStation.stationInfo?.mainVoltageMeterValues === true) + chargingStation.stationInfo.mainVoltageMeterValues === true) ) { meterValue.sampledValue.push( buildSampledValue(voltageSampledValueTemplate, voltageMeasurandValue) @@ -365,7 +366,7 @@ export const buildMeterValue = ( phaseLineToNeutralValue as MeterValuePhase ) ) - if (chargingStation.stationInfo?.phaseLineToLineVoltageMeterValues === true) { + if (chargingStation.stationInfo.phaseLineToLineVoltageMeterValues === true) { const phaseLineToLineValue = `L${phase}-L${ (phase + 1) % chargingStation.getNumberOfPhases() !== 0 ? (phase + 1) % chargingStation.getNumberOfPhases() @@ -443,17 +444,17 @@ export const buildMeterValue = ( } if (powerSampledValueTemplate != null) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - checkMeasurandPowerDivider(chargingStation, powerSampledValueTemplate.measurand!) + checkMeasurandPowerDivider(chargingStation, powerSampledValueTemplate.measurand) const errMsg = `MeterValues measurand ${ powerSampledValueTemplate.measurand ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER - }: Unknown ${chargingStation.stationInfo?.currentOutType} currentOutType in template file ${ + }: Unknown ${chargingStation.stationInfo.currentOutType} currentOutType in template file ${ chargingStation.templateFile }, cannot calculate ${ powerSampledValueTemplate.measurand ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER } measurand value` // eslint-disable-next-line @typescript-eslint/consistent-type-assertions const powerMeasurandValues: MeasurandValues = {} as MeasurandValues - const unitDivider = powerSampledValueTemplate?.unit === MeterValueUnit.KILO_WATT ? 1000 : 1 + const unitDivider = powerSampledValueTemplate.unit === MeterValueUnit.KILO_WATT ? 1000 : 1 const connectorMaximumAvailablePower = chargingStation.getConnectorMaximumAvailablePower(connectorId) const connectorMaximumPower = Math.round(connectorMaximumAvailablePower) @@ -464,7 +465,7 @@ export const buildMeterValue = ( const connectorMinimumPowerPerPhase = Math.round( connectorMinimumPower / chargingStation.getNumberOfPhases() ) - switch (chargingStation.stationInfo?.currentOutType) { + switch (chargingStation.stationInfo.currentOutType) { case CurrentType.AC: if (chargingStation.getNumberOfPhases() === 3) { const defaultFluctuatedPowerPerPhase = isNotEmptyString( @@ -477,7 +478,7 @@ export const buildMeterValue = ( connectorMinimumPower / unitDivider, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumPower / unitDivider } ) / chargingStation.getNumberOfPhases(), @@ -495,7 +496,7 @@ export const buildMeterValue = ( connectorMinimumPowerPerPhase / unitDivider, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumPowerPerPhase / unitDivider } ), @@ -513,7 +514,7 @@ export const buildMeterValue = ( connectorMinimumPowerPerPhase / unitDivider, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumPowerPerPhase / unitDivider } ), @@ -531,7 +532,7 @@ export const buildMeterValue = ( connectorMinimumPowerPerPhase / unitDivider, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumPowerPerPhase / unitDivider } ), @@ -569,7 +570,7 @@ export const buildMeterValue = ( connectorMinimumPower / unitDivider, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumPower / unitDivider } ), @@ -597,7 +598,7 @@ export const buildMeterValue = ( connectorMinimumPower / unitDivider, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumPower / unitDivider } ), @@ -710,10 +711,10 @@ export const buildMeterValue = ( } if (currentSampledValueTemplate != null) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - checkMeasurandPowerDivider(chargingStation, currentSampledValueTemplate.measurand!) + checkMeasurandPowerDivider(chargingStation, currentSampledValueTemplate.measurand) const errMsg = `MeterValues measurand ${ currentSampledValueTemplate.measurand ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER - }: Unknown ${chargingStation.stationInfo?.currentOutType} currentOutType in template file ${ + }: Unknown ${chargingStation.stationInfo.currentOutType} currentOutType in template file ${ chargingStation.templateFile }, cannot calculate ${ currentSampledValueTemplate.measurand ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER @@ -724,7 +725,7 @@ export const buildMeterValue = ( chargingStation.getConnectorMaximumAvailablePower(connectorId) const connectorMinimumAmperage = currentSampledValueTemplate.minimumValue ?? 0 let connectorMaximumAmperage: number - switch (chargingStation.stationInfo?.currentOutType) { + switch (chargingStation.stationInfo.currentOutType) { case CurrentType.AC: connectorMaximumAmperage = ACElectricUtils.amperagePerPhaseFromPower( chargingStation.getNumberOfPhases(), @@ -743,7 +744,7 @@ export const buildMeterValue = ( connectorMinimumAmperage, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumAmperage } ), @@ -761,7 +762,7 @@ export const buildMeterValue = ( connectorMinimumAmperage, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumAmperage } ), @@ -779,7 +780,7 @@ export const buildMeterValue = ( connectorMinimumAmperage, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumAmperage } ), @@ -797,7 +798,7 @@ export const buildMeterValue = ( connectorMinimumAmperage, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumAmperage } ), @@ -826,7 +827,7 @@ export const buildMeterValue = ( connectorMinimumAmperage, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumAmperage } ), @@ -857,7 +858,7 @@ export const buildMeterValue = ( connectorMinimumAmperage, { limitationEnabled: - chargingStation.stationInfo?.customValueLimitationMeterValues, + chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumAmperage } ), @@ -931,9 +932,9 @@ export const buildMeterValue = ( energySampledValueTemplate = getSampledValueTemplate(chargingStation, connectorId) if (energySampledValueTemplate != null) { // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - checkMeasurandPowerDivider(chargingStation, energySampledValueTemplate.measurand!) + checkMeasurandPowerDivider(chargingStation, energySampledValueTemplate.measurand) const unitDivider = - energySampledValueTemplate?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1 + energySampledValueTemplate.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1 const connectorMaximumAvailablePower = chargingStation.getConnectorMaximumAvailablePower(connectorId) const connectorMaximumEnergyRounded = roundTo( @@ -951,7 +952,7 @@ export const buildMeterValue = ( connectorMaximumEnergyRounded, connectorMinimumEnergyRounded, { - limitationEnabled: chargingStation.stationInfo?.customValueLimitationMeterValues, + limitationEnabled: chargingStation.stationInfo.customValueLimitationMeterValues, fallbackValue: connectorMinimumEnergyRounded, unitMultiplier: unitDivider } @@ -1011,7 +1012,7 @@ export const buildMeterValue = ( export const buildTransactionEndMeterValue = ( chargingStation: ChargingStation, connectorId: number, - meterStop: number + meterStop: number | undefined ): MeterValue => { let meterValue: MeterValue let sampledValueTemplate: SampledValueTemplate | undefined @@ -1045,7 +1046,7 @@ export const buildTransactionEndMeterValue = ( const checkMeasurandPowerDivider = ( chargingStation: ChargingStation, - measurandType: MeterValueMeasurand + measurandType: MeterValueMeasurand | undefined ): void => { if (chargingStation.powerDivider == null) { const errMsg = `MeterValues measurand ${ @@ -1053,7 +1054,7 @@ const checkMeasurandPowerDivider = ( }: powerDivider is undefined` logger.error(`${chargingStation.logPrefix()} ${errMsg}`) throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, RequestCommand.METER_VALUES) - } else if (chargingStation?.powerDivider <= 0) { + } else if (chargingStation.powerDivider <= 0) { const errMsg = `MeterValues measurand ${ measurandType ?? MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER }: powerDivider have zero or below value ${chargingStation.powerDivider}` @@ -1077,7 +1078,7 @@ const getLimitFromSampledValueTemplateCustomValue = ( ...options } const parsedValue = parseInt(value ?? '') - if (options?.limitationEnabled === true) { + if (options.limitationEnabled === true) { return max( // eslint-disable-next-line @typescript-eslint/no-non-null-assertion min((!isNaN(parsedValue) ? parsedValue : Infinity) * options.unitMultiplier!, maxLimit), @@ -1175,12 +1176,11 @@ const buildSampledValue = ( context?: MeterValueContext, phase?: MeterValuePhase ): SampledValue => { - const sampledValueContext = context ?? sampledValueTemplate?.context + const sampledValueContext = context ?? sampledValueTemplate.context const sampledValueLocation = // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - sampledValueTemplate?.location ?? getMeasurandDefaultLocation(sampledValueTemplate.measurand!) - const sampledValuePhase = phase ?? sampledValueTemplate?.phase - // eslint-disable-next-line @typescript-eslint/consistent-type-assertions + sampledValueTemplate.location ?? getMeasurandDefaultLocation(sampledValueTemplate.measurand!) + const sampledValuePhase = phase ?? sampledValueTemplate.phase return { ...(sampledValueTemplate.unit != null && { unit: sampledValueTemplate.unit @@ -1190,9 +1190,9 @@ const buildSampledValue = ( measurand: sampledValueTemplate.measurand }), ...(sampledValueLocation != null && { location: sampledValueLocation }), - ...(value != null && { value: value.toString() }), + ...{ value: value.toString() }, ...(sampledValuePhase != null && { phase: sampledValuePhase }) - } as SampledValue + } satisfies SampledValue } const getMeasurandDefaultLocation = ( @@ -1271,7 +1271,7 @@ export class OCPPServiceUtils { isRequestCommand && chargingStation.stationInfo?.commandsSupport?.outgoingCommands?.[command] != null ) { - return chargingStation.stationInfo?.commandsSupport?.outgoingCommands[command] + return chargingStation.stationInfo.commandsSupport.outgoingCommands[command] } logger.error(`${chargingStation.logPrefix()} Unknown outgoing OCPP command '${command}'`) return false @@ -1290,9 +1290,9 @@ export class OCPPServiceUtils { return true } else if ( isIncomingRequestCommand && - chargingStation.stationInfo?.commandsSupport?.incomingCommands?.[command] != null + chargingStation.stationInfo?.commandsSupport?.incomingCommands[command] != null ) { - return chargingStation.stationInfo?.commandsSupport?.incomingCommands[command] + return chargingStation.stationInfo.commandsSupport.incomingCommands[command] } logger.error(`${chargingStation.logPrefix()} Unknown incoming OCPP command '${command}'`) return false @@ -1309,7 +1309,7 @@ export class OCPPServiceUtils { isMessageTrigger && chargingStation.stationInfo?.messageTriggerSupport?.[messageTrigger] != null ) { - return chargingStation.stationInfo?.messageTriggerSupport[messageTrigger] + return chargingStation.stationInfo.messageTriggerSupport[messageTrigger] } logger.error( `${chargingStation.logPrefix()} Unknown incoming OCPP message trigger '${messageTrigger}'` @@ -1337,8 +1337,8 @@ export class OCPPServiceUtils { if (isDate(obj![key])) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion (obj![key] as string) = (obj![key] as Date).toISOString() - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion - } else if (obj![key] !== null && typeof obj![key] === 'object') { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unnecessary-condition + } else if (typeof obj![key] === 'object' && obj![key] !== null) { // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion, @typescript-eslint/no-non-null-assertion OCPPServiceUtils.convertDateToISOString(obj![key] as T) } diff --git a/src/charging-station/ui-server/AbstractUIServer.ts b/src/charging-station/ui-server/AbstractUIServer.ts index 78f04683..cd616738 100644 --- a/src/charging-station/ui-server/AbstractUIServer.ts +++ b/src/charging-station/ui-server/AbstractUIServer.ts @@ -103,7 +103,8 @@ export abstract class AbstractUIServer { private isBasicAuthEnabled (): boolean { return ( this.uiServerConfiguration.authentication?.enabled === true && - this.uiServerConfiguration.authentication?.type === AuthenticationType.BASIC_AUTH + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + this.uiServerConfiguration.authentication.type === AuthenticationType.BASIC_AUTH ) } diff --git a/src/charging-station/ui-server/UIHttpServer.ts b/src/charging-station/ui-server/UIHttpServer.ts index 0b6eee9f..27b9e845 100644 --- a/src/charging-station/ui-server/UIHttpServer.ts +++ b/src/charging-station/ui-server/UIHttpServer.ts @@ -122,13 +122,7 @@ export class UIHttpServer extends AbstractUIServer { const body = JSON.parse(Buffer.concat(bodyBuffer).toString()) as RequestPayload this.uiServices .get(version) - ?.requestHandler( - this.buildProtocolRequest( - uuid, - procedureName, - body ?? Constants.EMPTY_FROZEN_OBJECT - ) - ) + ?.requestHandler(this.buildProtocolRequest(uuid, procedureName, body)) .then((protocolResponse?: ProtocolResponse) => { if (protocolResponse != null) { this.sendResponse(protocolResponse) diff --git a/src/charging-station/ui-server/UIWebSocketServer.ts b/src/charging-station/ui-server/UIWebSocketServer.ts index 097533e0..6d6dc6df 100644 --- a/src/charging-station/ui-server/UIWebSocketServer.ts +++ b/src/charging-station/ui-server/UIWebSocketServer.ts @@ -80,7 +80,7 @@ export class UIWebSocketServer extends AbstractUIServer { }) }) this.httpServer.on('connect', (req: IncomingMessage, socket: Duplex, _head: Buffer) => { - if (req.headers?.connection !== 'Upgrade' || req.headers?.upgrade !== 'websocket') { + if (req.headers.connection !== 'Upgrade' || req.headers.upgrade !== 'websocket') { socket.write(`HTTP/1.1 ${StatusCodes.BAD_REQUEST} Bad Request\r\n\r\n`) socket.destroy() } @@ -115,18 +115,20 @@ export class UIWebSocketServer extends AbstractUIServer { } public sendResponse (response: ProtocolResponse): void { - const responseId = response?.[0] + const responseId = response[0] try { if (this.hasResponseHandler(responseId)) { const ws = this.responseHandlers.get(responseId) as WebSocket - if (ws?.readyState === WebSocket.OPEN) { + if (ws.readyState === WebSocket.OPEN) { ws.send(JSON.stringify(response)) } else { logger.error( `${this.logPrefix( moduleName, 'sendResponse' - )} Error at sending response id '${responseId}', WebSocket is not open: ${ws?.readyState}` + )} Error at sending response id '${responseId}', WebSocket is not open: ${ + ws.readyState + }` ) } } else { @@ -162,7 +164,7 @@ export class UIWebSocketServer extends AbstractUIServer { private broadcastToClients (message: string): void { for (const client of this.webSocketServer.clients) { - if (client?.readyState === WebSocket.OPEN) { + if (client.readyState === WebSocket.OPEN) { client.send(message) } } @@ -191,6 +193,7 @@ export class UIWebSocketServer extends AbstractUIServer { return false } + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (request.length !== 3) { logger.error( `${this.logPrefix(moduleName, 'validateRawDataRequest')} UI protocol request is malformed:`, @@ -199,7 +202,7 @@ export class UIWebSocketServer extends AbstractUIServer { return false } - if (!validateUUID(request?.[0])) { + if (!validateUUID(request[0])) { logger.error( `${this.logPrefix( moduleName, diff --git a/src/charging-station/ui-server/ui-services/AbstractUIService.ts b/src/charging-station/ui-server/ui-services/AbstractUIService.ts index 84740101..a4edbcaa 100644 --- a/src/charging-station/ui-server/ui-services/AbstractUIService.ts +++ b/src/charging-station/ui-server/ui-services/AbstractUIService.ts @@ -164,7 +164,7 @@ export abstract class AbstractUIService { if (isNotEmptyArray(payload.hashIds)) { payload.hashIds = payload.hashIds ?.map((hashId) => { - if (hashId != null && this.uiServer.chargingStations.has(hashId)) { + if (this.uiServer.chargingStations.has(hashId)) { return hashId } logger.warn( diff --git a/src/performance/PerformanceStatistics.ts b/src/performance/PerformanceStatistics.ts index f61d0958..88ea748c 100644 --- a/src/performance/PerformanceStatistics.ts +++ b/src/performance/PerformanceStatistics.ts @@ -41,19 +41,19 @@ export class PerformanceStatistics { PerformanceStatistics >() - private readonly objId: string - private readonly objName: string + private readonly objId: string | undefined + private readonly objName: string | undefined private performanceObserver!: PerformanceObserver private readonly statistics: Statistics private displayInterval?: NodeJS.Timeout - private constructor (objId: string, objName: string, uri: URL) { - this.objId = objId - this.objName = objName + private constructor (objId: string | undefined, objName: string | undefined, uri: URL) { + this.objId = objId ?? 'Object id not specified' + this.objName = objName ?? 'Object name not specified' this.initializePerformanceObserver() this.statistics = { - id: this.objId ?? 'Object id not specified', - name: this.objName ?? 'Object name not specified', + id: this.objId, + name: this.objName, uri: uri.toString(), createdAt: new Date(), statisticsData: new Map() @@ -164,7 +164,7 @@ export class PerformanceStatistics { this.stopLogStatisticsInterval() performance.clearMarks() performance.clearMeasures() - this.performanceObserver?.disconnect() + this.performanceObserver.disconnect() } public restart (): void { @@ -185,7 +185,7 @@ export class PerformanceStatistics { } private logStatistics (): void { - logger.info(`${this.logPrefix()}`, { + logger.info(this.logPrefix(), { ...this.statistics, statisticsData: JSONStringifyWithMapSupport(this.statistics.statisticsData) }) diff --git a/src/performance/storage/JsonFileStorage.ts b/src/performance/storage/JsonFileStorage.ts index 3fe5e58e..f44d9f2b 100644 --- a/src/performance/storage/JsonFileStorage.ts +++ b/src/performance/storage/JsonFileStorage.ts @@ -47,7 +47,7 @@ export class JsonFileStorage extends Storage { public open (): void { JsonFileStorage.performanceRecords = new Map() try { - if (this?.fd == null) { + if (this.fd == null) { if (!existsSync(dirname(this.dbName))) { mkdirSync(dirname(this.dbName), { recursive: true }) } @@ -66,9 +66,9 @@ export class JsonFileStorage extends Storage { public close (): void { JsonFileStorage.performanceRecords.clear() try { - if (this?.fd != null) { + if (this.fd != null) { closeSync(this.fd) - delete this?.fd + delete this.fd } } catch (error) { handleFileException( @@ -81,7 +81,7 @@ export class JsonFileStorage extends Storage { } private checkPerformanceRecordsFile (): void { - if (this?.fd == null) { + if (this.fd == null) { throw new BaseError( `${this.logPrefix} Performance records '${this.dbName}' file descriptor not found` ) diff --git a/src/performance/storage/MikroOrmStorage.ts b/src/performance/storage/MikroOrmStorage.ts index 4e2091a5..3eec553d 100644 --- a/src/performance/storage/MikroOrmStorage.ts +++ b/src/performance/storage/MikroOrmStorage.ts @@ -1,12 +1,6 @@ // Copyright Jerome Benoit. 2021-2023. All Rights Reserved. -import { - type Configuration, - type Connection, - type IDatabaseDriver, - MikroORM, - type Options -} from '@mikro-orm/core' +import { type Configuration, MikroORM, type Options } from '@mikro-orm/core' import { TsMorphMetadataProvider } from '@mikro-orm/reflection' import { Storage } from './Storage.js' @@ -40,7 +34,7 @@ export class MikroOrmStorage extends Storage { public async open (): Promise { try { - if (this?.orm == null) { + if (this.orm == null) { this.orm = await MikroORM.init(this.getOptions(), true) } } catch (error) { @@ -50,9 +44,9 @@ export class MikroOrmStorage extends Storage { public async close (): Promise { try { - if (this?.orm != null) { + if (this.orm != null) { await this.orm.close() - delete this?.orm + delete this.orm } } catch (error) { this.handleDBError(this.storageType, error as Error) @@ -63,15 +57,10 @@ export class MikroOrmStorage extends Storage { if (this.storageType === StorageType.SQLITE) { return `${Constants.DEFAULT_PERFORMANCE_RECORDS_DB_NAME}.db` } - return ( - this.storageUri.pathname.replace(/(?:^\/)|(?:\/$)/g, '') ?? - Constants.DEFAULT_PERFORMANCE_RECORDS_DB_NAME - ) + return this.storageUri.pathname.replace(/(?:^\/)|(?:\/$)/g, '') } - private getOptions (): - | Configuration> - | Options> { + private getOptions (): Configuration | Options { return { metadataProvider: TsMorphMetadataProvider, entities: [PerformanceRecord, PerformanceData], diff --git a/src/performance/storage/MongoDBStorage.ts b/src/performance/storage/MongoDBStorage.ts index 70256fc9..009d8161 100644 --- a/src/performance/storage/MongoDBStorage.ts +++ b/src/performance/storage/MongoDBStorage.ts @@ -15,9 +15,7 @@ export class MongoDBStorage extends Storage { super(storageUri, logPrefix) this.client = new MongoClient(this.storageUri.toString()) this.connected = false - this.dbName = - this.storageUri.pathname.replace(/(?:^\/)|(?:\/$)/g, '') ?? - Constants.DEFAULT_PERFORMANCE_RECORDS_DB_NAME + this.dbName = this.storageUri.pathname.replace(/(?:^\/)|(?:\/$)/g, '') } public async storePerformanceStatistics (performanceStatistics: Statistics): Promise { @@ -34,7 +32,7 @@ export class MongoDBStorage extends Storage { public async open (): Promise { try { - if (!this.connected && this?.client != null) { + if (!this.connected && this.client != null) { await this.client.connect() this.connected = true } @@ -45,7 +43,7 @@ export class MongoDBStorage extends Storage { public async close (): Promise { try { - if (this.connected && this?.client != null) { + if (this.connected && this.client != null) { await this.client.close() this.connected = false } @@ -55,7 +53,7 @@ export class MongoDBStorage extends Storage { } private checkDBConnection (): void { - if (this?.client == null) { + if (this.client == null) { throw new BaseError( `${this.logPrefix} ${this.getDBNameFromStorageType( StorageType.MONGO_DB diff --git a/src/performance/storage/Storage.ts b/src/performance/storage/Storage.ts index 8ee2a701..47246815 100644 --- a/src/performance/storage/Storage.ts +++ b/src/performance/storage/Storage.ts @@ -35,7 +35,7 @@ export abstract class Storage { }'${inTableOrCollectionStr}:`, error ) - if (params?.throwError === true) { + if (params.throwError === true) { throw error } } diff --git a/src/types/WorkerBroadcastChannel.ts b/src/types/WorkerBroadcastChannel.ts index ac4ea8e6..9ea1a0e6 100644 --- a/src/types/WorkerBroadcastChannel.ts +++ b/src/types/WorkerBroadcastChannel.ts @@ -34,7 +34,7 @@ export interface BroadcastChannelRequestPayload extends RequestPayload { export interface BroadcastChannelResponsePayload extends Omit { - hashId: string + hashId: string | undefined } export interface MessageEvent { diff --git a/src/utils/Configuration.ts b/src/utils/Configuration.ts index 8b0b1c8f..596b685c 100644 --- a/src/utils/Configuration.ts +++ b/src/utils/Configuration.ts @@ -45,7 +45,7 @@ type ConfigurationSectionType = // eslint-disable-next-line @typescript-eslint/no-extraneous-class export class Configuration { - public static configurationChangeCallback: () => Promise + public static configurationChangeCallback?: () => Promise private static readonly configurationFile = join( dirname(fileURLToPath(import.meta.url)), @@ -327,7 +327,8 @@ export class Configuration { ] as StationTemplateUrl[]) Configuration.getConfigurationData()?.stationTemplateUrls.forEach( (stationTemplateUrl: StationTemplateUrl) => { - if (stationTemplateUrl?.['numberOfStation' as keyof StationTemplateUrl] !== undefined) { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + if (stationTemplateUrl['numberOfStation' as keyof StationTemplateUrl] !== undefined) { console.error( `${chalk.green(logPrefix())} ${chalk.red( `Deprecated configuration key 'numberOfStation' usage for template file '${stationTemplateUrl.file}' in 'stationTemplateUrls'. Use 'numberOfStations' instead` @@ -495,7 +496,7 @@ export class Configuration { string, unknown > - )?.[key] !== undefined + )[key] !== undefined ) { console.error( `${chalk.green(logPrefix())} ${chalk.red( diff --git a/src/utils/ErrorUtils.ts b/src/utils/ErrorUtils.ts index 1fd0482b..41a61acc 100644 --- a/src/utils/ErrorUtils.ts +++ b/src/utils/ErrorUtils.ts @@ -57,21 +57,21 @@ export const handleFileException = ( default: logMsg = `${fileType} file ${file} error:` } - if (params?.consoleOut === true) { + if (params.consoleOut === true) { logMsg = `${logMsg} ` - if (params?.throwError === true) { + if (params.throwError === true) { console.error(`${chalk.green(prefix)}${chalk.red(logMsg)}`, error) } else { console.warn(`${chalk.green(prefix)}${chalk.yellow(logMsg)}`, error) } - } else if (params?.consoleOut === false) { - if (params?.throwError === true) { + } else if (params.consoleOut === false) { + if (params.throwError === true) { logger.error(`${prefix}${logMsg}`, error) } else { logger.warn(`${prefix}${logMsg}`, error) } } - if (params?.throwError === true) { + if (params.throwError === true) { throw error } } @@ -84,7 +84,7 @@ export const handleSendMessageError = ( ): void => { setDefaultErrorParams(params, { throwError: false, consoleOut: false }) logger.error(`${chargingStation.logPrefix()} Request command '${commandName}' error:`, error) - if (params?.throwError === true) { + if (params.throwError === true) { throw error } } diff --git a/src/utils/MessageChannelUtils.ts b/src/utils/MessageChannelUtils.ts index 842b8bfe..a61bf94a 100644 --- a/src/utils/MessageChannelUtils.ts +++ b/src/utils/MessageChannelUtils.ts @@ -51,12 +51,13 @@ export const buildPerformanceStatisticsMessage = ( const buildChargingStationDataPayload = (chargingStation: ChargingStation): ChargingStationData => { return { started: chargingStation.started, - stationInfo: chargingStation.stationInfo, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + stationInfo: chargingStation.stationInfo!, connectors: buildConnectorsStatus(chargingStation), evses: buildEvsesStatus(chargingStation, OutputFormat.worker), // eslint-disable-next-line @typescript-eslint/no-non-null-assertion ocppConfiguration: chargingStation.ocppConfiguration!, - wsState: chargingStation?.wsConnection?.readyState, + wsState: chargingStation.wsConnection?.readyState, bootNotificationResponse: chargingStation.bootNotificationResponse, ...(chargingStation.automaticTransactionGenerator != null && { automaticTransactionGenerator: diff --git a/src/utils/StatisticUtils.ts b/src/utils/StatisticUtils.ts index cef15f52..deb1624b 100644 --- a/src/utils/StatisticUtils.ts +++ b/src/utils/StatisticUtils.ts @@ -54,6 +54,7 @@ export const nthPercentile = (dataSet: number[], percentile: number): number => } const percentileIndexBase = (percentile / 100) * (sortedDataSet.length - 1) const percentileIndexInteger = Math.floor(percentileIndexBase) + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (sortedDataSet[percentileIndexInteger + 1] != null) { return ( sortedDataSet[percentileIndexInteger] + diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index 87ea9a2c..b8083596 100644 --- a/src/utils/Utils.ts +++ b/src/utils/Utils.ts @@ -154,7 +154,7 @@ export const getRandomFloat = (max = Number.MAX_VALUE, min = 0): number => { export const getRandomInteger = (max = Constants.MAX_RANDOM_INTEGER, min = 0): number => { max = Math.floor(max) - if (min != null && min !== 0) { + if (min !== 0) { min = Math.ceil(min) return Math.floor(randomInt(min, max + 1)) } @@ -175,7 +175,7 @@ export const roundTo = (numberValue: number, scale: number): number => { } export const getRandomFloatRounded = (max = Number.MAX_VALUE, min = 0, scale = 2): number => { - if (min != null && min !== 0) { + if (min !== 0) { return roundTo(getRandomFloat(max, min), scale) } return roundTo(getRandomFloat(max), scale) @@ -294,7 +294,7 @@ export const isNotEmptyArray = (object: unknown): boolean => { } export const isEmptyObject = (obj: object): boolean => { - if (obj?.constructor !== Object) { + if (obj.constructor !== Object) { return false } // Iterates over the keys of an object, if @@ -371,8 +371,8 @@ export const getWebSocketCloseEventStatusString = (code: number): string => { } } if ( - WebSocketCloseEventStatusString[code as keyof typeof WebSocketCloseEventStatusString] !== - undefined + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + WebSocketCloseEventStatusString[code as keyof typeof WebSocketCloseEventStatusString] != null ) { return WebSocketCloseEventStatusString[code as keyof typeof WebSocketCloseEventStatusString] } @@ -395,6 +395,7 @@ export const once = ( ): ((...args: A) => R) => { let result: R return (...args: A) => { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (fn != null) { result = fn.apply(context, args) ;(fn as unknown as undefined) = (context as unknown as undefined) = undefined diff --git a/src/worker/WorkerAbstract.ts b/src/worker/WorkerAbstract.ts index 38d76276..9a10e6f2 100644 --- a/src/worker/WorkerAbstract.ts +++ b/src/worker/WorkerAbstract.ts @@ -19,7 +19,7 @@ export abstract class WorkerAbstract { * @param workerScript - * @param workerOptions - */ - constructor (workerScript: string, workerOptions: WorkerOptions) { + constructor (workerScript: string | undefined, workerOptions: WorkerOptions) { if (workerScript == null) { throw new TypeError('Worker script is not defined') } diff --git a/src/worker/WorkerDynamicPool.ts b/src/worker/WorkerDynamicPool.ts index 6574dcc2..817536f0 100644 --- a/src/worker/WorkerDynamicPool.ts +++ b/src/worker/WorkerDynamicPool.ts @@ -38,7 +38,7 @@ export class WorkerDynamicPool extends WorkerAbstract { } get emitter (): EventEmitterAsyncResource | undefined { - return this.pool?.emitter + return this.pool.emitter } /** @inheritDoc */ diff --git a/src/worker/WorkerFixedPool.ts b/src/worker/WorkerFixedPool.ts index a2a0e759..83669041 100644 --- a/src/worker/WorkerFixedPool.ts +++ b/src/worker/WorkerFixedPool.ts @@ -37,7 +37,7 @@ export class WorkerFixedPool extends WorkerAbstract { } get emitter (): EventEmitterAsyncResource | undefined { - return this.pool?.emitter + return this.pool.emitter } /** @inheritDoc */ diff --git a/src/worker/WorkerSet.ts b/src/worker/WorkerSet.ts index b8e0e31f..ea5d654c 100644 --- a/src/worker/WorkerSet.ts +++ b/src/worker/WorkerSet.ts @@ -105,9 +105,6 @@ export class WorkerSet extends WorkerAbstract { if (!this.started) { throw new Error('Cannot add a WorkerSet element: not started') } - if (this.workerSet == null) { - throw new Error("Cannot add a WorkerSet element: 'workerSet' property does not exist") - } const workerSetElement = await this.getWorkerSetElement() workerSetElement.worker.postMessage({ event: WorkerMessageEvents.startWorkerElement, -- 2.34.1