diff --git a/lib/MyESP/MyESP.cpp b/lib/MyESP/MyESP.cpp index 9fd14b039..7e8dd644c 100644 --- a/lib/MyESP/MyESP.cpp +++ b/lib/MyESP/MyESP.cpp @@ -44,9 +44,6 @@ MyESP::MyESP() { _web_callback = NULL; - _helpProjectCmds = NULL; - _helpProjectCmds_count = 0; - _serial = false; _serial_default = false; @@ -250,23 +247,23 @@ void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) { } if (code == MESSAGE_SCANNING) { - myDebug_P(PSTR("[WIFI] Scanning\n")); + myDebug_P(PSTR("[WIFI] Scanning")); } if (code == MESSAGE_SCAN_FAILED) { - myDebug_P(PSTR("[WIFI] Scan failed\n")); + myDebug_P(PSTR("[WIFI] Scan failed")); } if (code == MESSAGE_NO_NETWORKS) { - myDebug_P(PSTR("[WIFI] No networks found\n")); + myDebug_P(PSTR("[WIFI] No networks found")); } if (code == MESSAGE_NO_KNOWN_NETWORKS) { - myDebug_P(PSTR("[WIFI] No known networks found\n")); + myDebug_P(PSTR("[WIFI] No known networks found")); } if (code == MESSAGE_FOUND_NETWORK) { - myDebug_P(PSTR("[WIFI] %s\n"), parameter); + myDebug_P(PSTR("[WIFI] %s"), parameter); } if (code == MESSAGE_CONNECT_WAITING) { @@ -274,35 +271,11 @@ void MyESP::_wifiCallback(justwifi_messages_t code, char * parameter) { } if (code == MESSAGE_ACCESSPOINT_CREATING) { - myDebug_P(PSTR("[WIFI] Creating access point\n")); + myDebug_P(PSTR("[WIFI] Creating access point")); } if (code == MESSAGE_ACCESSPOINT_FAILED) { - myDebug_P(PSTR("[WIFI] Could not create access point\n")); - } - - if (code == MESSAGE_WPS_START) { - myDebug_P(PSTR("[WIFI] WPS started\n")); - } - - if (code == MESSAGE_WPS_SUCCESS) { - myDebug_P(PSTR("[WIFI] WPS succeeded!\n")); - } - - if (code == MESSAGE_WPS_ERROR) { - myDebug_P(PSTR("[WIFI] WPS failed\n")); - } - - if (code == MESSAGE_SMARTCONFIG_START) { - myDebug_P(PSTR("[WIFI] Smart Config started\n")); - } - - if (code == MESSAGE_SMARTCONFIG_SUCCESS) { - myDebug_P(PSTR("[WIFI] Smart Config succeeded!\n")); - } - - if (code == MESSAGE_SMARTCONFIG_ERROR) { - myDebug_P(PSTR("[WIFI] Smart Config failed\n")); + myDebug_P(PSTR("[WIFI] Could not create access point")); } } @@ -548,9 +521,7 @@ void MyESP::_eeprom_setup() { } // Set callback of sketch function to process project messages -void MyESP::setTelnet(command_t * cmds, uint8_t count, telnetcommand_callback_f callback_cmd, telnet_callback_f callback) { - _helpProjectCmds = cmds; // command list - _helpProjectCmds_count = count; // number of commands +void MyESP::setTelnet(telnetcommand_callback_f callback_cmd, telnet_callback_f callback) { _telnetcommand_callback = callback_cmd; // external function to handle commands _telnet_callback = callback; } @@ -625,27 +596,11 @@ void MyESP::_consoleShowHelp() { myDebug_P(PSTR("* crash ")); #endif - // print custom commands if available. Taken from progmem - if (_telnetcommand_callback) { - // find the longest key length so we can right align it - uint8_t max_len = 0; - for (uint8_t i = 0; i < _helpProjectCmds_count; i++) { - if ((strlen(_helpProjectCmds[i].key) > max_len) && (!_helpProjectCmds[i].set)) { - max_len = strlen(_helpProjectCmds[i].key); - } - } - - for (uint8_t i = 0; i < _helpProjectCmds_count; i++) { - if (!_helpProjectCmds[i].set) { - SerialAndTelnet.print("* "); - SerialAndTelnet.print(_helpProjectCmds[i].key); - for (uint8_t j = 0; j < ((max_len + 5) - strlen(_helpProjectCmds[i].key)); j++) { // account for longest string length - SerialAndTelnet.print(" "); // padding - } - SerialAndTelnet.println(_helpProjectCmds[i].description); - } - } + // call callback function + if (_telnet_callback) { + (_telnet_callback)(TELNET_EVENT_SHOWCMD); } + myDebug_P(PSTR("")); // newline } @@ -654,31 +609,14 @@ void MyESP::_printSetCommands() { myDebug_P(PSTR("")); // newline myDebug_P(PSTR("The following set commands are available:")); myDebug_P(PSTR("")); // newline - myDebug_P(PSTR("* set erase")); - myDebug_P(PSTR("* set [value]")); - myDebug_P(PSTR("* set [value]")); - myDebug_P(PSTR("* set serial ")); + myDebug_P(PSTR(" set erase")); + myDebug_P(PSTR(" set [value]")); + myDebug_P(PSTR(" set [value]")); + myDebug_P(PSTR(" set serial ")); - // print custom commands if available. Taken from progmem - if (_telnetcommand_callback) { - // find the longest key length so we can right align it - uint8_t max_len = 0; - for (uint8_t i = 0; i < _helpProjectCmds_count; i++) { - if ((strlen(_helpProjectCmds[i].key) > max_len) && (_helpProjectCmds[i].set)) { - max_len = strlen(_helpProjectCmds[i].key); - } - } - - for (uint8_t i = 0; i < _helpProjectCmds_count; i++) { - if (_helpProjectCmds[i].set) { - SerialAndTelnet.print(FPSTR("* set ")); - SerialAndTelnet.print(FPSTR(_helpProjectCmds[i].key)); - for (uint8_t j = 0; j < ((max_len + 5) - strlen(_helpProjectCmds[i].key)); j++) { // account for longest string length - SerialAndTelnet.print(FPSTR(" ")); // padding - } - SerialAndTelnet.println(FPSTR(_helpProjectCmds[i].description)); - } - } + // call callback function + if (_telnet_callback) { + (_telnet_callback)(TELNET_EVENT_SHOWSET); } myDebug_P(PSTR("")); // newline @@ -938,7 +876,9 @@ void MyESP::_telnetCommand(char * commandLine) { #endif // call callback function - (_telnetcommand_callback)(wc, commandLine); + if (_telnetcommand_callback) { + (_telnetcommand_callback)(wc, commandLine); + } } // returns WiFi hostname as a String object @@ -1118,7 +1058,6 @@ void MyESP::_setSystemCheck(bool stable) { if (stable) { value = 0; // system is ok - // myDebug_P(PSTR("[SYSTEM] System OK\n")); } else { if (!_getRtcmemStatus()) { _setSystemStabilityCounter(1); @@ -1704,6 +1643,8 @@ void MyESP::_fs_setup() { _firstInstall = true; // flag as a first install } + myDebug_P(PSTR("[FS] Settings loaded from SPIFFS")); + // _fs_printConfig(); // enable for debugging } @@ -2141,7 +2082,7 @@ void MyESP::_webserver_setup() { webServer.begin(); - myDebug_P(PSTR("[WEB] Web server started.")); + myDebug_P(PSTR("[WEB] Web server started")); } // bootup sequence @@ -2182,6 +2123,9 @@ void MyESP::begin(const char * app_hostname, const char * app_name, const char * _telnet_setup(); // Telnet setup, called first to set Serial + // print a welcome message + myDebug_P(PSTR("\n\n* %s version %s"), _app_name, _app_version); + // set up onboard LED pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); @@ -2194,19 +2138,16 @@ void MyESP::begin(const char * app_hostname, const char * app_name, const char * _firstInstall = true; // flag as an initial install so the config file will be recreated } - _eeprom_setup(); // set up EEPROM for storing crash data, if compiled with -DCRASH - + _eeprom_setup(); // set up EEPROM for storing crash data, if compiled with -DCRASH _fs_setup(); // SPIFFS setup, do this first to get values _wifi_setup(); // WIFI setup _ota_setup(); // init OTA _webserver_setup(); // init web server - // print a welcome message - myDebug_P(PSTR("\n* %s version %s"), _app_name, _app_version); - SerialAndTelnet.flush(); - _setSystemCheck(false); // reset system check - _heartbeatCheck(true); // force heartbeat + _heartbeatCheck(true); // force heartbeat check (not the MQTT one) + + SerialAndTelnet.flush(); } /* diff --git a/lib/MyESP/MyESP.h b/lib/MyESP/MyESP.h index f04551d2a..d6eedb803 100644 --- a/lib/MyESP/MyESP.h +++ b/lib/MyESP/MyESP.h @@ -9,7 +9,7 @@ #ifndef MyEMS_h #define MyEMS_h -#define MYESP_VERSION "1.1.22" +#define MYESP_VERSION "1.1.23" #include #include @@ -68,6 +68,8 @@ extern struct rst_info resetInfo; #define TELNET_MAX_COMMAND_LENGTH 80 // length of a command #define TELNET_EVENT_CONNECT 1 #define TELNET_EVENT_DISCONNECT 0 +#define TELNET_EVENT_SHOWCMD 10 +#define TELNET_EVENT_SHOWSET 20 // ANSI Colors #define COLOR_RESET "\x1B[0m" @@ -189,6 +191,11 @@ constexpr size_t ArraySize(T (&)[N]) { return N; } +template +void PROGMEM_readAnything(const T * sce, T & dest) { + memcpy_P(&dest, sce, sizeof(T)); +} + #define UPTIME_OVERFLOW 4294967295 // Uptime overflow value // web min and max length of wifi ssid and password @@ -262,7 +269,7 @@ class MyESP { // debug & telnet void myDebug(const char * format, ...); void myDebug_P(PGM_P format_P, ...); - void setTelnet(command_t * cmds, uint8_t count, telnetcommand_callback_f callback_cmd, telnet_callback_f callback); + void setTelnet(telnetcommand_callback_f callback_cmd, telnet_callback_f callback); bool getUseSerial(); void setUseSerial(bool toggle); @@ -346,8 +353,6 @@ class MyESP { char * _telnet_readWord(bool allow_all_chars); void _telnet_setup(); char _command[TELNET_MAX_COMMAND_LENGTH]; // the input command from either Serial or Telnet - command_t * _helpProjectCmds; // Help of commands setted by project - uint8_t _helpProjectCmds_count; // # available commands void _consoleShowHelp(); telnetcommand_callback_f _telnetcommand_callback; // Callable for projects commands telnet_callback_f _telnet_callback; // callback for connect/disconnect diff --git a/src/ems-esp.cpp b/src/ems-esp.cpp index ebdef1a65..d1a80600f 100644 --- a/src/ems-esp.cpp +++ b/src/ems-esp.cpp @@ -93,7 +93,7 @@ typedef struct { bool doingColdShot; // true if we've just sent a jolt of cold water } _EMSESP_Shower; -command_t project_cmds[] = { +static const command_t project_cmds[] PROGMEM = { {true, "led ", "toggle status LED on/off"}, {true, "led_gpio ", "set the LED pin. Default is the onboard LED 2. For external D1 use 5"}, @@ -133,6 +133,7 @@ command_t project_cmds[] = { {false, "boiler comfort ", "set boiler warm water comfort setting"} }; +uint8_t _project_cmds_count = ArraySize(project_cmds); // store for overall system status _EMSESP_Status EMSESP_Status; @@ -980,13 +981,13 @@ float _readFloatNumber() { return atof(numTextPtr); } -// used to read the next string from an input buffer as a hex value and convert to an 8 bit int -uint8_t _readHexNumber() { +// used to read the next string from an input buffer as a hex value and convert to a 16 bit int +uint16_t _readHexNumber() { char * numTextPtr = strtok(NULL, ", \n"); if (numTextPtr == nullptr) { return 0; } - return (uint8_t)strtol(numTextPtr, 0, 16); + return (uint16_t)strtol(numTextPtr, 0, 16); } // used to read the next string from an input buffer @@ -1338,6 +1339,40 @@ bool SettingsCallback(MYESP_FSACTION action, uint8_t wc, const char * setting, c return ok; } +// print settings +void _showCommands(uint8_t event) { + bool mode = (event == TELNET_EVENT_SHOWSET); // show set commands or normal commands + command_t cmd; + + // find the longest key length so we can right-align the text + uint8_t max_len = 0; + uint8_t i; + for (i = 0; i < _project_cmds_count; i++) { + memcpy_P(&cmd, &project_cmds[i], sizeof(cmd)); + if ((strlen(cmd.key) > max_len) && (cmd.set == mode)) { + max_len = strlen(cmd.key); + } + } + + char line[200] = {0}; + for (i = 0; i < _project_cmds_count; i++) { + memcpy_P(&cmd, &project_cmds[i], sizeof(cmd)); + if (cmd.set == mode) { + if (event == TELNET_EVENT_SHOWSET) { + strlcpy(line, " set ", sizeof(line)); + } else { + strlcpy(line, "* ", sizeof(line)); + } + strlcat(line, cmd.key, sizeof(line)); + for (uint8_t j = 0; j < ((max_len + 5) - strlen(cmd.key)); j++) { // account for longest string length + strlcat(line, " ", sizeof(line)); // padding + } + strlcat(line, cmd.description, sizeof(line)); + myDebug(line); // print the line + } + } +} + // call back when a telnet client connects or disconnects // we set the logging here void TelnetCallback(uint8_t event) { @@ -1345,6 +1380,8 @@ void TelnetCallback(uint8_t event) { ems_setLogging(EMS_SYS_LOGGING_DEFAULT); } else if (event == TELNET_EVENT_DISCONNECT) { ems_setLogging(EMS_SYS_LOGGING_NONE); + } else if ((event == TELNET_EVENT_SHOWCMD) || (event == TELNET_EVENT_SHOWSET)) { + _showCommands(event); } } @@ -1694,7 +1731,9 @@ void WebCallback(char * body) { void WIFICallback() { // This is where we enable the UART service to scan the incoming serial Tx/Rx bus signals // This is done after we have a WiFi signal to avoid any resource conflicts + system_uart_swap(); // TODO check + /* if (myESP.getUseSerial()) { myDebug_P(PSTR("Warning! EMS bus communication disabled when Serial mode enabled. Use 'set serial off' to start communication.")); } else { @@ -1705,6 +1744,7 @@ void WIFICallback() { ems_discoverModels(); } } + */ } // Initialize the boiler settings and shower settings @@ -1727,6 +1767,9 @@ void initEMSESP() { EMSESP_Shower.timerPause = 0; EMSESP_Shower.duration = 0; EMSESP_Shower.doingColdShot = false; + + // call ems.cpp's init function to set all the internal params + ems_init(); } /* @@ -1799,35 +1842,40 @@ void showerCheck() { // SETUP // void setup() { - // init our own parameters - initEMSESP(); + initEMSESP(); // init parameters - // call ems.cpp's init function to set all the internal params - ems_init(); - - systemCheckTimer.attach(SYSTEMCHECK_TIME, do_systemCheck); // check if EMS is reachable - - // set up myESP for Wifi, MQTT, MDNS and Telnet - myESP.setTelnet(project_cmds, ArraySize(project_cmds), TelnetCommandCallback, TelnetCallback); // set up Telnet commands - myESP.setWIFI(NULL, NULL, WIFICallback); // empty ssid and password as we take this from the config file - - // MQTT host, username and password taken from the SPIFFS settings - myESP.setMQTT( - NULL, NULL, NULL, MQTT_BASE, MQTT_KEEPALIVE, MQTT_QOS, MQTT_RETAIN, MQTT_WILL_TOPIC, MQTT_WILL_ONLINE_PAYLOAD, MQTT_WILL_OFFLINE_PAYLOAD, MQTTCallback); - - // OTA callback which is called when OTA is starting and stopping - myESP.setOTA(OTACallback_pre, OTACallback_post); - - // custom settings in SPIFFS - myESP.setSettings(FSCallback, SettingsCallback); - - // web custom settings - myESP.setWeb(WebCallback); - - // start up all the services - myESP.begin(APP_HOSTNAME, APP_NAME, APP_VERSION); + myESP.setTelnet(TelnetCommandCallback, TelnetCallback); // set up Telnet commands + myESP.setWIFI(NULL, NULL, WIFICallback); // empty ssid and password as we take this from the config file + myESP.setMQTT(NULL, + NULL, + NULL, + MQTT_BASE, + MQTT_KEEPALIVE, + MQTT_QOS, + MQTT_RETAIN, + MQTT_WILL_TOPIC, + MQTT_WILL_ONLINE_PAYLOAD, + MQTT_WILL_OFFLINE_PAYLOAD, + MQTTCallback); // MQTT host, username and password taken from the SPIFFS settings + myESP.setOTA(OTACallback_pre, OTACallback_post); // OTA callback which is called when OTA is starting and stopping + myESP.setSettings(FSCallback, SettingsCallback); // custom settings in SPIFFS + myESP.setWeb(WebCallback); // web custom settings + myESP.begin(APP_HOSTNAME, APP_NAME, APP_VERSION); // start up all the services // at this point we have all the settings from our internall SPIFFS config file + // fire up the UART now + if (myESP.getUseSerial()) { + myDebug_P(PSTR("Warning! EMS bus communication disabled when Serial mode enabled. Use 'set serial off' to start communication.")); + } else { + Serial.println("Note: Serial output will now be disabled. Please use Telnet."); + Serial.flush(); + emsuart_init(); + myDebug_P(PSTR("[UART] Opened Rx/Tx connection")); + if (!EMSESP_Status.listen_mode) { + // go and find the boiler and thermostat types, if not in listen mode + ems_discoverModels(); + } + } // enable regular checks if not in test mode if (!EMSESP_Status.listen_mode) { @@ -1845,6 +1893,8 @@ void setup() { // check for Dallas sensors EMSESP_Status.dallas_sensors = ds18.setup(EMSESP_Status.dallas_gpio, EMSESP_Status.dallas_parasite); // returns #sensors + + systemCheckTimer.attach(SYSTEMCHECK_TIME, do_systemCheck); // check if EMS is reachable } // diff --git a/src/version.h b/src/version.h index c0cec732e..6c7a7827f 100644 --- a/src/version.h +++ b/src/version.h @@ -6,5 +6,5 @@ #pragma once #define APP_NAME "EMS-ESP" -#define APP_VERSION "1.8.1b19" +#define APP_VERSION "1.8.1b20" #define APP_HOSTNAME "ems-esp"