- if (powerSampledValueTemplate) {
- OCPP16ServiceUtils.checkMeasurandPowerDivider(
- chargingStation,
- powerSampledValueTemplate.measurand
- );
- const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${
- powerSampledValueTemplate.measurand ??
- OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
- }: Unknown ${chargingStation.getCurrentOutType()} currentOutType in template file ${
- chargingStation.templateFile
- }, 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 maximumPower = Math.round(
- chargingStation.getMaximumConfiguredPower() / chargingStation.stationInfo.powerDivider
- );
- const maximumPowerPerPhase = Math.round(
- chargingStation.getMaximumConfiguredPower() /
- chargingStation.stationInfo.powerDivider /
- chargingStation.getNumberOfPhases()
- );
- switch (chargingStation.getCurrentOutType()) {
- case CurrentType.AC:
- if (chargingStation.getNumberOfPhases() === 3) {
- const defaultFluctuatedPowerPerPhase =
- powerSampledValueTemplate.value &&
- Utils.getRandomFloatFluctuatedRounded(
- parseInt(powerSampledValueTemplate.value) / 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(maximumPowerPerPhase / unitDivider);
- powerMeasurandValues.L2 =
- phase2FluctuatedValue ??
- defaultFluctuatedPowerPerPhase ??
- Utils.getRandomFloatRounded(maximumPowerPerPhase / unitDivider);
- powerMeasurandValues.L3 =
- phase3FluctuatedValue ??
- defaultFluctuatedPowerPerPhase ??
- Utils.getRandomFloatRounded(maximumPowerPerPhase / unitDivider);
- } else {
- powerMeasurandValues.L1 = powerSampledValueTemplate.value
- ? Utils.getRandomFloatFluctuatedRounded(
- parseInt(powerSampledValueTemplate.value),
- powerSampledValueTemplate.fluctuationPercent ??
- Constants.DEFAULT_FLUCTUATION_PERCENT
- )
- : Utils.getRandomFloatRounded(maximumPower / 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(maximumPower / unitDivider);
- break;
- default:
- logger.error(errMsg);
- throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES);
- }
- meterValue.sampledValue.push(
- OCPP16ServiceUtils.buildSampledValue(
- powerSampledValueTemplate,
- powerMeasurandValues.allPhases
- )
- );
- const sampledValuesIndex = meterValue.sampledValue.length - 1;
- const maximumPowerRounded = Utils.roundTo(maximumPower / unitDivider, 2);
- if (
- Utils.convertToFloat(meterValue.sampledValue[sampledValuesIndex].value) >
- maximumPowerRounded ||
- debug
- ) {
- logger.error(
- `${chargingStation.logPrefix()} MeterValues measurand ${
- meterValue.sampledValue[sampledValuesIndex].measurand ??
- OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
- }: connectorId ${connectorId}, transaction ${connector.transactionId}, value: ${
- meterValue.sampledValue[sampledValuesIndex].value
- }/${maximumPowerRounded}`
- );
- }
- for (
- let phase = 1;
- chargingStation.getNumberOfPhases() === 3 && phase <= chargingStation.getNumberOfPhases();
- phase++
- ) {
- const phaseValue = `L${phase}-N`;
- meterValue.sampledValue.push(
- OCPP16ServiceUtils.buildSampledValue(
- (powerPerPhaseSampledValueTemplates[`L${phase}`] as SampledValueTemplate) ??
- powerSampledValueTemplate,
- powerMeasurandValues[`L${phase}`] as number,
- null,
- phaseValue as OCPP16MeterValuePhase
+ if (chargingScheduleHigher != null && chargingScheduleLower == null) {
+ return OCPP16ServiceUtils.composeChargingSchedule(chargingScheduleHigher, compositeInterval)
+ }
+ if (chargingScheduleHigher == null && chargingScheduleLower != null) {
+ return OCPP16ServiceUtils.composeChargingSchedule(chargingScheduleLower, compositeInterval)
+ }
+ const compositeChargingScheduleHigher: OCPP16ChargingSchedule | undefined =
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ OCPP16ServiceUtils.composeChargingSchedule(chargingScheduleHigher!, compositeInterval)
+ const compositeChargingScheduleLower: OCPP16ChargingSchedule | undefined =
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ OCPP16ServiceUtils.composeChargingSchedule(chargingScheduleLower!, compositeInterval)
+ const compositeChargingScheduleHigherInterval: Interval = {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ start: compositeChargingScheduleHigher!.startSchedule!,
+ end: addSeconds(
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ compositeChargingScheduleHigher!.startSchedule!,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ compositeChargingScheduleHigher!.duration!
+ )
+ }
+ const compositeChargingScheduleLowerInterval: Interval = {
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ start: compositeChargingScheduleLower!.startSchedule!,
+ end: addSeconds(
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ compositeChargingScheduleLower!.startSchedule!,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ compositeChargingScheduleLower!.duration!
+ )
+ }
+ const higherFirst = isBefore(
+ compositeChargingScheduleHigherInterval.start,
+ compositeChargingScheduleLowerInterval.start
+ )
+ if (
+ !areIntervalsOverlapping(
+ compositeChargingScheduleHigherInterval,
+ compositeChargingScheduleLowerInterval
+ )
+ ) {
+ return {
+ ...compositeChargingScheduleLower,
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
+ ...compositeChargingScheduleHigher!,
+ startSchedule: higherFirst
+ ? (compositeChargingScheduleHigherInterval.start as Date)
+ : (compositeChargingScheduleLowerInterval.start as Date),
+ duration: higherFirst
+ ? differenceInSeconds(
+ compositeChargingScheduleLowerInterval.end,
+ compositeChargingScheduleHigherInterval.start