X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FHelpers.ts;h=492d26aa10dbeb5a5d028e1a7d6d111c291ac368;hb=de7b9e0583275225509c099f75a2801371da54d0;hp=0384da3e3026f0f0ce6b006f2b2a640183a7d8a9;hpb=dc347546238a2a8c5cf9f5e1c60dac29913e3948;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/Helpers.ts b/src/charging-station/Helpers.ts index 0384da3e..492d26aa 100644 --- a/src/charging-station/Helpers.ts +++ b/src/charging-station/Helpers.ts @@ -1,10 +1,12 @@ import { createHash, randomBytes } from 'node:crypto'; import type { EventEmitter } from 'node:events'; import { basename, dirname, join } from 'node:path'; +import { env } from 'node:process'; import { fileURLToPath } from 'node:url'; import chalk from 'chalk'; import { + type Interval, addDays, addSeconds, addWeeks, @@ -16,9 +18,9 @@ import { isDate, isPast, isWithinInterval, - maxTime, toDate, } from 'date-fns'; +import { maxTime } from 'date-fns/constants'; import type { ChargingStation } from './ChargingStation'; import { getConfigurationKey } from './ConfigurationKeyUtils'; @@ -32,6 +34,7 @@ import { ChargingProfileKindType, ChargingRateUnitType, type ChargingSchedulePeriod, + type ChargingStationConfiguration, type ChargingStationInfo, type ChargingStationTemplate, ChargingStationWorkerMessageEvents, @@ -73,10 +76,13 @@ const moduleName = 'Helpers'; export const getChargingStationId = ( index: number, - stationTemplate: ChargingStationTemplate, + stationTemplate: ChargingStationTemplate | undefined, ): string => { + if (stationTemplate === undefined) { + return "Unknown 'chargingStationId'"; + } // In case of multiple instances: add instance index to charging station id - const instanceIndex = process.env.CF_INSTANCE_INDEX ?? 0; + const instanceIndex = env.CF_INSTANCE_INDEX ?? 0; const idSuffix = stationTemplate?.nameSuffix ?? ''; const idStr = `000000000${index.toString()}`; return stationTemplate?.fixedName @@ -174,9 +180,9 @@ export const getPhaseRotationValue = ( } else if (connectorId > 0 && numberOfPhases === 0) { return `${connectorId}.${ConnectorPhaseRotation.NotApplicable}`; // AC - } else if (connectorId > 0 && numberOfPhases === 1) { + } else if (connectorId >= 0 && numberOfPhases === 1) { return `${connectorId}.${ConnectorPhaseRotation.NotApplicable}`; - } else if (connectorId > 0 && numberOfPhases === 3) { + } else if (connectorId >= 0 && numberOfPhases === 3) { return `${connectorId}.${ConnectorPhaseRotation.RST}`; } }; @@ -249,6 +255,23 @@ export const checkTemplate = ( } }; +export const checkConfiguration = ( + stationConfiguration: ChargingStationConfiguration | undefined, + logPrefix: string, + configurationFile: string, +): void => { + if (isNullOrUndefined(stationConfiguration)) { + const errorMsg = `Failed to read charging station configuration file ${configurationFile}`; + logger.error(`${logPrefix} ${errorMsg}`); + throw new BaseError(errorMsg); + } + if (isEmptyObject(stationConfiguration!)) { + const errorMsg = `Empty charging station configuration from file ${configurationFile}`; + logger.error(`${logPrefix} ${errorMsg}`); + throw new BaseError(errorMsg); + } +}; + export const checkConnectorsConfiguration = ( stationTemplate: ChargingStationTemplate, logPrefix: string, @@ -262,7 +285,7 @@ export const checkConnectorsConfiguration = ( checkConfiguredMaxConnectors(configuredMaxConnectors, logPrefix, templateFile); const templateMaxConnectors = getMaxNumberOfConnectors(stationTemplate.Connectors!); checkTemplateMaxConnectors(templateMaxConnectors, logPrefix, templateFile); - const templateMaxAvailableConnectors = stationTemplate.Connectors![0] + const templateMaxAvailableConnectors = stationTemplate.Connectors?.[0] ? templateMaxConnectors - 1 : templateMaxConnectors; if ( @@ -339,11 +362,12 @@ export const initializeConnectorsMapStatus = ( }; export const resetConnectorStatus = (connectorStatus: ConnectorStatus): void => { - connectorStatus.chargingProfiles = isNotEmptyArray(connectorStatus.chargingProfiles) - ? connectorStatus.chargingProfiles?.filter( - (chargingProfile) => chargingProfile.transactionId !== connectorStatus?.transactionId, - ) - : []; + connectorStatus.chargingProfiles = + connectorStatus.transactionId && isNotEmptyArray(connectorStatus.chargingProfiles) + ? connectorStatus.chargingProfiles?.filter( + (chargingProfile) => chargingProfile.transactionId !== connectorStatus.transactionId, + ) + : []; connectorStatus.idTagLocalAuthorized = false; connectorStatus.idTagAuthorized = false; connectorStatus.transactionRemoteStarted = false; @@ -361,7 +385,7 @@ export const createBootNotificationRequest = ( stationInfo: ChargingStationInfo, bootReason: BootReasonEnumType = BootReasonEnumType.PowerUp, ): BootNotificationRequest => { - const ocppVersion = stationInfo.ocppVersion ?? OCPPVersion.VERSION_16; + const ocppVersion = stationInfo.ocppVersion!; switch (ocppVersion) { case OCPPVersion.VERSION_16: return { @@ -451,12 +475,9 @@ export const stationTemplateToStationInfo = ( export const createSerialNumber = ( stationTemplate: ChargingStationTemplate, stationInfo: ChargingStationInfo, - params: { + params?: { randomSerialNumberUpperCase?: boolean; randomSerialNumber?: boolean; - } = { - randomSerialNumberUpperCase: true, - randomSerialNumber: true, }, ): void => { params = { ...{ randomSerialNumberUpperCase: true, randomSerialNumber: true }, ...params }; @@ -560,14 +581,14 @@ export const getChargingStationConnectorChargingProfilesPowerLimit = ( if (!isNullOrUndefined(result)) { limit = result?.limit; chargingProfile = result?.chargingProfile; - switch (chargingStation.getCurrentOutType()) { + switch (chargingStation.stationInfo?.currentOutType) { case CurrentType.AC: limit = chargingProfile?.chargingSchedule?.chargingRateUnit === ChargingRateUnitType.WATT ? limit : ACElectricUtils.powerTotal( chargingStation.getNumberOfPhases(), - chargingStation.getVoltageOut(), + chargingStation.stationInfo.voltageOut!, limit!, ); break; @@ -575,10 +596,10 @@ export const getChargingStationConnectorChargingProfilesPowerLimit = ( limit = chargingProfile?.chargingSchedule?.chargingRateUnit === ChargingRateUnitType.WATT ? limit - : DCElectricUtils.power(chargingStation.getVoltageOut(), limit!); + : DCElectricUtils.power(chargingStation.stationInfo.voltageOut!, limit!); } const connectorMaximumPower = - chargingStation.getMaximumPower() / 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`, @@ -647,7 +668,7 @@ const getConfiguredMaxNumberOfConnectors = (stationTemplate: ChargingStationTemp } else if (isUndefined(stationTemplate.numberOfConnectors) === false) { configuredMaxNumberOfConnectors = stationTemplate.numberOfConnectors as number; } else if (stationTemplate.Connectors && !stationTemplate.Evses) { - configuredMaxNumberOfConnectors = stationTemplate.Connectors[0] + configuredMaxNumberOfConnectors = stationTemplate.Connectors?.[0] ? getMaxNumberOfConnectors(stationTemplate.Connectors) - 1 : getMaxNumberOfConnectors(stationTemplate.Connectors); } else if (stationTemplate.Evses && !stationTemplate.Connectors) { @@ -711,12 +732,12 @@ const warnDeprecatedTemplateKey = ( templateFile: string, logMsgToAppend = '', ): void => { - if (!isUndefined(template[key as keyof ChargingStationTemplate])) { + if (!isUndefined(template?.[key as keyof ChargingStationTemplate])) { const logMsg = `Deprecated template key '${key}' usage in file '${templateFile}'${ isNotEmptyString(logMsgToAppend) ? `. ${logMsgToAppend}` : '' }`; logger.warn(`${logPrefix} ${logMsg}`); - console.warn(chalk.yellow(`${logMsg}`)); + console.warn(`${chalk.green(logPrefix)} ${chalk.yellow(logMsg)}`); } }; @@ -725,7 +746,7 @@ const convertDeprecatedTemplateKey = ( deprecatedKey: string, key?: string, ): void => { - if (!isUndefined(template[deprecatedKey as keyof ChargingStationTemplate])) { + if (!isUndefined(template?.[deprecatedKey as keyof ChargingStationTemplate])) { if (!isUndefined(key)) { (template as unknown as Record)[key!] = template[deprecatedKey as keyof ChargingStationTemplate]; @@ -966,7 +987,10 @@ const canProceedRecurringChargingProfile = ( ); return false; } - if (isNullOrUndefined(chargingProfile.chargingSchedule.startSchedule)) { + if ( + chargingProfile.chargingProfileKind === ChargingProfileKindType.RECURRING && + isNullOrUndefined(chargingProfile.chargingSchedule.startSchedule) + ) { logger.error( `${logPrefix} ${moduleName}.canProceedRecurringChargingProfile: Recurring charging profile id ${chargingProfile.chargingProfileId} has no startSchedule defined`, );