Skip to content
This repository has been archived by the owner on Jun 12, 2024. It is now read-only.

Commit

Permalink
Improve charging profiles power limitation debugging
Browse files Browse the repository at this point in the history
Signed-off-by: Jérôme Benoit <jerome.benoit@piment-noir.org>
  • Loading branch information
Jérôme Benoit committed May 7, 2022
1 parent a68137e commit 0bb3ee6
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 23 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
"basic-ftp": "^4.6.6",
"chalk": "^4.1.2",
"express": "^4.18.1",
"moment": "^2.29.3",
"mongodb": "^4.5.0",
"poolifier": "^2.2.0",
"proper-lockfile": "^4.1.2",
Expand Down
1 change: 1 addition & 0 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export default {
'fs',
'@mikro-orm/core',
'@mikro-orm/reflection',
'moment',
'mongodb',
'path',
'perf_hooks',
Expand Down
85 changes: 62 additions & 23 deletions src/charging-station/ChargingStation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -740,10 +740,9 @@ export default class ChargingStation {
}

public getChargingProfilePowerLimit(connectorId: number): number | undefined {
let limit: number;
let matchingChargingProfile: ChargingProfile;
let limit: number, matchingChargingProfile: ChargingProfile;
let chargingProfiles: ChargingProfile[] = [];
// Get profiles for connector and sort by stack level
// Get charging profiles for connector and sort by stack level
chargingProfiles = this.getConnectorStatus(connectorId).chargingProfiles.sort(
(a, b) => b.stackLevel - a.stackLevel
);
Expand All @@ -754,7 +753,7 @@ export default class ChargingStation {
);
}
if (!Utils.isEmptyArray(chargingProfiles)) {
const result = this.getCurrentLimitFromOCPPProfiles(chargingProfiles);
const result = this.getCurrentLimitFromChargingProfiles(chargingProfiles);
if (!Utils.isNullOrUndefined(result)) {
limit = result.limit;
matchingChargingProfile = result.matchingChargingProfile;
Expand Down Expand Up @@ -790,8 +789,16 @@ export default class ChargingStation {
}

public setChargingProfile(connectorId: number, cp: ChargingProfile): void {
// Add support for connectorID 0
if (Utils.isNullOrUndefined(this.getConnectorStatus(connectorId).chargingProfiles)) {
logger.error(
`${this.logPrefix()} Trying to set a charging profile on connectorId ${connectorId} with an uninitialized charging profiles array attribute, applying deferred initialization`
);
this.getConnectorStatus(connectorId).chargingProfiles = [];
}
if (!Array.isArray(this.getConnectorStatus(connectorId).chargingProfiles)) {
logger.error(
`${this.logPrefix()} Trying to set a charging profile on connectorId ${connectorId} with an improper attribute type for the charging profiles array, applying proper type initialization`
);
this.getConnectorStatus(connectorId).chargingProfiles = [];
}
let cpReplaced = false;
Expand Down Expand Up @@ -2231,21 +2238,23 @@ export default class ChargingStation {
this.getConnectorStatus(connectorId).transactionEnergyActiveImportRegisterValue = 0;
}

private getCurrentLimitFromOCPPProfiles(chargingProfiles: ChargingProfile[]): {
/*
* Charging profiles should already be sorted by connectorId and stack level (highest stack level has priority)
*/
private getCurrentLimitFromChargingProfiles(chargingProfiles: ChargingProfile[]): {
limit: number;
matchingChargingProfile: ChargingProfile;
} {
} | null {
for (const chargingProfile of chargingProfiles) {
// Profiles should already be sorted by connectorID and Stack Level (highest stack level has prio)
// Set helpers
const now = moment();
const currentMoment = moment();
const chargingSchedule = chargingProfile.chargingSchedule;
// Check type (Recurring) and if it is already active
// Adjust the Daily Recurring Schedule to today
// 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 &&
now.isAfter(chargingSchedule.startSchedule)
currentMoment.isAfter(chargingSchedule.startSchedule)
) {
const currentDate = new Date();
chargingSchedule.startSchedule = new Date(chargingSchedule.startSchedule);
Expand All @@ -2255,30 +2264,52 @@ export default class ChargingStation {
currentDate.getDate()
);
// Check if the start of the schedule is yesterday
if (moment(chargingSchedule.startSchedule).isAfter(now)) {
if (moment(chargingSchedule.startSchedule).isAfter(currentMoment)) {
chargingSchedule.startSchedule.setDate(currentDate.getDate() - 1);
}
} else if (moment(chargingSchedule.startSchedule).isAfter(now)) {
} 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(now)) {
// 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
// Search the right schedule period
for (const schedulePeriod of chargingSchedule.chargingSchedulePeriod) {
// Handling of only one period
if (
chargingSchedule.chargingSchedulePeriod.length === 1 &&
schedulePeriod.startPeriod === 0
) {
return { limit: schedulePeriod.limit, matchingChargingProfile: chargingProfile };
const result = {
limit: schedulePeriod.limit,
matchingChargingProfile: chargingProfile,
};
logger.debug(
`${this.logPrefix()} Matching charging profile found for power limitation: %j`,
result
);
return result;
}
// Find the right Schedule Periods
// Find the right schedule period
if (
moment(chargingSchedule.startSchedule).add(schedulePeriod.startPeriod, 's').isAfter(now)
moment(chargingSchedule.startSchedule)
.add(schedulePeriod.startPeriod, 's')
.isAfter(currentMoment)
) {
// Found the schedule: Last but one is the correct one
return { limit: lastButOneSchedule.limit, matchingChargingProfile: chargingProfile };
// Found the schedule: last but one is the correct one
const result = {
limit: lastButOneSchedule.limit,
matchingChargingProfile: chargingProfile,
};
logger.debug(
`${this.logPrefix()} Matching charging profile found for power limitation: %j`,
result
);
return result;
}
// Keep it
lastButOneSchedule = schedulePeriod;
Expand All @@ -2289,7 +2320,15 @@ export default class ChargingStation {
chargingSchedule.chargingSchedulePeriod.length - 1
].startPeriod
) {
return { limit: lastButOneSchedule.limit, matchingChargingProfile: chargingProfile };
const result = {
limit: lastButOneSchedule.limit,
matchingChargingProfile: chargingProfile,
};
logger.debug(
`${this.logPrefix()} Matching charging profile found for power limitation: %j`,
result
);
return result;
}
}
}
Expand Down

0 comments on commit 0bb3ee6

Please sign in to comment.