added commandline option "--dumpconfig" for dumping resulting message definitions to stdout, added options for limiting to PB and dumping message definitions in "find" command, nicer "help" command output

This commit is contained in:
john30
2015-02-21 16:22:27 +01:00
parent e484bf57b9
commit 79a5f09c78
3 changed files with 126 additions and 92 deletions
+25 -16
View File
@@ -65,7 +65,7 @@ static struct options opt = {
"/dev/ttyUSB0", // device "/dev/ttyUSB0", // device
false, // noDeviceCheck false, // noDeviceCheck
CONFIG_PATH, // configPath CONFIG_PATH, // configPath
false, // checkConfig 0, // checkConfig
5, // pollInterval 5, // pollInterval
0xFF, // address 0xFF, // address
false, // answer false, // answer
@@ -98,19 +98,20 @@ static const char argpdoc[] =
"A daemon for access to eBUS devices."; "A daemon for access to eBUS devices.";
#define O_CHKCFG 1 #define O_CHKCFG 1
#define O_POLINT 2 #define O_DMPCFG 2
#define O_ANSWER 3 #define O_POLINT 3
#define O_ACQTIM 4 #define O_ANSWER 4
#define O_ACQRET 5 #define O_ACQTIM 5
#define O_SNDRET 6 #define O_ACQRET 6
#define O_RCVTIM 7 #define O_SNDRET 7
#define O_MASCNT 8 #define O_RCVTIM 8
#define O_LOCAL 9 #define O_MASCNT 9
#define O_LOGARE 10 #define O_LOCAL 10
#define O_LOGLEV 11 #define O_LOGARE 11
#define O_LOGRAW 12 #define O_LOGLEV 12
#define O_DMPFIL 13 #define O_LOGRAW 13
#define O_DMPSIZ 14 #define O_DMPFIL 14
#define O_DMPSIZ 15
/** the definition of the known program arguments. */ /** the definition of the known program arguments. */
static const struct argp_option argpoptions[] = { static const struct argp_option argpoptions[] = {
@@ -120,7 +121,8 @@ static const struct argp_option argpoptions[] = {
{NULL, 0, NULL, 0, "Message configuration options:", 2 }, {NULL, 0, NULL, 0, "Message configuration options:", 2 },
{"configpath", 'c', "PATH", 0, "Read CSV config files from PATH [" CONFIG_PATH "]", 0 }, {"configpath", 'c', "PATH", 0, "Read CSV config files from PATH [" CONFIG_PATH "]", 0 },
{"checkconfig", O_CHKCFG, NULL, 0, "Only check CSV config files, then stop", 0 }, {"checkconfig", O_CHKCFG, NULL, 0, "Check CSV config files, then stop", 0 },
{"dumpconfig", O_DMPCFG, NULL, 0, "Check and dump CSV config files, then stop", 0 },
{"pollinterval", O_POLINT, "SEC", 0, "Poll for data every SEC seconds (0=disable) [5]", 0 }, {"pollinterval", O_POLINT, "SEC", 0, "Poll for data every SEC seconds (0=disable) [5]", 0 },
{NULL, 0, NULL, 0, "eBUS options:", 3 }, {NULL, 0, NULL, 0, "eBUS options:", 3 },
@@ -184,7 +186,10 @@ error_t parse_opt(int key, char *arg, struct argp_state *state)
opt->configPath = arg; opt->configPath = arg;
break; break;
case O_CHKCFG: // --checkconfig case O_CHKCFG: // --checkconfig
opt->checkConfig = true; opt->checkConfig = 1;
break;
case O_DMPCFG: // --dumpconfig
opt->checkConfig = 2;
break; break;
case O_POLINT: // --pollinterval=5 case O_POLINT: // --pollinterval=5
opt->pollInterval = parseInt(arg, 10, 0, 3600, result); opt->pollInterval = parseInt(arg, 10, 0, 3600, result);
@@ -527,6 +532,10 @@ int main(int argc, char* argv[])
loadConfigFiles(&templates, &messages, true); loadConfigFiles(&templates, &messages, true);
if (opt.checkConfig > 1) {
logNotice(lf_main, "Configuration dump:");
messages.dump(cout);
}
messages.clear(); messages.clear();
templates.clear(); templates.clear();
+1 -1
View File
@@ -33,7 +33,7 @@ struct options
bool noDeviceCheck; //!< skip serial eBUS device test bool noDeviceCheck; //!< skip serial eBUS device test
const char* configPath; //!< path to CSV configuration files [/etc/ebusd] const char* configPath; //!< path to CSV configuration files [/etc/ebusd]
bool checkConfig; //!< only check CSV config files, then stop int checkConfig; //!< check CSV config files (!=0) and optionally dump (2), then stop
int pollInterval; //!< poll interval in seconds, 0 to disable [5] int pollInterval; //!< poll interval in seconds, 0 to disable [5]
unsigned char address; //!< own bus address [FF] unsigned char address; //!< own bus address [FF]
+77 -52
View File
@@ -229,7 +229,7 @@ string MainLoop::executeRead(vector<string> &args)
argPos++; argPos++;
} }
if (argPos == 0 || args.size() < argPos + 1 || args.size() > argPos + 2) if (argPos == 0 || args.size() < argPos + 1 || args.size() > argPos + 2)
return "usage: 'read [-v] [-f] [-m SECONDS] [-c CLASS] NAME [FIELD]'\n" return "usage: read [-v] [-f] [-m SECONDS] [-c CLASS] NAME [FIELD]\n"
" Read value(s).\n" " Read value(s).\n"
" -v be verbose (include field names, units, and comments)\n" " -v be verbose (include field names, units, and comments)\n"
" -f force reading from the bus (same as '-m 0')\n" " -f force reading from the bus (same as '-m 0')\n"
@@ -346,16 +346,16 @@ string MainLoop::executeWrite(vector<string> &args)
argPos++; argPos++;
} }
if (argPos == 0 || args.size() != argPos + 3) if (argPos == 0 || args.size() != argPos + 3)
return "usage: 'write [-c] CLASS NAME VALUE[;VALUE]*'\n" return "usage: write [-c] CLASS NAME VALUE[;VALUE]*\n"
" or: 'write -h ZZPBSBNNDx' or 'write -h ZZ PB SB NN Dx'\n" " or: write -h ZZPBSBNNDx\n"
" Write value(s).\n" " Write value(s) or hex message.\n"
" CLASS the CLASS of the message to send\n" " CLASS the CLASS of the message to send\n"
" NAME the NAME of the message to send\n" " NAME the NAME of the message to send\n"
" VALUE a single field VALUE\n" " VALUE a single field VALUE\n"
" -h directly write hex message:\n" " -h directly write hex message:\n"
" ZZ destination address\n" " ZZ destination address\n"
" PB SB primary/secondary command byte\n" " PB SB primary/secondary command byte\n"
" NN number of data bytes to send\n" " NN number of following data bytes\n"
" Dx the data byte(s) to send"; " Dx the data byte(s) to send";
Message* message = m_messages->find(args[argPos], args[argPos + 1], true); Message* message = m_messages->find(args[argPos], args[argPos + 1], true);
@@ -395,11 +395,14 @@ string MainLoop::executeWrite(vector<string> &args)
string MainLoop::executeFind(vector<string> &args) string MainLoop::executeFind(vector<string> &args)
{ {
size_t argPos = 1; size_t argPos = 1;
bool verbose = false, withRead = true, withWrite = false, withPassive = true, first = true, onlyWithData = false; bool verbose = false, configFormat = false, withRead = true, withWrite = false, withPassive = true, first = true, onlyWithData = false;
string clazz; string clazz;
int pb = -1;
while (args.size() > argPos && args[argPos][0] == '-') { while (args.size() > argPos && args[argPos][0] == '-') {
if (args[argPos] == "-v") if (args[argPos] == "-v")
verbose = true; verbose = true;
else if (args[argPos] == "-f")
configFormat = true;
else if (args[argPos] == "-r") { else if (args[argPos] == "-r") {
if (first) { if (first) {
first = false; first = false;
@@ -421,8 +424,23 @@ string MainLoop::executeFind(vector<string> &args)
} }
withPassive = true; withPassive = true;
} }
else if (args[argPos] == "-d") { else if (args[argPos] == "-d")
onlyWithData = true; onlyWithData = true;
else if (args[argPos] == "-i") {
argPos++;
if (argPos >= args.size()) {
argPos = 0; // print usage
break;
}
const char* str = args[argPos].c_str();
result_t result = RESULT_OK;
if (strncasecmp(str, "0x", 2) == 0)
pb = parseInt(str+2, 16, 0, 0xff, result); // hexadecimal
else
pb = parseInt(str, 10, 0, 0xff, result); // decimal
if (result != RESULT_OK) {
return getResultCode(result);
}
} }
else if (args[argPos] == "-c") { else if (args[argPos] == "-c") {
argPos++; argPos++;
@@ -439,33 +457,40 @@ string MainLoop::executeFind(vector<string> &args)
argPos++; argPos++;
} }
if (argPos == 0 || args.size() < argPos || args.size() > argPos + 1) if (argPos == 0 || args.size() < argPos || args.size() > argPos + 1)
return "usage: 'find [-v] [-r] [-w] [-p] [-d] [-c CLASS] [NAME]'\n" return "usage: find [-v] [-r] [-w] [-p] [-d] [-i PB] [-f] [-c CLASS] [NAME]\n"
" Find value(s).\n" " Find message(s).\n"
" -v be verbose (append destination address and update time)\n" " -v be verbose (append destination address and update time)\n"
" -r limit to active read messages (default read + passive)\n" " -r limit to active read messages (default: read + passive)\n"
" -w limit to active write messages (default read + passive)\n" " -w limit to active write messages (default: read + passive)\n"
" -p limit to passive messages (default read + passive)\n" " -p limit to passive messages (default: read + passive)\n"
" -d only retrieve messages with actual data" " -d only include messages with actual data\n"
" -i PB limit to messages with primary command byte PB ('0xPB' for hex)\n"
" -f list messages in CSV configuration file format\n"
" -c CLASS limit to messages of CLASS\n" " -c CLASS limit to messages of CLASS\n"
" NAME the NAME of the message to find or a part thereof"; " NAME the NAME of the message to find or a part thereof";
deque<Message*> messages; deque<Message*> messages;
if (args.size() == argPos) if (args.size() == argPos)
messages = m_messages->findAll(clazz, "", -1, false, withRead, withWrite, withPassive); messages = m_messages->findAll(clazz, "", pb, false, withRead, withWrite, withPassive);
else else
messages = m_messages->findAll(clazz, args[argPos], -1, false, withRead, withWrite, withPassive); messages = m_messages->findAll(clazz, args[argPos], pb, false, withRead, withWrite, withPassive);
bool found = false; bool found = false;
ostringstream result; ostringstream result;
char str[31]; char str[31];
for (deque<Message*>::iterator it = messages.begin(); it < messages.end();) { for (deque<Message*>::iterator it = messages.begin(); it < messages.end();) {
Message* message = *it++; Message* message = *it++;
unsigned char dstAddress = message->getDstAddress();
if (dstAddress == SYN)
continue;
time_t lastup = message->getLastUpdateTime(); time_t lastup = message->getLastUpdateTime();
if (onlyWithData && lastup == 0) if (onlyWithData && lastup == 0)
continue; continue;
if (configFormat) {
if (found)
result << endl;
message->dump(result);
} else {
unsigned char dstAddress = message->getDstAddress();
if (dstAddress == SYN)
continue;
if (found) if (found)
result << endl; result << endl;
result << message->getClass() << " " << message->getName() << " = "; result << message->getClass() << " " << message->getName() << " = ";
@@ -493,6 +518,7 @@ string MainLoop::executeFind(vector<string> &args)
else else
result << " read]"; result << " read]";
} }
}
found = true; found = true;
} }
if (!found) if (!found)
@@ -512,8 +538,8 @@ string MainLoop::executeListen(vector<string> &args, bool& listening)
} }
if (args.size() != 2 || args[1] != "stop") if (args.size() != 2 || args[1] != "stop")
return "usage: 'listen [stop]'\n" return "usage: listen [stop]\n"
" Listen for updates (or stop it)."; " Listen for updates or stop it.";
listening = false; listening = false;
return "listen stopped"; return "listen stopped";
@@ -522,7 +548,7 @@ string MainLoop::executeListen(vector<string> &args, bool& listening)
string MainLoop::executeState(vector<string> &args) string MainLoop::executeState(vector<string> &args)
{ {
if (args.size() == 0) if (args.size() == 0)
return "usage: 'state'\n" return "usage: state\n"
" Report bus state."; " Report bus state.";
if (m_busHandler->hasSignal()) { if (m_busHandler->hasSignal()) {
@@ -559,9 +585,8 @@ string MainLoop::executeScan(vector<string> &args)
return result.str(); return result.str();
} }
return "usage: 'scan'\n" return "usage: scan [full]\n"
" or: 'scan full'\n" " or: scan result\n"
" or: 'scan result'\n"
" Scan seen or all slaves, or report scan result."; " Scan seen or all slaves, or report scan result.";
} }
@@ -573,8 +598,8 @@ string MainLoop::executeLog(vector<string> &args)
else if (args.size() == 3 && strcasecmp(args[1].c_str(), "LEVEL") == 0) else if (args.size() == 3 && strcasecmp(args[1].c_str(), "LEVEL") == 0)
result = setLogLevel(args[2].c_str()); result = setLogLevel(args[2].c_str());
else else
return "usage: 'log areas AREA[,AREA]*'\n" return "usage: log areas AREA[,AREA]*\n"
" or: 'log level LEVEL'\n" " or: log level LEVEL\n"
" Set log area(s) or log level.\n" " Set log area(s) or log level.\n"
" AREA the log area to include (main|network|bus|update|all)\n" " AREA the log area to include (main|network|bus|update|all)\n"
" LEVEL the log level to set (error|notice|info|debug)"; " LEVEL the log level to set (error|notice|info|debug)";
@@ -588,8 +613,8 @@ string MainLoop::executeLog(vector<string> &args)
string MainLoop::executeRaw(vector<string> &args) string MainLoop::executeRaw(vector<string> &args)
{ {
if (args.size() != 1) if (args.size() != 1)
return "usage: 'raw'\n" return "usage: raw\n"
" Toggle log raw data."; " Toggle logging raw bytes.";
bool enabled = !m_device->getLogRaw(); bool enabled = !m_device->getLogRaw();
m_device->setLogRaw(enabled); m_device->setLogRaw(enabled);
@@ -600,8 +625,8 @@ string MainLoop::executeRaw(vector<string> &args)
string MainLoop::executeDump(vector<string> &args) string MainLoop::executeDump(vector<string> &args)
{ {
if (args.size() != 1) if (args.size() != 1)
return "usage: 'dump'\n" return "usage: dump\n"
" Toggle raw dump."; " Toggle dumping raw bytes.";
bool enabled = !m_device->getDumpRaw(); bool enabled = !m_device->getDumpRaw();
m_device->setDumpRaw(enabled); m_device->setDumpRaw(enabled);
@@ -612,10 +637,9 @@ string MainLoop::executeDump(vector<string> &args)
string MainLoop::executeReload(vector<string> &args) string MainLoop::executeReload(vector<string> &args)
{ {
if (args.size() != 1) if (args.size() != 1)
return "usage: 'reload'\n" return "usage: reload\n"
" Reload config files."; " Reload CSV config files.";
// reload commands
result_t result = loadConfigFiles(m_templates, m_messages); result_t result = loadConfigFiles(m_templates, m_messages);
return getResultCode(result); return getResultCode(result);
@@ -628,7 +652,7 @@ string MainLoop::executeStop(vector<string> &args, bool& running)
return "daemon stopped"; return "daemon stopped";
} }
return "usage: 'stop'\n" return "usage: stop\n"
" Stop the daemon."; " Stop the daemon.";
} }
@@ -639,30 +663,31 @@ string MainLoop::executeQuit(vector<string> &args, bool& connected)
return "connection closed"; return "connection closed";
} }
return "usage: 'quit'\n" return "usage: quit\n"
" Close client connection."; " Close client connection.";
} }
string MainLoop::executeHelp() string MainLoop::executeHelp()
{ {
return "usage:\n" return "usage:\n"
" read Read value(s) 'read [-v] [-f] [-m SECONDS] [-c CLASS] NAME [FIELD]'\n" " read|r Read value(s): read [-v] [-f] [-m SECONDS] [-c CLASS] NAME [FIELD]\n"
" write Write value(s) 'write [-c] CLASS NAME VALUE[;VALUE]*' or 'write -h ZZPBSBNNDx'\n" " write|w Write value(s): write [-c] CLASS NAME VALUE[;VALUE]*\n"
" find Find value(s) 'find [-v] [-r] [-w] [-p] [-d] [-c CLASS] [NAME]'\n" " Write hex message: write -h ZZPBSBNNDx'\n"
" listen Listen for updates 'listen [stop]'\n" " find|f Find message(s): find [-v] [-r] [-w] [-p] [-d] [-i PB] [-f] [-c CLASS] [NAME]\n"
" state Report bus state 'state'\n" " listen|l Listen for updates: listen [stop]\n"
" scan Scan seen slaves 'scan'\n" " state|s Report bus state\n"
" Scan all slaves 'scan full'\n" " scan Scan slaves: scan [full]\n"
" Report scan result 'scan result'\n" " Report scan result: scan result\n"
" log Set log area(s) 'log areas AREA[,AREA*]' (AREA: main|network|bus|update|all)\n" " log Set log area(s): log areas AREA[,AREA*]\n"
" Set log level 'log level LEVEL' (LEVEL: error|notice|info|debug)\n" " AREA: main|network|bus|update|all\n"
" raw Toggle log raw data 'raw'\n" " Set log level: log level LEVEL\n"
" dump Toggle raw dump 'dump'\n" " LEVEL: error|notice|info|debug\n"
" reload Reload config files 'reload'\n" " raw Toggle logging raw bytes\n"
" stop Stop the daemon 'stop'\n" " dump Toggle dumping raw bytes\n"
" quit Close connection 'quit'\n" " reload Reload CSV config files\n"
" help Print this help page 'help'\n" " stop Stop the daemon\n"
" Print command usage 'help COMMAND'"; " quit|q Close connection\n"
" help|h Print help help [COMMAND]";
} }
string MainLoop::getUpdates(time_t since, time_t until) string MainLoop::getUpdates(time_t since, time_t until)