Add metershell or --detailedfirst to print reference from value to field in driver. E.g. total_m3=3 and total_m3_field=1

master
Fredrik Öhrström 2024-11-24 18:37:36 +01:00
rodzic 39c4bbe615
commit 1c987f3f0e
10 zmienionych plików z 121 dodań i 7 usunięć

Wyświetl plik

@ -504,6 +504,11 @@ static shared_ptr<Configuration> parseNormalCommandLine(Configuration *c, int ar
i++;
continue;
}
if (!strcmp(argv[i], "--detailedfirst")) {
c->detailed_first = true;
i++;
continue;
}
if (!strncmp(argv[i], "--shell=", 8)) {
string cmd = string(argv[i]+8);
if (cmd == "") {

Wyświetl plik

@ -293,6 +293,21 @@ void handleIgnoreDuplicateTelegrams(Configuration *c, string value)
}
}
void handleDetailedFirst(Configuration *c, string value)
{
if (value == "true")
{
c->detailed_first = true;
}
else if (value == "false")
{
c->detailed_first = false;
}
else {
warning("detailedfirst should be either true or false, not \"%s\"\n", value.c_str());
}
}
void handleResetAfter(Configuration *c, string s)
{
if (s.length() >= 1)
@ -709,6 +724,7 @@ shared_ptr<Configuration> loadConfiguration(string root, ConfigOverrides overrid
if (p.first == "loglevel") handleLoglevel(c, p.second);
else if (p.first == "internaltesting") handleInternalTesting(c, p.second);
else if (p.first == "ignoreduplicates") handleIgnoreDuplicateTelegrams(c, p.second);
else if (p.first == "detailedfirst") handleDetailedFirst(c, p.second);
else if (p.first == "device") handleDeviceOrHex(c, p.second);
else if (p.first == "donotprobe") handleDoNotProbe(c, p.second);
else if (p.first == "listento") handleListenTo(c, p.second);

Wyświetl plik

@ -95,6 +95,7 @@ struct Configuration
bool use_logfile {};
bool use_stderr_for_log = true; // Default is to use stderr for logging.
bool ignore_duplicate_telegrams = true; // Default is to ignore duplicates.
bool detailed_first = false; // Print additional lines in telegram mapping back to driver field.
std::string logfile;
bool json {};
bool pretty_print_json {};

Wyświetl plik

@ -570,7 +570,12 @@ bool start(Configuration *config)
stderrEnabled(config->use_stderr_for_log);
setAlarmShells(config->alarm_shells);
setIgnoreDuplicateTelegrams(config->ignore_duplicate_telegrams);
setDetailedFirst(config->detailed_first);
if (config->new_meter_shells.size() > 0)
{
// We have metershells, force detailed first telegram.
setDetailedFirst(true);
}
log_start_information(config);
// Create the manager monitoring all filedescriptors and invoking callbacks.

Wyświetl plik

@ -1912,6 +1912,8 @@ void MeterCommonImplementation::printMeter(Telegram *t,
vector<string> *selected_fields,
bool pretty_print_json)
{
bool first = !t->meter->hasReceivedFirstTelegram();
*human_readable = concatFields(this, t, '\t', field_infos_, true, selected_fields, extra_constant_fields);
*fields = concatFields(this, t, separator, field_infos_, false, selected_fields, extra_constant_fields);
@ -1964,18 +1966,29 @@ void MeterCommonImplementation::printMeter(Telegram *t,
string out = nf.field_info->renderJson(this, &nf.dv_entry);
s += indent+out+","+newline;
if (first && getDetailedFirst())
{
size_t pos = out.find("\":");
if (pos != string::npos)
{
string rule = out.substr(0, pos)+"_field\":"+to_string(nf.field_info->index());
s += indent+rule+","+newline;
}
}
}
for (auto &p : string_values_)
{
string vname = p.first;
StringField& sf = p.second;
string out;
if (sf.field_info->printProperties().hasHIDE()) continue;
if (sf.field_info->printProperties().hasSTATUS())
{
string in = getStatusField(sf.field_info);
string out = tostrprintf("\"%s\":\"%s\"", vname.c_str(), in.c_str());
out = tostrprintf("\"%s\":\"%s\"", vname.c_str(), in.c_str());
s += indent+out+","+newline;
}
else
@ -1983,15 +1996,24 @@ void MeterCommonImplementation::printMeter(Telegram *t,
if (sf.value == "null")
{
// The string "null" translates to actual json null.
string out = tostrprintf("\"%s\":null", vname.c_str());
out = tostrprintf("\"%s\":null", vname.c_str());
s += indent+out+","+newline;
}
else
{
string out = tostrprintf("\"%s\":\"%s\"", vname.c_str(), sf.value.c_str());
out = tostrprintf("\"%s\":\"%s\"", vname.c_str(), sf.value.c_str());
s += indent+out+","+newline;
}
}
if (first && getDetailedFirst())
{
size_t pos = out.find("\":");
if (pos != string::npos)
{
string rule = out.substr(0, pos)+"_field\":"+to_string(sf.field_info->index());
s += indent+rule+","+newline;
}
}
}
s += indent+"\"timestamp\":\""+datetimeOfUpdateRobot()+"\"";

Wyświetl plik

@ -53,12 +53,14 @@ void Printer::print(Telegram *t, Meter *meter,
meter->printMeter(t, &human_readable, &fields, separator_, &json, &envs, more_json, selected_fields, pretty_print_json_);
if (!meter->hasReceivedFirstTelegram() &&
(new_meter_shell_cmdlines_.size() > 0 || meter->shellCmdlinesMeterAdded().size() > 0))
if (!meter->hasReceivedFirstTelegram())
{
meter->markFirstTelegramReceived();
envs.push_back("METER_FIRST_TELEGRAM=true");
printNewMeterShells(meter, envs);
if (new_meter_shell_cmdlines_.size() > 0 || meter->shellCmdlinesMeterAdded().size() > 0)
{
printNewMeterShells(meter, envs);
}
}
else
{

Wyświetl plik

@ -4135,6 +4135,18 @@ void setIgnoreDuplicateTelegrams(bool idt)
ignore_duplicate_telegrams_ = idt;
}
static bool detailed_first_ = false;
void setDetailedFirst(bool df)
{
detailed_first_ = df;
}
bool getDetailedFirst()
{
return detailed_first_;
}
bool BusDeviceCommonImplementation::handleTelegram(AboutTelegram &about, vector<uchar> frame)
{
bool handled = false;

Wyświetl plik

@ -86,6 +86,8 @@ const char *toLowerCaseString(BusDeviceType t);
BusDeviceType toBusDeviceType(string &t);
void setIgnoreDuplicateTelegrams(bool idt);
void setDetailedFirst(bool df);
bool getDetailedFirst();
// In link mode S1, is used when both the transmitter and receiver are stationary.
// It can be transmitted relatively seldom.

Wyświetl plik

@ -45,6 +45,9 @@ if [ "$?" != "0" ]; then RC="1"; fi
./tests/test_list_envs.sh $PROG
if [ "$?" != "0" ]; then RC="1"; fi
./tests/test_detailed_first.sh $PROG
if [ "$?" != "0" ]; then RC="1"; fi
#tests/test_unknown.sh $PROG
#if [ "$?" != "0" ]; then RC="1"; fi

Wyświetl plik

@ -0,0 +1,46 @@
#!/bin/sh
PROG="$1"
mkdir -p testoutput
TEST=testoutput
TESTNAME="Test detailed first telegram"
TESTRESULT="ERROR"
$PROG --detailedfirst --format=json 1844AE4C4455223368077A55000000_041389E20100023B0000 Gurka iperl 33225544 NOKEY | jq . --sort-keys | grep -v timestamp > $TEST/test_output.txt 2>&1
cat <<EOF > $TEST/test_expected.txt
{
"_": "telegram",
"id": "33225544",
"max_flow_m3h": 0,
"max_flow_m3h_field": 1,
"media": "water",
"meter": "iperl",
"name": "Gurka",
"total_m3": 123.529,
"total_m3_field": 0
}
EOF
if [ "$?" = "0" ]
then
diff $TEST/test_expected.txt $TEST/test_output.txt
if [ "$?" = "0" ]
then
echo OK: $TESTNAME
TESTRESULT="OK"
else
if [ "$USE_MELD" = "true" ]
then
meld $TEST/test_expected.txt $TEST/test_output.txt
fi
fi
fi
if [ "$TESTRESULT" = "ERROR" ]
then
echo ERROR: $TESTNAME
exit 1
fi