+export const stationTemplateToStationInfo = (
+ stationTemplate: ChargingStationTemplate,
+): ChargingStationInfo => {
+ stationTemplate = cloneObject<ChargingStationTemplate>(stationTemplate);
+ delete stationTemplate.power;
+ delete stationTemplate.powerUnit;
+ delete stationTemplate.Connectors;
+ delete stationTemplate.Evses;
+ delete stationTemplate.Configuration;
+ delete stationTemplate.AutomaticTransactionGenerator;
+ delete stationTemplate.chargeBoxSerialNumberPrefix;
+ delete stationTemplate.chargePointSerialNumberPrefix;
+ delete stationTemplate.meterSerialNumberPrefix;
+ return stationTemplate as ChargingStationInfo;
+};
+
+export const createSerialNumber = (
+ stationTemplate: ChargingStationTemplate,
+ stationInfo: ChargingStationInfo,
+ params: {
+ randomSerialNumberUpperCase?: boolean;
+ randomSerialNumber?: boolean;
+ } = {
+ randomSerialNumberUpperCase: true,
+ randomSerialNumber: true,
+ },
+): void => {
+ params = { ...{ randomSerialNumberUpperCase: true, randomSerialNumber: true }, ...params };
+ const serialNumberSuffix = params?.randomSerialNumber
+ ? getRandomSerialNumberSuffix({
+ upperCase: params.randomSerialNumberUpperCase,
+ })
+ : '';
+ isNotEmptyString(stationTemplate?.chargePointSerialNumberPrefix) &&
+ (stationInfo.chargePointSerialNumber = `${stationTemplate.chargePointSerialNumberPrefix}${serialNumberSuffix}`);
+ isNotEmptyString(stationTemplate?.chargeBoxSerialNumberPrefix) &&
+ (stationInfo.chargeBoxSerialNumber = `${stationTemplate.chargeBoxSerialNumberPrefix}${serialNumberSuffix}`);
+ isNotEmptyString(stationTemplate?.meterSerialNumberPrefix) &&
+ (stationInfo.meterSerialNumber = `${stationTemplate.meterSerialNumberPrefix}${serialNumberSuffix}`);
+};
+
+export const propagateSerialNumber = (
+ stationTemplate: ChargingStationTemplate,
+ stationInfoSrc: ChargingStationInfo,
+ stationInfoDst: 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;
+};
+
+export const getAmperageLimitationUnitDivider = (stationInfo: ChargingStationInfo): number => {
+ let unitDivider = 1;
+ switch (stationInfo.amperageLimitationUnit) {
+ case AmpereUnits.DECI_AMPERE:
+ unitDivider = 10;
+ break;
+ case AmpereUnits.CENTI_AMPERE:
+ unitDivider = 100;
+ break;
+ case AmpereUnits.MILLI_AMPERE:
+ unitDivider = 1000;
+ break;
+ }
+ return unitDivider;
+};
+
+export const getChargingStationConnectorChargingProfilesPowerLimit = (
+ chargingStation: ChargingStation,
+ connectorId: number,
+): number | undefined => {
+ let limit: number | undefined, matchingChargingProfile: ChargingProfile | undefined;
+ // Get charging profiles for connector id and sort by stack level
+ const chargingProfiles =
+ cloneObject<ChargingProfile[]>(
+ chargingStation.getConnectorStatus(connectorId)!.chargingProfiles!,
+ )?.sort((a, b) => b.stackLevel - a.stackLevel) ?? [];
+ // Get charging profiles on connector 0 and sort by stack level
+ if (isNotEmptyArray(chargingStation.getConnectorStatus(0)?.chargingProfiles)) {
+ chargingProfiles.push(
+ ...cloneObject<ChargingProfile[]>(
+ chargingStation.getConnectorStatus(0)!.chargingProfiles!,
+ ).sort((a, b) => b.stackLevel - a.stackLevel),
+ );
+ }
+ if (isNotEmptyArray(chargingProfiles)) {
+ const result = getLimitFromChargingProfiles(
+ chargingStation,
+ connectorId,
+ chargingProfiles,
+ chargingStation.logPrefix(),
+ );
+ if (!isNullOrUndefined(result)) {
+ limit = result?.limit;
+ matchingChargingProfile = result?.matchingChargingProfile;
+ switch (chargingStation.getCurrentOutType()) {
+ case CurrentType.AC:
+ limit =
+ matchingChargingProfile?.chargingSchedule?.chargingRateUnit ===
+ ChargingRateUnitType.WATT
+ ? limit
+ : ACElectricUtils.powerTotal(
+ chargingStation.getNumberOfPhases(),
+ chargingStation.getVoltageOut(),
+ limit!,
+ );
+ break;
+ case CurrentType.DC:
+ limit =
+ matchingChargingProfile?.chargingSchedule?.chargingRateUnit ===
+ ChargingRateUnitType.WATT
+ ? limit
+ : DCElectricUtils.power(chargingStation.getVoltageOut(), limit!);
+ }
+ const connectorMaximumPower =
+ chargingStation.getMaximumPower() / chargingStation.powerDivider;
+ if (limit! > connectorMaximumPower) {
+ logger.error(
+ `${chargingStation.logPrefix()} ${moduleName}.getChargingStationConnectorChargingProfilesPowerLimit: Charging profile id ${matchingChargingProfile?.chargingProfileId} limit ${limit} is greater than connector id ${connectorId} maximum ${connectorMaximumPower}: %j`,
+ result,
+ );
+ limit = connectorMaximumPower;