Initial support for SetChargingProfile command
authorJérôme Benoit <jerome.benoit@sap.com>
Sat, 28 Nov 2020 19:36:03 +0000 (20:36 +0100)
committerJérôme Benoit <jerome.benoit@sap.com>
Sat, 28 Nov 2020 19:36:03 +0000 (20:36 +0100)
Only store it at the connector level for now.

Signed-off-by: Jérôme Benoit <jerome.benoit@sap.com>
src/charging-station/ChargingStation.ts
src/types/Connectors.ts
src/types/ocpp/1.6/RequestResponses.ts
src/types/ocpp/1.6/Requests.ts
src/utils/Constants.ts

index 6bd51d017899670b8071b4b45df6958e0b4e0cfa..667c154b35595feb376ef14dbe175bfca3aa61cd 100644 (file)
@@ -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<DefaultResponse> {
     const transactionConnectorID: number = commandPayload.connectorId ? Utils.convertToInt(commandPayload.connectorId) : 1;
     if (this._getAuthorizeRemoteTxRequests() && this._getLocalAuthListEnabled() && this.hasAuthorizedTags()) {
index ac1b0a82f6296b3d9faefecbbc81226cc50c3c8e..8063368bf0c0ff5388a803528f46ec1fdc781de4 100644 (file)
@@ -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 {
index e89efc34314677d51481258a111d998d09789d20..baf66c159a390d8ba6c095d643d82d63e618e42f 100644 (file)
@@ -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;
+}
index 4a0cda58b057dd110bd9a79ffa9593aee51bb701..e8368793e5835f56a141c9268317767f7bffffc8 100644 (file)
@@ -63,3 +63,8 @@ export enum ResetType {
 export interface ResetRequest {
   type: ResetType;
 }
+
+export interface SetChargingProfileRequest {
+  connectorId: number;
+  csChargingProfiles: ChargingProfile;
+}
index 9955829959fb47896814f4dcddd2a3c2b4839343..c61a3197480c73d8b990d2b0440919c082a06121 100644 (file)
@@ -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 });