From 12fc74d6921babe7a275788b022165b751d6a8ce Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Wed, 24 Nov 2021 12:07:04 +0100 Subject: [PATCH] Add supervision connection URL support setup through OCPP parameter MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- README.md | 2 ++ src/charging-station/ChargingStation.ts | 28 ++++++++++++++----- .../ocpp/1.6/OCPP16ResponseService.ts | 2 +- src/types/ChargingStationTemplate.ts | 2 ++ src/types/ocpp/1.6/Configuration.ts | 4 +++ src/types/ocpp/Configuration.ts | 8 +++++- 6 files changed, 37 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 695690ad..47ae68cd 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,8 @@ Key | Value(s) | Default Value | Value type | Description supervisionURL | | '' | string | connection URI to OCPP-J server supervisionUser | | '' | string | basic HTTP authentication user to OCPP-J server supervisionPassword | | '' | string | basic HTTP authentication password to OCPP-J server +supervisionURLOCPPConfiguration | | '' | boolean | Allow supervision URL configuration via a vendor OCPP parameter key +supervisionURLOCPPKey | | '' | string | The vendor string that will be used as a vendor OCPP parameter key to set the supervision URL ocppVersion | 1.6 | 1.6 | string | OCPP version ocppProtocol | json | json | string | OCPP protocol wsOptions | | {} | ClientOptions & ClientRequestArgs | [ws](https://github.com/websockets/ws) and node.js [http](https://nodejs.org/api/http.html) clients options intersection diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index 92e4a912..db385612 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -4,7 +4,7 @@ import { AvailabilityType, BootNotificationRequest, CachedRequest, IncomingReque import { BootNotificationResponse, RegistrationStatus } from '../types/ocpp/Responses'; import ChargingStationConfiguration, { ConfigurationKey } from '../types/ChargingStationConfiguration'; import ChargingStationTemplate, { CurrentType, PowerUnits, Voltage } from '../types/ChargingStationTemplate'; -import { ConnectorPhaseRotation, StandardParametersKey, SupportedFeatureProfiles } from '../types/ocpp/Configuration'; +import { ConnectorPhaseRotation, StandardParametersKey, SupportedFeatureProfiles, VendorDefaultParametersKey } from '../types/ocpp/Configuration'; import { ConnectorStatus, SampledValueTemplate } from '../types/Connectors'; import { MeterValueMeasurand, MeterValuePhase } from '../types/ocpp/MeterValues'; import { WSError, WebSocketCloseEventStatusCode } from '../types/WebSocket'; @@ -53,7 +53,7 @@ export default class ChargingStation { private connectorsConfigurationHash!: string; private ocppIncomingRequestService!: OCPPIncomingRequestService; private readonly messageBuffer: Set; - private wsConnectionUrl!: URL; + private wsConfiguredConnectionUrl!: URL; private wsConnectionRestarted: boolean; private stopped: boolean; private autoReconnectRetryCount: number; @@ -76,6 +76,10 @@ export default class ChargingStation { this.authorizedTags = this.getAuthorizedTags(); } + get wsConnectionUrl(): URL { + return this.getSupervisionURLOCPPConfiguration() ? new URL(this.getConfigurationKey(this.stationInfo.supervisionURLOCPPKey ?? VendorDefaultParametersKey.ConnectionUrl).value + '/' + this.stationInfo.chargingStationId) : this.wsConfiguredConnectionUrl; + } + public logPrefix(): string { return Utils.logPrefix(` ${this.stationInfo.chargingStationId} |`); } @@ -361,8 +365,11 @@ export default class ChargingStation { }); } - public addConfigurationKey(key: string | StandardParametersKey, value: string, readonly = false, visible = true, reboot = false): void { + public addConfigurationKey(key: string | StandardParametersKey, value: string, options: { readonly?: boolean, visible?: boolean, reboot?: boolean } = { readonly: false, visible: true, reboot: false }): void { const keyFound = this.getConfigurationKey(key); + const readonly = options.readonly; + const visible = options.visible; + const reboot = options.reboot; if (!keyFound) { this.configuration.configurationKey.push({ key, @@ -428,6 +435,10 @@ export default class ChargingStation { } } + private getSupervisionURLOCPPConfiguration(): boolean { + return this.stationInfo.supervisionURLOCPPConfiguration ?? false; + } + private getChargingStationId(stationTemplate: ChargingStationTemplate): string { // In case of multiple instances: add instance index to charging station id const instanceIndex = process.env.CF_INSTANCE_INDEX ?? 0; @@ -486,7 +497,6 @@ export default class ChargingStation { ...!Utils.isUndefined(this.stationInfo.chargeBoxSerialNumberPrefix) && { chargeBoxSerialNumber: this.stationInfo.chargeBoxSerialNumberPrefix }, ...!Utils.isUndefined(this.stationInfo.firmwareVersion) && { firmwareVersion: this.stationInfo.firmwareVersion }, }; - this.wsConnectionUrl = new URL(this.getSupervisionURL().href + '/' + this.stationInfo.chargingStationId); // Build connectors if needed const maxConnectors = this.getMaxNumberOfConnectors(); if (maxConnectors <= 0) { @@ -541,6 +551,7 @@ export default class ChargingStation { this.initializeConnectorStatus(connectorId); } } + this.wsConfiguredConnectionUrl = new URL(this.getConfiguredSupervisionURL().href + '/' + this.stationInfo.chargingStationId); switch (this.getOCPPVersion()) { case OCPPVersion.VERSION_16: this.ocppIncomingRequestService = new OCPP16IncomingRequestService(this); @@ -566,10 +577,13 @@ export default class ChargingStation { } private initOCPPParameters(): void { + if (this.getSupervisionURLOCPPConfiguration() && !this.getConfigurationKey(this.stationInfo.supervisionURLOCPPKey ?? VendorDefaultParametersKey.ConnectionUrl)) { + this.addConfigurationKey(VendorDefaultParametersKey.ConnectionUrl, this.getConfiguredSupervisionURL().href, { reboot: true }); + } if (!this.getConfigurationKey(StandardParametersKey.SupportedFeatureProfiles)) { this.addConfigurationKey(StandardParametersKey.SupportedFeatureProfiles, `${SupportedFeatureProfiles.Core},${SupportedFeatureProfiles.Local_Auth_List_Management},${SupportedFeatureProfiles.Smart_Charging}`); } - this.addConfigurationKey(StandardParametersKey.NumberOfConnectors, this.getNumberOfConnectors().toString(), true); + this.addConfigurationKey(StandardParametersKey.NumberOfConnectors, this.getNumberOfConnectors().toString(), { readonly: true }); if (!this.getConfigurationKey(StandardParametersKey.MeterValuesSampledData)) { this.addConfigurationKey(StandardParametersKey.MeterValuesSampledData, MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER); } @@ -910,8 +924,8 @@ export default class ChargingStation { } } - private getSupervisionURL(): URL { - const supervisionUrls = Utils.cloneObject(this.stationInfo.supervisionURL ? this.stationInfo.supervisionURL : Configuration.getSupervisionURLs()); + private getConfiguredSupervisionURL(): URL { + const supervisionUrls = Utils.cloneObject(this.stationInfo.supervisionURL ?? Configuration.getSupervisionURLs()); let indexUrl = 0; if (!Utils.isEmptyArray(supervisionUrls)) { if (Configuration.getDistributeStationsToTenantsEqually()) { diff --git a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts index 3e63c84a..d429e045 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts @@ -49,7 +49,7 @@ export default class OCPP16ResponseService extends OCPPResponseService { private handleResponseBootNotification(payload: OCPP16BootNotificationResponse): void { if (payload.status === OCPP16RegistrationStatus.ACCEPTED) { this.chargingStation.addConfigurationKey(OCPP16StandardParametersKey.HeartBeatInterval, payload.interval.toString()); - this.chargingStation.addConfigurationKey(OCPP16StandardParametersKey.HeartbeatInterval, payload.interval.toString(), false, false); + this.chargingStation.addConfigurationKey(OCPP16StandardParametersKey.HeartbeatInterval, payload.interval.toString(), { visible: false }); this.chargingStation.heartbeatSetInterval ? this.chargingStation.restartHeartbeat() : this.chargingStation.startHeartbeat(); } else if (payload.status === OCPP16RegistrationStatus.PENDING) { logger.info(this.chargingStation.logPrefix() + ' Charging station in pending state on the central server'); diff --git a/src/types/ChargingStationTemplate.ts b/src/types/ChargingStationTemplate.ts index 74848226..0286663b 100644 --- a/src/types/ChargingStationTemplate.ts +++ b/src/types/ChargingStationTemplate.ts @@ -36,6 +36,8 @@ export interface AutomaticTransactionGenerator { export default interface ChargingStationTemplate { supervisionURL?: string; + supervisionURLOCPPConfiguration?: boolean; + supervisionURLOCPPKey?: string; supervisionUser?: string; supervisionPassword?: string; ocppVersion?: OCPPVersion; diff --git a/src/types/ocpp/1.6/Configuration.ts b/src/types/ocpp/1.6/Configuration.ts index 315c9646..474c691f 100644 --- a/src/types/ocpp/1.6/Configuration.ts +++ b/src/types/ocpp/1.6/Configuration.ts @@ -53,3 +53,7 @@ export enum OCPP16StandardParametersKey { ConnectorSwitch3to1PhaseSupported = 'ConnectorSwitch3to1PhaseSupported', MaxChargingProfilesInstalled = 'MaxChargingProfilesInstalled' } + +export enum OCPP16VendorDefaultParametersKey { + ConnectionUrl = 'ConnectionUrl' +} diff --git a/src/types/ocpp/Configuration.ts b/src/types/ocpp/Configuration.ts index 6559f815..b55c2121 100644 --- a/src/types/ocpp/Configuration.ts +++ b/src/types/ocpp/Configuration.ts @@ -1,4 +1,4 @@ -import { OCPP16StandardParametersKey, OCPP16SupportedFeatureProfiles } from './1.6/Configuration'; +import { OCPP16StandardParametersKey, OCPP16SupportedFeatureProfiles, OCPP16VendorDefaultParametersKey } from './1.6/Configuration'; export type StandardParametersKey = OCPP16StandardParametersKey; @@ -6,6 +6,12 @@ export const StandardParametersKey = { ...OCPP16StandardParametersKey }; +export type VendorDefaultParametersKey = OCPP16VendorDefaultParametersKey; + +export const VendorDefaultParametersKey = { + ...OCPP16VendorDefaultParametersKey +}; + export type SupportedFeatureProfiles = OCPP16SupportedFeatureProfiles; export const SupportedFeatureProfiles = { -- 2.34.1