+ }
+ }
+ // Current.Import measurand
+ const currentSampledValueTemplate = this.chargingStation.getSampledValueTemplate(connectorId, OCPP16MeterValueMeasurand.CURRENT_IMPORT);
+ let currentPerPhaseSampledValueTemplates: MeasurandPerPhaseSampledValueTemplates = {};
+ if (this.chargingStation.getNumberOfPhases() === 3) {
+ currentPerPhaseSampledValueTemplates = {
+ L1: this.chargingStation.getSampledValueTemplate(connectorId, OCPP16MeterValueMeasurand.CURRENT_IMPORT, OCPP16MeterValuePhase.L1),
+ L2: this.chargingStation.getSampledValueTemplate(connectorId, OCPP16MeterValueMeasurand.CURRENT_IMPORT, OCPP16MeterValuePhase.L2),
+ L3: this.chargingStation.getSampledValueTemplate(connectorId, OCPP16MeterValueMeasurand.CURRENT_IMPORT, OCPP16MeterValuePhase.L3),
+ };
+ }
+ if (currentSampledValueTemplate) {
+ OCPP16ServiceUtils.checkMeasurandPowerDivider(this.chargingStation, currentSampledValueTemplate.measurand);
+ const errMsg = `${this.chargingStation.logPrefix()} MeterValues measurand ${currentSampledValueTemplate.measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: Unknown ${this.chargingStation.getCurrentOutType()} currentOutType in template file ${this.chargingStation.stationTemplateFile}, cannot calculate ${currentSampledValueTemplate.measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER} measurand value`;
+ const currentMeasurandValues: MeasurandValues = {} as MeasurandValues;
+ let maxAmperage: number;
+ switch (this.chargingStation.getCurrentOutType()) {
+ case CurrentType.AC:
+ maxAmperage = ACElectricUtils.amperagePerPhaseFromPower(this.chargingStation.getNumberOfPhases(), this.chargingStation.stationInfo.maxPower / this.chargingStation.stationInfo.powerDivider, this.chargingStation.getVoltageOut());
+ if (this.chargingStation.getNumberOfPhases() === 3) {
+ const defaultFluctuatedAmperagePerPhase = currentSampledValueTemplate.value
+ && Utils.getRandomFloatFluctuatedRounded(parseInt(currentSampledValueTemplate.value), currentSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT);
+ const phase1FluctuatedValue = currentPerPhaseSampledValueTemplates?.L1?.value
+ && Utils.getRandomFloatFluctuatedRounded(parseInt(currentPerPhaseSampledValueTemplates.L1.value), currentPerPhaseSampledValueTemplates.L1.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT);
+ const phase2FluctuatedValue = currentPerPhaseSampledValueTemplates?.L2?.value
+ && Utils.getRandomFloatFluctuatedRounded(parseInt(currentPerPhaseSampledValueTemplates.L2.value), currentPerPhaseSampledValueTemplates.L2.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT);
+ const phase3FluctuatedValue = currentPerPhaseSampledValueTemplates?.L3?.value
+ && Utils.getRandomFloatFluctuatedRounded(parseInt(currentPerPhaseSampledValueTemplates.L3.value), currentPerPhaseSampledValueTemplates.L3.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT);
+ currentMeasurandValues.L1 = (phase1FluctuatedValue ?? defaultFluctuatedAmperagePerPhase) ?? Utils.getRandomFloatRounded(maxAmperage);
+ currentMeasurandValues.L2 = (phase2FluctuatedValue ?? defaultFluctuatedAmperagePerPhase) ?? Utils.getRandomFloatRounded(maxAmperage);
+ currentMeasurandValues.L3 = (phase3FluctuatedValue ?? defaultFluctuatedAmperagePerPhase) ?? Utils.getRandomFloatRounded(maxAmperage);
+ } else {
+ currentMeasurandValues.L1 = currentSampledValueTemplate.value
+ ? Utils.getRandomFloatFluctuatedRounded(parseInt(currentSampledValueTemplate.value), currentSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT)
+ : Utils.getRandomFloatRounded(maxAmperage);
+ currentMeasurandValues.L2 = 0;
+ currentMeasurandValues.L3 = 0;
+ }
+ currentMeasurandValues.allPhases = Utils.roundTo((currentMeasurandValues.L1 + currentMeasurandValues.L2 + currentMeasurandValues.L3) / this.chargingStation.getNumberOfPhases(), 2);
+ break;
+ case CurrentType.DC:
+ maxAmperage = DCElectricUtils.amperage(this.chargingStation.stationInfo.maxPower / this.chargingStation.stationInfo.powerDivider, this.chargingStation.getVoltageOut());
+ currentMeasurandValues.allPhases = currentSampledValueTemplate.value
+ ? Utils.getRandomFloatFluctuatedRounded(parseInt(currentSampledValueTemplate.value), currentSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT)
+ : Utils.getRandomFloatRounded(maxAmperage);
+ break;
+ default:
+ logger.error(errMsg);
+ throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES);
+ }
+ meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(currentSampledValueTemplate, currentMeasurandValues.allPhases));
+ const sampledValuesIndex = meterValue.sampledValue.length - 1;
+ if (Utils.convertToFloat(meterValue.sampledValue[sampledValuesIndex].value) > maxAmperage || debug) {
+ logger.error(`${this.chargingStation.logPrefix()} MeterValues measurand ${meterValue.sampledValue[sampledValuesIndex].measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${meterValue.sampledValue[sampledValuesIndex].value}/${maxAmperage}`);
+ }
+ for (let phase = 1; this.chargingStation.getNumberOfPhases() === 3 && phase <= this.chargingStation.getNumberOfPhases(); phase++) {
+ const phaseValue = `L${phase}`;
+ meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(currentPerPhaseSampledValueTemplates[phaseValue] ?? currentSampledValueTemplate,
+ currentMeasurandValues[phaseValue], null, phaseValue as OCPP16MeterValuePhase));
+ const sampledValuesPerPhaseIndex = meterValue.sampledValue.length - 1;
+ if (Utils.convertToFloat(meterValue.sampledValue[sampledValuesPerPhaseIndex].value) > maxAmperage || debug) {
+ logger.error(`${this.chargingStation.logPrefix()} MeterValues measurand ${meterValue.sampledValue[sampledValuesPerPhaseIndex].measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: phase ${meterValue.sampledValue[sampledValuesPerPhaseIndex].phase}, connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${meterValue.sampledValue[sampledValuesPerPhaseIndex].value}/${maxAmperage}`);