Commit | Line | Data |
---|---|---|
c8eeb62b JB |
1 | // Partial Copyright Jerome Benoit. 2021. All Rights Reserved. |
2 | ||
e7aeea18 JB |
3 | import { |
4 | MeterValueContext, | |
5 | MeterValueLocation, | |
6 | MeterValueUnit, | |
7 | OCPP16MeterValue, | |
8 | OCPP16MeterValueMeasurand, | |
9 | OCPP16MeterValuePhase, | |
10 | OCPP16SampledValue, | |
11 | } from '../../../types/ocpp/1.6/MeterValues'; | |
6ed92bc1 | 12 | |
73b9adec | 13 | import type ChargingStation from '../../ChargingStation'; |
14763b46 | 14 | import { ErrorType } from '../../../types/ocpp/ErrorType'; |
e58068fd | 15 | import OCPPError from '../../../exception/OCPPError'; |
a6b3c6c3 | 16 | import { RequestCommand } from '../../../types/ocpp/Requests'; |
057e2042 | 17 | import { SampledValueTemplate } from '../../../types/MeasurandPerPhaseSampledValueTemplates'; |
6ed92bc1 | 18 | import Utils from '../../../utils/Utils'; |
9f2e3130 | 19 | import logger from '../../../utils/Logger'; |
6ed92bc1 JB |
20 | |
21 | export class OCPP16ServiceUtils { | |
e7aeea18 JB |
22 | public static checkMeasurandPowerDivider( |
23 | chargingStation: ChargingStation, | |
24 | measurandType: OCPP16MeterValueMeasurand | |
25 | ): void { | |
6ed92bc1 | 26 | if (Utils.isUndefined(chargingStation.stationInfo.powerDivider)) { |
e7aeea18 JB |
27 | const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${ |
28 | measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER | |
29 | }: powerDivider is undefined`; | |
9f2e3130 | 30 | logger.error(errMsg); |
a6b3c6c3 | 31 | throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, RequestCommand.METER_VALUES); |
fd0c36fa | 32 | } else if (chargingStation.stationInfo?.powerDivider <= 0) { |
e7aeea18 JB |
33 | const errMsg = `${chargingStation.logPrefix()} MeterValues measurand ${ |
34 | measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER | |
35 | }: powerDivider have zero or below value ${chargingStation.stationInfo.powerDivider}`; | |
9f2e3130 | 36 | logger.error(errMsg); |
624df199 | 37 | throw new OCPPError(ErrorType.INTERNAL_ERROR, errMsg, RequestCommand.METER_VALUES); |
6ed92bc1 JB |
38 | } |
39 | } | |
40 | ||
e7aeea18 JB |
41 | public static buildSampledValue( |
42 | sampledValueTemplate: SampledValueTemplate, | |
43 | value: number, | |
44 | context?: MeterValueContext, | |
45 | phase?: OCPP16MeterValuePhase | |
46 | ): OCPP16SampledValue { | |
47 | const sampledValueValue = value ?? sampledValueTemplate?.value ?? null; | |
48 | const sampledValueContext = context ?? sampledValueTemplate?.context ?? null; | |
49 | const sampledValueLocation = | |
50 | sampledValueTemplate?.location ?? | |
51 | OCPP16ServiceUtils.getMeasurandDefaultLocation(sampledValueTemplate?.measurand ?? null); | |
52 | const sampledValuePhase = phase ?? sampledValueTemplate?.phase ?? null; | |
6ed92bc1 | 53 | return { |
e7aeea18 JB |
54 | ...(!Utils.isNullOrUndefined(sampledValueTemplate.unit) && { |
55 | unit: sampledValueTemplate.unit, | |
56 | }), | |
57 | ...(!Utils.isNullOrUndefined(sampledValueContext) && { context: sampledValueContext }), | |
58 | ...(!Utils.isNullOrUndefined(sampledValueTemplate.measurand) && { | |
59 | measurand: sampledValueTemplate.measurand, | |
60 | }), | |
61 | ...(!Utils.isNullOrUndefined(sampledValueLocation) && { location: sampledValueLocation }), | |
62 | ...(!Utils.isNullOrUndefined(sampledValueValue) && { value: sampledValueValue.toString() }), | |
63 | ...(!Utils.isNullOrUndefined(sampledValuePhase) && { phase: sampledValuePhase }), | |
6ed92bc1 JB |
64 | }; |
65 | } | |
66 | ||
e7aeea18 JB |
67 | public static getMeasurandDefaultUnit( |
68 | measurandType: OCPP16MeterValueMeasurand | |
69 | ): MeterValueUnit | undefined { | |
6ed92bc1 JB |
70 | switch (measurandType) { |
71 | case OCPP16MeterValueMeasurand.CURRENT_EXPORT: | |
72 | case OCPP16MeterValueMeasurand.CURRENT_IMPORT: | |
73 | case OCPP16MeterValueMeasurand.CURRENT_OFFERED: | |
74 | return MeterValueUnit.AMP; | |
75 | case OCPP16MeterValueMeasurand.ENERGY_ACTIVE_EXPORT_REGISTER: | |
76 | case OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER: | |
77 | return MeterValueUnit.WATT_HOUR; | |
78 | case OCPP16MeterValueMeasurand.POWER_ACTIVE_EXPORT: | |
79 | case OCPP16MeterValueMeasurand.POWER_ACTIVE_IMPORT: | |
80 | case OCPP16MeterValueMeasurand.POWER_OFFERED: | |
81 | return MeterValueUnit.WATT; | |
82 | case OCPP16MeterValueMeasurand.STATE_OF_CHARGE: | |
83 | return MeterValueUnit.PERCENT; | |
84 | case OCPP16MeterValueMeasurand.VOLTAGE: | |
85 | return MeterValueUnit.VOLT; | |
86 | } | |
87 | } | |
88 | ||
e7aeea18 JB |
89 | public static getMeasurandDefaultLocation( |
90 | measurandType: OCPP16MeterValueMeasurand | |
91 | ): MeterValueLocation | undefined { | |
6ed92bc1 JB |
92 | switch (measurandType) { |
93 | case OCPP16MeterValueMeasurand.STATE_OF_CHARGE: | |
94 | return MeterValueLocation.EV; | |
95 | } | |
96 | } | |
fd0c36fa | 97 | |
e7aeea18 JB |
98 | public static buildTransactionBeginMeterValue( |
99 | chargingStation: ChargingStation, | |
100 | connectorId: number, | |
101 | meterBegin: number | |
102 | ): OCPP16MeterValue { | |
fd0c36fa JB |
103 | const meterValue: OCPP16MeterValue = { |
104 | timestamp: new Date().toISOString(), | |
105 | sampledValue: [], | |
106 | }; | |
9ccca265 JB |
107 | // Energy.Active.Import.Register measurand (default) |
108 | const sampledValueTemplate = chargingStation.getSampledValueTemplate(connectorId); | |
109 | const unitDivider = sampledValueTemplate?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1; | |
e7aeea18 JB |
110 | meterValue.sampledValue.push( |
111 | OCPP16ServiceUtils.buildSampledValue( | |
112 | sampledValueTemplate, | |
113 | Utils.roundTo(meterBegin / unitDivider, 4), | |
114 | MeterValueContext.TRANSACTION_BEGIN | |
115 | ) | |
116 | ); | |
fd0c36fa JB |
117 | return meterValue; |
118 | } | |
119 | ||
e7aeea18 JB |
120 | public static buildTransactionEndMeterValue( |
121 | chargingStation: ChargingStation, | |
122 | connectorId: number, | |
123 | meterEnd: number | |
124 | ): OCPP16MeterValue { | |
fd0c36fa JB |
125 | const meterValue: OCPP16MeterValue = { |
126 | timestamp: new Date().toISOString(), | |
127 | sampledValue: [], | |
128 | }; | |
9ccca265 JB |
129 | // Energy.Active.Import.Register measurand (default) |
130 | const sampledValueTemplate = chargingStation.getSampledValueTemplate(connectorId); | |
131 | const unitDivider = sampledValueTemplate?.unit === MeterValueUnit.KILO_WATT_HOUR ? 1000 : 1; | |
e7aeea18 JB |
132 | meterValue.sampledValue.push( |
133 | OCPP16ServiceUtils.buildSampledValue( | |
134 | sampledValueTemplate, | |
135 | Utils.roundTo(meterEnd / unitDivider, 4), | |
136 | MeterValueContext.TRANSACTION_END | |
137 | ) | |
138 | ); | |
fd0c36fa JB |
139 | return meterValue; |
140 | } | |
141 | ||
e7aeea18 JB |
142 | public static buildTransactionDataMeterValues( |
143 | transactionBeginMeterValue: OCPP16MeterValue, | |
144 | transactionEndMeterValue: OCPP16MeterValue | |
145 | ): OCPP16MeterValue[] { | |
fd0c36fa JB |
146 | const meterValues: OCPP16MeterValue[] = []; |
147 | meterValues.push(transactionBeginMeterValue); | |
148 | meterValues.push(transactionEndMeterValue); | |
149 | return meterValues; | |
150 | } | |
6ed92bc1 | 151 | } |