diff --git a/lib/MyESP/MyESP.cpp b/lib/MyESP/MyESP.cpp index cccb28dce..f578b0751 100644 --- a/lib/MyESP/MyESP.cpp +++ b/lib/MyESP/MyESP.cpp @@ -1,5 +1,5 @@ /* - * MyESP - my ESP helper class to handle Wifi, MQTT and Telnet + * MyESP - my ESP helper class to handle WiFi, MQTT and Telnet * * Paul Derbyshire - December 2018 * @@ -26,7 +26,7 @@ MyESP::MyESP() { _app_name = strdup("MyESP"); _app_version = strdup(MYESP_VERSION); - _boottime = strdup(""); + _boottime = NULL; _load_average = 100; // calculated load average _telnetcommand_callback = NULL; @@ -314,6 +314,8 @@ void MyESP::_wifi_setup() { jw.enableScan(false); // Configure it to scan available networks and connect in order of dBm jw.cleanNetworks(); // Clean existing network configuration jw.addNetwork(_wifi_ssid, _wifi_password); // Add a network + + WiFi.setSleepMode(WIFI_NONE_SLEEP); // TODO: possible fix for wifi dropouts in core 2.5.0 } // set the callback function for the OTA onstart @@ -381,7 +383,6 @@ void MyESP::_ota_setup() { // There's been an error, reenable rotation EEPROMr.rotate(true); #endif - }); } @@ -498,47 +499,27 @@ void MyESP::_consoleShowHelp() { SerialAndTelnet.println(); if (WiFi.getMode() & WIFI_AP) { - SerialAndTelnet.printf("* ESP is in AP mode with SSID %s", jw.getAPSSID().c_str()); - SerialAndTelnet.println(); + SerialAndTelnet.printf("* Device is in AP mode with SSID %s", jw.getAPSSID().c_str()); } else { -#if defined(ARDUINO_ARCH_ESP32) - String hostname = String(WiFi.getHostname()); -#else - String hostname = WiFi.hostname(); -#endif - SerialAndTelnet.printf("* Hostname: %s IP: %s MAC: %s", - hostname.c_str(), - WiFi.localIP().toString().c_str(), - WiFi.macAddress().c_str()); -#ifdef ARDUINO_BOARD - SerialAndTelnet.printf(" Board: %s", ARDUINO_BOARD); -#endif - SerialAndTelnet.printf(" (MyESP v%s)", MYESP_VERSION); - -#ifdef BUILD_TIME - SerialAndTelnet.print(" (Build "); - _printBuildTime(BUILD_TIME); - SerialAndTelnet.print(")"); -#endif + SerialAndTelnet.printf("* Hostname: %s (%s)", getESPhostname().c_str(), WiFi.localIP().toString().c_str()); SerialAndTelnet.println(); - SerialAndTelnet.printf("* Connected to WiFi SSID: %s (signal %d%%)", WiFi.SSID().c_str(), getWifiQuality()); + SerialAndTelnet.printf("* WiFi SSID: %s (signal %d%%)", WiFi.SSID().c_str(), getWifiQuality()); SerialAndTelnet.println(); SerialAndTelnet.printf("* MQTT is %s", mqttClient.connected() ? "connected" : "disconnected"); - SerialAndTelnet.println(); + } + + SerialAndTelnet.println(); + + if (_boottime != NULL) { SerialAndTelnet.printf("* Boot time: %s", _boottime); SerialAndTelnet.println(); } - SerialAndTelnet.printf("* Free RAM: %d KB Load: %d%%", (ESP.getFreeHeap() / 1024), getSystemLoadAverage()); - SerialAndTelnet.println(); - // for battery power is ESP.getVcc() - SerialAndTelnet.println(FPSTR("*")); SerialAndTelnet.println(FPSTR("* Commands:")); - SerialAndTelnet.println(FPSTR("* ?=help, CTRL-D=quit")); - SerialAndTelnet.println(FPSTR("* reboot")); - SerialAndTelnet.println(FPSTR("* crash ")); - SerialAndTelnet.println(FPSTR("* set")); + SerialAndTelnet.println(FPSTR("* ?=help, CTRL-D=quit telnet")); + SerialAndTelnet.println(FPSTR("* set | reboot | system")); + SerialAndTelnet.println(FPSTR("* crash ")); SerialAndTelnet.println(FPSTR("* set wifi [ssid] [password]")); SerialAndTelnet.println(FPSTR("* set [value]")); SerialAndTelnet.println(FPSTR("* set erase")); @@ -761,6 +742,13 @@ void MyESP::_telnetCommand(char * commandLine) { resetESP(); } + // show system stats + if ((strcmp(ptrToCommandName, "system") == 0) && (wc == 1)) { + showSystemStats(); + return; + } + + // crash command if ((strcmp(ptrToCommandName, "crash") == 0) && (wc >= 2)) { char * cmd = _telnet_readWord(); @@ -771,8 +759,6 @@ void MyESP::_telnetCommand(char * commandLine) { } else if ((strcmp(cmd, "test") == 0) && (wc == 3)) { char * value = _telnet_readWord(); crashTest(atoi(value)); - } else if (strcmp(cmd, "info") == 0) { - crashInfo(); } return; // don't call custom command line callback } @@ -781,6 +767,82 @@ void MyESP::_telnetCommand(char * commandLine) { (_telnetcommand_callback)(wc, commandLine); } +// returns WiFi hostname as a String object +String MyESP::getESPhostname() { + String hostname; + +#if defined(ARDUINO_ARCH_ESP32) + hostname = String(WiFi.getHostname()); +#else + hostname = WiFi.hostname(); +#endif + + return (hostname); +} + +// print out ESP system stats +// for battery power is ESP.getVcc() +void MyESP::showSystemStats() { +#ifdef BUILD_TIME + myDebug_P("[SYSTEM] Build timestamp: %s)", _printBuildTime(BUILD_TIME);); +#endif + + myDebug_P(PSTR("[APP] MyESP version: %s"), MYESP_VERSION); + myDebug_P(PSTR("[APP] System Load: %d%%"), getSystemLoadAverage()); + + if (WiFi.getMode() & WIFI_AP) { + myDebug_P(PSTR("[WIFI] Device is in AP mode with SSID %s"), jw.getAPSSID().c_str()); + } else { + myDebug_P(PSTR("[WIFI] Wifi Hostname: %s"), getESPhostname().c_str()); + myDebug_P(PSTR("[WIFI] Wifi IP: %s"), WiFi.localIP().toString().c_str()); + myDebug_P(PSTR("[WIFI] Wifi signal strength: %d%%"), getWifiQuality()); + } + + myDebug_P(PSTR("[WIFI] Wifi MAC: %s"), WiFi.macAddress().c_str()); + +#ifdef CRASH + char output_str[80] = {0}; + char buffer[16] = {0}; + /* Crash info */ + myDebug_P(PSTR("[EEPROM] EEPROM size: %u"), EEPROMr.reserved() * SPI_FLASH_SEC_SIZE); + strlcpy(output_str, PSTR("[EEPROM] EEPROM Sector pool size is "), sizeof(output_str)); + strlcat(output_str, itoa(EEPROMr.size(), buffer, 10), sizeof(output_str)); + strlcat(output_str, PSTR(", and in use are: "), sizeof(output_str)); + for (uint32_t i = 0; i < EEPROMr.size(); i++) { + strlcat(output_str, itoa(EEPROMr.base() - i, buffer, 10), sizeof(output_str)); + strlcat(output_str, PSTR(" "), sizeof(output_str)); + } + myDebug_P(output_str); +#endif + +#ifdef ARDUINO_BOARD + myDebug_P(PSTR("[SYSTEM] Board: %s"), ARDUINO_BOARD); +#endif + + myDebug_P(PSTR("[SYSTEM] CPU chip ID: 0x%06X"), ESP.getChipId()); + myDebug_P(PSTR("[SYSTEM] CPU frequency: %u MHz"), ESP.getCpuFreqMHz()); + myDebug_P(PSTR("[SYSTEM] SDK version: %s"), ESP.getSdkVersion()); + myDebug_P(PSTR("[SYSTEM] Core version: %s"), ESP.getCoreVersion().c_str()); + myDebug_P(PSTR("[SYSTEM] Boot version: %d"), ESP.getBootVersion()); + myDebug_P(PSTR("[SYSTEM] Boot mode: %d"), ESP.getBootMode()); + //myDebug_P(PSTR("[SYSTEM] Firmware MD5: %s"), (char *)ESP.getSketchMD5().c_str()); + + FlashMode_t mode = ESP.getFlashChipMode(); + myDebug_P(PSTR("[FLASH] Flash chip ID: 0x%06X"), ESP.getFlashChipId()); + myDebug_P(PSTR("[FLASH] Flash speed: %u Hz"), ESP.getFlashChipSpeed()); + myDebug_P(PSTR("[FLASH] Flash mode: %s"), + mode == FM_QIO ? "QIO" : mode == FM_QOUT ? "QOUT" : mode == FM_DIO ? "DIO" : mode == FM_DOUT ? "DOUT" : "UNKNOWN"); + myDebug_P(PSTR("[FLASH] Flash size (CHIP): %d"), ESP.getFlashChipRealSize()); + myDebug_P(PSTR("[FLASH] Flash size (SDK): %d"), ESP.getFlashChipSize()); + myDebug_P(PSTR("[FLASH] Flash Reserved: %d"), 1 * SPI_FLASH_SEC_SIZE); + myDebug_P(PSTR("[MEM] Firmware size: %d"), ESP.getSketchSize()); + myDebug_P(PSTR("[MEM] Max OTA size: %d"), (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000); + myDebug_P(PSTR("[MEM] OTA Reserved: %d"), 4 * SPI_FLASH_SEC_SIZE); + myDebug_P(PSTR("[MEM] Free Heap: %d"), ESP.getFreeHeap()); + myDebug_P(PSTR("[MEM] Stack: %d"), ESP.getFreeContStack()); +} + + // handler for Telnet void MyESP::_telnetHandle() { SerialAndTelnet.handle(); @@ -1134,7 +1196,7 @@ void MyESP::_fs_setup() { fs_saveConfig(); } - //_fs_printConfig(); // TODO: for debugging + //_fs_printConfig(); // enable for debugging } uint16_t MyESP::getSystemLoadAverage() { @@ -1287,15 +1349,6 @@ void MyESP::crashClear() { EEPROMr.commit(); } -/* Crash info */ -void MyESP::crashInfo() { - myDebug_P(PSTR("[EEPROM] Sector pool size: %u"), EEPROMr.size()); - myDebug_P(PSTR("[EEPROM] Sectors in use : ")); - for (uint32_t i = 0; i < EEPROMr.size(); i++) { - myDebug_P(PSTR("%d"), EEPROMr.base() - i); - } -} - /** * Print out crash information that has been previously saved in EEPROM */ @@ -1378,14 +1431,16 @@ void MyESP::begin(const char * app_hostname, const char * app_name, const char * */ void MyESP::loop() { _calculateLoad(); - _telnetHandle(); // Telnet/Debugger + _telnetHandle(); jw.loop(); // WiFi + /* // do nothing else until we've got a wifi connection if (WiFi.getMode() & WIFI_AP) { return; } + */ ArduinoOTA.handle(); // OTA _mqttConnect(); // MQTT diff --git a/lib/MyESP/MyESP.h b/lib/MyESP/MyESP.h index 2ac6ff4b2..2c4b2078a 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.6c" +#define MYESP_VERSION "1.1.6d" #include #include @@ -75,13 +75,13 @@ void custom_crash_callback(struct rst_info *, uint32_t, uint32_t); #define COLOR_CYAN "\x1B[0;36m" #define COLOR_WHITE "\x1B[0;37m" #define COLOR_BOLD_ON "\x1B[1m" -#define COLOR_BOLD_OFF "\x1B[22m" // fixed by Scott Arlott +#define COLOR_BOLD_OFF "\x1B[22m" // fix by Scott Arlott to support Linux // SPIFFS #define SPIFFS_MAXSIZE 500 // https://arduinojson.org/v6/assistant/ // CRASH -#define EEPROM_ROTATE_DATA 11 // Reserved for the EEPROM_ROTATE library (3 bytes) +#define EEPROM_ROTATE_DATA 11 // Reserved for the EEPROM_ROTATE library (3 bytes) /** * Structure of the single crash data set * @@ -93,8 +93,8 @@ void custom_crash_callback(struct rst_info *, uint32_t, uint32_t); * 6. epc3 * 7. excvaddr * 8. depc - * 9. adress of stack start - * 10. adress of stack end + * 9. address of stack start + * 10. address of stack end * 11. stack trace bytes * ... */ @@ -188,6 +188,7 @@ class MyESP { void resetESP(); uint16_t getSystemLoadAverage(); int getWifiQuality(); + void showSystemStats(); private: @@ -223,6 +224,7 @@ class MyESP { char * _wifi_ssid; char * _wifi_password; bool _wifi_connected; + String getESPhostname(); // ota ota_callback_f _ota_callback; diff --git a/platformio.ini-example b/platformio.ini-example index 436020466..50f45d778 100644 --- a/platformio.ini-example +++ b/platformio.ini-example @@ -7,8 +7,8 @@ platform = espressif8266 [common] platform_def = espressif8266 platform_180 = espressif8266@1.8.0 -;platform = ${common.platform_def} -platform = ${common.platform_180} +platform = ${common.platform_def} +;platform = ${common.platform_180} flash_mode = dout diff --git a/src/ems-esp.ino b/src/ems-esp.ino index 3ef90cd38..634de71a0 100644 --- a/src/ems-esp.ino +++ b/src/ems-esp.ino @@ -251,6 +251,8 @@ void _renderBoolValue(const char * prefix, uint8_t value) { void showInfo() { // General stats from EMS bus + char buffer_type[128] = {0}; + myDebug("%sEMS-ESP System stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF); _EMS_SYS_LOGGING sysLog = ems_getLogging(); if (sysLog == EMS_SYS_LOGGING_BASIC) { @@ -263,9 +265,7 @@ void showInfo() { myDebug(" System logging set to None"); } - myDebug(" LED is %s", EMSESP_Status.led_enabled ? "on" : "off"); - myDebug(" Test Mode is %s", EMSESP_Status.test_mode ? "on" : "off"); - + myDebug(" LED is %s, Test Mode is %s", EMSESP_Status.led_enabled ? "on" : "off", EMSESP_Status.test_mode ? "on" : "off"); myDebug(" # connected Dallas temperature sensors=%d", EMSESP_Status.dallas_sensors); myDebug(" Thermostat is %s, Boiler is %s, Shower Timer is %s, Shower Alert is %s", @@ -286,19 +286,25 @@ void showInfo() { myDebug("%sBoiler stats:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF); // version details - char buffer_type[64]; myDebug(" Boiler type: %s", ems_getBoilerDescription(buffer_type)); // active stats if (ems_getBusConnected()) { - myDebug(" Hot tap water is %s", (EMS_Boiler.tapwaterActive ? "running" : "off")); - myDebug(" Central Heating is %s", (EMS_Boiler.heatingActive ? "active" : "off")); + if (EMS_Boiler.tapwaterActive != EMS_VALUE_INT_NOTSET) { + myDebug(" Hot tap water is %s", EMS_Boiler.tapwaterActive ? "running" : "off"); + } + + if (EMS_Boiler.heatingActive != EMS_VALUE_INT_NOTSET) { + myDebug(" Central Heating is %s", EMS_Boiler.heatingActive ? "active" : "off"); + } } // UBAParameterWW _renderBoolValue("Warm Water activated", EMS_Boiler.wWActivated); _renderBoolValue("Warm Water circulation pump available", EMS_Boiler.wWCircPump); - myDebug(" Warm Water is set to %s", (EMS_Boiler.wWComfort ? "Comfort" : "ECO")); + if (EMS_Boiler.wWComfort != EMS_VALUE_INT_NOTSET) { + myDebug(" Warm Water is set to %s", (EMS_Boiler.wWComfort ? "Comfort" : "ECO")); + } _renderIntValue("Warm Water selected temperature", "C", EMS_Boiler.wWSelTemp); _renderIntValue("Warm Water desired temperature", "C", EMS_Boiler.wWDesiredTemp); @@ -392,9 +398,9 @@ void showInfo() { // Dallas if (EMSESP_Status.dallas_sensors != 0) { + char s[80] = {0}; myDebug("%sExternal temperature sensors:%s", COLOR_BOLD_ON, COLOR_BOLD_OFF); - for (uint8_t i = 0; i < EMSESP_Status.dallas_sensors; i++) { - char s[80] = {0}; + for (uint8_t i = 0; i < EMSESP_Status.dallas_sensors; i++) { snprintf(s, sizeof(s), "Sensor #%d", i + 1); _renderFloatValue(s, "C", ds18.getValue(i)); } @@ -1066,7 +1072,7 @@ void showerCheck() { // if already in cold mode, ignore all this logic until we're out of the cold blast if (!EMSESP_Shower.doingColdShot) { // is the hot water running? - if (EMS_Boiler.tapwaterActive) { + if (EMS_Boiler.tapwaterActive == 1) { // if heater was previously off, start the timer if (EMSESP_Shower.timerStart == 0) { // hot water just started... @@ -1209,4 +1215,6 @@ void loop() { if (EMSESP_Status.shower_timer) { showerCheck(); } + + delay(1); // some time to WiFi and everything else to catch up } diff --git a/src/ems.cpp b/src/ems.cpp index 8818010f7..8d7d93f74 100644 --- a/src/ems.cpp +++ b/src/ems.cpp @@ -872,11 +872,15 @@ void _processType(uint8_t * telegram, uint8_t length) { * using a quick hack for checking the heating. Selected Flow Temp >= 70 */ void _checkActive() { - // hot tap water, using flow to check insread of the burner power - EMS_Boiler.tapwaterActive = ((EMS_Boiler.wWCurFlow != 0) && (EMS_Boiler.burnGas == EMS_VALUE_INT_ON)); + // hot tap water, using flow to check instead of the burner power + if (EMS_Boiler.wWCurFlow != EMS_VALUE_INT_NOTSET && EMS_Boiler.burnGas != EMS_VALUE_INT_NOTSET) { + EMS_Boiler.tapwaterActive = ((EMS_Boiler.wWCurFlow != 0) && (EMS_Boiler.burnGas == EMS_VALUE_INT_ON)); + } // heating - EMS_Boiler.heatingActive = ((EMS_Boiler.selFlowTemp >= EMS_BOILER_SELFLOWTEMP_HEATING) && (EMS_Boiler.burnGas == EMS_VALUE_INT_ON)); + if (EMS_Boiler.selFlowTemp != EMS_VALUE_INT_NOTSET && EMS_Boiler.burnGas != EMS_VALUE_INT_NOTSET) { + EMS_Boiler.heatingActive = ((EMS_Boiler.selFlowTemp >= EMS_BOILER_SELFLOWTEMP_HEATING) && (EMS_Boiler.burnGas == EMS_VALUE_INT_ON)); + } } /** diff --git a/src/version.h b/src/version.h index 0eed2b101..5b7e1213c 100644 --- a/src/version.h +++ b/src/version.h @@ -6,5 +6,5 @@ #pragma once #define APP_NAME "EMS-ESP" -#define APP_VERSION "1.5.7b" +#define APP_VERSION "1.5.7c" #define APP_HOSTNAME "ems-esp"