X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2FChargingStationUtils.ts;h=49a61101533043ae15cb09c6783eb197bf452cfd;hb=007b5bdeabda751743fdff8faac672b3ec57fb61;hp=1059a1d0c8b4da1215eb1184b1a25614ed32b07e;hpb=411894569d4a0333a4e38e911a178520a69448cd;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ChargingStationUtils.ts b/src/charging-station/ChargingStationUtils.ts index 1059a1d0..49a61101 100644 --- a/src/charging-station/ChargingStationUtils.ts +++ b/src/charging-station/ChargingStationUtils.ts @@ -9,6 +9,7 @@ import type { ChargingStation } from './internal'; import { BaseError } from '../exception'; import { AmpereUnits, + AvailabilityType, type BootNotificationRequest, BootReasonEnumType, type ChargingProfile, @@ -17,7 +18,9 @@ import { type ChargingSchedulePeriod, type ChargingStationInfo, type ChargingStationTemplate, + type ConnectorStatus, CurrentType, + type EvseTemplate, type OCPP16BootNotificationRequest, type OCPP20BootNotificationRequest, OCPPVersion, @@ -92,12 +95,18 @@ export class ChargingStationUtils { return true; } - public static getTemplateMaxNumberOfConnectors(stationTemplate: ChargingStationTemplate): number { - const templateConnectors = stationTemplate?.Connectors; - if (!templateConnectors) { + public static getMaxNumberOfEvses(evses: Record): number { + if (!evses) { return -1; } - return Object.keys(templateConnectors).length; + return Object.keys(evses).length; + } + + public static getMaxNumberOfConnectors(connectors: Record): number { + if (!connectors) { + return -1; + } + return Object.keys(connectors).length; } public static checkTemplateMaxConnectors( @@ -116,18 +125,28 @@ export class ChargingStationUtils { } } - public static getConfiguredNumberOfConnectors(stationTemplate: ChargingStationTemplate): number { + public static getConfiguredNumberOfConnectors(stationInfo: ChargingStationInfo): number { let configuredMaxConnectors: number; - if (Utils.isNotEmptyArray(stationTemplate.numberOfConnectors) === true) { - const numberOfConnectors = stationTemplate.numberOfConnectors as number[]; + if (Utils.isNotEmptyArray(stationInfo.numberOfConnectors) === true) { + const numberOfConnectors = stationInfo.numberOfConnectors as number[]; configuredMaxConnectors = numberOfConnectors[Math.floor(Utils.secureRandom() * numberOfConnectors.length)]; - } else if (Utils.isUndefined(stationTemplate.numberOfConnectors) === false) { - configuredMaxConnectors = stationTemplate.numberOfConnectors as number; - } else { - configuredMaxConnectors = stationTemplate?.Connectors[0] - ? ChargingStationUtils.getTemplateMaxNumberOfConnectors(stationTemplate) - 1 - : ChargingStationUtils.getTemplateMaxNumberOfConnectors(stationTemplate); + } else if (Utils.isUndefined(stationInfo.numberOfConnectors) === false) { + configuredMaxConnectors = stationInfo.numberOfConnectors as number; + } else if (stationInfo.Connectors && !stationInfo.Evses) { + configuredMaxConnectors = stationInfo?.Connectors[0] + ? ChargingStationUtils.getMaxNumberOfConnectors(stationInfo.Connectors) - 1 + : ChargingStationUtils.getMaxNumberOfConnectors(stationInfo.Connectors); + } else if (stationInfo.Evses && !stationInfo.Connectors) { + configuredMaxConnectors = 0; + for (const evse in stationInfo.Evses) { + if (evse === '0') { + continue; + } + configuredMaxConnectors += ChargingStationUtils.getMaxNumberOfConnectors( + stationInfo.Evses[evse].Connectors + ); + } } return configuredMaxConnectors; } @@ -144,6 +163,85 @@ export class ChargingStationUtils { } } + public static checkStationInfoConnectorStatus( + connectorId: number, + connectorStatus: ConnectorStatus, + logPrefix: string, + templateFile: string + ): void { + if (!Utils.isNullOrUndefined(connectorStatus?.status)) { + logger.warn( + `${logPrefix} Charging station information from template ${templateFile} with connector id ${connectorId} status configuration defined, undefine it` + ); + delete connectorStatus.status; + } + } + + public static buildConnectorsMap( + connectors: Record, + logPrefix: string, + templateFile: string + ): Map { + const connectorsMap = new Map(); + if (ChargingStationUtils.getMaxNumberOfConnectors(connectors) > 0) { + for (const connector in connectors) { + const connectorStatus = connectors[connector]; + const connectorId = Utils.convertToInt(connector); + ChargingStationUtils.checkStationInfoConnectorStatus( + connectorId, + connectorStatus, + logPrefix, + templateFile + ); + connectorsMap.set(connectorId, Utils.cloneObject(connectorStatus)); + } + } else { + logger.warn( + `${logPrefix} Charging station information from template ${templateFile} with no connectors, cannot build connectors map` + ); + } + return connectorsMap; + } + + public static initializeConnectorsMapStatus( + connectors: Map, + logPrefix: string + ): void { + for (const connectorId of connectors.keys()) { + if (connectorId > 0 && connectors.get(connectorId)?.transactionStarted === true) { + logger.warn( + `${logPrefix} Connector id ${connectorId} at initialization has a transaction started with id ${ + connectors.get(connectorId)?.transactionId + }` + ); + } + if (connectorId === 0) { + connectors.get(connectorId).availability = AvailabilityType.Operative; + if (Utils.isUndefined(connectors.get(connectorId)?.chargingProfiles)) { + connectors.get(connectorId).chargingProfiles = []; + } + } else if ( + connectorId > 0 && + Utils.isNullOrUndefined(connectors.get(connectorId)?.transactionStarted) + ) { + ChargingStationUtils.initializeConnectorStatus(connectors.get(connectorId)); + } + } + } + + public static resetConnectorStatus(connectorStatus: ConnectorStatus): void { + connectorStatus.idTagLocalAuthorized = false; + connectorStatus.idTagAuthorized = false; + connectorStatus.transactionRemoteStarted = false; + connectorStatus.transactionStarted = false; + delete connectorStatus?.localAuthorizeIdTag; + delete connectorStatus?.authorizeIdTag; + delete connectorStatus?.transactionId; + delete connectorStatus?.transactionIdTag; + connectorStatus.transactionEnergyActiveImportRegisterValue = 0; + delete connectorStatus?.transactionBeginMeterValue; + } + public static createBootNotificationRequest( stationInfo: ChargingStationInfo, bootReason: BootReasonEnumType = BootReasonEnumType.PowerUp @@ -330,17 +428,16 @@ export class ChargingStationUtils { ): number | undefined { let limit: number, matchingChargingProfile: ChargingProfile; // Get charging profiles for connector and sort by stack level - const chargingProfiles = Utils.cloneObject( - chargingStation - .getConnectorStatus(connectorId) - ?.chargingProfiles?.sort((a, b) => b.stackLevel - a.stackLevel) ?? [] - ); + const chargingProfiles = + Utils.cloneObject(chargingStation.getConnectorStatus(connectorId)?.chargingProfiles)?.sort( + (a, b) => b.stackLevel - a.stackLevel + ) ?? []; // Get profiles on connector 0 if (chargingStation.getConnectorStatus(0)?.chargingProfiles) { chargingProfiles.push( - ...chargingStation - .getConnectorStatus(0) - .chargingProfiles.sort((a, b) => b.stackLevel - a.stackLevel) + ...Utils.cloneObject(chargingStation.getConnectorStatus(0).chargingProfiles).sort( + (a, b) => b.stackLevel - a.stackLevel + ) ); } if (Utils.isNotEmptyArray(chargingProfiles)) { @@ -418,6 +515,19 @@ export class ChargingStationUtils { ); } + private static initializeConnectorStatus(connectorStatus: ConnectorStatus): void { + connectorStatus.availability = AvailabilityType.Operative; + connectorStatus.idTagLocalAuthorized = false; + connectorStatus.idTagAuthorized = false; + connectorStatus.transactionRemoteStarted = false; + connectorStatus.transactionStarted = false; + connectorStatus.energyActiveImportRegisterValue = 0; + connectorStatus.transactionEnergyActiveImportRegisterValue = 0; + if (Utils.isUndefined(connectorStatus.chargingProfiles)) { + connectorStatus.chargingProfiles = []; + } + } + private static warnDeprecatedTemplateKey( template: ChargingStationTemplate, key: string, @@ -446,7 +556,7 @@ export class ChargingStationUtils { } /** - * Charging profiles should already be sorted by connectorId and stack level (highest stack level has priority) + * Charging profiles should already be sorted by connector id and stack level (highest stack level has priority) * * @param chargingProfiles - * @param logPrefix -