@citrineos/data
Version:
The OCPP data module which includes all persistence layer implementation.
431 lines • 18.5 kB
JavaScript
// SPDX-FileCopyrightText: 2025 Contributors to the CitrineOS Project
//
// SPDX-License-Identifier: Apache-2.0
import { LocationEnum, MeasurandEnum, OCPP1_6, PhaseEnum, ReadingContextEnum, } from '@citrineos/base';
export class MeterValueMapper {
/**
* Converts native ReadingContextEnum to OCPP 1.6 MeterValuesRequestContext
*/
static toReadingContextEnumType(context) {
if (!context)
return undefined;
switch (context) {
case 'Interruption.Begin':
return OCPP1_6.MeterValuesRequestContext.Interruption_Begin;
case 'Interruption.End':
return OCPP1_6.MeterValuesRequestContext.Interruption_End;
case 'Other':
return OCPP1_6.MeterValuesRequestContext.Other;
case 'Sample.Clock':
return OCPP1_6.MeterValuesRequestContext.Sample_Clock;
case 'Sample.Periodic':
return OCPP1_6.MeterValuesRequestContext.Sample_Periodic;
case 'Transaction.Begin':
return OCPP1_6.MeterValuesRequestContext.Transaction_Begin;
case 'Transaction.End':
return OCPP1_6.MeterValuesRequestContext.Transaction_End;
case 'Trigger':
return OCPP1_6.MeterValuesRequestContext.Trigger;
default:
return undefined;
}
}
/**
* Converts OCPP 1.6 MeterValuesRequestContext to native ReadingContextEnum
*/
static fromReadingContextEnumType(context) {
if (!context)
return undefined;
switch (context) {
case OCPP1_6.MeterValuesRequestContext.Interruption_Begin:
return 'Interruption.Begin';
case OCPP1_6.MeterValuesRequestContext.Interruption_End:
return 'Interruption.End';
case OCPP1_6.MeterValuesRequestContext.Other:
return 'Other';
case OCPP1_6.MeterValuesRequestContext.Sample_Clock:
return 'Sample.Clock';
case OCPP1_6.MeterValuesRequestContext.Sample_Periodic:
return 'Sample.Periodic';
case OCPP1_6.MeterValuesRequestContext.Transaction_Begin:
return 'Transaction.Begin';
case OCPP1_6.MeterValuesRequestContext.Transaction_End:
return 'Transaction.End';
case OCPP1_6.MeterValuesRequestContext.Trigger:
return 'Trigger';
default:
return 'Sample.Periodic';
}
}
/**
* Converts native MeasurandEnum to OCPP 1.6 MeterValuesRequestMeasurand
*/
static toMeasurandEnumType(measurand) {
if (!measurand)
return undefined;
switch (measurand) {
case 'Current.Export':
return OCPP1_6.MeterValuesRequestMeasurand.Current_Export;
case 'Current.Import':
return OCPP1_6.MeterValuesRequestMeasurand.Current_Import;
case 'Current.Offered':
return OCPP1_6.MeterValuesRequestMeasurand.Current_Offered;
case 'Energy.Active.Export.Register':
return OCPP1_6.MeterValuesRequestMeasurand.Energy_Active_Export_Register;
case 'Energy.Active.Import.Register':
return OCPP1_6.MeterValuesRequestMeasurand.Energy_Active_Import_Register;
case 'Energy.Reactive.Export.Register':
return OCPP1_6.MeterValuesRequestMeasurand.Energy_Reactive_Export_Register;
case 'Energy.Reactive.Import.Register':
return OCPP1_6.MeterValuesRequestMeasurand.Energy_Reactive_Import_Register;
case 'Energy.Active.Export.Interval':
return OCPP1_6.MeterValuesRequestMeasurand.Energy_Active_Export_Interval;
case 'Energy.Active.Import.Interval':
return OCPP1_6.MeterValuesRequestMeasurand.Energy_Active_Import_Interval;
case 'Energy.Reactive.Export.Interval':
return OCPP1_6.MeterValuesRequestMeasurand.Energy_Reactive_Export_Interval;
case 'Energy.Reactive.Import.Interval':
return OCPP1_6.MeterValuesRequestMeasurand.Energy_Reactive_Import_Interval;
case 'Frequency':
return OCPP1_6.MeterValuesRequestMeasurand.Frequency;
case 'Power.Active.Export':
return OCPP1_6.MeterValuesRequestMeasurand.Power_Active_Export;
case 'Power.Active.Import':
return OCPP1_6.MeterValuesRequestMeasurand.Power_Active_Import;
case 'Power.Factor':
return OCPP1_6.MeterValuesRequestMeasurand.Power_Factor;
case 'Power.Offered':
return OCPP1_6.MeterValuesRequestMeasurand.Power_Offered;
case 'Power.Reactive.Export':
return OCPP1_6.MeterValuesRequestMeasurand.Power_Reactive_Export;
case 'Power.Reactive.Import':
return OCPP1_6.MeterValuesRequestMeasurand.Power_Reactive_Import;
case 'SoC':
return OCPP1_6.MeterValuesRequestMeasurand.SoC;
case 'Voltage':
return OCPP1_6.MeterValuesRequestMeasurand.Voltage;
default:
// Note: OCPP 2.0.1 measurands not supported in 1.6:
// Energy.Active.Net, Energy.Reactive.Net, Energy.Apparent.Net,
// Energy.Apparent.Import, Energy.Apparent.Export
return undefined;
}
}
/**
* Converts OCPP 1.6 MeterValuesRequestMeasurand to native MeasurandEnum
*/
static fromMeasurandEnumType(measurand) {
if (!measurand)
return undefined;
switch (measurand) {
case OCPP1_6.MeterValuesRequestMeasurand.Current_Export:
return 'Current.Export';
case OCPP1_6.MeterValuesRequestMeasurand.Current_Import:
return 'Current.Import';
case OCPP1_6.MeterValuesRequestMeasurand.Current_Offered:
return 'Current.Offered';
case OCPP1_6.MeterValuesRequestMeasurand.Energy_Active_Export_Register:
return 'Energy.Active.Export.Register';
case OCPP1_6.MeterValuesRequestMeasurand.Energy_Active_Import_Register:
return 'Energy.Active.Import.Register';
case OCPP1_6.MeterValuesRequestMeasurand.Energy_Reactive_Export_Register:
return 'Energy.Reactive.Export.Register';
case OCPP1_6.MeterValuesRequestMeasurand.Energy_Reactive_Import_Register:
return 'Energy.Reactive.Import.Register';
case OCPP1_6.MeterValuesRequestMeasurand.Energy_Active_Export_Interval:
return 'Energy.Active.Export.Interval';
case OCPP1_6.MeterValuesRequestMeasurand.Energy_Active_Import_Interval:
return 'Energy.Active.Import.Interval';
case OCPP1_6.MeterValuesRequestMeasurand.Energy_Reactive_Export_Interval:
return 'Energy.Reactive.Export.Interval';
case OCPP1_6.MeterValuesRequestMeasurand.Energy_Reactive_Import_Interval:
return 'Energy.Reactive.Import.Interval';
case OCPP1_6.MeterValuesRequestMeasurand.Frequency:
return 'Frequency';
case OCPP1_6.MeterValuesRequestMeasurand.Power_Active_Export:
return 'Power.Active.Export';
case OCPP1_6.MeterValuesRequestMeasurand.Power_Active_Import:
return 'Power.Active.Import';
case OCPP1_6.MeterValuesRequestMeasurand.Power_Factor:
return 'Power.Factor';
case OCPP1_6.MeterValuesRequestMeasurand.Power_Offered:
return 'Power.Offered';
case OCPP1_6.MeterValuesRequestMeasurand.Power_Reactive_Export:
return 'Power.Reactive.Export';
case OCPP1_6.MeterValuesRequestMeasurand.Power_Reactive_Import:
return 'Power.Reactive.Import';
case OCPP1_6.MeterValuesRequestMeasurand.RPM:
return 'RPM';
case OCPP1_6.MeterValuesRequestMeasurand.SoC:
return 'SoC';
case OCPP1_6.MeterValuesRequestMeasurand.Temperature:
return 'Temperature';
case OCPP1_6.MeterValuesRequestMeasurand.Voltage:
return 'Voltage';
default:
return 'Energy.Active.Import.Register';
}
}
/**
* Converts native LocationEnum to OCPP 1.6 MeterValuesRequestLocation
*/
static toLocationEnumType(location) {
if (!location)
return undefined;
switch (location) {
case 'Body':
return OCPP1_6.MeterValuesRequestLocation.Body;
case 'Cable':
return OCPP1_6.MeterValuesRequestLocation.Cable;
case 'EV':
return OCPP1_6.MeterValuesRequestLocation.EV;
case 'Inlet':
return OCPP1_6.MeterValuesRequestLocation.Inlet;
case 'Outlet':
return OCPP1_6.MeterValuesRequestLocation.Outlet;
default:
return undefined;
}
}
/**
* Converts OCPP 1.6 MeterValuesRequestLocation to native LocationEnum
*/
static fromLocationEnumType(location) {
if (!location)
return undefined;
switch (location) {
case OCPP1_6.MeterValuesRequestLocation.Body:
return 'Body';
case OCPP1_6.MeterValuesRequestLocation.Cable:
return 'Cable';
case OCPP1_6.MeterValuesRequestLocation.EV:
return 'EV';
case OCPP1_6.MeterValuesRequestLocation.Inlet:
return 'Inlet';
case OCPP1_6.MeterValuesRequestLocation.Outlet:
return 'Outlet';
default:
return 'Outlet';
}
}
/**
* Converts native PhaseEnum to OCPP 1.6 MeterValuesRequestPhase
*/
static toPhaseEnumType(phase) {
if (!phase)
return undefined;
switch (phase) {
case 'L1':
return OCPP1_6.MeterValuesRequestPhase.L1;
case 'L2':
return OCPP1_6.MeterValuesRequestPhase.L2;
case 'L3':
return OCPP1_6.MeterValuesRequestPhase.L3;
case 'N':
return OCPP1_6.MeterValuesRequestPhase.N;
case 'L1-N':
return OCPP1_6.MeterValuesRequestPhase.L1_N;
case 'L2-N':
return OCPP1_6.MeterValuesRequestPhase.L2_N;
case 'L3-N':
return OCPP1_6.MeterValuesRequestPhase.L3_N;
case 'L1-L2':
return OCPP1_6.MeterValuesRequestPhase.L1_L2;
case 'L2-L3':
return OCPP1_6.MeterValuesRequestPhase.L2_L3;
case 'L3-L1':
return OCPP1_6.MeterValuesRequestPhase.L3_L1;
default:
return undefined;
}
}
/**
* Converts OCPP 1.6 MeterValuesRequestPhase to native PhaseEnum
*/
static fromPhaseEnumType(phase) {
if (!phase)
return undefined;
switch (phase) {
case OCPP1_6.MeterValuesRequestPhase.L1:
return 'L1';
case OCPP1_6.MeterValuesRequestPhase.L2:
return 'L2';
case OCPP1_6.MeterValuesRequestPhase.L3:
return 'L3';
case OCPP1_6.MeterValuesRequestPhase.N:
return 'N';
case OCPP1_6.MeterValuesRequestPhase.L1_N:
return 'L1-N';
case OCPP1_6.MeterValuesRequestPhase.L2_N:
return 'L2-N';
case OCPP1_6.MeterValuesRequestPhase.L3_N:
return 'L3-N';
case OCPP1_6.MeterValuesRequestPhase.L1_L2:
return 'L1-L2';
case OCPP1_6.MeterValuesRequestPhase.L2_L3:
return 'L2-L3';
case OCPP1_6.MeterValuesRequestPhase.L3_L1:
return 'L3-L1';
default:
return undefined;
}
}
/**
* Converts native UnitOfMeasure to OCPP 1.6 MeterValuesRequestUnit
*/
static toUnitEnumType(unit) {
if (!unit)
return undefined;
switch (unit) {
case 'Wh':
return OCPP1_6.MeterValuesRequestUnit.Wh;
case 'kWh':
return OCPP1_6.MeterValuesRequestUnit.kWh;
case 'varh':
return OCPP1_6.MeterValuesRequestUnit.varh;
case 'kvarh':
return OCPP1_6.MeterValuesRequestUnit.kvarh;
case 'W':
return OCPP1_6.MeterValuesRequestUnit.W;
case 'kW':
return OCPP1_6.MeterValuesRequestUnit.kW;
case 'VA':
return OCPP1_6.MeterValuesRequestUnit.VA;
case 'kVA':
return OCPP1_6.MeterValuesRequestUnit.kVA;
case 'var':
return OCPP1_6.MeterValuesRequestUnit.var;
case 'kvar':
return OCPP1_6.MeterValuesRequestUnit.kvar;
case 'A':
return OCPP1_6.MeterValuesRequestUnit.A;
case 'V':
return OCPP1_6.MeterValuesRequestUnit.V;
case 'K':
return OCPP1_6.MeterValuesRequestUnit.K;
case 'Celsius':
return OCPP1_6.MeterValuesRequestUnit.Celsius;
case 'Fahrenheit':
return OCPP1_6.MeterValuesRequestUnit.Fahrenheit;
case 'Percent':
return OCPP1_6.MeterValuesRequestUnit.Percent;
default:
return undefined;
}
}
/**
* Converts OCPP 1.6 MeterValuesRequestUnit to native unit string
*/
static fromUnitEnumType(unit) {
if (!unit)
return undefined;
switch (unit) {
case OCPP1_6.MeterValuesRequestUnit.Wh:
return 'Wh';
case OCPP1_6.MeterValuesRequestUnit.kWh:
return 'kWh';
case OCPP1_6.MeterValuesRequestUnit.varh:
return 'varh';
case OCPP1_6.MeterValuesRequestUnit.kvarh:
return 'kvarh';
case OCPP1_6.MeterValuesRequestUnit.W:
return 'W';
case OCPP1_6.MeterValuesRequestUnit.kW:
return 'kW';
case OCPP1_6.MeterValuesRequestUnit.VA:
return 'VA';
case OCPP1_6.MeterValuesRequestUnit.kVA:
return 'kVA';
case OCPP1_6.MeterValuesRequestUnit.var:
return 'var';
case OCPP1_6.MeterValuesRequestUnit.kvar:
return 'kvar';
case OCPP1_6.MeterValuesRequestUnit.A:
return 'A';
case OCPP1_6.MeterValuesRequestUnit.V:
return 'V';
case OCPP1_6.MeterValuesRequestUnit.K:
return 'K';
case OCPP1_6.MeterValuesRequestUnit.Celcius:
case OCPP1_6.MeterValuesRequestUnit.Celsius:
return 'Celsius';
case OCPP1_6.MeterValuesRequestUnit.Fahrenheit:
return 'Fahrenheit';
case OCPP1_6.MeterValuesRequestUnit.Percent:
return 'Percent';
default:
return undefined;
}
}
/**
* OCPP 1.6 SampledValue type (inline from MeterValuesRequest)
*/
static toSampledValueType(sampledValue) {
return {
value: String(sampledValue.value * 10 ** (sampledValue.unitOfMeasure?.multiplier ?? 0)),
context: MeterValueMapper.toReadingContextEnumType(sampledValue.context),
measurand: MeterValueMapper.toMeasurandEnumType(sampledValue.measurand),
phase: MeterValueMapper.toPhaseEnumType(sampledValue.phase),
location: MeterValueMapper.toLocationEnumType(sampledValue.location),
unit: MeterValueMapper.toUnitEnumType(sampledValue.unitOfMeasure?.unit),
// Note: no support for OCPP 1.6 signedMeterValues
};
}
static toMeterValueType(meterValue) {
return {
timestamp: meterValue.timestamp,
sampledValue: MeterValueMapper.toSampledValueTypes(meterValue.sampledValue),
};
}
static toSampledValueTypes(sampledValues) {
return sampledValues.map((sv) => MeterValueMapper.toSampledValueType(sv));
}
/**
* Validates the format field for OCPP 1.6 sampledValue.
*/
static validateFormat(format) {
return format === undefined || format === OCPP1_6.MeterValuesRequestFormat.Raw;
}
/**
* Converts OCPP 1.6 sampledValue to native SampledValue
*/
static fromSampledValueType(sampledValueType) {
// Validate format - return undefined if not Raw or undefined
if (!MeterValueMapper.validateFormat(sampledValueType.format)) {
console.warn(`Unsupported OCPP 1.6 sampledValue format: ${sampledValueType.format}`);
return undefined;
}
const sampledValue = {
value: parseFloat(sampledValueType.value),
context: MeterValueMapper.fromReadingContextEnumType(sampledValueType.context),
measurand: MeterValueMapper.fromMeasurandEnumType(sampledValueType.measurand),
phase: MeterValueMapper.fromPhaseEnumType(sampledValueType.phase),
location: MeterValueMapper.fromLocationEnumType(sampledValueType.location),
};
const unit = MeterValueMapper.fromUnitEnumType(sampledValueType.unit);
if (unit) {
sampledValue.unitOfMeasure = {
unit,
multiplier: 0, // OCPP 1.6 does not have multiplier
};
}
return sampledValue;
}
/**
* Converts OCPP 1.6 SampledValueType[] back to SampledValue[]
*/
static fromSampledValueTypes(sampledValueTypes) {
const sampledValues = sampledValueTypes.map((svt) => MeterValueMapper.fromSampledValueType(svt));
return sampledValues;
}
/**
* Converts OCPP 1.6 MeterValueType back to a partial MeterValue structure
*/
static fromMeterValueType(meterValueType) {
return {
timestamp: meterValueType.timestamp,
sampledValue: MeterValueMapper.fromSampledValueTypes(meterValueType.sampledValue),
};
}
}
//# sourceMappingURL=MeterValueMapper.js.map