From 3e4f7fdc17e08859ce8be96bb3c21cdb6b66fc54 Mon Sep 17 00:00:00 2001 From: Proddy Date: Thu, 12 Jan 2023 17:38:50 +0100 Subject: [PATCH] error handling in tests --- src/console.cpp | 12 ---- src/test/test.cpp | 138 +++++++++++++++++++++++++++++----------------- src/test/test.h | 9 +-- 3 files changed, 90 insertions(+), 69 deletions(-) diff --git a/src/console.cpp b/src/console.cpp index 964ee2cbf..a809562b0 100644 --- a/src/console.cpp +++ b/src/console.cpp @@ -154,18 +154,6 @@ static void setup_commands(std::shared_ptr & commands) { Test::run_test(shell, arguments[0].c_str(), arguments[1].c_str()); } }); - - commands->add_command(ShellContext::MAIN, - CommandFlags::USER, - string_vector{F_(debug)}, - string_vector{F_(name_optional)}, - [](Shell & shell, const std::vector & arguments) { - if (arguments.empty()) { - Test::debug(shell, "default"); - } else { - Test::debug(shell, arguments.front()); - } - }); #endif commands->add_command(ShellContext::MAIN, CommandFlags::USER, string_vector{F_(su)}, [=](Shell & shell, const std::vector & arguments) { diff --git a/src/test/test.cpp b/src/test/test.cpp index f64fec0fb..ede3941a7 100644 --- a/src/test/test.cpp +++ b/src/test/test.cpp @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -#if defined(EMSESP_DEBUG) +#if defined(EMSESP_DEBUG) || defined(EMSESP_STANDALONE) #include "test.h" @@ -242,16 +242,14 @@ bool Test::run_test(const char * command, int8_t id) { return false; } -// These next tests are run from the Console, so inherit the Shell -// using the test command +// These next tests are run from the Consol via the test command, so inherit the Shell void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const std::string & data) { - // switch to su - shell.add_flags(CommandFlags::ADMIN); + shell.add_flags(CommandFlags::ADMIN); // switch to su // init stuff Mqtt::ha_enabled(true); EMSESP::rxservice_.ems_mask(EMSbus::EMS_MASK_BUDERUS); - EMSESP::watch(EMSESP::Watch::WATCH_RAW); // raw + EMSESP::watch(EMSESP::Watch::WATCH_RAW); // raw mode std::string command(20, '\0'); if ((cmd.empty()) || (cmd == "default")) { @@ -260,6 +258,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const command = cmd; } + bool ok = false; + if (command == "general") { shell.printfln("Testing adding a general boiler & thermostat..."); run_test("general"); @@ -267,6 +267,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("show values"); shell.invoke_command("call system publish"); shell.invoke_command("show mqtt"); + ok = true; } // https://github.com/emsesp/EMS-ESP32/issues/869 @@ -274,12 +275,23 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.printfln("Testing memory by adding lots of devices and entities..."); run_test("memory"); shell.invoke_command("show values"); + ok = true; } -// -// the tests take a lot of memory when built for the ESP32 -// so only including the full set in standalone, otherwise a limited selection of basic tests -// +// THESE ONLY WORK WITH AN ESP32, not in standalone mode +#ifndef EMSESP_STANDALONE + if (command == "ls") { + listDir(LittleFS, "/", 3); + Serial.println(); + ok = true; + } +#endif + + // + // the tests take a lot of memory when built for the ESP32 + // so only including the full set in standalone, otherwise a limited selection of basic tests + // + #ifdef EMSESP_STANDALONE // all tests with EMSESP_STANDALONE @@ -287,6 +299,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.printfln("Adding all devices and entities..."); System::test_set_all_active(true); EMSESP::dump_all_values(shell); + ok = true; } if (command == "modes") { @@ -295,6 +308,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("call thermostat mode auto"); shell.invoke_command("call thermostat mode Manuell"); // DE shell.invoke_command("call thermostat mode 1"); + ok = true; } if (command == "render") { @@ -363,6 +377,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const temp = 0x63; doub = Helpers::transformNumFloat(temp, 2); // divide by 2 shell.printfln("Round test div2 from x%02X to %d to %f", temp, temp, doub); + ok = true; } if (command == "devices") { @@ -370,6 +385,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // A fake response - UBADevices(0x07) rx_telegram({0x08, 0x00, 0x07, 0x00, 0x0B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + ok = true; } // check for boiler and controller on same product_id @@ -381,6 +397,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // UBAuptime uart_telegram({0x08, 0x0B, 0x14, 00, 0x3C, 0x1F, 0xAC, 0x70}); + ok = true; } if (command == "620") { @@ -391,6 +408,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // Version Boiler uart_telegram({0x08, 0x0B, 0x02, 0x00, 0x5F, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + ok = true; } // unknown device @@ -409,6 +427,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("show devices"); shell.invoke_command("call system report"); + ok = true; } if (command == "unknown2") { @@ -416,11 +435,13 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // simulate getting version information back from an unknown device rx_telegram({0x09, 0x0B, 0x02, 0x00, 0x5A, 0x01, 0x02}); // productID is 90 which doesn't exist + ok = true; } if (command == "gateway") { shell.printfln("Testing Gateway..."); run_test("gateway"); + ok = true; } if (command == "310") { @@ -430,6 +451,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("show"); shell.invoke_command("call system publish"); shell.invoke_command("show mqtt"); + ok = true; } if (command == "2thermostats") { @@ -437,6 +459,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const run_test("2thermostats"); shell.invoke_command("show"); shell.invoke_command("show devices"); + ok = true; } if (command == "web") { @@ -448,7 +471,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const run_test("boiler"); run_test("thermostat"); -#if defined(EMSESP_STANDALONE) DynamicJsonDocument doc(8000); // some absurd high number for (const auto & emsdevice : EMSESP::emsdevices) { if (emsdevice) { @@ -483,7 +505,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const Serial.println(" **"); } } -#endif + ok = true; } if (command == "board_profile") { @@ -493,6 +515,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("set board_profile wemos"); shell.invoke_command("exit"); shell.invoke_command("call system settings"); + ok = true; } if (command == "boiler") { @@ -521,6 +544,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const EMSESP::mqtt_.incoming("ems-esp/boiler", "{\"cmd\":\"heatingactivated\",\"data\":1}"); shell.invoke_command("show mqtt"); + ok = true; } if (command == "shower_alert") { @@ -530,6 +554,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // device type, command, data Command::call(EMSdevice::DeviceType::BOILER, "wwtapactivated", "false"); + ok = true; } if (command == "fr120") { @@ -542,6 +567,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("show"); shell.invoke_command("show devices"); + ok = true; } if (command == "ha") { @@ -564,6 +590,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // shell.invoke_command("call thermostat seltemp"); // sensor.thermostat_hc1_selected_room_temperature // shell.invoke_command("call thermostat entities"); // shell.invoke_command("call boiler entities"); + ok = true; } if (command == "lastcode") { @@ -582,6 +609,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const {0x08, 0x0B, 0xC2, 0, 0x08, 0xAC, 00, 0x10, 0x31, 0x48, 0x30, 0x31, 0x15, 0x80, 0x95, 0x0B, 0x0E, 0x10, 0x38, 00, 0x7F, 0xFF, 0xFF, 0xFF}); // shell.invoke_command("show"); + + ok = true; } if (command == "dv") { @@ -596,11 +625,13 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("call boiler wwseltemp"); shell.invoke_command("call system publish"); + ok = true; } if (command == "dallas") { shell.printfln("Testing adding Dallas sensor"); emsesp::EMSESP::dallassensor_.test(); + ok = true; } if (command == "dallas_full") { @@ -617,6 +648,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const EMSESP::dallassensor_.update("01-0203-0405-0607", "testdallas", 2); shell.invoke_command("show"); shell.invoke_command("call system publish"); + ok = true; } if (command == "analog") { @@ -636,6 +668,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const EMSESP::analogsensor_.update(36, "analogtest", 2, 0.7, 17, 1); shell.invoke_command("show"); // shell.invoke_command("call system publish"); + ok = true; } if (command == "healthcheck") { @@ -648,6 +681,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // n=2 = EMSESP::system_.HEALTHCHECK_NO_NETWORK shell.printfln("Testing healthcheck with %d", n); EMSESP::system_.healthcheck(n); + ok = true; } if (command == "custom") { @@ -677,6 +711,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("call thermostat seltemp"); shell.invoke_command("call system publish"); + + ok = true; } if (command == "masked") { @@ -701,6 +737,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("call boiler wwseltemp"); shell.invoke_command("call system publish"); + ok = true; } if (command == "dv2") { @@ -721,10 +758,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("call boiler wwseltemp"); shell.invoke_command("call system publish"); + ok = true; } if (command == "api_values") { -#if defined(EMSESP_STANDALONE) shell.printfln("Testing API getting values"); Mqtt::ha_enabled(false); Mqtt::nested_format(1); @@ -754,7 +791,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const EMSESP::webAPIService.webAPIService_get(&request); request.url("/api/boiler/flamecurr/bad"); EMSESP::webAPIService.webAPIService_get(&request); -#endif + ok = true; } if (command == "mqtt_post") { @@ -769,9 +806,9 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const run_test("thermostat"); EMSESP::mqtt_.incoming("ems-esp/boiler/wwseltemp", "59"); + ok = true; } -#if defined(EMSESP_STANDALONE) // https://github.com/emsesp/EMS-ESP32/issues/541 if (command == "api_wwmode") { shell.printfln("Testing API wwmode"); @@ -789,8 +826,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const json = doc.as(); request.url("/api/thermostat/wwmode"); EMSESP::webAPIService.webAPIService_post(&request, json); + ok = true; } -#endif if (command == "api") { shell.printfln("Testing API with MQTT and REST, standalone"); @@ -804,7 +841,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const run_test("boiler"); run_test("thermostat"); -#if defined(EMSESP_STANDALONE) AsyncWebServerRequest requestX; DynamicJsonDocument docX(2000); JsonVariant jsonX; @@ -940,7 +976,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const strlcpy(command_s, "hc3_seltemp", sizeof(command_s)); ncmd = Command::parse_command_string(command_s, id_n); shell.printfln("test cmd parse cmd=%s id=%d", ncmd, id_n); -#endif // Console tests shell.invoke_command("call thermostat entities"); @@ -974,7 +1009,6 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const Mqtt::base("home/cellar/heating"); EMSESP::mqtt_.incoming("home/cellar/heating/thermostat/mode"); // empty payload, sends reponse -#if defined(EMSESP_STANDALONE) // Web API TESTS AsyncWebServerRequest request; @@ -1060,7 +1094,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const json = doc.as(); request.url("/api/thermostat/mode/auto"); EMSESP::webAPIService.webAPIService_post(&request, json); -#endif + ok = true; } if (command == "mqtt_nested") { @@ -1081,6 +1115,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const Mqtt::nested_format(2); shell.invoke_command("call system publish"); shell.invoke_command("show mqtt"); + ok = true; } if (command == "thermostat") { @@ -1097,6 +1132,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const EMSESP::mqtt_.incoming("ems-esp/thermostat_hc3", "{\"cmd\":\"temp\",\"data\":-3}"); shell.invoke_command("show mqtt"); + ok = true; } if (command == "tc100") { @@ -1108,6 +1144,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // 0x0A uart_telegram({0x98, 0x0B, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}); + ok = true; } if (command == "solar") { @@ -1121,6 +1158,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("call system publish"); // EMSESP::txservice_.send_raw("B0 00 FF 18 02 62 80 00 B8"); + ok = true; } if (command == "heatpump") { @@ -1128,6 +1166,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const run_test("heatpump"); shell.invoke_command("call"); shell.invoke_command("call heatpump info"); + ok = true; } if (command == "solar200") { @@ -1153,6 +1192,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const uart_telegram("30 00 FF 0A 02 6A 03"); // SM100 pump off 0 shell.invoke_command("show"); + ok = true; } if (command == "km") { @@ -1211,6 +1251,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const EMSESP::show_ems(shell); EMSESP::show_device_values(shell); + ok = true; } if (command == "cr100") { @@ -1236,12 +1277,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.loop_all(); EMSESP::txservice_.send(); // send it to UART + ok = true; } if (command == "rx2") { shell.printfln("Testing Rx2..."); for (uint8_t i = 0; i < 30; i++) { uart_telegram({0x08, 0x0B, 0x33, 0x00, 0x08, 0xFF, 0x34, 0xFB, 0x00, 0x28, 0x00, 0x00, 0x46, 0x00, 0xFF, 0xFF, 0x00}); + ok = true; } } @@ -1300,6 +1343,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // test 0x2A - DHWStatus3 uart_telegram({0x88, 00, 0x2A, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0xD2, 00, 00, 0x80, 00, 00, 01, 0x9D, 0x80, 0x00, 0x02, 0x79, 00}); + ok = true; } if (command == "tx") { @@ -1337,6 +1381,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const for (uint8_t i = 0; i < 10; i++) { EMSESP::txservice_.send(); // send it to UART } + + ok = true; } if (command == "poll") { @@ -1362,6 +1408,8 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const uint8_t t2[] = {0x21, 0x22}; EMSESP::send_write_request(0x91, 0x17, 0x00, t2, sizeof(t2), 0); EMSESP::show_ems(shell); + + ok = true; } if (command == "cmd") { @@ -1393,12 +1441,14 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("call thermostat wwmode"); // should do nothing shell.invoke_command("call thermostat mode auto 2"); // should error, no hc2 shell.invoke_command("call thermostat temp 22.56"); + ok = true; } if (command == "pin") { shell.printfln("Testing pin..."); shell.invoke_command("call system pin"); shell.invoke_command("call system pin 1 true"); + ok = true; } if (command == "mqtt2") { @@ -1422,6 +1472,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const Mqtt::publish("test", jo); Mqtt::show_mqtt(shell); // show queue + ok = true; } if (command == "mqtt") { @@ -1516,6 +1567,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const Mqtt::resubscribe(); Mqtt::show_mqtt(shell); // show queue + ok = true; } if (command == "poll2") { @@ -1527,6 +1579,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const EMSESP::incoming_telegram(poll, 1); EMSESP::show_ems(shell); + ok = true; } if (command == "rx2") { @@ -1534,6 +1587,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const uart_telegram({0x1B, 0x5B, 0xFD, 0x2D, 0x9E, 0x3A, 0xB6, 0xE5, 0x02, 0x20, 0x33, 0x30, 0x32, 0x3A, 0x20, 0x5B, 0x73, 0xFF, 0xFF, 0xCB, 0xDF, 0xB7, 0xA7, 0xB5, 0x67, 0x77, 0x77, 0xE4, 0xFF, 0xFD, 0x77, 0xFF}); + ok = true; } // https://github.com/emsesp/EMS-ESP/issues/380#issuecomment-633663007 @@ -1541,6 +1595,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.printfln("Testing rx3..."); uart_telegram({0x21, 0x0B, 0xFF, 0x00}); + ok = true; } // testing the UART tx command, without a queue @@ -1549,6 +1604,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const uint8_t t[] = {0x0B, 0x88, 0x18, 0x00, 0x20, 0xD4}; // including CRC EMSuart::transmit(t, sizeof(t)); + ok = true; } // send read request with offset @@ -1557,6 +1613,7 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const // send_read_request(0x18, 0x08); EMSESP::txservice_.read_request(0x18, 0x08, 27); // no offset + ok = true; } if (command == "mixer") { @@ -1572,11 +1629,10 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const shell.invoke_command("call system publish"); shell.invoke_command("show mqtt"); -// shell.invoke_command("call mixer wwc1 info"); -// shell.invoke_command("call mixer wwc2 info"); + // shell.invoke_command("call mixer wwc1 info"); + // shell.invoke_command("call mixer wwc2 info"); -// test API -#if defined(EMSESP_STANDALONE) + // test API AsyncWebServerRequest request; request.url("/api/mixer"); EMSESP::webAPIService.webAPIService_get(&request); @@ -1584,35 +1640,33 @@ void Test::run_test(uuid::console::Shell & shell, const std::string & cmd, const EMSESP::webAPIService.webAPIService_get(&request); request.url("/api/mixer/wwc2/pumpstatus"); EMSESP::webAPIService.webAPIService_get(&request); -#endif + ok = true; } if (command == "crash") { shell.printfln("Forcing a crash..."); - #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdiv-by-zero" #pragma GCC diagnostic ignored "-Wunused-variable" uint8_t a = 2 / 0; shell.printfln("Testing %s", a); - #pragma GCC diagnostic pop + ok = true; } +#endif - // if we're here, we didn't recognize the test - shell.printfln("Unknown test command: %s", command.c_str()); - -#endif // EMSES_STANDALONE + if (!ok) { + shell.printfln("Unknown test command: %s", command.c_str()); + EMSESP::logger().notice("Unknown test command: %s", command.c_str()); + } } // loop console. simulates what EMSESP::loop() does void Test::refresh() { - // #if defined(EMSESP_STANDALONE) uuid::loop(); EMSESP::rxservice_.loop(); EMSESP::mqtt_.loop(); Shell::loop_all(); - // #endif } // simulates a telegram in the Rx queue, but without the CRC which is added automatically @@ -1764,24 +1818,6 @@ void Test::listDir(fs::FS & fs, const char * dirname, uint8_t levels) { } #endif -void Test::debug(uuid::console::Shell & shell, const std::string & cmd) { - // shell.add_flags(CommandFlags::ADMIN); // switch to su - - std::string command(20, '\0'); - if ((cmd.empty()) || (cmd == "default")) { - command = "ls"; - } else { - command = cmd; - } - -#ifndef EMSESP_STANDALONE - if (command == "ls") { - listDir(LittleFS, "/", 3); - Serial.println(); - } -#endif -} - } // namespace emsesp #endif diff --git a/src/test/test.h b/src/test/test.h index a253fbc24..c9510e78f 100644 --- a/src/test/test.h +++ b/src/test/test.h @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -#if defined(EMSESP_DEBUG) +#if defined(EMSESP_DEBUG) || defined(EMSESP_STANDALONE) #ifndef EMSESP_TEST_H #define EMSESP_TEST_H @@ -30,7 +30,7 @@ namespace emsesp { // #define EMSESP_DEBUG_DEFAULT "solar" // #define EMSESP_DEBUG_DEFAULT "web" // #define EMSESP_DEBUG_DEFAULT "mqtt" -// #define EMSESP_DEBUG_DEFAULT "general" +#define EMSESP_DEBUG_DEFAULT "general" // #define EMSESP_DEBUG_DEFAULT "boiler" // #define EMSESP_DEBUG_DEFAULT "mqtt2" // #define EMSESP_DEBUG_DEFAULT "mqtt_nested" @@ -52,7 +52,7 @@ namespace emsesp { // #define EMSESP_DEBUG_DEFAULT "api_wwmode" // #define EMSESP_DEBUG_DEFAULT "custom" // #define EMSESP_DEBUG_DEFAULT "entity_dump" -#define EMSESP_DEBUG_DEFAULT "memory" +// #define EMSESP_DEBUG_DEFAULT "memory" class Test { public: @@ -64,11 +64,8 @@ class Test { static void uart_telegram(const char * rx_data); static void uart_telegram_withCRC(const char * rx_data); static void add_device(uint8_t device_id, uint8_t product_id); - static void debug(uuid::console::Shell & shell, const std::string & command); static void refresh(); -#ifndef EMSESP_STANDALONE static void listDir(fs::FS & fs, const char * dirname, uint8_t levels); -#endif }; } // namespace emsesp