kopia lustrzana https://github.com/weetmuts/wmbusmeters
Add timestamp_utc timestamp_lt for explicit choice of date format for fields.
rodzic
6009382d4f
commit
efbcafab9f
|
@ -1,3 +1,3 @@
|
||||||
# Test Aventies Water Meter
|
# Test Aventies Water Meter
|
||||||
telegram=76442104710007612507727100076121042507B5006005E2E95A3C2A1279A5415E6732679B43369FD5FDDDD783EEEBB48236D34E7C94AF0A18A5FDA5F7D64111EB42D4D891622139F2952F9D12A20088DFA4CF8123871123EE1F6C1DCEA414879DDB4E05E508F1826D7EFBA6964DF804C9261EA23BBF03
|
telegram=76442104710007612507727100076121042507B5006005E2E95A3C2A1279A5415E6732679B43369FD5FDDDD783EEEBB48236D34E7C94AF0A18A5FDA5F7D64111EB42D4D891622139F2952F9D12A20088DFA4CF8123871123EE1F6C1DCEA414879DDB4E05E508F1826D7EFBA6964DF804C9261EA23BBF03
|
||||||
|466.472;UT;Votten;61070071
|
|466.472*UT*1111-11-11T11:11.11Z*1111-11-11 11:11.11*Votten*61070071*extra_info
|
||||||
|
|
|
@ -205,7 +205,7 @@ void list_fields(Configuration *config, string meter_driver)
|
||||||
mi.driver = toMeterDriver(meter_driver);
|
mi.driver = toMeterDriver(meter_driver);
|
||||||
shared_ptr<Meter> meter = createMeter(&mi);
|
shared_ptr<Meter> meter = createMeter(&mi);
|
||||||
|
|
||||||
int width = 0;
|
int width = 13; // Width of timestamp_utc
|
||||||
for (auto &p : meter->prints())
|
for (auto &p : meter->prints())
|
||||||
{
|
{
|
||||||
if ((int)p.field_name.size() > width) width = p.field_name.size();
|
if ((int)p.field_name.size() > width) width = p.field_name.size();
|
||||||
|
@ -223,8 +223,10 @@ void list_fields(Configuration *config, string meter_driver)
|
||||||
printf("%s Timestamp when wmbusmeters received the telegram. Local time for hr/fields UTC for json.\n", timestamp.c_str());
|
printf("%s Timestamp when wmbusmeters received the telegram. Local time for hr/fields UTC for json.\n", timestamp.c_str());
|
||||||
string timestamp_ut = padLeft("timestamp_ut", width);
|
string timestamp_ut = padLeft("timestamp_ut", width);
|
||||||
printf("%s Unix timestamp when wmbusmeters received the telegram.\n", timestamp_ut.c_str());
|
printf("%s Unix timestamp when wmbusmeters received the telegram.\n", timestamp_ut.c_str());
|
||||||
string timestamp_lt = padLeft("timestamp_l", width);
|
string timestamp_lt = padLeft("timestamp_lt", width);
|
||||||
printf("%s Unix timestamp when wmbusmeters received the telegram.\n", timestamp_ut.c_str());
|
printf("%s Local time when wmbusmeters received the telegram.\n", timestamp_lt.c_str());
|
||||||
|
string timestamp_utc = padLeft("timestamp_utc", width);
|
||||||
|
printf("%s UTC time when wmbusmeters received the telegram.\n", timestamp_utc.c_str());
|
||||||
string device = padLeft("device", width);
|
string device = padLeft("device", width);
|
||||||
printf("%s The wmbus device that received the telegram.\n", device.c_str());
|
printf("%s The wmbus device that received the telegram.\n", device.c_str());
|
||||||
string rssi = padLeft("rssi_dbm", width);
|
string rssi = padLeft("rssi_dbm", width);
|
||||||
|
|
212
src/meters.cc
212
src/meters.cc
|
@ -584,7 +584,8 @@ void MeterCommonImplementation::triggerUpdate(Telegram *t)
|
||||||
t->handled = true;
|
t->handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
string concatAllFields(Meter *m, Telegram *t, char c, vector<Print> &prints, vector<Unit> &cs, bool hr, vector<string> *added_fields)
|
string concatAllFields(Meter *m, Telegram *t, char c, vector<Print> &prints, vector<Unit> &cs, bool hr,
|
||||||
|
vector<string> *added_fields, vector<string> *extra_constant_fields)
|
||||||
{
|
{
|
||||||
string s;
|
string s;
|
||||||
s = "";
|
s = "";
|
||||||
|
@ -623,102 +624,155 @@ string concatAllFields(Meter *m, Telegram *t, char c, vector<Print> &prints, vec
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
string concatFields(Meter *m, Telegram *t, char c, vector<Print> &prints, vector<Unit> &cs, bool hr,
|
string findField(string key, vector<string> *extra_constant_fields)
|
||||||
vector<string> *selected_fields, vector<string> *added_fields)
|
|
||||||
{
|
{
|
||||||
if (selected_fields == NULL || selected_fields->size() == 0)
|
key = key+"=";
|
||||||
|
for (string ecf : *extra_constant_fields)
|
||||||
{
|
{
|
||||||
return concatAllFields(m, t, c, prints, cs, hr, added_fields);
|
if (startsWith(ecf, key))
|
||||||
|
{
|
||||||
|
return ecf.substr(key.length());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
string s;
|
return "";
|
||||||
s = "";
|
}
|
||||||
|
|
||||||
for (string field : *selected_fields)
|
// Is the desired field one of the fields common to all meters and telegrams?
|
||||||
|
bool checkCommonField(string *buf, string field, Meter *m, Telegram *t, char c)
|
||||||
|
{
|
||||||
|
if (field == "name")
|
||||||
{
|
{
|
||||||
if (field == "name")
|
*buf += m->name() + c;
|
||||||
{
|
return true;
|
||||||
s += m->name() + c;
|
}
|
||||||
continue;
|
if (field == "id")
|
||||||
}
|
{
|
||||||
if (field == "id")
|
*buf += t->ids.back() + c;
|
||||||
{
|
return true;
|
||||||
s += t->ids.back() + c;
|
}
|
||||||
continue;
|
if (field == "timestamp")
|
||||||
}
|
{
|
||||||
if (field == "timestamp")
|
*buf += m->datetimeOfUpdateHumanReadable() + c;
|
||||||
{
|
return true;
|
||||||
s += m->datetimeOfUpdateHumanReadable() + c;
|
}
|
||||||
continue;
|
if (field == "timestamp_lt")
|
||||||
}
|
{
|
||||||
if (field == "timestamp_lt")
|
*buf += m->datetimeOfUpdateHumanReadable() + c;
|
||||||
{
|
return true;
|
||||||
s += m->datetimeOfUpdateHumanReadable() + c;
|
}
|
||||||
continue;
|
if (field == "timestamp_utc")
|
||||||
}
|
{
|
||||||
if (field == "timestamp_utc")
|
*buf += m->datetimeOfUpdateRobot() + c;
|
||||||
{
|
return true;
|
||||||
s += m->datetimeOfUpdateRobot() + c;
|
}
|
||||||
continue;
|
if (field == "timestamp_ut")
|
||||||
}
|
{
|
||||||
if (field == "timestamp_ut")
|
*buf += m->unixTimestampOfUpdate() + c;
|
||||||
{
|
return true;
|
||||||
s += m->unixTimestampOfUpdate() + c;
|
}
|
||||||
continue;
|
if (field == "device")
|
||||||
}
|
{
|
||||||
if (field == "device")
|
*buf += t->about.device + c;
|
||||||
{
|
return true;
|
||||||
s += t->about.device + c;
|
}
|
||||||
continue;
|
if (field == "rssi_dbm")
|
||||||
}
|
{
|
||||||
if (field == "rssi_dbm")
|
*buf += to_string(t->about.rssi_dbm) + c;
|
||||||
{
|
return true;
|
||||||
s += to_string(t->about.rssi_dbm) + c;
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool handled = false;
|
return false;
|
||||||
for (Print p : prints)
|
}
|
||||||
|
|
||||||
|
// Is the desired field one of the meter printable fields?
|
||||||
|
bool checkPrintableField(string *buf, string field, Meter *m, Telegram *t, char c,
|
||||||
|
vector<Print> &prints, vector<Unit> &cs)
|
||||||
|
{
|
||||||
|
for (Print p : prints)
|
||||||
|
{
|
||||||
|
if (p.getValueString)
|
||||||
{
|
{
|
||||||
if (p.getValueString)
|
// Strings are simply just print them.
|
||||||
|
if (field == p.vname)
|
||||||
{
|
{
|
||||||
if (field == p.vname)
|
*buf += p.getValueString() + c;
|
||||||
{
|
return true;
|
||||||
s += p.getValueString() + c;
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (p.getValueDouble)
|
}
|
||||||
|
else if (p.getValueDouble)
|
||||||
|
{
|
||||||
|
// Doubles have to be converted into the proper unit.
|
||||||
|
string default_unit = unitToStringLowerCase(p.default_unit);
|
||||||
|
string var = p.vname+"_"+default_unit;
|
||||||
|
if (field == var)
|
||||||
{
|
{
|
||||||
string default_unit = unitToStringLowerCase(p.default_unit);
|
// Default unit.
|
||||||
string var = p.vname+"_"+default_unit;
|
*buf += valueToString(p.getValueDouble(p.default_unit), p.default_unit) + c;
|
||||||
if (field == var)
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Added conversion unit.
|
||||||
|
Unit u = replaceWithConversionUnit(p.default_unit, cs);
|
||||||
|
if (u != p.default_unit)
|
||||||
{
|
{
|
||||||
s += valueToString(p.getValueDouble(p.default_unit), p.default_unit) + c;
|
string unit = unitToStringLowerCase(u);
|
||||||
handled = true;
|
string var = p.vname+"_"+unit;
|
||||||
}
|
if (field == var)
|
||||||
else
|
|
||||||
{
|
|
||||||
Unit u = replaceWithConversionUnit(p.default_unit, cs);
|
|
||||||
if (u != p.default_unit)
|
|
||||||
{
|
{
|
||||||
string unit = unitToStringLowerCase(u);
|
*buf += valueToString(p.getValueDouble(u), u) + c;
|
||||||
string var = p.vname+"_"+unit;
|
return true;
|
||||||
if (field == var)
|
|
||||||
{
|
|
||||||
s += valueToString(p.getValueDouble(u), u) + c;
|
|
||||||
handled = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the desired field one of the constant fields?
|
||||||
|
bool checkConstantField(string *buf, string field, char c, vector<string> *extra_constant_fields)
|
||||||
|
{
|
||||||
|
// Ok, lets look for extra constant fields and print any such static information.
|
||||||
|
string v = findField(field, extra_constant_fields);
|
||||||
|
if (v != "")
|
||||||
|
{
|
||||||
|
*buf += v + c;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
string concatFields(Meter *m, Telegram *t, char c, vector<Print> &prints, vector<Unit> &cs, bool hr,
|
||||||
|
vector<string> *selected_fields, vector<string> *added_fields, vector<string> *extra_constant_fields)
|
||||||
|
{
|
||||||
|
if (selected_fields == NULL || selected_fields->size() == 0)
|
||||||
|
{
|
||||||
|
return concatAllFields(m, t, c, prints, cs, hr, added_fields, extra_constant_fields);
|
||||||
|
}
|
||||||
|
string buf = "";
|
||||||
|
|
||||||
|
for (string field : *selected_fields)
|
||||||
|
{
|
||||||
|
bool handled = checkCommonField(&buf, field, m, t, c);
|
||||||
|
if (handled) continue;
|
||||||
|
|
||||||
|
handled = checkPrintableField(&buf, field, m, t, c, prints, cs);
|
||||||
|
if (handled) continue;
|
||||||
|
|
||||||
|
handled = checkConstantField(&buf, field, c, extra_constant_fields);
|
||||||
|
if (handled) continue;
|
||||||
|
|
||||||
if (!handled)
|
if (!handled)
|
||||||
{
|
{
|
||||||
s += "?"+field+"?"+c;
|
buf += "?"+field+"?"+c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (s.back() == c) s.pop_back();
|
if (buf.back() == c) buf.pop_back();
|
||||||
return s;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MeterCommonImplementation::handleTelegram(AboutTelegram &about, vector<uchar> input_frame, bool simulated, string *ids, bool *id_match)
|
bool MeterCommonImplementation::handleTelegram(AboutTelegram &about, vector<uchar> input_frame, bool simulated, string *ids, bool *id_match)
|
||||||
|
@ -780,8 +834,8 @@ void MeterCommonImplementation::printMeter(Telegram *t,
|
||||||
vector<string> *selected_fields,
|
vector<string> *selected_fields,
|
||||||
vector<string> *added_fields)
|
vector<string> *added_fields)
|
||||||
{
|
{
|
||||||
*human_readable = concatFields(this, t, '\t', prints_, conversions_, true, selected_fields, added_fields);
|
*human_readable = concatFields(this, t, '\t', prints_, conversions_, true, selected_fields, added_fields, extra_constant_fields);
|
||||||
*fields = concatFields(this, t, separator, prints_, conversions_, false, selected_fields, added_fields);
|
*fields = concatFields(this, t, separator, prints_, conversions_, false, selected_fields, added_fields, extra_constant_fields);
|
||||||
|
|
||||||
string media;
|
string media;
|
||||||
if (t->tpl_id_found)
|
if (t->tpl_id_found)
|
||||||
|
|
|
@ -1374,6 +1374,11 @@ int countSetBits(int v)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool startsWith(string &s, string &prefix)
|
||||||
|
{
|
||||||
|
return startsWith(s, prefix.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
bool startsWith(string &s, const char *prefix)
|
bool startsWith(string &s, const char *prefix)
|
||||||
{
|
{
|
||||||
size_t len = strlen(prefix);
|
size_t len = strlen(prefix);
|
||||||
|
|
|
@ -176,6 +176,7 @@ AccessCheck checkIfExistsAndSameGroup(std::string device);
|
||||||
int countSetBits(int v);
|
int countSetBits(int v);
|
||||||
|
|
||||||
bool startsWith(std::string &s, const char *prefix);
|
bool startsWith(std::string &s, const char *prefix);
|
||||||
|
bool startsWith(std::string &s, std::string &prefix);
|
||||||
|
|
||||||
// Given alfa=beta it returns "alfa":"beta"
|
// Given alfa=beta it returns "alfa":"beta"
|
||||||
std::string makeQuotedJson(std::string &s);
|
std::string makeQuotedJson(std::string &s);
|
||||||
|
|
2
test.sh
2
test.sh
|
@ -110,7 +110,7 @@ if [ "$?" != "0" ]; then RC="1"; fi
|
||||||
|
|
||||||
if [ -x ../additional_tests.sh ]
|
if [ -x ../additional_tests.sh ]
|
||||||
then
|
then
|
||||||
(cd ..; ./additional_tests.sh)
|
(cd ..; ./additional_tests.sh $PROG)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo Slower tests...
|
echo Slower tests...
|
||||||
|
|
|
@ -14,16 +14,20 @@ cat simulations/simulation_unix_timestamp.txt | grep '^{' > $TEST/test_expected.
|
||||||
|
|
||||||
NOW=$(date +%s)
|
NOW=$(date +%s)
|
||||||
cat simulations/simulation_unix_timestamp.txt | grep '^|' | sed 's/^|//' | sed "s/UT/${NOW}/" > $TEST/test_expected.txt
|
cat simulations/simulation_unix_timestamp.txt | grep '^|' | sed 's/^|//' | sed "s/UT/${NOW}/" > $TEST/test_expected.txt
|
||||||
$PROG --format=fields --selectfields=total_m3,timestamp_ut,name,id simulations/simulation_t1.txt $METERS > $TEST/test_output.txt 2> $TEST/test_stderr.txt
|
$PROG --format=fields --separator='*' --field_extra=extra_info --selectfields=total_m3,timestamp_ut,timestamp_utc,timestamp_lt,name,id,extra simulations/simulation_t1.txt $METERS > $TEST/test_output.txt 2> $TEST/test_stderr.txt
|
||||||
if [ "$?" = "0" ]
|
if [ "$?" = "0" ]
|
||||||
then
|
then
|
||||||
cat $TEST/test_output.txt | sed 's/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9].[0-9][0-9]$/1111-11-11 11:11.11/' > $TEST/test_responses.txt
|
cat $TEST/test_output.txt | \
|
||||||
|
sed 's/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9].[0-9][0-9]/1111-11-11 11:11.11/g' | \
|
||||||
|
sed 's/[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]T[0-9][0-9]:[0-9][0-9].[0-9][0-9]Z/1111-11-11T11:11.11Z/g' \
|
||||||
|
> $TEST/test_responses.txt
|
||||||
diff $TEST/test_expected.txt $TEST/test_responses.txt
|
diff $TEST/test_expected.txt $TEST/test_responses.txt
|
||||||
if [ "$?" = "0" ]
|
if [ "$?" = "0" ]
|
||||||
then
|
then
|
||||||
echo OK fields: $TESTNAME
|
echo OK fields: $TESTNAME
|
||||||
TESTRESULT="OK"
|
TESTRESULT="OK"
|
||||||
else
|
else
|
||||||
|
meld $TEST/test_expected.txt $TEST/test_responses.txt
|
||||||
TESTRESULT="ERROR"
|
TESTRESULT="ERROR"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
|
|
Ładowanie…
Reference in New Issue