From 8c476a1f1117b85fa29a435fc8733a482472139f Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sat, 28 Nov 2020 20:36:03 +0100 Subject: [PATCH] Initial support for SetChargingProfile command MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Only store it at the connector level for now. Signed-off-by: Jérôme Benoit --- src/charging-station/ChargingStation.ts | 24 ++++++++++++++++++++++-- src/types/Connectors.ts | 2 ++ src/types/ocpp/1.6/RequestResponses.ts | 10 ++++++++++ src/types/ocpp/1.6/Requests.ts | 5 +++++ src/utils/Constants.ts | 5 ++++- 5 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index 6bd51d01..667c154b 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -1,11 +1,12 @@ import { AuthorizationStatus, StartTransactionRequest, StartTransactionResponse, StopTransactionReason, StopTransactionRequest, StopTransactionResponse } from '../types/ocpp/1.6/Transaction'; -import { BootNotificationResponse, ChangeConfigurationResponse, DefaultResponse, GetConfigurationResponse, HeartbeatResponse, RegistrationStatus, StatusNotificationResponse, UnlockConnectorResponse } from '../types/ocpp/1.6/RequestResponses'; +import { BootNotificationResponse, ChangeConfigurationResponse, DefaultResponse, GetConfigurationResponse, HeartbeatResponse, RegistrationStatus, SetChargingProfileResponse, StatusNotificationResponse, UnlockConnectorResponse } from '../types/ocpp/1.6/RequestResponses'; +import { ChargingProfile, ChargingProfilePurposeType } from '../types/ocpp/1.6/ChargingProfile'; import ChargingStationConfiguration, { ConfigurationKey } from '../types/ChargingStationConfiguration'; import ChargingStationTemplate, { PowerOutType } from '../types/ChargingStationTemplate'; import Connectors, { Connector } from '../types/Connectors'; import { MeterValue, MeterValueLocation, MeterValueMeasurand, MeterValuePhase, MeterValueUnit, MeterValuesRequest, MeterValuesResponse, SampledValue } from '../types/ocpp/1.6/MeterValues'; import { PerformanceObserver, performance } from 'perf_hooks'; -import Requests, { BootNotificationRequest, ChangeConfigurationRequest, GetConfigurationRequest, HeartbeatRequest, RemoteStartTransactionRequest, RemoteStopTransactionRequest, ResetRequest, StatusNotificationRequest, UnlockConnectorRequest } from '../types/ocpp/1.6/Requests'; +import Requests, { BootNotificationRequest, ChangeConfigurationRequest, GetConfigurationRequest, HeartbeatRequest, RemoteStartTransactionRequest, RemoteStopTransactionRequest, ResetRequest, SetChargingProfileRequest, StatusNotificationRequest, UnlockConnectorRequest } from '../types/ocpp/1.6/Requests'; import WebSocket, { MessageEvent } from 'ws'; import AutomaticTransactionGenerator from './AutomaticTransactionGenerator'; @@ -1369,6 +1370,25 @@ export default class ChargingStation { } } + handleRequestSetChargingProfile(commandPayload: SetChargingProfileRequest): SetChargingProfileResponse { + if (!this.getConnector(commandPayload.connectorId)) { + logger.error(`${this._logPrefix()} Trying to set a charging profile to a non existing connector Id ${commandPayload.connectorId}`); + return Constants.OCPP_CHARGING_PROFILE_RESPONSE_REJECTED; + } + if (commandPayload.csChargingProfiles.chargingProfilePurpose === ChargingProfilePurposeType.TX_PROFILE && !this.getConnector(commandPayload.connectorId)?.transactionStarted) { + return Constants.OCPP_CHARGING_PROFILE_RESPONSE_REJECTED; + } + this.getConnector(commandPayload.connectorId).chargingProfiles.forEach((chargingProfile: ChargingProfile, index: number) => { + if (chargingProfile.chargingProfileId === commandPayload.csChargingProfiles.chargingProfileId + || (chargingProfile.stackLevel === commandPayload.csChargingProfiles.stackLevel && chargingProfile.chargingProfilePurpose === commandPayload.csChargingProfiles.chargingProfilePurpose)) { + this.getConnector(commandPayload.connectorId).chargingProfiles[index] = chargingProfile; + return Constants.OCPP_CHARGING_PROFILE_RESPONSE_ACCEPTED; + } + }); + this.getConnector(commandPayload.connectorId).chargingProfiles.push(commandPayload.csChargingProfiles); + return Constants.OCPP_CHARGING_PROFILE_RESPONSE_ACCEPTED; + } + async handleRequestRemoteStartTransaction(commandPayload: RemoteStartTransactionRequest): Promise { const transactionConnectorID: number = commandPayload.connectorId ? Utils.convertToInt(commandPayload.connectorId) : 1; if (this._getAuthorizeRemoteTxRequests() && this._getLocalAuthListEnabled() && this.hasAuthorizedTags()) { diff --git a/src/types/Connectors.ts b/src/types/Connectors.ts index ac1b0a82..8063368b 100644 --- a/src/types/Connectors.ts +++ b/src/types/Connectors.ts @@ -1,4 +1,5 @@ import { ChargePointStatus } from './ocpp/1.6/ChargePointStatus'; +import { ChargingProfile } from './ocpp/1.6/ChargingProfile'; import { SampledValue } from './ocpp/1.6/MeterValues'; export interface Connector { @@ -10,6 +11,7 @@ export interface Connector { transactionSetInterval?: NodeJS.Timeout; idTag?: string; lastEnergyActiveImportRegisterValue?: number; + chargingProfiles?: ChargingProfile[] } export default interface Connectors { diff --git a/src/types/ocpp/1.6/RequestResponses.ts b/src/types/ocpp/1.6/RequestResponses.ts index e89efc34..baf66c15 100644 --- a/src/types/ocpp/1.6/RequestResponses.ts +++ b/src/types/ocpp/1.6/RequestResponses.ts @@ -53,3 +53,13 @@ export interface GetConfigurationResponse { configurationKey: ConfigurationKey[]; unknownKey: string[]; } + +export enum ChargingProfileStatus { + ACCEPTED = 'Accepted', + REJECTED = 'Rejected', + NOT_SUPPORTED = 'NotSupported', +} + +export interface SetChargingProfileResponse { + status: ChargingProfileStatus; +} diff --git a/src/types/ocpp/1.6/Requests.ts b/src/types/ocpp/1.6/Requests.ts index 4a0cda58..e8368793 100644 --- a/src/types/ocpp/1.6/Requests.ts +++ b/src/types/ocpp/1.6/Requests.ts @@ -63,3 +63,8 @@ export enum ResetType { export interface ResetRequest { type: ResetType; } + +export interface SetChargingProfileRequest { + connectorId: number; + csChargingProfiles: ChargingProfile; +} diff --git a/src/utils/Constants.ts b/src/utils/Constants.ts index 99558299..c61a3197 100644 --- a/src/utils/Constants.ts +++ b/src/utils/Constants.ts @@ -1,4 +1,4 @@ -import { ConfigurationStatus, DefaultStatus, UnlockStatus } from '../types/ocpp/1.6/RequestResponses'; +import { ChargingProfileStatus, ConfigurationStatus, DefaultStatus, UnlockStatus } from '../types/ocpp/1.6/RequestResponses'; export default class Constants { static readonly ENTITY_CHARGING_STATION = 'ChargingStation'; @@ -12,6 +12,9 @@ export default class Constants { static readonly OCPP_CONFIGURATION_RESPONSE_REJECTED = Object.freeze({ status: ConfigurationStatus.REJECTED }); static readonly OCPP_CONFIGURATION_RESPONSE_REBOOT_REQUIRED = Object.freeze({ status: ConfigurationStatus.REBOOT_REQUIRED }); static readonly OCPP_CONFIGURATION_RESPONSE_NOT_SUPPORTED = Object.freeze({ status: ConfigurationStatus.NOT_SUPPORTED }); + static readonly OCPP_CHARGING_PROFILE_RESPONSE_ACCEPTED = Object.freeze({ status: ChargingProfileStatus.ACCEPTED }); + static readonly OCPP_CHARGING_PROFILE_RESPONSE_REJECTED = Object.freeze({ status: ChargingProfileStatus.REJECTED }); + static readonly OCPP_CHARGING_PROFILE_RESPONSE_NOT_SUPPORTED = Object.freeze({ status: ChargingProfileStatus.NOT_SUPPORTED }); static readonly OCPP_RESPONSE_UNLOCKED = Object.freeze({ status: UnlockStatus.UNLOCKED }); static readonly OCPP_RESPONSE_UNLOCK_FAILED = Object.freeze({ status: UnlockStatus.UNLOCK_FAILED }); static readonly OCPP_RESPONSE_UNLOCK_NOT_SUPPORTED = Object.freeze({ status: UnlockStatus.NOT_SUPPORTED }); -- 2.34.1