diff --git a/lib/uuid-console/src/shell.cpp b/lib/uuid-console/src/shell.cpp index 94b27887d..8005913c1 100644 --- a/lib/uuid-console/src/shell.cpp +++ b/lib/uuid-console/src/shell.cpp @@ -85,11 +85,7 @@ void Shell::stop() { blocking_data->stop_ = true; } else { -#if defined(EMSESP_STANDALONE) if (running()) { -#else - if (running() && !has_flags(CommandFlags::LOCAL)) { // do not close local shell -#endif stopped_ = true; stopped(); } diff --git a/src/emsesp.cpp b/src/emsesp.cpp index 05d15d67f..d8945d69e 100644 --- a/src/emsesp.cpp +++ b/src/emsesp.cpp @@ -1341,7 +1341,7 @@ bool EMSESP::add_device(const uint8_t device_id, const uint8_t product_id, const fetch_device_values(device_id); // go and fetch its device entity data // Print to LOG showing we've added a new device - LOG_INFO("Dectected EMS device: %s (0x%02X)", EMSdevice::device_type_2_device_name(device_type), device_id); + LOG_INFO("Detected EMS device: %s (0x%02X)", EMSdevice::device_type_2_device_name(device_type), device_id); // register the MQTT subscribe topic for this device // except for connect, controller and gateway @@ -1542,20 +1542,12 @@ void EMSESP::start() { system_.PSram(ESP.getPsramSize()); #endif -// don't need shell if running unit tests -#ifndef EMSESP_UNITY - // Serial console's shell serial_console_.begin(SERIAL_CONSOLE_BAUD_RATE); - shell_ = std::make_shared(*this, serial_console_, true); - shell_->maximum_log_messages(100); - shell_->start(); -#if defined(EMSESP_DEBUG) - shell_->log_level(uuid::log::Level::DEBUG); -#else - shell_->log_level(uuid::log::Level::TRACE); -#endif + +// always start a serial console if we're running standalone, except if we're running unit tests #if defined(EMSESP_STANDALONE) - shell_->add_flags(CommandFlags::ADMIN); // always start in su/admin mode when running tests +#ifndef EMSESP_UNITY + start_serial_console(); #endif #endif @@ -1580,9 +1572,11 @@ void EMSESP::start() { bool factory_settings = false; #endif - webLogService.begin(); // start web log service. now we can start capturing logs to the web log + // start web log service. now we can start capturing logs to the web log + webLogService.begin(); - esp8266React.begin(); // loads core system services settings (network, mqtt, ap, ntp etc) + // loads core system services settings (network, mqtt, ap, ntp etc) + esp8266React.begin(); #ifndef EMSESP_STANDALONE LOG_INFO("Booting EMS-ESP version %s from %s partition", EMSESP_APP_VERSION, esp_ota_get_running_partition()->label); // welcome message @@ -1654,11 +1648,11 @@ void EMSESP::start() { // main loop calling all services void EMSESP::loop() { - esp8266React.loop(); // web services - system_.loop(); // does LED and checks system health, and syslog service - static bool upload_status = true; // ready for any OTA uploads + esp8266React.loop(); // web services + system_.loop(); // does LED and checks system health, and syslog service // if we're doing an OTA upload, skip everything except from console refresh + static bool upload_status = true; // ready for any OTA uploads if (!system_.upload_isrunning()) { // service loops webLogService.loop(); // log in Web UI @@ -1689,13 +1683,54 @@ void EMSESP::loop() { if (system_.telnet_enabled()) { telnet_.loop(); } -#else - if (!shell_->running()) { - ::exit(0); - } #endif Shell::loop_all(); + + static bool show_prompt = true; + + // user has to ctrl-c to create a serial console stream, exit command will close it + // this is to save around 2kb of heap memory + if (shell_) { + if (!shell_->running()) { + shell_.reset(); +#ifdef EMSESP_STANDALONE + ::exit(0); // kill session +#endif + shell_prompt(); + } + } else { + if (show_prompt) { + shell_prompt(); + show_prompt = false; // only show it once + } + int c = serial_console_.read(); + if (c != -1) { + show_prompt = true; + } + if (c == '\x03' || c == '\x0C') { + start_serial_console(); + } + } +} + +void EMSESP::start_serial_console() { + shell_ = std::make_shared(*this, serial_console_, true); + shell_->maximum_log_messages(100); + shell_->add_flags(CommandFlags::ADMIN); // always start in su/admin mode when running tests + shell_->start(); +#if defined(EMSESP_DEBUG) + shell_->log_level(uuid::log::Level::DEBUG); +#else + shell_->log_level(uuid::log::Level::TRACE); +#endif +} + +void EMSESP::shell_prompt() { +#ifndef EMSESP_STANDALONE + serial_console_.println(); + serial_console_.println("Press ^C to activate this serial console"); +#endif } } // namespace emsesp diff --git a/src/emsesp.h b/src/emsesp.h index 8afc2b4b8..9f1ba1efd 100644 --- a/src/emsesp.h +++ b/src/emsesp.h @@ -252,6 +252,9 @@ class EMSESP { static void publish_response(std::shared_ptr telegram); static void publish_all_loop(); + void shell_prompt(); + void start_serial_console(); + static constexpr uint32_t EMS_FETCH_FREQUENCY = 60000; // check every minute static constexpr uint8_t EMS_WAIT_KM_TIMEOUT = 60; // wait one minute