Add timestamp_utc timestamp_lt for explicit choice of date format for fields.

pull/324/head
Fredrik Öhrström 2021-08-08 16:50:25 +02:00
rodzic 6009382d4f
commit efbcafab9f
7 zmienionych plików z 152 dodań i 86 usunięć

Wyświetl plik

@ -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

Wyświetl plik

@ -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);

Wyświetl plik

@ -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)

Wyświetl plik

@ -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);

Wyświetl plik

@ -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);

Wyświetl plik

@ -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...

Wyświetl plik

@ -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