kopia lustrzana https://github.com/weetmuts/wmbusmeters
Alarm test work again.
rodzic
802e62cbbd
commit
891e3f4228
26
CHANGES
26
CHANGES
|
@ -1,6 +1,32 @@
|
||||||
|
|
||||||
|
IMPORTANT CHANGES THAT MIGHT AFFECT YOU!
|
||||||
|
|
||||||
|
** No udev rules
|
||||||
|
|
||||||
|
Wmbusmeters new default behaviour is to NOT exit if no wmbus
|
||||||
|
device is found. It stays running all the time even if no
|
||||||
|
wmbus device is detected. As soon as a device is inserted
|
||||||
|
it will detect/configure and start using the device.
|
||||||
|
|
||||||
|
When reading stdin and files, then wmbusmeters will exit
|
||||||
|
as soon as there is no more data.
|
||||||
|
|
||||||
|
This means that the udev rules no longer are needed and must be
|
||||||
|
removed. This will be done automatically by the install script.
|
||||||
|
|
||||||
|
** Use stderr for logging, stdout for data.
|
||||||
|
|
||||||
|
wmbusmeters now uses STDERR as default for info/verbose/debug/trace output.
|
||||||
|
This will not affect you if you run wmbusmeters as a daemon,
|
||||||
|
but if you start wmbusmeters yourself you should check where stderr is going.
|
||||||
|
To use the old style add --usestdoutforlogging.
|
||||||
|
|
||||||
|
** New features
|
||||||
|
|
||||||
To list the shell envs for a meter do --listenvs=multical21
|
To list the shell envs for a meter do --listenvs=multical21
|
||||||
To list the fields avilable for a meter do --listfields=multical21
|
To list the fields avilable for a meter do --listfields=multical21
|
||||||
|
To list all meters do --listmeters
|
||||||
|
To search for a meter do --listmeters=water or --listmeters=multi
|
||||||
|
|
||||||
Version 0.9.36: 2020-09-08
|
Version 0.9.36: 2020-09-08
|
||||||
|
|
||||||
|
|
|
@ -142,6 +142,9 @@ Usage: wmbusmeters {options} <device>{:suffix} ( [meter_name] [meter_type]{:<mod
|
||||||
As <options> you can use:
|
As <options> you can use:
|
||||||
|
|
||||||
--addconversions=<unit>+ add conversion to these units to json and meter env variables (GJ)
|
--addconversions=<unit>+ add conversion to these units to json and meter env variables (GJ)
|
||||||
|
--alarmexpectedactivity=mon-fri(08-17) Specify when the timeout is tested, default is mon-sun(00-23)
|
||||||
|
--alarmshell=<cmdline> invokes cmdline when an alarm triggers
|
||||||
|
--alarmtimeout=<time> Expect a telegram to arrive within <time> seconds, eg 60s, 60m, 24h during expected activity.
|
||||||
--debug for a lot of information
|
--debug for a lot of information
|
||||||
--exitafter=<time> exit program after time, eg 20h, 10m 5s
|
--exitafter=<time> exit program after time, eg 20h, 10m 5s
|
||||||
--format=<hr/json/fields> for human readable, json or semicolon separated fields
|
--format=<hr/json/fields> for human readable, json or semicolon separated fields
|
||||||
|
|
24
install.sh
24
install.sh
|
@ -74,8 +74,6 @@ echo man page: installed "$ROOT"/usr/share/man/man1/wmbusmeters.1.gz
|
||||||
## Create wmbusmeters user
|
## Create wmbusmeters user
|
||||||
##
|
##
|
||||||
|
|
||||||
ID=$(id -u wmbusmeters 2>/dev/null)
|
|
||||||
|
|
||||||
if [ -f "$ROOT"/usr/sbin/nologin ]
|
if [ -f "$ROOT"/usr/sbin/nologin ]
|
||||||
then
|
then
|
||||||
USERSHELL="$ROOT/usr/sbin/nologin"
|
USERSHELL="$ROOT/usr/sbin/nologin"
|
||||||
|
@ -88,15 +86,17 @@ fi
|
||||||
|
|
||||||
if [ "$ADDUSER" = "true" ]
|
if [ "$ADDUSER" = "true" ]
|
||||||
then
|
then
|
||||||
|
# Create the wmbusmeters group, if it does not already exist.
|
||||||
|
groupadd -f wmbusmeters
|
||||||
|
|
||||||
|
ID=$(id -u wmbusmeters 2>/dev/null)
|
||||||
if [ -z "$ID" ]
|
if [ -z "$ID" ]
|
||||||
then
|
then
|
||||||
# Create the wmbusmeters group, if it does not already exist.
|
|
||||||
groupadd -f wmbusmeters
|
|
||||||
# Create the wmbusmeters user
|
# Create the wmbusmeters user
|
||||||
useradd --system --shell $USERSHELL -g wmbusmeters --groups dialout wmbusmeters
|
useradd --system --shell $USERSHELL -g wmbusmeters wmbusmeters
|
||||||
echo user: added wmbusmeters
|
echo user: added wmbusmeters
|
||||||
else
|
else
|
||||||
echo user: wmbusmeters unmodified
|
echo user: wmbusmeters already exists
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$(groups wmbusmeters | grep -o dialout)" = "" ]
|
if [ "$(groups wmbusmeters | grep -o dialout)" = "" ]
|
||||||
|
@ -107,6 +107,16 @@ then
|
||||||
else
|
else
|
||||||
echo user: wmbusmeters already added to dialout
|
echo user: wmbusmeters already added to dialout
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "$(groups wmbusmeters | grep -o plugdev)" = "" ]
|
||||||
|
then
|
||||||
|
# Add the wmbusmeters user to plugdev
|
||||||
|
usermod -a -G plugdev wmbusmeters
|
||||||
|
echo user: added wmbusmeters to plugdev group
|
||||||
|
else
|
||||||
|
echo user: wmbusmeters already added to plugdev
|
||||||
|
fi
|
||||||
|
|
||||||
if [ ! -z "$SUDO_USER" ]
|
if [ ! -z "$SUDO_USER" ]
|
||||||
then
|
then
|
||||||
if [ "$(groups $SUDO_USER | grep -o wmbusmeters)" = "" ]
|
if [ "$(groups $SUDO_USER | grep -o wmbusmeters)" = "" ]
|
||||||
|
@ -236,7 +246,7 @@ fi
|
||||||
# This means that wmbusmeters will rely on the conf file device setting.
|
# This means that wmbusmeters will rely on the conf file device setting.
|
||||||
cat <<'EOF' > $CURR_WMBS
|
cat <<'EOF' > $CURR_WMBS
|
||||||
[Unit]
|
[Unit]
|
||||||
Description="wmbusmeters service (no udev trigger)"
|
Description="wmbusmeters service"
|
||||||
Documentation=https://github.com/weetmuts/wmbusmeters
|
Documentation=https://github.com/weetmuts/wmbusmeters
|
||||||
Documentation=man:wmbusmeters(1)
|
Documentation=man:wmbusmeters(1)
|
||||||
After=network.target
|
After=network.target
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
telegram=|2A442D2C998734761B168D2091D37CAC21576C78|02FF207100041308190000441308190000615B7F616713|+0
|
telegram=|2A442D2C998734761B168D2091D37CAC21576C78|02FF207100041308190000441308190000615B7F616713|+0
|
||||||
{"media":"cold water","meter":"multical21","name":"MyTapWater","id":"76348799","total_m3":6.408,"target_m3":6.408,"max_flow_m3h":0,"flow_temperature_c":127,"external_temperature_c":19,"current_status":"DRY","time_dry":"22-31 days","time_reversed":"","time_leaking":"","time_bursting":"","timestamp":"1111-11-11T11:11:11Z"}
|
{"media":"cold water","meter":"multical21","name":"MyTapWater","id":"76348799","total_m3":6.408,"target_m3":6.408,"max_flow_m3h":0,"flow_temperature_c":127,"external_temperature_c":19,"current_status":"DRY","time_dry":"22-31 days","time_reversed":"","time_leaking":"","time_bursting":"","timestamp":"1111-11-11T11:11:11Z"}
|
||||||
telegram=|2A442D2C998734761B168D2091D37CAC21576C78|02FF207100041308190000441308190000615B7F616713|+3
|
telegram=|2A442D2C998734761B168D2091D37CAC21576C78|02FF207100041308190000441308190000615B7F616713|+5
|
||||||
{"media":"cold water","meter":"multical21","name":"MyTapWater","id":"76348799","total_m3":6.408,"target_m3":6.408,"max_flow_m3h":0,"flow_temperature_c":127,"external_temperature_c":19,"current_status":"DRY","time_dry":"22-31 days","time_reversed":"","time_leaking":"","time_bursting":"","timestamp":"1111-11-11T11:11:11Z"}
|
{"media":"cold water","meter":"multical21","name":"MyTapWater","id":"76348799","total_m3":6.408,"target_m3":6.408,"max_flow_m3h":0,"flow_temperature_c":127,"external_temperature_c":19,"current_status":"DRY","time_dry":"22-31 days","time_reversed":"","time_leaking":"","time_bursting":"","timestamp":"1111-11-11T11:11:11Z"}
|
||||||
|
|
19
src/admin.cc
19
src/admin.cc
|
@ -72,7 +72,6 @@ LIST_OF_WMBUS_RECEIVERS
|
||||||
bool detectIfRoot();
|
bool detectIfRoot();
|
||||||
string userName();
|
string userName();
|
||||||
bool detectIfMemberOfGroup(string group);
|
bool detectIfMemberOfGroup(string group);
|
||||||
void detectProcesses(string cmd, vector<int> *pids);
|
|
||||||
void detectWMBUSReceiver();
|
void detectWMBUSReceiver();
|
||||||
void resetWMBUSReceiver();
|
void resetWMBUSReceiver();
|
||||||
void probeFor(string type, AccessCheck(*func)(string,Detected*,SerialCommunicationManager*));
|
void probeFor(string type, AccessCheck(*func)(string,Detected*,SerialCommunicationManager*));
|
||||||
|
@ -359,24 +358,6 @@ bool detectIfMemberOfGroup(string group)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void detectProcesses(string cmd, vector<int> *pids)
|
|
||||||
{
|
|
||||||
vector<string> args;
|
|
||||||
vector<string> envs;
|
|
||||||
args.push_back(cmd);
|
|
||||||
string out;
|
|
||||||
invokeShellCaptureOutput("/bin/pidof", args, envs, &out, true);
|
|
||||||
|
|
||||||
char buf[out.size()+1];
|
|
||||||
strcpy(buf, out.c_str());
|
|
||||||
char *pch;
|
|
||||||
pch = strtok (buf," \n");
|
|
||||||
while (pch != NULL)
|
|
||||||
{
|
|
||||||
pids->push_back(atoi(pch));
|
|
||||||
pch = strtok (NULL, " \n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void stopDaemon()
|
void stopDaemon()
|
||||||
{
|
{
|
||||||
|
|
92
src/main.cc
92
src/main.cc
|
@ -20,6 +20,7 @@
|
||||||
#include"meters.h"
|
#include"meters.h"
|
||||||
#include"printer.h"
|
#include"printer.h"
|
||||||
#include"serial.h"
|
#include"serial.h"
|
||||||
|
#include"shell.h"
|
||||||
#include"util.h"
|
#include"util.h"
|
||||||
#include"version.h"
|
#include"version.h"
|
||||||
#include"wmbus.h"
|
#include"wmbus.h"
|
||||||
|
@ -49,6 +50,7 @@ void logStartInformation(Configuration *config);
|
||||||
bool start(Configuration *config);
|
bool start(Configuration *config);
|
||||||
void startUsingConfigFiles(string root, bool is_daemon, string device_override, string listento_override);
|
void startUsingConfigFiles(string root, bool is_daemon, string device_override, string listento_override);
|
||||||
void startDaemon(string pid_file, string device_override, string listento_override); // Will use config files.
|
void startDaemon(string pid_file, string device_override, string listento_override); // Will use config files.
|
||||||
|
void checkIfMultipleWmbusmetersRunning();
|
||||||
void list_shell_envs(Configuration *config, string meter_type);
|
void list_shell_envs(Configuration *config, string meter_type);
|
||||||
void list_fields(Configuration *config, string meter_type);
|
void list_fields(Configuration *config, string meter_type);
|
||||||
void list_meters(Configuration *config);
|
void list_meters(Configuration *config);
|
||||||
|
@ -81,6 +83,9 @@ set<string> not_swradio_wmbus_devices_;
|
||||||
// it has been read, do not open it again!
|
// it has been read, do not open it again!
|
||||||
set<string> do_not_open_file_again_;
|
set<string> do_not_open_file_again_;
|
||||||
|
|
||||||
|
// Store simulation files here.
|
||||||
|
set<string> simulation_files_;
|
||||||
|
|
||||||
// Rendering the telegrams to json,fields or shell calls is
|
// Rendering the telegrams to json,fields or shell calls is
|
||||||
// done by the printer.
|
// done by the printer.
|
||||||
unique_ptr<Printer> printer_;
|
unique_ptr<Printer> printer_;
|
||||||
|
@ -150,14 +155,15 @@ provided you with this binary. Read the full license for all details.
|
||||||
const char *short_manual =
|
const char *short_manual =
|
||||||
#include"short_manual.h"
|
#include"short_manual.h"
|
||||||
puts(short_manual);
|
puts(short_manual);
|
||||||
|
exit(0);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (config->daemon)
|
if (config->daemon)
|
||||||
{
|
{
|
||||||
startDaemon(config->pid_file, config->device_override, config->listento_override);
|
startDaemon(config->pid_file, config->device_override, config->listento_override);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
if (config->useconfig)
|
if (config->useconfig)
|
||||||
{
|
{
|
||||||
startUsingConfigFiles(config->config_root, false, config->device_override, config->listento_override);
|
startUsingConfigFiles(config->config_root, false, config->device_override, config->listento_override);
|
||||||
|
@ -492,6 +498,20 @@ void remove_lost_swradio_devices_from_ignore_list(vector<string> &devices)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void check_statuses()
|
||||||
|
{
|
||||||
|
LOCK("(main)", "check_statuses", devices_lock_);
|
||||||
|
vector<WMBus*> not_working;
|
||||||
|
for (auto &w : wmbus_devices_)
|
||||||
|
{
|
||||||
|
if (w->isWorking())
|
||||||
|
{
|
||||||
|
w->checkStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UNLOCK("(main)", "check_statuses", devices_lock_);
|
||||||
|
}
|
||||||
|
|
||||||
void check_for_dead_wmbus_devices(Configuration *config)
|
void check_for_dead_wmbus_devices(Configuration *config)
|
||||||
{
|
{
|
||||||
trace("[MAIN] checking for dead wmbus devices...\n");
|
trace("[MAIN] checking for dead wmbus devices...\n");
|
||||||
|
@ -503,9 +523,9 @@ void check_for_dead_wmbus_devices(Configuration *config)
|
||||||
if (!w->isWorking())
|
if (!w->isWorking())
|
||||||
{
|
{
|
||||||
not_working.push_back(w.get());
|
not_working.push_back(w.get());
|
||||||
if (!config->use_auto_detect)
|
if (config->use_auto_detect)
|
||||||
{
|
{
|
||||||
notice("Lost %s closing %s\n", w->device().c_str(), toString(w->type()));
|
info("Lost %s closing %s\n", w->device().c_str(), toString(w->type()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -529,7 +549,8 @@ void check_for_dead_wmbus_devices(Configuration *config)
|
||||||
{
|
{
|
||||||
if (!printed_warning_)
|
if (!printed_warning_)
|
||||||
{
|
{
|
||||||
info("(main) no wmbus device detected, waiting for a device to be plugged in.\n");
|
info("No wmbus device detected, waiting for a device to be plugged in.\n");
|
||||||
|
checkIfMultipleWmbusmetersRunning();
|
||||||
printed_warning_ = true;
|
printed_warning_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -546,7 +567,7 @@ void open_wmbus_device(Configuration *config, string how, string device, Detecte
|
||||||
// A newly plugged in device has been manually configured or automatically detected! Start using it!
|
// A newly plugged in device has been manually configured or automatically detected! Start using it!
|
||||||
if (config->use_auto_detect)
|
if (config->use_auto_detect)
|
||||||
{
|
{
|
||||||
notice("Detected %s %s on %s\n", how.c_str(), toString(detected->type), device.c_str());
|
notice("Configure %s on %s\n", how.c_str(), toString(detected->type), device.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -562,6 +583,11 @@ void open_wmbus_device(Configuration *config, string how, string device, Detecte
|
||||||
bool simulated = detected->type == WMBusDeviceType::DEVICE_SIMULATOR;
|
bool simulated = detected->type == WMBusDeviceType::DEVICE_SIMULATOR;
|
||||||
wmbus->onTelegram([&, simulated](vector<uchar> data){return meter_manager_->handleTelegram(data, simulated);});
|
wmbus->onTelegram([&, simulated](vector<uchar> data){return meter_manager_->handleTelegram(data, simulated);});
|
||||||
wmbus->setTimeout(config->alarm_timeout, config->alarm_expected_activity);
|
wmbus->setTimeout(config->alarm_timeout, config->alarm_expected_activity);
|
||||||
|
if (detected->type == DEVICE_SIMULATOR)
|
||||||
|
{
|
||||||
|
debug("(main) added %s to files\n", detected->device.file.c_str());
|
||||||
|
simulation_files_.insert(detected->device.file);
|
||||||
|
}
|
||||||
UNLOCK("(main)", "perform_auto_scan_of_devices", devices_lock_);
|
UNLOCK("(main)", "perform_auto_scan_of_devices", devices_lock_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -593,11 +619,11 @@ void perform_auto_scan_of_serial_devices(Configuration *config)
|
||||||
// A modem, an android phone, a teletype Model 33, etc....
|
// A modem, an android phone, a teletype Model 33, etc....
|
||||||
// Mark this serial device as unknown, to avoid repeated detection attempts.
|
// Mark this serial device as unknown, to avoid repeated detection attempts.
|
||||||
not_serial_wmbus_devices_.insert(device);
|
not_serial_wmbus_devices_.insert(device);
|
||||||
info("(main) ignoring %s, it does not respond as any of the supported wmbus devices.\n", device.c_str());
|
verbose("(main) ignoring %s, it does not respond as any of the supported wmbus devices.\n", device.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
open_wmbus_device(config, "auto scan detected", device, &detected);
|
open_wmbus_device(config, "during auto scan", device, &detected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -630,12 +656,12 @@ void perform_auto_scan_of_swradio_devices(Configuration *config)
|
||||||
{
|
{
|
||||||
// We cannot access this swradio device.
|
// We cannot access this swradio device.
|
||||||
not_swradio_wmbus_devices_.insert(device);
|
not_swradio_wmbus_devices_.insert(device);
|
||||||
info("(main) ignoring swradio %s since it is unavailable.\n", device.c_str());
|
verbose("(main) ignoring swradio %s since it is unavailable.\n", device.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
detected.device.file = device;
|
detected.device.file = device;
|
||||||
open_wmbus_device(config, "auto scan detected", device, &detected);
|
open_wmbus_device(config, "during auto scan", device, &detected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -659,7 +685,11 @@ void detectAndConfigureWMBusDevices(Configuration *config)
|
||||||
trace("(main) %s already configured\n", sd->device().c_str());
|
trace("(main) %s already configured\n", sd->device().c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (simulation_files_.count(device.file) > 0)
|
||||||
|
{
|
||||||
|
debug("(main) %s already configured as simulation\n", device.file.c_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (do_not_open_file_again_.count(device.file) == 0)
|
if (do_not_open_file_again_.count(device.file) == 0)
|
||||||
{
|
{
|
||||||
Detected detected = detectWMBusDeviceSetting(device.file,
|
Detected detected = detectWMBusDeviceSetting(device.file,
|
||||||
|
@ -674,7 +704,7 @@ void detectAndConfigureWMBusDevices(Configuration *config)
|
||||||
// Only read stdin and files once!
|
// Only read stdin and files once!
|
||||||
do_not_open_file_again_.insert(device.file);
|
do_not_open_file_again_.insert(device.file);
|
||||||
}
|
}
|
||||||
open_wmbus_device(config, "manual configuration", device.str(), &detected);
|
open_wmbus_device(config, "using manual setting", device.str(), &detected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -745,6 +775,7 @@ bool start(Configuration *config)
|
||||||
// If our software unexpectedly exits, then stop the manager, to try
|
// If our software unexpectedly exits, then stop the manager, to try
|
||||||
// to achive a nice shutdown.
|
// to achive a nice shutdown.
|
||||||
onExit(call(serial_manager_.get(),stop));
|
onExit(call(serial_manager_.get(),stop));
|
||||||
|
serial_manager_->eachEventLooping([]() { check_statuses(); });
|
||||||
|
|
||||||
// Create the printer object that knows how to translate
|
// Create the printer object that knows how to translate
|
||||||
// telegrams into json, fields that are written into log files
|
// telegrams into json, fields that are written into log files
|
||||||
|
@ -778,10 +809,14 @@ bool start(Configuration *config)
|
||||||
|
|
||||||
if (!config->use_auto_detect)
|
if (!config->use_auto_detect)
|
||||||
{
|
{
|
||||||
serial_manager_->expectDevicesToWork();
|
if (simulation_files_.size() == 0)
|
||||||
|
{
|
||||||
|
serial_manager_->expectDevicesToWork();
|
||||||
|
}
|
||||||
if (wmbus_devices_.size() == 0)
|
if (wmbus_devices_.size() == 0)
|
||||||
{
|
{
|
||||||
notice("(main) no wmbus device configured! Exiting.\n");
|
notice("No wmbus device configured! Exiting.\n");
|
||||||
|
checkIfMultipleWmbusmetersRunning();
|
||||||
serial_manager_->stop();
|
serial_manager_->stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -789,7 +824,8 @@ bool start(Configuration *config)
|
||||||
{
|
{
|
||||||
if (wmbus_devices_.size() == 0)
|
if (wmbus_devices_.size() == 0)
|
||||||
{
|
{
|
||||||
notice("(main) no wmbus device detected, waiting for a device to be plugged in.\n");
|
notice("No wmbus device detected, waiting for a device to be plugged in.\n");
|
||||||
|
checkIfMultipleWmbusmetersRunning();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -947,3 +983,29 @@ void startUsingConfigFiles(string root, bool is_daemon, string device_override,
|
||||||
}
|
}
|
||||||
while (restart);
|
while (restart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void checkIfMultipleWmbusmetersRunning()
|
||||||
|
{
|
||||||
|
pid_t my_pid = getpid();
|
||||||
|
vector<int> daemons;
|
||||||
|
detectProcesses("wmbusmetersd", &daemons);
|
||||||
|
for (int i : daemons)
|
||||||
|
{
|
||||||
|
if (i != my_pid)
|
||||||
|
{
|
||||||
|
info("Notice! Wmbusmeters daemon (pid %d) is running and it might hog any wmbus devices.\n", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vector<int> processes;
|
||||||
|
detectProcesses("wmbusmeters", &processes);
|
||||||
|
|
||||||
|
for (int i : processes)
|
||||||
|
{
|
||||||
|
if (i != my_pid)
|
||||||
|
{
|
||||||
|
info("Notice! Other wmbusmeters (pid %d) is running and it might hog any wmbus devices.\n", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -77,6 +77,8 @@ struct SerialCommunicationManagerImp : public SerialCommunicationManager
|
||||||
|
|
||||||
void listenTo(SerialDevice *sd, function<void()> cb);
|
void listenTo(SerialDevice *sd, function<void()> cb);
|
||||||
void onDisappear(SerialDevice *sd, function<void()> cb);
|
void onDisappear(SerialDevice *sd, function<void()> cb);
|
||||||
|
void eachEventLooping(function<void()> cb);
|
||||||
|
|
||||||
void expectDevicesToWork();
|
void expectDevicesToWork();
|
||||||
void stop();
|
void stop();
|
||||||
void startEventLoop();
|
void startEventLoop();
|
||||||
|
@ -121,17 +123,18 @@ private:
|
||||||
pthread_mutex_t devices_lock_ = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t devices_lock_ = PTHREAD_MUTEX_INITIALIZER;
|
||||||
vector<SerialDeviceImp*> devices_;
|
vector<SerialDeviceImp*> devices_;
|
||||||
vector<Timer> timers_;
|
vector<Timer> timers_;
|
||||||
pthread_mutex_t timers_lock_ = PTHREAD_MUTEX_INITIALIZER;
|
// pthread_mutex_t timers_lock_ = PTHREAD_MUTEX_INITIALIZER;
|
||||||
bool calling_timers_ {};
|
bool calling_timers_ {};
|
||||||
pthread_mutex_t timer_thread_lock_ = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t timer_thread_lock_ = PTHREAD_MUTEX_INITIALIZER; // Only have one regular callback thread running.
|
||||||
|
function<void()> on_event_looping_;
|
||||||
};
|
};
|
||||||
|
|
||||||
SerialCommunicationManagerImp::~SerialCommunicationManagerImp()
|
SerialCommunicationManagerImp::~SerialCommunicationManagerImp()
|
||||||
{
|
{
|
||||||
|
// Stop the loop.
|
||||||
|
stop();
|
||||||
// Close all managed devices (not yet closed)
|
// Close all managed devices (not yet closed)
|
||||||
closeAll();
|
closeAll();
|
||||||
// Stop the event loop.
|
|
||||||
stop();
|
|
||||||
// Grab the event_loop_lock. This can only be done when the eventLoop has stopped running.
|
// Grab the event_loop_lock. This can only be done when the eventLoop has stopped running.
|
||||||
LOCK("(serial)", "destructor", event_loop_lock_);
|
LOCK("(serial)", "destructor", event_loop_lock_);
|
||||||
// Now we can be sure the eventLoop has stopped and it is safe to
|
// Now we can be sure the eventLoop has stopped and it is safe to
|
||||||
|
@ -723,6 +726,11 @@ void SerialCommunicationManagerImp::onDisappear(SerialDevice *sd, function<void(
|
||||||
si->on_disappear_ = cb;
|
si->on_disappear_ = cb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SerialCommunicationManagerImp::eachEventLooping(function<void()> cb)
|
||||||
|
{
|
||||||
|
on_event_looping_ = cb;
|
||||||
|
}
|
||||||
|
|
||||||
void SerialCommunicationManagerImp::expectDevicesToWork()
|
void SerialCommunicationManagerImp::expectDevicesToWork()
|
||||||
{
|
{
|
||||||
debug("(serial) expecting devices to work\n");
|
debug("(serial) expecting devices to work\n");
|
||||||
|
@ -770,14 +778,15 @@ void SerialCommunicationManagerImp::waitForStop()
|
||||||
}
|
}
|
||||||
usleep(1000*1000);
|
usleep(1000*1000);
|
||||||
}
|
}
|
||||||
|
debug("(serial) closing %d devices\n", devices_.size());
|
||||||
|
closeAll();
|
||||||
|
|
||||||
if (signalsInstalled())
|
if (signalsInstalled())
|
||||||
{
|
{
|
||||||
if (select_thread_) pthread_kill(select_thread_, SIGUSR1);
|
if (select_thread_) pthread_kill(select_thread_, SIGUSR1);
|
||||||
}
|
}
|
||||||
pthread_join(select_thread_, NULL);
|
pthread_join(select_thread_, NULL);
|
||||||
|
|
||||||
debug("(serial) closing %d devices\n", devices_.size());
|
|
||||||
closeAll();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SerialCommunicationManagerImp::isRunning()
|
bool SerialCommunicationManagerImp::isRunning()
|
||||||
|
@ -848,19 +857,28 @@ void SerialCommunicationManagerImp::closeAll()
|
||||||
void SerialCommunicationManagerImp::executeTimerCallbacks()
|
void SerialCommunicationManagerImp::executeTimerCallbacks()
|
||||||
{
|
{
|
||||||
time_t curr = time(NULL);
|
time_t curr = time(NULL);
|
||||||
LOCK("(serial)", "executeTimerCallbacks", timers_lock_);
|
vector<Timer> to_be_called;
|
||||||
vector<Timer> timers_copy = timers_;
|
|
||||||
UNLOCK("(serial)", "executeTimerCallbacks", timers_lock_);
|
|
||||||
|
|
||||||
for (Timer &t : timers_copy)
|
LOCK("(serial)", "executeTimerCallbacks", devices_lock_);
|
||||||
|
|
||||||
|
for (Timer &t : timers_)
|
||||||
{
|
{
|
||||||
if (t.isTime(curr))
|
if (t.isTime(curr))
|
||||||
{
|
{
|
||||||
trace("[SERIAL] invoking callback %d %s\n", t.id, t.name.c_str());
|
trace("[SERIAL] timer isTime! %d %s\n", t.id, t.name.c_str());
|
||||||
t.last_call = curr;
|
t.last_call = curr;
|
||||||
t.callback();
|
to_be_called.push_back(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UNLOCK("(serial)", "executeTimerCallbacks", devices_lock_);
|
||||||
|
|
||||||
|
for (Timer &t : to_be_called)
|
||||||
|
{
|
||||||
|
trace("[SERIAL] invoking callback %s(%d)\n", t.name.c_str(), t.id);
|
||||||
|
t.callback();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
time_t SerialCommunicationManagerImp::calculateTimeToNearestTimerCallback(time_t now)
|
time_t SerialCommunicationManagerImp::calculateTimeToNearestTimerCallback(time_t now)
|
||||||
|
@ -1006,10 +1024,13 @@ void *SerialCommunicationManagerImp::eventLoop()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug("(serial) not starting timer thread since it is already running.\n");
|
trace("(serial) not starting timer thread since it is already running.\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Invoke callback every event looping....
|
||||||
|
if (on_event_looping_) on_event_looping_();
|
||||||
|
|
||||||
if (non_working.size() > 0 && expect_devices_to_work_ && resetting_ == false)
|
if (non_working.size() > 0 && expect_devices_to_work_ && resetting_ == false)
|
||||||
{
|
{
|
||||||
debug("(serial) non working devices found, exiting.\n");
|
debug("(serial) non working devices found, exiting.\n");
|
||||||
|
@ -1121,17 +1142,17 @@ SerialCommunicationManager::~SerialCommunicationManager()
|
||||||
int SerialCommunicationManagerImp::startRegularCallback(string name, int seconds, function<void()> callback)
|
int SerialCommunicationManagerImp::startRegularCallback(string name, int seconds, function<void()> callback)
|
||||||
{
|
{
|
||||||
Timer t = { (int)timers_.size(), seconds, time(NULL), callback, name };
|
Timer t = { (int)timers_.size(), seconds, time(NULL), callback, name };
|
||||||
LOCK("(serial)", "startRegularCallback", timers_lock_);
|
LOCK("(serial)", "startRegularCallback", devices_lock_);
|
||||||
timers_.push_back(t);
|
timers_.push_back(t);
|
||||||
UNLOCK("(serial)", "startRegularCallback", timers_lock_);
|
UNLOCK("(serial)", "startRegularCallback", devices_lock_);
|
||||||
debug("(serial) registered regular callback %d %s every %d seconds\n", t.id, name.c_str(), seconds);
|
debug("(serial) registered regular callback %s(%d) every %d seconds\n", name.c_str(), t.id, seconds);
|
||||||
return t.id;
|
return t.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SerialCommunicationManagerImp::stopRegularCallback(int id)
|
void SerialCommunicationManagerImp::stopRegularCallback(int id)
|
||||||
{
|
{
|
||||||
debug("(serial) stopping regular callback %d\n", id);
|
debug("(serial) stopping regular callback %d\n", id);
|
||||||
LOCK("(serial)", "stopRegularCallback", timers_lock_);
|
LOCK("(serial)", "stopRegularCallback", devices_lock_);
|
||||||
for (auto i = timers_.begin(); i != timers_.end(); ++i)
|
for (auto i = timers_.begin(); i != timers_.end(); ++i)
|
||||||
{
|
{
|
||||||
if ((*i).id == id)
|
if ((*i).id == id)
|
||||||
|
@ -1140,7 +1161,7 @@ void SerialCommunicationManagerImp::stopRegularCallback(int id)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UNLOCK("(serial)", "startRegularCallback", timers_lock_);
|
UNLOCK("(serial)", "stopRegularCallback", devices_lock_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,8 @@ struct SerialCommunicationManager
|
||||||
virtual void listenTo(SerialDevice *sd, function<void()> cb) = 0;
|
virtual void listenTo(SerialDevice *sd, function<void()> cb) = 0;
|
||||||
// Invoke cb callback when the serial device has disappeared!
|
// Invoke cb callback when the serial device has disappeared!
|
||||||
virtual void onDisappear(SerialDevice *sd, function<void()> cb) = 0;
|
virtual void onDisappear(SerialDevice *sd, function<void()> cb) = 0;
|
||||||
|
// Invoke once every select loop, typically once per second.
|
||||||
|
virtual void eachEventLooping(function<void()> cb) = 0;
|
||||||
// Normally the communication mananager runs for ever.
|
// Normally the communication mananager runs for ever.
|
||||||
// But if you expect configured devices to work, then
|
// But if you expect configured devices to work, then
|
||||||
// the manager will exit when there are no working devices.
|
// the manager will exit when there are no working devices.
|
||||||
|
|
19
src/shell.cc
19
src/shell.cc
|
@ -325,3 +325,22 @@ bool invokeShellCaptureOutput(string program, vector<string> args, vector<string
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void detectProcesses(string cmd, vector<int> *pids)
|
||||||
|
{
|
||||||
|
vector<string> args;
|
||||||
|
vector<string> envs;
|
||||||
|
args.push_back(cmd);
|
||||||
|
string out;
|
||||||
|
invokeShellCaptureOutput("/bin/pidof", args, envs, &out, true);
|
||||||
|
|
||||||
|
char buf[out.size()+1];
|
||||||
|
strcpy(buf, out.c_str());
|
||||||
|
char *pch;
|
||||||
|
pch = strtok (buf," \n");
|
||||||
|
while (pch != NULL)
|
||||||
|
{
|
||||||
|
pids->push_back(atoi(pch));
|
||||||
|
pch = strtok (NULL, " \n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -25,3 +25,4 @@ bool invokeShellCaptureOutput(string program, vector<string> args, vector<string
|
||||||
bool invokeBackgroundShell(string program, vector<string> args, vector<string> envs, int *out, int *pid);
|
bool invokeBackgroundShell(string program, vector<string> args, vector<string> envs, int *out, int *pid);
|
||||||
bool stillRunning(int pid);
|
bool stillRunning(int pid);
|
||||||
void stopBackgroundShell(int pid);
|
void stopBackgroundShell(int pid);
|
||||||
|
void detectProcesses(string cmd, vector<int> *pids);
|
||||||
|
|
|
@ -333,6 +333,7 @@ int test_linkmodes()
|
||||||
}
|
}
|
||||||
debug("test7 OK\n\n");
|
debug("test7 OK\n\n");
|
||||||
|
|
||||||
|
manager->stop();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,7 @@
|
||||||
// Default select timeout one second.
|
// Default select timeout one second.
|
||||||
#define SELECT_TIMEOUT 1
|
#define SELECT_TIMEOUT 1
|
||||||
|
|
||||||
// Default checkStatus callback frequency every 60 seconds, when an alarmtimeout has been set.
|
// Default checkStatus callback frequency every 2 seconds, when an alarmtimeout has been set.
|
||||||
#define CHECKSTATUS_TIMER 60
|
#define CHECKSTATUS_TIMER 2
|
||||||
// When running internal tests on timeouts use 2 seconds instead.
|
|
||||||
#define CHECKSTATUS_TIMER_INTERNAL_TESTING 2
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
79
src/wmbus.cc
79
src/wmbus.cc
|
@ -3262,7 +3262,6 @@ bool Telegram::findFormatBytesFromKnownMeterSignatures(vector<uchar> *format_byt
|
||||||
|
|
||||||
WMBusCommonImplementation::~WMBusCommonImplementation()
|
WMBusCommonImplementation::~WMBusCommonImplementation()
|
||||||
{
|
{
|
||||||
manager_->stopRegularCallback(regular_cb_id_);
|
|
||||||
debug("(wmbus) deleted %s\n", toString(type()));
|
debug("(wmbus) deleted %s\n", toString(type()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3277,12 +3276,14 @@ WMBusCommonImplementation::WMBusCommonImplementation(WMBusDeviceType t,
|
||||||
// Initialize timeout from now.
|
// Initialize timeout from now.
|
||||||
last_received_ = time(NULL);
|
last_received_ = time(NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
// Invoke the check status once per minute. Unless internal testing, then it is every 2 seconds.
|
// Invoke the check status once per minute. Unless internal testing, then it is every 2 seconds.
|
||||||
int default_timer = isInternalTestingEnabled() ? CHECKSTATUS_TIMER_INTERNAL_TESTING : CHECKSTATUS_TIMER;
|
int default_timer = CHECKSTATUS_TIMER;
|
||||||
string info = "simulator";
|
string info = "simulator";
|
||||||
if (serial != NULL) info = serial_->device();
|
if (serial != NULL) info = serial_->device();
|
||||||
string alarm_id = "CHECK_STATUS "+string(toString(t))+":"+info;
|
string alarm_id = "CHECK_STATUS "+string(toString(t))+":"+info;
|
||||||
regular_cb_id_ = manager_->startRegularCallback(alarm_id, default_timer, call(this,checkStatus));
|
regular_cb_id_ = manager_->startRegularCallback(alarm_id, default_timer, call(this,checkStatus));
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
WMBusDeviceType WMBusCommonImplementation::type()
|
WMBusDeviceType WMBusCommonImplementation::type()
|
||||||
|
@ -3394,6 +3395,7 @@ bool WMBusCommonImplementation::isWorking()
|
||||||
|
|
||||||
void WMBusCommonImplementation::checkStatus()
|
void WMBusCommonImplementation::checkStatus()
|
||||||
{
|
{
|
||||||
|
trace("[ALARM] check status\n");
|
||||||
if (protocol_error_count_ >= 20)
|
if (protocol_error_count_ >= 20)
|
||||||
{
|
{
|
||||||
string msg;
|
string msg;
|
||||||
|
@ -3416,58 +3418,73 @@ void WMBusCommonImplementation::checkStatus()
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
time_t then = now - timeout_;
|
time_t then = now - timeout_;
|
||||||
time_t since = now-last_received_;
|
time_t since = now-last_received_;
|
||||||
if (timeout_ > 0 && since < timeout_)
|
|
||||||
|
// If no timeout set, just return.
|
||||||
|
if (timeout_ == 0) return;
|
||||||
|
|
||||||
|
if (since < timeout_)
|
||||||
{
|
{
|
||||||
trace("[WMBUS] No timeout. All ok. (%d s) Now %d seconds since last telegram was received.\n", since);
|
trace("[WMBUS] No timeout since=%d timeout=%d. All ok.\n", since, timeout_);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
last_received_ = time(NULL);
|
||||||
|
|
||||||
// The timeout has expired! But is the timeout expected because there should be no activity now?
|
// The timeout has expired! But is the timeout expected because there should be no activity now?
|
||||||
// Also, do not sound the alarm unless we actually have a possible timeout within the expected activity,
|
// Also, do not sound the alarm unless we actually have a possible timeout within the expected activity,
|
||||||
// otherwise we will always get an alarm when we enter the expected activity period.
|
// otherwise we will always get an alarm when we enter the expected activity period.
|
||||||
if (isInsideTimePeriod(now, expected_activity_) &&
|
if (!(isInsideTimePeriod(now, expected_activity_) &&
|
||||||
isInsideTimePeriod(then, expected_activity_))
|
isInsideTimePeriod(then, expected_activity_)))
|
||||||
{
|
{
|
||||||
|
trace("[WMBUS] hit timeout(%d s) but this is ok, since there is no expected activity.\n", timeout_);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
time_t nowt = time(NULL);
|
// Ok, timeout has triggered for real! Deal with it!
|
||||||
struct tm nowtm;
|
struct tm nowtm;
|
||||||
localtime_r(&nowt, &nowtm);
|
localtime_r(&now, &nowtm);
|
||||||
|
|
||||||
string now = strdatetime(&nowtm);
|
string nowtxt = strdatetime(&nowtm);
|
||||||
|
|
||||||
string msg;
|
string msg;
|
||||||
strprintf(msg, "%d seconds of inactivity resetting %s %s "
|
strprintf(msg, "%d seconds of inactivity resetting %s %s "
|
||||||
"(timeout %ds expected %s now %s)",
|
"(timeout %ds expected %s now %s)",
|
||||||
since, device().c_str(), toString(type()),
|
since, device().c_str(), toString(type()),
|
||||||
timeout_, expected_activity_.c_str(), now.c_str());
|
timeout_, expected_activity_.c_str(), nowtxt.c_str());
|
||||||
|
|
||||||
logAlarm("inactivity", msg);
|
logAlarm("inactivity", msg);
|
||||||
|
|
||||||
bool ok = reset();
|
bool ok = reset();
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
warning("(wmbus) successfully reset wmbus device\n");
|
warning("(wmbus) successfully reset wmbus device\n");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
strprintf(msg, "failed to reset wmbus device %s %s exiting wmbusmeters", device().c_str(), toString(type()));
|
|
||||||
logAlarm("device_failure", msg);
|
|
||||||
manager_->stop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
debug("(wmbus) Hit timeout(%d s) but no expected activity!\n", timeout_);
|
strprintf(msg, "failed to reset wmbus device %s %s exiting wmbusmeters", device().c_str(), toString(type()));
|
||||||
|
logAlarm("device_failure", msg);
|
||||||
|
manager_->stop();
|
||||||
}
|
}
|
||||||
// Fake last received to restart the timeout.
|
|
||||||
last_received_ = time(NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WMBusCommonImplementation::setTimeout(int seconds, string expected_activity)
|
void WMBusCommonImplementation::setTimeout(int seconds, string expected_activity)
|
||||||
{
|
{
|
||||||
|
assert(seconds >= 0);
|
||||||
|
|
||||||
timeout_ = seconds;
|
timeout_ = seconds;
|
||||||
|
if (expected_activity == "")
|
||||||
|
{
|
||||||
|
expected_activity = "mon-sun(00-23)";
|
||||||
|
}
|
||||||
expected_activity_ = expected_activity;
|
expected_activity_ = expected_activity;
|
||||||
debug("(wmbus) set timeout %s to \"%d\" with expected activity \"%s\"\n", toString(type_), timeout_, expected_activity_.c_str());
|
if (seconds > 0)
|
||||||
|
{
|
||||||
|
debug("(wmbus) set timeout %s to \"%d\" with expected activity \"%s\"\n", toString(type_), timeout_, expected_activity_.c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug("(wmbus) no alarm (expected activity) for %s\n", toString(type_));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int toInt(TPLSecurityMode tsm)
|
int toInt(TPLSecurityMode tsm)
|
||||||
|
|
|
@ -61,7 +61,9 @@ struct WMBusIM871A : public virtual WMBusCommonImplementation
|
||||||
void simulate() { }
|
void simulate() { }
|
||||||
|
|
||||||
WMBusIM871A(unique_ptr<SerialDevice> serial, SerialCommunicationManager *manager);
|
WMBusIM871A(unique_ptr<SerialDevice> serial, SerialCommunicationManager *manager);
|
||||||
~WMBusIM871A() { }
|
~WMBusIM871A() {
|
||||||
|
manager_->onDisappear(this->serial(), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,11 @@ struct WMBusRTLWMBUS : public virtual WMBusCommonImplementation
|
||||||
void simulate();
|
void simulate();
|
||||||
|
|
||||||
WMBusRTLWMBUS(unique_ptr<SerialDevice> serial, SerialCommunicationManager *manager);
|
WMBusRTLWMBUS(unique_ptr<SerialDevice> serial, SerialCommunicationManager *manager);
|
||||||
|
~WMBusRTLWMBUS()
|
||||||
|
{
|
||||||
|
manager_->listenTo(this->serial(), NULL);
|
||||||
|
manager_->onDisappear(this->serial(), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -177,7 +177,11 @@ void WMBusSimulator::simulate()
|
||||||
curr = time(NULL);
|
curr = time(NULL);
|
||||||
if (curr > start_time + rel_time) break;
|
if (curr > start_time + rel_time) break;
|
||||||
usleep(1000*1000);
|
usleep(1000*1000);
|
||||||
if (!manager_->isRunning()) break;
|
if (!manager_->isRunning())
|
||||||
|
{
|
||||||
|
debug("(simulator) exiting early\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,8 +70,6 @@ struct WMBusCommonImplementation : public virtual WMBus
|
||||||
bool link_modes_configured_ {};
|
bool link_modes_configured_ {};
|
||||||
LinkModeSet link_modes_ {};
|
LinkModeSet link_modes_ {};
|
||||||
|
|
||||||
int regular_cb_id_;
|
|
||||||
|
|
||||||
unique_ptr<SerialDevice> serial_;
|
unique_ptr<SerialDevice> serial_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
11
test.sh
11
test.sh
|
@ -78,11 +78,10 @@ if [ "$?" != "0" ]; then RC="1"; fi
|
||||||
tests/test_serial_bads.sh $PROG
|
tests/test_serial_bads.sh $PROG
|
||||||
if [ "$?" != "0" ]; then RC="1"; fi
|
if [ "$?" != "0" ]; then RC="1"; fi
|
||||||
|
|
||||||
#if [ "$(uname)" = "Linux" ]
|
if [ "$(uname)" = "Linux" ]
|
||||||
#then
|
then
|
||||||
# tests/test_alarm.sh $PROG
|
tests/test_alarm.sh $PROG
|
||||||
# if [ "$?" != "0" ]; then RC="1"; fi
|
if [ "$?" != "0" ]; then RC="1"; fi
|
||||||
|
fi
|
||||||
#fi
|
|
||||||
|
|
||||||
exit $RC
|
exit $RC
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
loglevel=debug
|
loglevel=normal
|
||||||
# Set internaltesting=true to shorten times for test to finish in reasonable time.
|
# Set internaltesting=true to shorten times for test to finish in reasonable time.
|
||||||
internaltesting=true
|
internaltesting=true
|
||||||
device=must_be_overriden
|
device=must_be_overriden
|
||||||
|
@ -9,7 +9,7 @@ shell=echo METER =="$METER_JSON"== >> /tmp/wmbusmeters_telegram_test
|
||||||
# The alarm will always be logged in the log file.
|
# The alarm will always be logged in the log file.
|
||||||
alarmshell=echo ALARM_SHELL "$ALARM_TYPE" "$ALARM_MESSAGE" >> /tmp/wmbusmeters_alarm_test
|
alarmshell=echo ALARM_SHELL "$ALARM_TYPE" "$ALARM_MESSAGE" >> /tmp/wmbusmeters_alarm_test
|
||||||
# Expect a received telegram no longer than 1 second since the last telegram!
|
# Expect a received telegram no longer than 1 second since the last telegram!
|
||||||
alarmtimeout=1s
|
alarmtimeout=4s
|
||||||
# Only sound the alarm if the timeout is reached when the radio is actually
|
# Only sound the alarm if the timeout is reached when the radio is actually
|
||||||
# expected to be transmitting. Some meters disable transmissions during nights
|
# expected to be transmitting. Some meters disable transmissions during nights
|
||||||
# and weekends. Change this to mon-fri(08-19)
|
# and weekends. Change this to mon-fri(08-19)
|
||||||
|
|
|
@ -12,10 +12,10 @@ echo "RUNNING $TESTNAME ..."
|
||||||
> /tmp/wmbusmeters_telegram_test
|
> /tmp/wmbusmeters_telegram_test
|
||||||
> /tmp/wmbusmeters_alarm_test
|
> /tmp/wmbusmeters_alarm_test
|
||||||
|
|
||||||
$PROG --useconfig=tests/config7 --device=simulations/simulation_alarm.txt | sed 's/....-..-.. ..:../1111-11-11 11:11/' > $TEST/test_output.txt
|
$PROG --useconfig=tests/config7 --device=simulations/simulation_alarm.txt 2> $TEST/test_stderr.txt | sed 's/....-..-..T..:..:..Z/1111-11-11T11:11:11Z/' > $TEST/test_output.txt
|
||||||
|
|
||||||
cat > $TEST/test_expected.txt <<EOF
|
cat > $TEST/test_expected.txt <<EOF
|
||||||
(alarm) inactivity: 2 seconds of inactivity resetting simulations/simulation_alarm.txt DEVICE_SIMULATOR (timeout 1s expected mon-sun(00-23) now 1111-11-11 11:11)
|
(alarm) inactivity: 4 seconds of inactivity resetting simulations/simulation_alarm.txt DEVICE_SIMULATOR (timeout 4s expected mon-sun(00-23) now 1111-11-11 11:11)
|
||||||
(wmbus) successfully reset wmbus device
|
(wmbus) successfully reset wmbus device
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
@ -25,16 +25,18 @@ METER =={"media":"cold water","meter":"multical21","name":"Water","id":"76348799
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat > /tmp/wmbusmeters_alarm_expected <<EOF
|
cat > /tmp/wmbusmeters_alarm_expected <<EOF
|
||||||
ALARM_SHELL inactivity 2 seconds of inactivity resetting simulations/simulation_alarm.txt DEVICE_SIMULATOR (timeout 1s expected mon-sun(00-23) now 1111-11-11 11:11)
|
ALARM_SHELL inactivity 4 seconds of inactivity resetting simulations/simulation_alarm.txt DEVICE_SIMULATOR (timeout 4s expected mon-sun(00-23) now 1111-11-11 11:11)
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
REST=$(diff $TEST/test_output.txt $TEST/test_expected.txt)
|
cat $TEST/test_stderr.txt | sed 's/now ....-..-.. ..:../now 1111-11-11 11:11/' > $TEST/test_responses.txt
|
||||||
|
|
||||||
|
REST=$(diff $TEST/test_responses.txt $TEST/test_expected.txt)
|
||||||
|
|
||||||
if [ ! -z "$REST" ]
|
if [ ! -z "$REST" ]
|
||||||
then
|
then
|
||||||
echo ERROR STDOUT: $TESTNAME
|
echo ERROR STDERR: $TESTNAME
|
||||||
echo -----------------
|
echo -----------------
|
||||||
diff $TEST/test_output.txt $TEST/test_expected.txt
|
diff $TEST/test_responses.txt $TEST/test_expected.txt
|
||||||
echo -----------------
|
echo -----------------
|
||||||
TESTRESULT="ERROR"
|
TESTRESULT="ERROR"
|
||||||
fi
|
fi
|
||||||
|
|
Ładowanie…
Reference in New Issue