From b9f756e5e9e81aa01e938cfe17f40a49c5000871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20=C3=96hrstr=C3=B6m?= Date: Mon, 12 Dec 2022 17:41:22 +0100 Subject: [PATCH] Add m3ch unit for power based on m3c. --- src/meters.cc | 47 ++++++++++++++++++------------ src/meters_common_implementation.h | 8 ++--- src/testinternals.cc | 4 +++ src/units.cc | 1 + src/units.h | 1 + test.sh | 3 ++ 6 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/meters.cc b/src/meters.cc index 72f1bd4..93d2aea 100644 --- a/src/meters.cc +++ b/src/meters.cc @@ -251,6 +251,17 @@ void MeterCommonImplementation::addExtraCalculatedField(string ecf) Quantity quantity = toQuantity(unit); + FieldInfo *existing = findFieldInfo(vname, quantity); + if (existing != NULL) + { + if (!canConvert(unit, existing->displayUnit())) + { + warning("Warning! Cannot add the calculated field: %s since it would conflict with the already declared field %s for quantity %s.\n", + parts[0].c_str(), vname.c_str(), toString(quantity)); + return; + } + } + addNumericFieldWithCalculator( vname, "Calculated: "+ecf, @@ -394,13 +405,13 @@ void MeterCommonImplementation::addNumericFieldWithExtractor(string vname, Quantity vquantity, VifScaling vif_scaling, FieldMatcher matcher, - Unit use_unit) + Unit display_unit) { field_infos_.emplace_back( FieldInfo(field_infos_.size(), vname, vquantity, - use_unit == Unit::Unknown ? defaultUnitForQuantity(vquantity) : use_unit, + display_unit == Unit::Unknown ? defaultUnitForQuantity(vquantity) : display_unit, vif_scaling, matcher, help, @@ -419,7 +430,7 @@ void MeterCommonImplementation::addNumericFieldWithCalculator(string vname, PrintProperties print_properties, Quantity vquantity, string formula, - Unit use_unit) + Unit display_unit) { Formula *f = newFormula(); bool ok = f->parse(this, formula); @@ -438,7 +449,7 @@ void MeterCommonImplementation::addNumericFieldWithCalculator(string vname, FieldInfo(field_infos_.size(), vname, vquantity, - use_unit == Unit::Unknown ? defaultUnitForQuantity(vquantity) : use_unit, + display_unit == Unit::Unknown ? defaultUnitForQuantity(vquantity) : display_unit, VifScaling::Auto, FieldMatcher::noMatcher(), help, @@ -458,7 +469,7 @@ void MeterCommonImplementation::addNumericFieldWithCalculatorAndMatcher(string v Quantity vquantity, string formula, FieldMatcher matcher, - Unit use_unit) + Unit display_unit) { Formula *f = newFormula(); bool ok = f->parse(this, formula); @@ -477,7 +488,7 @@ void MeterCommonImplementation::addNumericFieldWithCalculatorAndMatcher(string v FieldInfo(field_infos_.size(), vname, vquantity, - use_unit == Unit::Unknown ? defaultUnitForQuantity(vquantity) : use_unit, + display_unit == Unit::Unknown ? defaultUnitForQuantity(vquantity) : display_unit, VifScaling::Auto, matcher, help, @@ -522,13 +533,13 @@ void MeterCommonImplementation::addNumericField( Quantity vquantity, PrintProperties print_properties, string help, - Unit use_unit) + Unit display_unit) { field_infos_.emplace_back( FieldInfo(field_infos_.size(), vname, vquantity, - use_unit == Unit::Unknown ? defaultUnitForQuantity(vquantity) : use_unit, + display_unit == Unit::Unknown ? defaultUnitForQuantity(vquantity) : display_unit, VifScaling::None, FieldMatcher::noMatcher(), help, @@ -1169,8 +1180,8 @@ bool checkPrintableField(string *buf, string field, Meter *m, Telegram *t, char else { // Doubles have to be converted into the proper unit. - string default_unit = unitToStringLowerCase(fi.displayUnit()); - string var = fi.vname()+"_"+default_unit; + string display_unit_s = unitToStringLowerCase(fi.displayUnit()); + string var = fi.vname()+"_"+display_unit_s; if (field == var) { // Default unit. @@ -1713,10 +1724,10 @@ string FieldInfo::generateFieldNameWithUnit(DVEntry *dve) return field_name_->apply(dve); } - string default_unit = unitToStringLowerCase(displayUnit()); + string display_unit_s = unitToStringLowerCase(displayUnit()); string var = field_name_->apply(dve); - return var+"_"+default_unit; + return var+"_"+display_unit_s; } @@ -1724,7 +1735,7 @@ string FieldInfo::renderJson(Meter *m, DVEntry *dve) { string s; - string default_unit = unitToStringLowerCase(displayUnit()); + string display_unit_s = unitToStringLowerCase(displayUnit()); string field_name = generateFieldNameNoUnit(dve); if (xuantity() == Quantity::Text) @@ -1749,16 +1760,16 @@ string FieldInfo::renderJson(Meter *m, DVEntry *dve) { if (displayUnit() == Unit::DateLT) { - s += "\""+field_name+"_"+default_unit+"\":\""+strdate(m->getNumericValue(field_name, Unit::DateLT))+"\""; + s += "\""+field_name+"_"+display_unit_s+"\":\""+strdate(m->getNumericValue(field_name, Unit::DateLT))+"\""; } else if (displayUnit() == Unit::DateTimeLT) { - s += "\""+field_name+"_"+default_unit+"\":\""+strdatetime(m->getNumericValue(field_name, Unit::DateTimeLT))+"\""; + s += "\""+field_name+"_"+display_unit_s+"\":\""+strdatetime(m->getNumericValue(field_name, Unit::DateTimeLT))+"\""; } else { // All numeric values. - s += "\""+field_name+"_"+default_unit+"\":"+valueToString(m->getNumericValue(field_name, displayUnit()), displayUnit()); + s += "\""+field_name+"_"+display_unit_s+"\":"+valueToString(m->getNumericValue(field_name, displayUnit()), displayUnit()); } } @@ -1929,7 +1940,7 @@ void MeterCommonImplementation::printMeter(Telegram *t, { if (fi.printProperties().hasJSON() && !fi.printProperties().hasHIDE()) { - string default_unit = unitToStringUpperCase(fi.displayUnit()); + string display_unit_s = unitToStringUpperCase(fi.displayUnit()); string var = fi.vname(); std::transform(var.begin(), var.end(), var.begin(), ::toupper); if (fi.xuantity() == Quantity::Text) @@ -1939,7 +1950,7 @@ void MeterCommonImplementation::printMeter(Telegram *t, } else { - string envvar = "METER_"+var+"_"+default_unit+"="+valueToString(getNumericValue(&fi, fi.displayUnit()), fi.displayUnit()); + string envvar = "METER_"+var+"_"+display_unit_s+"="+valueToString(getNumericValue(&fi, fi.displayUnit()), fi.displayUnit()); envs->push_back(envvar); } } diff --git a/src/meters_common_implementation.h b/src/meters_common_implementation.h index d3e2f1b..1614a3b 100644 --- a/src/meters_common_implementation.h +++ b/src/meters_common_implementation.h @@ -145,7 +145,7 @@ protected: Quantity vquantity, // Value belongs to this quantity, this quantity determines the default unit. VifScaling vif_scaling, // How should any Vif value be scaled. FieldMatcher matcher, - Unit use_unit = Unit::Unknown); // If specified use this unit for the json field instead instead of the default unit. + Unit display_unit = Unit::Unknown); // If specified use this unit for the json field instead instead of the default unit. void addNumericFieldWithCalculator( string vname, // Name of value without unit, eg "total" "total_month{storagenr}" @@ -153,7 +153,7 @@ protected: PrintProperties print_properties, // Should this be printed by default in fields,json and hr. Quantity vquantity, // Value belongs to this quantity, this quantity determines the default unit. string formula, // The formula can reference the other fields and + them together. - Unit use_unit = Unit::Unknown); // If specified use this unit for the json field instead instead of the default unit. + Unit display_unit = Unit::Unknown); // If specified use this unit for the json field instead instead of the default unit. void addNumericFieldWithCalculatorAndMatcher( string vname, // Name of value without unit, eg "total" "total_month{storagenr}" @@ -162,7 +162,7 @@ protected: Quantity vquantity, // Value belongs to this quantity, this quantity determines the default unit. string formula, // The formula can reference the other fields and + them together. FieldMatcher matcher, // We can generate a calculated field per match. - Unit use_unit = Unit::Unknown); // If specified use this unit for the json field instead instead of the default unit. + Unit display_unit = Unit::Unknown); // If specified use this unit for the json field instead instead of the default unit. void addNumericField( string vname, // Name of value without unit, eg total @@ -177,7 +177,7 @@ protected: Quantity vquantity, // Value belongs to this quantity. PrintProperties print_properties, // Should this be printed by default in fields,json and hr. string help, - Unit use_unit = Unit::Unknown); // If specified use this unit for the json field instead instead of the default unit. + Unit display_unit = Unit::Unknown); // If specified use this unit for the json field instead instead of the default unit. #define SET_STRING_FUNC(varname) {[=](string s){varname = s;}} #define GET_STRING_FUNC(varname) {[=](){return varname; }} diff --git a/src/testinternals.cc b/src/testinternals.cc index 9e575bb..691eb85 100644 --- a/src/testinternals.cc +++ b/src/testinternals.cc @@ -1929,6 +1929,10 @@ LIST_OF_QUANTITIES fill_with_units_from(Quantity::Power, &to_set); test_si_convert(1, 1, Unit::KW, "kw", Unit::KW, "kw", Quantity::Power, &from_set, &to_set); + // The power variant is m3ch. + test_si_convert(99.0, 99.0, Unit::M3CH, "m3ch", Unit::M3CH, "m3ch", Quantity::Power, &from_set, &to_set); + + test_expected_failed_si_convert(Unit::M3CH, Unit::KW, Quantity::Power); check_units_tested(from_set, to_set, Quantity::Power); diff --git a/src/units.cc b/src/units.cc index d4439c8..691e38e 100644 --- a/src/units.cc +++ b/src/units.cc @@ -81,6 +81,7 @@ using namespace std; X(M3C, 1.0, SIExp().m(3).c(1)) \ \ X(KW, 1000.0, SIExp().kg(1).m(2).s(-3)) \ + X(M3CH, 3600.0, SIExp().m(3).c(1).s(-1)) \ \ X(M3, 1.0, SIExp().m(3)) \ X(L, 1.0/1000.0, SIExp().m(3)) \ diff --git a/src/units.h b/src/units.h index ae674ba..d2f1610 100644 --- a/src/units.h +++ b/src/units.h @@ -85,6 +85,7 @@ LIST_OF_QUANTITIES X(M3C,m3c,"m³°C",Energy,"cubic meter celsius") \ \ X(KW,kw,"kW",Power,"kilo Watt") \ + X(M3CH,m3ch,"m³°C/h",Power,"cubic meter celsius per hour") \ \ X(M3,m3,"m³",Volume,"cubic meter") \ X(L,l,"l",Volume,"litre") \ diff --git a/test.sh b/test.sh index 61c3463..7d95c37 100755 --- a/test.sh +++ b/test.sh @@ -87,6 +87,9 @@ if [ "$?" != "0" ]; then RC="1"; fi tests/test_conversions.sh $PROG if [ "$?" != "0" ]; then RC="1"; fi +tests/test_calculate.sh $PROG +if [ "$?" != "0" ]; then RC="1"; fi + tests/test_formulas.sh $PROG if [ "$?" != "0" ]; then RC="1"; fi