+ return reservableConnectors;
+};
+
+export const getHashId = (index: number, stationTemplate: ChargingStationTemplate): string => {
+ const chargingStationInfo = {
+ chargePointModel: stationTemplate.chargePointModel,
+ chargePointVendor: stationTemplate.chargePointVendor,
+ ...(!isUndefined(stationTemplate.chargeBoxSerialNumberPrefix) && {
+ chargeBoxSerialNumber: stationTemplate.chargeBoxSerialNumberPrefix,
+ }),
+ ...(!isUndefined(stationTemplate.chargePointSerialNumberPrefix) && {
+ chargePointSerialNumber: stationTemplate.chargePointSerialNumberPrefix,
+ }),
+ ...(!isUndefined(stationTemplate.meterSerialNumberPrefix) && {
+ meterSerialNumber: stationTemplate.meterSerialNumberPrefix,
+ }),
+ ...(!isUndefined(stationTemplate.meterType) && {
+ meterType: stationTemplate.meterType,
+ }),
+ };
+ return createHash(Constants.DEFAULT_HASH_ALGORITHM)
+ .update(`${JSON.stringify(chargingStationInfo)}${getChargingStationId(index, stationTemplate)}`)
+ .digest('hex');
+};
+
+export const checkChargingStation = (
+ chargingStation: ChargingStation,
+ logPrefix: string,
+): boolean => {
+ if (chargingStation.started === false && chargingStation.starting === false) {
+ logger.warn(`${logPrefix} charging station is stopped, cannot proceed`);
+ return false;
+ }
+ return true;
+};
+
+export const getPhaseRotationValue = (
+ connectorId: number,
+ numberOfPhases: number,
+): string | undefined => {
+ // AC/DC
+ if (connectorId === 0 && numberOfPhases === 0) {
+ return `${connectorId}.${ConnectorPhaseRotation.RST}`;
+ } else if (connectorId > 0 && numberOfPhases === 0) {
+ return `${connectorId}.${ConnectorPhaseRotation.NotApplicable}`;
+ // AC
+ } else if (connectorId > 0 && numberOfPhases === 1) {
+ return `${connectorId}.${ConnectorPhaseRotation.NotApplicable}`;
+ } else if (connectorId > 0 && numberOfPhases === 3) {
+ return `${connectorId}.${ConnectorPhaseRotation.RST}`;
+ }
+};
+
+export const getMaxNumberOfEvses = (evses: Record<string, EvseTemplate>): number => {
+ if (!evses) {
+ return -1;
+ }
+ return Object.keys(evses).length;
+};
+
+const getMaxNumberOfConnectors = (connectors: Record<string, ConnectorStatus>): number => {
+ if (!connectors) {
+ return -1;
+ }
+ return Object.keys(connectors).length;
+};
+
+export const getBootConnectorStatus = (
+ chargingStation: ChargingStation,
+ connectorId: number,
+ connectorStatus: ConnectorStatus,
+): ConnectorStatusEnum => {
+ let connectorBootStatus: ConnectorStatusEnum;
+ if (
+ !connectorStatus?.status &&
+ (chargingStation.isChargingStationAvailable() === false ||
+ chargingStation.isConnectorAvailable(connectorId) === false)
+ ) {
+ connectorBootStatus = ConnectorStatusEnum.Unavailable;
+ } else if (!connectorStatus?.status && connectorStatus?.bootStatus) {
+ // Set boot status in template at startup
+ connectorBootStatus = connectorStatus?.bootStatus;
+ } else if (connectorStatus?.status) {
+ // Set previous status at startup
+ connectorBootStatus = connectorStatus?.status;
+ } else {
+ // Set default status
+ connectorBootStatus = ConnectorStatusEnum.Available;
+ }
+ return connectorBootStatus;
+};
+
+export const checkTemplate = (
+ stationTemplate: ChargingStationTemplate,
+ logPrefix: string,
+ templateFile: string,
+): void => {
+ if (isNullOrUndefined(stationTemplate)) {
+ const errorMsg = `Failed to read charging station template file ${templateFile}`;
+ logger.error(`${logPrefix} ${errorMsg}`);
+ throw new BaseError(errorMsg);
+ }
+ if (isEmptyObject(stationTemplate)) {
+ const errorMsg = `Empty charging station information from template file ${templateFile}`;
+ logger.error(`${logPrefix} ${errorMsg}`);
+ throw new BaseError(errorMsg);
+ }
+ if (isEmptyObject(stationTemplate.AutomaticTransactionGenerator!)) {
+ stationTemplate.AutomaticTransactionGenerator = Constants.DEFAULT_ATG_CONFIGURATION;
+ logger.warn(
+ `${logPrefix} Empty automatic transaction generator configuration from template file ${templateFile}, set to default: %j`,
+ Constants.DEFAULT_ATG_CONFIGURATION,
+ );