Refactor OCPP requests sending helpers
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 1.6 / OCPP16ServiceUtils.ts
CommitLineData
c8eeb62b
JB
1// Partial Copyright Jerome Benoit. 2021. All Rights Reserved.
2
9ccca265 3import { MeterValueContext, MeterValueLocation, MeterValueUnit, OCPP16MeterValue, OCPP16MeterValueMeasurand, OCPP16MeterValuePhase, OCPP16SampledValue } from '../../../types/ocpp/1.6/MeterValues';
6ed92bc1
JB
4
5import ChargingStation from '../../ChargingStation';
14763b46 6import { ErrorType } from '../../../types/ocpp/ErrorType';
e58068fd 7import OCPPError from '../../../exception/OCPPError';
a6b3c6c3 8import { RequestCommand } from '../../../types/ocpp/Requests';
057e2042 9import { SampledValueTemplate } from '../../../types/MeasurandPerPhaseSampledValueTemplates';
6ed92bc1 10import Utils from '../../../utils/Utils';
9f2e3130 11import logger from '../../../utils/Logger';
6ed92bc1
JB
12
13export class OCPP16ServiceUtils {
14 public static checkMeasurandPowerDivider(chargingStation: ChargingStation, measurandType: OCPP16MeterValueMeasurand): void {
15 if (Utils.isUndefined(chargingStation.stationInfo.powerDivider)) {
16 const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider is undefined`;
9f2e3130 17 logger.error(errMsg);
a6b3c6c3 18 throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, RequestCommand.METER_VALUES);
fd0c36fa 19 } else if (chargingStation.stationInfo?.powerDivider <= 0) {
6ed92bc1 20 const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider have zero or below value ${chargingStation.stationInfo.powerDivider}`;
9f2e3130 21 logger.error(errMsg);
624df199 22 throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, RequestCommand.METER_VALUES);
6ed92bc1
JB
23 }
24 }
25
9ccca265 26 public static buildSampledValue(sampledValueTemplate: SampledValueTemplate, value: number, context?: MeterValueContext, phase?: OCPP16MeterValuePhase): OCPP16SampledValue {
290d006c
JB
27 const sampledValueValue = value ?? (sampledValueTemplate?.value ?? null);
28 const sampledValueContext = context ?? (sampledValueTemplate?.context ?? null);
29 const sampledValueLocation = sampledValueTemplate?.location ?? OCPP16ServiceUtils.getMeasurandDefaultLocation(sampledValueTemplate?.measurand ?? null);
30 const sampledValuePhase = phase ?? (sampledValueTemplate?.phase ?? null);
6ed92bc1
JB
31 return {
32 ...!Utils.isNullOrUndefined(sampledValueTemplate.unit) && { unit: sampledValueTemplate.unit },
33 ...!Utils.isNullOrUndefined(sampledValueContext) && { context: sampledValueContext },
34 ...!Utils.isNullOrUndefined(sampledValueTemplate.measurand) && { measurand: sampledValueTemplate.measurand },
35 ...!Utils.isNullOrUndefined(sampledValueLocation) && { location: sampledValueLocation },
9ccca265 36 ...!Utils.isNullOrUndefined(sampledValueValue) && { value: sampledValueValue.toString() },
6ed92bc1
JB
37 ...!Utils.isNullOrUndefined(sampledValuePhase) && { phase: sampledValuePhase },
38 };
39 }
40
4a1857a2 41 public static getMeasurandDefaultUnit(measurandType: OCPP16MeterValueMeasurand): MeterValueUnit | undefined {
6ed92bc1
JB
42 switch (measurandType) {
43 case OCPP16MeterValueMeasurand.CURRENT_EXPORT:
44 case OCPP16MeterValueMeasurand.CURRENT_IMPORT:
45 case OCPP16MeterValueMeasurand.CURRENT_OFFERED:
46 return MeterValueUnit.AMP;
47 case OCPP16MeterValueMeasurand.ENERGY_ACTIVE_EXPORT_REGISTER:
48 case OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER:
49 return MeterValueUnit.WATT_HOUR;
50 case OCPP16MeterValueMeasurand.POWER_ACTIVE_EXPORT:
51 case OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT:
52 case OCPP16MeterValueMeasurand.POWER_OFFERED:
53 return MeterValueUnit.WATT;
54 case OCPP16MeterValueMeasurand.STATE_OF_CHARGE:
55 return MeterValueUnit.PERCENT;
56 case OCPP16MeterValueMeasurand.VOLTAGE:
57 return MeterValueUnit.VOLT;
58 }
59 }
60
4a1857a2 61 public static getMeasurandDefaultLocation(measurandType: OCPP16MeterValueMeasurand): MeterValueLocation | undefined {
6ed92bc1
JB
62 switch (measurandType) {
63 case OCPP16MeterValueMeasurand.STATE_OF_CHARGE:
64 return MeterValueLocation.EV;
65 }
66 }
fd0c36fa
JB
67
68 public static buildTransactionBeginMeterValue(chargingStation: ChargingStation, connectorId: number, meterBegin: number): OCPP16MeterValue {
69 const meterValue: OCPP16MeterValue = {
70 timestamp: new Date().toISOString(),
71 sampledValue: [],
72 };
9ccca265
JB
73 // Energy.Active.Import.Register measurand (default)
74 const sampledValueTemplate = chargingStation.getSampledValueTemplate(connectorId);
75 const unitDivider = sampledValueTemplate?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1;
76 meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(sampledValueTemplate, Utils.roundTo(meterBegin / unitDivider, 4), MeterValueContext.TRANSACTION_BEGIN));
fd0c36fa
JB
77 return meterValue;
78 }
79
80 public static buildTransactionEndMeterValue(chargingStation: ChargingStation, connectorId: number, meterEnd: number): OCPP16MeterValue {
81 const meterValue: OCPP16MeterValue = {
82 timestamp: new Date().toISOString(),
83 sampledValue: [],
84 };
9ccca265
JB
85 // Energy.Active.Import.Register measurand (default)
86 const sampledValueTemplate = chargingStation.getSampledValueTemplate(connectorId);
87 const unitDivider = sampledValueTemplate?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1;
88 meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(sampledValueTemplate, Utils.roundTo(meterEnd / unitDivider, 4), MeterValueContext.TRANSACTION_END));
fd0c36fa
JB
89 return meterValue;
90 }
91
92 public static buildTransactionDataMeterValues(transactionBeginMeterValue: OCPP16MeterValue, transactionEndMeterValue: OCPP16MeterValue): OCPP16MeterValue[] {
93 const meterValues: OCPP16MeterValue[] = [];
94 meterValues.push(transactionBeginMeterValue);
95 meterValues.push(transactionEndMeterValue);
96 return meterValues;
97 }
6ed92bc1 98}