Updated command line options and added man page

pull/22/head
weetmuts 2019-02-26 22:19:16 +01:00
rodzic c3bf72b155
commit 58e89749d3
14 zmienionych plików z 303 dodań i 110 usunięć

Wyświetl plik

@ -7,6 +7,7 @@ Running wmbusmeters as daemon is now supported.
Using rtl_wmbus to receive wmbus messages from
rtl_sdr is work in progress.
Updated README
Updated some command line options robot is now format.
Version 0.8.4: 2019-02-23
@ -24,7 +25,7 @@ Now properly extracts temperature from short frames!
Added support for Multical21 meters with max flow configuration.
Note! Since max flow was added to multical21, there is an extra
column in the human output and --robot=fields output.
column in the human output and --format=fields output.
There is also "max_flow_m3h"="123" in the json output, but that does not
affect existing code depending on json.

Wyświetl plik

@ -27,7 +27,7 @@ Check the config file /etc/wmbusmeters.conf:
loglevel=normal
device=auto
logtelegrams=false
meterfilesdir=/var/log/wmbusmeters/meter_readings
meterfiles=/var/log/wmbusmeters/meter_readings
logfile=/var/log/wmbusmeters/wmbusmeters.log
shell=/usr/bin/mosquitto_pub -h localhost -t wmbusmeters -m "$METER_JSON"
```
@ -66,31 +66,45 @@ The files/dir should then be located here:
```
wmbusmeters version: 0.9
Usage: wmbusmeters {options} (auto | /dev/ttyUSBx)] { [meter_name] [meter_type] [meter_id] [meter_key] }*
Usage: wmbusmeters {options} <device> ( [meter_name] [meter_type] [meter_id] [meter_key] )*
Add more meter quadruplets to listen to more meters.
Add --verbose for detailed debug information.
--robot or --robot=json for json output.
--robot=fields for semicolon separated fields.
--separator=X change field separator to X.
--logfile=file
--meterfiles=dir to create status files below dir,
named dir/meter_name, containing the latest reading.
--meterfiles defaults dir to /tmp.
--c1 or --t1 listen to C1 or T1 messages
--shell=cmd invokes cmd with env variables containing the latest reading.
--shellenvs list the env variables available for the meter.
--oneshot wait for an update from each meter, then quit.
--useconfig=dir look for configuration file in dir/etc/wmbusmeters.conf and
dir/etc/wmbusmeters.d
--useconfig defaults to the root /etc
--exitafter=20h program exits after running for twenty hours,
or 10m for ten minutes or 5s for five seconds.
As <options> you can use:
Specifying auto as the device will automatically look for usb
wmbus dongles on /dev/im871a and /dev/amb8465.
--c1 or --t1 listen to C1 or T1 messages when no meters are supplied
--debug for a lot of information
--exitafter=<time> exit program after time, eg 20h, 10m 5s
--format=<hr/json/fields> for human readable, json or semicolon separated fields
--logfile=<file> use this file instead of stdout
--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
--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
--shellenvs list the env variables available for the meter
--useconfig=<dir> load config files from dir/etc
--verbose for more information
You can specify the device rtlwmbus to have wmbusmeters spawn rtl_sdr|rtlwmbus
As a <device> you can use:
"/dev/ttyUSB" to which a im871a/amb8465 dongle is attached,
or you can specify auto and wmbusmeters will look for a suitable dongle
on the device links /dev/im871a and /dev/amb8465.
"rtlwmbus:868.95M" to have wmbusmeters spawn:
"rtl_sdr -f 868.95M -s 1600000 - 2>/dev/null | rtl_wmbus"
(you might have to tweak 868.95M to nearby frequencies depending
on the rtl-sdr dongle you are using)
"rtlwmbus:<commandline>" to have wmbusmeters spawn
that commandline instead, the output is expected to be like rtl_wmbus.
As meter quadruples you specify:
<meter_name> a mnemonic for this particular meter
<meter_type> one of the supported meters
<meter_id> an 8 digit mbus id, usually printed on the meter
<meter_key> an encryption key unique for the meter
if the meter uses no encryption, then supply ""
Supported water meters:
Kamstrup Multical 21 (multical21)
@ -104,13 +118,6 @@ Electricity meter Kamstrup Omnipower (omnipower)
Heat cost allocator Qundis Q caloric (qcaloric)
```
No meter quadruplets means listen for telegram traffic and print any id heard,
but you have to specify if you want to listen using radio mode C1 or T1. E.g.
```
wmbusmeters --t1 /dev/ttyUSB0
```
You can listen to multiple meters as long as they all require the same radio mode C1 or T1.
So (currently) you cannot listen to a multical21 and a supercom587 with a single dongle at the same time.
@ -128,17 +135,17 @@ Example output:
(Here the multical21 itself, is configured to send target volume, therefore the max flow is 0.000 m3/h.)
Example robot json output:
Example format json output:
`wmbusmeters --robot=json auto MyTapWater multical21 12345678 00112233445566778899AABBCCDDEEFF MyHeater multical302 22222222 00112233445566778899AABBCCDDEEFF`
`wmbusmeters --format=json auto MyTapWater multical21 12345678 00112233445566778899AABBCCDDEEFF MyHeater multical302 22222222 00112233445566778899AABBCCDDEEFF`
`{"media":"cold water","meter":"multical21","name":"MyTapWater","id":"12345678","total_m3":6.388,"target_m3":6.377,"max_flow_m3h":0.000,"flow_temperature":8,"external_temperature":23,"current_status":"DRY","time_dry":"22-31 days","time_reversed":"","time_leaking":"","time_bursting":"","timestamp":"2018-02-08T09:07:22Z"}`
`{"media":"heat","meter":"multical302","name":"MyHeater","id":"22222222","total_kwh":0.000,"total_volume_m3":0.000,"current_kw":"0.000","timestamp":"2018-02-08T09:07:22Z"}`
Example robot fields output:
Example format fields output:
`wmbusmeters --robot=fields auto GreenhouseWater multical21 33333333 ""`
`wmbusmeters --format=fields auto GreenhouseWater multical21 33333333 ""`
`GreenhouseTapWater;33333333;9999.099;77.712;0.000;11;31;;2018-03-05 12:10.24`
@ -158,7 +165,7 @@ You can use `--debug` to get both verbose output and the actual data bytes sent
If the meter does not use encryption of its meter data, then enter an empty key on the command line.
(you must enter "")
`wmbusmeters --robot --meterfiles auto MyTapWater multical21 12345678 ""`
`wmbusmeters --format=json --meterfiles auto MyTapWater multical21 12345678 ""`
If you have a Multical21 meter and you have received a KEM file and its password,
from your water municipality, then you can use the XMLExtract.java utility to get
@ -194,19 +201,19 @@ Binary generated: `./wmbusmeters_0.8_armhf.deb`
# System configuration
Add yourself to the dialout group to get access to the newly plugged in im871A USB stick.
Or even better, add this udev rule:
`make install` installs `/usr/bin/wmbusmeters`, `/usr/sbin/wmbusmetersd`, `wmbusmeters.service`
and `99-wmbus-usb-serial.rules`.
Create the file: `/etc/udev/rules.d/99-usb-serial.rules` with the content
```
SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", SYMLINK+="im871a",MODE="0660", GROUP="yourowngroup"
SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", SYMLINK+="amb8465",MODE="0660", GROUP="yourowngroup"
```
This means that when a im871a/amb8465 dongle is inserted, then the appropriate /dev/im871a or
/dev/amb8465 link is created. Also the wmbusmeters daemon will be automatically
started/stopped whenever the im871a/amb8465 dongle is inserted/removed,
and the daemon starts when the computer boots, if the dongle is already inserted.
When you insert the wmbus USB dongle, a properly named symlink will be
created: either `/dev/im871a` or `/dev/amb8465`. These symlinks are
necessary if you want to pass "auto" to wmbusmeters instead of the
exact serial port /dev/ttyUSBx.
If you do not want the daemon to start automatically, simply edit
/dev/udev/rules.d/99-wmbus-usb-serial.rules and remove `,TAG+="systemd",ENV{SYSTEMD_WANTS}="wmbusmeters.service"`
from each line.
You can also start/stop the daemon with `sudo systemctl start wmbusmeters`
# Source code

Wyświetl plik

@ -47,6 +47,17 @@ ln -s $ROOT/usr/bin/wmbusmeters $ROOT/usr/sbin/wmbusmetersd
echo binaries: installed $ROOT/usr/bin/wmbusmeters and $ROOT/usr/sbin/wmbusmetersd
####################################################################
##
## Intall wmbusmeters manual page
##
rm -f $ROOT/usr/share/man/man1/wmbusmeters.1.gz
mkdir -p $ROOT/usr/share/man/man1
gzip -c wmbusmeters.1 > $ROOT/usr/share/man/man1/wmbusmeters.1.gz
echo man page: installed $ROOT/usr/share/man/man1/wmbusmeters.1.gz
####################################################################
##
## Create wmbusmeters user
@ -126,8 +137,8 @@ then
loglevel=normal
device=auto
logtelegrams=false
robot=json
meterfilesdir=/var/log/wmbusmeters/meter_readings
format=json
meterfiles=/var/log/wmbusmeters/meter_readings
meterfilestype=overwrite
logfile=/var/log/wmbusmeters/wmbusmeters.log
EOF

Wyświetl plik

@ -115,29 +115,29 @@ unique_ptr<Configuration> parseCommandLine(int argc, char **argv) {
}
return unique_ptr<Configuration>(c);
}
if (!strncmp(argv[i], "--robot", 7)) {
if (strlen(argv[i]) == 7 ||
(strlen(argv[i]) == 12 &&
!strncmp(argv[i]+7, "=json", 5)))
if (!strncmp(argv[i], "--format", 8)) {
if (strlen(argv[i]) == 8 ||
(strlen(argv[i]) == 13 &&
!strncmp(argv[i]+8, "=json", 5)))
{
c->json = true;
c->fields = false;
}
else if (strlen(argv[i]) == 14 &&
else if (strlen(argv[i]) == 15 &&
!strncmp(argv[i]+7, "=fields", 7))
{
c->json = false;
c->fields = true;
c->separator = ';';
} else {
error("Unknown output format: \"%s\"\n", argv[i]+7);
error("Unknown output format: \"%s\"\n", argv[i]+8);
}
i++;
continue;
}
if (!strncmp(argv[i], "--separator=", 12)) {
if (!c->fields) {
error("You must specify --robot=fields before --separator=X\n");
error("You must specify --format=fields before --separator=X\n");
}
if (strlen(argv[i]) != 13) {
error("You must supply a single character as the field separator.\n");
@ -164,6 +164,21 @@ unique_ptr<Configuration> parseCommandLine(int argc, char **argv) {
i++;
continue;
}
if (!strncmp(argv[i], "--meterfilesaction", 18)) {
if (strlen(argv[i]) > 18 && argv[i][18] == '=') {
if (!strncmp(argv[i]+19, "overwrite", 9)) {
c->meterfiles_action = MeterFileType::Overwrite;
} else if (!strncmp(argv[i]+19, "append", 6)) {
c->meterfiles_action = MeterFileType::Append;
} else {
error("No such meter file action %s\n", argv[i]+19);
}
} else {
error("Incorrect option %s\n", argv[i]);
}
i++;
continue;
}
if (!strncmp(argv[i], "--logfile=", 10)) {
c->use_logfile = true;
if (strlen(argv[i]) > 10) {

Wyświetl plik

@ -118,11 +118,11 @@ void handleLogtelegrams(Configuration *c, string logtelegrams)
}
}
void handleMeterfilesdir(Configuration *c, string meterfilesdir)
void handleMeterfiles(Configuration *c, string meterfiles)
{
if (meterfilesdir.length() > 0)
if (meterfiles.length() > 0)
{
c->meterfiles_dir = meterfilesdir;
c->meterfiles_dir = meterfiles;
c->meterfiles = true;
if (!checkIfDirExists(c->meterfiles_dir.c_str())) {
warning("Cannot write meter files into dir \"%s\"\n", c->meterfiles_dir.c_str());
@ -130,16 +130,16 @@ void handleMeterfilesdir(Configuration *c, string meterfilesdir)
}
}
void handleMeterfilestype(Configuration *c, string meterfilestype)
void handleMeterfilesAction(Configuration *c, string meterfilesaction)
{
if (meterfilestype == "overwrite")
if (meterfilesaction == "overwrite")
{
c->meterfiles_type = MeterFileType::Overwrite;
} else if (meterfilestype == "append")
c->meterfiles_action = MeterFileType::Overwrite;
} else if (meterfilesaction == "append")
{
c->meterfiles_type = MeterFileType::Append;
c->meterfiles_action = MeterFileType::Append;
} else {
warning("No such meter file type \"%s\"\n", meterfilestype.c_str());
warning("No such meter file action \"%s\"\n", meterfilesaction.c_str());
}
}
@ -152,20 +152,24 @@ void handleLogfile(Configuration *c, string logfile)
}
}
void handleRobot(Configuration *c, string robot)
void handleFormat(Configuration *c, string format)
{
if (robot == "json")
if (format == "hr")
{
c->json = false;
c->fields = false;
} else if (format == "json")
{
c->json = true;
c->fields = false;
}
else if (robot == "fields")
else if (format == "fields")
{
c->json = false;
c->fields = true;
c->separator = ';';
} else {
warning("Unknown output format: \"%s\"\n", robot.c_str());
warning("Unknown output format: \"%s\"\n", format.c_str());
}
}
@ -205,10 +209,10 @@ unique_ptr<Configuration> loadConfiguration(string root)
if (p.first == "loglevel") handleLoglevel(c, p.second);
else if (p.first == "device") handleDevice(c, p.second);
else if (p.first == "logtelegrams") handleLogtelegrams(c, p.second);
else if (p.first == "meterfilesdir") handleMeterfilesdir(c, p.second);
else if (p.first == "meterfilestype") handleMeterfilestype(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 == "logfile") handleLogfile(c, p.second);
else if (p.first == "robot") handleRobot(c, p.second);
else if (p.first == "format") handleFormat(c, p.second);
else if (p.first == "separator") handleSeparator(c, p.second);
else if (p.first == "shell") handleShell(c, p.second);
else

Wyświetl plik

@ -56,7 +56,7 @@ struct Configuration {
bool logtelegrams {};
bool meterfiles {};
std::string meterfiles_dir;
MeterFileType meterfiles_type {};
MeterFileType meterfiles_action {};
bool use_logfile {};
std::string logfile;
bool json {};

Wyświetl plik

@ -48,37 +48,59 @@ int main(int argc, char **argv)
if (cmdline->need_help) {
printf("wmbusmeters version: " WMBUSMETERS_VERSION "\n");
printf("Usage: wmbusmeters [options] (auto | /dev/ttyUSBx) { [meter_name] [meter_type] [meter_id] [meter_key] }* \n\n");
printf("Add more meter quadruplets to listen to more meters.\n");
printf("Add --verbose for more detailed information on communication.\n");
printf(" --robot or --robot=json for json output.\n");
printf(" --robot=fields for semicolon separated fields.\n");
printf(" --separator=X change field separator to X.\n");
printf(" --logfile=file\n");
printf(" --meterfiles=dir to create status files below dir,\n"
" named dir/meter_name, containing the latest reading.\n");
printf(" --meterfiles defaults dir to /tmp.\n");
printf(" --shell=cmd invokes cmd with env variables containing the latest reading.\n");
printf(" --shellenvs list the env variables available for the meter.\n");
printf(" --oneshot wait for an update from each meter, then quit.\n");
printf(" --useconfig=dir look for configuration file in dir/etc/wmbusmeters.conf and\n");
printf(" dir/etc/wmbusmeters.d\n");
printf(" --useconfig defaults to the root /etc\n");
printf(" --exitafter=20h program exits after running for twenty hoursh\n"
" or 10m for ten minutes or 5s for five seconds.\n");
printf(" --useconfig read from /etc/wmbusmeters.conf and /etc/wmbusmeters.d\n");
printf(" check the man page for how to write the config files.\n");
printf(" --reload signals a running wmbusmeters daemon to reload the configuration,\n");
printf(" when you have modified config files and/or usb dongles.\n\n");
const char *msg = R"MANUAL(
Usage: wmbusmeters {options} <device> ( [meter_name] [meter_type] [meter_id] [meter_key] )*
printf("Specifying auto as the device will automatically look for usb\n");
printf("wmbus dongles on /dev/im871a and /dev/amb8465\n\n");
As <options> you can use:
printf("You can specify the device rtlwmbus to have wmbusmeters spawn rtl_sdr|rtlwmbus\n\n");
--c1 or --t1 listen to C1 or T1 messages when no meters are supplied
--debug for a lot of information
--exitafter=<time> exit program after time, eg 20h, 10m 5s
--format=<hr/json/fields> for human readable, json or semicolon separated fields
--logfile=<file> use this file instead of stdout
--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
--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
--shellenvs list the env variables available for the meter
--useconfig=<dir> load config files from dir/etc
--verbose for more information
printf("The meter types: multical21,flowiq3100,supercom587,iperl (water meters) are supported.\n"
"The meter types: multical302 (heat) and omnipower (electricity) qcaloric (heat cost)\n"
"are work in progress.\n\n");
As a <device> you can use:
"/dev/ttyUSB" to which a im871a/amb8465 dongle is attached,
or you can specify auto and wmbusmeters will look for a suitable dongle
on the device links /dev/im871a and /dev/amb8465.
"rtlwmbus:868.95M" to have wmbusmeters spawn:
"rtl_sdr -f 868.95M -s 1600000 - 2>/dev/null | rtl_wmbus"
(you might have to tweak 868.95M to nearby frequencies depending
on the rtl-sdr dongle you are using)
"rtlwmbus:<commandline>" to have wmbusmeters spawn
that commandline instead, the output is expected to be like rtl_wmbus.
As meter quadruples you specify:
<meter_name> a mnemonic for this particular meter
<meter_type> one of the supported meters
<meter_id> an 8 digit mbus id, usually printed on the meter
<meter_key> an encryption key unique for the meter
if the meter uses no encryption, then supply ""
Supported water meters:
Kamstrup Multical 21 (multical21)
Kamstrup flowIQ 3100 (flowiq3100)
Sontex Supercom 587 (supercom587)
Sensus iPERL (iperl)
Work in progress:
Heat meter Kamstrup Multical 302 (multical302)
Electricity meter Kamstrup Omnipower (omnipower)
Heat cost allocator Qundis Q caloric (qcaloric)
)MANUAL";
puts(msg);
}
else
if (cmdline->daemon) {
@ -183,7 +205,7 @@ void startUsingCommandline(Configuration *config)
auto output = unique_ptr<Printer>(new Printer(config->json, config->fields,
config->separator, config->meterfiles, config->meterfiles_dir,
config->shells,
config->meterfiles_type == MeterFileType::Overwrite));
config->meterfiles_action == MeterFileType::Overwrite));
vector<unique_ptr<Meter>> meters;
if (config->meters.size() > 0) {

Wyświetl plik

@ -1,4 +1,4 @@
loglevel=normal
device=simulations/simulation_c1.txt
logtelegrams=false
robot=json
format=json

Wyświetl plik

@ -1,6 +1,6 @@
loglevel=normal
device=simulations/simulation_t1.txt
logtelegrams=false
robot=json
meterfilesdir=testoutput/meter_readings2
format=json
meterfiles=testoutput/meter_readings2
logfile=testoutput/thelog2.txt

Wyświetl plik

@ -7,7 +7,7 @@ mkdir -p testoutput
TEST=testoutput
cat simulations/simulation_c1.txt | grep '^{' > $TEST/test_expected.txt
$PROG --robot=json simulations/simulation_c1.txt \
$PROG --format=json simulations/simulation_c1.txt \
MyHeater multical302 12345678 "" \
MyTapWater multical21 76348799 "" \
Vadden multical21 44556677 "" \

Wyświetl plik

@ -46,5 +46,5 @@ if [ "$ERRORS" = "true" ]
then
echo Failed config2 tests
else
echo Config2 with logfile and meterfilesdir OK
echo Config2 with logfile and meterfiles OK
fi

Wyświetl plik

@ -8,7 +8,7 @@ TEST=testoutput
rm -f /tmp/MyTapWater
cat simulations/simulation_c1.txt | grep '^{' | grep 76348799 | tail -n 1 > $TEST/test_expected.txt
$PROG --meterfiles --robot=json simulations/simulation_c1.txt MyTapWater multical21 76348799 "" > /dev/null
$PROG --meterfiles --format=json simulations/simulation_c1.txt MyTapWater multical21 76348799 "" > /dev/null
cat /tmp/MyTapWater | 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" ]
@ -20,7 +20,7 @@ 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 --robot=json simulations/simulation_c1.txt MyTapWater multical21 76348799 "" > /dev/null
$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
diff $TEST/test_expected.txt $TEST/test_response.txt
if [ "$?" == "0" ]

Wyświetl plik

@ -7,7 +7,7 @@ mkdir -p testoutput
TEST=testoutput
cat simulations/simulation_t1.txt | grep '^{' > $TEST/test_expected.txt
$PROG --robot=json simulations/simulation_t1.txt \
$PROG --format=json simulations/simulation_t1.txt \
MyWarmWater supercom587 12345678 "" \
MyColdWater supercom587 11111111 "" \
MoreWater iperl 12345699 "" \

133
wmbusmeters.1 100644
Wyświetl plik

@ -0,0 +1,133 @@
.TH BEAK 1
.SH NAME
wmbusmeters \- read the wireless mbus protocol to acquire and relay utility meter readings.
.SH SYNOPSIS
.B wmbusmeters [options] <device> (<meter_name> <meter_type> <meter_id> meter_key>)*
.B wmbusmetersd <pid_file>
.SH DESCRIPTION
Wmbusmeters acquires wmbus telegrams, parses them and relays them to some other software for further processing.
It can for example listen to radio traffic using dedicated wmbus dongles like (im871a/amb8465) or
a generic software defined radio dongle (rtl_sdr).
After the received telegram has been decrypted and parsed, it is relayed using a shell command, or stored in a log file.
The shell commands can for example relay the telegram using MQTT (eg mqtt_publish) sent to a REST API (eg curl)
or store it in a database (eg psql).
.SH OPTIONS
[\fB\--c1\fR] listen to C1 messages when no meters are supplied
[\fB\--debug\fR] for a lot of information
[\fB\--exitafter=\fR<time>] exit program after time, eg 20h, 10m 5s
[\fB\--format=\fR(hr|json|fields)] for human readable, json or semicolon separated fields
[\fB\--logfile=\fR<dir>] use this file instead of stdout
[\fB\--logtelegrams\fR] log the contents of the telegrams for easy replay
[\fB\--meterfiles=\fR<dir>] store meter readings in dir
[\fB\--meterfilesaction=\fR(overwrite|append)] overwrite or append to the meter readings file
[\fB\--oneshot\fR] wait for an update from each meter, then quit
[\fB\--separator=\fR<c>] change field separator to c
[\fB\--shell=\fR<cmdline>] invokes cmdline with env variables containing the latest reading
[\fB\--shellenvs\fR] list the env variables available for the meter
[\fB\--t1\fR] listen to T1 messages when no meters are supplied
[\fB\--useconfig=\fR<dir>] load config files from dir/etc
[\fB\--verbose\fR] for more information
.SH DEVICES
.TP
[\fB/dev/ttyUSB0\fR] to which an im871a or amb8456 dongle is attached
.TP
[\fBauto\fR] look for /dev/im871a or /dev/amb8465
.TP
[\fBrtlwmbus:<freq>\fR] use software defined radio rtl_sdr|rtl_wmbus to received wmbus telegrams
.TP
[\fBsimulation.txt\fR] read telegrams from file to replay telegram feed (use --logtelegrams to acquire feed for replay)
.SH METER QUADRUPLES
.TP
[\fBmeter_name\fR] a mnemonic for your utility meter
.TP
[\fBmeter_type\fR] multical21/flowiq3100/supercom587/iperl/multical302/omnipower/qcaloric
.TP
[\fBmeter_id\fR] an 8 digit number, usually printed on the meter
.TP
[\fBmeter_key\fR] a unique key for the meter, if meter telegrams are not encrypted, you must supply an empty key: ""
.SH EXAMPLES
.TP
Listen to T1 traffic using a wmbus dongle attached to ttyUSB0.
% wmbusmeters --t1 /dev/ttyUSB0
.TP
Listen to C1 traffic and assume that a wmbus dongle is either /dev/im871a or /dev/amb8465.
% wmbusmeters --c1 auto
.TP
Listen to both T1 and C1 traffic using rtl_sdr|rtl_wmbus and the standard frequency 868.95M, which
might need tweaking depending on the rtl_sdr dongle you are using.
% wmbusmeters rtlwmbus:868.95M
.TP
Execute using config file /home/me/etc/wmbusmeters.conf and meter config files in /home/me/etc/wmbusmeters.d
% wmbusmeters --useconfig=/home/me
.TP
Start a daemon using config file /etc/wmbusmeters.conf and meter config files in /etc/wmbusmeters.d
% wmbusmetersd --useconfig=/
.TP
An example wmbusmeters.conf:
.nf
loglevel=normal
device=auto
logtelegrams=false
meterfiles=/var/log/wmbusmeters/meter_readings
logfile=/var/log/wmbusmeters/wmbusmeters.log
shell=/usr/bin/mosquitto_pub -h localhost -t wmbusmeters -m "$METER_JSON"
.fi
.TP
An example wmbusmeters.d file:
.nf
name=MyTapWater
type=multical21
id=12345678
key=001122334455667788AABBCCDDEEFF
.SH AUTHOR
Written by Fredrik Öhrström.
.SH COPYRIGHT
Copyright \(co 2017-2019 Fredrik Öhrström.
.br
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
.br
This is free software: you are free to change and redistribute it.
.br
There is NO WARRANTY, to the extent permitted by law.