// Partial Copyright Jerome Benoit. 2021. All Rights Reserved.
-import { ACElectricUtils, DCElectricUtils } from '../../../utils/ElectricUtils';
+import OCPPError from '../../../exception/OCPPError';
import { CurrentType, Voltage } from '../../../types/ChargingStationTemplate';
-import MeasurandPerPhaseSampledValueTemplates, {
+import type {
+ MeasurandPerPhaseSampledValueTemplates,
SampledValueTemplate,
} from '../../../types/MeasurandPerPhaseSampledValueTemplates';
+import type { MeasurandValues } from '../../../types/MeasurandValues';
+import type { OCPP16ChargingProfile } from '../../../types/ocpp/1.6/ChargingProfile';
+import {
+ OCPP16StandardParametersKey,
+ OCPP16SupportedFeatureProfiles,
+} from '../../../types/ocpp/1.6/Configuration';
import {
MeterValueContext,
MeterValueLocation,
OCPP16IncomingRequestCommand,
OCPP16RequestCommand,
} from '../../../types/ocpp/1.6/Requests';
-import {
- OCPP16StandardParametersKey,
- OCPP16SupportedFeatureProfiles,
-} from '../../../types/ocpp/1.6/Configuration';
-
-import type ChargingStation from '../../ChargingStation';
-import { ChargingStationUtils } from '../../ChargingStationUtils';
-import Constants from '../../../utils/Constants';
import { ErrorType } from '../../../types/ocpp/ErrorType';
-import MeasurandValues from '../../../types/MeasurandValues';
-import OCPPError from '../../../exception/OCPPError';
-import { OCPPServiceUtils } from '../OCPPServiceUtils';
-import Utils from '../../../utils/Utils';
+import Constants from '../../../utils/Constants';
+import { ACElectricUtils, DCElectricUtils } from '../../../utils/ElectricUtils';
import logger from '../../../utils/Logger';
+import Utils from '../../../utils/Utils';
+import type ChargingStation from '../../ChargingStation';
+import { OCPPServiceUtils } from '../OCPPServiceUtils';
export class OCPP16ServiceUtils extends OCPPServiceUtils {
public static checkFeatureProfile(
};
const connector = chargingStation.getConnectorStatus(connectorId);
// SoC measurand
- const socSampledValueTemplate = ChargingStationUtils.getSampledValueTemplate(
+ const socSampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.STATE_OF_CHARGE
}
}
// Voltage measurand
- const voltageSampledValueTemplate = ChargingStationUtils.getSampledValueTemplate(
+ const voltageSampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.VOLTAGE
) {
const phaseLineToNeutralValue = `L${phase}-N`;
const voltagePhaseLineToNeutralSampledValueTemplate =
- ChargingStationUtils.getSampledValueTemplate(
+ OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.VOLTAGE,
: chargingStation.getNumberOfPhases()
}`;
const voltagePhaseLineToLineSampledValueTemplate =
- ChargingStationUtils.getSampledValueTemplate(
+ OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.VOLTAGE,
}
}
// Power.Active.Import measurand
- const powerSampledValueTemplate = ChargingStationUtils.getSampledValueTemplate(
+ const powerSampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT
let powerPerPhaseSampledValueTemplates: MeasurandPerPhaseSampledValueTemplates = {};
if (chargingStation.getNumberOfPhases() === 3) {
powerPerPhaseSampledValueTemplates = {
- L1: ChargingStationUtils.getSampledValueTemplate(
+ L1: OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT,
OCPP16MeterValuePhase.L1_N
),
- L2: ChargingStationUtils.getSampledValueTemplate(
+ L2: OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT,
OCPP16MeterValuePhase.L2_N
),
- L3: ChargingStationUtils.getSampledValueTemplate(
+ L3: OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT,
chargingStation,
powerSampledValueTemplate.measurand
);
- const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${
+ const errMsg = `MeterValues measurand ${
powerSampledValueTemplate.measurand ??
OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
}: Unknown ${chargingStation.getCurrentOutType()} currentOutType in template file ${
: Utils.getRandomFloatRounded(connectorMaximumPower / unitDivider);
break;
default:
- logger.error(errMsg);
+ logger.error(`${chargingStation.logPrefix()} ${errMsg}`);
throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES);
}
meterValue.sampledValue.push(
}
}
// Current.Import measurand
- const currentSampledValueTemplate = ChargingStationUtils.getSampledValueTemplate(
+ const currentSampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.CURRENT_IMPORT
let currentPerPhaseSampledValueTemplates: MeasurandPerPhaseSampledValueTemplates = {};
if (chargingStation.getNumberOfPhases() === 3) {
currentPerPhaseSampledValueTemplates = {
- L1: ChargingStationUtils.getSampledValueTemplate(
+ L1: OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.CURRENT_IMPORT,
OCPP16MeterValuePhase.L1
),
- L2: ChargingStationUtils.getSampledValueTemplate(
+ L2: OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.CURRENT_IMPORT,
OCPP16MeterValuePhase.L2
),
- L3: ChargingStationUtils.getSampledValueTemplate(
+ L3: OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId,
OCPP16MeterValueMeasurand.CURRENT_IMPORT,
chargingStation,
currentSampledValueTemplate.measurand
);
- const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${
+ const errMsg = `MeterValues measurand ${
currentSampledValueTemplate.measurand ??
OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
}: Unknown ${chargingStation.getCurrentOutType()} currentOutType in template file ${
: Utils.getRandomFloatRounded(connectorMaximumAmperage);
break;
default:
- logger.error(errMsg);
+ logger.error(`${chargingStation.logPrefix()} ${errMsg}`);
throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES);
}
meterValue.sampledValue.push(
}
}
// Energy.Active.Import.Register measurand (default)
- const energySampledValueTemplate = ChargingStationUtils.getSampledValueTemplate(
+ const energySampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId
);
// Persist previous value on connector
if (
connector &&
- !Utils.isNullOrUndefined(connector.energyActiveImportRegisterValue) &&
+ Utils.isNullOrUndefined(connector.energyActiveImportRegisterValue) === false &&
connector.energyActiveImportRegisterValue >= 0 &&
- !Utils.isNullOrUndefined(connector.transactionEnergyActiveImportRegisterValue) &&
+ Utils.isNullOrUndefined(connector.transactionEnergyActiveImportRegisterValue) === false &&
connector.transactionEnergyActiveImportRegisterValue >= 0
) {
connector.energyActiveImportRegisterValue += energyValueRounded;
sampledValue: [],
};
// Energy.Active.Import.Register measurand (default)
- const sampledValueTemplate = ChargingStationUtils.getSampledValueTemplate(
+ const sampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId
);
sampledValue: [],
};
// Energy.Active.Import.Register measurand (default)
- const sampledValueTemplate = ChargingStationUtils.getSampledValueTemplate(
+ const sampledValueTemplate = OCPP16ServiceUtils.getSampledValueTemplate(
chargingStation,
connectorId
);
return meterValues;
}
+ public static setChargingProfile(
+ chargingStation: ChargingStation,
+ connectorId: number,
+ cp: OCPP16ChargingProfile
+ ): void {
+ if (Utils.isNullOrUndefined(chargingStation.getConnectorStatus(connectorId).chargingProfiles)) {
+ logger.error(
+ `${chargingStation.logPrefix()} Trying to set a charging profile on connectorId ${connectorId} with an uninitialized charging profiles array attribute, applying deferred initialization`
+ );
+ chargingStation.getConnectorStatus(connectorId).chargingProfiles = [];
+ }
+ if (Array.isArray(chargingStation.getConnectorStatus(connectorId).chargingProfiles) === false) {
+ logger.error(
+ `${chargingStation.logPrefix()} Trying to set a charging profile on connectorId ${connectorId} with an improper attribute type for the charging profiles array, applying proper type initialization`
+ );
+ chargingStation.getConnectorStatus(connectorId).chargingProfiles = [];
+ }
+ let cpReplaced = false;
+ if (!Utils.isEmptyArray(chargingStation.getConnectorStatus(connectorId).chargingProfiles)) {
+ chargingStation
+ .getConnectorStatus(connectorId)
+ .chargingProfiles?.forEach((chargingProfile: OCPP16ChargingProfile, index: number) => {
+ if (
+ chargingProfile.chargingProfileId === cp.chargingProfileId ||
+ (chargingProfile.stackLevel === cp.stackLevel &&
+ chargingProfile.chargingProfilePurpose === cp.chargingProfilePurpose)
+ ) {
+ chargingStation.getConnectorStatus(connectorId).chargingProfiles[index] = cp;
+ cpReplaced = true;
+ }
+ });
+ }
+ !cpReplaced && chargingStation.getConnectorStatus(connectorId).chargingProfiles?.push(cp);
+ }
+
private static buildSampledValue(
sampledValueTemplate: SampledValueTemplate,
value: number,
chargingStation: ChargingStation,
measurandType: OCPP16MeterValueMeasurand
): void {
- if (Utils.isUndefined(chargingStation.stationInfo.powerDivider)) {
- const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${
+ if (Utils.isUndefined(chargingStation.powerDivider)) {
+ const errMsg = `MeterValues measurand ${
measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
}: powerDivider is undefined`;
- logger.error(errMsg);
+ logger.error(`${chargingStation.logPrefix()} ${errMsg}`);
throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES);
- } else if (chargingStation.stationInfo?.powerDivider <= 0) {
- const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${
+ } else if (chargingStation?.powerDivider <= 0) {
+ const errMsg = `MeterValues measurand ${
measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
- }: powerDivider have zero or below value ${chargingStation.stationInfo.powerDivider}`;
- logger.error(errMsg);
+ }: powerDivider have zero or below value ${chargingStation.powerDivider}`;
+ logger.error(`${chargingStation.logPrefix()} ${errMsg}`);
throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, OCPP16RequestCommand.METER_VALUES);
}
}