Reference: https://github.com/SAP/e-mobility-charging-stations-simulator/issues/505
Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
type ErrorResponse,
ErrorType,
type EvseStatus,
+ type EvseStatusConfiguration,
FileType,
FirmwareStatus,
type FirmwareStatusNotificationRequest,
public saveOcppConfiguration(): void {
if (this.getOcppPersistentConfiguration()) {
- this.saveConfiguration();
+ this.saveConfiguration({ stationInfo: false, connectors: false, evses: false });
}
}
private saveStationInfo(): void {
if (this.getStationInfoPersistentConfiguration()) {
- this.saveConfiguration();
+ this.saveConfiguration({ ocppConfiguration: false, connectors: false, evses: false });
}
}
this.templateFile
);
this.connectors.set(connectorId, Utils.cloneObject<ConnectorStatus>(connectorStatus));
- this.getConnectorStatus(connectorId).availability = AvailabilityType.Operative;
- if (Utils.isUndefined(this.getConnectorStatus(connectorId)?.chargingProfiles)) {
- this.getConnectorStatus(connectorId).chargingProfiles = [];
- }
- ChargingStationUtils.initializeConnectorsMapStatus(this.connectors, this.logPrefix());
}
+ ChargingStationUtils.initializeConnectorsMapStatus(this.connectors, this.logPrefix());
+ this.saveConnectorsStatus();
} else {
logger.warn(
`${this.logPrefix()} Charging station information from template ${
const templateMaxEvses = ChargingStationUtils.getMaxNumberOfEvses(stationInfo?.Evses);
if (templateMaxEvses > 0) {
for (const evse in stationInfo.Evses) {
- this.evses.set(Utils.convertToInt(evse), {
+ const evseId = Utils.convertToInt(evse);
+ this.evses.set(evseId, {
connectors: ChargingStationUtils.buildConnectorsMap(
stationInfo?.Evses[evse]?.Connectors,
this.logPrefix(),
availability: AvailabilityType.Operative,
});
ChargingStationUtils.initializeConnectorsMapStatus(
- this.evses.get(Utils.convertToInt(evse))?.connectors,
+ this.evses.get(evseId)?.connectors,
this.logPrefix()
);
}
+ this.saveEvsesStatus();
} else {
logger.warn(
`${this.logPrefix()} Charging station information from template ${
return configuration;
}
- private saveConfiguration(): void {
+ private saveConnectorsStatus() {
+ if (this.getOcppPersistentConfiguration()) {
+ this.saveConfiguration({ stationInfo: false, ocppConfiguration: false, evses: false });
+ }
+ }
+
+ private saveEvsesStatus() {
+ if (this.getOcppPersistentConfiguration()) {
+ this.saveConfiguration({ stationInfo: false, ocppConfiguration: false, connectors: false });
+ }
+ }
+
+ private saveConfiguration(
+ params: {
+ stationInfo?: boolean;
+ ocppConfiguration?: boolean;
+ connectors?: boolean;
+ evses?: boolean;
+ } = { stationInfo: true, ocppConfiguration: true, connectors: true, evses: true }
+ ): void {
if (this.configurationFile) {
+ params = {
+ ...params,
+ ...{ stationInfo: true, ocppConfiguration: true, connectors: true, evses: true },
+ };
try {
if (!fs.existsSync(path.dirname(this.configurationFile))) {
fs.mkdirSync(path.dirname(this.configurationFile), { recursive: true });
}
const configurationData: ChargingStationConfiguration =
Utils.cloneObject(this.getConfigurationFromFile()) ?? {};
- this.ocppConfiguration?.configurationKey &&
- (configurationData.configurationKey = this.ocppConfiguration.configurationKey);
- this.stationInfo && (configurationData.stationInfo = this.stationInfo);
+ if (params.stationInfo && this.stationInfo) {
+ configurationData.stationInfo = this.stationInfo;
+ }
+ if (params.ocppConfiguration && this.ocppConfiguration?.configurationKey) {
+ configurationData.configurationKey = this.ocppConfiguration.configurationKey;
+ }
+ if (params.connectors && this.connectors.size > 0) {
+ configurationData.connectorsStatus = [...this.connectors.values()].map(
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ ({ transactionSetInterval, ...connectorStatusRest }) => connectorStatusRest
+ );
+ }
+ if (params.evses && this.evses.size > 0) {
+ configurationData.evsesStatus = [...this.evses.values()].map((evseStatus) => {
+ const status = {
+ ...evseStatus,
+ connectorsStatus: [...evseStatus.connectors.values()].map(
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ ({ transactionSetInterval, ...connectorStatusRest }) => connectorStatusRest
+ ),
+ };
+ delete status.connectors;
+ return status as EvseStatusConfiguration;
+ });
+ }
delete configurationData.configurationHash;
const configurationHash = crypto
.createHash(Constants.DEFAULT_HASH_ALGORITHM)
templateFile
);
connectorsMap.set(connectorId, Utils.cloneObject<ConnectorStatus>(connectorStatus));
- connectorsMap.get(connectorId).availability = AvailabilityType.Operative;
- if (Utils.isUndefined(connectorsMap.get(connectorId)?.chargingProfiles)) {
- connectorsMap.get(connectorId).chargingProfiles = [];
- }
}
} else {
logger.warn(
);
}
if (
+ connectorId === 0 &&
+ Utils.isNullOrUndefined(connectors.get(connectorId)?.transactionStarted)
+ ) {
+ 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)
) {
}
}
- public static initializeConnectorStatus(connectorStatus: ConnectorStatus): void {
- connectorStatus.idTagLocalAuthorized = false;
- connectorStatus.idTagAuthorized = false;
- connectorStatus.transactionRemoteStarted = false;
- connectorStatus.transactionStarted = false;
- connectorStatus.energyActiveImportRegisterValue = 0;
- connectorStatus.transactionEnergyActiveImportRegisterValue = 0;
- }
-
public static resetConnectorStatus(connectorStatus: ConnectorStatus): void {
connectorStatus.idTagLocalAuthorized = false;
connectorStatus.idTagAuthorized = false;
);
}
+ 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,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
({ transactionSetInterval, ...connectorStatusRest }) => connectorStatusRest
),
+ evses: [...chargingStation.evses.values()].map((evseStatus) => {
+ return {
+ ...evseStatus,
+ connectors: [...evseStatus.connectors.values()].map(
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ ({ transactionSetInterval, ...connectorStatusRest }) => connectorStatusRest
+ ),
+ };
+ }),
ocppConfiguration: chargingStation.ocppConfiguration,
wsState: chargingStation?.wsConnection?.readyState,
bootNotificationResponse: chargingStation.bootNotificationResponse,
ChargingStationAutomaticTransactionGeneratorConfiguration,
ChargingStationInfoConfiguration,
ChargingStationOcppConfiguration,
+ ConnectorStatus,
+ EvseStatus,
} from './internal';
+type ConnectorsConfiguration = {
+ connectorsStatus?: ConnectorStatus[];
+};
+
+export type EvseStatusConfiguration = Omit<EvseStatus, 'connectors'> & {
+ connectorsStatus?: ConnectorStatus[];
+};
+
+type EvsesConfiguration = {
+ evsesStatus?: EvseStatusConfiguration[];
+};
+
export type ChargingStationConfiguration = ChargingStationInfoConfiguration &
ChargingStationOcppConfiguration &
- ChargingStationAutomaticTransactionGeneratorConfiguration & {
+ ChargingStationAutomaticTransactionGeneratorConfiguration &
+ ConnectorsConfiguration &
+ EvsesConfiguration & {
configurationHash?: string;
};
ChargingStationInfo,
ChargingStationOcppConfiguration,
ConnectorStatus,
+ EvseStatus,
JsonObject,
Statistics,
} from './internal';
chargingStationWorkerOptions?: ChargingStationWorkerOptions;
}
+type EvseStatusType = Omit<EvseStatus, 'connectors'> & {
+ connectors?: ConnectorStatus[];
+};
+
export interface ChargingStationData extends WorkerData {
started: boolean;
stationInfo: ChargingStationInfo;
connectors: ConnectorStatus[];
+ evses: EvseStatusType[];
ocppConfiguration: ChargingStationOcppConfiguration;
wsState?:
| typeof WebSocket.CONNECTING
type ErrorResponse,
ErrorType,
type EvseStatus,
+ type EvseStatusConfiguration,
type EvseTemplate,
FileType,
FirmwareStatus,
"cSpell.words": [
"Avenir",
"composables",
+ "evse",
+ "evses",
"finalhandler",
"iccid",
"idtag",
import type { JsonObject } from './JsonType';
export type ChargingStationData = {
- stationInfo: ChargingStationInfo;
started: boolean;
+ stationInfo: ChargingStationInfo;
+ connectors: ConnectorStatus[];
+ evses: EvseStatus[];
wsState?:
| typeof WebSocket.CONNECTING
| typeof WebSocket.OPEN
| typeof WebSocket.CLOSING
| typeof WebSocket.CLOSED;
- bootNotificationResponse: BootNotificationResponse;
- connectors: ConnectorStatus[];
- automaticTransactionGeneratorStatuses?: Status[];
+ bootNotificationResponse?: BootNotificationResponse;
+ automaticTransactionGenerator?: Status[];
};
export type ChargingStationInfo = {
transactionEnergyActiveImportRegisterValue?: number; // In Wh
};
+export type EvseStatus = {
+ availability: AvailabilityType;
+ connectors?: ConnectorStatus[];
+};
+
export type AvailabilityType = OCPP16AvailabilityType;
export enum OCPP16AvailabilityType {