+ return template;
+ }
+
+ private getStationInfoFromTemplate(): ChargingStationInfo {
+ const stationTemplate: ChargingStationTemplate = this.getTemplateFromFile();
+ if (Utils.isNullOrUndefined(stationTemplate)) {
+ const errorMsg = `Failed to read charging station template file ${this.templateFile}`;
+ logger.error(`${this.logPrefix()} ${errorMsg}`);
+ throw new BaseError(errorMsg);
+ }
+ if (Utils.isEmptyObject(stationTemplate)) {
+ const errorMsg = `Empty charging station information from template file ${this.templateFile}`;
+ logger.error(`${this.logPrefix()} ${errorMsg}`);
+ throw new BaseError(errorMsg);
+ }
+ // Deprecation template keys section
+ ChargingStationUtils.warnDeprecatedTemplateKey(
+ stationTemplate,
+ 'supervisionUrl',
+ this.templateFile,
+ this.logPrefix(),
+ "Use 'supervisionUrls' instead"
+ );
+ 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;