- /**
- * Charging profiles should already be sorted by connectorId and stack level (highest stack level has priority)
- *
- * @param chargingProfiles -
- * @param logPrefix -
- * @returns
- */
- private static getLimitFromChargingProfiles(
- chargingProfiles: ChargingProfile[],
- logPrefix: string
- ): {
- limit: number;
- matchingChargingProfile: ChargingProfile;
- } | null {
- const debugLogMsg = `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Matching charging profile found for power limitation: %j`;
- for (const chargingProfile of chargingProfiles) {
- // Set helpers
- const currentMoment = moment();
- const chargingSchedule = chargingProfile.chargingSchedule;
- // Check type (recurring) and if it is already active
- // Adjust the daily recurring schedule to today
- if (
- chargingProfile.chargingProfileKind === ChargingProfileKindType.RECURRING &&
- chargingProfile.recurrencyKind === RecurrencyKindType.DAILY &&
- currentMoment.isAfter(chargingSchedule.startSchedule)
- ) {
- const currentDate = new Date();
- chargingSchedule.startSchedule = new Date(chargingSchedule.startSchedule);
- chargingSchedule.startSchedule.setFullYear(
- currentDate.getFullYear(),
- currentDate.getMonth(),
- currentDate.getDate()
- );
- // Check if the start of the schedule is yesterday
- if (moment(chargingSchedule.startSchedule).isAfter(currentMoment)) {
- chargingSchedule.startSchedule.setDate(currentDate.getDate() - 1);
- }
- } else if (moment(chargingSchedule.startSchedule).isAfter(currentMoment)) {
- return null;
- }
- // Check if the charging profile is active
- if (
- moment(chargingSchedule.startSchedule)
- .add(chargingSchedule.duration, 's')
- .isAfter(currentMoment)
- ) {
- let lastButOneSchedule: ChargingSchedulePeriod;
- // Search the right schedule period
- for (const schedulePeriod of chargingSchedule.chargingSchedulePeriod) {
- // Handling of only one period
- if (
- chargingSchedule.chargingSchedulePeriod.length === 1 &&
- schedulePeriod.startPeriod === 0
- ) {
- const result = {
- limit: schedulePeriod.limit,
- matchingChargingProfile: chargingProfile,
- };
- logger.debug(debugLogMsg, result);
- return result;
- }
- // Find the right schedule period
- if (
- moment(chargingSchedule.startSchedule)
- .add(schedulePeriod.startPeriod, 's')
- .isAfter(currentMoment)
- ) {
- // Found the schedule: last but one is the correct one
- const result = {
- limit: lastButOneSchedule.limit,
- matchingChargingProfile: chargingProfile,
- };
- logger.debug(debugLogMsg, result);
- return result;
+const 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 (isUndefined(connectorStatus.chargingProfiles)) {
+ connectorStatus.chargingProfiles = [];
+ }
+};
+
+const warnDeprecatedTemplateKey = (
+ template: ChargingStationTemplate,
+ key: string,
+ logPrefix: string,
+ templateFile: string,
+ logMsgToAppend = '',
+): void => {
+ if (!isUndefined(template[key as keyof ChargingStationTemplate])) {
+ const logMsg = `Deprecated template key '${key}' usage in file '${templateFile}'${
+ isNotEmptyString(logMsgToAppend) ? `. ${logMsgToAppend}` : ''
+ }`;
+ logger.warn(`${logPrefix} ${logMsg}`);
+ console.warn(chalk.yellow(`${logMsg}`));
+ }
+};
+
+const convertDeprecatedTemplateKey = (
+ template: ChargingStationTemplate,
+ deprecatedKey: string,
+ key?: string,
+): void => {
+ if (!isUndefined(template[deprecatedKey as keyof ChargingStationTemplate])) {
+ if (!isUndefined(key)) {
+ (template as unknown as Record<string, unknown>)[key!] =
+ template[deprecatedKey as keyof ChargingStationTemplate];
+ }
+ delete template[deprecatedKey as keyof ChargingStationTemplate];
+ }
+};
+
+interface ChargingProfilesLimit {
+ limit: number;
+ matchingChargingProfile: ChargingProfile;
+}
+
+/**
+ * Charging profiles should already be sorted by connector id and stack level (highest stack level has priority)
+ *
+ * @param chargingProfiles -
+ * @param logPrefix -
+ * @returns ChargingProfilesLimit
+ */
+const getLimitFromChargingProfiles = (
+ chargingStation: ChargingStation,
+ connectorId: number,
+ chargingProfiles: ChargingProfile[],
+ logPrefix: string,
+): ChargingProfilesLimit | undefined => {
+ const debugLogMsg = `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Matching charging profile found for power limitation: %j`;
+ const currentDate = new Date();
+ for (const chargingProfile of chargingProfiles) {
+ // Set helpers
+ const chargingSchedule = chargingProfile.chargingSchedule;
+ if (!chargingSchedule?.startSchedule) {
+ logger.warn(
+ `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: startSchedule is not defined in charging profile id ${chargingProfile.chargingProfileId}. Trying to set it to the connector transaction start date`,
+ );
+ // OCPP specifies that if startSchedule is not defined, it should be relative to start of the connector transaction
+ chargingSchedule.startSchedule =
+ chargingStation.getConnectorStatus(connectorId)?.transactionStart;
+ }
+ if (!(chargingSchedule?.startSchedule instanceof Date)) {
+ logger.warn(
+ `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: startSchedule is not a Date object in charging profile id ${chargingProfile.chargingProfileId}. Trying to convert it to a Date object`,
+ );
+ chargingSchedule.startSchedule = convertToDate(chargingSchedule.startSchedule)!;
+ }
+ // Adjust recurring start schedule
+ if (chargingProfile.chargingProfileKind === ChargingProfileKindType.RECURRING) {
+ switch (chargingProfile.recurrencyKind) {
+ case RecurrencyKindType.DAILY:
+ if (isBefore(chargingSchedule.startSchedule, startOfDay(currentDate))) {
+ addDays(
+ chargingSchedule.startSchedule,
+ differenceInDays(chargingSchedule.startSchedule, endOfDay(currentDate)),
+ );
+ if (
+ isBefore(chargingSchedule.startSchedule, startOfDay(currentDate)) ||
+ isAfter(chargingSchedule.startSchedule, endOfDay(currentDate))
+ ) {
+ logger.error(
+ `${logPrefix} ${moduleName}.getLimitFromChargingProfiles: Recurring ${
+ chargingProfile.recurrencyKind
+ } charging profile id ${
+ chargingProfile.chargingProfileId
+ } startSchedule ${chargingSchedule.startSchedule.toISOString()} is not properly translated to the current day`,
+ );
+ }