+ ChargingStationUtils.convertDeprecatedTemplateKey(
+ stationTemplate,
+ 'supervisionUrl',
+ 'supervisionUrls'
+ );
+ const stationInfo: ChargingStationInfo =
+ ChargingStationUtils.stationTemplateToStationInfo(stationTemplate);
+ stationInfo.hashId = ChargingStationUtils.getHashId(this.index, stationTemplate);
+ stationInfo.chargingStationId = ChargingStationUtils.getChargingStationId(
+ this.index,
+ stationTemplate
+ );
+ ChargingStationUtils.createSerialNumber(stationTemplate, stationInfo);
+ if (!Utils.isEmptyArray(stationTemplate.power)) {
+ stationTemplate.power = stationTemplate.power as number[];
+ const powerArrayRandomIndex = Math.floor(Utils.secureRandom() * stationTemplate.power.length);
+ stationInfo.maximumPower =
+ stationTemplate.powerUnit === PowerUnits.KILO_WATT
+ ? stationTemplate.power[powerArrayRandomIndex] * 1000
+ : stationTemplate.power[powerArrayRandomIndex];
+ } else {
+ stationTemplate.power = stationTemplate.power as number;
+ stationInfo.maximumPower =
+ stationTemplate.powerUnit === PowerUnits.KILO_WATT
+ ? stationTemplate.power * 1000
+ : stationTemplate.power;
+ }
+ stationInfo.firmwareVersionPattern =
+ stationTemplate.firmwareVersionPattern ?? Constants.SEMVER_PATTERN;
+ if (
+ stationInfo.firmwareVersion &&
+ new RegExp(stationInfo.firmwareVersionPattern).test(stationInfo.firmwareVersion) === false
+ ) {
+ logger.warn(
+ `${this.logPrefix()} Firmware version '${stationInfo.firmwareVersion}' in template file ${
+ this.templateFile
+ } does not match firmware version pattern '${stationInfo.firmwareVersionPattern}'`
+ );
+ }
+ stationInfo.resetTime = stationTemplate.resetTime
+ ? stationTemplate.resetTime * 1000
+ : Constants.CHARGING_STATION_DEFAULT_RESET_TIME;
+ const configuredMaxConnectors =
+ ChargingStationUtils.getConfiguredNumberOfConnectors(stationTemplate);
+ ChargingStationUtils.checkConfiguredMaxConnectors(
+ configuredMaxConnectors,
+ this.templateFile,
+ this.logPrefix()
+ );
+ const templateMaxConnectors =
+ ChargingStationUtils.getTemplateMaxNumberOfConnectors(stationTemplate);
+ ChargingStationUtils.checkTemplateMaxConnectors(
+ templateMaxConnectors,
+ this.templateFile,
+ this.logPrefix()
+ );
+ if (
+ configuredMaxConnectors >
+ (stationTemplate?.Connectors[0] ? templateMaxConnectors - 1 : templateMaxConnectors) &&
+ !stationTemplate?.randomConnectors
+ ) {
+ logger.warn(
+ `${this.logPrefix()} Number of connectors exceeds the number of connector configurations in template ${
+ this.templateFile
+ }, forcing random connector configurations affectation`
+ );
+ stationInfo.randomConnectors = true;
+ }
+ // Build connectors if needed (FIXME: should be factored out)
+ this.initializeConnectors(stationInfo, configuredMaxConnectors, templateMaxConnectors);
+ stationInfo.maximumAmperage = this.getMaximumAmperage(stationInfo);
+ ChargingStationUtils.createStationInfoHash(stationInfo);
+ return stationInfo;
+ }
+
+ private getStationInfoFromFile(): ChargingStationInfo | null {
+ let stationInfo: ChargingStationInfo = null;
+ this.getStationInfoPersistentConfiguration() &&
+ (stationInfo = this.getConfigurationFromFile()?.stationInfo ?? null);
+ stationInfo && ChargingStationUtils.createStationInfoHash(stationInfo);
+ return stationInfo;
+ }
+
+ private getStationInfo(): ChargingStationInfo {
+ const stationInfoFromTemplate: ChargingStationInfo = this.getStationInfoFromTemplate();
+ const stationInfoFromFile: ChargingStationInfo = this.getStationInfoFromFile();
+ // Priority: charging station info from template > charging station info from configuration file > charging station info attribute
+ if (stationInfoFromFile?.templateHash === stationInfoFromTemplate.templateHash) {
+ if (this.stationInfo?.infoHash === stationInfoFromFile?.infoHash) {
+ return this.stationInfo;
+ }
+ return stationInfoFromFile;
+ }
+ stationInfoFromFile &&
+ ChargingStationUtils.propagateSerialNumber(
+ this.getTemplateFromFile(),
+ stationInfoFromFile,
+ stationInfoFromTemplate
+ );
+ return stationInfoFromTemplate;
+ }
+
+ private saveStationInfo(): void {
+ if (this.getStationInfoPersistentConfiguration()) {
+ this.saveConfiguration();
+ }
+ }
+
+ private getOcppVersion(): OCPPVersion {
+ return this.stationInfo.ocppVersion ?? OCPPVersion.VERSION_16;
+ }
+
+ private getOcppPersistentConfiguration(): boolean {
+ return this.stationInfo?.ocppPersistentConfiguration ?? true;
+ }
+
+ private getStationInfoPersistentConfiguration(): boolean {
+ return this.stationInfo?.stationInfoPersistentConfiguration ?? true;
+ }
+
+ private handleUnsupportedVersion(version: OCPPVersion) {
+ const errMsg = `Unsupported protocol version '${version}' configured in template file ${this.templateFile}`;
+ logger.error(`${this.logPrefix()} ${errMsg}`);
+ throw new BaseError(errMsg);
+ }
+
+ private initialize(): void {
+ this.configurationFile = path.join(
+ path.dirname(this.templateFile.replace('station-templates', 'configurations')),
+ ChargingStationUtils.getHashId(this.index, this.getTemplateFromFile()) + '.json'
+ );
+ this.stationInfo = this.getStationInfo();
+ this.saveStationInfo();
+ // Avoid duplication of connectors related information in RAM
+ this.stationInfo?.Connectors && delete this.stationInfo.Connectors;
+ this.configuredSupervisionUrl = this.getConfiguredSupervisionUrl();
+ if (this.getEnableStatistics() === true) {
+ this.performanceStatistics = PerformanceStatistics.getInstance(
+ this.stationInfo.hashId,
+ this.stationInfo.chargingStationId,
+ this.configuredSupervisionUrl
+ );
+ }
+ this.bootNotificationRequest = ChargingStationUtils.createBootNotificationRequest(
+ this.stationInfo
+ );
+ this.powerDivider = this.getPowerDivider();
+ // OCPP configuration
+ this.ocppConfiguration = this.getOcppConfiguration();
+ this.initializeOcppConfiguration();