Added meterfilesnaming

pull/31/head 0.9.11
weetmuts 2019-06-20 14:28:52 +02:00
rodzic bd63a73d0a
commit 6d6e1b5d93
12 zmienionych plików z 130 dodań i 31 usunięć

11
CHANGES
Wyświetl plik

@ -1,4 +1,13 @@
Version 0.9.10: 2019-6-13
Version 0.9.11: 2019-06-20
Added --meterfilesnaming=(name|id|name-id)
to choose the file name written meter file.
Naming using id or name-id is necessary when a meter
specification listens to many different meters using id
wildcards.
Version 0.9.10: 2019-06-13
Update logrotate to trigger HUP when rotating log files.
This will re-initialize the serial connection to the usb dongle

Wyświetl plik

@ -34,6 +34,7 @@ logtelegrams=false
format=json
meterfiles=/var/log/wmbusmeters/meter_readings
meterfilesaction=overwrite
meterfilesnaming=name
logfile=/var/log/wmbusmeters/wmbusmeters.log
shell=/usr/bin/mosquitto_pub -h localhost -t wmbusmeters/$METER_ID -m "$METER_JSON"
```
@ -103,6 +104,7 @@ As <options> you can use:
--logtelegrams log the contents of the telegrams for easy replay
--meterfiles=<dir> store meter readings in dir
--meterfilesaction=(overwrite|append) overwrite or append to the meter readings file
--meterfilesnaming=(name|id|name-id) the meter file is the meter's: name, id or name-id
--n1a to --n1f listen to N1 messages (perhaps)
--oneshot wait for an update from each meter, then quit
--separator=<c> change field separator to c

Wyświetl plik

@ -180,24 +180,6 @@ unique_ptr<Configuration> parseCommandLine(int argc, char **argv) {
i++;
continue;
}
if (!strncmp(argv[i], "--meterfiles", 12)) {
c->meterfiles = true;
if (strlen(argv[i]) > 12 && argv[i][12] == '=') {
size_t len = strlen(argv[i])-13;
if (len > 0) {
c->meterfiles_dir = string(argv[i]+13, len);
} else {
c->meterfiles_dir = "/tmp";
}
} else {
c->meterfiles_dir = "/tmp";
}
if (!checkIfDirExists(c->meterfiles_dir.c_str())) {
error("Cannot write meter files into dir \"%s\"\n", c->meterfiles_dir.c_str());
}
i++;
continue;
}
if (!strncmp(argv[i], "--meterfilesaction", 18)) {
if (strlen(argv[i]) > 18 && argv[i][18] == '=') {
if (!strncmp(argv[i]+19, "overwrite", 9)) {
@ -213,6 +195,47 @@ unique_ptr<Configuration> parseCommandLine(int argc, char **argv) {
i++;
continue;
}
if (!strncmp(argv[i], "--meterfilesnaming", 18)) {
if (strlen(argv[i]) > 18 && argv[i][18] == '=') {
if (!strncmp(argv[i]+19, "name-id", 7))
{
c->meterfiles_naming = MeterFileNaming::NameId;
}
else if (!strncmp(argv[i]+19, "name", 4))
{
c->meterfiles_naming = MeterFileNaming::Name;
}
else if (!strncmp(argv[i]+19, "id", 2))
{
c->meterfiles_naming = MeterFileNaming::Id;
} else
{
error("No such meter file naming %s\n", argv[i]+19);
}
} else {
error("Incorrect option %s\n", argv[i]);
}
i++;
continue;
}
if (!strcmp(argv[i], "--meterfiles") ||
(!strncmp(argv[i], "--meterfiles", 12) &&
strlen(argv[i]) > 12 &&
argv[i][12] == '='))
{
c->meterfiles = true;
size_t len = strlen(argv[i]);
if (len > 13) {
c->meterfiles_dir = string(argv[i]+13, len-13);
} else {
c->meterfiles_dir = "/tmp";
}
if (!checkIfDirExists(c->meterfiles_dir.c_str())) {
error("Cannot write meter files into dir \"%s\"\n", c->meterfiles_dir.c_str());
}
i++;
continue;
}
if (!strncmp(argv[i], "--logfile=", 10)) {
c->use_logfile = true;
if (strlen(argv[i]) > 10) {

Wyświetl plik

@ -210,6 +210,26 @@ void handleMeterfilesAction(Configuration *c, string meterfilesaction)
}
}
void handleMeterfilesNaming(Configuration *c, string type)
{
if (type == "name")
{
c->meterfiles_naming = MeterFileNaming::Name;
}
else if (type == "id")
{
c->meterfiles_naming = MeterFileNaming::Id;
}
else if (type == "name-id")
{
c->meterfiles_naming = MeterFileNaming::NameId;
}
else
{
warning("No such meter file naming \"%s\"\n", type.c_str());
}
}
void handleLogfile(Configuration *c, string logfile)
{
if (logfile.length() > 0)
@ -296,6 +316,7 @@ unique_ptr<Configuration> loadConfiguration(string root)
else if (p.first == "logtelegrams") handleLogtelegrams(c, p.second);
else if (p.first == "meterfiles") handleMeterfiles(c, p.second);
else if (p.first == "meterfilesaction") handleMeterfilesAction(c, p.second);
else if (p.first == "meterfilesnaming") handleMeterfilesNaming(c, p.second);
else if (p.first == "logfile") handleLogfile(c, p.second);
else if (p.first == "format") handleFormat(c, p.second);
else if (p.first == "separator") handleSeparator(c, p.second);

Wyświetl plik

@ -31,6 +31,11 @@ enum class MeterFileType
Overwrite, Append
};
enum class MeterFileNaming
{
Name, Id, NameId
};
struct Configuration {
bool daemon {};
std::string pid_file;
@ -47,6 +52,7 @@ struct Configuration {
bool meterfiles {};
std::string meterfiles_dir;
MeterFileType meterfiles_action {};
MeterFileNaming meterfiles_naming {};
bool use_logfile {};
std::string logfile;
bool json {};

Wyświetl plik

@ -97,6 +97,7 @@ As <options> you can use:
--logtelegrams log the contents of the telegrams for easy replay
--meterfiles=<dir> store meter readings in dir
--meterfilesaction=(overwrite|append) overwrite or append to the meter readings file
--meterfilesnaming=(name|id|name-id) the meter file is the meter's: name, id or name-id
--oneshot wait for an update from each meter, then quit
--separator=<c> change field separator to c
--shell=<cmdline> invokes cmdline with env variables containing the latest reading
@ -272,7 +273,8 @@ bool startUsingCommandline(Configuration *config)
config->separator, config->meterfiles, config->meterfiles_dir,
config->use_logfile, config->logfile,
config->shells,
config->meterfiles_action == MeterFileType::Overwrite));
config->meterfiles_action == MeterFileType::Overwrite,
config->meterfiles_naming));
vector<unique_ptr<Meter>> meters;
if (config->meters.size() > 0) {

Wyświetl plik

@ -23,7 +23,8 @@ using namespace std;
Printer::Printer(bool json, bool fields, char separator,
bool use_meterfiles, string &meterfiles_dir,
bool use_logfile, string &logfile,
vector<string> shell_cmdlines, bool overwrite)
vector<string> shell_cmdlines, bool overwrite,
MeterFileNaming naming)
{
json_ = json;
fields_ = fields;
@ -34,6 +35,7 @@ Printer::Printer(bool json, bool fields, char separator,
logfile_ = logfile;
shell_cmdlines_ = shell_cmdlines;
overwrite_ = overwrite;
naming_ = naming;
}
void Printer::print(Telegram *t, Meter *meter)
@ -49,12 +51,12 @@ void Printer::print(Telegram *t, Meter *meter)
printed = true;
}
if (use_meterfiles_) {
printFiles(meter, human_readable, fields, json);
printFiles(meter, t, human_readable, fields, json);
printed = true;
}
if (!printed) {
// This will print on stdout or in the logfile.
printFiles(meter, human_readable, fields, json);
printFiles(meter, t, human_readable, fields, json);
}
}
@ -72,14 +74,24 @@ void Printer::printShells(Meter *meter, vector<string> &envs)
}
}
void Printer::printFiles(Meter *meter, string &human_readable, string &fields, string &json)
void Printer::printFiles(Meter *meter, Telegram *t, string &human_readable, string &fields, string &json)
{
FILE *output = stdout;
if (use_meterfiles_) {
char filename[128];
memset(filename, 0, sizeof(filename));
snprintf(filename, 127, "%s/%s", meterfiles_dir_.c_str(), meter->name().c_str());
switch (naming_) {
case MeterFileNaming::Name:
snprintf(filename, 127, "%s/%s", meterfiles_dir_.c_str(), meter->name().c_str());
break;
case MeterFileNaming::Id:
snprintf(filename, 127, "%s/%s", meterfiles_dir_.c_str(), t->id.c_str());
break;
case MeterFileNaming::NameId:
snprintf(filename, 127, "%s/%s-%s", meterfiles_dir_.c_str(), meter->name().c_str(), t->id.c_str());
break;
}
const char *mode = overwrite_ ? "w" : "a";
output = fopen(filename, mode);
if (!output) {

Wyświetl plik

@ -17,6 +17,7 @@
#include"cmdline.h"
#include"meters.h"
#include"wmbus.h"
using namespace std;
@ -27,7 +28,8 @@ struct Printer {
bool meterfiles, string &meterfiles_dir,
bool use_logfile, string &logfile,
vector<string> shell_cmdlines,
bool overwrite);
bool overwrite,
MeterFileNaming naming);
void print(Telegram *t, Meter *meter);
@ -41,8 +43,9 @@ struct Printer {
char separator_;
vector<string> shell_cmdlines_;
bool overwrite_;
MeterFileNaming naming_;
void printShells(Meter *meter, vector<string> &envs);
void printFiles(Meter *meter, string &human_readable, string &fields, string &json);
void printFiles(Meter *meter, Telegram *t, string &human_readable, string &fields, string &json);
};

Wyświetl plik

@ -4,4 +4,5 @@ logtelegrams=false
format=json
meterfiles=testoutput/meter_readings3
meterfilesaction=append
meterfilesnaming=id
logfile=testoutput/thelog3.txt

Wyświetl plik

@ -4,14 +4,20 @@ PROG="$1"
TEST=testoutput
mkdir -p $TEST/meter_readings3
rm -f $TEST/meter_readings3/Element
rm -f $TEST/meter_readings3/*
cat simulations/simulation_multiple_qcalorics.txt | grep '^{' > $TEST/test_expected.txt
$PROG --useconfig=tests/config3 > $TEST/test_output.txt
if [ "$?" == "0" ]
then
cat $TEST/meter_readings3/Element | sed 's/"timestamp":"....-..-..T..:..:..Z"/"timestamp":"1111-11-11T11:11:11Z"/' > $TEST/test_responses.txt
FILES=$(ls $TEST/meter_readings3/ | tr '\n' ' ')
if [ ! "$FILES" = "78563412 78563413 88563414 " ]
then
echo Failure, not the expected files in meter readings directory.
exit 1
fi
cat $TEST/meter_readings3/* | sed 's/"timestamp":"....-..-..T..:..:..Z"/"timestamp":"1111-11-11T11:11:11Z"/' > $TEST/test_responses.txt
diff $TEST/test_expected.txt $TEST/test_responses.txt
if [ "$?" == "0" ]
then

Wyświetl plik

@ -20,11 +20,23 @@ fi
rm -rf /tmp/testmeters
mkdir /tmp/testmeters
cat simulations/simulation_c1.txt | grep '^{' | grep 76348799 | tail -n 1 > $TEST/test_expected.txt
$PROG --meterfiles=/tmp/testmeters --format=json simulations/simulation_c1.txt MyTapWater multical21 76348799 "" > /dev/null
cat /tmp/testmeters/MyTapWater | sed 's/"timestamp":"....-..-..T..:..:..Z"/"timestamp":"1111-11-11T11:11:11Z"/' > $TEST/test_response.txt
$PROG --meterfiles=/tmp/testmeters --meterfilesnaming=name-id --format=json simulations/simulation_c1.txt MyTapWater multical21 76348799 "" > /dev/null
cat /tmp/testmeters/MyTapWater-76348799 | sed 's/"timestamp":"....-..-..T..:..:..Z"/"timestamp":"1111-11-11T11:11:11Z"/' > $TEST/test_response.txt
diff $TEST/test_expected.txt $TEST/test_response.txt
if [ "$?" == "0" ]
then
echo Meterfiles dir OK
rm -rf /tmp/testmeters
fi
rm -rf /tmp/testmeters
mkdir /tmp/testmeters
cat simulations/simulation_c1.txt | grep '^{' | grep 76348799 | tail -n 1 > $TEST/test_expected.txt
$PROG --meterfiles=/tmp/testmeters --meterfilesnaming=id --format=json simulations/simulation_c1.txt MyTapWater multical21 76348799 ""
cat /tmp/testmeters/76348799 | sed 's/"timestamp":"....-..-..T..:..:..Z"/"timestamp":"1111-11-11T11:11:11Z"/' > $TEST/test_response.txt
diff $TEST/test_expected.txt $TEST/test_response.txt
if [ "$?" == "0" ]
then
echo Meterfiles naming OK
rm -rf /tmp/testmeters
fi

Wyświetl plik

@ -43,6 +43,8 @@ mqtt_publish) sent to a REST API (eg curl) or store it in a database
\fB\--meterfilesaction=\fR(overwrite|append) overwrite or append to the meter readings file
\fB\--meterfilesnaming=\fR(name|id|name-id) the meter file is the meter's: name, id or name-id
\fB\--oneshot\fR wait for an update from each meter, then quit
\fB\--separator=\fR<c> change field separator to c