kopia lustrzana https://github.com/weetmuts/wmbusmeters
Add new units for phase angle: deg rad. Add more fields to abbb23.
rodzic
414e55a17a
commit
a920e25d45
|
@ -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.",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
|
17
src/units.cc
17
src/units.cc
|
@ -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;
|
||||
|
|
10
src/units.h
10
src/units.h
|
@ -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);
|
||||
|
|
Ładowanie…
Reference in New Issue