From ed3d28080b6597ba2f728d625e34ce05aea49d06 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Benoit?= Date: Sun, 2 Oct 2022 07:36:54 +0200 Subject: [PATCH] Cleanup shared helpers structure MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Jérôme Benoit --- src/charging-station/ChargingStationUtils.ts | 167 +----------------- .../ocpp/1.6/OCPP16IncomingRequestService.ts | 6 +- .../ocpp/1.6/OCPP16RequestService.ts | 2 +- .../ocpp/1.6/OCPP16ResponseService.ts | 2 +- .../ocpp/1.6/OCPP16ServiceUtils.ts | 152 ++++++++++++++-- src/charging-station/ocpp/OCPPServiceUtils.ts | 43 +++++ .../ui-server/UIHttpServer.ts | 4 +- .../ui-server/UIServerFactory.ts | 4 +- .../UIServiceUtils.ts => UIServerUtils.ts} | 12 +- .../ui-server/UIWebSocketServer.ts | 8 +- 10 files changed, 199 insertions(+), 201 deletions(-) rename src/charging-station/ui-server/{ui-services/UIServiceUtils.ts => UIServerUtils.ts} (82%) diff --git a/src/charging-station/ChargingStationUtils.ts b/src/charging-station/ChargingStationUtils.ts index e378fdec..1670fb00 100644 --- a/src/charging-station/ChargingStationUtils.ts +++ b/src/charging-station/ChargingStationUtils.ts @@ -12,23 +12,14 @@ import { CurrentType, Voltage, } from '../types/ChargingStationTemplate'; -import type { SampledValueTemplate } from '../types/MeasurandPerPhaseSampledValueTemplates'; import { ChargingProfileKindType, RecurrencyKindType } from '../types/ocpp/1.6/ChargingProfile'; import type { ChargingProfile, ChargingSchedulePeriod } from '../types/ocpp/ChargingProfile'; -import { StandardParametersKey } from '../types/ocpp/Configuration'; -import { MeterValueMeasurand, MeterValuePhase } from '../types/ocpp/MeterValues'; -import { - type BootNotificationRequest, - IncomingRequestCommand, - RequestCommand, -} from '../types/ocpp/Requests'; +import type { BootNotificationRequest } from '../types/ocpp/Requests'; import { WorkerProcessType } from '../types/Worker'; import Configuration from '../utils/Configuration'; import Constants from '../utils/Constants'; import logger from '../utils/Logger'; import Utils from '../utils/Utils'; -import type ChargingStation from './ChargingStation'; -import { ChargingStationConfigurationUtils } from './ChargingStationConfigurationUtils'; const moduleName = 'ChargingStationUtils'; @@ -289,41 +280,6 @@ export class ChargingStationUtils { return unitDivider; } - public static setChargingProfile( - chargingStation: ChargingStation, - connectorId: number, - cp: ChargingProfile - ): void { - if (Utils.isNullOrUndefined(chargingStation.getConnectorStatus(connectorId).chargingProfiles)) { - logger.error( - `${chargingStation.logPrefix()} Trying to set a charging profile on connectorId ${connectorId} with an uninitialized charging profiles array attribute, applying deferred initialization` - ); - chargingStation.getConnectorStatus(connectorId).chargingProfiles = []; - } - if (Array.isArray(chargingStation.getConnectorStatus(connectorId).chargingProfiles) === false) { - logger.error( - `${chargingStation.logPrefix()} Trying to set a charging profile on connectorId ${connectorId} with an improper attribute type for the charging profiles array, applying proper type initialization` - ); - chargingStation.getConnectorStatus(connectorId).chargingProfiles = []; - } - let cpReplaced = false; - if (!Utils.isEmptyArray(chargingStation.getConnectorStatus(connectorId).chargingProfiles)) { - chargingStation - .getConnectorStatus(connectorId) - .chargingProfiles?.forEach((chargingProfile: ChargingProfile, index: number) => { - if ( - chargingProfile.chargingProfileId === cp.chargingProfileId || - (chargingProfile.stackLevel === cp.stackLevel && - chargingProfile.chargingProfilePurpose === cp.chargingProfilePurpose) - ) { - chargingStation.getConnectorStatus(connectorId).chargingProfiles[index] = cp; - cpReplaced = true; - } - }); - } - !cpReplaced && chargingStation.getConnectorStatus(connectorId).chargingProfiles?.push(cp); - } - /** * Charging profiles should already be sorted by connectorId and stack level (highest stack level has priority) * @@ -442,87 +398,6 @@ export class ChargingStationUtils { return defaultVoltageOut; } - public static getSampledValueTemplate( - chargingStation: ChargingStation, - connectorId: number, - measurand: MeterValueMeasurand = MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER, - phase?: MeterValuePhase - ): SampledValueTemplate | undefined { - const onPhaseStr = phase ? `on phase ${phase} ` : ''; - if (Constants.SUPPORTED_MEASURANDS.includes(measurand) === false) { - logger.warn( - `${chargingStation.logPrefix()} Trying to get unsupported MeterValues measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId}` - ); - return; - } - if ( - measurand !== MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER && - !ChargingStationConfigurationUtils.getConfigurationKey( - chargingStation, - StandardParametersKey.MeterValuesSampledData - )?.value.includes(measurand) - ) { - logger.debug( - `${chargingStation.logPrefix()} Trying to get MeterValues measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId} not found in '${ - StandardParametersKey.MeterValuesSampledData - }' OCPP parameter` - ); - return; - } - const sampledValueTemplates: SampledValueTemplate[] = - chargingStation.getConnectorStatus(connectorId).MeterValues; - for ( - let index = 0; - !Utils.isEmptyArray(sampledValueTemplates) && index < sampledValueTemplates.length; - index++ - ) { - if ( - Constants.SUPPORTED_MEASURANDS.includes( - sampledValueTemplates[index]?.measurand ?? - MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER - ) === false - ) { - logger.warn( - `${chargingStation.logPrefix()} Unsupported MeterValues measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId}` - ); - } else if ( - phase && - sampledValueTemplates[index]?.phase === phase && - sampledValueTemplates[index]?.measurand === measurand && - ChargingStationConfigurationUtils.getConfigurationKey( - chargingStation, - StandardParametersKey.MeterValuesSampledData - )?.value.includes(measurand) === true - ) { - return sampledValueTemplates[index]; - } else if ( - !phase && - !sampledValueTemplates[index].phase && - sampledValueTemplates[index]?.measurand === measurand && - ChargingStationConfigurationUtils.getConfigurationKey( - chargingStation, - StandardParametersKey.MeterValuesSampledData - )?.value.includes(measurand) === true - ) { - return sampledValueTemplates[index]; - } else if ( - measurand === MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER && - (!sampledValueTemplates[index].measurand || - sampledValueTemplates[index].measurand === measurand) - ) { - return sampledValueTemplates[index]; - } - } - if (measurand === MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER) { - const errorMsg = `Missing MeterValues for default measurand '${measurand}' in template on connectorId ${connectorId}`; - logger.error(`${chargingStation.logPrefix()} ${errorMsg}`); - throw new BaseError(errorMsg); - } - logger.debug( - `${chargingStation.logPrefix()} No MeterValues for measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId}` - ); - } - public static getAuthorizationFile(stationInfo: ChargingStationInfo): string | undefined { return ( stationInfo.authorizationFile && @@ -534,46 +409,6 @@ export class ChargingStationUtils { ); } - public static isRequestCommandSupported( - command: RequestCommand, - chargingStation: ChargingStation - ): boolean { - const isRequestCommand = Object.values(RequestCommand).includes(command); - if ( - isRequestCommand === true && - !chargingStation.stationInfo?.commandsSupport?.outgoingCommands - ) { - return true; - } else if ( - isRequestCommand === true && - chargingStation.stationInfo?.commandsSupport?.outgoingCommands - ) { - return chargingStation.stationInfo?.commandsSupport?.outgoingCommands[command] ?? false; - } - logger.error(`${chargingStation.logPrefix()} Unknown outgoing OCPP command '${command}'`); - return false; - } - - public static isIncomingRequestCommandSupported( - command: IncomingRequestCommand, - chargingStation: ChargingStation - ): boolean { - const isIncomingRequestCommand = Object.values(IncomingRequestCommand).includes(command); - if ( - isIncomingRequestCommand === true && - !chargingStation.stationInfo?.commandsSupport?.incomingCommands - ) { - return true; - } else if ( - isIncomingRequestCommand === true && - chargingStation.stationInfo?.commandsSupport?.incomingCommands - ) { - return chargingStation.stationInfo?.commandsSupport?.incomingCommands[command] ?? false; - } - logger.error(`${chargingStation.logPrefix()} Unknown incoming OCPP command '${command}'`); - return false; - } - private static getRandomSerialNumberSuffix(params?: { randomBytesLength?: number; upperCase?: boolean; diff --git a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts index 7c449ca5..0597e5ce 100644 --- a/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16IncomingRequestService.ts @@ -303,7 +303,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer ) { if ( this.incomingRequestHandlers.has(commandName) && - ChargingStationUtils.isIncomingRequestCommandSupported(commandName, chargingStation) + OCPP16ServiceUtils.isIncomingRequestCommandSupported(commandName, chargingStation) ) { try { this.validatePayload(chargingStation, commandName, commandPayload); @@ -569,7 +569,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer ) { return Constants.OCPP_SET_CHARGING_PROFILE_RESPONSE_REJECTED; } - ChargingStationUtils.setChargingProfile( + OCPP16ServiceUtils.setChargingProfile( chargingStation, commandPayload.connectorId, commandPayload.csChargingProfiles @@ -912,7 +912,7 @@ export default class OCPP16IncomingRequestService extends OCPPIncomingRequestSer cp: OCPP16ChargingProfile ): boolean { if (cp && cp.chargingProfilePurpose === ChargingProfilePurposeType.TX_PROFILE) { - ChargingStationUtils.setChargingProfile(chargingStation, connectorId, cp); + OCPP16ServiceUtils.setChargingProfile(chargingStation, connectorId, cp); logger.debug( `${chargingStation.logPrefix()} Charging profile(s) set at remote start transaction on connector id ${connectorId}, dump their stack: %j`, chargingStation.getConnectorStatus(connectorId).chargingProfiles diff --git a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts index e0628496..d840e5e9 100644 --- a/src/charging-station/ocpp/1.6/OCPP16RequestService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16RequestService.ts @@ -150,7 +150,7 @@ export default class OCPP16RequestService extends OCPPRequestService { commandParams?: JsonType, params?: RequestParams ): Promise { - if (ChargingStationUtils.isRequestCommandSupported(commandName, chargingStation)) { + if (OCPP16ServiceUtils.isRequestCommandSupported(commandName, chargingStation)) { const requestPayload = this.buildRequestPayload( chargingStation, commandName, diff --git a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts index 8f8d0bae..041122c5 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ResponseService.ts @@ -178,7 +178,7 @@ export default class OCPP16ResponseService extends OCPPResponseService { if (chargingStation.isRegistered() || commandName === OCPP16RequestCommand.BOOT_NOTIFICATION) { if ( this.responseHandlers.has(commandName) && - ChargingStationUtils.isRequestCommandSupported(commandName, chargingStation) + OCPP16ServiceUtils.isRequestCommandSupported(commandName, chargingStation) ) { try { this.validatePayload(chargingStation, commandName, payload); diff --git a/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts b/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts index f5c4df73..2dc498e8 100644 --- a/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts +++ b/src/charging-station/ocpp/1.6/OCPP16ServiceUtils.ts @@ -1,5 +1,6 @@ // Partial Copyright Jerome Benoit. 2021. All Rights Reserved. +import BaseError from '../../../exception/BaseError'; import OCPPError from '../../../exception/OCPPError'; import { CurrentType, Voltage } from '../../../types/ChargingStationTemplate'; import type { @@ -24,13 +25,16 @@ import { OCPP16IncomingRequestCommand, OCPP16RequestCommand, } from '../../../types/ocpp/1.6/Requests'; +import type { ChargingProfile } from '../../../types/ocpp/ChargingProfile'; +import { StandardParametersKey } from '../../../types/ocpp/Configuration'; import { ErrorType } from '../../../types/ocpp/ErrorType'; +import { MeterValueMeasurand, type MeterValuePhase } from '../../../types/ocpp/MeterValues'; import Constants from '../../../utils/Constants'; import { ACElectricUtils, DCElectricUtils } from '../../../utils/ElectricUtils'; import logger from '../../../utils/Logger'; import Utils from '../../../utils/Utils'; import type ChargingStation from '../../ChargingStation'; -import { ChargingStationUtils } from '../../ChargingStationUtils'; +import { ChargingStationConfigurationUtils } from '../../ChargingStationConfigurationUtils'; import { OCPPServiceUtils } from '../OCPPServiceUtils'; export class OCPP16ServiceUtils extends OCPPServiceUtils { @@ -63,7 +67,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { }; const connector = chargingStation.getConnectorStatus(connectorId); // SoC measurand - const socSampledValueTemplate = ChargingStationUtils.getSampledValueTemplate( + const socSampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.STATE_OF_CHARGE @@ -91,7 +95,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { } } // Voltage measurand - const voltageSampledValueTemplate = ChargingStationUtils.getSampledValueTemplate( + const voltageSampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.VOLTAGE @@ -121,7 +125,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { ) { const phaseLineToNeutralValue = `L${phase}-N`; const voltagePhaseLineToNeutralSampledValueTemplate = - ChargingStationUtils.getSampledValueTemplate( + OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.VOLTAGE, @@ -156,7 +160,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { : chargingStation.getNumberOfPhases() }`; const voltagePhaseLineToLineSampledValueTemplate = - ChargingStationUtils.getSampledValueTemplate( + OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.VOLTAGE, @@ -192,7 +196,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { } } // Power.Active.Import measurand - const powerSampledValueTemplate = ChargingStationUtils.getSampledValueTemplate( + const powerSampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT @@ -200,19 +204,19 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { let powerPerPhaseSampledValueTemplates: MeasurandPerPhaseSampledValueTemplates = {}; if (chargingStation.getNumberOfPhases() === 3) { powerPerPhaseSampledValueTemplates = { - L1: ChargingStationUtils.getSampledValueTemplate( + L1: OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT, OCPP16MeterValuePhase.L1_N ), - L2: ChargingStationUtils.getSampledValueTemplate( + L2: OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT, OCPP16MeterValuePhase.L2_N ), - L3: ChargingStationUtils.getSampledValueTemplate( + L3: OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT, @@ -399,7 +403,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { } } // Current.Import measurand - const currentSampledValueTemplate = ChargingStationUtils.getSampledValueTemplate( + const currentSampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.CURRENT_IMPORT @@ -407,19 +411,19 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { let currentPerPhaseSampledValueTemplates: MeasurandPerPhaseSampledValueTemplates = {}; if (chargingStation.getNumberOfPhases() === 3) { currentPerPhaseSampledValueTemplates = { - L1: ChargingStationUtils.getSampledValueTemplate( + L1: OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.CURRENT_IMPORT, OCPP16MeterValuePhase.L1 ), - L2: ChargingStationUtils.getSampledValueTemplate( + L2: OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.CURRENT_IMPORT, OCPP16MeterValuePhase.L2 ), - L3: ChargingStationUtils.getSampledValueTemplate( + L3: OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId, OCPP16MeterValueMeasurand.CURRENT_IMPORT, @@ -607,7 +611,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { } } // Energy.Active.Import.Register measurand (default) - const energySampledValueTemplate = ChargingStationUtils.getSampledValueTemplate( + const energySampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId ); @@ -690,7 +694,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { sampledValue: [], }; // Energy.Active.Import.Register measurand (default) - const sampledValueTemplate = ChargingStationUtils.getSampledValueTemplate( + const sampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId ); @@ -715,7 +719,7 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { sampledValue: [], }; // Energy.Active.Import.Register measurand (default) - const sampledValueTemplate = ChargingStationUtils.getSampledValueTemplate( + const sampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate( chargingStation, connectorId ); @@ -740,6 +744,122 @@ export class OCPP16ServiceUtils extends OCPPServiceUtils { return meterValues; } + public static setChargingProfile( + chargingStation: ChargingStation, + connectorId: number, + cp: ChargingProfile + ): void { + if (Utils.isNullOrUndefined(chargingStation.getConnectorStatus(connectorId).chargingProfiles)) { + logger.error( + `${chargingStation.logPrefix()} Trying to set a charging profile on connectorId ${connectorId} with an uninitialized charging profiles array attribute, applying deferred initialization` + ); + chargingStation.getConnectorStatus(connectorId).chargingProfiles = []; + } + if (Array.isArray(chargingStation.getConnectorStatus(connectorId).chargingProfiles) === false) { + logger.error( + `${chargingStation.logPrefix()} Trying to set a charging profile on connectorId ${connectorId} with an improper attribute type for the charging profiles array, applying proper type initialization` + ); + chargingStation.getConnectorStatus(connectorId).chargingProfiles = []; + } + let cpReplaced = false; + if (!Utils.isEmptyArray(chargingStation.getConnectorStatus(connectorId).chargingProfiles)) { + chargingStation + .getConnectorStatus(connectorId) + .chargingProfiles?.forEach((chargingProfile: ChargingProfile, index: number) => { + if ( + chargingProfile.chargingProfileId === cp.chargingProfileId || + (chargingProfile.stackLevel === cp.stackLevel && + chargingProfile.chargingProfilePurpose === cp.chargingProfilePurpose) + ) { + chargingStation.getConnectorStatus(connectorId).chargingProfiles[index] = cp; + cpReplaced = true; + } + }); + } + !cpReplaced && chargingStation.getConnectorStatus(connectorId).chargingProfiles?.push(cp); + } + + private static getSampledValueTemplate( + chargingStation: ChargingStation, + connectorId: number, + measurand: MeterValueMeasurand = MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER, + phase?: MeterValuePhase + ): SampledValueTemplate | undefined { + const onPhaseStr = phase ? `on phase ${phase} ` : ''; + if (Constants.SUPPORTED_MEASURANDS.includes(measurand) === false) { + logger.warn( + `${chargingStation.logPrefix()} Trying to get unsupported MeterValues measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId}` + ); + return; + } + if ( + measurand !== MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER && + !ChargingStationConfigurationUtils.getConfigurationKey( + chargingStation, + StandardParametersKey.MeterValuesSampledData + )?.value.includes(measurand) + ) { + logger.debug( + `${chargingStation.logPrefix()} Trying to get MeterValues measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId} not found in '${ + StandardParametersKey.MeterValuesSampledData + }' OCPP parameter` + ); + return; + } + const sampledValueTemplates: SampledValueTemplate[] = + chargingStation.getConnectorStatus(connectorId).MeterValues; + for ( + let index = 0; + !Utils.isEmptyArray(sampledValueTemplates) && index < sampledValueTemplates.length; + index++ + ) { + if ( + Constants.SUPPORTED_MEASURANDS.includes( + sampledValueTemplates[index]?.measurand ?? + MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER + ) === false + ) { + logger.warn( + `${chargingStation.logPrefix()} Unsupported MeterValues measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId}` + ); + } else if ( + phase && + sampledValueTemplates[index]?.phase === phase && + sampledValueTemplates[index]?.measurand === measurand && + ChargingStationConfigurationUtils.getConfigurationKey( + chargingStation, + StandardParametersKey.MeterValuesSampledData + )?.value.includes(measurand) === true + ) { + return sampledValueTemplates[index]; + } else if ( + !phase && + !sampledValueTemplates[index].phase && + sampledValueTemplates[index]?.measurand === measurand && + ChargingStationConfigurationUtils.getConfigurationKey( + chargingStation, + StandardParametersKey.MeterValuesSampledData + )?.value.includes(measurand) === true + ) { + return sampledValueTemplates[index]; + } else if ( + measurand === MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER && + (!sampledValueTemplates[index].measurand || + sampledValueTemplates[index].measurand === measurand) + ) { + return sampledValueTemplates[index]; + } + } + if (measurand === MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER) { + const errorMsg = `Missing MeterValues for default measurand '${measurand}' in template on connectorId ${connectorId}`; + logger.error(`${chargingStation.logPrefix()} ${errorMsg}`); + throw new BaseError(errorMsg); + } + logger.debug( + `${chargingStation.logPrefix()} No MeterValues for measurand '${measurand}' ${onPhaseStr}in template on connectorId ${connectorId}` + ); + } + private static buildSampledValue( sampledValueTemplate: SampledValueTemplate, value: number, diff --git a/src/charging-station/ocpp/OCPPServiceUtils.ts b/src/charging-station/ocpp/OCPPServiceUtils.ts index 96b34218..dcf3a999 100644 --- a/src/charging-station/ocpp/OCPPServiceUtils.ts +++ b/src/charging-station/ocpp/OCPPServiceUtils.ts @@ -1,6 +1,9 @@ import type { DefinedError, ErrorObject } from 'ajv'; import { ErrorType } from '../../types/ocpp/ErrorType'; +import { IncomingRequestCommand, RequestCommand } from '../../types/ocpp/Requests'; +import logger from '../../utils/Logger'; +import type ChargingStation from '../ChargingStation'; export class OCPPServiceUtils { protected constructor() { @@ -23,6 +26,46 @@ export class OCPPServiceUtils { return ErrorType.FORMAT_VIOLATION; } + public static isRequestCommandSupported( + command: RequestCommand, + chargingStation: ChargingStation + ): boolean { + const isRequestCommand = Object.values(RequestCommand).includes(command); + if ( + isRequestCommand === true && + !chargingStation.stationInfo?.commandsSupport?.outgoingCommands + ) { + return true; + } else if ( + isRequestCommand === true && + chargingStation.stationInfo?.commandsSupport?.outgoingCommands + ) { + return chargingStation.stationInfo?.commandsSupport?.outgoingCommands[command] ?? false; + } + logger.error(`${chargingStation.logPrefix()} Unknown outgoing OCPP command '${command}'`); + return false; + } + + public static isIncomingRequestCommandSupported( + command: IncomingRequestCommand, + chargingStation: ChargingStation + ): boolean { + const isIncomingRequestCommand = Object.values(IncomingRequestCommand).includes(command); + if ( + isIncomingRequestCommand === true && + !chargingStation.stationInfo?.commandsSupport?.incomingCommands + ) { + return true; + } else if ( + isIncomingRequestCommand === true && + chargingStation.stationInfo?.commandsSupport?.incomingCommands + ) { + return chargingStation.stationInfo?.commandsSupport?.incomingCommands[command] ?? false; + } + logger.error(`${chargingStation.logPrefix()} Unknown incoming OCPP command '${command}'`); + return false; + } + protected static getLimitFromSampledValueTemplateCustomValue( value: string, limit: number, diff --git a/src/charging-station/ui-server/UIHttpServer.ts b/src/charging-station/ui-server/UIHttpServer.ts index 7b777b86..223c5bbb 100644 --- a/src/charging-station/ui-server/UIHttpServer.ts +++ b/src/charging-station/ui-server/UIHttpServer.ts @@ -16,7 +16,7 @@ import { import logger from '../../utils/Logger'; import Utils from '../../utils/Utils'; import { AbstractUIServer } from './AbstractUIServer'; -import { UIServiceUtils } from './ui-services/UIServiceUtils'; +import { UIServerUtils } from './UIServerUtils'; const moduleName = 'UIHttpServer'; @@ -90,7 +90,7 @@ export default class UIHttpServer extends AbstractUIServer { this.responseHandlers.set(uuid, res); try { const fullProtocol = `${protocol}${version}`; - if (UIServiceUtils.isProtocolAndVersionSupported(fullProtocol) === false) { + if (UIServerUtils.isProtocolAndVersionSupported(fullProtocol) === false) { throw new BaseError(`Unsupported UI protocol version: '${fullProtocol}'`); } this.registerProtocolVersionUIService(version); diff --git a/src/charging-station/ui-server/UIServerFactory.ts b/src/charging-station/ui-server/UIServerFactory.ts index e7b341d1..2a125af0 100644 --- a/src/charging-station/ui-server/UIServerFactory.ts +++ b/src/charging-station/ui-server/UIServerFactory.ts @@ -4,8 +4,8 @@ import type { UIServerConfiguration } from '../../types/ConfigurationData'; import { ApplicationProtocol } from '../../types/UIProtocol'; import Configuration from '../../utils/Configuration'; import type { AbstractUIServer } from './AbstractUIServer'; -import { UIServiceUtils } from './ui-services/UIServiceUtils'; import UIHttpServer from './UIHttpServer'; +import { UIServerUtils } from './UIServerUtils'; import UIWebSocketServer from './UIWebSocketServer'; export default class UIServerFactory { @@ -16,7 +16,7 @@ export default class UIServerFactory { public static getUIServerImplementation( uiServerConfiguration?: UIServerConfiguration ): AbstractUIServer | null { - if (UIServiceUtils.isLoopback(uiServerConfiguration.options?.host) === false) { + if (UIServerUtils.isLoopback(uiServerConfiguration.options?.host) === false) { console.warn( chalk.yellow( 'Loopback address not detected in UI server configuration. This is not recommended.' diff --git a/src/charging-station/ui-server/ui-services/UIServiceUtils.ts b/src/charging-station/ui-server/UIServerUtils.ts similarity index 82% rename from src/charging-station/ui-server/ui-services/UIServiceUtils.ts rename to src/charging-station/ui-server/UIServerUtils.ts index b6137886..fc37ddc6 100644 --- a/src/charging-station/ui-server/ui-services/UIServiceUtils.ts +++ b/src/charging-station/ui-server/UIServerUtils.ts @@ -1,10 +1,10 @@ import type { IncomingMessage } from 'http'; -import { Protocol, ProtocolVersion } from '../../../types/UIProtocol'; -import logger from '../../../utils/Logger'; -import Utils from '../../../utils/Utils'; +import { Protocol, ProtocolVersion } from '../../types/UIProtocol'; +import logger from '../../utils/Logger'; +import Utils from '../../utils/Utils'; -export class UIServiceUtils { +export class UIServerUtils { private constructor() { // This is intentional } @@ -20,7 +20,7 @@ export class UIServiceUtils { return false; } for (const fullProtocol of protocols) { - if (UIServiceUtils.isProtocolAndVersionSupported(fullProtocol) === true) { + if (UIServerUtils.isProtocolAndVersionSupported(fullProtocol) === true) { return fullProtocol; } } @@ -33,7 +33,7 @@ export class UIServiceUtils { }; public static isProtocolAndVersionSupported = (protocolStr: string): boolean => { - const [protocol, version] = UIServiceUtils.getProtocolAndVersion(protocolStr); + const [protocol, version] = UIServerUtils.getProtocolAndVersion(protocolStr); return ( Object.values(Protocol).includes(protocol) === true && Object.values(ProtocolVersion).includes(version) === true diff --git a/src/charging-station/ui-server/UIWebSocketServer.ts b/src/charging-station/ui-server/UIWebSocketServer.ts index 4ac5d235..cf1bfa65 100644 --- a/src/charging-station/ui-server/UIWebSocketServer.ts +++ b/src/charging-station/ui-server/UIWebSocketServer.ts @@ -11,7 +11,7 @@ import { WebSocketCloseEventStatusCode } from '../../types/WebSocket'; import logger from '../../utils/Logger'; import Utils from '../../utils/Utils'; import { AbstractUIServer } from './AbstractUIServer'; -import { UIServiceUtils } from './ui-services/UIServiceUtils'; +import { UIServerUtils } from './UIServerUtils'; const moduleName = 'UIWebSocketServer'; @@ -21,14 +21,14 @@ export default class UIWebSocketServer extends AbstractUIServer { public constructor(protected readonly uiServerConfiguration: UIServerConfiguration) { super(uiServerConfiguration); this.webSocketServer = new WebSocketServer({ - handleProtocols: UIServiceUtils.handleProtocols, + handleProtocols: UIServerUtils.handleProtocols, noServer: true, }); } public start(): void { this.webSocketServer.on('connection', (ws: WebSocket, req: IncomingMessage): void => { - if (UIServiceUtils.isProtocolAndVersionSupported(ws.protocol) === false) { + if (UIServerUtils.isProtocolAndVersionSupported(ws.protocol) === false) { logger.error( `${this.logPrefix( moduleName, @@ -37,7 +37,7 @@ export default class UIWebSocketServer extends AbstractUIServer { ); ws.close(WebSocketCloseEventStatusCode.CLOSE_PROTOCOL_ERROR); } - const [, version] = UIServiceUtils.getProtocolAndVersion(ws.protocol); + const [, version] = UIServerUtils.getProtocolAndVersion(ws.protocol); this.registerProtocolVersionUIService(version); ws.on('message', (rawData) => { const request = this.validateRawDataRequest(rawData); -- 2.34.1