Add --driverdir=<dir> and --driver=<file> for loading drivers from text files.

pull/1167/head
Fredrik Öhrström 2024-02-11 00:12:31 +01:00
rodzic 440ea263b1
commit 04ed4d7628
15 zmienionych plików z 1969 dodań i 677 usunięć

Wyświetl plik

@ -157,6 +157,7 @@ PROG_OBJS:=\
$(BUILD)/bus.o \
$(BUILD)/cmdline.o \
$(BUILD)/config.o \
$(BUILD)/drivers.o \
$(BUILD)/dvparser.o \
$(BUILD)/formula.o \
$(BUILD)/mbus_rawtty.o \

Wyświetl plik

@ -414,6 +414,8 @@ As {options} you can use:
--calculate_flow_f=flow_temperature_c
--debug for a lot of information
--donotprobe=<tty> do not auto-probe this tty. Use multiple times for several ttys or specify "all" for all ttys.
--driver=<file> load a driver
--driverdir=<dir> load all drivers in dir
--exitafter=<time> exit program after time, eg 20h, 10m 5s
--format=<hr/json/fields> for human readable, json or semicolon separated fields
--help list all options

Wyświetl plik

@ -50,3 +50,18 @@ then
else
echo "conf dir: $ROOT/etc/wmbusmeters.d unchanged"
fi
####################################################################
##
## Create /etc/wmbusmeters.drivers.d
##
if [ ! -d "$ROOT"/etc/wmbusmeters.drivers.d ]
then
# Create the drivers directory
mkdir -p "$ROOT"/etc/wmbusmeters.drivers.d
chmod -R 755 "$ROOT"/etc/wmbusmeters.drivers.d
echo "conf dir: created $ROOT/etc/wmbusmeters.drivers.d"
else
echo "conf dir: $ROOT/etc/wmbusmeters.drivers.d unchanged"
fi

Wyświetl plik

@ -16,6 +16,7 @@
*/
#include"cmdline.h"
#include"drivers.h"
#include"meters.h"
#include"util.h"
@ -62,17 +63,9 @@ shared_ptr<Configuration> parseCommandLine(int argc, char **argv)
static shared_ptr<Configuration> parseNormalCommandLine(Configuration *c, int argc, char **argv)
{
int i = 1;
// First find all logging flags, --silent --verbose --normal --debug
while (argv[i] && argv[i][0] == '-')
{
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help") || !strcmp(argv[i], "--help")) {
c->need_help = true;
return shared_ptr<Configuration>(c);
}
if (!strncmp(argv[i], "--device=", 9) || // Deprecated
!strncmp(argv[i], "--overridedevice=", 17))
{
error("You can only use --overridedevice=xyz with --useconfig=xyz\n");
}
if (!strcmp(argv[i], "--silent")) {
c->silent = true;
i++;
@ -93,6 +86,48 @@ static shared_ptr<Configuration> parseNormalCommandLine(Configuration *c, int ar
i++;
continue;
}
if (!strcmp(argv[i], "--debug")) {
c->debug = true;
verboseEnabled(true);
debugEnabled(true);
i++;
continue;
}
if (!strcmp(argv[i], "--trace")) {
c->debug = true;
c->trace = true;
verboseEnabled(true);
debugEnabled(true);
traceEnabled(true);
i++;
continue;
}
i++;
}
// Now do the rest of the arguments.
i = 1;
while (argv[i] && argv[i][0] == '-')
{
if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "-help") || !strcmp(argv[i], "--help")) {
c->need_help = true;
return shared_ptr<Configuration>(c);
}
if (!strcmp(argv[i], "--silent") ||
!strcmp(argv[i], "--verbose") ||
!strcmp(argv[i], "--normal") ||
!strcmp(argv[i], "--debug") ||
!strcmp(argv[i], "--trace"))
{
// Handled already.
i++;
continue;
}
if (!strncmp(argv[i], "--device=", 9) || // Deprecated
!strncmp(argv[i], "--overridedevice=", 17))
{
error("You can only use --overridedevice=xyz with --useconfig=xyz\n");
}
if (!strcmp(argv[i], "--version")) {
c->version = true;
return shared_ptr<Configuration>(c);
@ -164,23 +199,6 @@ static shared_ptr<Configuration> parseNormalCommandLine(Configuration *c, int ar
i++;
continue;
}
if (!strcmp(argv[i], "--debug")) {
c->debug = true;
verboseEnabled(true);
debugEnabled(true);
i++;
continue;
}
if (!strcmp(argv[i], "--trace")) {
c->debug = true;
c->trace = true;
verboseEnabled(true);
debugEnabled(true);
traceEnabled(true);
i++;
continue;
}
if (!strncmp(argv[i], "--logtimestamps=", 16))
{
string ts = string(argv[i]+16);
@ -588,6 +606,31 @@ static shared_ptr<Configuration> parseNormalCommandLine(Configuration *c, int ar
i++;
continue;
}
if (!strncmp(argv[i], "--driversdir=", 13))
{
size_t len = strlen(argv[i]) - 13;
c->drivers_dir = string(argv[i]+13, len);
if (!checkIfDirExists(c->drivers_dir.c_str()))
{
error("You must supply a valid directory to --driversdir=<dir>\n");
}
i++;
loadDriversFromDir(c->drivers_dir);
continue;
}
if (!strncmp(argv[i], "--driver=", 9))
{
size_t len = strlen(argv[i]) - 9;
string driver = string(argv[i]+9, len);
if (!checkFileExists(driver.c_str()))
{
error("You must supply a valid file to --driver=<file>\n");
}
i++;
loadDriver(driver);
continue;
}
error("Unknown option \"%s\"\n", argv[i]);
}

Wyświetl plik

@ -16,6 +16,7 @@
*/
#include"config.h"
#include"drivers.h"
#include"meters.h"
#include"units.h"
@ -679,12 +680,14 @@ shared_ptr<Configuration> loadConfiguration(string root, ConfigOverrides overrid
string conf_dir = root;
string conf_file = root+"/etc/wmbusmeters.conf";
string conf_meter_dir = root+"/etc/wmbusmeters.d";
string conf_drivers_dir = root+"/etc/wmbusmeters.drivers.d";
if (!checkFileExists(conf_file.c_str()))
{
conf_dir = root+"/etc";
conf_file = root+"/wmbusmeters.conf";
conf_meter_dir = root+"/wmbusmeters.d";
conf_drivers_dir = root+"/wmbusmeters.drivers.d";
}
debug("(config) loading %s\n", conf_file.c_str());
@ -805,6 +808,8 @@ shared_ptr<Configuration> loadConfiguration(string root, ConfigOverrides overrid
handleLogfile(c, overrides.logfile_override);
}
loadDriversFromDir(conf_drivers_dir);
return shared_ptr<Configuration>(c);
}

Wyświetl plik

@ -68,6 +68,7 @@ struct Configuration
ConfigOverrides overrides;
bool useconfig {};
std::string config_root;
std::string drivers_dir;
bool need_help {};
bool silent {};
bool verbose {};

Wyświetl plik

@ -1,5 +1,5 @@
/*
Copyright (C) 2023 Fredrik Öhrström (gpl-3.0-or-later)
Copyright (C) 2023-2024 Fredrik Öhrström (gpl-3.0-or-later)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -67,7 +67,7 @@ bool DriverDynamic::load(DriverInfo *di, const string &file)
string default_fields = check_default_fields(xmqGetString(doc, NULL, "/driver/default_fields"), file);
di->setDefaultFields(default_fields);
verbose("(driver) loading driver %s\n", name.c_str());
verbose("(driver) loading driver %s from file %s\n", name.c_str(), file.c_str());
di->setDynamic(file, doc);
@ -90,7 +90,7 @@ DriverDynamic::DriverDynamic(MeterInfo &mi, DriverInfo &di) :
{
XMQDoc *doc = di.getDynamicDriver();
verbose("(driver) constructing driver %s from file %s\n",
verbose("(driver) constructing driver %s from already loaded file %s\n",
di.name().str().c_str(),
fileName().c_str());

41
src/drivers.c 100644
Wyświetl plik

@ -0,0 +1,41 @@
/*
Copyright (C) 2024 Fredrik Öhrström (gpl-3.0-or-later)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include<vector>
#include<string>
#include"util.h"
#include"drivers.h"
#include"meters.h"
using namespace std;
void loadDriversFromDir(std::string dir)
{
if (!checkIfDirExists(dir.c_str())) return;
vector<string> drivers;
listFiles(dir, &drivers);
verbose("(drivers) scanning dir %s\n", dir.c_str());
for (string &file : drivers)
{
string filename = dir+"/"+file;
string s = loadDriver(filename);
}
}

25
src/drivers.h 100644
Wyświetl plik

@ -0,0 +1,25 @@
/*
Copyright (C) 2024 Fredrik Öhrström (gpl-3.0-or-later)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DRIVERS_H_
#define DRIVERS_H_
#include<string>
void loadDriversFromDir(std::string dir);
#endif

Wyświetl plik

@ -18,6 +18,7 @@
#include"bus.h"
#include"cmdline.h"
#include"config.h"
#include"drivers.h"
#include"meters.h"
#include"printer.h"
#include"rtlsdr.h"
@ -311,11 +312,17 @@ void list_meters(Configuration *config)
{
string mname = di->name().str();
const char *info = toString(di->type());
const char *where = "";
const string f = di->getDynamicFileName();
if (f != "")
{
where = f.c_str();
}
if (config->list_meters_search == "" || \
stringFoundCaseIgnored(info, config->list_meters_search) || \
stringFoundCaseIgnored(mname.c_str(), config->list_meters_search)) \
printf("%-14s %s\n", mname.c_str(), info);
printf("%-14s %s %s\n", mname.c_str(), info, where);
}
}

Wyświetl plik

@ -77,6 +77,21 @@ vector<DriverInfo*> &allDrivers()
return *registered_drivers_list_;
}
void removeDriver(const string &name)
{
for (auto i = registered_drivers_list_->begin(); i != registered_drivers_list_->end(); i++)
{
if ((*i)->name().str() == name)
{
registered_drivers_list_->erase(i);
break;
}
}
registered_drivers_->erase(name);
assert(registered_drivers_->count(name) == 0);
}
void addRegisteredDriver(DriverInfo di)
{
verifyDriverLookupCreated();
@ -192,13 +207,22 @@ string loadDriver(const string &file)
{
error("Failed to load driver from file: %s\n", file.c_str());
}
// Check that the driver name has not been registered before!
if (lookupDriver(di.name().str()) != NULL)
// Check if the driver name has been registered before....
DriverInfo *old = lookupDriver(di.name().str());
if (old != NULL)
{
debug("Ignoring loaded driver %s %s since it is already registered!\n",
di.name().str().c_str(),
file.c_str());
return di.name().str();
if (old->getDynamicFileName() != "")
{
error("Newly loaded driver file %s tries to register the same name %s as driver file %s has already taken!\n",
file.c_str(), di.name().str().c_str(), old->getDynamicFileName().c_str());
}
else
{
verbose("(drivers) newly loaded driver %s overrides builtin driver\n",
file.c_str(), di.name().str().c_str());
removeDriver(di.name().str());
}
}
// Check that no other driver also triggers on the same detection values.
@ -209,8 +233,30 @@ string loadDriver(const string &file)
bool foo = p->detect(d.mfct, d.type, d.version);
if (foo)
{
error("Newly loaded driver %s tries to register the same auto detect combo as driver %s alread has taken!\n",
di.name().str().c_str(), p->name().str().c_str());
string mfct = manufacturerFlag(d.mfct);
if (p->getDynamicFileName() != "")
{
// It is not ok to override an previously file loaded driver!
error("Newly loaded driver %s tries to register the same "
"auto detect combo as driver %s alread has taken! mvt=%s,%02x,%02x\n",
di.name().str().c_str(),
p->name().str().c_str(),
mfct.c_str(),
d.version,
d.type);
}
else
{
// It is ok to override a built in driver!
verbose("(driver) newly loaded driver %s forces removal of builtin "
"driver %s since it auto-detects the same combo! mvt=%s,%02x,%02x\n",
di.name().str().c_str(),
p->name().str().c_str(),
mfct.c_str(),
d.version,
d.type);
removeDriver(p->name().str());
}
}
}
}

Wyświetl plik

@ -236,6 +236,8 @@ DriverInfo pickMeterDriver(Telegram *t);
// Return true for mbus and S2/C2/T2 drivers.
bool driverNeedsPolling(DriverName& dn);
string loadDriver(const string &file);
vector<DriverInfo*>& allDrivers();
////////////////////////////////////////////////////////////////////////////////////////////////////////////

2175
src/xmq.c

Plik diff jest za duży Load Diff

195
src/xmq.h
Wyświetl plik

@ -86,6 +86,7 @@ typedef struct XMQParseCallbacks XMQParseCallbacks;
@XMQ_CONTENT_XML: xml detected
@XMQ_CONTENT_HTML: html detected
@XMQ_CONTENT_JSON: json detected
@XMQ_CONTENT_TEXT: valid utf8 text input/output is selected
Specify the file/buffer content type.
*/
@ -97,7 +98,8 @@ typedef enum
XMQ_CONTENT_HTMQ = 3,
XMQ_CONTENT_XML = 4,
XMQ_CONTENT_HTML = 5,
XMQ_CONTENT_JSON = 6
XMQ_CONTENT_JSON = 6,
XMQ_CONTENT_TEXT = 7
} XMQContentType;
/**
@ -143,76 +145,37 @@ typedef enum
} XMQTrimType;
/**
XMQColorType: The normal coloring options for xmq.
@COLORTYPE_xmq_c: Comments
@COLORTYPE_xmq_q: Standalone quote.
@COLORTYPE_xmq_e: Entity
@COLORTYPE_xmq_ens: Element Namespace
@COLORTYPE_xmq_en: Element Name
@COLORTYPE_xmq_ek: Element Key
@COLORTYPE_xmq_ekv: Element Key Value
@COLORTYPE_xmq_ans: Attribute NameSpace
@COLORTYPE_xmq_ak: Attribute Key
@COLORTYPE_xmq_akv: Attribute Key Value
@COLORTYPE_xmq_cp: Compound Parentheses
@COLORTYPE_xmq_uw: Unicode Whitespace
@COLORTYPE_xmq_tw: Tab Whitespace
XMQSyntax:
@SYNTAX_C: Comments
@SYNTAX_Q: Standalone quote.
@SYNTAX_E: Entity
@SYNTAX_ENS: Element Namespace
@SYNTAX_EN: Element Name
@SYNTAX_EK: Element Key
@SYNTAX_EKV: Element Key Value
@SYNTAX_ANS: Attribute NameSpace
@SYNTAX_AK: Attribute Key
@SYNTAX_AKV: Attribute Key Value
@SYNTAX_CP: Compound Parentheses
@SYNTAX_NDC: Namespace declaration
@SYNTAX_UW: Unicode Whitespace
*/
typedef enum
{
COLORTYPE_xmq_c = 0, // Comments
COLORTYPE_xmq_q = 1, // Standalone quote.
COLORTYPE_xmq_e = 2, // Entity
COLORTYPE_xmq_ens = 3, // Element Namespace
COLORTYPE_xmq_en = 4, // Element Name
COLORTYPE_xmq_ek = 5, // Element Key
COLORTYPE_xmq_ekv = 6, // Element Key Value
COLORTYPE_xmq_ans = 7, // Attribute NameSpace
COLORTYPE_xmq_ak = 8, // Attribute Key
COLORTYPE_xmq_akv = 9, // Attribute Key Value
COLORTYPE_xmq_cp = 10, // Compound Parentheses
COLORTYPE_xmq_uw = 11, // Unicode Whitespace
} XMQColorType;
/**
XMQColor:
Map token type into color index.
*/
typedef enum XMQColor {
COLOR_none,
COLOR_whitespace,
COLOR_unicode_whitespace,
COLOR_indentation_whitespace,
COLOR_equals,
COLOR_brace_left,
COLOR_brace_right,
COLOR_apar_left,
COLOR_apar_right,
COLOR_cpar_left,
COLOR_cpar_right,
COLOR_quote,
COLOR_entity,
COLOR_comment,
COLOR_comment_continuation,
COLOR_ns_colon,
COLOR_element_ns,
COLOR_element_name,
COLOR_element_key,
COLOR_element_value_text,
COLOR_element_value_quote,
COLOR_element_value_entity,
COLOR_element_value_compound_quote,
COLOR_element_value_compound_entity,
COLOR_attr_ns,
COLOR_attr_ns_declaration,
COLOR_attr_key,
COLOR_attr_value_text,
COLOR_attr_value_quote,
COLOR_attr_value_entity,
COLOR_attr_value_compound_quote,
COLOR_attr_value_compound_entity,
} XMQColor;
SYNTAX_C = 0, // Comments
SYNTAX_Q = 1, // Standalone quote.
SYNTAX_E = 2, // Entity
SYNTAX_ENS = 3, // Element Namespace
SYNTAX_EN = 4, // Element Name
SYNTAX_EK = 5, // Element Key
SYNTAX_EKV = 6, // Element Key Value
SYNTAX_ANS = 7, // Attribute NameSpace
SYNTAX_AK = 8, // Attribute Key
SYNTAX_AKV = 9, // Attribute Key Value
SYNTAX_CP = 10, // Compound Parentheses
SYNTAX_NDC = 11, // Namespace declaration
SYNTAX_UW = 12, // Unicode Whitespace
} XMQSyntax;
/**
XMQReader:
@ -281,21 +244,6 @@ typedef enum
*/
typedef XMQProceed (*XMQNodeCallback)(XMQDoc *doc, XMQNode *node, void *user_data);
///////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////// FUNCTIONS /////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
xmqDetectContentType:
@start: points to first byte of buffer to scan for content type
@stop: points to byte after buffer
Detect the content type xmq/xml/html/json by examining a few leading
non-whitespace words/characters.
*/
XMQContentType xmqDetectContentType(const char *start, const char *stop);
/**
XMQParseError:
@XMQ_ERROR_CANNOT_READ_FILE: file not found or cannot be opened for reading.
@ -331,6 +279,7 @@ XMQContentType xmqDetectContentType(const char *start, const char *stop);
*/
typedef enum
{
XMQ_ERROR_NONE = 0,
XMQ_ERROR_CANNOT_READ_FILE = 1,
XMQ_ERROR_OOM = 2,
XMQ_ERROR_NOT_XMQ = 3,
@ -359,25 +308,43 @@ typedef enum
XMQ_ERROR_EXPECTED_HTML = 26,
XMQ_ERROR_EXPECTED_JSON = 27,
XMQ_ERROR_PARSING_XML = 28,
XMQ_ERROR_PARSING_HTML = 29
XMQ_ERROR_PARSING_HTML = 29,
XMQ_WARNING_QUOTES_NEEDED = 100
} XMQParseError;
const char *xmqParseErrorToString(XMQParseError e);
/** Allocate an empty XMQParseCallback structure. All callbacks are NULL and none will be called. */
XMQParseCallbacks *xmqNewParseCallbacks();
/** Free the XMQParseCallback structure. */
void xmqFreeParseCallbacks(XMQParseCallbacks *cb);
///////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////// FUNCTIONS /////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////
/**
xmqSetupParseCallbacksNoopTokens:
xmqDetectContentType:
@start: points to first byte of buffer to scan for content type
@stop: points to byte after buffer
When tokenizing only, for coloring or debugging, you can
use the setup functions below for a few standardized handlers.
Detect the content type xmq/xml/html/json by examining a few leading
non-whitespace words/characters.
*/
XMQContentType xmqDetectContentType(const char *start, const char *stop);
/**
xmqParseErrorToString:
@e: Translate this error to a human readable string.
*/
void xmqSetupParseCallbacksNoopTokens(XMQParseCallbacks *state);
const char *xmqParseErrorToString(XMQParseError e);
/**
xmqNewParseCallbacks:
Allocate an empty XMQParseCallback structure. All callbacks are NULL and none will be called.
*/
XMQParseCallbacks *xmqNewParseCallbacks();
/**
xmqFreeParseCallbacks:
Free the XMQParseCallback structure.
*/
void xmqFreeParseCallbacks(XMQParseCallbacks *cb);
/**
xmqSetupParseCallbacksColorizeTokens:
@ -469,6 +436,20 @@ XMQDoc *xmqNewDoc();
*/
void xmqSetDocSourceName(XMQDoc *doq, const char *source_name);
/**
xmqGetOriginalContentType:
If available, return the original content type (xmq/htmq/xml/html/json/text) of this document.
*/
XMQContentType xmqGetOriginalContentType(XMQDoc *doq);
/**
xmqGetOriginalSize:
If available, return the size of the original content, ie the loaded file size.
*/
size_t xmqGetOriginalSize(XMQDoc *doq);
/**
xmqGetRootNode:
@ -542,10 +523,10 @@ void xmqSetUseColor(XMQOutputSettings *os, bool use_color);
void xmqSetEscapeNewlines(XMQOutputSettings *os, bool escape_newlines);
void xmqSetEscapeNon7bit(XMQOutputSettings *os, bool escape_non_7bit);
void xmqSetOutputFormat(XMQOutputSettings *os, XMQContentType output_format);
//void xmqSetColoring(XMQOutputSettings *os, XMQColoring coloring);
void xmqSetRenderFormat(XMQOutputSettings *os, XMQRenderFormat render_to);
void xmqSetRenderRaw(XMQOutputSettings *os, bool render_raw);
void xmqSetRenderOnlyStyle(XMQOutputSettings *os, bool only_style);
void xmqSetRenderStyle(XMQOutputSettings *os, const char *render_style);
void xmqSetWriterContent(XMQOutputSettings *os, XMQWriter content);
void xmqSetWriterError(XMQOutputSettings *os, XMQWriter error);
@ -729,27 +710,21 @@ void xmqRenderHtmlSettings(XMQOutputSettings *settings,
const char *use_class);
/**
xmqOverrideColorType:
xmqOverrideColor:
@settings:
@render_style: Use "" for the default render_style
@sc: The syntax element you want to change the color for.
Change the color strings for the given color type. You have to run xmqSetupDefaultColors first.
*/
void xmqOverrideColorType(XMQOutputSettings *settings,
XMQColorType ct,
const char *pre,
const char *post,
const char *ns);
/**
xmqOverrideColor:
Change the color strings for the given color. You have to run xmqSetupDefaultColors first.
*/
void xmqOverrideColor(XMQOutputSettings *settings,
XMQColor c,
const char *render_style,
XMQSyntax sc,
const char *pre,
const char *post,
const char *ns);
#ifdef __cplusplus
_hideRBfromEditor
#endif

Wyświetl plik

@ -16,10 +16,10 @@ mkdir -p $TEST
TESTNAME="Test config override with oneshot"
TESTRESULT="ERROR"
cat simulations/serial_aes.msg | grep '^{' | jq --sort-keys . | tr -d '#' > $TEST/test_expected.txt
cat simulations/serial_aes.msg | grep '^{' | jq . --sort-keys | tr -d '#' > $TEST/test_expected.txt
cat simulations/serial_aes.msg | grep '^[CT]' | tr -d '#' > $TEST/test_input.txt
cat $TEST/test_input.txt | $PROG --useconfig=tests/config9 --overridedevice=stdin:rtlwmbus --oneshot 2> $TEST/test_stderr.txt | jq --sort-keys . > $TEST/test_output.txt
cat $TEST/test_input.txt | $PROG --useconfig=tests/config9 --overridedevice=stdin:rtlwmbus --oneshot 2> $TEST/test_stderr.txt | jq . --sort-keys > $TEST/test_output.txt
if ! grep -q "(main) all meters have received at least one update, stopping." $TEST/test_stderr.txt
then
@ -35,6 +35,10 @@ then
echo "OK: $TESTNAME"
TESTRESULT="OK"
else
if [ "$USE_MELD" = "true" ]
then
meld $TEST/test_expected.txt $TEST/test_response.txt
fi
echo "ERROR: $TESTNAME"
exit 1
fi
@ -42,11 +46,11 @@ fi
TESTNAME="Test config override with exitafter"
TESTRESULT="ERROR"
cat simulations/serial_aes.msg | grep '^{' | jq --sort-keys . | tr -d '#' > $TEST/test_expected.txt
cat simulations/serial_aes.msg | grep '^{' | jq . --sort-keys | tr -d '#' > $TEST/test_expected.txt
cat simulations/serial_aes.msg | grep '^[CT]' | tr -d '#' > $TEST/test_input.txt
# Read from stdin
{ cat $TEST/test_input.txt ; sleep 4; } | $PROG --useconfig=tests/config9 --overridedevice=stdin:rtlwmbus --exitafter=1s 2> $TEST/test_stderr.txt | jq --sort-keys . > $TEST/test_output.txt
{ cat $TEST/test_input.txt ; sleep 4; } | $PROG --useconfig=tests/config9 --overridedevice=stdin:rtlwmbus --exitafter=1s 2> $TEST/test_stderr.txt | jq . --sort-keys > $TEST/test_output.txt
if ! grep -q "(serial) exit after " $TEST/test_stderr.txt
then