- for (let phase = 1; self.chargingStation.getNumberOfPhases() === 3 && phase <= self.chargingStation.getNumberOfPhases(); phase++) {
- const phaseValue = `L${phase}-N`;
- meterValue.sampledValue.push({
- ...!Utils.isUndefined(meterValuesTemplate[index].unit) ? { unit: meterValuesTemplate[index].unit } : { unit: MeterValueUnit.WATT },
- ...!Utils.isUndefined(meterValuesTemplate[index].context) && { context: meterValuesTemplate[index].context },
- ...!Utils.isUndefined(meterValuesTemplate[index].measurand) && { measurand: meterValuesTemplate[index].measurand },
- ...!Utils.isUndefined(meterValuesTemplate[index].location) && { location: meterValuesTemplate[index].location },
- ...!Utils.isUndefined(meterValuesTemplate[index].value) ? { value: meterValuesTemplate[index].value } : { value: powerMeasurandValues[`L${phase}`] as string },
- phase: phaseValue as MeterValuePhase,
- });
- }
- // Current.Import measurand
- } else if (meterValuesTemplate[index].measurand && meterValuesTemplate[index].measurand === OCPP16MeterValueMeasurand.CURRENT_IMPORT && self.chargingStation.getConfigurationKey(OCPP16StandardParametersKey.MeterValuesSampledData).value.includes(OCPP16MeterValueMeasurand.CURRENT_IMPORT)) {
- // FIXME: factor out powerDivider checks
- if (Utils.isUndefined(self.chargingStation.stationInfo.powerDivider)) {
- const errMsg = `${self.chargingStation.logPrefix()} MeterValues measurand ${meterValuesTemplate[index].measurand ? meterValuesTemplate[index].measurand : OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider is undefined`;
- logger.error(errMsg);
- throw Error(errMsg);
- } else if (self.chargingStation.stationInfo.powerDivider && self.chargingStation.stationInfo.powerDivider <= 0) {
- const errMsg = `${self.chargingStation.logPrefix()} MeterValues measurand ${meterValuesTemplate[index].measurand ? meterValuesTemplate[index].measurand : OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider have zero or below value ${self.chargingStation.stationInfo.powerDivider}`;
- logger.error(errMsg);
- throw Error(errMsg);
- }
- const errMsg = `${self.chargingStation.logPrefix()} MeterValues measurand ${meterValuesTemplate[index].measurand ? meterValuesTemplate[index].measurand : OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: Unknown ${self.chargingStation.getPowerOutType()} powerOutType in template file ${self.chargingStation.stationTemplateFile}, cannot calculate ${meterValuesTemplate[index].measurand ? meterValuesTemplate[index].measurand : OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER} measurand value`;
- const currentMeasurandValues: MeasurandValues = {} as MeasurandValues;
- let maxAmperage: number;
- switch (self.chargingStation.getPowerOutType()) {
- case PowerOutType.AC:
- maxAmperage = ElectricUtils.ampPerPhaseFromPower(self.chargingStation.getNumberOfPhases(), self.chargingStation.stationInfo.maxPower / self.chargingStation.stationInfo.powerDivider, self.chargingStation.getVoltageOut());
- if (Utils.isUndefined(meterValuesTemplate[index].value)) {
- currentMeasurandValues.L1 = Utils.getRandomFloatRounded(maxAmperage);
- currentMeasurandValues.L2 = 0;
- currentMeasurandValues.L3 = 0;
- if (self.chargingStation.getNumberOfPhases() === 3) {
- currentMeasurandValues.L2 = Utils.getRandomFloatRounded(maxAmperage);
- currentMeasurandValues.L3 = Utils.getRandomFloatRounded(maxAmperage);
- }
- currentMeasurandValues.allPhases = Utils.roundTo((currentMeasurandValues.L1 + currentMeasurandValues.L2 + currentMeasurandValues.L3) / self.chargingStation.getNumberOfPhases(), 2);
- }
- break;
- case PowerOutType.DC:
- maxAmperage = ElectricUtils.ampTotalFromPower(self.chargingStation.stationInfo.maxPower / self.chargingStation.stationInfo.powerDivider, self.chargingStation.getVoltageOut());
- if (Utils.isUndefined(meterValuesTemplate[index].value)) {
- currentMeasurandValues.allPhases = Utils.getRandomFloatRounded(maxAmperage);
- }
- break;
- default:
- logger.error(errMsg);
- throw Error(errMsg);
- }
- meterValue.sampledValue.push({
- ...!Utils.isUndefined(meterValuesTemplate[index].unit) ? { unit: meterValuesTemplate[index].unit } : { unit: MeterValueUnit.AMP },
- ...!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: currentMeasurandValues.allPhases.toString() },
- });
- const sampledValuesIndex = meterValue.sampledValue.length - 1;
- if (Utils.convertToFloat(meterValue.sampledValue[sampledValuesIndex].value) > maxAmperage || debug) {
- logger.error(`${self.chargingStation.logPrefix()} MeterValues measurand ${meterValue.sampledValue[sampledValuesIndex].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; self.chargingStation.getNumberOfPhases() === 3 && phase <= self.chargingStation.getNumberOfPhases(); phase++) {
- const phaseValue = `L${phase}`;
- meterValue.sampledValue.push({
- ...!Utils.isUndefined(meterValuesTemplate[index].unit) ? { unit: meterValuesTemplate[index].unit } : { unit: MeterValueUnit.AMP },
- ...!Utils.isUndefined(meterValuesTemplate[index].context) && { context: meterValuesTemplate[index].context },
- ...!Utils.isUndefined(meterValuesTemplate[index].measurand) && { measurand: meterValuesTemplate[index].measurand },
- ...!Utils.isUndefined(meterValuesTemplate[index].location) && { location: meterValuesTemplate[index].location },
- ...!Utils.isUndefined(meterValuesTemplate[index].value) ? { value: meterValuesTemplate[index].value } : { value: currentMeasurandValues[phaseValue] as string },
- phase: phaseValue as MeterValuePhase,
- });
- }
- // Energy.Active.Import.Register measurand (default)
- } else if (!meterValuesTemplate[index].measurand || meterValuesTemplate[index].measurand === OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER) {
- // FIXME: factor out powerDivider checks
- if (Utils.isUndefined(self.chargingStation.stationInfo.powerDivider)) {
- const errMsg = `${self.chargingStation.logPrefix()} MeterValues measurand ${meterValuesTemplate[index].measurand ? meterValuesTemplate[index].measurand : OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider is undefined`;
- logger.error(errMsg);
- throw Error(errMsg);
- } else if (self.chargingStation.stationInfo.powerDivider && self.chargingStation.stationInfo.powerDivider <= 0) {
- const errMsg = `${self.chargingStation.logPrefix()} MeterValues measurand ${meterValuesTemplate[index].measurand ? meterValuesTemplate[index].measurand : OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider have zero or below value ${self.chargingStation.stationInfo.powerDivider}`;
+ }
+ }
+ // Power.Active.Import measurand
+ const powerSampledValueTemplate = self.chargingStation.getSampledValueTemplate(connectorId, OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT);
+ let powerPerPhaseSampledValueTemplates: MeasurandPerPhaseSampledValueTemplates = {};
+ if (self.chargingStation.getNumberOfPhases() === 3) {
+ powerPerPhaseSampledValueTemplates = {
+ L1: self.chargingStation.getSampledValueTemplate(connectorId, OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT, OCPP16MeterValuePhase.L1_N),
+ L2: self.chargingStation.getSampledValueTemplate(connectorId, OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT, OCPP16MeterValuePhase.L2_N),
+ L3: self.chargingStation.getSampledValueTemplate(connectorId, OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT, OCPP16MeterValuePhase.L3_N),
+ };
+ }
+ if (powerSampledValueTemplate) {
+ OCPP16ServiceUtils.checkMeasurandPowerDivider(self.chargingStation, powerSampledValueTemplate.measurand);
+ const errMsg = `${self.chargingStation.logPrefix()} MeterValues measurand ${powerSampledValueTemplate.measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: Unknown ${self.chargingStation.getCurrentOutType()} currentOutType in template file ${self.chargingStation.stationTemplateFile}, cannot calculate ${powerSampledValueTemplate.measurand ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER} measurand value`;
+ const powerMeasurandValues = {} as MeasurandValues;
+ const unitDivider = powerSampledValueTemplate?.unit === MeterValueUnit.KILO_WATT ? 1000 : 1;
+ const maxPower = Math.round(self.chargingStation.stationInfo.maxPower / self.chargingStation.stationInfo.powerDivider);
+ const maxPowerPerPhase = Math.round((self.chargingStation.stationInfo.maxPower / self.chargingStation.stationInfo.powerDivider) / self.chargingStation.getNumberOfPhases());
+ switch (self.chargingStation.getCurrentOutType()) {
+ case CurrentType.AC:
+ if (self.chargingStation.getNumberOfPhases() === 3) {
+ const defaultFluctuatedPowerPerPhase = powerSampledValueTemplate.value
+ && Utils.getRandomFloatFluctuatedRounded(parseInt(powerSampledValueTemplate.value) / self.chargingStation.getNumberOfPhases(), powerSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT);
+ const phase1FluctuatedValue = powerPerPhaseSampledValueTemplates?.L1?.value
+ && Utils.getRandomFloatFluctuatedRounded(parseInt(powerPerPhaseSampledValueTemplates.L1.value), powerPerPhaseSampledValueTemplates.L1.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT);
+ const phase2FluctuatedValue = powerPerPhaseSampledValueTemplates?.L2?.value
+ && Utils.getRandomFloatFluctuatedRounded(parseInt(powerPerPhaseSampledValueTemplates.L2.value), powerPerPhaseSampledValueTemplates.L2.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT);
+ const phase3FluctuatedValue = powerPerPhaseSampledValueTemplates?.L3?.value
+ && Utils.getRandomFloatFluctuatedRounded(parseInt(powerPerPhaseSampledValueTemplates.L3.value), powerPerPhaseSampledValueTemplates.L3.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT);
+ powerMeasurandValues.L1 = (phase1FluctuatedValue ?? defaultFluctuatedPowerPerPhase) ?? Utils.getRandomFloatRounded(maxPowerPerPhase / unitDivider);
+ powerMeasurandValues.L2 = (phase2FluctuatedValue ?? defaultFluctuatedPowerPerPhase) ?? Utils.getRandomFloatRounded(maxPowerPerPhase / unitDivider);
+ powerMeasurandValues.L3 = (phase3FluctuatedValue ?? defaultFluctuatedPowerPerPhase) ?? Utils.getRandomFloatRounded(maxPowerPerPhase / unitDivider);
+ } else {
+ powerMeasurandValues.L1 = powerSampledValueTemplate.value
+ ? Utils.getRandomFloatFluctuatedRounded(parseInt(powerSampledValueTemplate.value), powerSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT)
+ : Utils.getRandomFloatRounded(maxPower / unitDivider);
+ powerMeasurandValues.L2 = 0;
+ powerMeasurandValues.L3 = 0;
+ }
+ powerMeasurandValues.allPhases = Utils.roundTo(powerMeasurandValues.L1 + powerMeasurandValues.L2 + powerMeasurandValues.L3, 2);
+ break;
+ case CurrentType.DC:
+ powerMeasurandValues.allPhases = powerSampledValueTemplate.value
+ ? Utils.getRandomFloatFluctuatedRounded(parseInt(powerSampledValueTemplate.value), powerSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT)
+ : Utils.getRandomFloatRounded(maxPower / unitDivider);
+ break;
+ default: