From 3e56671bfc8495092ca083c1ead16120950f73a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20=C3=96hrstr=C3=B6m?= Date: Sat, 23 Apr 2022 10:18:04 +0200 Subject: [PATCH] User meter->getNumericValue instead of fi->getValueDouble. --- src/meters.cc | 114 ++++++++++++++++++++++++++++---------------------- src/meters.h | 48 +++++++++++---------- 2 files changed, 92 insertions(+), 70 deletions(-) diff --git a/src/meters.cc b/src/meters.cc index 5ee4f8f..f5701fe 100644 --- a/src/meters.cc +++ b/src/meters.cc @@ -1230,10 +1230,14 @@ string concatAllFields(Meter *m, Telegram *t, char c, vector &fields, { if (fi.printProperties().hasFIELD()) { - if (fi.hasGetValueDouble()) + if (fi.xuantity() == Quantity::Text) + { + s += m->getStringValue(&fi); + } + else { Unit u = replaceWithConversionUnit(fi.defaultUnit(), cs); - double v = fi.getValueDouble(u); + double v = m->getNumericValue(&fi, u); if (hr) { s += valueToString(v, u); s += " "+unitToStringHR(u); @@ -1241,10 +1245,6 @@ string concatAllFields(Meter *m, Telegram *t, char c, vector &fields, s += to_string(v); } } - if (fi.hasGetValueString()) - { - s += fi.getValueString(); - } s += c; } } @@ -1318,16 +1318,16 @@ bool checkPrintableField(string *buf, string field, Meter *m, Telegram *t, char { for (FieldInfo &fi : fields) { - if (fi.hasGetValueString()) + if (fi.xuantity() == Quantity::Text) { // Strings are simply just print them. if (field == fi.vname()) { - *buf += fi.getValueString() + c; + *buf += m->getStringValue(&fi) + c; return true; } } - else if (fi.hasGetValueDouble()) + else { // Doubles have to be converted into the proper unit. string default_unit = unitToStringLowerCase(fi.defaultUnit()); @@ -1335,7 +1335,7 @@ bool checkPrintableField(string *buf, string field, Meter *m, Telegram *t, char if (field == var) { // Default unit. - *buf += valueToString(fi.getValueDouble(fi.defaultUnit()), fi.defaultUnit()) + c; + *buf += valueToString(m->getNumericValue(&fi, fi.defaultUnit()), fi.defaultUnit()) + c; return true; } else @@ -1348,7 +1348,7 @@ bool checkPrintableField(string *buf, string field, Meter *m, Telegram *t, char string var = fi.vname()+"_"+unit; if (field == var) { - *buf += valueToString(fi.getValueDouble(u), u) + c; + *buf += valueToString(m->getNumericValue(&fi, u), u) + c; return true; } } @@ -1491,13 +1491,25 @@ void MeterCommonImplementation::processContent(Telegram *t) void MeterCommonImplementation::setNumericValue(FieldInfo *fi, Unit u, double v) { + if (fi->hasSetNumericValueOverride()) + { + // Use setter function to store value somewhere. + fi->setNumericValueOverride(u, v); + return; + } + + // Store value in default meter location for numeric values. string field_name_no_unit = fi->vname(); - //printf("Setting numeric %s = %f\n", field_name_no_unit.c_str(), v); numeric_values_[field_name_no_unit] = NumericField(u, v, fi); } double MeterCommonImplementation::getNumericValue(FieldInfo *fi, Unit to) { + if (fi->hasGetNumericValueOverride()) + { + return fi->getNumericValueOverride(to); + } + string field_name_no_unit = fi->vname(); if (numeric_values_.count(field_name_no_unit) == 0) return -471147114711; NumericField &nf = numeric_values_[field_name_no_unit]; @@ -1506,6 +1518,12 @@ double MeterCommonImplementation::getNumericValue(FieldInfo *fi, Unit to) void MeterCommonImplementation::setStringValue(FieldInfo *fi, string v) { + if (fi->hasSetStringValueOverride()) + { + fi->setStringValueOverride(v); + return; + } + string field_name_no_unit = fi->vname(); //printf("Setting string %s = %s\n", field_name_no_unit.c_str(), v.c_str()); string_values_[field_name_no_unit] = StringField(v, fi); @@ -1513,6 +1531,11 @@ void MeterCommonImplementation::setStringValue(FieldInfo *fi, string v) string MeterCommonImplementation::getStringValue(FieldInfo *fi) { + if (fi->hasGetStringValueOverride()) + { + return fi->getStringValueOverride(); + } + string field_name_no_unit = fi->vname(); if (string_values_.count(field_name_no_unit) == 0) return "???"; StringField &sf = string_values_[field_name_no_unit]; @@ -1539,17 +1562,17 @@ string MeterCommonImplementation::renderJsonOnlyDefaultUnit(string vname) FieldInfo *fi = findFieldInfo(vname); if (fi == NULL) return "unknown field "+vname; - return fi->renderJsonOnlyDefaultUnit(); + return fi->renderJsonOnlyDefaultUnit(this); } -string FieldInfo::renderJsonOnlyDefaultUnit() +string FieldInfo::renderJsonOnlyDefaultUnit(Meter *m) { - return renderJson(NULL); + return renderJson(m, NULL); } -string FieldInfo::renderJsonText() +string FieldInfo::renderJsonText(Meter *m) { - return renderJson(NULL); + return renderJson(m, NULL); } string FieldInfo::generateFieldName(DVEntry *dve) @@ -1565,19 +1588,19 @@ string FieldInfo::generateFieldName(DVEntry *dve) return vname()+"_"+default_unit; } -string FieldInfo::renderJson(vector *conversions) +string FieldInfo::renderJson(Meter *m, vector *conversions) { string s; string default_unit = unitToStringLowerCase(defaultUnit()); string var = vname(); - if (hasGetValueString()) + if (xuantity() == Quantity::Text) { - s += "\""+var+"\":\""+getValueString()+"\""; + s += "\""+var+"\":\""+m->getStringValue(this)+"\""; } - else if (hasGetValueDouble()) + else { - s += "\""+var+"_"+default_unit+"\":"+valueToString(getValueDouble(defaultUnit()), defaultUnit()); + s += "\""+var+"_"+default_unit+"\":"+valueToString(m->getNumericValue(this, defaultUnit()), defaultUnit()); if (conversions != NULL) { @@ -1586,14 +1609,10 @@ string FieldInfo::renderJson(vector *conversions) { string unit = unitToStringLowerCase(u); // Appending extra conversion unit. - s += ",\""+var+"_"+unit+"\":"+valueToString(getValueDouble(u), u); + s += ",\""+var+"_"+unit+"\":"+valueToString(m->getNumericValue(this, u), u); } } } - else - { - s = "?"; - } return s; } @@ -1649,7 +1668,7 @@ void MeterCommonImplementation::printMeter(Telegram *t, { if (fi.printProperties().hasJSON()) { - s += indent+fi.renderJson(&conversions())+","+newline; + s += indent+fi.renderJson(this, &conversions())+","+newline; } } s += indent+"\"timestamp\":\""+datetimeOfUpdateRobot()+"\""; @@ -1696,26 +1715,28 @@ void MeterCommonImplementation::printMeter(Telegram *t, envs->push_back(string("METER_RSSI_DBM=")+to_string(t->about.rssi_dbm)); } - for (FieldInfo p : field_infos_) + for (FieldInfo& fi : field_infos_) { - if (p.printProperties().hasJSON()) + if (fi.printProperties().hasJSON()) { - string default_unit = unitToStringUpperCase(p.defaultUnit()); - string var = p.vname(); + string default_unit = unitToStringUpperCase(fi.defaultUnit()); + string var = fi.vname(); std::transform(var.begin(), var.end(), var.begin(), ::toupper); - if (p.hasGetValueString()) { - string envvar = "METER_"+var+"="+p.getValueString(); + if (fi.xuantity() == Quantity::Text) + { + string envvar = "METER_"+var+"="+getStringValue(&fi); envs->push_back(envvar); } - if (p.hasGetValueDouble()) { - string envvar = "METER_"+var+"_"+default_unit+"="+valueToString(p.getValueDouble(p.defaultUnit()), p.defaultUnit()); + else + { + string envvar = "METER_"+var+"_"+default_unit+"="+valueToString(getNumericValue(&fi, fi.defaultUnit()), fi.defaultUnit()); envs->push_back(envvar); - Unit u = replaceWithConversionUnit(p.defaultUnit(), conversions_); - if (u != p.defaultUnit()) + Unit u = replaceWithConversionUnit(fi.defaultUnit(), conversions_); + if (u != fi.defaultUnit()) { string unit = unitToStringUpperCase(u); - string envvar = "METER_"+var+"_"+unit+"="+valueToString(p.getValueDouble(u), u); + string envvar = "METER_"+var+"_"+unit+"="+valueToString(getNumericValue(&fi, u), u); envs->push_back(envvar); } } @@ -2115,9 +2136,8 @@ bool FieldInfo::extractNumeric(Meter *m, Telegram *t, DVEntry *dve) { decoded_unit = toDefaultUnit(matcher_.vif_range); } - setValueDouble(decoded_unit, extracted_double_value); m->setNumericValue(this, decoded_unit, extracted_double_value); - t->addMoreExplanation(dve->offset, renderJson(&m->conversions())); + t->addMoreExplanation(dve->offset, renderJson(m, &m->conversions())); found = true; } return found; @@ -2159,9 +2179,8 @@ bool FieldInfo::extractString(Meter *m, Telegram *t, DVEntry *dve) if (dve->extractLong(&extracted_bits)) { string translated_bits = lookup().translate(extracted_bits); - setValueString(translated_bits); m->setStringValue(this, translated_bits); - t->addMoreExplanation(dve->offset, renderJsonText()); + t->addMoreExplanation(dve->offset, renderJsonText(m)); found = true; } } @@ -2170,9 +2189,8 @@ bool FieldInfo::extractString(Meter *m, Telegram *t, DVEntry *dve) struct tm datetime; dve->extractDate(&datetime); string extracted_device_date_time = strdatetime(&datetime); - setValueString(extracted_device_date_time); m->setStringValue(this, extracted_device_date_time); - t->addMoreExplanation(dve->offset, renderJsonText()); + t->addMoreExplanation(dve->offset, renderJsonText(m)); found = true; } else if (matcher_.vif_range == VIFRange::Date) @@ -2180,9 +2198,8 @@ bool FieldInfo::extractString(Meter *m, Telegram *t, DVEntry *dve) struct tm date; dve->extractDate(&date); string extracted_device_date = strdate(&date); - setValueString(extracted_device_date); m->setStringValue(this, extracted_device_date); - t->addMoreExplanation(dve->offset, renderJsonText()); + t->addMoreExplanation(dve->offset, renderJsonText(m)); found = true; } else if (matcher_.vif_range == VIFRange::EnhancedIdentification || @@ -2190,9 +2207,8 @@ bool FieldInfo::extractString(Meter *m, Telegram *t, DVEntry *dve) { string extracted_id; dve->extractReadableString(&extracted_id); - setValueString(extracted_id); m->setStringValue(this, extracted_id); - t->addMoreExplanation(dve->offset, renderJsonText()); + t->addMoreExplanation(dve->offset, renderJsonText(m)); found = true; } else diff --git a/src/meters.h b/src/meters.h index 1d7cf75..ad45149 100644 --- a/src/meters.h +++ b/src/meters.h @@ -316,10 +316,10 @@ struct FieldInfo FieldMatcher matcher, string help, PrintProperties print_properties, - function get_value_double, - function get_value_string, - function set_value_double, - function set_value_string, + function get_numeric_value_override, + function get_string_value_override, + function set_numeric_value_override, + function set_string_value_override, Translate::Lookup lookup ) : vname_(vname), @@ -329,10 +329,10 @@ struct FieldInfo matcher_(matcher), help_(help), print_properties_(print_properties), - get_value_double_(get_value_double), - get_value_string_(get_value_string), - set_value_double_(set_value_double), - set_value_string_(set_value_string), + get_numeric_value_override_(get_numeric_value_override), + get_string_value_override_(get_string_value_override), + set_numeric_value_override_(set_numeric_value_override), + set_string_value_override_(set_string_value_override), lookup_(lookup) {} @@ -344,13 +344,15 @@ struct FieldInfo string help() { return help_; } PrintProperties printProperties() { return print_properties_; } - double getValueDouble(Unit u) { if (get_value_double_) return get_value_double_(u); else return -12345678; } - bool hasGetValueDouble() { return get_value_double_ != NULL; } - string getValueString() { if (get_value_string_) return get_value_string_(); else return "?"; } - bool hasGetValueString() { return get_value_string_ != NULL; } + double getNumericValueOverride(Unit u) { if (get_numeric_value_override_) return get_numeric_value_override_(u); else return -12345678; } + bool hasGetNumericValueOverride() { return get_numeric_value_override_ != NULL; } + string getStringValueOverride() { if (get_string_value_override_) return get_string_value_override_(); else return "?"; } + bool hasGetStringValueOverride() { return get_string_value_override_ != NULL; } - void setValueDouble(Unit u, double d) { if (set_value_double_) set_value_double_(u, d); } - void setValueString(string s) { if (set_value_string_) set_value_string_(s); } + void setNumericValueOverride(Unit u, double v) { if (set_numeric_value_override_) set_numeric_value_override_(u, v); } + bool hasSetNumericValueOverride() { return set_numeric_value_override_ != NULL; } + void setStringValueOverride(string v) { if (set_string_value_override_) set_string_value_override_(v); } + bool hasSetStringValueOverride() { return set_string_value_override_ != NULL; } bool extractNumeric(Meter *m, Telegram *t, DVEntry *dve = NULL); bool extractString(Meter *m, Telegram *t, DVEntry *dve = NULL); @@ -358,15 +360,16 @@ struct FieldInfo bool matches(DVEntry *dve); void performExtraction(Meter *m, Telegram *t, DVEntry *dve); - string renderJsonOnlyDefaultUnit(); - string renderJson(vector *additional_conversions); - string renderJsonText(); + string renderJsonOnlyDefaultUnit(Meter *m); + string renderJson(Meter *m, vector *additional_conversions); + string renderJsonText(Meter *m); // Render the field name based on the actual field from the telegram. // A FieldInfo can be declared to handle any number of storage fields of a certain range. // The vname is then a pattern total_at_month_{storagenr-32} that gets translated into // total_at_month_2 (for the dventry with storage nr 34.) string generateFieldName(DVEntry *dve); + Translate::Lookup& lookup() { return lookup_; } private: @@ -379,10 +382,13 @@ private: string help_; // Helpful information on this meters use of this value. PrintProperties print_properties_; - function get_value_double_; // Callback to fetch the value from the meter. - function get_value_string_; // Callback to fetch the value from the meter. - function set_value_double_; // Call back to set the value in the c++ object - function set_value_string_; // Call back to set the value string in the c++ object + // Normally the values are stored inside the meter object using its setNumeric/setString/getNumeric/getString + // But for special fields we can override this default location with these setters/getters. + function get_numeric_value_override_; // Callback to fetch the value from the meter. + function get_string_value_override_; // Callback to fetch the value from the meter. + function set_numeric_value_override_; // Call back to set the value in the c++ object + function set_string_value_override_; // Call back to set the value string in the c++ object + Translate::Lookup lookup_; };