From: Jérôme Benoit Date: Tue, 31 Mar 2026 22:03:59 +0000 (+0200) Subject: fix(ocpp): warn on OCPP 1.6 keys in template only, silent remap for internal code X-Git-Tag: ocpp-server@v4.1.1~2 X-Git-Url: https://git.piment-noir.org/?a=commitdiff_plain;h=a428896fece63ca81fb65377715296357630216a;p=e-mobility-charging-stations-simulator.git fix(ocpp): warn on OCPP 1.6 keys in template only, silent remap for internal code Simplify OCPP2_PARAMETER_KEY_MAP to a plain Map and make resolveKey always silent. Move warning to a one-shot template validation pass (warnOnOCPP16TemplateKeys) called after template loading, before init defaults. Warnings now only fire when the operator uses OCPP 1.6 key names in an OCPP 2.0 station template, not when internal cross-version code resolves keys. --- diff --git a/src/charging-station/ChargingStation.ts b/src/charging-station/ChargingStation.ts index 14c68d7f..87ebc66c 100644 --- a/src/charging-station/ChargingStation.ts +++ b/src/charging-station/ChargingStation.ts @@ -112,6 +112,7 @@ import { deleteConfigurationKey, getConfigurationKey, setConfigurationKeyValue, + warnOnOCPP16TemplateKeys, } from './ConfigurationKeyUtils.js' import { buildConnectorsMap, @@ -1776,6 +1777,7 @@ export class ChargingStation extends EventEmitter { this.powerDivider = this.getPowerDivider() // OCPP configuration this.ocppConfiguration = this.getOcppConfiguration(options?.persistentConfiguration) + warnOnOCPP16TemplateKeys(this) this.initializeOcppConfiguration() this.initializeOcppServices() if (this.stationInfo.autoRegister === true) { diff --git a/src/charging-station/ConfigurationKeyUtils.ts b/src/charging-station/ConfigurationKeyUtils.ts index ff83ffed..7fe1e319 100644 --- a/src/charging-station/ConfigurationKeyUtils.ts +++ b/src/charging-station/ConfigurationKeyUtils.ts @@ -7,116 +7,75 @@ import { OCPPVersion, StandardParametersKey, } from '../types/index.js' -import { logger, once } from '../utils/index.js' +import { logger } from '../utils/index.js' export const buildConfigKey = (component: string, variable: string, instance?: string): string => { const base = `${component}.${variable}` return instance != null ? `${base}.${instance}` : base } -const OCPP2_PARAMETER_KEY_MAP = new Map< - ConfigurationKeyType, - { - resolved: ConfigurationKeyType - warnOnce: (chargingStation: ChargingStation) => void - } - >( - ( - [ - [ - StandardParametersKey.AuthorizeRemoteTxRequests, - buildConfigKey(OCPP20ComponentName.AuthCtrlr, StandardParametersKey.AuthorizeRemoteStart), - ], - [ - StandardParametersKey.ConnectionTimeOut, - buildConfigKey(OCPP20ComponentName.TxCtrlr, StandardParametersKey.EVConnectionTimeOut), - ], - [ - StandardParametersKey.LocalAuthorizeOffline, - buildConfigKey( - OCPP20ComponentName.AuthCtrlr, - StandardParametersKey.LocalAuthorizationOffline - ), - ], - [ - StandardParametersKey.LocalAuthListEnabled, - buildConfigKey(OCPP20ComponentName.LocalAuthListCtrlr, StandardParametersKey.Enabled), - ], - [ - StandardParametersKey.LocalPreAuthorize, - buildConfigKey(OCPP20ComponentName.AuthCtrlr, StandardParametersKey.LocalPreAuthorization), - ], - [ - StandardParametersKey.MeterValueSampleInterval, - buildConfigKey( - OCPP20ComponentName.SampledDataCtrlr, - StandardParametersKey.TxUpdatedInterval - ), - ], - [ - StandardParametersKey.MeterValuesSampledData, - buildConfigKey( - OCPP20ComponentName.SampledDataCtrlr, - StandardParametersKey.TxUpdatedMeasurands - ), - ], - [ - StandardParametersKey.ReserveConnectorZeroSupported, - buildConfigKey(OCPP20ComponentName.ReservationCtrlr, StandardParametersKey.NonEvseSpecific), - ], - [ - StandardParametersKey.HeartbeatInterval, - buildConfigKey(OCPP20ComponentName.OCPPCommCtrlr, StandardParametersKey.HeartbeatInterval), - ], - [ - StandardParametersKey.HeartBeatInterval, - buildConfigKey(OCPP20ComponentName.OCPPCommCtrlr, StandardParametersKey.HeartbeatInterval), - ], - [ - StandardParametersKey.WebSocketPingInterval, - buildConfigKey( - OCPP20ComponentName.OCPPCommCtrlr, - StandardParametersKey.WebSocketPingInterval - ), - ], - [ - StandardParametersKey.MeterValuesAlignedData, - buildConfigKey(OCPP20ComponentName.AlignedDataCtrlr, StandardParametersKey.Measurands), - ], - [ - StandardParametersKey.ClockAlignedDataInterval, - buildConfigKey( - OCPP20ComponentName.AlignedDataCtrlr, - StandardParametersKey.AlignedDataInterval - ), - ], - [ - StandardParametersKey.StopTxnSampledData, - buildConfigKey( - OCPP20ComponentName.SampledDataCtrlr, - StandardParametersKey.TxEndedMeasurands - ), - ], - [ - StandardParametersKey.StopTxnAlignedData, - buildConfigKey( - OCPP20ComponentName.AlignedDataCtrlr, - StandardParametersKey.TxEndedMeasurands - ), - ], - ] as [ConfigurationKeyType, ConfigurationKeyType][] - ).map(([from, to]) => [ - from, - { - resolved: to, - warnOnce: once((cs: ChargingStation) => { - logger.warn( - `${cs.logPrefix()} OCPP 1.6 configuration key '${from}' remapped to OCPP 2.0 variable '${to}'` - ) - }), - }, - ]) - ) +const OCPP2_PARAMETER_KEY_MAP = new Map([ + [ + StandardParametersKey.AuthorizeRemoteTxRequests, + buildConfigKey(OCPP20ComponentName.AuthCtrlr, StandardParametersKey.AuthorizeRemoteStart), + ], + [ + StandardParametersKey.ClockAlignedDataInterval, + buildConfigKey(OCPP20ComponentName.AlignedDataCtrlr, StandardParametersKey.AlignedDataInterval), + ], + [ + StandardParametersKey.ConnectionTimeOut, + buildConfigKey(OCPP20ComponentName.TxCtrlr, StandardParametersKey.EVConnectionTimeOut), + ], + [ + StandardParametersKey.HeartbeatInterval, + buildConfigKey(OCPP20ComponentName.OCPPCommCtrlr, StandardParametersKey.HeartbeatInterval), + ], + [ + StandardParametersKey.HeartBeatInterval, + buildConfigKey(OCPP20ComponentName.OCPPCommCtrlr, StandardParametersKey.HeartbeatInterval), + ], + [ + StandardParametersKey.LocalAuthListEnabled, + buildConfigKey(OCPP20ComponentName.LocalAuthListCtrlr, StandardParametersKey.Enabled), + ], + [ + StandardParametersKey.LocalAuthorizeOffline, + buildConfigKey(OCPP20ComponentName.AuthCtrlr, StandardParametersKey.LocalAuthorizationOffline), + ], + [ + StandardParametersKey.LocalPreAuthorize, + buildConfigKey(OCPP20ComponentName.AuthCtrlr, StandardParametersKey.LocalPreAuthorization), + ], + [ + StandardParametersKey.MeterValuesAlignedData, + buildConfigKey(OCPP20ComponentName.AlignedDataCtrlr, StandardParametersKey.Measurands), + ], + [ + StandardParametersKey.MeterValueSampleInterval, + buildConfigKey(OCPP20ComponentName.SampledDataCtrlr, StandardParametersKey.TxUpdatedInterval), + ], + [ + StandardParametersKey.MeterValuesSampledData, + buildConfigKey(OCPP20ComponentName.SampledDataCtrlr, StandardParametersKey.TxUpdatedMeasurands), + ], + [ + StandardParametersKey.ReserveConnectorZeroSupported, + buildConfigKey(OCPP20ComponentName.ReservationCtrlr, StandardParametersKey.NonEvseSpecific), + ], + [ + StandardParametersKey.StopTxnAlignedData, + buildConfigKey(OCPP20ComponentName.AlignedDataCtrlr, StandardParametersKey.TxEndedMeasurands), + ], + [ + StandardParametersKey.StopTxnSampledData, + buildConfigKey(OCPP20ComponentName.SampledDataCtrlr, StandardParametersKey.TxEndedMeasurands), + ], + [ + StandardParametersKey.WebSocketPingInterval, + buildConfigKey(OCPP20ComponentName.OCPPCommCtrlr, StandardParametersKey.WebSocketPingInterval), + ], +]) const resolveKey = ( chargingStation: ChargingStation, @@ -124,15 +83,30 @@ const resolveKey = ( ): ConfigurationKeyType => { const version = chargingStation.stationInfo?.ocppVersion if (version === OCPPVersion.VERSION_20 || version === OCPPVersion.VERSION_201) { - const mapping = OCPP2_PARAMETER_KEY_MAP.get(key) - if (mapping != null) { - mapping.warnOnce(chargingStation) - return mapping.resolved - } + return OCPP2_PARAMETER_KEY_MAP.get(key) ?? key } return key } +export const warnOnOCPP16TemplateKeys = (chargingStation: ChargingStation): void => { + const version = chargingStation.stationInfo?.ocppVersion + if (version !== OCPPVersion.VERSION_20 && version !== OCPPVersion.VERSION_201) { + return + } + const keys = chargingStation.ocppConfiguration?.configurationKey + if (!Array.isArray(keys)) { + return + } + for (const entry of keys) { + const resolved = OCPP2_PARAMETER_KEY_MAP.get(entry.key) + if (resolved != null) { + logger.warn( + `${chargingStation.logPrefix()} Template uses OCPP 1.6 key '${entry.key}', use OCPP 2.0 variable '${resolved}' instead` + ) + } + } +} + interface AddConfigurationKeyParams { caseInsensitive?: boolean overwrite?: boolean