1 // Partial Copyright Jerome Benoit. 2021. All Rights Reserved.
8 OCPP16MeterValueMeasurand
,
11 } from
'../../../types/ocpp/1.6/MeterValues';
13 import type ChargingStation from
'../../ChargingStation';
14 import { ErrorType
} from
'../../../types/ocpp/ErrorType';
15 import OCPPError from
'../../../exception/OCPPError';
16 import { RequestCommand
} from
'../../../types/ocpp/Requests';
17 import { SampledValueTemplate
} from
'../../../types/MeasurandPerPhaseSampledValueTemplates';
18 import Utils from
'../../../utils/Utils';
19 import logger from
'../../../utils/Logger';
21 export class OCPP16ServiceUtils
{
22 public static checkMeasurandPowerDivider(
23 chargingStation
: ChargingStation
,
24 measurandType
: OCPP16MeterValueMeasurand
26 if (Utils
.isUndefined(chargingStation
.stationInfo
.powerDivider
)) {
27 const errMsg
= `${chargingStation.logPrefix()} MeterValues measurand ${
28 measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
29 }: powerDivider is undefined`;
31 throw new OCPPError(ErrorType
.INTERNAL_ERROR
, errMsg
, RequestCommand
.METER_VALUES
);
32 } else if (chargingStation
.stationInfo
?.powerDivider
<= 0) {
33 const errMsg
= `${chargingStation.logPrefix()} MeterValues measurand ${
34 measurandType ?? OCPP16MeterValueMeasurand.ENERGY_ACTIVE_IMPORT_REGISTER
35 }: powerDivider have zero or below value ${chargingStation.stationInfo.powerDivider}`;
37 throw new OCPPError(ErrorType
.INTERNAL_ERROR
, errMsg
, RequestCommand
.METER_VALUES
);
41 public static buildSampledValue(
42 sampledValueTemplate
: SampledValueTemplate
,
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;
54 ...(!Utils
.isNullOrUndefined(sampledValueTemplate
.unit
) && {
55 unit
: sampledValueTemplate
.unit
,
57 ...(!Utils
.isNullOrUndefined(sampledValueContext
) && { context
: sampledValueContext
}),
58 ...(!Utils
.isNullOrUndefined(sampledValueTemplate
.measurand
) && {
59 measurand
: sampledValueTemplate
.measurand
,
61 ...(!Utils
.isNullOrUndefined(sampledValueLocation
) && { location
: sampledValueLocation
}),
62 ...(!Utils
.isNullOrUndefined(sampledValueValue
) && { value
: sampledValueValue
.toString() }),
63 ...(!Utils
.isNullOrUndefined(sampledValuePhase
) && { phase
: sampledValuePhase
}),
67 public static getMeasurandDefaultUnit(
68 measurandType
: OCPP16MeterValueMeasurand
69 ): MeterValueUnit
| undefined {
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
;
89 public static getMeasurandDefaultLocation(
90 measurandType
: OCPP16MeterValueMeasurand
91 ): MeterValueLocation
| undefined {
92 switch (measurandType
) {
93 case OCPP16MeterValueMeasurand
.STATE_OF_CHARGE
:
94 return MeterValueLocation
.EV
;
98 public static buildTransactionBeginMeterValue(
99 chargingStation
: ChargingStation
,
102 ): OCPP16MeterValue
{
103 const meterValue
: OCPP16MeterValue
= {
104 timestamp
: new Date().toISOString(),
107 // Energy.Active.Import.Register measurand (default)
108 const sampledValueTemplate
= chargingStation
.getSampledValueTemplate(connectorId
);
109 const unitDivider
= sampledValueTemplate
?.unit
=== MeterValueUnit
.KILO_WATT_HOUR
? 1000 : 1;
110 meterValue
.sampledValue
.push(
111 OCPP16ServiceUtils
.buildSampledValue(
112 sampledValueTemplate
,
113 Utils
.roundTo(meterBegin
/ unitDivider
, 4),
114 MeterValueContext
.TRANSACTION_BEGIN
120 public static buildTransactionEndMeterValue(
121 chargingStation
: ChargingStation
,
124 ): OCPP16MeterValue
{
125 const meterValue
: OCPP16MeterValue
= {
126 timestamp
: new Date().toISOString(),
129 // Energy.Active.Import.Register measurand (default)
130 const sampledValueTemplate
= chargingStation
.getSampledValueTemplate(connectorId
);
131 const unitDivider
= sampledValueTemplate
?.unit
=== MeterValueUnit
.KILO_WATT_HOUR
? 1000 : 1;
132 meterValue
.sampledValue
.push(
133 OCPP16ServiceUtils
.buildSampledValue(
134 sampledValueTemplate
,
135 Utils
.roundTo(meterEnd
/ unitDivider
, 4),
136 MeterValueContext
.TRANSACTION_END
142 public static buildTransactionDataMeterValues(
143 transactionBeginMeterValue
: OCPP16MeterValue
,
144 transactionEndMeterValue
: OCPP16MeterValue
145 ): OCPP16MeterValue
[] {
146 const meterValues
: OCPP16MeterValue
[] = [];
147 meterValues
.push(transactionBeginMeterValue
);
148 meterValues
.push(transactionEndMeterValue
);