X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FChargingStationUtils.ts;h=645fbd95f31aea77430cc43e9163aa69848acde3;hb=60c59a02878ddd2ddbac38ec3b3d38f706e538e9;hp=b57e98e6741222f309d04d8ac84ed3ccbf4bec37;hpb=fa7bccf4a465d2156c43a3b5f33f0b521da52dc3;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ChargingStationUtils.ts b/src/charging-station/ChargingStationUtils.ts index b57e98e6..645fbd95 100644 --- a/src/charging-station/ChargingStationUtils.ts +++ b/src/charging-station/ChargingStationUtils.ts @@ -1,32 +1,40 @@ -import { ChargingProfile, ChargingSchedulePeriod } from '../types/ocpp/ChargingProfile'; -import { ChargingProfileKindType, RecurrencyKindType } from '../types/ocpp/1.6/ChargingProfile'; +import crypto from 'crypto'; +import path from 'path'; +import { fileURLToPath } from 'url'; + +import moment from 'moment'; + +import BaseError from '../exception/BaseError'; +import type ChargingStationInfo from '../types/ChargingStationInfo'; import ChargingStationTemplate, { AmpereUnits, CurrentType, Voltage, } from '../types/ChargingStationTemplate'; -import { MeterValueMeasurand, MeterValuePhase } from '../types/ocpp/MeterValues'; - -import { BootNotificationRequest } from '../types/ocpp/Requests'; -import ChargingStation from './ChargingStation'; -import { ChargingStationConfigurationUtils } from './ChargingStationConfigurationUtils'; -import ChargingStationInfo from '../types/ChargingStationInfo'; -import Configuration from '../utils/Configuration'; -import Constants from '../utils/Constants'; -import { FileType } from '../types/FileType'; -import FileUtils from '../utils/FileUtils'; -import { SampledValueTemplate } from '../types/MeasurandPerPhaseSampledValueTemplates'; +import type { SampledValueTemplate } from '../types/MeasurandPerPhaseSampledValueTemplates'; +import { ChargingProfileKindType, RecurrencyKindType } from '../types/ocpp/1.6/ChargingProfile'; +import type { ChargingProfile, ChargingSchedulePeriod } from '../types/ocpp/ChargingProfile'; import { StandardParametersKey } from '../types/ocpp/Configuration'; -import Utils from '../utils/Utils'; +import { MeterValueMeasurand, MeterValuePhase } from '../types/ocpp/MeterValues'; +import { + BootNotificationRequest, + IncomingRequestCommand, + RequestCommand, +} from '../types/ocpp/Requests'; import { WebSocketCloseEventStatusString } from '../types/WebSocket'; import { WorkerProcessType } from '../types/Worker'; -import crypto from 'crypto'; -import fs from 'fs'; +import Configuration from '../utils/Configuration'; +import Constants from '../utils/Constants'; import logger from '../utils/Logger'; -import moment from 'moment'; -import path from 'path'; +import Utils from '../utils/Utils'; +import type ChargingStation from './ChargingStation'; +import { ChargingStationConfigurationUtils } from './ChargingStationConfigurationUtils'; export class ChargingStationUtils { + private constructor() { + // This is intentional + } + public static getChargingStationId( index: number, stationTemplate: ChargingStationTemplate @@ -158,12 +166,12 @@ export class ChargingStationUtils { public static workerPoolInUse(): boolean { return [WorkerProcessType.DYNAMIC_POOL, WorkerProcessType.STATIC_POOL].includes( - Configuration.getWorkerProcess() + Configuration.getWorker().processType ); } public static workerDynamicPoolInUse(): boolean { - return Configuration.getWorkerProcess() === WorkerProcessType.DYNAMIC_POOL; + return Configuration.getWorker().processType === WorkerProcessType.DYNAMIC_POOL; } /** @@ -229,29 +237,21 @@ export class ChargingStationUtils { delete stationTemplate.AutomaticTransactionGenerator; delete stationTemplate.chargeBoxSerialNumberPrefix; delete stationTemplate.chargePointSerialNumberPrefix; + delete stationTemplate.meterSerialNumberPrefix; return stationTemplate; } public static createStationInfoHash(stationInfo: ChargingStationInfo): void { - const previousInfoHash = stationInfo?.infoHash ?? ''; delete stationInfo.infoHash; - const currentInfoHash = crypto + stationInfo.infoHash = crypto .createHash(Constants.DEFAULT_HASH_ALGORITHM) .update(JSON.stringify(stationInfo)) .digest('hex'); - if ( - Utils.isEmptyString(previousInfoHash) || - (!Utils.isEmptyString(previousInfoHash) && currentInfoHash !== previousInfoHash) - ) { - stationInfo.infoHash = currentInfoHash; - } else { - stationInfo.infoHash = previousInfoHash; - } } public static createSerialNumber( stationTemplate: ChargingStationTemplate, - stationInfo: ChargingStationInfo, + stationInfo: ChargingStationInfo = {} as ChargingStationInfo, params: { randomSerialNumberUpperCase?: boolean; randomSerialNumber?: boolean; @@ -268,24 +268,36 @@ export class ChargingStationUtils { upperCase: params.randomSerialNumberUpperCase, }) : ''; - stationTemplate?.chargePointSerialNumberPrefix && - stationInfo && - Utils.isNullOrUndefined(stationInfo?.chargePointSerialNumber) - ? (stationInfo.chargePointSerialNumber = - stationTemplate.chargePointSerialNumberPrefix + serialNumberSuffix) - : stationInfo && delete stationInfo.chargePointSerialNumber; - stationTemplate?.chargeBoxSerialNumberPrefix && - stationInfo && - Utils.isNullOrUndefined(stationInfo?.chargeBoxSerialNumber) - ? (stationInfo.chargeBoxSerialNumber = - stationTemplate.chargeBoxSerialNumberPrefix + serialNumberSuffix) - : stationInfo && delete stationInfo.chargeBoxSerialNumber; - stationTemplate?.meterSerialNumberPrefix && - stationInfo && - Utils.isNullOrUndefined(stationInfo?.meterSerialNumber) - ? (stationInfo.meterSerialNumber = - stationTemplate.meterSerialNumberPrefix + serialNumberSuffix) - : stationInfo && delete stationInfo.meterSerialNumber; + stationInfo.chargePointSerialNumber = + stationTemplate?.chargePointSerialNumberPrefix && + stationTemplate.chargePointSerialNumberPrefix + serialNumberSuffix; + stationInfo.chargeBoxSerialNumber = + stationTemplate?.chargeBoxSerialNumberPrefix && + stationTemplate.chargeBoxSerialNumberPrefix + serialNumberSuffix; + stationInfo.meterSerialNumber = + stationTemplate?.meterSerialNumberPrefix && + stationTemplate.meterSerialNumberPrefix + serialNumberSuffix; + } + + public static propagateSerialNumber( + stationTemplate: ChargingStationTemplate, + stationInfoSrc: ChargingStationInfo, + stationInfoDst: ChargingStationInfo = {} as ChargingStationInfo + ) { + if (!stationInfoSrc || !stationTemplate) { + throw new BaseError( + 'Missing charging station template or existing configuration to propagate serial number' + ); + } + stationTemplate?.chargePointSerialNumberPrefix && stationInfoSrc?.chargePointSerialNumber + ? (stationInfoDst.chargePointSerialNumber = stationInfoSrc.chargePointSerialNumber) + : stationInfoDst?.chargePointSerialNumber && delete stationInfoDst.chargePointSerialNumber; + stationTemplate?.chargeBoxSerialNumberPrefix && stationInfoSrc?.chargeBoxSerialNumber + ? (stationInfoDst.chargeBoxSerialNumber = stationInfoSrc.chargeBoxSerialNumber) + : stationInfoDst?.chargeBoxSerialNumber && delete stationInfoDst.chargeBoxSerialNumber; + stationTemplate?.meterSerialNumberPrefix && stationInfoSrc?.meterSerialNumber + ? (stationInfoDst.meterSerialNumber = stationInfoSrc.meterSerialNumber) + : stationInfoDst?.meterSerialNumber && delete stationInfoDst.meterSerialNumber; } public static getAmperageLimitationUnitDivider(stationInfo: ChargingStationInfo): number { @@ -425,7 +437,7 @@ export class ChargingStationUtils { break; default: logger.error(errMsg); - throw new Error(errMsg); + throw new BaseError(errMsg); } return defaultVoltageOut; } @@ -504,49 +516,58 @@ export class ChargingStationUtils { if (measurand === MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER) { const errorMsg = `${chargingStation.logPrefix()} Missing MeterValues for default measurand '${measurand}' in template on connectorId ${connectorId}`; logger.error(errorMsg); - throw new Error(errorMsg); + throw new BaseError(errorMsg); } logger.debug( `${chargingStation.logPrefix()} No MeterValues for measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId}` ); } - public static getAuthorizedTags( - stationInfo: ChargingStationInfo, - templateFile: string, - logPrefix: string - ): string[] { - let authorizedTags: string[] = []; - const authorizationFile = ChargingStationUtils.getAuthorizationFile(stationInfo); - if (authorizationFile) { - try { - // Load authorization file - authorizedTags = JSON.parse(fs.readFileSync(authorizationFile, 'utf8')) as string[]; - } catch (error) { - FileUtils.handleFileException( - logPrefix, - FileType.Authorization, - authorizationFile, - error as NodeJS.ErrnoException - ); - } - } else { - logger.info(logPrefix + ' No authorization file given in template file ' + templateFile); - } - return authorizedTags; - } - public static getAuthorizationFile(stationInfo: ChargingStationInfo): string | undefined { return ( stationInfo.authorizationFile && path.join( - path.resolve(__dirname, '../'), + path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../'), 'assets', path.basename(stationInfo.authorizationFile) ) ); } + public static isRequestCommandSupported( + command: RequestCommand, + chargingStation: ChargingStation + ): boolean { + const isRequestCommand = Object.values(RequestCommand).includes(command); + if (isRequestCommand && !chargingStation.stationInfo?.commandsSupport?.outgoingCommands) { + return true; + } else if (isRequestCommand && chargingStation.stationInfo?.commandsSupport?.outgoingCommands) { + return chargingStation.stationInfo?.commandsSupport?.outgoingCommands[command] ?? false; + } + logger.error(`${chargingStation.logPrefix()} Unknown outgoing OCPP command '${command}'`); + return false; + } + + public static isIncomingRequestCommandSupported( + command: IncomingRequestCommand, + chargingStation: ChargingStation + ): boolean { + const isIncomingRequestCommand = Object.values(IncomingRequestCommand).includes(command); + if ( + isIncomingRequestCommand && + !chargingStation.stationInfo?.commandsSupport?.incomingCommands + ) { + return true; + } else if ( + isIncomingRequestCommand && + chargingStation.stationInfo?.commandsSupport?.incomingCommands + ) { + return chargingStation.stationInfo?.commandsSupport?.incomingCommands[command] ?? false; + } + logger.error(`${chargingStation.logPrefix()} Unknown incoming OCPP command '${command}'`); + return false; + } + private static getRandomSerialNumberSuffix(params?: { randomBytesLength?: number; upperCase?: boolean;