From: Jérôme Benoit Date: Wed, 23 Mar 2022 09:56:44 +0000 (+0100) Subject: Initial implementation to get the charging profiles limit X-Git-Tag: v1.1.57~34 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=cfa9539e3892495462e357f79485f0babbe85521;p=e-mobility-charging-stations-simulator.git Initial implementation to get the charging profiles limit Not used yet Signed-off-by: Jérôme Benoit --- diff --git a/README.md b/README.md index 978a2bb1..aa55b804 100644 --- a/README.md +++ b/README.md @@ -225,7 +225,7 @@ But the modifications to test have to be done to the files in the build result d **src/assets/configurations/\.json**: -The charging station configuration file is automatically generated at startup from the charging station configuration template file. +The charging station configuration file is automatically generated at startup from the charging station configuration template file and are persistent. The charging station configuration file content can be regenerated partially on matching charging station configuration template file changes. The charging station serial number is kept unchanged. diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index 507246b5..06276174 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -16,6 +16,11 @@ import { RegistrationStatus, StatusNotificationResponse, } from '../types/ocpp/Responses'; +import { + ChargingProfile, + ChargingRateUnitType, + ChargingSchedulePeriod, +} from '../types/ocpp/ChargingProfile'; import ChargingStationConfiguration, { Section } from '../types/ChargingStationConfiguration'; import ChargingStationOcppConfiguration, { ConfigurationKey, @@ -41,7 +46,6 @@ import WebSocket, { Data, OPEN, RawData } from 'ws'; import AutomaticTransactionGenerator from './AutomaticTransactionGenerator'; import { ChargePointErrorCode } from '../types/ocpp/ChargePointErrorCode'; import { ChargePointStatus } from '../types/ocpp/ChargePointStatus'; -import { ChargingProfile } from '../types/ocpp/ChargingProfile'; import ChargingStationInfo from '../types/ChargingStationInfo'; import { ChargingStationWorkerMessageEvents } from '../types/ChargingStationWorker'; import Configuration from '../utils/Configuration'; @@ -704,6 +708,56 @@ export default class ChargingStation { } } + public getChargingProfileLimit( + connectorId: number + ): { limit: number; unit: ChargingRateUnitType } | undefined { + const timestamp = new Date().getTime(); + let matchingChargingProfile: ChargingProfile; + let chargingSchedulePeriods: ChargingSchedulePeriod[] = []; + if (!Utils.isEmptyArray(this.getConnectorStatus(connectorId).chargingProfiles)) { + const chargingProfiles: ChargingProfile[] = this.getConnectorStatus( + connectorId + ).chargingProfiles.filter( + (chargingProfile) => + timestamp >= chargingProfile.chargingSchedule?.startSchedule.getTime() && + timestamp < + chargingProfile.chargingSchedule?.startSchedule.getTime() + + chargingProfile.chargingSchedule.duration && + chargingProfile?.stackLevel === Math.max(...chargingProfiles.map((cp) => cp?.stackLevel)) + ); + if (!Utils.isEmptyArray(chargingProfiles)) { + for (const chargingProfile of chargingProfiles) { + if (!Utils.isEmptyArray(chargingProfile.chargingSchedule.chargingSchedulePeriod)) { + chargingSchedulePeriods = + chargingProfile.chargingSchedule.chargingSchedulePeriod.filter( + (chargingSchedulePeriod, index) => { + timestamp >= + chargingProfile.chargingSchedule.startSchedule.getTime() + + chargingSchedulePeriod.startPeriod && + chargingProfile.chargingSchedule.chargingSchedulePeriod[index + 1] && + timestamp < + chargingProfile.chargingSchedule.startSchedule.getTime() + + chargingProfile.chargingSchedule.chargingSchedulePeriod[index + 1] + ?.startPeriod; + } + ); + if (!Utils.isEmptyArray(chargingSchedulePeriods)) { + matchingChargingProfile = chargingProfile; + break; + } + } + } + } + } + + return ( + !Utils.isEmptyArray(chargingSchedulePeriods) && { + limit: chargingSchedulePeriods[0].limit, + unit: matchingChargingProfile.chargingSchedule.chargingRateUnit, + } + ); + } + public setChargingProfile(connectorId: number, cp: ChargingProfile): void { let cpReplaced = false; if (!Utils.isEmptyArray(this.getConnectorStatus(connectorId).chargingProfiles)) { diff --git a/src/types/ocpp/1.6/ChargingProfile.ts b/src/types/ocpp/1.6/ChargingProfile.ts index 6416bf5d..e39c2137 100644 --- a/src/types/ocpp/1.6/ChargingProfile.ts +++ b/src/types/ocpp/1.6/ChargingProfile.ts @@ -15,18 +15,18 @@ export interface OCPP16ChargingProfile extends JsonType { export interface ChargingSchedule extends JsonType { duration?: number; startSchedule?: Date; - chargingRateUnit: ChargingRateUnitType; - chargingSchedulePeriod: ChargingSchedulePeriod[]; + chargingRateUnit: OCPP16ChargingRateUnitType; + chargingSchedulePeriod: OCPP16ChargingSchedulePeriod[]; minChargeRate?: number; } -export interface ChargingSchedulePeriod extends JsonType { +export interface OCPP16ChargingSchedulePeriod extends JsonType { startPeriod: number; limit: number; numberPhases?: number; } -export enum ChargingRateUnitType { +export enum OCPP16ChargingRateUnitType { WATT = 'W', AMPERE = 'A', } @@ -46,4 +46,5 @@ export enum ChargingProfilePurposeType { export enum RecurrencyKindType { DAILY = 'Daily', WEEKLY = 'Weekly', + MONTHLY = 'Monthly', } diff --git a/src/types/ocpp/ChargingProfile.ts b/src/types/ocpp/ChargingProfile.ts index 6dab7cff..d2c36d7d 100644 --- a/src/types/ocpp/ChargingProfile.ts +++ b/src/types/ocpp/ChargingProfile.ts @@ -1,3 +1,15 @@ -import { OCPP16ChargingProfile } from './1.6/ChargingProfile'; +import { + OCPP16ChargingProfile, + OCPP16ChargingRateUnitType, + OCPP16ChargingSchedulePeriod, +} from './1.6/ChargingProfile'; export type ChargingProfile = OCPP16ChargingProfile; + +export type ChargingSchedulePeriod = OCPP16ChargingSchedulePeriod; + +export type ChargingRateUnitType = OCPP16ChargingRateUnitType; + +export const ChargingRateUnitType = { + ...OCPP16ChargingRateUnitType, +};