- public async sendMeterValues(
- connectorId: number,
- transactionId: number,
- interval: number,
- debug = false
- ): Promise<void> {
- const meterValue: OCPP16MeterValue = {
- timestamp: new Date().toISOString(),
- sampledValue: [],
- };
- const connector = this.chargingStation.getConnectorStatus(connectorId);
- // SoC measurand
- const socSampledValueTemplate = this.chargingStation.getSampledValueTemplate(
- connectorId,
- OCPP16MeterValueMeasurand.STATE_OF_CHARGE
- );
- if (socSampledValueTemplate) {
- const socSampledValueTemplateValue = socSampledValueTemplate.value
- ? Utils.getRandomFloatFluctuatedRounded(
- parseInt(socSampledValueTemplate.value),
- socSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT
- )
- : Utils.getRandomInteger(100);
- meterValue.sampledValue.push(
- OCPP16ServiceUtils.buildSampledValue(socSampledValueTemplate, socSampledValueTemplateValue)
- );
- const sampledValuesIndex = meterValue.sampledValue.length - 1;
- if (Utils.convertToInt(meterValue.sampledValue[sampledValuesIndex].value) > 100 || 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
- }/100`
- );
- }
- }
- // Voltage measurand
- const voltageSampledValueTemplate = this.chargingStation.getSampledValueTemplate(
- connectorId,
- OCPP16MeterValueMeasurand.VOLTAGE
- );
- if (voltageSampledValueTemplate) {
- const voltageSampledValueTemplateValue = voltageSampledValueTemplate.value
- ? parseInt(voltageSampledValueTemplate.value)
- : this.chargingStation.getVoltageOut();
- const fluctuationPercent =
- voltageSampledValueTemplate.fluctuationPercent ?? Constants.DEFAULT_FLUCTUATION_PERCENT;
- const voltageMeasurandValue = Utils.getRandomFloatFluctuatedRounded(
- voltageSampledValueTemplateValue,
- fluctuationPercent
- );
- if (
- this.chargingStation.getNumberOfPhases() !== 3 ||
- (this.chargingStation.getNumberOfPhases() === 3 &&
- this.chargingStation.getMainVoltageMeterValues())
- ) {
- meterValue.sampledValue.push(
- OCPP16ServiceUtils.buildSampledValue(voltageSampledValueTemplate, voltageMeasurandValue)
- );
- }
- for (
- let phase = 1;
- this.chargingStation.getNumberOfPhases() === 3 &&
- phase <= this.chargingStation.getNumberOfPhases();
- phase++
- ) {
- const phaseLineToNeutralValue = `L${phase}-N`;
- const voltagePhaseLineToNeutralSampledValueTemplate =
- this.chargingStation.getSampledValueTemplate(
- connectorId,
- OCPP16MeterValueMeasurand.VOLTAGE,
- phaseLineToNeutralValue as OCPP16MeterValuePhase
- );
- let voltagePhaseLineToNeutralMeasurandValue: number;
- if (voltagePhaseLineToNeutralSampledValueTemplate) {
- const voltagePhaseLineToNeutralSampledValueTemplateValue =
- voltagePhaseLineToNeutralSampledValueTemplate.value
- ? parseInt(voltagePhaseLineToNeutralSampledValueTemplate.value)
- : this.chargingStation.getVoltageOut();
- const fluctuationPhaseToNeutralPercent =
- voltagePhaseLineToNeutralSampledValueTemplate.fluctuationPercent ??
- Constants.DEFAULT_FLUCTUATION_PERCENT;
- voltagePhaseLineToNeutralMeasurandValue = Utils.getRandomFloatFluctuatedRounded(
- voltagePhaseLineToNeutralSampledValueTemplateValue,
- fluctuationPhaseToNeutralPercent
- );
- }
- meterValue.sampledValue.push(
- OCPP16ServiceUtils.buildSampledValue(
- voltagePhaseLineToNeutralSampledValueTemplate ?? voltageSampledValueTemplate,
- voltagePhaseLineToNeutralMeasurandValue ?? voltageMeasurandValue,
- null,
- phaseLineToNeutralValue as OCPP16MeterValuePhase
- )
- );
- if (this.chargingStation.getPhaseLineToLineVoltageMeterValues()) {
- const phaseLineToLineValue = `L${phase}-L${
- (phase + 1) % this.chargingStation.getNumberOfPhases() !== 0
- ? (phase + 1) % this.chargingStation.getNumberOfPhases()
- : this.chargingStation.getNumberOfPhases()
- }`;
- const voltagePhaseLineToLineSampledValueTemplate =
- this.chargingStation.getSampledValueTemplate(
- connectorId,
- OCPP16MeterValueMeasurand.VOLTAGE,
- phaseLineToLineValue as OCPP16MeterValuePhase
- );
- let voltagePhaseLineToLineMeasurandValue: number;
- if (voltagePhaseLineToLineSampledValueTemplate) {
- const voltagePhaseLineToLineSampledValueTemplateValue =
- voltagePhaseLineToLineSampledValueTemplate.value
- ? parseInt(voltagePhaseLineToLineSampledValueTemplate.value)
- : Voltage.VOLTAGE_400;
- const fluctuationPhaseLineToLinePercent =
- voltagePhaseLineToLineSampledValueTemplate.fluctuationPercent ??
- Constants.DEFAULT_FLUCTUATION_PERCENT;
- voltagePhaseLineToLineMeasurandValue = Utils.getRandomFloatFluctuatedRounded(
- voltagePhaseLineToLineSampledValueTemplateValue,
- fluctuationPhaseLineToLinePercent
- );
- }
- const defaultVoltagePhaseLineToLineMeasurandValue = Utils.getRandomFloatFluctuatedRounded(
- Voltage.VOLTAGE_400,
- fluctuationPercent
- );
- meterValue.sampledValue.push(
- OCPP16ServiceUtils.buildSampledValue(
- voltagePhaseLineToLineSampledValueTemplate ?? voltageSampledValueTemplate,
- voltagePhaseLineToLineMeasurandValue ?? defaultVoltagePhaseLineToLineMeasurandValue,
- null,
- phaseLineToLineValue as OCPP16MeterValuePhase
- )
- );
- }
- }
- }
- // Power.Active.Import measurand
- const powerSampledValueTemplate = this.chargingStation.getSampledValueTemplate(
- connectorId,
- OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT
- );
- let powerPerPhaseSampledValueTemplates: MeasurandPerPhaseSampledValueTemplates = {};
- if (this.chargingStation.getNumberOfPhases() === 3) {
- powerPerPhaseSampledValueTemplates = {
- L1: this.chargingStation.getSampledValueTemplate(
- connectorId,
- OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT,
- OCPP16MeterValuePhase.L1_N
- ),
- L2: this.chargingStation.getSampledValueTemplate(
- connectorId,
- OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT,
- OCPP16MeterValuePhase.L2_N
- ),
- L3: this.chargingStation.getSampledValueTemplate(
- connectorId,
- OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT,
- OCPP16MeterValuePhase.L3_N
- ),
- };
- }
- if (powerSampledValueTemplate) {
- OCPP16ServiceUtils.checkMeasurandPowerDivider(
- this.chargingStation,
- powerSampledValueTemplate.measurand
- );
- const errMsg = `${this.chargingStation.logPrefix()} MeterValues measurand ${
- powerSampledValueTemplate.measurand ??
- OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
- }: Unknown ${this.chargingStation.getCurrentOutType()} currentOutType in template file ${
- this.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(
- this.chargingStation.stationInfo.maxPower / this.chargingStation.stationInfo.powerDivider
- );
- const maxPowerPerPhase = Math.round(
- this.chargingStation.stationInfo.maxPower /
- this.chargingStation.stationInfo.powerDivider /
- this.chargingStation.getNumberOfPhases()
- );
- switch (this.chargingStation.getCurrentOutType()) {
- case CurrentType.AC:
- if (this.chargingStation.getNumberOfPhases() === 3) {
- const defaultFluctuatedPowerPerPhase =
- powerSampledValueTemplate.value &&
- Utils.getRandomFloatFluctuatedRounded(
- parseInt(powerSampledValueTemplate.value) /
- this.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:
- 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 maxPowerRounded = Utils.roundTo(maxPower / unitDivider, 2);
- if (
- Utils.convertToFloat(meterValue.sampledValue[sampledValuesIndex].value) > maxPowerRounded ||
- 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
- }/${maxPowerRounded}`
- );
- }
- for (
- let phase = 1;
- this.chargingStation.getNumberOfPhases() === 3 &&
- phase <= this.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
- )
+ private buildRequestPayload<Request extends JsonType>(
+ commandName: OCPP16RequestCommand,
+ commandParams?: JsonType
+ ): Request {
+ let connectorId: number;
+ switch (commandName) {
+ case OCPP16RequestCommand.AUTHORIZE:
+ return {
+ ...(!Utils.isUndefined(commandParams?.idTag)
+ ? { idTag: commandParams.idTag }
+ : { idTag: Constants.DEFAULT_IDTAG }),
+ } as unknown as Request;
+ case OCPP16RequestCommand.BOOT_NOTIFICATION:
+ return {
+ chargePointModel: commandParams?.chargePointModel,
+ chargePointVendor: commandParams?.chargePointVendor,
+ ...(!Utils.isUndefined(commandParams?.chargeBoxSerialNumber) && {
+ chargeBoxSerialNumber: commandParams.chargeBoxSerialNumber,
+ }),
+ ...(!Utils.isUndefined(commandParams?.chargePointSerialNumber) && {
+ chargePointSerialNumber: commandParams.chargePointSerialNumber,
+ }),
+ ...(!Utils.isUndefined(commandParams?.firmwareVersion) && {
+ firmwareVersion: commandParams.firmwareVersion,
+ }),
+ ...(!Utils.isUndefined(commandParams?.iccid) && { iccid: commandParams.iccid }),
+ ...(!Utils.isUndefined(commandParams?.imsi) && { imsi: commandParams.imsi }),
+ ...(!Utils.isUndefined(commandParams?.meterSerialNumber) && {
+ meterSerialNumber: commandParams.meterSerialNumber,
+ }),
+ ...(!Utils.isUndefined(commandParams?.meterType) && {
+ meterType: commandParams.meterType,
+ }),
+ } as unknown as Request;
+ case OCPP16RequestCommand.DIAGNOSTICS_STATUS_NOTIFICATION:
+ return {
+ status: commandParams?.diagnosticsStatus,
+ } as unknown as Request;
+ case OCPP16RequestCommand.HEARTBEAT:
+ return {} as unknown as Request;
+ case OCPP16RequestCommand.METER_VALUES:
+ return {
+ connectorId: commandParams?.connectorId,
+ transactionId: commandParams?.transactionId,
+ meterValue: Array.isArray(commandParams?.meterValue)
+ ? commandParams?.meterValue
+ : [commandParams?.meterValue],
+ } as unknown as Request;
+ case OCPP16RequestCommand.STATUS_NOTIFICATION:
+ return {
+ connectorId: commandParams?.connectorId,
+ status: commandParams?.status,
+ errorCode: commandParams?.errorCode,
+ } as unknown as Request;
+ case OCPP16RequestCommand.START_TRANSACTION:
+ return {
+ connectorId: commandParams?.connectorId,
+ ...(!Utils.isUndefined(commandParams?.idTag)
+ ? { idTag: commandParams?.idTag }
+ : { idTag: Constants.DEFAULT_IDTAG }),
+ meterStart: this.chargingStation.getEnergyActiveImportRegisterByConnectorId(
+ commandParams?.connectorId as number
+ ),
+ timestamp: new Date().toISOString(),
+ } as unknown as Request;
+ case OCPP16RequestCommand.STOP_TRANSACTION:
+ connectorId = this.chargingStation.getConnectorIdByTransactionId(
+ commandParams?.transactionId as number