Almost done printing automatically from print spec.

pull/31/head
weetmuts 2019-05-04 13:55:52 +02:00
rodzic 65f29be6a3
commit 1e053dd56b
7 zmienionych plików z 108 dodań i 32 usunięć

Wyświetl plik

@ -288,6 +288,7 @@ void startUsingCommandline(Configuration *config)
meters.push_back(create##cname(wmbus.get(), m.name, m.id, m.key)); \
verbose("(wmbusmeters) configured \"%s\" \"" #mname "\" \"%s\" %s\n", \
m.name.c_str(), m.id.c_str(), keymsg); \
meters.back()->addConversions(config->conversions); \
break;
LIST_OF_METERS
#undef X

Wyświetl plik

@ -23,6 +23,7 @@
#include"units.h"
#include"util.h"
#include<algorithm>
#include<memory.h>
#include<stdio.h>
#include<string>
@ -34,7 +35,6 @@
X(current_kwh, currentPeriodEnergyConsumption, Unit::KWH) \
X(previous_kwh, previousPeriodEnergyConsumption, Unit::KWH) \
struct MeterVario451 : public virtual HeatMeter, public virtual MeterCommonImplementation {
MeterVario451(WMBus *bus, string& name, string& id, string& key);
@ -64,6 +64,22 @@ MeterVario451::MeterVario451(WMBus *bus, string& name, string& id, string& key)
{
addMedia(0x04); // C telegrams
addMedia(0xC3); // T telegrams
addPrint("total", Quantity::Energy,
[&](Unit u){ return totalEnergyConsumption(u); },
"The total energy consumption recorded by this meter.",
true);
addPrint("current", Quantity::Energy,
[&](Unit u){ return currentPeriodEnergyConsumption(u); },
"Energy consumption so far in this billing period.",
true);
addPrint("previous", Quantity::Energy,
[&](Unit u){ return previousPeriodEnergyConsumption(u); },
"Energy consumption in previous billing period.",
true);
MeterCommonImplementation::bus()->onTelegram(calll(this,handleTelegram,Telegram*));
}
@ -165,10 +181,29 @@ void MeterVario451::processContent(Telegram *t) {
prev_energy_gj_ = prev;
}
unique_ptr<HeatMeter> createVario451(WMBus *bus, string& name, string& id, string& key) {
unique_ptr<HeatMeter> createVario451(WMBus *bus, string& name, string& id, string& key)
{
return unique_ptr<HeatMeter>(new MeterVario451(bus,name,id,key));
}
string concatFields(Meter *m, Telegram *t, char c, vector<Print> &prints, vector<Unit> &cs)
{
string s;
s = "";
s += m->name() + c;
s += t->id + c;
for (Print p : prints)
{
if (p.field)
{
Unit u = replaceWithConversionUnit(p.default_unit, cs);
double v = p.getValueFunc(u);
s += strWithUnitHR(v, u) + c;
}
}
s += m->datetimeOfUpdateHumanReadable();
return s;
}
void MeterVario451::printMeter(Telegram *t,
string *human_readable,
@ -176,24 +211,8 @@ void MeterVario451::printMeter(Telegram *t,
string *json,
vector<string> *envs)
{
string s;
s = "";
s += name() + "\t";
s += t->id + "\t";
#define X(key,func,unit) {s+=strWithUnitHR(func(Unit::KWH),unit) + "\t";}
METER_OUTPUT
#undef X
s += datetimeOfUpdateHumanReadable();
*human_readable = s;
s = "";
s += name() + "\t";
s += t->id + "\t";
#define X(key,func,unit) {s+=strWithUnitLowerCase(func(Unit::KWH),unit) + separator;}
METER_OUTPUT
#undef X
s += datetimeOfUpdateHumanReadable();
*fields = s;
*human_readable = concatFields(this, t, '\t', prints_, conversions_);
*fields = concatFields(this, t, separator, prints_, conversions_);
#define Q(x,y) "\""#x"\":"#y","
#define QS(x,y) "\""#x"\":\""#y"\","
@ -220,10 +239,20 @@ void MeterVario451::printMeter(Telegram *t,
*json = buf;
envs->push_back(string("METER_JSON=")+*json);
envs->push_back(string("METER_TYPE=vario451"));
envs->push_back(string("METER_TYPE=")+meterName());
envs->push_back(string("METER_ID=")+t->id);
envs->push_back(string("METER_TOTAL_KWH=")+to_string(totalEnergyConsumption(Unit::KWH)));
envs->push_back(string("METER_CURRENT_KWH=")+to_string(currentPeriodEnergyConsumption(Unit::KWH)));
envs->push_back(string("METER_PREVIOUS_KWH=")+to_string(previousPeriodEnergyConsumption(Unit::KWH)));
for (Print p : prints_)
{
if (p.field)
{
Unit u = replaceWithConversionUnit(p.default_unit, conversions_);
string unit = unitToStringUpperCase(u);
string var = p.vname;
std::transform(var.begin(), var.end(), var.begin(), ::toupper);
string envvar = "METER_"+var+"_"+unit+"="+to_string(p.getValueFunc(u));
envs->push_back(envvar);
}
}
envs->push_back(string("METER_TIMESTAMP=")+datetimeOfUpdateRobot());
}

Wyświetl plik

@ -39,6 +39,14 @@ MeterCommonImplementation::MeterCommonImplementation(WMBus *bus, string& name, s
}
}
void MeterCommonImplementation::addConversions(std::vector<Unit> cs)
{
for (Unit c : cs)
{
conversions_.push_back(c);
}
}
MeterType MeterCommonImplementation::type()
{
return type_;
@ -54,6 +62,12 @@ void MeterCommonImplementation::addMedia(int m)
media_.push_back(m);
}
void MeterCommonImplementation::addPrint(string vname, Quantity vquantity,
function<double(Unit)> getValueFunc, string help, bool field)
{
prints_.push_back( { vname, vquantity, defaultUnitForQuantity(vquantity), getValueFunc, help, field });
}
void MeterCommonImplementation::addManufacturer(int m)
{
manufacturers_.insert(m);

Wyświetl plik

@ -80,6 +80,8 @@ struct Meter {
virtual double getRecordAsDouble(std::string record) = 0;
virtual uint16_t getRecordAsUInt16(std::string record) = 0;
virtual void addConversions(std::vector<Unit> cs) = 0;
virtual ~Meter() = default;
};

Wyświetl plik

@ -26,9 +26,12 @@
struct Print
{
string vname; // Value name, like: total current previous
Unit vunit; // Value unit, like: Unit::KWH Unit::GJ Unit::M3 Unit::L
string vname; // Value name, like: total current previous target
Quantity quantity; // Quantity: Energy, Volume
Unit default_unit; // Default unit for above quantity: KWH, M3
function<double(Unit)> getValueFunc; // Callback to fetch the value from the meter.
string help; // Helpful information on this meters use of this value.
bool field; // If true, print in hr/fields output.
};
struct MeterCommonImplementation : public virtual Meter
@ -65,8 +68,10 @@ struct MeterCommonImplementation : public virtual Meter
protected:
void triggerUpdate(Telegram *t);
void addConversions(std::vector<Unit> cs);
void addMedia(int media);
void addManufacturer(int m);
void addPrint(string vname, Quantity vquantity, function<double(Unit)> getValueFunc, string help, bool field);
private:
@ -82,10 +87,11 @@ private:
bool use_aes_ {};
time_t datetime_of_update_ {};
LinkMode required_link_mode_ {};
vector<Unit> conversions_ {};
protected:
std::map<std::string,std::pair<int,std::string>> values_;
vector<Unit> conversions_;
vector<Print> prints_;
};
#endif

Wyświetl plik

@ -65,6 +65,16 @@ void assertQuantity(Unit u, Quantity q)
}
}
Unit defaultUnitForQuantity(Quantity q)
{
#define X(quantity,default_unit) if (q == Quantity::quantity) return Unit::default_unit;
LIST_OF_QUANTITIES
#undef X
return Unit::Unknown;
}
Unit toUnit(string s)
{
#define X(cname,lcname,hrname,quantity,explanation) if (s == #cname) return Unit::cname;
@ -114,3 +124,12 @@ string strWithUnitLowerCase(double v, Unit u)
r += " "+unitToStringLowerCase(u);
return r;
}
Unit replaceWithConversionUnit(Unit u, vector<Unit> cs)
{
for (Unit c : cs)
{
if (canConvert(u, c)) return c;
}
return u;
}

Wyświetl plik

@ -22,9 +22,9 @@
#include<vector>
#define LIST_OF_QUANTITIES \
X(Energy) \
X(Power) \
X(Volume) \
X(Energy,KWH) \
X(Power,KW) \
X(Volume,M3) \
#define LIST_OF_UNITS \
@ -44,7 +44,7 @@ LIST_OF_UNITS
enum class Quantity
{
#define X(quantity) quantity,
#define X(quantity,default_unit) quantity,
LIST_OF_QUANTITIES
#undef X
Unknown
@ -55,8 +55,13 @@ double convert(double v, Unit from, Unit to);
Unit toUnit(std::string s);
bool isQuantity(Unit u, Quantity q);
void assertQuantity(Unit u, Quantity q);
Unit defaultUnitForQuantity(Quantity q);
std::string unitToStringHR(Unit u);
std::string unitToStringLowerCase(Unit u);
std::string unitToStringUpperCase(Unit u);
std::string strWithUnitHR(double v, Unit u);
std::string strWithUnitLowerCase(double v, Unit u);
Unit replaceWithConversionUnit(Unit u, std::vector<Unit> cs);
#endif