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
|
||||
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);
|
||||
shared_ptr<Meter> meter = createMeter(&mi);
|
||||
|
||||
int width = 0;
|
||||
int width = 13; // Width of timestamp_utc
|
||||
for (auto &p : meter->prints())
|
||||
{
|
||||
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());
|
||||
string timestamp_ut = padLeft("timestamp_ut", width);
|
||||
printf("%s Unix timestamp when wmbusmeters received the telegram.\n", timestamp_ut.c_str());
|
||||
string timestamp_lt = padLeft("timestamp_l", width);
|
||||
printf("%s Unix timestamp when wmbusmeters received the telegram.\n", timestamp_ut.c_str());
|
||||
string timestamp_lt = padLeft("timestamp_lt", width);
|
||||
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);
|
||||
printf("%s The wmbus device that received the telegram.\n", device.c_str());
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
s = "";
|
||||
|
@ -623,102 +624,155 @@ string concatAllFields(Meter *m, Telegram *t, char c, vector<Print> &prints, vec
|
|||
return s;
|
||||
}
|
||||
|
||||
string concatFields(Meter *m, Telegram *t, char c, vector<Print> &prints, vector<Unit> &cs, bool hr,
|
||||
vector<string> *selected_fields, vector<string> *added_fields)
|
||||
string findField(string key, vector<string> *extra_constant_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;
|
||||
s = "";
|
||||
return "";
|
||||
}
|
||||
|
||||
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")
|
||||
{
|
||||
s += m->name() + c;
|
||||
continue;
|
||||
}
|
||||
if (field == "id")
|
||||
{
|
||||
s += t->ids.back() + c;
|
||||
continue;
|
||||
}
|
||||
if (field == "timestamp")
|
||||
{
|
||||
s += m->datetimeOfUpdateHumanReadable() + c;
|
||||
continue;
|
||||
}
|
||||
if (field == "timestamp_lt")
|
||||
{
|
||||
s += m->datetimeOfUpdateHumanReadable() + c;
|
||||
continue;
|
||||
}
|
||||
if (field == "timestamp_utc")
|
||||
{
|
||||
s += m->datetimeOfUpdateRobot() + c;
|
||||
continue;
|
||||
}
|
||||
if (field == "timestamp_ut")
|
||||
{
|
||||
s += m->unixTimestampOfUpdate() + c;
|
||||
continue;
|
||||
}
|
||||
if (field == "device")
|
||||
{
|
||||
s += t->about.device + c;
|
||||
continue;
|
||||
}
|
||||
if (field == "rssi_dbm")
|
||||
{
|
||||
s += to_string(t->about.rssi_dbm) + c;
|
||||
continue;
|
||||
}
|
||||
*buf += m->name() + c;
|
||||
return true;
|
||||
}
|
||||
if (field == "id")
|
||||
{
|
||||
*buf += t->ids.back() + c;
|
||||
return true;
|
||||
}
|
||||
if (field == "timestamp")
|
||||
{
|
||||
*buf += m->datetimeOfUpdateHumanReadable() + c;
|
||||
return true;
|
||||
}
|
||||
if (field == "timestamp_lt")
|
||||
{
|
||||
*buf += m->datetimeOfUpdateHumanReadable() + c;
|
||||
return true;
|
||||
}
|
||||
if (field == "timestamp_utc")
|
||||
{
|
||||
*buf += m->datetimeOfUpdateRobot() + c;
|
||||
return true;
|
||||
}
|
||||
if (field == "timestamp_ut")
|
||||
{
|
||||
*buf += m->unixTimestampOfUpdate() + c;
|
||||
return true;
|
||||
}
|
||||
if (field == "device")
|
||||
{
|
||||
*buf += t->about.device + c;
|
||||
return true;
|
||||
}
|
||||
if (field == "rssi_dbm")
|
||||
{
|
||||
*buf += to_string(t->about.rssi_dbm) + c;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool handled = false;
|
||||
for (Print p : prints)
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
s += p.getValueString() + c;
|
||||
handled = true;
|
||||
}
|
||||
*buf += p.getValueString() + c;
|
||||
return 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);
|
||||
string var = p.vname+"_"+default_unit;
|
||||
if (field == var)
|
||||
// Default unit.
|
||||
*buf += valueToString(p.getValueDouble(p.default_unit), p.default_unit) + c;
|
||||
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;
|
||||
handled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Unit u = replaceWithConversionUnit(p.default_unit, cs);
|
||||
if (u != p.default_unit)
|
||||
string unit = unitToStringLowerCase(u);
|
||||
string var = p.vname+"_"+unit;
|
||||
if (field == var)
|
||||
{
|
||||
string unit = unitToStringLowerCase(u);
|
||||
string var = p.vname+"_"+unit;
|
||||
if (field == var)
|
||||
{
|
||||
s += valueToString(p.getValueDouble(u), u) + c;
|
||||
handled = true;
|
||||
}
|
||||
*buf += valueToString(p.getValueDouble(u), u) + c;
|
||||
return 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)
|
||||
{
|
||||
s += "?"+field+"?"+c;
|
||||
buf += "?"+field+"?"+c;
|
||||
}
|
||||
}
|
||||
if (s.back() == c) s.pop_back();
|
||||
return s;
|
||||
if (buf.back() == c) buf.pop_back();
|
||||
return buf;
|
||||
}
|
||||
|
||||
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> *added_fields)
|
||||
{
|
||||
*human_readable = concatFields(this, t, '\t', prints_, conversions_, true, selected_fields, added_fields);
|
||||
*fields = concatFields(this, t, separator, prints_, conversions_, false, 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, extra_constant_fields);
|
||||
|
||||
string media;
|
||||
if (t->tpl_id_found)
|
||||
|
|
|
@ -1374,6 +1374,11 @@ int countSetBits(int v)
|
|||
return n;
|
||||
}
|
||||
|
||||
bool startsWith(string &s, string &prefix)
|
||||
{
|
||||
return startsWith(s, prefix.c_str());
|
||||
}
|
||||
|
||||
bool startsWith(string &s, const char *prefix)
|
||||
{
|
||||
size_t len = strlen(prefix);
|
||||
|
|
|
@ -176,6 +176,7 @@ AccessCheck checkIfExistsAndSameGroup(std::string device);
|
|||
int countSetBits(int v);
|
||||
|
||||
bool startsWith(std::string &s, const char *prefix);
|
||||
bool startsWith(std::string &s, std::string &prefix);
|
||||
|
||||
// Given alfa=beta it returns "alfa":"beta"
|
||||
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 ]
|
||||
then
|
||||
(cd ..; ./additional_tests.sh)
|
||||
(cd ..; ./additional_tests.sh $PROG)
|
||||
fi
|
||||
|
||||
echo Slower tests...
|
||||
|
|
|
@ -14,16 +14,20 @@ cat simulations/simulation_unix_timestamp.txt | grep '^{' > $TEST/test_expected.
|
|||
|
||||
NOW=$(date +%s)
|
||||
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" ]
|
||||
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
|
||||
if [ "$?" = "0" ]
|
||||
then
|
||||
echo OK fields: $TESTNAME
|
||||
TESTRESULT="OK"
|
||||
else
|
||||
meld $TEST/test_expected.txt $TEST/test_responses.txt
|
||||
TESTRESULT="ERROR"
|
||||
fi
|
||||
else
|
||||
|
|
Ładowanie…
Reference in New Issue