diff --git a/src/driver_gransystems.cc b/src/driver_gransystems.cc index ae17ec5..867a370 100644 --- a/src/driver_gransystems.cc +++ b/src/driver_gransystems.cc @@ -73,7 +73,7 @@ namespace Translate::Type::BitToString, AlwaysTrigger, AutoMask, - "", + "OK", { { 0x0001, "METER_HARDWARE_ERROR" }, { 0x0002, "RTC_ERROR" }, @@ -88,7 +88,7 @@ namespace Translate::Type::BitToString, TriggerBits(0x01020000), AutoMask, - "", + "OK", { { 0x0008, "DEVICE_NOT_CONFIGURED" }, { 0x0010, "INTERNAL_ERROR" }, @@ -102,7 +102,7 @@ namespace Translate::Type::BitToString, TriggerBits(0x01010000), AutoMask, - "", + "OK", { { 0x0008, "CALIBRATION_EEPROM_ERROR" }, { 0x0010, "NETWORK_INTERFERENCE" }, diff --git a/src/formula.h b/src/formula.h index d762cc7..58738a3 100644 --- a/src/formula.h +++ b/src/formula.h @@ -57,10 +57,21 @@ Formula *newFormula(); struct StringInterpolator { - // Create a string interpolation from for example: "historic_{storage_counter / - 12 counter}_value" - // Which for a dventry with storage 13 will "generate historic_1_value" + /** + parse: Parse a field name like: "historic_{storage_counter / - 12 counter}_value" + @f: String to parse and find {...} subformulas inside. + + Parse and prepare it for being applied to an actual dve. + E.g. for a dventry with storage 13 the formula above will generate "historic_1_value" + */ virtual bool parse(const std::string &f) = 0; + /** + apply: Insert inline formulas in field names like "total_{subunit_nr}" insert the result of the formula. + @dve: A pointer to a telegram entry to use (ie containing storagenr/tariffnr/subunitnr etc.) Can be NULL. + + */ virtual std::string apply(DVEntry *dve) = 0; + virtual ~StringInterpolator() = 0; }; diff --git a/src/meters.cc b/src/meters.cc index 419ecd5..03d952c 100644 --- a/src/meters.cc +++ b/src/meters.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2017-2022 Fredrik Öhrström (gpl-3.0-or-later) + Copyright (C) 2017-2023 Fredrik Öhrström (gpl-3.0-or-later) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1111,6 +1111,9 @@ bool MeterCommonImplementation::handleTelegram(AboutTelegram &about, vectorhasSetNumericValueOverride()) - { - // 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; if (dve == NULL) { - field_name_no_unit = fi->vname(); + string field_name_no_unit = fi->vname(); + numeric_values_[pair(field_name_no_unit, fi->xuantity())] = NumericField(u, v, fi); } else { field_name_no_unit = fi->generateFieldNameNoUnit(dve); + numeric_values_[pair(field_name_no_unit, fi->xuantity())] = NumericField(u, v, fi, *dve); } - - numeric_values_[pair(field_name_no_unit, fi->xuantity())] = NumericField(u, v, fi); } void MeterCommonImplementation::setNumericValue(string vname, Unit u, double v) @@ -1289,8 +1284,6 @@ bool MeterCommonImplementation::hasValue(FieldInfo *fi) bool MeterCommonImplementation::hasNumericValue(FieldInfo *fi) { - if (fi->hasGetNumericValueOverride()) return true; - pair key(fi->vname(),fi->xuantity()); return numeric_values_.count(key) != 0; @@ -1298,18 +1291,11 @@ bool MeterCommonImplementation::hasNumericValue(FieldInfo *fi) bool MeterCommonImplementation::hasStringValue(FieldInfo *fi) { - if (fi->hasGetStringValueOverride()) return true; - return string_values_.count(fi->vname()) != 0; } double MeterCommonImplementation::getNumericValue(FieldInfo *fi, Unit to) { - if (fi->hasGetNumericValueOverride()) - { - return fi->getNumericValueOverride(to); - } - string field_name_no_unit = fi->vname(); pair key(field_name_no_unit,fi->xuantity()); if (numeric_values_.count(key) == 0) @@ -1323,12 +1309,6 @@ double MeterCommonImplementation::getNumericValue(FieldInfo *fi, Unit to) double MeterCommonImplementation::getNumericValue(string vname, Unit to) { Quantity q = toQuantity(to); - FieldInfo *fi = findFieldInfo(vname, q); - - if (fi != NULL && fi->hasGetNumericValueOverride()) - { - return fi->getNumericValueOverride(to); - } pair key(vname,q); if (numeric_values_.count(key) == 0) @@ -1341,12 +1321,6 @@ double MeterCommonImplementation::getNumericValue(string vname, Unit to) void MeterCommonImplementation::setStringValue(FieldInfo *fi, string v) { - if (fi->hasSetStringValueOverride()) - { - fi->setStringValueOverride(v); - return; - } - string field_name_no_unit = fi->vname(); string_values_[field_name_no_unit] = StringField(v, fi); } @@ -1365,13 +1339,6 @@ void MeterCommonImplementation::setStringValue(string vname, string v) string MeterCommonImplementation::getStringValue(FieldInfo *fi) { - if (fi->hasGetStringValueOverride()) - { - // There is a custom getter for this field. Use this instead. - return fi->getStringValueOverride(); - } - - // Fetch the string value from the default string storage in the meter. string field_name_no_unit = fi->vname(); if (string_values_.count(field_name_no_unit) == 0) { @@ -1636,6 +1603,27 @@ void MeterCommonImplementation::printMeter(Telegram *t, map> founds; // Multiple dventries can match to a single field info. set found_vnames; + for (auto &p : numeric_values_) + { + string vname = p.first.first; + NumericField& nf = p.second; + if (nf.field_info->printProperties().hasHIDE()) continue; + + string out = nf.field_info->renderJson(this, &nf.dv_entry); + s += indent+out+","+newline; + } + + for (auto &p : string_values_) + { + string vname = p.first; + StringField& sf = p.second; + + if (sf.field_info->printProperties().hasHIDE()) continue; + + string out = tostrprintf("\"%s\":\"%s\"", vname.c_str(), sf.value.c_str()); + s += indent+out+","+newline; + } + /* for (FieldInfo& fi : field_infos_) { if (fi.printProperties().hasHIDE()) continue; @@ -1700,7 +1688,7 @@ void MeterCommonImplementation::printMeter(Telegram *t, } } } - + */ s += indent+"\"timestamp\":\""+datetimeOfUpdateRobot()+"\""; if (t->about.device != "") diff --git a/src/meters.h b/src/meters.h index 1071f75..37a57cf 100644 --- a/src/meters.h +++ b/src/meters.h @@ -296,16 +296,6 @@ struct FieldInfo string help() { return help_; } PrintProperties printProperties() { return print_properties_; } - 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 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); bool hasMatcher(); diff --git a/src/meters_common_implementation.h b/src/meters_common_implementation.h index 9164e42..0781e5c 100644 --- a/src/meters_common_implementation.h +++ b/src/meters_common_implementation.h @@ -38,9 +38,11 @@ struct NumericField Unit unit {}; double value {}; FieldInfo *field_info {}; + DVEntry dv_entry {}; NumericField() {} NumericField(Unit u, double v, FieldInfo *f) : unit(u), value(v), field_info(f) {} + NumericField(Unit u, double v, FieldInfo *f, DVEntry &dve) : unit(u), value(v), field_info(f), dv_entry(dve) {} }; struct StringField @@ -238,7 +240,7 @@ protected: vector selected_fields_; // Map difvif key to hex values from telegrams. std::map> hex_values_; - // Map field name (total_volume) to numeric value. + // Map field name including unit (total_volume_m3) to numeric value. std::map,NumericField> numeric_values_; // Map field name (at_date) to string value. std::map string_values_;