From 0698906cd14672417ed119978ee89138c267f316 Mon Sep 17 00:00:00 2001 From: John Date: Sat, 23 Sep 2023 14:09:27 +0200 Subject: [PATCH] allow limiting number of scan retries (fixes 1013) --- src/ebusd/main.cpp | 13 ++++++++++++- src/ebusd/main.h | 1 + src/ebusd/mainloop.cpp | 13 ++++++++++--- src/ebusd/mainloop.h | 3 +++ 4 files changed, 26 insertions(+), 4 deletions(-) diff --git a/src/ebusd/main.cpp b/src/ebusd/main.cpp index e3f336e28..79deee4d8 100644 --- a/src/ebusd/main.cpp +++ b/src/ebusd/main.cpp @@ -92,6 +92,7 @@ static struct options s_opt = { false, // scanConfig 0, // initialScan + 5, // scanRetries getenv("LANG"), // preferLanguage false, // checkConfig OF_NONE, // dumpConfig @@ -165,7 +166,8 @@ static const char argpdoc[] = #define O_INISND -2 #define O_DEVLAT (O_INISND-1) -#define O_CFGLNG (O_DEVLAT-1) +#define O_SCNRET (O_DEVLAT-1) +#define O_CFGLNG (O_SCNRET-1) #define O_CHKCFG (O_CFGLNG-1) #define O_DMPCFG (O_CHKCFG-1) #define O_DMPCTO (O_DMPCFG-1) @@ -223,6 +225,7 @@ static const struct argp_option argpoptions[] = { "\"off\" for not picking CSV files by scan result (default when configpath is given).\n" "If combined with --checkconfig, you can add scan message data as " "arguments for checking a particular scan configuration, e.g. \"FF08070400/0AB5454850303003277201\".", 0 }, + {"scanretries", O_SCNRET, "COUNT", 0, "Retry scanning devices COUNT times [5]", 0 }, {"configlang", O_CFGLNG, "LANG", 0, "Prefer LANG in multilingual configuration files [system default language]", 0 }, {"checkconfig", O_CHKCFG, nullptr, 0, "Check config files, then stop", 0 }, @@ -361,6 +364,14 @@ error_t parse_opt(int key, char *arg, struct argp_state *state) { s_scanConfigOrPathSet = true; break; } + case O_SCNRET: // --scanretries=10 + value = parseInt(arg, 10, 0, 100, &result); + if (result != RESULT_OK) { + argp_error(state, "invalid scanretries"); + return EINVAL; + } + opt->scanRetries = value; + break; case O_CFGLNG: // --configlang=LANG opt->preferLanguage = arg; break; diff --git a/src/ebusd/main.h b/src/ebusd/main.h index 98b421d27..a085d0e35 100644 --- a/src/ebusd/main.h +++ b/src/ebusd/main.h @@ -49,6 +49,7 @@ typedef struct options { * else: single slave address. */ symbol_t initialScan; + int scanRetries; //!< number of retries for scanning devices [10] const char* preferLanguage; //!< preferred language in configuration files bool checkConfig; //!< check config files, then stop OutputFormat dumpConfig; //!< dump config files, then stop diff --git a/src/ebusd/mainloop.cpp b/src/ebusd/mainloop.cpp index 3d90cc4aa..c457431ee 100644 --- a/src/ebusd/mainloop.cpp +++ b/src/ebusd/mainloop.cpp @@ -109,8 +109,8 @@ MainLoop::MainLoop(const struct options& opt, Device *device, MessageMap* messag Queue* requestQueue) : Thread(), m_device(device), m_reconnectCount(0), m_userList(opt.accessLevel), m_messages(messages), m_scanHelper(scanHelper), m_address(opt.address), m_scanConfig(opt.scanConfig), - m_initialScan(opt.readOnly ? ESC : opt.initialScan), m_scanStatus(SCAN_STATUS_NONE), - m_polling(opt.pollInterval > 0), m_enableHex(opt.enableHex), + m_initialScan(opt.readOnly ? ESC : opt.initialScan), m_scanRetries(opt.scanRetries), + m_scanStatus(SCAN_STATUS_NONE), m_polling(opt.pollInterval > 0), m_enableHex(opt.enableHex), m_shutdown(false), m_runUpdateCheck(opt.updateCheck), m_httpClient(), m_requestQueue(requestQueue) { m_device->setListener(this); // open Device @@ -228,6 +228,7 @@ void MainLoop::run() { symbol_t lastScanAddress = 0; // 0 is known to be a master scanStatus_t lastScanStatus = m_scanStatus; int scanCompleted = 0; + int scanRetry = 0; time(&now); start = now; lastTaskRun = now; @@ -261,7 +262,7 @@ void MainLoop::run() { m_busHandler->reconnect(); m_reconnectCount++; } - if (m_scanConfig) { + if (m_scanConfig && scanRetry <= m_scanRetries) { bool loadDelay = false; if (m_initialScan != ESC && reload && m_busHandler->hasSignal()) { loadDelay = true; @@ -312,6 +313,8 @@ void MainLoop::run() { scanCompleted++; if (scanCompleted > SCAN_REPEAT_COUNT) { // repeat failed scan only every Nth time scanCompleted = 0; + scanRetry++; + logNotice(lf_main, "scan completed %d time(s), %s", scanRetry, scanRetry <= m_scanRetries ? "check again" : "end"); } } else { m_scanStatus = SCAN_STATUS_RUNNING; @@ -424,7 +427,11 @@ void MainLoop::run() { bool connected = true; if (!req->empty()) { req->log(); + bool currentReload = reload; result_t result = decodeRequest(req, &connected, &reqMode, &user, &reload, &ostream); + if (reload && !currentReload) { + scanRetry = 0; // restart scan counting + } if (!req->isHttp() && (ostream.tellp() == 0 || result != RESULT_OK)) { if (reqMode.listenMode != lm_direct) { ostream.str(""); diff --git a/src/ebusd/mainloop.h b/src/ebusd/mainloop.h index ae099db57..d5efc5a00 100644 --- a/src/ebusd/mainloop.h +++ b/src/ebusd/mainloop.h @@ -416,6 +416,9 @@ class MainLoop : public Thread, DeviceListener { * (@a ESC=none, 0xfe=broadcast ident, @a SYN=full scan, else: single slave address). */ const symbol_t m_initialScan; + /** number of retries for scanning a device. */ + const int m_scanRetries; + /** the current scan status. */ scanStatus_t m_scanStatus;