kopia lustrzana https://github.com/weetmuts/wmbusmeters
Almost done printing automatically from print spec.
rodzic
65f29be6a3
commit
1e053dd56b
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
19
src/units.cc
19
src/units.cc
|
@ -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;
|
||||
}
|
||||
|
|
13
src/units.h
13
src/units.h
|
@ -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
|
||||
|
|
Ładowanie…
Reference in New Issue