Converted water meters to unit scaling.

pull/31/head
weetmuts 2019-05-04 17:38:10 +02:00
rodzic 49f7410519
commit 2a47115cb9
10 zmienionych plików z 225 dodań i 506 usunięć

Wyświetl plik

@ -36,15 +36,15 @@ struct MeterApator162 : public virtual WaterMeter, public virtual MeterCommonImp
MeterApator162(WMBus *bus, string& name, string& id, string& key);
// Total water counted through the meter
double totalWaterConsumption();
double totalWaterConsumption(Unit u);
bool hasTotalWaterConsumption();
double targetWaterConsumption();
double targetWaterConsumption(Unit u);
bool hasTargetWaterConsumption();
double maxFlow();
double maxFlow(Unit u);
bool hasMaxFlow();
double flowTemperature();
double flowTemperature(Unit u);
bool hasFlowTemperature();
double externalTemperature();
double externalTemperature(Unit u);
bool hasExternalTemperature();
string statusHumanReadable();
@ -77,7 +77,7 @@ MeterApator162::MeterApator162(WMBus *bus, string& name, string& id, string& key
}
double MeterApator162::totalWaterConsumption()
double MeterApator162::totalWaterConsumption(Unit u)
{
return total_water_consumption_;
}
@ -166,7 +166,7 @@ void MeterApator162::printMeter(Telegram *t,
"%s",
name().c_str(),
t->id.c_str(),
totalWaterConsumption(),
totalWaterConsumption(Unit::M3),
datetimeOfUpdateHumanReadable().c_str());
*human_readable = buf;
@ -178,7 +178,7 @@ void MeterApator162::printMeter(Telegram *t,
"%s",
name().c_str(), separator,
t->id.c_str(), separator,
totalWaterConsumption(), separator,
totalWaterConsumption(Unit::M3), separator,
datetimeOfUpdateRobot().c_str());
*fields = buf;
@ -198,7 +198,7 @@ void MeterApator162::printMeter(Telegram *t,
mediaTypeJSON(t->a_field_device_type).c_str(),
name().c_str(),
t->id.c_str(),
totalWaterConsumption(),
totalWaterConsumption(Unit::M3),
datetimeOfUpdateRobot().c_str());
*json = buf;
@ -206,7 +206,7 @@ void MeterApator162::printMeter(Telegram *t,
envs->push_back(string("METER_JSON=")+*json);
envs->push_back(string("METER_TYPE=apator162"));
envs->push_back(string("METER_ID=")+t->id);
envs->push_back(string("METER_TOTAL_M3=")+to_string(totalWaterConsumption()));
envs->push_back(string("METER_TOTAL_M3=")+to_string(totalWaterConsumption(Unit::M3)));
envs->push_back(string("METER_TIMESTAMP=")+datetimeOfUpdateRobot());
}
@ -215,7 +215,7 @@ bool MeterApator162::hasTotalWaterConsumption()
return true;
}
double MeterApator162::targetWaterConsumption()
double MeterApator162::targetWaterConsumption(Unit u)
{
return 0.0;
}
@ -225,7 +225,7 @@ bool MeterApator162::hasTargetWaterConsumption()
return false;
}
double MeterApator162::maxFlow()
double MeterApator162::maxFlow(Unit u)
{
return 0.0;
}
@ -235,7 +235,7 @@ bool MeterApator162::hasMaxFlow()
return false;
}
double MeterApator162::flowTemperature()
double MeterApator162::flowTemperature(Unit u)
{
return 127;
}
@ -245,7 +245,7 @@ bool MeterApator162::hasFlowTemperature()
return false;
}
double MeterApator162::externalTemperature()
double MeterApator162::externalTemperature(Unit u)
{
return 127;
}

Wyświetl plik

@ -37,15 +37,15 @@ struct MeterIperl : public virtual WaterMeter, public virtual MeterCommonImpleme
MeterIperl(WMBus *bus, string& name, string& id, string& key);
// Total water counted through the meter
double totalWaterConsumption();
double totalWaterConsumption(Unit u);
bool hasTotalWaterConsumption();
double targetWaterConsumption();
double targetWaterConsumption(Unit u);
bool hasTargetWaterConsumption();
double maxFlow();
double maxFlow(Unit u);
bool hasMaxFlow();
double flowTemperature();
double flowTemperature(Unit u);
bool hasFlowTemperature();
double externalTemperature();
double externalTemperature(Unit u);
bool hasExternalTemperature();
string statusHumanReadable();
@ -79,7 +79,7 @@ MeterIperl::MeterIperl(WMBus *bus, string& name, string& id, string& key) :
}
double MeterIperl::totalWaterConsumption()
double MeterIperl::totalWaterConsumption(Unit u)
{
return total_water_consumption_;
}
@ -160,8 +160,8 @@ void MeterIperl::printMeter(Telegram *t,
"%s",
name().c_str(),
t->id.c_str(),
totalWaterConsumption(),
maxFlow(),
totalWaterConsumption(Unit::M3),
maxFlow(Unit::M3H),
datetimeOfUpdateHumanReadable().c_str());
*human_readable = buf;
@ -174,8 +174,8 @@ void MeterIperl::printMeter(Telegram *t,
"%s",
name().c_str(), separator,
t->id.c_str(), separator,
totalWaterConsumption(), separator,
maxFlow(), separator,
totalWaterConsumption(Unit::M3), separator,
maxFlow(Unit::M3H), separator,
datetimeOfUpdateRobot().c_str());
*fields = buf;
@ -196,8 +196,8 @@ void MeterIperl::printMeter(Telegram *t,
mediaTypeJSON(t->a_field_device_type).c_str(),
name().c_str(),
t->id.c_str(),
totalWaterConsumption(),
maxFlow(),
totalWaterConsumption(Unit::M3),
maxFlow(Unit::M3H),
datetimeOfUpdateRobot().c_str());
*json = buf;
@ -205,8 +205,8 @@ void MeterIperl::printMeter(Telegram *t,
envs->push_back(string("METER_JSON=")+*json);
envs->push_back(string("METER_TYPE=iperl"));
envs->push_back(string("METER_ID=")+t->id);
envs->push_back(string("METER_TOTAL_M3=")+to_string(totalWaterConsumption()));
envs->push_back(string("METER_MAX_FLOW_M3H=")+to_string(maxFlow()));
envs->push_back(string("METER_TOTAL_M3=")+to_string(totalWaterConsumption(Unit::M3)));
envs->push_back(string("METER_MAX_FLOW_M3H=")+to_string(maxFlow(Unit::M3H)));
envs->push_back(string("METER_TIMESTAMP=")+datetimeOfUpdateRobot());
}
@ -215,7 +215,7 @@ bool MeterIperl::hasTotalWaterConsumption()
return true;
}
double MeterIperl::targetWaterConsumption()
double MeterIperl::targetWaterConsumption(Unit u)
{
return 0.0;
}
@ -225,7 +225,7 @@ bool MeterIperl::hasTargetWaterConsumption()
return false;
}
double MeterIperl::maxFlow()
double MeterIperl::maxFlow(Unit u)
{
return max_flow_;
}
@ -235,7 +235,7 @@ bool MeterIperl::hasMaxFlow()
return true;
}
double MeterIperl::flowTemperature()
double MeterIperl::flowTemperature(Unit u)
{
return 127;
}
@ -245,7 +245,7 @@ bool MeterIperl::hasFlowTemperature()
return false;
}
double MeterIperl::externalTemperature()
double MeterIperl::externalTemperature(Unit u)
{
return 127;
}

Wyświetl plik

@ -32,41 +32,20 @@
using namespace std;
struct MKRadio3 : public virtual WaterMeter, public virtual MeterCommonImplementation {
struct MKRadio3 : public virtual WaterMeter, public virtual MeterCommonImplementation
{
MKRadio3(WMBus *bus, string& name, string& id, string& key);
// Total water counted through the meter
double totalWaterConsumption();
double totalWaterConsumption(Unit u);
bool hasTotalWaterConsumption();
double targetWaterConsumption();
double targetWaterConsumption(Unit u);
bool hasTargetWaterConsumption();
double maxFlow();
bool hasMaxFlow();
double flowTemperature();
bool hasFlowTemperature();
double externalTemperature();
bool hasExternalTemperature();
string statusHumanReadable();
string status();
string timeDry();
string timeReversed();
string timeLeaking();
string timeBursting();
void printMeter(Telegram *t,
string *human_readable,
string *fields, char separator,
string *json,
vector<string> *envs);
private:
void handleTelegram(Telegram *t);
void processContent(Telegram *t);
string decodeTime(int time);
double total_water_consumption_ {};
double target_water_consumption_ {};
double total_water_consumption_m3_ {};
double target_water_consumption_m3_ {};
};
MKRadio3::MKRadio3(WMBus *bus, string& name, string& id, string& key) :
@ -74,55 +53,25 @@ MKRadio3::MKRadio3(WMBus *bus, string& name, string& id, string& key) :
{
addMedia(0x62);
addMedia(0x72);
addPrint("total", Quantity::Volume,
[&](Unit u){ return totalWaterConsumption(u); },
"The total water consumption recorded by this meter.",
true);
addPrint("target", Quantity::Volume,
[&](Unit u){ return targetWaterConsumption(u); },
"The total water consumption recorded at the beginning of this month.",
true);
MeterCommonImplementation::bus()->onTelegram(calll(this,handleTelegram,Telegram*));
}
double MKRadio3::totalWaterConsumption()
{
return total_water_consumption_;
}
unique_ptr<WaterMeter> createMKRadio3(WMBus *bus, string& name, string& id, string& key)
{
return unique_ptr<WaterMeter>(new MKRadio3(bus,name,id,key));
}
void MKRadio3::handleTelegram(Telegram *t)
{
if (!isTelegramForMe(t)) {
// This telegram is not intended for this meter.
return;
}
verbose("(%s) telegram for %s %02x%02x%02x%02x\n", "mkradio3",
name().c_str(),
t->a_field_address[0], t->a_field_address[1], t->a_field_address[2],
t->a_field_address[3]);
t->expectVersion("mkradio3", 0x74);
if (t->isEncrypted() && !useAes() && !t->isSimulated()) {
warning("(mkradio3) warning: telegram is encrypted but no key supplied!\n");
}
if (useAes()) {
vector<uchar> aeskey = key();
decryptMode5_AES_CBC(t, aeskey);
} else {
t->content = t->payload;
}
char log_prefix[256];
snprintf(log_prefix, 255, "(%s) log", "mkradio3");
logTelegram(log_prefix, t->parsed, t->content);
int content_start = t->parsed.size();
processContent(t);
if (isDebugEnabled()) {
snprintf(log_prefix, 255, "(%s)", "mkradio3");
t->explainParse(log_prefix, content_start);
}
triggerUpdate(t);
}
void MKRadio3::processContent(Telegram *t)
{
// Meter record:
@ -154,75 +103,14 @@ void MKRadio3::processContent(Telegram *t)
t->explanations.push_back({ offset, currs });
t->addMoreExplanation(offset, " curr consumption (%f m3)", curr);
total_water_consumption_ = prev+curr;
target_water_consumption_ = prev;
total_water_consumption_m3_ = prev+curr;
target_water_consumption_m3_ = prev;
}
void MKRadio3::printMeter(Telegram *t,
string *human_readable,
string *fields, char separator,
string *json,
vector<string> *envs)
double MKRadio3::totalWaterConsumption(Unit u)
{
char buf[65536];
buf[65535] = 0;
snprintf(buf, sizeof(buf)-1,
"%s\t"
"%s\t"
"% 3.3f m3\t"
"% 3.3f m3\t"
"%s",
name().c_str(),
t->id.c_str(),
totalWaterConsumption(),
targetWaterConsumption(),
datetimeOfUpdateHumanReadable().c_str());
*human_readable = buf;
snprintf(buf, sizeof(buf)-1,
"%s%c"
"%s%c"
"%f%c"
"%f%c"
"%s",
name().c_str(), separator,
t->id.c_str(), separator,
totalWaterConsumption(), separator,
targetWaterConsumption(), separator,
datetimeOfUpdateRobot().c_str());
*fields = buf;
#define Q(x,y) "\""#x"\":"#y","
#define QS(x,y) "\""#x"\":\""#y"\","
#define QSE(x,y) "\""#x"\":\""#y"\""
snprintf(buf, sizeof(buf)-1, "{"
QS(media,%s)
QS(meter,mkradio3)
QS(name,%s)
QS(id,%s)
Q(total_m3,%f)
Q(target_m3,%f)
QSE(timestamp,%s)
"}",
mediaTypeJSON(t->a_field_device_type).c_str(),
name().c_str(),
t->id.c_str(),
totalWaterConsumption(),
targetWaterConsumption(),
datetimeOfUpdateRobot().c_str());
*json = buf;
envs->push_back(string("METER_JSON=")+*json);
envs->push_back(string("METER_TYPE=mkradio3"));
envs->push_back(string("METER_ID=")+t->id);
envs->push_back(string("METER_TOTAL_M3=")+to_string(totalWaterConsumption()));
envs->push_back(string("METER_TARGET_M3=")+to_string(targetWaterConsumption()));
envs->push_back(string("METER_TIMESTAMP=")+datetimeOfUpdateRobot());
assertQuantity(u, Quantity::Volume);
return convert(total_water_consumption_m3_, Unit::M3, u);
}
bool MKRadio3::hasTotalWaterConsumption()
@ -230,72 +118,12 @@ bool MKRadio3::hasTotalWaterConsumption()
return true;
}
double MKRadio3::targetWaterConsumption()
double MKRadio3::targetWaterConsumption(Unit u)
{
return target_water_consumption_;
return target_water_consumption_m3_;
}
bool MKRadio3::hasTargetWaterConsumption()
{
return true;
}
double MKRadio3::maxFlow()
{
return 0.0;
}
bool MKRadio3::hasMaxFlow()
{
return false;
}
double MKRadio3::flowTemperature()
{
return 127;
}
bool MKRadio3::hasFlowTemperature()
{
return false;
}
double MKRadio3::externalTemperature()
{
return 127;
}
bool MKRadio3::hasExternalTemperature()
{
return false;
}
string MKRadio3::statusHumanReadable()
{
return "";
}
string MKRadio3::status()
{
return "";
}
string MKRadio3::timeDry()
{
return "";
}
string MKRadio3::timeReversed()
{
return "";
}
string MKRadio3::timeLeaking()
{
return "";
}
string MKRadio3::timeBursting()
{
return "";
}

Wyświetl plik

@ -48,23 +48,23 @@ struct MeterMultical21 : public virtual WaterMeter, public virtual MeterCommonIm
MeterMultical21(WMBus *bus, string& name, string& id, string& key, MeterType mt);
// Total water counted through the meter
double totalWaterConsumption();
double totalWaterConsumption(Unit u);
bool hasTotalWaterConsumption();
// Meter sends target water consumption or max flow, depending on meter configuration
// We can see which was sent inside the wmbus message!
// Target water consumption: The total consumption at the start of the previous 30 day period.
double targetWaterConsumption();
double targetWaterConsumption(Unit u);
bool hasTargetWaterConsumption();
// Max flow during last month or last 24 hours depending on meter configuration.
double maxFlow();
double maxFlow(Unit u);
bool hasMaxFlow();
// Water temperature
double flowTemperature();
double flowTemperature(Unit u);
bool hasFlowTemperature();
// Surrounding temperature
double externalTemperature();
double externalTemperature(Unit u);
bool hasExternalTemperature();
// statusHumanReadable: DRY,REVERSED,LEAK,BURST if that status is detected right now, followed by
@ -122,7 +122,7 @@ MeterMultical21::MeterMultical21(WMBus *bus, string& name, string& id, string& k
}
double MeterMultical21::totalWaterConsumption()
double MeterMultical21::totalWaterConsumption(Unit u)
{
return total_water_consumption_;
}
@ -132,7 +132,7 @@ bool MeterMultical21::hasTotalWaterConsumption()
return has_total_water_consumption_;
}
double MeterMultical21::targetWaterConsumption()
double MeterMultical21::targetWaterConsumption(Unit u)
{
return target_volume_;
}
@ -142,7 +142,7 @@ bool MeterMultical21::hasTargetWaterConsumption()
return has_target_volume_;
}
double MeterMultical21::maxFlow()
double MeterMultical21::maxFlow(Unit u)
{
return max_flow_;
}
@ -152,7 +152,7 @@ bool MeterMultical21::hasMaxFlow()
return has_max_flow_;
}
double MeterMultical21::flowTemperature()
double MeterMultical21::flowTemperature(Unit u)
{
return flow_temperature_;
}
@ -162,7 +162,7 @@ bool MeterMultical21::hasFlowTemperature()
return has_flow_temperature_;
}
double MeterMultical21::externalTemperature()
double MeterMultical21::externalTemperature(Unit u)
{
return external_temperature_;
}
@ -500,14 +500,14 @@ void MeterMultical21::printMeter(Telegram *t,
et[9] = 0;
if (hasFlowTemperature()) {
snprintf(ft, sizeof(ft)-1, "% 2.0f", flowTemperature());
snprintf(ft, sizeof(ft)-1, "% 2.0f", flowTemperature(Unit::C));
} else {
ft[0] = '-';
ft[1] = 0;
}
if (hasExternalTemperature()) {
snprintf(et, sizeof(et)-1, "% 2.0f", externalTemperature());
snprintf(et, sizeof(et)-1, "% 2.0f", externalTemperature(Unit::C));
} else {
et[0] = '-';
et[1] = 0;
@ -525,9 +525,9 @@ void MeterMultical21::printMeter(Telegram *t,
"%s",
name().c_str(),
t->id.c_str(),
totalWaterConsumption(),
targetWaterConsumption(),
maxFlow(),
totalWaterConsumption(Unit::M3),
targetWaterConsumption(Unit::M3),
maxFlow(Unit::M3H),
ft,
et,
statusHumanReadable().c_str(),
@ -547,11 +547,11 @@ void MeterMultical21::printMeter(Telegram *t,
"%s",
name().c_str(), separator,
t->id.c_str(), separator,
totalWaterConsumption(), separator,
targetWaterConsumption(), separator,
maxFlow(), separator,
flowTemperature(), separator,
externalTemperature(), separator,
totalWaterConsumption(Unit::M3), separator,
targetWaterConsumption(Unit::M3), separator,
maxFlow(Unit::M3H), separator,
flowTemperature(Unit::C), separator,
externalTemperature(Unit::C), separator,
statusHumanReadable().c_str(), separator,
datetimeOfUpdateRobot().c_str());
@ -582,11 +582,11 @@ void MeterMultical21::printMeter(Telegram *t,
meter_name_,
name().c_str(),
t->id.c_str(),
totalWaterConsumption(),
targetWaterConsumption(),
maxFlow(),
flowTemperature(),
externalTemperature(),
totalWaterConsumption(Unit::M3),
targetWaterConsumption(Unit::M3),
maxFlow(Unit::M3H),
flowTemperature(Unit::C),
externalTemperature(Unit::C),
status().c_str(), // DRY REVERSED LEAK BURST
timeDry().c_str(),
timeReversed().c_str(),
@ -599,11 +599,11 @@ void MeterMultical21::printMeter(Telegram *t,
envs->push_back(string("METER_JSON=")+*json);
envs->push_back(string("METER_TYPE=")+meter_name_);
envs->push_back(string("METER_ID=")+t->id);
envs->push_back(string("METER_TOTAL_M3=")+to_string(totalWaterConsumption()));
envs->push_back(string("METER_TARGET_M3=")+to_string(targetWaterConsumption()));
envs->push_back(string("METER_MAX_FLOW_M3H=")+to_string(maxFlow()));
envs->push_back(string("METER_FLOW_TEMPERATURE=")+to_string(flowTemperature()));
envs->push_back(string("METER_EXTERNAL_TEMPERATURE=")+to_string(externalTemperature()));
envs->push_back(string("METER_TOTAL_M3=")+to_string(totalWaterConsumption(Unit::M3)));
envs->push_back(string("METER_TARGET_M3=")+to_string(targetWaterConsumption(Unit::M3)));
envs->push_back(string("METER_MAX_FLOW_M3H=")+to_string(maxFlow(Unit::M3H)));
envs->push_back(string("METER_FLOW_TEMPERATURE=")+to_string(flowTemperature(Unit::C)));
envs->push_back(string("METER_EXTERNAL_TEMPERATURE=")+to_string(externalTemperature(Unit::C)));
envs->push_back(string("METER_STATUS=")+status());
envs->push_back(string("METER_TIME_DRY=")+timeDry());
envs->push_back(string("METER_TIME_REVERSED=")+timeReversed());

Wyświetl plik

@ -36,56 +36,42 @@ struct MeterSupercom587 : public virtual WaterMeter, public virtual MeterCommonI
MeterSupercom587(WMBus *bus, string& name, string& id, string& key);
// Total water counted through the meter
double totalWaterConsumption();
double totalWaterConsumption(Unit u);
bool hasTotalWaterConsumption();
double targetWaterConsumption();
bool hasTargetWaterConsumption();
double maxFlow();
bool hasMaxFlow();
double flowTemperature();
bool hasFlowTemperature();
double externalTemperature();
bool hasExternalTemperature();
string statusHumanReadable();
string status();
string timeDry();
string timeReversed();
string timeLeaking();
string timeBursting();
void printMeter(Telegram *t,
string *human_readable,
string *fields, char separator,
string *json,
vector<string> *envs);
private:
void handleTelegram(Telegram *t);
void processContent(Telegram *t);
string decodeTime(int time);
double total_water_consumption_ {};
double total_water_consumption_m3_ {};
};
unique_ptr<WaterMeter> createSupercom587(WMBus *bus, string& name, string& id, string& key)
{
return unique_ptr<WaterMeter>(new MeterSupercom587(bus,name,id,key));
}
MeterSupercom587::MeterSupercom587(WMBus *bus, string& name, string& id, string& key) :
MeterCommonImplementation(bus, name, id, key, MeterType::SUPERCOM587, MANUFACTURER_SON, LinkMode::T1)
{
addMedia(0x06);
addMedia(0x07);
addPrint("total", Quantity::Volume,
[&](Unit u){ return totalWaterConsumption(u); },
"The total water consumption recorded by this meter.",
true);
MeterCommonImplementation::bus()->onTelegram(calll(this,handleTelegram,Telegram*));
}
double MeterSupercom587::totalWaterConsumption()
double MeterSupercom587::totalWaterConsumption(Unit u)
{
return total_water_consumption_;
assertQuantity(u, Quantity::Volume);
return convert(total_water_consumption_m3_, Unit::M3, u);
}
unique_ptr<WaterMeter> createSupercom587(WMBus *bus, string& name, string& id, string& key)
{
return unique_ptr<WaterMeter>(new MeterSupercom587(bus,name,id,key));
}
void MeterSupercom587::handleTelegram(Telegram *t)
{
@ -131,141 +117,11 @@ void MeterSupercom587::processContent(Telegram *t)
int offset;
extractDVdouble(&values, "0C13", &offset, &total_water_consumption_);
t->addMoreExplanation(offset, " total consumption (%f m3)", total_water_consumption_);
}
void MeterSupercom587::printMeter(Telegram *t,
string *human_readable,
string *fields, char separator,
string *json,
vector<string> *envs)
{
char buf[65536];
buf[65535] = 0;
snprintf(buf, sizeof(buf)-1,
"%s\t"
"%s\t"
"% 3.3f m3\t"
"%s",
name().c_str(),
t->id.c_str(),
totalWaterConsumption(),
datetimeOfUpdateHumanReadable().c_str());
*human_readable = buf;
snprintf(buf, sizeof(buf)-1,
"%s%c"
"%s%c"
"%f%c"
"%s",
name().c_str(), separator,
t->id.c_str(), separator,
totalWaterConsumption(), separator,
datetimeOfUpdateRobot().c_str());
*fields = buf;
#define Q(x,y) "\""#x"\":"#y","
#define QS(x,y) "\""#x"\":\""#y"\","
#define QSE(x,y) "\""#x"\":\""#y"\""
snprintf(buf, sizeof(buf)-1, "{"
QS(media,%s)
QS(meter,supercom587)
QS(name,%s)
QS(id,%s)
Q(total_m3,%f)
QSE(timestamp,%s)
"}",
mediaTypeJSON(t->a_field_device_type).c_str(),
name().c_str(),
t->id.c_str(),
totalWaterConsumption(),
datetimeOfUpdateRobot().c_str());
*json = buf;
envs->push_back(string("METER_JSON=")+*json);
envs->push_back(string("METER_TYPE=supercom587"));
envs->push_back(string("METER_ID=")+t->id);
envs->push_back(string("METER_TOTAL_M3=")+to_string(totalWaterConsumption()));
envs->push_back(string("METER_TIMESTAMP=")+datetimeOfUpdateRobot());
extractDVdouble(&values, "0C13", &offset, &total_water_consumption_m3_);
t->addMoreExplanation(offset, " total consumption (%f m3)", total_water_consumption_m3_);
}
bool MeterSupercom587::hasTotalWaterConsumption()
{
return true;
}
double MeterSupercom587::targetWaterConsumption()
{
return 0.0;
}
bool MeterSupercom587::hasTargetWaterConsumption()
{
return false;
}
double MeterSupercom587::maxFlow()
{
return 0.0;
}
bool MeterSupercom587::hasMaxFlow()
{
return false;
}
double MeterSupercom587::flowTemperature()
{
return 127;
}
bool MeterSupercom587::hasFlowTemperature()
{
return false;
}
double MeterSupercom587::externalTemperature()
{
return 127;
}
bool MeterSupercom587::hasExternalTemperature()
{
return false;
}
string MeterSupercom587::statusHumanReadable()
{
return "";
}
string MeterSupercom587::status()
{
return "";
}
string MeterSupercom587::timeDry()
{
return "";
}
string MeterSupercom587::timeReversed()
{
return "";
}
string MeterSupercom587::timeLeaking()
{
return "";
}
string MeterSupercom587::timeBursting()
{
return "";
}

Wyświetl plik

@ -23,11 +23,7 @@
#include"units.h"
#include"util.h"
#include<algorithm>
#include<memory.h>
#include<stdio.h>
#include<string>
#include<time.h>
#include<vector>
struct MeterVario451 : public virtual HeatMeter, public virtual MeterCommonImplementation
@ -36,13 +32,10 @@ struct MeterVario451 : public virtual HeatMeter, public virtual MeterCommonImple
double totalEnergyConsumption(Unit u);
double currentPeriodEnergyConsumption(Unit u);
double currentPowerConsumption(Unit u);
double previousPeriodEnergyConsumption(Unit u);
double totalVolume(Unit u);
private:
void handleTelegram(Telegram *t);
void processContent(Telegram *t);
double total_energy_gj_ {};
@ -50,6 +43,11 @@ struct MeterVario451 : public virtual HeatMeter, public virtual MeterCommonImple
double prev_energy_gj_ {};
};
unique_ptr<HeatMeter> createVario451(WMBus *bus, string& name, string& id, string& key)
{
return unique_ptr<HeatMeter>(new MeterVario451(bus,name,id,key));
}
MeterVario451::MeterVario451(WMBus *bus, string& name, string& id, string& key) :
MeterCommonImplementation(bus, name, id, key, MeterType::VARIO451, MANUFACTURER_TCH, LinkMode::T1)
{
@ -86,58 +84,12 @@ double MeterVario451::currentPeriodEnergyConsumption(Unit u)
return convert(curr_energy_gj_, Unit::GJ, u);
}
double MeterVario451::currentPowerConsumption(Unit u)
{
return 0;
}
double MeterVario451::previousPeriodEnergyConsumption(Unit u)
{
assertQuantity(u, Quantity::Energy);
return convert(prev_energy_gj_, Unit::GJ, u);
}
double MeterVario451::totalVolume(Unit u)
{
return 0;
}
void MeterVario451::handleTelegram(Telegram *t) {
if (!isTelegramForMe(t)) {
// This telegram is not intended for this meter.
return;
}
verbose("(vario451) %s %02x%02x%02x%02x ",
name().c_str(),
t->a_field_address[0], t->a_field_address[1], t->a_field_address[2],
t->a_field_address[3]);
if (t->isEncrypted() && !useAes() && !t->isSimulated()) {
// This is ugly but I have no idea how to do this proper way :/
// Techem Vario 4 Typ 4.5.1 sends T and also encrypted C telegrams
// We are intrested in T only (for now)
//warning("(vario451) warning: telegram is encrypted but no key supplied!\n");
return;
}
if (useAes()) {
vector<uchar> aeskey = key();
decryptMode1_AES_CTR(t, aeskey);
} else {
t->content = t->payload;
}
logTelegram("(vario451) log", t->parsed, t->content);
int content_start = t->parsed.size();
processContent(t);
if (isDebugEnabled()) {
t->explainParse("(vario451)", content_start);
}
triggerUpdate(t);
}
void MeterVario451::processContent(Telegram *t)
{
map<string,pair<int,DVEntry>> vendor_values;
@ -172,8 +124,3 @@ void MeterVario451::processContent(Telegram *t)
curr_energy_gj_ = curr;
prev_energy_gj_ = prev;
}
unique_ptr<HeatMeter> createVario451(WMBus *bus, string& name, string& id, string& key)
{
return unique_ptr<HeatMeter>(new MeterVario451(bus,name,id,key));
}

Wyświetl plik

@ -18,6 +18,8 @@
#include"meters.h"
#include"meters_common_implementation.h"
#include"units.h"
#include"wmbus.h"
#include"wmbus_utils.h"
#include<algorithm>
#include<memory.h>
@ -253,6 +255,51 @@ string concatFields(Meter *m, Telegram *t, char c, vector<Print> &prints, vector
return s;
}
void MeterCommonImplementation::handleTelegram(Telegram *t)
{
if (!isTelegramForMe(t)) {
// This telegram is not intended for this meter.
return;
}
verbose("(%s) %s %02x%02x%02x%02x ",
meterName().c_str(),
name().c_str(),
t->a_field_address[0], t->a_field_address[1], t->a_field_address[2],
t->a_field_address[3]);
//t->expectVersion("mkradio3", 0x74);
if (t->isEncrypted() && !useAes() && !t->isSimulated())
{
warning("(%s) warning: telegram is encrypted but no key supplied!\n",
meterName().c_str());
}
if (useAes()) {
vector<uchar> aeskey = key();
decryptMode1_AES_CTR(t, aeskey);
} else {
t->content = t->payload;
}
char log_prefix[256];
snprintf(log_prefix, 255, "(%s) log", meterName().c_str());
logTelegram(log_prefix, t->parsed, t->content);
int content_start = t->parsed.size();
// Invoke meter specific parsing!
processContent(t);
// All done....
if (isDebugEnabled())
{
char log_prefix[256];
snprintf(log_prefix, 255, "(%s)", meterName().c_str());
t->explainParse("(vario451)", content_start);
}
triggerUpdate(t);
}
void MeterCommonImplementation::printMeter(Telegram *t,
string *human_readable,
string *fields, char separator,
@ -313,3 +360,36 @@ void MeterCommonImplementation::printMeter(Telegram *t,
}
envs->push_back(string("METER_TIMESTAMP=")+datetimeOfUpdateRobot());
}
double WaterMeter::totalWaterConsumption(Unit u) { return -47.11; }
bool WaterMeter::hasTotalWaterConsumption() { return false; }
double WaterMeter::targetWaterConsumption(Unit u) { return -47.11; }
bool WaterMeter::hasTargetWaterConsumption() { return false; }
double WaterMeter::maxFlow(Unit u) { return -47.11; }
bool WaterMeter::hasMaxFlow() { return false; }
double WaterMeter::flowTemperature(Unit u) { return -47.11; }
bool WaterMeter::hasFlowTemperature() { return false; }
double WaterMeter::externalTemperature(Unit u) { return -47.11; }
bool WaterMeter::hasExternalTemperature() { return false; }
string WaterMeter::statusHumanReadable() { return "-47.11"; }
string WaterMeter::status() { return "-47.11"; }
string WaterMeter::timeDry() { return "-47.11"; }
string WaterMeter::timeReversed() { return "-47.11"; }
string WaterMeter::timeLeaking() { return "-47.11"; }
string WaterMeter::timeBursting() { return "-47.11"; }
double HeatMeter::totalEnergyConsumption(Unit u) { return -47.11; }
double HeatMeter::currentPeriodEnergyConsumption(Unit u) { return -47.11; }
double HeatMeter::previousPeriodEnergyConsumption(Unit u) { return -47.11; }
double HeatMeter::currentPowerConsumption(Unit u) { return -47.11; }
double HeatMeter::totalVolume(Unit u) { return -47.11; }
double ElectricityMeter::totalEnergyConsumption() { return -47.11; }
double ElectricityMeter::currentPowerConsumption() { return -47.11; }
double ElectricityMeter::totalEnergyProduction() { return -47.11; }
double ElectricityMeter::currentPowerProduction() { return -47.11; }
double HeatCostMeter::currentConsumption() { return -47.11; }
string HeatCostMeter::setDate() { return "47.11"; }
double HeatCostMeter::consumptionAtSetDate() { return -47.11; }

Wyświetl plik

@ -71,6 +71,7 @@ struct Meter {
string *json,
vector<string> *envs) = 0;
void handleTelegram(Telegram *t);
virtual bool isTelegramForMe(Telegram *t) = 0;
virtual bool useAes() = 0;
virtual vector<uchar> key() = 0;
@ -86,44 +87,44 @@ struct Meter {
};
struct WaterMeter : public virtual Meter {
virtual double totalWaterConsumption() = 0; // m3
virtual bool hasTotalWaterConsumption() = 0;
virtual double targetWaterConsumption() = 0; // m3
virtual bool hasTargetWaterConsumption() = 0;
virtual double maxFlow() = 0;
virtual bool hasMaxFlow() = 0;
virtual double flowTemperature() = 0; // °C
virtual bool hasFlowTemperature() = 0;
virtual double externalTemperature() = 0; // °C
virtual bool hasExternalTemperature() = 0;
virtual double totalWaterConsumption(Unit u); // m3
virtual bool hasTotalWaterConsumption();
virtual double targetWaterConsumption(Unit u); // m3
virtual bool hasTargetWaterConsumption();
virtual double maxFlow(Unit u); // m3/s
virtual bool hasMaxFlow();
virtual double flowTemperature(Unit u); // °C
virtual bool hasFlowTemperature();
virtual double externalTemperature(Unit u); // °C
virtual bool hasExternalTemperature();
virtual string statusHumanReadable() = 0;
virtual string status() = 0;
virtual string timeDry() = 0;
virtual string timeReversed() = 0;
virtual string timeLeaking() = 0;
virtual string timeBursting() = 0;
virtual string statusHumanReadable();
virtual string status();
virtual string timeDry();
virtual string timeReversed();
virtual string timeLeaking();
virtual string timeBursting();
};
struct HeatMeter : public virtual Meter {
virtual double totalEnergyConsumption(Unit u) = 0; // kwh
virtual double currentPeriodEnergyConsumption(Unit u) = 0; // kwh
virtual double previousPeriodEnergyConsumption(Unit u) = 0; // kwh
virtual double currentPowerConsumption(Unit u) = 0; // kw
virtual double totalVolume(Unit u) = 0; // m3
virtual double totalEnergyConsumption(Unit u); // kwh
virtual double currentPeriodEnergyConsumption(Unit u); // kwh
virtual double previousPeriodEnergyConsumption(Unit u); // kwh
virtual double currentPowerConsumption(Unit u); // kw
virtual double totalVolume(Unit u); // m3
};
struct ElectricityMeter : public virtual Meter {
virtual double totalEnergyConsumption() = 0; // kwh
virtual double currentPowerConsumption() = 0; // kw
virtual double totalEnergyProduction() = 0; // kwh
virtual double currentPowerProduction() = 0; // kw
virtual double totalEnergyConsumption(); // kwh
virtual double currentPowerConsumption(); // kw
virtual double totalEnergyProduction(); // kwh
virtual double currentPowerProduction(); // kw
};
struct HeatCostMeter : public virtual Meter {
virtual double currentConsumption() = 0;
virtual string setDate() = 0;
virtual double consumptionAtSetDate() = 0;
virtual double currentConsumption();
virtual string setDate();
virtual double consumptionAtSetDate();
};
struct GenericMeter : public virtual Meter {

Wyświetl plik

@ -72,12 +72,15 @@ protected:
void addMedia(int media);
void addManufacturer(int m);
void addPrint(string vname, Quantity vquantity, function<double(Unit)> getValueFunc, string help, bool field);
void handleTelegram(Telegram *t);
void printMeter(Telegram *t,
string *human_readable,
string *fields, char separator,
string *json,
vector<string> *envs);
virtual void processContent(Telegram *t) = 0;
private:
MeterType type_ {};

Wyświetl plik

@ -25,6 +25,8 @@
X(Energy,KWH) \
X(Power,KW) \
X(Volume,M3) \
X(Flow,M3H) \
X(Temperature,C) \
#define LIST_OF_UNITS \
@ -33,6 +35,8 @@
X(M3,m3,m3,Volume,"cubic meter") \
X(L,l,l,Volume,"litre") \
X(KW,kw,kW,Power,"kilo Watt") \
X(M3H,m3h,m3/h,Flow,"cubic meters per hour") \
X(C,c,°C,Temperature,"celsius") \
enum class Unit
{