/* Copyright (C) 2018-2020 Fredrik Öhrström 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 the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef METERS_COMMON_IMPLEMENTATION_H_ #define METERS_COMMON_IMPLEMENTATION_H_ #include"dvparser.h" #include"meters.h" #include"units.h" #include #include enum PrintProperty { JSON = 1, // This field should be printed when using --format=json FIELD = 2, // This field should be printed when using --format=field IMPORTANT = 4, // The most important field. }; struct MeterCommonImplementation : public virtual Meter { int index(); void setIndex(int i); string bus(); vector& ids(); string idsc(); vector fields(); vector prints(); string name(); MeterDriver driver(); DriverName driverName(); ELLSecurityMode expectedELLSecurityMode(); TPLSecurityMode expectedTPLSecurityMode(); string datetimeOfUpdateHumanReadable(); string datetimeOfUpdateRobot(); string unixTimestampOfUpdate(); void onUpdate(function cb); int numUpdates(); static bool isTelegramForMeter(Telegram *t, Meter *meter, MeterInfo *mi); MeterKeys *meterKeys(); MeterCommonImplementation(MeterInfo &mi, string driver); MeterCommonImplementation(MeterInfo &mi, DriverInfo &di); ~MeterCommonImplementation() = default; string meterDriver() { return driver_; } protected: void triggerUpdate(Telegram *t); void setExpectedELLSecurityMode(ELLSecurityMode dsm); void setExpectedTPLSecurityMode(TPLSecurityMode tsm); void addConversions(std::vector cs); std::vector& conversions() { return conversions_; } void addShell(std::string cmdline); void addExtraConstantField(std::string ecf); std::vector &shellCmdlines(); std::vector &meterExtraConstantFields(); void setMeterType(MeterType mt); void addLinkMode(LinkMode lm); // Print with the default unit for this quantity. void addPrint(string vname, Quantity vquantity, function getValueFunc, string help, bool field, bool json); // Print with exactly this unit for this quantity. void addPrint(string vname, Quantity vquantity, Unit unit, function getValueFunc, string help, bool field, bool json); // Print the dimensionless Text quantity, no unit is needed. void addPrint(string vname, Quantity vquantity, function getValueFunc, string help, bool field, bool json); #define SET_FUNC(varname,to_unit) {[&](Unit from_unit, double d){varname = convert(d, from_unit, to_unit);}} #define GET_FUNC(varname,from_unit) {[&](Unit to_unit){return convert(varname, from_unit, to_unit);}} void addFieldWithExtractor( string vname, // Name of value without unit, eg total Quantity vquantity, // Value belongs to this quantity. DifVifKey dif_vif_key, // You can hardocde a dif vif header here or use NoDifVifKey VifScaling vif_scaling, MeasurementType mt, // If not using a hardcoded key, search for mt,vi,s,t and i instead. ValueInformation vi, StorageNr s, TariffNr t, IndexNr i, int print_properties, // Should this be printed by default in fields,json and hr. string help, function setValueFunc, // Use the SET macro above. function getValueFunc); // Use the GET macro above. #define SET_STRING_FUNC(varname) {[&](string s){varname = s;}} #define GET_STRING_FUNC(varname) {[&](){return varname; }} void addStringFieldWithExtractor( string vname, // Name of value without unit, eg total Quantity vquantity, // Value belongs to this quantity. DifVifKey dif_vif_key, // You can hardocde a dif vif header here or use NoDifVifKey MeasurementType mt, // If not using a hardcoded key, search for mt,vi,s,t and i instead. ValueInformation vi, StorageNr s, TariffNr t, IndexNr i, int print_properties, // Should this be printed by default in fields,json and hr. string help, function setValueFunc, // Use the SET_STRING macro above. function getValueFunc); // Use the GET_STRING macro above. // Decode a bit field and print void addPrintTextFromBits(string vname, // Name of field, no suffix unit added since it is text. string help, // An explanation of the field. int props, // json,field,important function getValueFunc); // The default implementation of poll does nothing. // Override for mbus meters that need to be queried and likewise for C2/T2 wmbus-meters. void poll(shared_ptr bus); bool handleTelegram(AboutTelegram &about, vector frame, bool simulated, string *id, bool *id_match, Telegram *out_analyzed = NULL); void printMeter(Telegram *t, string *human_readable, string *fields, char separator, string *json, vector *envs, vector *more_json, // Add this json "key"="value" strings. vector *selected_fields); // Only print these fields. // Json fields cannot be modified expect by adding conversions. // Json fields include all values except timestamp_ut, timestamp_utc, timestamp_lt // since Json is assumed to be decoded by a program and the current timestamp which is the // same as timestamp_utc, can always be decoded/recoded into local time or a unix timestamp. FieldInfo *findFieldInfo(string vname); string renderJsonOnlyDefaultUnit(string vname); void processFieldExtractors(Telegram *t); virtual void processContent(Telegram *t); private: int index_ {}; MeterType type_ {}; string driver_ {}; DriverName driver_name_; string bus_ {}; MeterKeys meter_keys_ {}; ELLSecurityMode expected_ell_sec_mode_ {}; TPLSecurityMode expected_tpl_sec_mode_ {}; string name_; vector ids_; string idsc_; vector> on_update_; int num_updates_ {}; time_t datetime_of_update_ {}; LinkModeSet link_modes_ {}; vector shell_cmdlines_; vector extra_constant_fields_; protected: std::map> values_; vector conversions_; vector prints_; vector fields_; }; #endif