X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FChargingStation.ts;h=29119f92cf35d85f449fdf7d360f20b66af63e50;hb=17bc43d765c22c8d8c132484f8dc9c3edd370d91;hp=c9806f21e6b614574b457daeb3f24f02df359ea8;hpb=130783a74f495abcb198b7f01abe19dab4f7fb47;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index c9806f21..29119f92 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -9,91 +9,87 @@ import { parentPort } from 'worker_threads'; import merge from 'just-merge'; import WebSocket, { type RawData } from 'ws'; -import AuthorizedTagsCache from './AuthorizedTagsCache'; -import AutomaticTransactionGenerator from './AutomaticTransactionGenerator'; +import { AuthorizedTagsCache } from './AuthorizedTagsCache'; +import { AutomaticTransactionGenerator } from './AutomaticTransactionGenerator'; import { ChargingStationConfigurationUtils } from './ChargingStationConfigurationUtils'; import { ChargingStationUtils } from './ChargingStationUtils'; -import ChargingStationWorkerBroadcastChannel from './ChargingStationWorkerBroadcastChannel'; +import { ChargingStationWorkerBroadcastChannel } from './ChargingStationWorkerBroadcastChannel'; import { MessageChannelUtils } from './MessageChannelUtils'; -import OCPP16IncomingRequestService from './ocpp/1.6/OCPP16IncomingRequestService'; -import OCPP16RequestService from './ocpp/1.6/OCPP16RequestService'; -import OCPP16ResponseService from './ocpp/1.6/OCPP16ResponseService'; -import { OCPP16ServiceUtils } from './ocpp/1.6/OCPP16ServiceUtils'; -import OCPP20IncomingRequestService from './ocpp/2.0/OCPP20IncomingRequestService'; -import OCPP20RequestService from './ocpp/2.0/OCPP20RequestService'; -import OCPP20ResponseService from './ocpp/2.0/OCPP20ResponseService'; -import type OCPPIncomingRequestService from './ocpp/OCPPIncomingRequestService'; -import type OCPPRequestService from './ocpp/OCPPRequestService'; -import { OCPPServiceUtils } from './ocpp/OCPPServiceUtils'; -import SharedLRUCache from './SharedLRUCache'; -import BaseError from '../exception/BaseError'; -import OCPPError from '../exception/OCPPError'; -import PerformanceStatistics from '../performance/PerformanceStatistics'; -import type { AutomaticTransactionGeneratorConfiguration } from '../types/AutomaticTransactionGenerator'; -import type { ChargingStationConfiguration } from '../types/ChargingStationConfiguration'; -import type { ChargingStationInfo } from '../types/ChargingStationInfo'; -import type { ChargingStationOcppConfiguration } from '../types/ChargingStationOcppConfiguration'; import { - type ChargingStationTemplate, - CurrentType, - PowerUnits, - type WsOptions, -} from '../types/ChargingStationTemplate'; -import { SupervisionUrlDistribution } from '../types/ConfigurationData'; -import type { ConnectorStatus } from '../types/ConnectorStatus'; -import { FileType } from '../types/FileType'; -import type { JsonType } from '../types/JsonType'; -import { - ConnectorPhaseRotation, - StandardParametersKey, - SupportedFeatureProfiles, - VendorDefaultParametersKey, -} from '../types/ocpp/Configuration'; -import { ConnectorStatusEnum } from '../types/ocpp/ConnectorStatusEnum'; -import { ErrorType } from '../types/ocpp/ErrorType'; -import { MessageType } from '../types/ocpp/MessageType'; -import { MeterValue, MeterValueMeasurand } from '../types/ocpp/MeterValues'; -import { OCPPVersion } from '../types/ocpp/OCPPVersion'; + OCPP16IncomingRequestService, + OCPP16RequestService, + OCPP16ResponseService, + OCPP16ServiceUtils, + OCPP20IncomingRequestService, + OCPP20RequestService, + OCPP20ResponseService, + type OCPPIncomingRequestService, + type OCPPRequestService, + OCPPServiceUtils, +} from './ocpp'; +import { SharedLRUCache } from './SharedLRUCache'; +import { BaseError, OCPPError } from '../exception'; +import { PerformanceStatistics } from '../performance'; import { + type AutomaticTransactionGeneratorConfiguration, AvailabilityType, type BootNotificationRequest, + type BootNotificationResponse, type CachedRequest, + type ChargingStationConfiguration, + type ChargingStationInfo, + type ChargingStationOcppConfiguration, + type ChargingStationTemplate, + ConnectorPhaseRotation, + ConnectorStatus, + ConnectorStatusEnum, + CurrentType, type ErrorCallback, + type ErrorResponse, + ErrorType, + FileType, FirmwareStatus, type FirmwareStatusNotificationRequest, + type FirmwareStatusNotificationResponse, + type FirmwareUpgrade, type HeartbeatRequest, + type HeartbeatResponse, type IncomingRequest, - IncomingRequestCommand, + type IncomingRequestCommand, + type JsonType, + MessageType, + type MeterValue, + MeterValueMeasurand, type MeterValuesRequest, + type MeterValuesResponse, + OCPPVersion, type OutgoingRequest, + PowerUnits, + RegistrationStatusEnumType, RequestCommand, + type Response, type ResponseCallback, + StandardParametersKey, type StatusNotificationRequest, -} from '../types/ocpp/Requests'; -import { - type BootNotificationResponse, - type ErrorResponse, - type FirmwareStatusNotificationResponse, - type HeartbeatResponse, - type MeterValuesResponse, - RegistrationStatusEnumType, - type Response, type StatusNotificationResponse, -} from '../types/ocpp/Responses'; -import { StopTransactionReason, type StopTransactionRequest, type StopTransactionResponse, -} from '../types/ocpp/Transaction'; -import { WSError, WebSocketCloseEventStatusCode } from '../types/WebSocket'; -import Configuration from '../utils/Configuration'; -import Constants from '../utils/Constants'; + SupervisionUrlDistribution, + SupportedFeatureProfiles, + VendorDefaultParametersKey, + type WSError, + WebSocketCloseEventStatusCode, + type WsOptions, +} from '../types'; +import { Configuration } from '../utils/Configuration'; +import { Constants } from '../utils/Constants'; import { ACElectricUtils, DCElectricUtils } from '../utils/ElectricUtils'; -import FileUtils from '../utils/FileUtils'; -import logger from '../utils/Logger'; -import Utils from '../utils/Utils'; +import { FileUtils } from '../utils/FileUtils'; +import { logger } from '../utils/Logger'; +import { Utils } from '../utils/Utils'; -export default class ChargingStation { +export class ChargingStation { public readonly index: number; public readonly templateFile: string; public stationInfo!: ChargingStationInfo; @@ -157,17 +153,19 @@ export default class ChargingStation { ); } - public logPrefix(): string { + public logPrefix = (): string => { return Utils.logPrefix( ` ${ - this?.stationInfo?.chargingStationId ?? - ChargingStationUtils.getChargingStationId(this.index, this.getTemplateFromFile()) + (Utils.isNotEmptyString(this?.stationInfo?.chargingStationId) && + this?.stationInfo?.chargingStationId) ?? + ChargingStationUtils.getChargingStationId(this.index, this.getTemplateFromFile()) ?? + '' } |` ); - } + }; public hasAuthorizedTags(): boolean { - return !Utils.isEmptyArray( + return Utils.isNotEmptyArray( this.authorizedTagsCache.getAuthorizedTags( ChargingStationUtils.getAuthorizationFile(this.stationInfo) ) @@ -506,12 +504,12 @@ export default class ChargingStation { this.openWSConnection(); // Monitor charging station template file this.templateFileWatcher = FileUtils.watchJsonFile( - this.logPrefix(), - FileType.ChargingStationTemplate, this.templateFile, - null, + FileType.ChargingStationTemplate, + this.logPrefix(), + undefined, (event, filename): void => { - if (!Utils.isEmptyString(filename) && event === 'change') { + if (Utils.isNotEmptyString(filename) && event === 'change') { try { logger.debug( `${this.logPrefix()} ${FileType.ChargingStationTemplate} ${ @@ -710,7 +708,7 @@ export default class ChargingStation { this.getAutomaticTransactionGeneratorConfigurationFromTemplate(), this ); - if (!Utils.isEmptyArray(connectorIds)) { + if (Utils.isNotEmptyArray(connectorIds)) { for (const connectorId of connectorIds) { this.automaticTransactionGenerator?.startConnector(connectorId); } @@ -721,7 +719,7 @@ export default class ChargingStation { } public stopAutomaticTransactionGenerator(connectorIds?: number[]): void { - if (!Utils.isEmptyArray(connectorIds)) { + if (Utils.isNotEmptyArray(connectorIds)) { for (const connectorId of connectorIds) { this.automaticTransactionGenerator?.stopConnector(connectorId); } @@ -819,10 +817,10 @@ export default class ChargingStation { } } catch (error) { FileUtils.handleFileException( - this.logPrefix(), - FileType.ChargingStationTemplate, this.templateFile, - error as NodeJS.ErrnoException + FileType.ChargingStationTemplate, + error as NodeJS.ErrnoException, + this.logPrefix() ); } return template; @@ -862,7 +860,7 @@ export default class ChargingStation { ); stationInfo.ocppVersion = stationTemplate?.ocppVersion ?? OCPPVersion.VERSION_16; ChargingStationUtils.createSerialNumber(stationTemplate, stationInfo); - if (!Utils.isEmptyArray(stationTemplate?.power)) { + if (Utils.isNotEmptyArray(stationTemplate?.power)) { stationTemplate.power = stationTemplate.power as number[]; const powerArrayRandomIndex = Math.floor(Utils.secureRandom() * stationTemplate.power.length); stationInfo.maximumPower = @@ -879,7 +877,7 @@ export default class ChargingStation { stationInfo.firmwareVersionPattern = stationTemplate?.firmwareVersionPattern ?? Constants.SEMVER_PATTERN; if ( - !Utils.isEmptyString(stationInfo.firmwareVersion) && + Utils.isNotEmptyString(stationInfo.firmwareVersion) && new RegExp(stationInfo.firmwareVersionPattern).test(stationInfo.firmwareVersion) === false ) { logger.warn( @@ -888,8 +886,11 @@ export default class ChargingStation { } does not match firmware version pattern '${stationInfo.firmwareVersionPattern}'` ); } - stationInfo.firmwareUpgrade = merge( + stationInfo.firmwareUpgrade = merge( { + versionUpgrade: { + step: 1, + }, reset: true, }, stationTemplate?.firmwareUpgrade ?? {} @@ -1031,10 +1032,9 @@ export default class ChargingStation { } if ( this.stationInfo.firmwareStatus === FirmwareStatus.Installing && - !Utils.isEmptyString(this.stationInfo.firmwareVersion) && - !Utils.isEmptyString(this.stationInfo.firmwareVersionPattern) + Utils.isNotEmptyString(this.stationInfo.firmwareVersion) && + Utils.isNotEmptyString(this.stationInfo.firmwareVersionPattern) ) { - const versionStep = this.stationInfo.firmwareUpgrade?.versionUpgrade?.step ?? 1; const patternGroup: number | undefined = this.stationInfo.firmwareUpgrade?.versionUpgrade?.patternGroup ?? this.stationInfo.firmwareVersion?.split('.').length; @@ -1043,7 +1043,8 @@ export default class ChargingStation { ?.slice(1, patternGroup + 1); const patchLevelIndex = match.length - 1; match[patchLevelIndex] = ( - Utils.convertToInt(match[patchLevelIndex]) + versionStep + Utils.convertToInt(match[patchLevelIndex]) + + this.stationInfo.firmwareUpgrade?.versionUpgrade?.step ).toString(); this.stationInfo.firmwareVersion = match?.join('.'); } @@ -1096,7 +1097,7 @@ export default class ChargingStation { ); } if ( - !Utils.isEmptyString(this.stationInfo?.amperageLimitationOcppKey) && + Utils.isNotEmptyString(this.stationInfo?.amperageLimitationOcppKey) && !ChargingStationConfigurationUtils.getConfigurationKey( this, this.stationInfo.amperageLimitationOcppKey @@ -1335,10 +1336,10 @@ export default class ChargingStation { } } catch (error) { FileUtils.handleFileException( - this.logPrefix(), - FileType.ChargingStationConfiguration, this.configurationFile, - error as NodeJS.ErrnoException + FileType.ChargingStationConfiguration, + error as NodeJS.ErrnoException, + this.logPrefix() ); } } @@ -1381,10 +1382,10 @@ export default class ChargingStation { } } catch (error) { FileUtils.handleFileException( - this.logPrefix(), - FileType.ChargingStationConfiguration, this.configurationFile, - error as NodeJS.ErrnoException + FileType.ChargingStationConfiguration, + error as NodeJS.ErrnoException, + this.logPrefix() ); } } else { @@ -1761,7 +1762,7 @@ export default class ChargingStation { private getAmperageLimitation(): number | undefined { if ( - !Utils.isEmptyString(this.stationInfo?.amperageLimitationOcppKey) && + Utils.isNotEmptyString(this.stationInfo?.amperageLimitationOcppKey) && ChargingStationConfigurationUtils.getConfigurationKey( this, this.stationInfo.amperageLimitationOcppKey @@ -1922,7 +1923,7 @@ export default class ChargingStation { private getConfiguredSupervisionUrl(): URL { const supervisionUrls = this.stationInfo?.supervisionUrls ?? Configuration.getSupervisionUrls(); - if (!Utils.isEmptyArray(supervisionUrls)) { + if (Utils.isNotEmptyArray(supervisionUrls)) { switch (Configuration.getSupervisionUrlDistribution()) { case SupervisionUrlDistribution.ROUND_ROBIN: // FIXME