- // eslint-disable-next-line consistent-this
- async sendMeterValues(connectorId: number, interval: number, self: ChargingStation, debug = false): Promise<void> {
- try {
- const meterValue: MeterValue = {
- timestamp: new Date().toISOString(),
- sampledValue: [],
- };
- const meterValuesTemplate: SampledValue[] = self.getConnector(connectorId).MeterValues;
- for (let index = 0; index < meterValuesTemplate.length; index++) {
- const connector = self.getConnector(connectorId);
- // SoC measurand
- if (meterValuesTemplate[index].measurand && meterValuesTemplate[index].measurand === MeterValueMeasurand.STATE_OF_CHARGE && self._getConfigurationKey('MeterValuesSampledData').value.includes(MeterValueMeasurand.STATE_OF_CHARGE)) {
- meterValue.sampledValue.push({
- ...!Utils.isUndefined(meterValuesTemplate[index].unit) ? { unit: meterValuesTemplate[index].unit } : { unit: MeterValueUnit.PERCENT },
- ...!Utils.isUndefined(meterValuesTemplate[index].context) && { context: meterValuesTemplate[index].context },
- measurand: meterValuesTemplate[index].measurand,
- ...!Utils.isUndefined(meterValuesTemplate[index].location) ? { location: meterValuesTemplate[index].location } : { location: MeterValueLocation.EV },
- ...!Utils.isUndefined(meterValuesTemplate[index].value) ? { value: meterValuesTemplate[index].value } : { value: Utils.getRandomInt(100).toString() },
- });
- const sampledValuesIndex = meterValue.sampledValue.length - 1;
- if (Utils.convertToInt(meterValue.sampledValue[sampledValuesIndex].value) > 100 || debug) {
- logger.error(`${self._logPrefix()} MeterValues measurand ${meterValue.sampledValue[sampledValuesIndex].measurand ? meterValue.sampledValue[sampledValuesIndex].measurand : MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${meterValue.sampledValue[sampledValuesIndex].value}/100`);
- }
- // Voltage measurand
- } else if (meterValuesTemplate[index].measurand && meterValuesTemplate[index].measurand === MeterValueMeasurand.VOLTAGE && self._getConfigurationKey('MeterValuesSampledData').value.includes(MeterValueMeasurand.VOLTAGE)) {
- const voltageMeasurandValue = Utils.getRandomFloatRounded(self._getVoltageOut() + self._getVoltageOut() * 0.1, self._getVoltageOut() - self._getVoltageOut() * 0.1);
- meterValue.sampledValue.push({
- ...!Utils.isUndefined(meterValuesTemplate[index].unit) ? { unit: meterValuesTemplate[index].unit } : { unit: MeterValueUnit.VOLT },
- ...!Utils.isUndefined(meterValuesTemplate[index].context) && { context: meterValuesTemplate[index].context },
- measurand: meterValuesTemplate[index].measurand,
- ...!Utils.isUndefined(meterValuesTemplate[index].location) && { location: meterValuesTemplate[index].location },
- ...!Utils.isUndefined(meterValuesTemplate[index].value) ? { value: meterValuesTemplate[index].value } : { value: voltageMeasurandValue.toString() },
- });
- for (let phase = 1; self._getNumberOfPhases() === 3 && phase <= self._getNumberOfPhases(); phase++) {
- let phaseValue: string;
- if (self._getVoltageOut() >= 0 && self._getVoltageOut() <= 250) {
- phaseValue = `L${phase}-N`;
- } else if (self._getVoltageOut() > 250) {
- phaseValue = `L${phase}-L${(phase + 1) % self._getNumberOfPhases() !== 0 ? (phase + 1) % self._getNumberOfPhases() : self._getNumberOfPhases()}`;
+ private initializeOcppConfiguration(): void {
+ if (
+ !ChargingStationConfigurationUtils.getConfigurationKey(
+ this,
+ StandardParametersKey.HeartbeatInterval
+ )
+ ) {
+ ChargingStationConfigurationUtils.addConfigurationKey(
+ this,
+ StandardParametersKey.HeartbeatInterval,
+ '0'
+ );
+ }
+ if (
+ !ChargingStationConfigurationUtils.getConfigurationKey(
+ this,
+ StandardParametersKey.HeartBeatInterval
+ )
+ ) {
+ ChargingStationConfigurationUtils.addConfigurationKey(
+ this,
+ StandardParametersKey.HeartBeatInterval,
+ '0',
+ { visible: false }
+ );
+ }
+ if (
+ this.getSupervisionUrlOcppConfiguration() &&
+ !ChargingStationConfigurationUtils.getConfigurationKey(this, this.getSupervisionUrlOcppKey())
+ ) {
+ ChargingStationConfigurationUtils.addConfigurationKey(
+ this,
+ this.getSupervisionUrlOcppKey(),
+ this.configuredSupervisionUrl.href,
+ { reboot: true }
+ );
+ } else if (
+ !this.getSupervisionUrlOcppConfiguration() &&
+ ChargingStationConfigurationUtils.getConfigurationKey(this, this.getSupervisionUrlOcppKey())
+ ) {
+ ChargingStationConfigurationUtils.deleteConfigurationKey(
+ this,
+ this.getSupervisionUrlOcppKey(),
+ { save: false }
+ );
+ }
+ if (
+ this.stationInfo.amperageLimitationOcppKey &&
+ !ChargingStationConfigurationUtils.getConfigurationKey(
+ this,
+ this.stationInfo.amperageLimitationOcppKey
+ )
+ ) {
+ ChargingStationConfigurationUtils.addConfigurationKey(
+ this,
+ this.stationInfo.amperageLimitationOcppKey,
+ (
+ this.stationInfo.maximumAmperage *
+ ChargingStationUtils.getAmperageLimitationUnitDivider(this.stationInfo)
+ ).toString()
+ );
+ }
+ if (
+ !ChargingStationConfigurationUtils.getConfigurationKey(
+ this,
+ StandardParametersKey.SupportedFeatureProfiles
+ )
+ ) {
+ ChargingStationConfigurationUtils.addConfigurationKey(
+ this,
+ StandardParametersKey.SupportedFeatureProfiles,
+ `${SupportedFeatureProfiles.Core},${SupportedFeatureProfiles.FirmwareManagement},${SupportedFeatureProfiles.LocalAuthListManagement},${SupportedFeatureProfiles.SmartCharging},${SupportedFeatureProfiles.RemoteTrigger}`
+ );
+ }
+ ChargingStationConfigurationUtils.addConfigurationKey(
+ this,
+ StandardParametersKey.NumberOfConnectors,
+ this.getNumberOfConnectors().toString(),
+ { readonly: true },
+ { overwrite: true }
+ );
+ if (
+ !ChargingStationConfigurationUtils.getConfigurationKey(
+ this,
+ StandardParametersKey.MeterValuesSampledData
+ )
+ ) {
+ ChargingStationConfigurationUtils.addConfigurationKey(
+ this,
+ StandardParametersKey.MeterValuesSampledData,
+ MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
+ );
+ }
+ if (
+ !ChargingStationConfigurationUtils.getConfigurationKey(
+ this,
+ StandardParametersKey.ConnectorPhaseRotation
+ )
+ ) {
+ const connectorPhaseRotation = [];
+ for (const connectorId of this.connectors.keys()) {
+ // AC/DC
+ if (connectorId === 0 && this.getNumberOfPhases() === 0) {
+ connectorPhaseRotation.push(`${connectorId}.${ConnectorPhaseRotation.RST}`);
+ } else if (connectorId > 0 && this.getNumberOfPhases() === 0) {
+ connectorPhaseRotation.push(`${connectorId}.${ConnectorPhaseRotation.NotApplicable}`);
+ // AC
+ } else if (connectorId > 0 && this.getNumberOfPhases() === 1) {
+ connectorPhaseRotation.push(`${connectorId}.${ConnectorPhaseRotation.NotApplicable}`);
+ } else if (connectorId > 0 && this.getNumberOfPhases() === 3) {
+ connectorPhaseRotation.push(`${connectorId}.${ConnectorPhaseRotation.RST}`);
+ }
+ }
+ ChargingStationConfigurationUtils.addConfigurationKey(
+ this,
+ StandardParametersKey.ConnectorPhaseRotation,
+ connectorPhaseRotation.toString()
+ );
+ }
+ if (
+ !ChargingStationConfigurationUtils.getConfigurationKey(
+ this,
+ StandardParametersKey.AuthorizeRemoteTxRequests
+ )
+ ) {
+ ChargingStationConfigurationUtils.addConfigurationKey(
+ this,
+ StandardParametersKey.AuthorizeRemoteTxRequests,
+ 'true'
+ );
+ }
+ if (
+ !ChargingStationConfigurationUtils.getConfigurationKey(
+ this,
+ StandardParametersKey.LocalAuthListEnabled
+ ) &&
+ ChargingStationConfigurationUtils.getConfigurationKey(
+ this,
+ StandardParametersKey.SupportedFeatureProfiles
+ )?.value.includes(SupportedFeatureProfiles.LocalAuthListManagement)
+ ) {
+ ChargingStationConfigurationUtils.addConfigurationKey(
+ this,
+ StandardParametersKey.LocalAuthListEnabled,
+ 'false'
+ );
+ }
+ if (
+ !ChargingStationConfigurationUtils.getConfigurationKey(
+ this,
+ StandardParametersKey.ConnectionTimeOut
+ )
+ ) {
+ ChargingStationConfigurationUtils.addConfigurationKey(
+ this,
+ StandardParametersKey.ConnectionTimeOut,
+ Constants.DEFAULT_CONNECTION_TIMEOUT.toString()
+ );
+ }
+ this.saveOcppConfiguration();
+ }
+
+ private initializeConnectors(
+ stationInfo: ChargingStationInfo,
+ configuredMaxConnectors: number,
+ templateMaxConnectors: number
+ ): void {
+ if (!stationInfo?.Connectors && this.connectors.size === 0) {
+ const logMsg = `No already defined connectors and charging station information from template ${this.templateFile} with no connectors configuration defined`;
+ logger.error(`${this.logPrefix()} ${logMsg}`);
+ throw new BaseError(logMsg);
+ }
+ if (!stationInfo?.Connectors[0]) {
+ logger.warn(
+ `${this.logPrefix()} Charging station information from template ${
+ this.templateFile
+ } with no connector Id 0 configuration`
+ );
+ }
+ if (stationInfo?.Connectors) {
+ const connectorsConfigHash = crypto
+ .createHash(Constants.DEFAULT_HASH_ALGORITHM)
+ .update(JSON.stringify(stationInfo?.Connectors) + configuredMaxConnectors.toString())
+ .digest('hex');
+ const connectorsConfigChanged =
+ this.connectors?.size !== 0 && this.connectorsConfigurationHash !== connectorsConfigHash;
+ if (this.connectors?.size === 0 || connectorsConfigChanged) {
+ connectorsConfigChanged && this.connectors.clear();
+ this.connectorsConfigurationHash = connectorsConfigHash;
+ // Add connector Id 0
+ let lastConnector = '0';
+ for (lastConnector in stationInfo?.Connectors) {
+ const lastConnectorId = Utils.convertToInt(lastConnector);
+ if (
+ lastConnectorId === 0 &&
+ this.getUseConnectorId0(stationInfo) &&
+ stationInfo?.Connectors[lastConnector]
+ ) {
+ this.connectors.set(
+ lastConnectorId,
+ Utils.cloneObject<ConnectorStatus>(stationInfo?.Connectors[lastConnector])
+ );
+ this.getConnectorStatus(lastConnectorId).availability = AvailabilityType.OPERATIVE;
+ if (Utils.isUndefined(this.getConnectorStatus(lastConnectorId)?.chargingProfiles)) {
+ this.getConnectorStatus(lastConnectorId).chargingProfiles = [];