From b9e80ad5d81547d3bbd719f3b15284cad8825776 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 3 Jun 2020 18:49:31 +0200 Subject: [PATCH 1/8] merged with michael's changes - https://github.com/proddy/EMS-ESP/pull/393 --- src/boiler.cpp | 2 +- src/emsesp.cpp | 1 - src/emsesp.h | 1 - src/sensors.h | 2 +- src/thermostat.cpp | 17 ++++++++--------- src/version.h | 2 +- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/boiler.cpp b/src/boiler.cpp index 6b11f8b28..d6edcb6c8 100644 --- a/src/boiler.cpp +++ b/src/boiler.cpp @@ -344,7 +344,7 @@ void Boiler::show_values(uuid::console::Shell & shell) { } print_value(shell, 2, F("Warm Water activated"), Helpers::render_value(buffer, wWActivated_, EMS_VALUE_BOOL)); - print_value(shell, 2, F("Warm Water charging type"), wWCircPumpType_ ? "3-way valve" : "charge pump"); + print_value(shell, 2, F("Warm Water charging type"), wWCircPumpType_ ? "3-way valve" : "charge pump"); print_value(shell, 2, F("Warm Water circulation pump available"), Helpers::render_value(buffer, wWCircPump_, EMS_VALUE_BOOL)); if (wWCircPumpMode_ == 7) { print_value(shell, 2, F("Warm Water circulation pump freq"), "continuous"); diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 61791328e..1a081d49c 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -819,7 +819,6 @@ void EMSESP::loop() { shower_.loop(); // check for shower on/off sensors_.loop(); // this will also send out via MQTT console_.loop(); // telnet/serial console - delay(ESP_DELAY); // some time to WiFi and everything else to catch up, calls yield, and also prevent overheating // force a query on the EMS devices to fetch latest data at a set interval (1 min) if ((uuid::get_uptime() - last_fetch_ > EMS_FETCH_FREQUENCY)) { diff --git a/src/emsesp.h b/src/emsesp.h index b93a5803a..1f5a55861 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -46,7 +46,6 @@ #include "shower.h" #define LOG_TRACE_WATCH_NONE 0 // no watch set -#define ESP_DELAY 1 namespace emsesp { diff --git a/src/sensors.h b/src/sensors.h index f4bf76d91..c8dedf664 100644 --- a/src/sensors.h +++ b/src/sensors.h @@ -69,7 +69,7 @@ class Sensors { #ifdef WEMOS_D1_32 static constexpr uint8_t SENSOR_GPIO = 18; // Wemos D1-32 for compatibility D5 #else - static constexpr uint8_t SENSOR_GPIO = 14; + static constexpr uint8_t SENSOR_GPIO = 14; // D5 is LED on wemos lolin D32, so use GPIO14 #endif #endif diff --git a/src/thermostat.cpp b/src/thermostat.cpp index 1fafff48b..edb177398 100644 --- a/src/thermostat.cpp +++ b/src/thermostat.cpp @@ -1456,15 +1456,14 @@ void Thermostat::console_commands(Shell & shell, unsigned int context) { EMSESPShell::commands->add_command(ShellContext::THERMOSTAT, CommandFlags::ADMIN, flash_string_vector{F_(change), F_(temp)}, - flash_string_vector{F_(degrees_mandatory), F_(hc_optional),F_(mode_optional)}, + flash_string_vector{F_(degrees_mandatory), F_(hc_optional), F_(mode_optional)}, [=](Shell & shell __attribute__((unused)), const std::vector & arguments) { - uint8_t hc = (arguments.size() >= 2) ? arguments[1].at(0) - '0' : DEFAULT_HEATING_CIRCUIT; - if ((arguments.size() == 3)) { - set_temperature(atof(arguments.front().c_str()), arguments.back().c_str(), hc); - } else { - set_temperature(atof(arguments.front().c_str()), HeatingCircuit::Mode::AUTO, hc); - } - + uint8_t hc = (arguments.size() >= 2) ? arguments[1].at(0) - '0' : DEFAULT_HEATING_CIRCUIT; + if ((arguments.size() == 3)) { + set_temperature(atof(arguments.front().c_str()), arguments.back().c_str(), hc); + } else { + set_temperature(atof(arguments.front().c_str()), HeatingCircuit::Mode::AUTO, hc); + } }); EMSESPShell::commands->add_command( @@ -1473,7 +1472,7 @@ void Thermostat::console_commands(Shell & shell, unsigned int context) { flash_string_vector{F_(change), F_(mode)}, flash_string_vector{F_(mode_mandatory), F_(hc_optional)}, [=](Shell & shell __attribute__((unused)), const std::vector & arguments) { - uint8_t hc = (arguments.size() == 2) ? arguments[1].at(0) - '0' : DEFAULT_HEATING_CIRCUIT; + uint8_t hc = (arguments.size() == 2) ? arguments[1].at(0) - '0' : DEFAULT_HEATING_CIRCUIT; set_mode(arguments.front(), hc); }, [](Shell & shell __attribute__((unused)), const std::vector & arguments __attribute__((unused))) -> const std::vector { diff --git a/src/version.h b/src/version.h index efc44d9a0..c9d3820dd 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define EMSESP_APP_VERSION "2.0.0a12" +#define EMSESP_APP_VERSION "2.0.0a13" From 0d787d56f8f558af390a42b2ca25336cf56eec0a Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 3 Jun 2020 23:32:03 +0200 Subject: [PATCH 2/8] added poll ack after we get a poll request in Tx --- src/telegram.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/telegram.cpp b/src/telegram.cpp index 07026b4b8..66420ea93 100644 --- a/src/telegram.cpp +++ b/src/telegram.cpp @@ -388,10 +388,9 @@ void TxService::send() { return; } - // if there's nothing in the queue to send - // optionally, send back a poll and quit + // if there's nothing in the queue to transmit, send back a poll and quit if (tx_telegrams_.empty()) { - // send_poll(); // TODO commented out poll for now. should add back when stable. + send_poll(); return; } @@ -409,7 +408,7 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) { // build the header auto telegram = tx_telegram.telegram_; - // src - set MSB if its Junkers/HT3 + // src - set MSB if it's Junkers/HT3 uint8_t src = telegram->src; if (ems_mask() != EMS_MASK_UNSET) { src ^= ems_mask(); @@ -484,7 +483,10 @@ void TxService::send_telegram(const QueuedTxTelegram & tx_telegram) { // send the telegram to the UART Tx EMSUART_STATUS status = EMSuart::transmit(telegram_raw, length); - //LOG_TRACE(F("Tx: %s"), Helpers::data_to_hex(telegram_raw, length).c_str()); +#ifdef EMSESP_DEBUG + LOG_TRACE(F("Tx: %s"), Helpers::data_to_hex(telegram_raw, length).c_str()); +#endif + if (status != EMS_TX_STATUS_OK) { LOG_ERROR(F("Failed to transmit Tx via UART. Error: %s"), status == EMS_TX_WTD_TIMEOUT ? F("Timeout") : F("BRK")); } From ca39f7fd6f00d0b7ddbccccf3eb5a4e0efa0a7b4 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 3 Jun 2020 23:32:23 +0200 Subject: [PATCH 3/8] added another TODO to use Templates for the read_value functions --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 79ac9a0cc..6556d4c0f 100644 --- a/README.md +++ b/README.md @@ -140,6 +140,7 @@ TODO validate 0xE9 with data from Koen. (https://github.com/proddy/EMS-ESP/issue ``` TODO replace vectors of class objects with shared pointers and use emplace_back since it instantiates during construction. It may have a performance gain. TODO make more use of comparison operators in the Telegram class e.g. the compare like "friend inline bool operator==(const Telegram & lhs, const Telegram & rhs)" +TODO replace read_value with C++ Templates per data type TODO exit from serial should be prevented? Because you never can really exit, just close it. TODO add real unit tests using platformio's test bed (https://docs.platformio.org/en/latest/plus/pio-remote.html) TODO See if it's easier to use timers instead of millis() timers, using https://github.com/esp8266/Arduino/blob/master/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino From a5e60d9e39dc4527c88d6fc55c6eed362a3d5e8e Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 3 Jun 2020 23:32:47 +0200 Subject: [PATCH 4/8] remove yield. we have too many yields, they're everywhere! --- src/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 223a8e54a..8e0208cbb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -24,5 +24,4 @@ void setup() { void loop() { emsesp::EMSESP::loop(); - yield(); } From a6549bc66d9872de4c0c1a4b28dd294948fc3d98 Mon Sep 17 00:00:00 2001 From: proddy Date: Wed, 3 Jun 2020 23:33:23 +0200 Subject: [PATCH 5/8] improve Tx retry code --- src/emsesp.cpp | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 1a081d49c..b1aa2ad0e 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -568,21 +568,21 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) { } // are we waiting for a response from a recent Tx Read or Write? + bool tx_successful = false; if (EMSbus::tx_waiting()) { - // if it's a single byte 1 or 4 then its maybe a response from the last write action EMSbus::tx_waiting(false); // reset Tx wait state + + // if it's a single byte 1 or 4 then its maybe a response from the last write action if (length == 1) { if (first_value == TxService::TX_WRITE_SUCCESS) { LOG_DEBUG(F("Last Tx write successful. Sending read request.")); txservice_.increment_telegram_write_count(); // last tx/write was confirmed ok txservice_.send_poll(); // close the bus - txservice_.post_send_query(); // send type_id to last destination + txservice_.post_send_query(); // follow up with any post-read + tx_successful = true; } else if (first_value == TxService::TX_WRITE_FAIL) { LOG_ERROR(F("Last Tx write rejected by host")); txservice_.send_poll(); // close the bus - } else { - // ignore it, it's probably a poll and we can wait for the next one - return; } } else { // got a telegram with data in it. See if the src/dest matches that from the last one we sent @@ -592,18 +592,24 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) { if (txservice_.is_last_tx(src, dest)) { LOG_DEBUG(F("Last Tx read successful")); txservice_.increment_telegram_read_count(); - txservice_.send_poll(); - } else { - // the telegram we got wasn't what we had requested - // So re-send the last Tx and increment retry count - uint8_t retries = txservice_.retry_tx(); // returns 0 if exceeded count - if (retries) { - LOG_ERROR(F("Last Tx read failed. Retrying #%d..."), retries); - } else { - LOG_ERROR(F("Last Tx read failed after %d retries"), txservice_.MAXIMUM_TX_RETRIES); - } + txservice_.send_poll(); // close the bus + tx_successful = true; } } + + // if Tx wasn't successful, retry + if (!tx_successful) { + // the telegram we got wasn't what we had requested + // So re-send the last Tx and increment retry count + uint8_t retries = txservice_.retry_tx(); // returns 0 if exceeded count + if (retries) { + LOG_ERROR(F("Last Tx read failed. Retrying #%d..."), retries); + } else { + LOG_ERROR(F("Last Tx read failed after %d retries. Abandoning Tx operation."), txservice_.MAXIMUM_TX_RETRIES); + } + + return; + } } // check for poll @@ -826,7 +832,7 @@ void EMSESP::loop() { fetch_device_values(); } - // helps ease wifi outages + // helps ease wifi dropouts effecting MQTT and Telnet services // https://github.com/esp8266/Arduino/blob/e721089e601985e633641ab7323f81a84ea0cd1b/cores/esp8266/core_esp8266_wiring.cpp#L41-L57 delay(1); } From 5fdb3d63962f59be0da6c389133c2c210fc12c9b Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 4 Jun 2020 11:04:27 +0200 Subject: [PATCH 6/8] add setup instructions --- README.md | 44 +++++++++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 6556d4c0f..597888a0c 100644 --- a/README.md +++ b/README.md @@ -21,19 +21,39 @@ Note: Version 2.0 is not backward compatible with v1.0. The File system structur - A web interface built using React and TypeScript to be secure and cross-browser compatible. Each restful endpoint is protected and issues a JWT which is then sent using Bearer Authentication. Implements a Web captive portal. On first installs EMS-ESP starts an Access Point where system settings can be configured. Note, this is still in a separate repo and pending a merge into this project. -- A new console. Like 1.9.x it works with both Serial and Telnet but a lot more intuitive behaving like a Linux shell and secure. Multiple telnet sessions are supported now but watch out for slow connections and low memory. A password is need to change any settings. You can use TAB to auto-complete commands, ctrl-L, ctrl-U and the other typical console type shortcuts. Some key commands: +- A new console. Like in version 1.9 it works with both Serial and Telnet but a lot more intuitive, behaving similar to a Linux-style shell. It supports multiple connections and any commands that effect the behavior of EMS-ESP are secure behind an admin password. You can use TAB to auto-complete commands, ctrl-L, ctrl-U and the other typical console type shortcuts. ctrl-D to exit the current menu. Some other important commands: * `help` lists the commands and keywords - * some commands take you into a new context, a bit like a sub-menu. e.g. `system`, `mqtt`, `thermostat`. Use `help` to show which commands this context has and `exit` to get back to the root. + * some commands take you into a new context, a bit like a sub-menu. e.g. `system`, `mqtt`, `thermostat`. Use `help` to show which commands this context has and `exit` or CTRL-D to get back to the root. * To change a setting use the `set` command. Typing `set` shows the current settings. * `show` shows the data specific to the context you're in. * `su` to switch to Admin which enables more commands such as most of the `set` commands. The default password is "neo" which can be changed with `passwd` from the system menu. When in Admin mode the command prompt switches from `$` to `#`. - * `log` sets the logging. `log off` disables logging. Use `log trace` to see the telegram traffic and `log debug` for very verbose logging. To watch a specific telegram ID or device ID use `log trace [id]`. + * `log` sets the logging. `log off` disables logging. Use `log trace` to see the telegram traffic and `log debug` for very verbose logging. To watch a specific telegram ID or device ID use `log trace [full|raw| [id]`. -- There is no "serial mode" anymore like with version 1.9. When the Wifi cannot connect to the SSID it will automatically enter a "safe" mode where the Serial console is activated, baud 115200. Note Serial is always available on the ESP32 because it has 2 UARTs. +- There is no "serial mode" anymore like with version 1.9. When the Wifi cannot connect to the SSID it will automatically enter a "safe" mode where the Serial console is activated, baud 115200. Note Serial is always available on the ESP32 because it has multiple UARTs. - LED behaves like in 1.9. A solid LED means good connection and EMS data is coming in. A slow pulse means either the WiFi or the EMS bus is not connected. A very fast pulse is when the system is booting up and configuring itself. -- on a new install you will want to enter `su` and then go to the `system` context. Use `set wifi ...` to set the network up. Then go to the `mqtt` context to set the mqtt up. +### Setting up for the first time: + + - connect the ESP8266/ESP32 via USB and enter via the serial/com port with baud 115200 + - type `su` and use the default password *neo* + - type `system` to go to the system sub-menu (which we call a context) + - type `set` to see the current settings + - use `set wifi` to change the SSID and password. Remember TAB auto-completes the command + - CTRL-D to get back to the root + - use `mqtt` to enter the MQTT menu. Same approach using the `set` command to set the MQTT IP and any credentials. CTRL-D to get back to the root. + - use `ems` to change to the EMS BUS tx mode if you find Tx is not working. + - reboot and next time use the Telnet via WiFi to connect as the serial mode will be disabled. + +### Debugging + - Turn on logging with either `log all` or `log trace` or `log debug` + - Error messages are shown in the color red + - type `show` from the main root to see if any data has come in + - if not, go to the `ems` context and type `show` which will display some EMS bus stats + - use the `refresh` command to fetch new data from the EMS bus + - use `scan devices` or `scan devices deep` to locate devices on the EMS bus. If any are unknown please report back to the project so we can update our EMS device library. + + # Full Console Commands @@ -44,7 +64,7 @@ common commands available in all contexts: log [level] [full|raw] [trace ID] su -(top level) +(top root level) refresh show show version @@ -124,17 +144,10 @@ thermostat ### **Known issues, bugs and improvements currently working on** ``` -TODO ESP32 - when saving SPIFFS the UART stop and restart() functions need to flush queue to avoid miss fires -TODO sometimes with tx_mode 0 there are a few CRC errors due to collision when waiting for a BRK signal. +TODO Optimized ESP8266 and ESP32 UART code (via Michael) TODO console auto-complete with 'set' command in the system context is not showing all commands, only the hostname. ``` -### **Features to add next** - -``` -TODO validate 0xE9 with data from Koen. (https://github.com/proddy/EMS-ESP/issues/382) -``` - ### **To tidy up in code later** ``` @@ -143,7 +156,7 @@ TODO make more use of comparison operators in the Telegram class e.g. the compar TODO replace read_value with C++ Templates per data type TODO exit from serial should be prevented? Because you never can really exit, just close it. TODO add real unit tests using platformio's test bed (https://docs.platformio.org/en/latest/plus/pio-remote.html) -TODO See if it's easier to use timers instead of millis() timers, using https://github.com/esp8266/Arduino/blob/master/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino +TODO See if it's easier to use timers instead of millis() based timers, using https://github.com/esp8266/Arduino/blob/master/libraries/esp8266/examples/BlinkPolledTimeout/BlinkPolledTimeout.ino ``` ### **These features to add next** @@ -152,5 +165,6 @@ TODO See if it's easier to use timers instead of millis() timers, using https:// TODO merge in the web code which has the Captive AP and better wifi reconnect logic. Use IPV6 and NTP from lwip2 TODO decide if I want to port over the shower one-shot cold water logic. Don't think its used. TODO when doing show in telnet, should we sort the ems devices? +TODO validate 0xE9 with data from Koen. (https://github.com/proddy/EMS-ESP/issues/382) ``` From ffff17fce1e7b2df8e6ebc13f9762a6fffe12a72 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 4 Jun 2020 11:04:51 +0200 Subject: [PATCH 7/8] minor text changes --- src/mqtt.cpp | 2 +- src/system.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mqtt.cpp b/src/mqtt.cpp index e14acc1b8..5954bb79b 100644 --- a/src/mqtt.cpp +++ b/src/mqtt.cpp @@ -369,7 +369,7 @@ void Mqtt::show_topic_handlers(uuid::console::Shell & shell, const uint8_t devic return; } - shell.print(F(" These MQTT topics are registered: ")); + shell.print(F(" Subscribed MQTT topics: ")); for (const auto & mqtt_function : mqtt_functions_) { if (mqtt_function.device_id_ == device_id) { shell.printf(F("%s "), mqtt_function.topic_.c_str()); diff --git a/src/system.cpp b/src/system.cpp index d9dc6e478..b577584e2 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -144,7 +144,7 @@ void System::start() { // register MQTT system commands Mqtt::subscribe("cmd", std::bind(&System::mqtt_commands, this, _1)); -// RTC state variables - onky for ESP8266 +// RTC state variables - only for ESP8266 #if defined(ESP8266) state_.registerVar(&reset_counter_); // we send a pointer to each of our variables state_.registerVar(&safe_mode_); From c619701137ab6051b762cb3bb37d53222e19cde6 Mon Sep 17 00:00:00 2001 From: proddy Date: Thu, 4 Jun 2020 11:05:03 +0200 Subject: [PATCH 8/8] show tx fails in ems sub-menu --- src/emsesp.cpp | 22 +++++++++++----------- src/telegram.cpp | 9 ++++++--- src/telegram.h | 9 +++++++++ 3 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/emsesp.cpp b/src/emsesp.cpp index b1aa2ad0e..fd8da4e07 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -110,22 +110,22 @@ void EMSESP::trace_watch_id(uint16_t trace_watch_id) { } } -// show the Rx and Tx queues +// show the EMS bus status plus both Rx and Tx queues void EMSESP::show_emsbus(uuid::console::Shell & shell) { - // EMS bus specific + // EMS bus information if (rxservice_.bus_connected()) { uint8_t success_rate = 0; if (rxservice_.telegram_error_count()) { success_rate = ((float)rxservice_.telegram_error_count() / (float)rxservice_.telegram_count()) * 100; } - shell.printfln(F("EMS Bus protocol: %s, #telegrams received: %d, #Read requests sent: %d, #Write requests sent: %d, #CRC errors: %d (%d%%)"), - EMSbus::is_ht3() ? F("HT3") : F("Buderus"), - rxservice_.telegram_count(), - txservice_.telegram_read_count(), - txservice_.telegram_write_count(), - rxservice_.telegram_error_count(), - success_rate); + shell.printfln(F("EMS Bus info:")); + shell.printfln(F(" Bus protocol: %s"), EMSbus::is_ht3() ? F("HT3") : F("Buderus")); + shell.printfln(F(" #telegrams received: %d"), rxservice_.telegram_count()); + shell.printfln(F(" #read requests sent: %d"), txservice_.telegram_read_count()); + shell.printfln(F(" #write requests sent: %d"), txservice_.telegram_write_count()); + shell.printfln(F(" #CRC errors: %d (%d%%)"), rxservice_.telegram_error_count(), success_rate); + shell.printfln(F(" #Tx fails: %d"), txservice_.telegram_fail_count()); } else { shell.printfln(F("EMS Bus is disconnected")); } @@ -603,9 +603,9 @@ void EMSESP::incoming_telegram(uint8_t * data, const uint8_t length) { // So re-send the last Tx and increment retry count uint8_t retries = txservice_.retry_tx(); // returns 0 if exceeded count if (retries) { - LOG_ERROR(F("Last Tx read failed. Retrying #%d..."), retries); + LOG_ERROR(F("Last Tx operation failed. Retrying #%d..."), retries); } else { - LOG_ERROR(F("Last Tx read failed after %d retries. Abandoning Tx operation."), txservice_.MAXIMUM_TX_RETRIES); + LOG_ERROR(F("Last Tx operation failed after %d retries. Ignoring request."), txservice_.MAXIMUM_TX_RETRIES); } return; diff --git a/src/telegram.cpp b/src/telegram.cpp index 66420ea93..3187a64cd 100644 --- a/src/telegram.cpp +++ b/src/telegram.cpp @@ -611,10 +611,13 @@ void TxService::remember_tx(const uint8_t * data, const uint8_t length) { // returns retry count, or 0 if all done uint8_t TxService::retry_tx() { if (++retry_count_ == MAXIMUM_TX_RETRIES) { - reset_retry_count(); // give up - } else { - add(telegram_last_, telegram_last_length_); // add the last Tx telegram to the tx queue, at the top + reset_retry_count(); // give up + increment_telegram_fail_count(); // another Tx fail + return 0; } + + add(telegram_last_, telegram_last_length_); // add the last Tx telegram to the tx queue, at the top + return retry_count_; } diff --git a/src/telegram.h b/src/telegram.h index ef6129b21..4c8608d82 100644 --- a/src/telegram.h +++ b/src/telegram.h @@ -270,6 +270,14 @@ class TxService : public EMSbus { telegram_read_count_++; } + uint16_t telegram_fail_count() const { + return telegram_fail_count_; + } + + void increment_telegram_fail_count() { + telegram_fail_count_++; + } + uint16_t telegram_write_count() const { return telegram_write_count_; } @@ -312,6 +320,7 @@ class TxService : public EMSbus { const std::shared_ptr telegram_last; // copy of last telegram uint16_t telegram_read_count_ = 0; // # Tx successful reads uint16_t telegram_write_count_ = 0; // # Tx successful writes + uint16_t telegram_fail_count_ = 0; // # Tx unsuccessful transmits uint8_t retry_count_ = 0; // count for # Tx retries