Add new units for phase angle: deg rad. Add more fields to abbb23.

pull/1021/head
Fredrik Öhrström 2023-08-26 17:05:52 +02:00
rodzic 414e55a17a
commit a920e25d45
5 zmienionych plików z 229 dodań i 1 usunięć

Wyświetl plik

@ -529,6 +529,190 @@ namespace
0.001
);
addNumericFieldWithExtractor(
"power_l1",
"Power factor for phase L1.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Dimensionless,
VifScaling::None,
FieldMatcher::build()
.set(DifVifKey("02FFE0FF8100")),
Unit::FACTOR,
0.001
);
addNumericFieldWithExtractor(
"power_l2",
"Power factor for phase L2.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Dimensionless,
VifScaling::None,
FieldMatcher::build()
.set(DifVifKey("02FFE0FF8200")),
Unit::FACTOR,
0.001
);
addNumericFieldWithExtractor(
"power_l3",
"Power factor.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Dimensionless,
VifScaling::None,
FieldMatcher::build()
.set(DifVifKey("02FFE0FF8300")),
Unit::FACTOR,
0.001
);
addNumericFieldWithExtractor(
"power_phase_angle",
"Total power phase angle.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Angle,
VifScaling::NoneSigned,
FieldMatcher::build()
.set(DifVifKey("02FFD200")),
Unit::DEGREE,
0.1
);
addNumericFieldWithExtractor(
"phase_angle_power_l1",
"Power phase angle for phase L1.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Angle,
VifScaling::NoneSigned,
FieldMatcher::build()
.set(DifVifKey("02FFD2FF8100")),
Unit::DEGREE,
0.1
);
addNumericFieldWithExtractor(
"phase_angle_power_l2",
"Power phase angle for phase L2.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Angle,
VifScaling::NoneSigned,
FieldMatcher::build()
.set(DifVifKey("02FFD2FF8200")),
Unit::DEGREE,
0.1
);
addNumericFieldWithExtractor(
"phase_angle_power_l3",
"Power phase angle for phase L3.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Angle,
VifScaling::NoneSigned,
FieldMatcher::build()
.set(DifVifKey("02FFD2FF8300")),
Unit::DEGREE,
0.1
);
addNumericFieldWithExtractor(
"total_reactive_energy_consumption",
"Total cumulative reactive kvarh imported energy.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Reactive_Energy,
VifScaling::Auto,
FieldMatcher::build()
.set(MeasurementType::Instantaneous)
.set(VIFRange::AnyEnergyVIF)
.set(SubUnitNr(2))
.add(VIFCombinableRaw(0)),
Unit::KVARH
);
addNumericFieldWithExtractor(
"total_reactive_energy_consumption_tariff_{tariff_counter}",
"Total cumulative reactive kvarh imported energy per tariff.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Energy,
VifScaling::Auto,
FieldMatcher::build()
.set(MeasurementType::Instantaneous)
.set(VIFRange::AnyEnergyVIF)
.set(SubUnitNr(2))
.set(TariffNr(1),TariffNr(4))
.add(VIFCombinableRaw(0))
);
addNumericFieldWithExtractor(
"total_reactive_energy_production",
"Total cumulative reactive kvarh exported energy.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Reactive_Energy,
VifScaling::Auto,
FieldMatcher::build()
.set(MeasurementType::Instantaneous)
.set(VIFRange::AnyEnergyVIF)
.set(SubUnitNr(3))
.add(VIFCombinableRaw(0)),
Unit::KVARH
);
addNumericFieldWithExtractor(
"total_reactive_energy_production_tariff_{tariff_counter}",
"Total cumulative reactive kvarh exported energy per tariff.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Energy,
VifScaling::Auto,
FieldMatcher::build()
.set(MeasurementType::Instantaneous)
.set(VIFRange::AnyEnergyVIF)
.set(SubUnitNr(3))
.set(TariffNr(1),TariffNr(4))
.add(VIFCombinableRaw(0))
);
addNumericFieldWithExtractor(
"current_quadrant",
"The quadrant in which the current is measured.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Dimensionless,
VifScaling::None,
FieldMatcher::build()
.set(DifVifKey("01FF9700")),
Unit::NUMBER
);
addNumericFieldWithExtractor(
"current_quadrant_l1",
"The quadrant in which the current is measured for phase L1.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Dimensionless,
VifScaling::None,
FieldMatcher::build()
.set(DifVifKey("01FF97FF8100")),
Unit::NUMBER
);
addNumericFieldWithExtractor(
"current_quadrant_l2",
"The quadrant in which the current is measured for phase L2.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Dimensionless,
VifScaling::None,
FieldMatcher::build()
.set(DifVifKey("01FF97FF8200")),
Unit::NUMBER
);
addNumericFieldWithExtractor(
"current_quadrant_l3",
"The quadrant in which the current is measured for phase L3.",
DEFAULT_PRINT_PROPERTIES,
Quantity::Dimensionless,
VifScaling::None,
FieldMatcher::build()
.set(DifVifKey("01FF97FF8300")),
Unit::NUMBER
);
addNumericFieldWithExtractor(
"energy_co2",
"Energy in co2.",

Wyświetl plik

@ -2196,6 +2196,11 @@ bool FieldInfo::extractNumeric(Meter *m, Telegram *t, DVEntry *dve)
// Hardcoded scale factor for this field used for manufacturer specific values without vif units.
extracted_double_value *= scale();
}
if (overrideConversion(decoded_unit, display_unit_))
{
// Special case! Transform the decoded unit into the display unit. I.e. kwh was replaced with kvarh.
decoded_unit = display_unit_;
}
m->setNumericValue(this, dve, display_unit_, convert(extracted_double_value, decoded_unit, display_unit_));
t->addMoreExplanation(dve->offset, renderJson(m, dve));
found = true;

Wyświetl plik

@ -2026,9 +2026,23 @@ LIST_OF_QUANTITIES
test_si_convert(2211717, 2211717, Unit::COUNTER, "counter", Unit::FACTOR, "counter", Quantity::Dimensionless, &from_set, &to_set);
test_si_convert(2211717, 2211717, Unit::FACTOR, "counter", Unit::COUNTER, "counter", Quantity::Dimensionless, &from_set, &to_set);
test_si_convert(2211717, 2211717, Unit::NUMBER, "counter", Unit::COUNTER, "counter", Quantity::Dimensionless, &from_set, &to_set);
test_si_convert(2211717, 2211717, Unit::FACTOR, "counter", Unit::NUMBER, "counter", Quantity::Dimensionless, &from_set, &to_set);
check_units_tested(from_set, to_set, Quantity::Dimensionless);
// Test angles: deg rad
/////////////////////////////////////////////////////////////////////////////////////////////////////
q_set.erase(Quantity::Angle);
fill_with_units_from(Quantity::Angle, &from_set);
fill_with_units_from(Quantity::Angle, &to_set);
test_si_convert(180, 3.1415926535897931l, Unit::DEGREE, "deg", Unit::RADIAN, "rad", Quantity::Angle, &from_set, &to_set);
test_si_convert(3.1415926535897931l, 180, Unit::RADIAN, "rad", Unit::DEGREE, "deg", Quantity::Angle, &from_set, &to_set);
check_units_tested(from_set, to_set, Quantity::Angle);
// Test point in time units: ut utc lt
/////////////////////////////////////////////////////////////////////////////////////////////////////

Wyświetl plik

@ -59,11 +59,17 @@ using namespace std;
X(BAR, PA, {vto=vfrom*100000.0;}) \
X(COUNTER, FACTOR,{vto=vfrom;}) \
X(FACTOR, COUNTER, {vto=vfrom;}) \
X(COUNTER, NUMBER,{vto=vfrom;}) \
X(NUMBER, COUNTER, {vto=vfrom;}) \
X(FACTOR, NUMBER, {vto=vfrom;}) \
X(NUMBER, FACTOR, {vto=vfrom;}) \
X(UnixTimestamp,DateTimeLT, {vto=vfrom; }) \
X(DateTimeLT,UnixTimestamp, {vto=vfrom; }) \
X(DateLT,UnixTimestamp, {vto=vfrom; }) \
X(DateTimeLT, DateLT, {vto=vfrom; }) \
X(DateLT, DateTimeLT, {vto=vfrom; }) \
X(DEGREE, RADIAN, {vto=vfrom*M_PI/180.0;}) \
X(RADIAN, DEGREE, {vto=vfrom*180.0/M_PI;}) \
#define LIST_OF_SI_CONVERSIONS \
@ -111,8 +117,11 @@ using namespace std;
\
X(RH, 1.0, SIExp()) \
X(HCA, 1.0, SIExp()) \
X(DEGREE, 1.0, SIExp()) \
X(RADIAN, 180.0/M_PI, SIExp()) \
X(COUNTER, 1.0, SIExp()) \
X(FACTOR, 1.0, SIExp()) \
X(NUMBER, 1.0, SIExp()) \
X(TXT, 1.0, SIExp()) \
@ -138,6 +147,14 @@ LIST_OF_UNITS
return SI_Unknown;
}
bool overrideConversion(Unit from, Unit to)
{
// The mbus protocol lacks kvarh and kva. Some meters, like the abbb23 uses kwh for kvarh.
// Permit 1 to 1 conversion from kwh to kvarh and kva in extractNumeric.
if (from == Unit::KWH && (to == Unit::KVARH || to == Unit::KVAH)) return true;
return false;
}
bool canConvert(Unit ufrom, Unit uto)
{
if (ufrom == uto) return true;

Wyświetl plik

@ -53,7 +53,8 @@
X(RelativeHumidity,RH) \
X(HCA,HCA) \
X(Text,TXT) \
X(Dimensionless,COUNTER) \
X(Angle,DEGREE) \
X(Dimensionless,COUNTER) \
enum class Quantity
{
@ -114,8 +115,11 @@ LIST_OF_QUANTITIES
X(RH,rh,"RH",RelativeHumidity,"relative humidity") \
X(HCA,hca,"hca",HCA,"heat cost allocation") \
X(TXT,txt,"txt",Text,"text") \
X(DEGREE,deg,"°",Angle,"degree") \
X(RADIAN,rad,"rad",Angle,"radian") \
X(COUNTER,counter,"counter",Dimensionless,"counter") \
X(FACTOR,factor,"factor",Dimensionless,"factor") \
X(NUMBER,nr,"number",Dimensionless,"number") \
enum class Unit
{
@ -267,6 +271,10 @@ double convert(double v, Unit from, Unit to);
Unit whenMultiplied(Unit left, Unit right);
double multiply(double l, Unit left, double r, Unit right);
// Used to convert protocol KWH to KVARH/KVA, strictly speaking
// not a valid conversion, but permitted to work around limitations in the mbus protocol usage.
bool overrideConversion(Unit from, Unit to);
// Either uppercase KWH or lowercase kwh works here.
Unit toUnit(std::string s);
const SIUnit &toSIUnit(Unit u);