Release 1.0.17
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 1.6 / OCPP16ServiceUtils.ts
CommitLineData
fd0c36fa 1import { MeterValueContext, MeterValueLocation, MeterValuePhase, MeterValueUnit, OCPP16MeterValue, OCPP16MeterValueMeasurand, OCPP16SampledValue } from '../../../types/ocpp/1.6/MeterValues';
6ed92bc1
JB
2
3import ChargingStation from '../../ChargingStation';
4import Utils from '../../../utils/Utils';
5import logger from '../../../utils/Logger';
6
7export class OCPP16ServiceUtils {
8 public static checkMeasurandPowerDivider(chargingStation: ChargingStation, measurandType: OCPP16MeterValueMeasurand): void {
9 if (Utils.isUndefined(chargingStation.stationInfo.powerDivider)) {
10 const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider is undefined`;
11 logger.error(errMsg);
12 throw Error(errMsg);
fd0c36fa 13 } else if (chargingStation.stationInfo?.powerDivider <= 0) {
6ed92bc1
JB
14 const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider have zero or below value ${chargingStation.stationInfo.powerDivider}`;
15 logger.error(errMsg);
16 throw Error(errMsg);
17 }
18 }
19
20 public static buildSampledValue(sampledValueTemplate: OCPP16SampledValue, value: number, context?: MeterValueContext, phase?: MeterValuePhase): OCPP16SampledValue {
21 const sampledValueContext = context ?? (sampledValueTemplate.context ?? null);
22 const sampledValueLocation = sampledValueTemplate.location
23 ? sampledValueTemplate.location
24 : (OCPP16ServiceUtils.getMeasurandDefaultLocation(sampledValueTemplate.measurand ?? null));
25 const sampledValuePhase = phase ?? (sampledValueTemplate.phase ?? null);
26 return {
27 ...!Utils.isNullOrUndefined(sampledValueTemplate.unit) && { unit: sampledValueTemplate.unit },
28 ...!Utils.isNullOrUndefined(sampledValueContext) && { context: sampledValueContext },
29 ...!Utils.isNullOrUndefined(sampledValueTemplate.measurand) && { measurand: sampledValueTemplate.measurand },
30 ...!Utils.isNullOrUndefined(sampledValueLocation) && { location: sampledValueLocation },
31 ...!Utils.isNullOrUndefined(sampledValueTemplate.value) ? { value: sampledValueTemplate.value } : { value: value.toString() },
32 ...!Utils.isNullOrUndefined(sampledValuePhase) && { phase: sampledValuePhase },
33 };
34 }
35
4a1857a2 36 public static getMeasurandDefaultUnit(measurandType: OCPP16MeterValueMeasurand): MeterValueUnit | undefined {
6ed92bc1
JB
37 switch (measurandType) {
38 case OCPP16MeterValueMeasurand.CURRENT_EXPORT:
39 case OCPP16MeterValueMeasurand.CURRENT_IMPORT:
40 case OCPP16MeterValueMeasurand.CURRENT_OFFERED:
41 return MeterValueUnit.AMP;
42 case OCPP16MeterValueMeasurand.ENERGY_ACTIVE_EXPORT_REGISTER:
43 case OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER:
44 return MeterValueUnit.WATT_HOUR;
45 case OCPP16MeterValueMeasurand.POWER_ACTIVE_EXPORT:
46 case OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT:
47 case OCPP16MeterValueMeasurand.POWER_OFFERED:
48 return MeterValueUnit.WATT;
49 case OCPP16MeterValueMeasurand.STATE_OF_CHARGE:
50 return MeterValueUnit.PERCENT;
51 case OCPP16MeterValueMeasurand.VOLTAGE:
52 return MeterValueUnit.VOLT;
53 }
54 }
55
4a1857a2 56 public static getMeasurandDefaultLocation(measurandType: OCPP16MeterValueMeasurand): MeterValueLocation | undefined {
6ed92bc1
JB
57 switch (measurandType) {
58 case OCPP16MeterValueMeasurand.STATE_OF_CHARGE:
59 return MeterValueLocation.EV;
60 }
61 }
fd0c36fa
JB
62
63 public static buildTransactionBeginMeterValue(chargingStation: ChargingStation, connectorId: number, meterBegin: number): OCPP16MeterValue {
64 const meterValue: OCPP16MeterValue = {
65 timestamp: new Date().toISOString(),
66 sampledValue: [],
67 };
68 const meterValuesTemplate: OCPP16SampledValue[] = chargingStation.getConnector(connectorId).MeterValues;
69 for (let index = 0; index < meterValuesTemplate.length; index++) {
70 // Energy.Active.Import.Register measurand (default)
71 if (!meterValuesTemplate[index].measurand || meterValuesTemplate[index].measurand === OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER) {
72 const unitDivider = meterValuesTemplate[index]?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1;
73 meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(meterValuesTemplate[index],
74 Utils.roundTo(meterBegin / unitDivider, 4), MeterValueContext.TRANSACTION_BEGIN));
75 }
76 }
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 };
85 const meterValuesTemplate: OCPP16SampledValue[] = chargingStation.getConnector(connectorId).MeterValues;
86 for (let index = 0; index < meterValuesTemplate.length; index++) {
87 // Energy.Active.Import.Register measurand (default)
88 if (!meterValuesTemplate[index].measurand || meterValuesTemplate[index].measurand === OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER) {
89 const unitDivider = meterValuesTemplate[index]?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1;
90 meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(meterValuesTemplate[index], Utils.roundTo(meterEnd / unitDivider, 4), MeterValueContext.TRANSACTION_END));
91 }
92 }
93 return meterValue;
94 }
95
96 public static buildTransactionDataMeterValues(transactionBeginMeterValue: OCPP16MeterValue, transactionEndMeterValue: OCPP16MeterValue): OCPP16MeterValue[] {
97 const meterValues: OCPP16MeterValue[] = [];
98 meterValues.push(transactionBeginMeterValue);
99 meterValues.push(transactionEndMeterValue);
100 return meterValues;
101 }
6ed92bc1 102}