Add charge point in Static Limit + Charging Plan
MODIFY
src/integration/charging-station-vendor/ChargingStationVendorIntegration.ts
src/integration/charging-station-vendor/ChargingStationVendorIntegration.ts
import { ChargingProfile, ChargingRateUnitType, ChargingSchedule } from '../../types/ChargingProfile';
-import ChargingStation, { ConnectorCurrentLimit, ConnectorCurrentLimitSource, PowerLimitUnits, StaticLimitAmps } from '../../types/ChargingStation';
+import ChargingStation, { ChargePoint, ConnectorCurrentLimit, ConnectorCurrentLimitSource, PowerLimitUnits, StaticLimitAmps } from '../../types/ChargingStation';
import { OCPPChangeConfigurationCommandResult, OCPPChargingProfileStatus, OCPPClearChargingProfileCommandResult, OCPPClearChargingProfileStatus, OCPPConfigurationStatus, OCPPGetCompositeScheduleCommandResult, OCPPGetCompositeScheduleStatus, OCPPSetChargingProfileCommandResult } from '../../types/ocpp/OCPPClient';
import BackendError from '../../exception/BackendError';
@@ -19,8 +19,8 @@ export default abstract class ChargingStationVendorIntegration {
this.chargingStation = chargingStation;
}
- public async getStaticPowerLimitation(tenantID: string, chargingStation: ChargingStation, chargePointID?: number): Promise<number> {
- const chargePoint = Utils.getChargingStationChargePointFromID(chargingStation, chargePointID);
+ public async getStaticPowerLimitation(tenantID: string, chargingStation: ChargingStation,
+ chargePoint?: ChargePoint): Promise<number> {
let ampLimitation = 0;
Logging.logDebug({
tenantID: tenantID,
@@ -35,7 +35,7 @@ export default abstract class ChargingStationVendorIntegration {
tenantID: tenantID,
source: chargingStation.id,
action: ServerAction.CHARGING_STATION_LIMIT_POWER,
- message: `Charge Point '${chargePointID}' is excluded from power limitation`,
+ message: `Charge Point '${chargePoint.chargePointID}' is excluded from power limitation`,
module: MODULE_NAME, method: 'getStaticPowerLimitation',
detailedMessages: { chargePoint }
});
@@ -46,7 +46,7 @@ export default abstract class ChargingStationVendorIntegration {
tenantID: tenantID,
source: chargingStation.id,
action: ServerAction.CHARGING_STATION_LIMIT_POWER,
- message: `No OCPP parameter provided in template for Charge Point '${chargePointID}'`,
+ message: `No OCPP parameter provided in template for Charge Point '${chargePoint.chargePointID}'`,
module: MODULE_NAME, method: 'getStaticPowerLimitation',
detailedMessages: { chargePoint }
});
@@ -58,7 +58,7 @@ export default abstract class ChargingStationVendorIntegration {
if (ocppConfiguration && ocppConfiguration.configurationKey && ocppConfiguration.configurationKey.length > 0 &&
ocppConfiguration.configurationKey[0].value) {
const connectorLimitAmps = Utils.convertToInt(ocppConfiguration.configurationKey[0].value);
- ampLimitation = this.convertFromVendorAmp(chargingStation, 0, connectorLimitAmps);
+ ampLimitation = this.convertLimitAmpToAllPhases(chargingStation, chargePoint, 0, connectorLimitAmps);
}
Logging.logDebug({
tenantID: tenantID,
@@ -72,8 +72,7 @@ export default abstract class ChargingStationVendorIntegration {
}
public async setStaticPowerLimitation(tenantID: string, chargingStation: ChargingStation,
- chargePointID?: number, maxAmps?: number): Promise<OCPPChangeConfigurationCommandResult> {
- const chargePoint = Utils.getChargingStationChargePointFromID(chargingStation, chargePointID);
+ chargePoint?: ChargePoint, maxAmps?: number): Promise<OCPPChangeConfigurationCommandResult> {
Logging.logDebug({
tenantID: tenantID,
source: chargingStation.id,
@@ -87,7 +86,7 @@ export default abstract class ChargingStationVendorIntegration {
tenantID: tenantID,
source: chargingStation.id,
action: ServerAction.CHARGING_STATION_LIMIT_POWER,
- message: `Charge Point '${chargePointID}' is excluded from power limitation`,
+ message: `Charge Point '${chargePoint.chargePointID}' is excluded from power limitation`,
module: MODULE_NAME, method: 'setStaticPowerLimitation',
detailedMessages: { chargePoint }
});
@@ -98,7 +97,7 @@ export default abstract class ChargingStationVendorIntegration {
tenantID: tenantID,
source: chargingStation.id,
action: ServerAction.CHARGING_STATION_LIMIT_POWER,
- message: `No OCPP parameter provided in template for Charge Point '${chargePointID}'`,
+ message: `No OCPP parameter provided in template for Charge Point '${chargePoint.chargePointID}'`,
module: MODULE_NAME, method: 'setStaticPowerLimitation',
detailedMessages: { chargePoint }
});
@@ -131,7 +130,7 @@ export default abstract class ChargingStationVendorIntegration {
});
}
// Fixed the max amp per connector
- const occpLimitAmpValue = this.getOCPPParamValueForChargingLimitation(chargingStation, maxAmps);
+ const occpLimitAmpValue = this.convertLimitAmpPerPhase(chargingStation, chargePoint, 0, maxAmps);
// Get the OCPP Client
const chargingStationClient = await ChargingStationClientFactory.getChargingStationClient(tenantID, chargingStation);
if (!chargingStationClient) {
@@ -171,7 +170,7 @@ export default abstract class ChargingStationVendorIntegration {
// Refresh Configuration
await OCPPUtils.requestAndSaveChargingStationOcppParameters(tenantID, chargingStation);
// Update the charger's connectors
- const limitAmpsPerConnector = Utils.getLimitAmpsPerConnector(chargingStation, maxAmps);
+ const limitAmpsPerConnector = this.chargePointToConnectorLimitAmps(chargePoint, maxAmps);
for (const connector of chargingStation.connectors) {
connector.amperageLimit = limitAmpsPerConnector;
}
@@ -201,11 +200,11 @@ export default abstract class ChargingStationVendorIntegration {
});
for (const chargePoint of chargingStation.chargePoints) {
if (ocppParamName === chargePoint.ocppParamForPowerLimitation) {
- // Update the charger
+ // Update the connector limit amps
for (const connectorID of chargePoint.connectorIDs) {
- const connector = chargingStation.connectors[connectorID];
- connector.amperageLimit = this.convertFromVendorAmp(
- chargingStation, connectorID, Utils.convertToInt(ocppParamValue));
+ const connector = Utils.getChargingStationConnectorFromID(chargingStation, connectorID);
+ connector.amperageLimit = this.convertLimitAmpToAllPhases(
+ chargingStation, chargePoint, connectorID, Utils.convertToInt(ocppParamValue));
Logging.logInfo({
tenantID: tenantID,
source: chargingStation.id,
@@ -229,7 +228,7 @@ export default abstract class ChargingStationVendorIntegration {
});
}
- public async setChargingProfile(tenantID: string, chargingStation: ChargingStation,
+ public async setChargingProfile(tenantID: string, chargingStation: ChargingStation, chargePoint: ChargePoint,
chargingProfile: ChargingProfile): Promise<OCPPSetChargingProfileCommandResult | OCPPSetChargingProfileCommandResult[]> {
Logging.logDebug({
tenantID: tenantID,
@@ -259,7 +258,8 @@ export default abstract class ChargingStationVendorIntegration {
});
}
// Convert to vendor specific profile
- const vendorSpecificChargingProfile = this.convertToVendorChargingProfile(chargingStation, chargingProfile);
+ const vendorSpecificChargingProfile = this.convertToVendorChargingProfile(
+ chargingStation, chargePoint, chargingProfile);
try {
// Check if we have to load all connectors in case connector 0 fails
if (chargingProfile.connectorID === 0) {
@@ -394,7 +394,7 @@ export default abstract class ChargingStationVendorIntegration {
}
// Reapply the current limitation
for (const chargePoint of chargingStation.chargePoints) {
- await this.setStaticPowerLimitation(tenantID, chargingStation, chargePoint.chargePointID,
+ await this.setStaticPowerLimitation(tenantID, chargingStation, chargePoint,
Utils.getChargingStationAmperageLimit(chargingStation, chargePoint));
}
Logging.logDebug({
@@ -410,7 +410,7 @@ export default abstract class ChargingStationVendorIntegration {
// Reapply the current limitation
if (result.status === OCPPClearChargingProfileStatus.ACCEPTED) {
for (const chargePoint of chargingStation.chargePoints) {
- await this.setStaticPowerLimitation(tenantID, chargingStation, chargePoint.chargePointID,
+ await this.setStaticPowerLimitation(tenantID, chargingStation, chargePoint,
Utils.getChargingStationAmperageLimit(chargingStation, chargePoint));
}
}
@@ -432,7 +432,7 @@ export default abstract class ChargingStationVendorIntegration {
// Reapply the current limitation
if (result.status === OCPPClearChargingProfileStatus.ACCEPTED) {
for (const chargePoint of chargingStation.chargePoints) {
- await this.setStaticPowerLimitation(tenantID, chargingStation, chargePoint.chargePointID,
+ await this.setStaticPowerLimitation(tenantID, chargingStation, chargePoint,
Utils.getChargingStationAmperageLimit(chargingStation, chargePoint));
}
}
@@ -458,7 +458,7 @@ export default abstract class ChargingStationVendorIntegration {
}
}
- public async getCompositeSchedule(tenantID: string, chargingStation: ChargingStation,
+ public async getCompositeSchedule(tenantID: string, chargingStation: ChargingStation, chargePoint: ChargePoint,
connectorID: number, durationSecs: number): Promise<OCPPGetCompositeScheduleCommandResult | OCPPGetCompositeScheduleCommandResult[]> {
Logging.logDebug({
tenantID: tenantID,
@@ -516,7 +516,7 @@ export default abstract class ChargingStationVendorIntegration {
});
// Convert
connectorResult.chargingSchedule = this.convertFromVendorChargingSchedule(
- chargingStation, connectorResult.connectorId, connectorResult.chargingSchedule);
+ chargingStation, chargePoint, connectorResult.connectorId, connectorResult.chargingSchedule);
results.push(connectorResult);
}
Logging.logDebug({
@@ -539,7 +539,7 @@ export default abstract class ChargingStationVendorIntegration {
});
// Convert
result.chargingSchedule = this.convertFromVendorChargingSchedule(
- chargingStation, result.connectorId, result.chargingSchedule);
+ chargingStation, chargePoint, result.connectorId, result.chargingSchedule);
return result;
}
// Connector ID > 0
@@ -559,7 +559,7 @@ export default abstract class ChargingStationVendorIntegration {
});
// Convert
result.chargingSchedule = this.convertFromVendorChargingSchedule(
- chargingStation, result.connectorId, result.chargingSchedule);
+ chargingStation, chargePoint, result.connectorId, result.chargingSchedule);
return result;
} catch (error) {
Logging.logError({
@@ -579,7 +579,7 @@ export default abstract class ChargingStationVendorIntegration {
}
}
- public async getCurrentConnectorLimit(tenantID: string, chargingStation: ChargingStation, connectorID: number): Promise<ConnectorCurrentLimit> {
+ public async getCurrentConnectorLimit(tenantID: string, chargingStation: ChargingStation, chargePoint: ChargePoint, connectorID: number): Promise<ConnectorCurrentLimit> {
Logging.logDebug({
tenantID: tenantID,
source: chargingStation.id,
@@ -605,7 +605,7 @@ export default abstract class ChargingStationVendorIntegration {
if (chargingStation.capabilities && chargingStation.capabilities.supportChargingProfiles) {
// Get the current Charging Plan
const compositeSchedule = await this.getCompositeSchedule(
- tenantID, chargingStation, connectorID, 60) as OCPPGetCompositeScheduleCommandResult;
+ tenantID, chargingStation, chargePoint, connectorID, 60) as OCPPGetCompositeScheduleCommandResult;
// Get the current connector limitation from the charging plan
// When startPeriod of first schedule is 0 meaning that the charging plan is in progress
if (compositeSchedule && compositeSchedule.chargingSchedule && compositeSchedule.chargingSchedule.chargingSchedulePeriod &&
@@ -635,8 +635,7 @@ export default abstract class ChargingStationVendorIntegration {
// Check next the static power limitation
if (chargingStation.capabilities && chargingStation.capabilities.supportStaticLimitationForChargingStation) {
// Read the static limitation
- const connector = Utils.getChargingStationChargePointFromID(chargingStation, connectorID);
- let connectorLimitAmps = await this.getStaticPowerLimitation(tenantID, chargingStation, connector.chargePointID);
+ let connectorLimitAmps = await this.getStaticPowerLimitation(tenantID, chargingStation, chargePoint);
// Check
if (connectorLimitAmps > limitDefaultMaxAmps) {
connectorLimitAmps = limitDefaultMaxAmps;
@@ -683,22 +682,8 @@ export default abstract class ChargingStationVendorIntegration {
return result;
}
- public getOCPPParamValueForChargingLimitation(chargingStation: ChargingStation, limitAmp: number): number {
- // Check at charge point level
- if (chargingStation.chargePoints) {
- for (const chargePoint of chargingStation.chargePoints) {
- if (chargePoint.excludeFromPowerLimitation) {
- continue;
- }
- if (chargePoint.cannotChargeInParallel || chargePoint.sharePowerToAllConnectors) {
- return limitAmp / Utils.getChargingStationNumberOfConnectedPhases(chargingStation);
- }
- }
- }
- return limitAmp / chargingStation.connectors.length / Utils.getChargingStationNumberOfConnectedPhases(chargingStation);
- }
-
- public convertToVendorChargingProfile(chargingStation: ChargingStation, chargingProfile: ChargingProfile): ChargingProfile {
+ public convertToVendorChargingProfile(chargingStation: ChargingStation,
+ chargePoint: ChargePoint, chargingProfile: ChargingProfile): ChargingProfile {
// Get vendor specific charging profile
const vendorSpecificChargingProfile = JSON.parse(JSON.stringify(chargingProfile));
// Check connector
@@ -712,33 +697,34 @@ export default abstract class ChargingStationVendorIntegration {
// Check Unit
if (chargingStation.powerLimitUnit === PowerLimitUnits.AMPERE) {
// Limit Amps per phase
- schedulePeriod.limit = Utils.getLimitAmpsPerConnector(chargingStation, schedulePeriod.limit) /
- Utils.getChargingStationNumberOfConnectedPhases(chargingStation, vendorSpecificChargingProfile.connectorID);
+ schedulePeriod.limit = this.convertLimitAmpPerPhase(
+ chargingStation, chargePoint,
+ vendorSpecificChargingProfile.connectorID, schedulePeriod.limit);
} else {
// Limit Watts for all the phases (Cahors)
schedulePeriod.limit = Utils.convertAmpToWatt(
chargingStation, vendorSpecificChargingProfile.connectorID,
- Utils.getLimitAmpsPerConnector(chargingStation, schedulePeriod.limit));
+ this.chargePointToConnectorLimitAmps(chargePoint, schedulePeriod.limit));
}
}
}
return vendorSpecificChargingProfile;
}
- public convertFromVendorChargingSchedule(chargingStation: ChargingStation, connectorID: number, chargingSchedule: ChargingSchedule): ChargingSchedule {
+ public convertFromVendorChargingSchedule(chargingStation: ChargingStation, chargePoint: ChargePoint, connectorID: number, chargingSchedule: ChargingSchedule): ChargingSchedule {
// Get vendor specific charging profile
if (!chargingSchedule) {
return chargingSchedule;
}
if (chargingSchedule.chargingSchedulePeriod) {
for (const chargingSchedulePeriod of chargingSchedule.chargingSchedulePeriod) {
- // Convert to Amps?
+ // Convert to Amps for all phases
if (chargingSchedule.chargingRateUnit === ChargingRateUnitType.WATT) {
chargingSchedulePeriod.limit = Utils.convertWattToAmp(chargingStation, connectorID, chargingSchedulePeriod.limit);
}
// Limit is per connector and per phase Convert to max Amp
- chargingSchedulePeriod.limit = this.convertFromVendorAmp(
- chargingStation, connectorID, chargingSchedulePeriod.limit);
+ chargingSchedulePeriod.limit = this.convertLimitAmpToAllPhases(
+ chargingStation, chargePoint, connectorID, chargingSchedulePeriod.limit);
}
}
// Convert to Amps?
@@ -748,9 +734,46 @@ export default abstract class ChargingStationVendorIntegration {
return chargingSchedule;
}
- private convertFromVendorAmp(chargingStation: ChargingStation, connectorID = 0, ampLimit: number): number {
- return ampLimit * (connectorID === 0 ? chargingStation.connectors.length : 1) *
- Utils.getChargingStationNumberOfConnectedPhases(chargingStation, connectorID);
+ private convertLimitAmpPerPhase(chargingStation: ChargingStation, chargePoint: ChargePoint, connectorID = 0, limitAmpAllPhases: number): number {
+ let limitAmpPerPhase = limitAmpAllPhases;
+ // Per charge point?
+ if (connectorID === 0) {
+ // Get Amp per connector
+ limitAmpPerPhase = this.chargePointToConnectorLimitAmps(chargePoint, limitAmpPerPhase);
+ }
+ // Per pahse
+ limitAmpPerPhase /= Utils.getChargingStationNumberOfConnectedPhases(chargingStation, chargePoint, connectorID);
+ return limitAmpPerPhase;
+ }
+
+ private convertLimitAmpToAllPhases(chargingStation: ChargingStation, chargePoint: ChargePoint, connectorID = 0, limitAmpPerPhase: number): number {
+ let limitAmpAllPhases = limitAmpPerPhase;
+ // Per charge point?
+ if (connectorID === 0) {
+ // Get Amp per connector
+ limitAmpAllPhases = this.connectorToChargePointLimitAmps(chargePoint, limitAmpAllPhases);
+ }
+ // Per pahse
+ limitAmpAllPhases *= Utils.getChargingStationNumberOfConnectedPhases(chargingStation, chargePoint, connectorID);
+ return limitAmpAllPhases;
+ }
+
+ private chargePointToConnectorLimitAmps(chargePoint: ChargePoint, limitAmp: number): number {
+ // Check at charge point level
+ if (chargePoint.cannotChargeInParallel || chargePoint.sharePowerToAllConnectors) {
+ return limitAmp;
+ }
+ // Default
+ return limitAmp / chargePoint.connectorIDs.length;
+ }
+
+ private connectorToChargePointLimitAmps(chargePoint: ChargePoint, limitAmp: number): number {
+ // Check at charge point level
+ if (chargePoint.cannotChargeInParallel || chargePoint.sharePowerToAllConnectors) {
+ return limitAmp;
+ }
+ // Default
+ return limitAmp * chargePoint.connectorIDs.length;
}
}

MODIFY
src/server/ocpp/services/OCPPService.ts
src/server/ocpp/services/OCPPService.ts
@@ -1180,14 +1180,18 @@ export default class OCPPService {
const chargingStationVendor = ChargingStationVendorFactory.getChargingStationVendorImpl(chargingStation);
if (chargingStationVendor) {
// Get current limitation
- const connectorLimit = await chargingStationVendor.getCurrentConnectorLimit(tenantID, chargingStation, transaction.connectorId);
+ const connector = Utils.getChargingStationConnectorFromID(chargingStation, transaction.connectorId);
+ const chargePoint = Utils.getChargingStationChargePointFromID(chargingStation, connector.chargePointID);
+ const connectorLimit = await chargingStationVendor.getCurrentConnectorLimit(
+ tenantID, chargingStation, chargePoint, transaction.connectorId);
consumption.limitAmps = connectorLimit.limitAmps;
consumption.limitWatts = connectorLimit.limitWatts;
consumption.limitSource = connectorLimit.limitSource;
} else {
// Default
- consumption.limitAmps = chargingStation.connectors[transaction.connectorId - 1].amperageLimit;
- consumption.limitWatts = chargingStation.connectors[transaction.connectorId - 1].power;
+ const connector = Utils.getChargingStationConnectorFromID(chargingStation, transaction.connectorId);
+ consumption.limitAmps = connector.amperageLimit;
+ consumption.limitWatts = connector.power;
consumption.limitSource = ConnectorCurrentLimitSource.CONNECTOR;
}
// Check Org

MODIFY
src/server/ocpp/utils/OCPPUtils.ts
src/server/ocpp/utils/OCPPUtils.ts
@@ -424,6 +424,8 @@ export default class OCPPUtils {
message: 'Charging Station not found',
});
}
+ // Get charge point
+ const chargePoint = Utils.getChargingStationChargePointFromID(chargingStation, chargingProfile.chargePointID);
// Get Vendor Instance
const chargingStationVendor = ChargingStationVendorFactory.getChargingStationVendorImpl(chargingStation);
if (!chargingStationVendor) {
@@ -435,7 +437,8 @@ export default class OCPPUtils {
});
}
// Set Charging Profile
- const result = await chargingStationVendor.setChargingProfile(tenantID, chargingStation, chargingProfile);
+ const result = await chargingStationVendor.setChargingProfile(
+ tenantID, chargingStation, chargePoint, chargingProfile);
// Check for Array
let resultStatus = OCPPChargingProfileStatus.ACCEPTED;
if (Array.isArray(result)) {

MODIFY
src/server/rest/service/ChargingStationService.ts
src/server/rest/service/ChargingStationService.ts
@@ -200,12 +200,13 @@ export default class ChargingStationService {
// Update Connectors
for (const filteredConnector of filteredRequest.connectors) {
// Set
- chargingStation.connectors[filteredConnector.connectorId - 1].type = filteredConnector.type;
- chargingStation.connectors[filteredConnector.connectorId - 1].power = filteredConnector.power;
- chargingStation.connectors[filteredConnector.connectorId - 1].amperage = filteredConnector.amperage;
- chargingStation.connectors[filteredConnector.connectorId - 1].voltage = filteredConnector.voltage;
- chargingStation.connectors[filteredConnector.connectorId - 1].currentType = filteredConnector.currentType;
- chargingStation.connectors[filteredConnector.connectorId - 1].numberOfConnectedPhase = filteredConnector.numberOfConnectedPhase;
+ const connector = Utils.getChargingStationConnectorFromID(chargingStation, filteredConnector.connectorId);
+ connector.type = filteredConnector.type;
+ connector.power = filteredConnector.power;
+ connector.amperage = filteredConnector.amperage;
+ connector.voltage = filteredConnector.voltage;
+ connector.currentType = filteredConnector.currentType;
+ connector.numberOfConnectedPhase = filteredConnector.numberOfConnectedPhase;
}
}
// Update timestamp
@@ -253,21 +254,13 @@ export default class ChargingStationService {
user: req.user
});
}
- // Check existence
+ // Check
const chargingStation = await ChargingStationStorage.getChargingStation(req.user.tenantID, filteredRequest.chargeBoxID);
UtilsService.assertObjectExists(action, chargingStation, `Charging Station '${filteredRequest.chargeBoxID}' doesn't exist.`,
MODULE_NAME, 'handleChargingStationLimitPower', req.user);
- // Check
- if (!Utils.getChargingStationChargePointFromID(chargingStation, filteredRequest.chargePointID)) {
- throw new AppError({
- source: filteredRequest.chargeBoxID,
- action: action,
- errorCode: HTTPError.GENERAL_ERROR,
- message: `The Charge Point ID number '${filteredRequest.chargePointID}' does not exist`,
- module: MODULE_NAME, method: 'handleChargingStationLimitPower',
- user: req.user
- });
- }
+ const chargePoint = Utils.getChargingStationChargePointFromID(chargingStation, filteredRequest.chargePointID);
+ UtilsService.assertObjectExists(action, chargePoint, `Charge Point '${filteredRequest.chargePointID}' doesn't exist.`,
+ MODULE_NAME, 'handleChargingStationLimitPower', req.user);
let siteID = null;
if (Utils.isComponentActiveFromToken(req.user, TenantComponents.ORGANIZATION)) {
// Get the Site Area
@@ -359,7 +352,7 @@ export default class ChargingStationService {
}
// Call the limitation
const result = await chargingStationVendor.setStaticPowerLimitation(req.user.tenantID, chargingStation,
- filteredRequest.chargePointID, filteredRequest.ampLimitValue);
+ chargePoint, filteredRequest.ampLimitValue);
if (result.status !== OCPPConfigurationStatus.ACCEPTED && result.status !== OCPPConfigurationStatus.REBOOT_REQUIRED) {
throw new AppError({
source: chargingStation.id,
@@ -476,8 +469,11 @@ export default class ChargingStationService {
const chargingStation = await ChargingStationStorage.getChargingStation(req.user.tenantID, filteredRequest.chargingStationID);
UtilsService.assertObjectExists(action, chargingStation, `ChargingStation '${req.body.ChargingStationID}' doesn't exist.`,
MODULE_NAME, 'handleUpdateChargingProfile', req.user);
+ const chargePoint = Utils.getChargingStationChargePointFromID(chargingStation, filteredRequest.chargePointID);
+ UtilsService.assertObjectExists(action, chargePoint, `Charge Point '${filteredRequest.chargePointID}' doesn't exist.`,
+ MODULE_NAME, 'handleUpdateChargingProfile', req.user);
// Check Mandatory fields
- Utils.checkIfChargingProfileIsValid(chargingStation, filteredRequest, req);
+ Utils.checkIfChargingProfileIsValid(chargingStation, chargePoint, filteredRequest, req);
let siteID = null;
if (Utils.isComponentActiveFromToken(req.user, TenantComponents.ORGANIZATION)) {
// Get the Site Area
@@ -1071,8 +1067,10 @@ export default class ChargingStationService {
});
}
// Get composite schedule
+ const connector = Utils.getChargingStationConnectorFromID(chargingStation, filteredRequest.args.connectorId);
+ const chargePoint = Utils.getChargingStationChargePointFromID(chargingStation, connector.chargePointID);
result = await chargingStationVendor.getCompositeSchedule(
- req.user.tenantID, chargingStation, filteredRequest.args.connectorId, filteredRequest.args.duration);
+ req.user.tenantID, chargingStation, chargePoint, filteredRequest.args.connectorId, filteredRequest.args.duration);
} else {
// Check auth
if (!Authorizations.canPerformActionOnChargingStation(req.user, command as unknown as Action, chargingStation)) {

MODIFY
src/server/rest/service/security/ChargingStationSecurity.ts
src/server/rest/service/security/ChargingStationSecurity.ts
@@ -93,6 +93,7 @@ export default class ChargingStationSecurity {
return chargePoint;
}
return {
+ chargePointID: chargePoint.chargePointID,
currentType: chargePoint.currentType,
voltage: chargePoint.voltage,
amperage: chargePoint.amperage,
@@ -100,6 +101,7 @@ export default class ChargingStationSecurity {
cannotChargeInParallel: chargePoint.cannotChargeInParallel,
sharePowerToAllConnectors: chargePoint.sharePowerToAllConnectors,
excludeFromPowerLimitation: chargePoint.excludeFromPowerLimitation,
+ ocppParamForPowerLimitation: chargePoint.ocppParamForPowerLimitation,
power: chargePoint.power,
efficiency: chargePoint.efficiency,
connectorIDs: chargePoint.connectorIDs
@@ -283,6 +285,9 @@ export default class ChargingStationSecurity {
if (Utils.objectHasProperty(request, 'connectorID')) {
filteredRequest.connectorID = sanitize(request.connectorID);
}
+ if (Utils.objectHasProperty(request, 'chargePointID')) {
+ filteredRequest.chargePointID = sanitize(request.chargePointID);
+ }
if (Utils.objectHasProperty(request, 'profile')) {
filteredRequest.profile = ChargingStationSecurity.filterChargingProfile(request.profile);
}

MODIFY
src/types/ChargingProfile.ts
src/types/ChargingProfile.ts
export interface ChargingProfile {
id?: string;
chargingStationID: string;
+ chargePointID: number;
connectorID?: number;
profile: Profile;
}

MODIFY
src/utils/Utils.ts
src/utils/Utils.ts
@@ -51,7 +51,7 @@ export default class Utils {
if (!chargingStation || !chargingStation.connectors) {
return 0;
}
- const connector = chargingStation.connectors[connectorId - 1];
+ const connector = Utils.getChargingStationConnectorFromID(chargingStation, connectorId);
if (connector.power <= 3680) {
// Notify every 120 mins
intervalMins = 120;
@@ -241,7 +241,7 @@ export default class Utils {
let lockAllConnectors = false;
// Check
for (const connectorID of chargePoint.connectorIDs) {
- const connector = chargingStation.connectors[connectorID];
+ const connector = Utils.getChargingStationConnectorFromID(chargingStation, connectorID);
if (!connector) {
continue;
}
@@ -253,7 +253,7 @@ export default class Utils {
// Lock?
if (lockAllConnectors) {
for (const connectorID of chargePoint.connectorIDs) {
- const connector = chargingStation.connectors[connectorID];
+ const connector = Utils.getChargingStationConnectorFromID(chargingStation, connectorID);
if (!connector) {
continue;
}
@@ -496,10 +496,16 @@ export default class Utils {
}
public static getChargingStationChargePointFromID(chargingStation: ChargingStation, chargePointID: number): ChargePoint {
+ if (!chargingStation.chargePoints) {
+ return null;
+ }
return chargingStation.chargePoints.find((chargePoint) => chargePoint.chargePointID === chargePointID);
}
public static getChargingStationConnectorFromID(chargingStation: ChargingStation, connectorID: number): Connector {
+ if (!chargingStation.connectors) {
+ return null;
+ }
return chargingStation.connectors.find((connector) => connector.connectorId === connectorID);
}
@@ -541,36 +547,34 @@ export default class Utils {
}
}
// Check at connector level
- if (chargingStation.connectors && chargingStation.connectors[connectorId - 1] &&
- chargingStation.connectors[connectorId - 1].power) {
- return chargingStation.connectors[connectorId - 1].power;
+ const connector = Utils.getChargingStationConnectorFromID(chargingStation, connectorId);
+ if (connector && connector.power) {
+ return connector.power;
}
}
return 0;
}
- public static getChargingStationNumberOfConnectedPhases(chargingStation: ChargingStation, connectorId = 0): number {
+ public static getChargingStationNumberOfConnectedPhases(chargingStation: ChargingStation,
+ chargePoint?: ChargePoint, connectorId = 0): number {
if (chargingStation) {
// Check at charge point level
- if (chargingStation.chargePoints) {
- for (const chargePoint of chargingStation.chargePoints) {
- // Take the first
- if (connectorId === 0 && chargePoint.numberOfConnectedPhase > 0) {
+ if (chargePoint) {
+ if (connectorId === 0 && chargePoint.numberOfConnectedPhase) {
return chargePoint.numberOfConnectedPhase;
}
- if (chargePoint.connectorIDs.includes(connectorId) && chargePoint.numberOfConnectedPhase > 0) {
+ if (chargePoint.connectorIDs.includes(connectorId) && chargePoint.numberOfConnectedPhase) {
return chargePoint.numberOfConnectedPhase;
}
}
- }
// Check at connector level
if (chargingStation.connectors) {
for (const connector of chargingStation.connectors) {
// Take the first
- if (connectorId === 0 && connector.numberOfConnectedPhase > 0) {
+ if (connectorId === 0 && connector.numberOfConnectedPhase) {
return connector.numberOfConnectedPhase;
}
- if (connector.connectorId === connectorId && connector.numberOfConnectedPhase > 0) {
+ if (connector.connectorId === connectorId && connector.numberOfConnectedPhase) {
return connector.numberOfConnectedPhase;
}
}
@@ -692,7 +696,7 @@ export default class Utils {
let amperageLimit = 0;
if (chargingStation) {
if (connectorId > 0) {
- return chargingStation.connectors[connectorId - 1].amperageLimit;
+ return Utils.getChargingStationConnectorFromID(chargingStation, connectorId).amperageLimit;
}
// Check at charge point level
if (chargingStation.chargePoints) {
@@ -702,7 +706,7 @@ export default class Utils {
}
// Add limit amp of one connector of the charge point
if (chargePoint.cannotChargeInParallel || chargePoint.sharePowerToAllConnectors) {
- return chargingStation.connectors[chargePoint.connectorIDs[0] - 1].amperageLimit;
+ return Utils.getChargingStationConnectorFromID(chargingStation, chargePoint.connectorIDs[0]).amperageLimit;
}
// Add limit amp of all connectors of the charge point
for (const connectorID of chargePoint.connectorIDs) {
@@ -716,7 +720,7 @@ export default class Utils {
if (chargePointOfCS.cannotChargeInParallel ||
chargePointOfCS.sharePowerToAllConnectors) {
// Add limit amp of one connector
- amperageLimit += chargingStation.connectors[chargePointOfCS.connectorIDs[0] - 1].amperageLimit;
+ amperageLimit += Utils.getChargingStationConnectorFromID(chargingStation, chargePointOfCS.connectorIDs[0]).amperageLimit;
} else {
// Add limit amp of all connectors
for (const connectorID of chargePointOfCS.connectorIDs) {
@@ -735,21 +739,6 @@ export default class Utils {
return amperageLimit;
}
- public static getLimitAmpsPerConnector(chargingStation: ChargingStation, limitAmp: number): number {
- // Check at charge point level
- if (chargingStation.chargePoints) {
- for (const chargePoint of chargingStation.chargePoints) {
- if (chargePoint.excludeFromPowerLimitation) {
- continue;
- }
- if (chargePoint.cannotChargeInParallel || chargePoint.sharePowerToAllConnectors) {
- return limitAmp;
- }
- }
- }
- return limitAmp / chargingStation.connectors.length;
- }
-
public static isEmptyArray(array): boolean {
if (Array.isArray(array) && array.length > 0) {
return false;
@@ -1094,7 +1083,8 @@ export default class Utils {
}
}
- public static checkIfChargingProfileIsValid(chargingStation: ChargingStation, filteredRequest: ChargingProfile, req: Request): void {
+ public static checkIfChargingProfileIsValid(chargingStation: ChargingStation, chargePoint: ChargePoint,
+ filteredRequest: ChargingProfile, req: Request): void {
if (!filteredRequest.profile) {
throw new AppError({
source: Constants.CENTRAL_SERVER,
@@ -1151,10 +1141,8 @@ export default class Utils {
});
}
// Check Max Limitation of each Schedule
- const maxAmpLimit = Utils.getChargingStationAmperageLimit(chargingStation);
- console.log('====================================');
- console.log(maxAmpLimit);
- console.log('====================================');
+ const maxAmpLimit = Utils.getChargingStationAmperageLimit(
+ chargingStation, chargePoint, filteredRequest.connectorID);
for (const chargingSchedulePeriod of filteredRequest.profile.chargingSchedule.chargingSchedulePeriod) {
// Check Min
if (chargingSchedulePeriod.limit < StaticLimitAmps.MIN_LIMIT) {

Add charge point in Static Limit + Charging Plan