- };
- }
- 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}`
- );
- }
- }
- }
- // Energy.Active.Import.Register measurand (default)
- const energySampledValueTemplate = this.chargingStation.getSampledValueTemplate(connectorId);
- if (energySampledValueTemplate) {
- OCPP16ServiceUtils.checkMeasurandPowerDivider(
- this.chargingStation,
- energySampledValueTemplate.measurand
- );
- const unitDivider =
- energySampledValueTemplate?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1;
- const maxEnergyRounded = Utils.roundTo(
- ((this.chargingStation.stationInfo.maxPower /
- this.chargingStation.stationInfo.powerDivider) *
- interval) /
- (3600 * 1000),
- 2
- );
- const energyValueRounded = energySampledValueTemplate.value
- ? // Cumulate the fluctuated value around the static one
- Utils.getRandomFloatFluctuatedRounded(
- parseInt(energySampledValueTemplate.value),
- energySampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT
- )
- : Utils.getRandomFloatRounded(maxEnergyRounded);
- // Persist previous value on connector
- if (
- connector &&
- !Utils.isNullOrUndefined(connector.energyActiveImportRegisterValue) &&
- connector.energyActiveImportRegisterValue >= 0 &&
- !Utils.isNullOrUndefined(connector.transactionEnergyActiveImportRegisterValue) &&
- connector.transactionEnergyActiveImportRegisterValue >= 0
- ) {
- connector.energyActiveImportRegisterValue += energyValueRounded;
- connector.transactionEnergyActiveImportRegisterValue += energyValueRounded;
- } else {
- connector.energyActiveImportRegisterValue = 0;
- connector.transactionEnergyActiveImportRegisterValue = 0;
- }
- meterValue.sampledValue.push(
- OCPP16ServiceUtils.buildSampledValue(
- energySampledValueTemplate,
- Utils.roundTo(
- this.chargingStation.getEnergyActiveImportRegisterByTransactionId(transactionId) /
- unitDivider,
- 2
- )
- )
- );
- const sampledValuesIndex = meterValue.sampledValue.length - 1;
- if (energyValueRounded > maxEnergyRounded || debug) {
- logger.error(
- `${this.chargingStation.logPrefix()} MeterValues measurand ${
- meterValue.sampledValue[sampledValuesIndex].measurand ??
- OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
- }: connectorId ${connectorId}, transaction ${
- connector.transactionId
- }, value: ${energyValueRounded}/${maxEnergyRounded}, duration: ${Utils.roundTo(
- interval / (3600 * 1000),
- 4
- )}h`
- );
- }
- }
- const payload: MeterValuesRequest = {
- connectorId,
- transactionId,
- meterValue: [meterValue],
- };
- await this.sendMessage(Utils.generateUUID(), payload, OCPP16RequestCommand.METER_VALUES);