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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

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