Apply dependencies update.
[e-mobility-charging-stations-simulator.git] / src / charging-station / ocpp / 1.6 / OCPP16ServiceUtils.ts
1 import { MeterValueContext, MeterValueLocation, MeterValueUnit, OCPP16MeterValue, OCPP16MeterValueMeasurand, OCPP16MeterValuePhase, OCPP16SampledValue } from '../../../types/ocpp/1.6/MeterValues';
2
3 import ChargingStation from '../../ChargingStation';
4 import { SampledValueTemplate } from '../../../types/Connectors';
5 import Utils from '../../../utils/Utils';
6 import logger from '../../../utils/Logger';
7
8 export class OCPP16ServiceUtils {
9 public static checkMeasurandPowerDivider(chargingStation: ChargingStation, measurandType: OCPP16MeterValueMeasurand): void {
10 if (Utils.isUndefined(chargingStation.stationInfo.powerDivider)) {
11 const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider is undefined`;
12 logger.error(errMsg);
13 throw Error(errMsg);
14 } else if (chargingStation.stationInfo?.powerDivider <= 0) {
15 const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER}: powerDivider have zero or below value ${chargingStation.stationInfo.powerDivider}`;
16 logger.error(errMsg);
17 throw Error(errMsg);
18 }
19 }
20
21 public static buildSampledValue(sampledValueTemplate: SampledValueTemplate, value: number, context?: MeterValueContext, phase?: OCPP16MeterValuePhase): OCPP16SampledValue {
22 const sampledValueValue = value ?? (sampledValueTemplate.value ?? null);
23 const sampledValueContext = context ?? (sampledValueTemplate.context ?? null);
24 const sampledValueLocation = sampledValueTemplate.location ?? 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(sampledValueValue) && { value: sampledValueValue.toString() },
32 ...!Utils.isNullOrUndefined(sampledValuePhase) && { phase: sampledValuePhase },
33 };
34 }
35
36 public static getMeasurandDefaultUnit(measurandType: OCPP16MeterValueMeasurand): MeterValueUnit | undefined {
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
56 public static getMeasurandDefaultLocation(measurandType: OCPP16MeterValueMeasurand): MeterValueLocation | undefined {
57 switch (measurandType) {
58 case OCPP16MeterValueMeasurand.STATE_OF_CHARGE:
59 return MeterValueLocation.EV;
60 }
61 }
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 // Energy.Active.Import.Register measurand (default)
69 const sampledValueTemplate = chargingStation.getSampledValueTemplate(connectorId);
70 const unitDivider = sampledValueTemplate?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1;
71 meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(sampledValueTemplate, Utils.roundTo(meterBegin / unitDivider, 4), MeterValueContext.TRANSACTION_BEGIN));
72 return meterValue;
73 }
74
75 public static buildTransactionEndMeterValue(chargingStation: ChargingStation, connectorId: number, meterEnd: number): OCPP16MeterValue {
76 const meterValue: OCPP16MeterValue = {
77 timestamp: new Date().toISOString(),
78 sampledValue: [],
79 };
80 // Energy.Active.Import.Register measurand (default)
81 const sampledValueTemplate = chargingStation.getSampledValueTemplate(connectorId);
82 const unitDivider = sampledValueTemplate?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1;
83 meterValue.sampledValue.push(OCPP16ServiceUtils.buildSampledValue(sampledValueTemplate, Utils.roundTo(meterEnd / unitDivider, 4), MeterValueContext.TRANSACTION_END));
84 return meterValue;
85 }
86
87 public static buildTransactionDataMeterValues(transactionBeginMeterValue: OCPP16MeterValue, transactionEndMeterValue: OCPP16MeterValue): OCPP16MeterValue[] {
88 const meterValues: OCPP16MeterValue[] = [];
89 meterValues.push(transactionBeginMeterValue);
90 meterValues.push(transactionEndMeterValue);
91 return meterValues;
92 }
93 }