diff --git a/src/ArduinoLog.cpp b/src/ArduinoLog.cpp
new file mode 100644
index 00000000..51336c61
--- /dev/null
+++ b/src/ArduinoLog.cpp
@@ -0,0 +1,166 @@
+/*
+ _ ___ ___ _ _ ___ _ _ ___ _ ___ ___
+ /_\ | _ \ \| | | |_ _| \| |/ _ \| | / _ \ / __|
+ / _ \| / |) | |_| || || .` | (_) | |_| (_) | (_ |
+ /_/ \_\_|_\___/ \___/|___|_|\_|\___/|____\___/ \___|
+
+ Log library for Arduino
+ version 1.0.3
+ https://github.com/thijse/Arduino-Log
+
+Licensed under the MIT License .
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#include "ArduinoLog.h"
+
+void Logging::begin(int level, Print * logOutput, bool showLevel)
+{
+#ifndef DISABLE_LOGGING
+ setLevel(level);
+ setShowLevel(showLevel);
+ _logOutput = logOutput;
+#endif
+}
+
+void Logging::setLevel(int level)
+{
+#ifndef DISABLE_LOGGING
+ _level = constrain(level, LOG_LEVEL_SILENT, LOG_LEVEL_VERBOSE);
+#endif
+}
+
+int Logging::getLevel() const
+{
+#ifndef DISABLE_LOGGING
+ return _level;
+#else
+ return 0;
+#endif
+}
+
+void Logging::setShowLevel(bool showLevel)
+{
+#ifndef DISABLE_LOGGING
+ _showLevel = showLevel;
+#endif
+}
+
+bool Logging::getShowLevel() const
+{
+#ifndef DISABLE_LOGGING
+ return _showLevel;
+#else
+ return false;
+#endif
+}
+
+void Logging::setPrefix(printfunction f)
+{
+#ifndef DISABLE_LOGGING
+ _prefix = f;
+#endif
+}
+
+void Logging::setSuffix(printfunction f)
+{
+#ifndef DISABLE_LOGGING
+ _suffix = f;
+#endif
+}
+
+void Logging::print(const __FlashStringHelper * format, va_list args)
+{
+#ifndef DISABLE_LOGGING
+ PGM_P p = reinterpret_cast(format);
+ char c = pgm_read_byte(p++);
+ for(; c != 0; c = pgm_read_byte(p++)) {
+ if(c == '%') {
+ c = pgm_read_byte(p++);
+ printFormat(c, &args);
+ } else {
+ _logOutput->print(c);
+ }
+ }
+#endif
+}
+
+void Logging::print(const char * format, va_list args)
+{
+#ifndef DISABLE_LOGGING
+ for(; *format != 0; ++format) {
+ if(*format == '%') {
+ ++format;
+ printFormat(*format, &args);
+ } else {
+ _logOutput->print(*format);
+ }
+ }
+#endif
+}
+
+void Logging::printFormat(const char format, va_list * args)
+{
+#ifndef DISABLE_LOGGING
+ if(format == '%') {
+ _logOutput->print(format);
+ } else if(format == 's') {
+ register char * s = (char *)va_arg(*args, int);
+ _logOutput->print(s);
+ } else if(format == 'S') {
+ register __FlashStringHelper * s = (__FlashStringHelper *)va_arg(*args, int);
+ _logOutput->print(s);
+ } else if(format == 'd' || format == 'i') {
+ _logOutput->print(va_arg(*args, int), DEC);
+ } else if(format == 'u') {
+ _logOutput->print(va_arg(*args, unsigned int), DEC);
+ } else if(format == 'D' || format == 'F') {
+ _logOutput->print(va_arg(*args, double));
+ } else if(format == 'x') {
+ _logOutput->print(va_arg(*args, int), HEX);
+ } else if(format == 'X') {
+ _logOutput->print("0x");
+ _logOutput->print(va_arg(*args, int), HEX);
+ } else if(format == 'b') {
+ _logOutput->print(va_arg(*args, int), BIN);
+ } else if(format == 'B') {
+ _logOutput->print("0b");
+ _logOutput->print(va_arg(*args, int), BIN);
+ } else if(format == 'l') {
+ _logOutput->print(va_arg(*args, long), DEC);
+ } else if(format == 'c') {
+ _logOutput->print((char)va_arg(*args, int));
+ } else if(format == 't') {
+ if(va_arg(*args, int) == 1) {
+ _logOutput->print("T");
+ } else {
+ _logOutput->print("F");
+ }
+ } else if(format == 'T') {
+ if(va_arg(*args, int) == 1) {
+ _logOutput->print(F("true"));
+ } else {
+ _logOutput->print(F("false"));
+ }
+ }
+#endif
+}
+
+Logging Log = Logging();
diff --git a/src/ArduinoLog.h b/src/ArduinoLog.h
new file mode 100644
index 00000000..56082bea
--- /dev/null
+++ b/src/ArduinoLog.h
@@ -0,0 +1,298 @@
+/*
+ _ ___ ___ _ _ ___ _ _ ___ _ ___ ___
+ /_\ | _ \ \| | | |_ _| \| |/ _ \| | / _ \ / __|
+ / _ \| / |) | |_| || || .` | (_) | |_| (_) | (_ |
+ /_/ \_\_|_\___/ \___/|___|_|\_|\___/|____\___/ \___|
+
+ Log library for Arduino
+ version 1.0.3
+ https://github.com/thijse/Arduino-Log
+
+Licensed under the MIT License .
+
+*/
+
+#ifndef LOGGING_H
+#define LOGGING_H
+#include
+#include
+#if defined(ARDUINO) && ARDUINO >= 100
+#include "Arduino.h"
+#else
+#include "WProgram.h"
+#endif
+typedef void (*printfunction)(int level, Print *);
+
+//#include
+//#include
+// *************************************************************************
+// Uncomment line below to fully disable logging, and reduce project size
+// ************************************************************************
+//#define DISABLE_LOGGING
+
+#define LOG_LEVEL_SILENT 0
+#define LOG_LEVEL_FATAL 1
+#define LOG_LEVEL_ERROR 2
+#define LOG_LEVEL_WARNING 3
+#define LOG_LEVEL_NOTICE 4
+#define LOG_LEVEL_TRACE 5
+#define LOG_LEVEL_VERBOSE 6
+
+#define CR "\n"
+#define LOGGING_VERSION 1_0_3
+
+/**
+ * Logging is a helper class to output informations over
+ * RS232. If you know log4j or log4net, this logging class
+ * is more or less similar ;-)
+ * Different loglevels can be used to extend or reduce output
+ * All methods are able to handle any number of output parameters.
+ * All methods print out a formated string (like printf).
+ * To reduce output and program size, reduce loglevel.
+ *
+ * Output format string can contain below wildcards. Every wildcard
+ * must be start with percent sign (\%)
+ *
+ * ---- Wildcards
+ *
+ * %s replace with an string (char*)
+ * %c replace with an character
+ * %d replace with an integer value
+ * %l replace with an long value
+ * %x replace and convert integer value into hex
+ * %X like %x but combine with 0x123AB
+ * %b replace and convert integer value into binary
+ * %B like %x but combine with 0b10100011
+ * %t replace and convert boolean value into "t" or "f"
+ * %T like %t but convert into "true" or "false"
+ *
+ * ---- Loglevels
+ *
+ * 0 - LOG_LEVEL_SILENT no output
+ * 1 - LOG_LEVEL_FATAL fatal errors
+ * 2 - LOG_LEVEL_ERROR all errors
+ * 3 - LOG_LEVEL_WARNING errors and warnings
+ * 4 - LOG_LEVEL_NOTICE errors, warnings and notices
+ * 5 - LOG_LEVEL_TRACE errors, warnings, notices, traces
+ * 6 - LOG_LEVEL_VERBOSE all
+ */
+
+class Logging {
+ public:
+ /**
+ * default Constructor
+ */
+ Logging()
+#ifndef DISABLE_LOGGING
+ : _level(LOG_LEVEL_SILENT), _showLevel(true), _logOutput(NULL)
+#endif
+ {}
+
+ /**
+ * Initializing, must be called as first. Note that if you use
+ * this variant of Init, you need to initialize the baud rate
+ * yourself, if printer happens to be a serial port.
+ *
+ * \param level - logging levels <= this will be logged.
+ * \param printer - place that logging output will be sent to.
+ * \return void
+ *
+ */
+ void begin(int level, Print * output, bool showLevel = true);
+
+ /**
+ * Set the log level.
+ *
+ * \param level - The new log level.
+ * \return void
+ */
+ void setLevel(int level);
+
+ /**
+ * Get the log level.
+ *
+ * \return The current log level.
+ */
+ int getLevel() const;
+
+ /**
+ * Set whether to show the log level.
+ *
+ * \param showLevel - true if the log level should be shown for each log
+ * false otherwise.
+ * \return void
+ */
+ void setShowLevel(bool showLevel);
+
+ /**
+ * Get whether the log level is shown during logging
+ *
+ * \return true if the log level is be shown for each log
+ * false otherwise.
+ */
+ bool getShowLevel() const;
+
+ /**
+ * Sets a function to be called before each log command.
+ *
+ * \param f - The function to be called
+ * \return void
+ */
+ void setPrefix(printfunction f);
+
+ /**
+ * Sets a function to be called after each log command.
+ *
+ * \param f - The function to be called
+ * \return void
+ */
+ void setSuffix(printfunction f);
+
+ /**
+ * Output a fatal error message. Output message contains
+ * F: followed by original message
+ * Fatal error messages are printed out at
+ * loglevels >= LOG_LEVEL_FATAL
+ *
+ * \param msg format string to output
+ * \param ... any number of variables
+ * \return void
+ */
+ template void fatal(T msg, Args... args)
+ {
+#ifndef DISABLE_LOGGING
+ printLevel(LOG_LEVEL_FATAL, msg, args...);
+#endif
+ }
+
+ /**
+ * Output an error message. Output message contains
+ * E: followed by original message
+ * Error messages are printed out at
+ * loglevels >= LOG_LEVEL_ERROR
+ *
+ * \param msg format string to output
+ * \param ... any number of variables
+ * \return void
+ */
+ template void error(T msg, Args... args)
+ {
+#ifndef DISABLE_LOGGING
+ printLevel(LOG_LEVEL_ERROR, msg, args...);
+#endif
+ }
+
+ /**
+ * Output a warning message. Output message contains
+ * W: followed by original message
+ * Warning messages are printed out at
+ * loglevels >= LOG_LEVEL_WARNING
+ *
+ * \param msg format string to output
+ * \param ... any number of variables
+ * \return void
+ */
+ template void warning(T msg, Args... args)
+ {
+#ifndef DISABLE_LOGGING
+ printLevel(LOG_LEVEL_WARNING, msg, args...);
+#endif
+ }
+
+ /**
+ * Output a notice message. Output message contains
+ * N: followed by original message
+ * Notice messages are printed out at
+ * loglevels >= LOG_LEVEL_NOTICE
+ *
+ * \param msg format string to output
+ * \param ... any number of variables
+ * \return void
+ */
+ template void notice(T msg, Args... args)
+ {
+#ifndef DISABLE_LOGGING
+ printLevel(LOG_LEVEL_NOTICE, msg, args...);
+#endif
+ }
+
+ /**
+ * Output a trace message. Output message contains
+ * N: followed by original message
+ * Trace messages are printed out at
+ * loglevels >= LOG_LEVEL_TRACE
+ *
+ * \param msg format string to output
+ * \param ... any number of variables
+ * \return void
+ */
+ template void trace(T msg, Args... args)
+ {
+#ifndef DISABLE_LOGGING
+ printLevel(LOG_LEVEL_TRACE, msg, args...);
+#endif
+ }
+
+ /**
+ * Output a verbose message. Output message contains
+ * V: followed by original message
+ * Debug messages are printed out at
+ * loglevels >= LOG_LEVEL_VERBOSE
+ *
+ * \param msg format string to output
+ * \param ... any number of variables
+ * \return void
+ */
+ template void verbose(T msg, Args... args)
+ {
+#ifndef DISABLE_LOGGING
+ printLevel(LOG_LEVEL_VERBOSE, msg, args...);
+#endif
+ }
+
+ private:
+ void print(const char * format, va_list args);
+
+ void print(const __FlashStringHelper * format, va_list args);
+
+ void printFormat(const char format, va_list * args);
+
+ template void printLevel(int level, T msg, ...)
+ {
+#ifndef DISABLE_LOGGING
+ if(level > _level) {
+ return;
+ }
+
+ if(_prefix != NULL) {
+ _prefix(level, _logOutput);
+ }
+
+ if(_showLevel) {
+ static const char levels[] = "FEWNTV";
+ _logOutput->print(levels[level - 1]);
+ _logOutput->print(": ");
+ }
+
+ va_list args;
+ va_start(args, msg);
+ print(msg, args);
+
+ if(_suffix != NULL) {
+ _suffix(level, _logOutput);
+ }
+#endif
+ }
+
+#ifndef DISABLE_LOGGING
+ int _level;
+ bool _showLevel;
+ Print * _logOutput;
+
+ printfunction _prefix = NULL;
+ printfunction _suffix = NULL;
+#endif
+};
+
+extern Logging Log;
+#endif
\ No newline at end of file
diff --git a/src/hasp_config.cpp b/src/hasp_config.cpp
index 7d283ce8..5828fb97 100644
--- a/src/hasp_config.cpp
+++ b/src/hasp_config.cpp
@@ -1,5 +1,6 @@
#include "Arduino.h"
#include "ArduinoJson.h"
+#include "ArduinoLog.h"
#include // Include the SPIFFS library
#if defined(ARDUINO_ARCH_ESP32)
@@ -7,24 +8,28 @@
#endif
#include "hasp_config.h"
-#include "hasp_log.h"
+//#include "hasp_log.h"
#include "hasp_debug.h"
#include "hasp_http.h"
-#include "hasp_mqtt.h"
#include "hasp_wifi.h"
#include "hasp_mdns.h"
#include "hasp_gui.h"
-// #include "hasp_tft.h"
#include "hasp_ota.h"
#include "hasp_spiffs.h"
#include "hasp_telnet.h"
#include "hasp.h"
+#include "hasp_conf.h"
+#if HASP_USE_MQTT
+#include "hasp_mqtt.h"
+#endif
+
void confDebugSet(const char * name)
{
- char buffer[128];
+ /*char buffer[128];
snprintf(buffer, sizeof(buffer), PSTR("CONF: * %s set"), name);
- debugPrintln(buffer);
+ debugPrintln(buffer);*/
+ Log.trace(F("CONF: * %s set"), name);
}
bool configSet(int8_t & value, const JsonVariant & setting, const char * name)
@@ -64,26 +69,14 @@ bool configSet(uint16_t & value, const JsonVariant & setting, const char * name)
return false;
}
-bool configChanged()
-{
- return false;
-}
-
-void configLoop()
-{
- if(configChanged()) {
- // configSetConfig();
- }
-}
-
void configStartDebug(bool setupdebug, String & configFile)
{
if(setupdebug) {
debugStart(); // Debug started, now we can use it; HASP header sent
- debugPrintln(F("FILE: [SUCCESS] SPI flash FS mounted"));
+ Log.notice(F("FILE: [SUCCESS] SPI flash FS mounted"));
spiffsList();
}
- debugPrintln(String(F("CONF: Loading ")) + configFile);
+ Log.notice(F("CONF: Loading %s"), configFile.c_str());
}
void configGetConfig(JsonDocument & settings, bool setupdebug = false)
@@ -96,7 +89,7 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false)
if(file) {
size_t size = file.size();
if(size > 1024) {
- errorPrintln(F("CONF: %sConfig file size is too large"));
+ Log.error(F("CONF: Config file size is too large"));
return;
}
@@ -105,7 +98,9 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false)
file.close();
/* Load Debug params */
- debugPreSetup(settings[F("debug")]);
+ if(setupdebug) {
+ debugPreSetup(settings[F("debug")]);
+ }
configStartDebug(setupdebug, configFile);
// show settings in log
@@ -115,16 +110,16 @@ void configGetConfig(JsonDocument & settings, bool setupdebug = false)
output.replace(settings[F("http")][F("pass")].as(), passmask);
output.replace(settings[F("mqtt")][F("pass")].as(), passmask);
output.replace(settings[F("wifi")][F("pass")].as(), passmask);
- debugPrintln(String(F("CONF: ")) + output);
+ Log.verbose(F("CONF: %s"), output.c_str());
+ Log.notice(F("CONF: [SUCCESS] Loaded %s"), configFile.c_str());
- debugPrintln(String(F("CONF: [SUCCESS] Loaded ")) + configFile);
- debugSetup(settings[F("debug")]);
+ if(setupdebug) debugSetup(settings[F("debug")]);
return;
}
}
configStartDebug(setupdebug, configFile);
- errorPrintln(String(F("CONF: %sFailed to load ")) + configFile);
+ Log.error(F("CONF: Failed to load %s"), configFile.c_str());
}
void configWriteConfig()
@@ -134,62 +129,56 @@ void configWriteConfig()
configFile = String(FPSTR(HASP_CONFIG_FILE));
/* Read Config File */
- DynamicJsonDocument settings(2 * 1024);
- debugPrintln(String(F("CONF: Config LOADING first ")) + configFile);
+ DynamicJsonDocument settings(1024 * 2);
+ Log.notice(F("CONF: Config LOADING first %s"), configFile.c_str());
configGetConfig(settings, false);
- debugPrintln(String(F("CONF: Config LOADED first ")) + configFile);
+ Log.trace(F("CONF: Config LOADED first %s"), configFile.c_str());
bool changed = true;
#if HASP_USE_WIFI
changed |= wifiGetConfig(settings[F("wifi")].to());
-
#if HASP_USE_MQTT
changed |= mqttGetConfig(settings[F("mqtt")].to());
#endif
-
#if HASP_USE_TELNET
changed |= telnetGetConfig(settings[F("telnet")].to());
#endif
-
#if HASP_USE_MDNS
changed |= mdnsGetConfig(settings[F("mdns")].to());
#endif
-
#if HASP_USE_HTTP
changed |= httpGetConfig(settings[F("http")].to());
#endif
-
#endif
changed |= debugGetConfig(settings[F("debug")].to());
changed |= guiGetConfig(settings[F("gui")].to());
changed |= haspGetConfig(settings[F("hasp")].to());
// changed |= otaGetConfig(settings[F("ota")].to());
- // changed |= tftGetConfig(settings[F("tft")].to());
if(changed) {
File file = SPIFFS.open(configFile, "w");
if(file) {
- debugPrintln(String(F("CONF: Writing ")) + configFile);
+ Log.notice(F("CONF: Writing %s"), configFile.c_str());
size_t size = serializeJson(settings, file);
file.close();
if(size > 0) {
- debugPrintln(String(F("CONF: [SUCCESS] Saved ")) + configFile);
+ Log.verbose(F("CONF: [SUCCESS] Saved %s"), configFile.c_str());
return;
}
}
- errorPrintln(String(F("CONF: %sFailed to write ")) + configFile);
+ Log.error(F("CONF: Failed to write %s"), configFile.c_str());
} else {
- debugPrintln(F("CONF: Configuration was not changed"));
+ Log.verbose(F("CONF: Configuration was not changed"));
}
}
void configSetup(JsonDocument & settings)
{
if(!SPIFFS.begin()) {
- errorPrintln(F("FILE: %sSPI flash init failed. Unable to mount FS."));
+ Log.error(F("FILE: SPI flash init failed. Unable to mount FS."));
} else {
configGetConfig(settings, true);
}
@@ -212,5 +201,5 @@ void configOutput(const JsonObject & settings)
password += F("\"");
if(password.length() > 2) output.replace(password, passmask);
- debugPrintln(String(F("CONF: ")) + output);
+ Log.trace(F("CONF: %s"), output.c_str());
}
\ No newline at end of file
diff --git a/src/hasp_debug.cpp b/src/hasp_debug.cpp
index 6a2537b2..2350bbc2 100644
--- a/src/hasp_debug.cpp
+++ b/src/hasp_debug.cpp
@@ -3,6 +3,8 @@
#include "ArduinoJson.h"
#include "lvgl.h"
+#include "ArduinoLog.h"
+
#if defined(ARDUINO_ARCH_ESP8266)
#include
#else
@@ -12,20 +14,22 @@
#include "hasp_log.h"
#include "hasp_hal.h"
+#include "hasp_mqtt.h"
#include "hasp_debug.h"
#include "hasp_config.h"
#include "hasp_dispatch.h"
-#if HASP_USE_TELNET != 0
-#include "hasp_telnet.h"
-#endif
-
#ifdef USE_CONFIG_OVERRIDE
#include "user_config_override.h"
#endif
#if HASP_USE_SYSLOG != 0
-#include
+#include "Syslog.h"
+
+#if HASP_USE_TELNET != 0
+#include "hasp_telnet.h"
+//#include "hasp_telnet.cpp"
+#endif
#ifndef SYSLOG_SERVER
#define SYSLOG_SERVER ""
@@ -37,9 +41,29 @@
#define APP_NAME "HASP"
#endif
-std::string debugAppName = APP_NAME;
-std::string debugSyslogHost = SYSLOG_SERVER;
+//#define TERM_COLOR_Black "\u001b[30m"
+#define TERM_COLOR_GRAY "\e[37m"
+#define TERM_COLOR_RED "\e[91m"
+#define TERM_COLOR_GREEN "\e[92m"
+#define TERM_COLOR_YELLOW "\e[93m"
+#define TERM_COLOR_BLUE "\e[94m"
+#define TERM_COLOR_MAGENTA "\e[35m"
+#define TERM_COLOR_CYAN "\e[96m"
+#define TERM_COLOR_WHITE "\e[97m"
+#define TERM_COLOR_RESET "\e[0m"
+
+// unsigned char TERM_COLOR_CYAN[] = {27, '[', '3', '6', 'm'};
+// unsigned char TERM_COLOR_RESET[] = {27, '[', '0', 'm'};
+
+const char * syslogAppName = APP_NAME;
+char debugSyslogHost[32] = SYSLOG_SERVER;
uint16_t debugSyslogPort = SYSLOG_PORT;
+uint8_t debugSyslogFacility = 0;
+uint8_t debugSyslogProtocol = 0;
+uint16_t debugSerialBaud = 11520; // Multiplied by 10
+bool debugSerialStarted = false;
+
+extern char mqttNodeName[16];
// A UDP instance to let us send and receive packets over UDP
WiFiUDP syslogClient;
@@ -47,8 +71,7 @@ WiFiUDP syslogClient;
// Create a new syslog instance with LOG_KERN facility
// Syslog syslog(syslogClient, SYSLOG_SERVER, SYSLOG_PORT, MQTT_CLIENT, APP_NAME, LOG_KERN);
// Create a new empty syslog instance
-Syslog syslog(syslogClient, debugSyslogHost.c_str(), debugSyslogPort, debugAppName.c_str(), debugAppName.c_str(),
- LOG_LOCAL0);
+Syslog * syslog;
#endif
unsigned long debugLastMillis = 0;
@@ -72,133 +95,226 @@ String debugHaspHeader()
void debugStart()
{
-#if defined(ARDUINO_ARCH_ESP32)
- Serial.begin(115200); /* prepare for possible serial debug */
-#else
- Serial.begin(74880); /* prepare for possible serial debug */
-#endif
-
- Serial.flush();
- Serial.println();
- Serial.println(debugHaspHeader());
- Serial.flush();
+ if(debugSerialStarted) {
+ Serial.flush();
+ Serial.println();
+ Serial.println(debugHaspHeader());
+ Serial.flush();
+ }
// prepare syslog configuration here (can be anywhere before first call of
// log/logf method)
-
-#if HASP_USE_SYSLOG != 0
- syslog.server(debugSyslogHost.c_str(), debugSyslogPort);
- syslog.deviceHostname(debugAppName.c_str());
- syslog.appName(debugAppName.c_str());
- syslog.defaultPriority(LOG_LOCAL0);
-#endif
}
-void serialPrintln(const char * debugText)
+void serialPrintln(const char * debugText, uint8_t level)
{
+ /*
String debugTimeText((char *)0);
debugTimeText.reserve(128);
- debugTimeText = F("[");
+ uint8_t heapfrag = halGetHeapFragmentation();
+ debugTimeText = F("[");
debugTimeText += String(float(millis()) / 1000, 3);
debugTimeText += F("s] ");
debugTimeText += halGetMaxFreeBlock();
debugTimeText += F("/");
debugTimeText += ESP.getFreeHeap();
debugTimeText += F(" ");
- debugTimeText += halGetHeapFragmentation();
+ if(heapfrag < 10) debugTimeText += F(" ");
+ debugTimeText += heapfrag;
debugTimeText += F(" ");
#if LV_MEM_CUSTOM == 0
- /*lv_mem_monitor_t mem_mon;
+ lv_mem_monitor_t mem_mon;
lv_mem_monitor(&mem_mon);
+ debugTimeText += F("| ");
debugTimeText += mem_mon.used_pct;
debugTimeText += F("% ");
debugTimeText += mem_mon.free_biggest_size;
debugTimeText += F("b/");
debugTimeText += mem_mon.free_size;
- debugTimeText += F("b ");*/
+ debugTimeText += F("b ");
+ debugTimeText += (mem_mon.total_size - mem_mon.free_size);
+ debugTimeText += F("b | ");
#endif
- Serial.print(debugTimeText);
- Serial.println(debugText);
+ if(debugSerialStarted) {
+ // Serial.print(debugTimeText);
+ // Serial.println(debugText);
+ }*/
+
+ switch(level) {
+ case LOG_LEVEL_FATAL:
+ Log.fatal(debugText);
+ break;
+ case LOG_LEVEL_ERROR:
+ Log.error(debugText);
+ break;
+ case LOG_LEVEL_WARNING:
+ Log.warning(debugText);
+ break;
+ case LOG_LEVEL_VERBOSE:
+ Log.verbose(debugText);
+ break;
+ case LOG_LEVEL_TRACE:
+ Log.trace(debugText);
+ break;
+ default:
+ Log.notice(debugText);
+ }
#if HASP_USE_TELNET != 0
- telnetPrint(debugTimeText.c_str());
+ // telnetPrint(debugTimeText.c_str());
telnetPrintln(debugText);
#endif
}
-void serialPrintln(String & debugText)
+void serialPrintln(String & debugText, uint8_t level)
{
- serialPrintln(debugText.c_str());
+ serialPrintln(debugText.c_str(), level);
}
#if HASP_USE_SYSLOG != 0
-void syslogSend(uint8_t log, const char * debugText)
+void syslogSend(uint8_t priority, const char * debugText)
{
- if(WiFi.isConnected() && debugSyslogHost != "") {
- switch(log) {
- case 1:
- syslog.log(LOG_WARNING, debugText);
- break;
- case 2:
- syslog.log(LOG_ERR, debugText);
- break;
- default:
- syslog.log(LOG_INFO, debugText);
- }
+ if(strlen(debugSyslogHost) != 0 && WiFi.isConnected()) {
+ syslog->log(priority, debugText);
}
}
#endif
+void debugSetup(JsonObject settings)
+{
+ debugSetConfig(settings);
+
+#if HASP_USE_SYSLOG != 0
+ syslog = new Syslog(syslogClient, debugSyslogProtocol == 0 ? SYSLOG_PROTO_IETF : SYSLOG_PROTO_BSD);
+ syslog->server(debugSyslogHost, debugSyslogPort);
+ syslog->deviceHostname(mqttNodeName);
+ syslog->appName(syslogAppName);
+ uint16_t priority = (uint16_t)(debugSyslogFacility + 16) << 3; // localx facility, x = 0-7
+ syslog->defaultPriority(priority);
+#endif
+}
+
void debugStop()
{
- Serial.flush();
+ if(debugSerialStarted) Serial.flush();
}
bool debugGetConfig(const JsonObject & settings)
{
+ settings[FPSTR(F_CONFIG_BAUD)] = debugSerialBaud;
settings[FPSTR(F_DEBUG_TELEPERIOD)] = debugTelePeriod;
+#if HASP_USE_SYSLOG != 0
+ settings[FPSTR(F_CONFIG_HOST)] = debugSyslogHost;
+ settings[FPSTR(F_CONFIG_PORT)] = debugSyslogPort;
+ settings[FPSTR(F_CONFIG_PROTOCOL)] = debugSyslogProtocol;
+ settings[FPSTR(F_CONFIG_LOG)] = debugSyslogFacility;
+#endif
+
configOutput(settings);
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-bool debugSetConfigLog(const JsonObject & settings, bool silent)
+bool debugSetConfig(const JsonObject & settings)
{
- if(!silent) configOutput(settings);
+ configOutput(settings);
bool changed = false;
- if(!settings[FPSTR(F_DEBUG_TELEPERIOD)].isNull()) {
- uint16_t period = settings[FPSTR(F_DEBUG_TELEPERIOD)].as();
- if(debugTelePeriod != period) {
- if(!silent) debugPrintln(F("debugTelePeriod set"));
- debugTelePeriod = period;
- changed = true;
- }
+ /* Serial Settings*/
+ changed |= configSet(debugSerialBaud, settings[FPSTR(F_CONFIG_BAUD)], PSTR("debugSerialBaud"));
+
+ /* Teleperiod Settings*/
+ changed |= configSet(debugTelePeriod, settings[FPSTR(F_DEBUG_TELEPERIOD)], PSTR("debugTelePeriod"));
+
+ /* Syslog Settings*/
+#if HASP_USE_SYSLOG != 0
+ if(!settings[FPSTR(F_CONFIG_HOST)].isNull()) {
+ changed |= strcmp(debugSyslogHost, settings[FPSTR(F_CONFIG_HOST)]) != 0;
+ strncpy(debugSyslogHost, settings[FPSTR(F_CONFIG_HOST)], sizeof(debugSyslogHost));
}
+ changed |= configSet(debugSyslogPort, settings[FPSTR(F_CONFIG_PORT)], PSTR("debugSyslogPort"));
+ changed |= configSet(debugSyslogProtocol, settings[FPSTR(F_CONFIG_PROTOCOL)], PSTR("debugSyslogProtocol"));
+ changed |= configSet(debugSyslogFacility, settings[FPSTR(F_CONFIG_LOG)], PSTR("debugSyslogFacility"));
+#endif
return changed;
}
-bool debugSetConfig(const JsonObject & settings)
+void printTimestamp(int level, Print * _logOutput)
{
- return debugSetConfigLog(settings, false);
+ char c[128];
+ int m = snprintf(c, sizeof(c), PSTR("[%10.3fs] %5u/%5u %2u | "), float(millis()) / 1000, halGetMaxFreeBlock(),
+ ESP.getFreeHeap(), halGetHeapFragmentation());
+
+#if LV_MEM_CUSTOM == 0
+ /* lv_mem_monitor_t mem_mon;
+ lv_mem_monitor(&mem_mon);
+ debugTimeText += F("| ");
+ debugTimeText += mem_mon.used_pct;
+ debugTimeText += F("% ");
+ debugTimeText += mem_mon.free_biggest_size;
+ debugTimeText += F("b/");
+ debugTimeText += mem_mon.free_size;
+ debugTimeText += F("b ");
+ debugTimeText += (mem_mon.total_size - mem_mon.free_size);
+ debugTimeText += F("b | ");*/
+#endif
+
+ _logOutput->print(TERM_COLOR_CYAN);
+ _logOutput->print(c);
+ switch(level) {
+ case LOG_LEVEL_FATAL:
+ case LOG_LEVEL_ERROR:
+ _logOutput->print(TERM_COLOR_RED);
+ break;
+ case LOG_LEVEL_WARNING:
+ _logOutput->print(TERM_COLOR_YELLOW);
+ break;
+ case LOG_LEVEL_NOTICE:
+ _logOutput->print(TERM_COLOR_WHITE);
+ break;
+ case LOG_LEVEL_VERBOSE:
+ _logOutput->print(TERM_COLOR_CYAN);
+ break;
+ case LOG_LEVEL_TRACE:
+ _logOutput->print(TERM_COLOR_GRAY);
+ break;
+ default:
+ _logOutput->print(TERM_COLOR_RESET);
+ }
+}
+
+void printNewline(int level, Print * _logOutput)
+{
+ _logOutput->print(TERM_COLOR_MAGENTA);
+ _logOutput->print("\r\n");
}
void debugPreSetup(JsonObject settings)
{
- debugSetConfigLog(settings, true);
-}
-void debugSetup(JsonObject settings)
-{
- debugSetConfigLog(settings, false);
+ Log.begin(LOG_LEVEL_VERBOSE, &Serial, true);
+ Log.setPrefix(printTimestamp); // Uncomment to get timestamps as prefix
+ Log.setSuffix(printNewline); // Uncomment to get newline as suffix
+
+ uint16_t baudrate = settings[FPSTR(F_CONFIG_BAUD)].as();
+ if(baudrate > 0) {
+ Serial.begin(baudrate * 10); /* prepare for possible serial debug */
+ debugSerialStarted = true;
+ }
+
+ // Serial.begin(74880); /* prepare for possible serial debug */
+ // Serial.begin(115200);
}
void debugLoop()
+{}
+
+void debugEverySecond()
{
if(debugTelePeriod > 0 && (millis() - debugLastMillis) >= debugTelePeriod * 1000) {
dispatchStatusUpdate();
diff --git a/src/hasp_debug.h b/src/hasp_debug.h
index 5bc288db..262c0666 100644
--- a/src/hasp_debug.h
+++ b/src/hasp_debug.h
@@ -8,11 +8,12 @@ String debugHaspHeader(void);
void debugPreSetup(JsonObject settings);
void debugSetup(JsonObject settings);
void debugLoop(void);
+void debugEverySecond(void);
void debugStart(void);
void debugStop(void);
-void serialPrintln(String & debugText);
-void serialPrintln(const char * debugText);
+void serialPrintln(String & debugText, uint8_t level);
+void serialPrintln(const char * debugText, uint8_t level);
void syslogSend(uint8_t log, const char * debugText);
diff --git a/src/hasp_dispatch.cpp b/src/hasp_dispatch.cpp
index 5060c0d0..57793a12 100644
--- a/src/hasp_dispatch.cpp
+++ b/src/hasp_dispatch.cpp
@@ -1,10 +1,10 @@
#include "StringStream.h"
#include "ArduinoJson.h"
+#include "ArduinoLog.h"
#include "hasp_dispatch.h"
#include "hasp_config.h"
#include "hasp_debug.h"
-#include "hasp_mqtt.h"
#include "hasp_http.h"
#include "hasp_mdns.h"
#include "hasp_wifi.h"
@@ -12,6 +12,22 @@
#include "hasp_gui.h"
#include "hasp.h"
+#include "hasp_conf.h"
+#if HASP_USE_MQTT
+#include "hasp_mqtt.h"
+#endif
+
+void dispatchPrintln(String header, String & data)
+{
+ /* String message((char *)0);
+ message.reserve(128);
+ message = header;
+ message += F(": ");
+ message += data;
+ debugPrintln(message); */
+ Log.notice(F("%s: %s"), header.c_str(), data.c_str());
+}
+
bool isON(const char * payload)
{
return strcmp_P(payload, PSTR("ON")) == 0;
@@ -33,7 +49,9 @@ void dispatchLoop()
void dispatchStatusUpdate()
{
+#if HASP_USE_MQTT
mqttStatusUpdate();
+#endif
}
void dispatchOutput(int output, bool state)
@@ -50,31 +68,44 @@ void dispatchOutput(int output, bool state)
}
}
+void dispatchOutput(String strTopic, const char * payload)
+{
+ String strTemp((char *)0);
+ strTemp.reserve(128);
+ strTemp = strTopic.substring(7, strTopic.length());
+ dispatchOutput(strTemp.toInt(), isON(payload));
+}
+
+void dispatchButtonAttribute(String & strTopic, const char * payload)
+{
+ String strPageId((char *)0);
+ String strTemp((char *)0);
+
+ strPageId = strTopic.substring(2, strTopic.indexOf("]"));
+ strTemp = strTopic.substring(strTopic.indexOf("]") + 1, strTopic.length());
+
+ if(strTemp.startsWith(".b[")) {
+ String strObjId((char *)0);
+ String strAttr((char *)0);
+
+ strObjId = strTemp.substring(3, strTemp.indexOf("]"));
+ strAttr = strTemp.substring(strTemp.indexOf("]") + 1, strTemp.length());
+ // debugPrintln(strPageId + " && " + strObjId + " && " + strAttr);
+
+ int pageid = strPageId.toInt();
+ int objid = strObjId.toInt();
+
+ if(pageid >= 0 && pageid <= 255 && objid >= 0 && objid <= 255) {
+ haspProcessAttribute((uint8_t)pageid, (uint8_t)objid, strAttr, payload);
+ } // valid page
+ }
+}
+
// objectattribute=value
void dispatchAttribute(String & strTopic, const char * payload)
{
if(strTopic.startsWith("p[")) {
- String strPageId((char *)0);
- String strTemp((char *)0);
-
- strPageId = strTopic.substring(2, strTopic.indexOf("]"));
- strTemp = strTopic.substring(strTopic.indexOf("]") + 1, strTopic.length());
-
- if(strTemp.startsWith(".b[")) {
- String strObjId((char *)0);
- String strAttr((char *)0);
-
- strObjId = strTemp.substring(3, strTemp.indexOf("]"));
- strAttr = strTemp.substring(strTemp.indexOf("]") + 1, strTemp.length());
- // debugPrintln(strPageId + " && " + strObjId + " && " + strAttr);
-
- int pageid = strPageId.toInt();
- int objid = strObjId.toInt();
-
- if(pageid >= 0 && pageid <= 255 && objid > 0 && objid <= 255) {
- haspProcessAttribute((uint8_t)pageid, (uint8_t)objid, strAttr, payload);
- } // valid page
- }
+ dispatchButtonAttribute(strTopic, payload);
} else if(strTopic.startsWith(F("output"))) {
#if defined(ARDUINO_ARCH_ESP8266)
uint8_t state = isON(payload) ? HIGH : LOW;
@@ -97,27 +128,29 @@ void dispatchAttribute(String & strTopic, const char * payload)
haspDisplayAP(String(F("HASP-ABC123")).c_str(), String(F("haspadmin")).c_str());
} else if(strTopic.length() == 7 && strTopic.startsWith(F("output"))) {
- String strTemp((char *)0);
- strTemp = strTopic.substring(7, strTopic.length());
- dispatchOutput(strTemp.toInt(), true);
+ dispatchOutput(strTopic, payload);
}
}
void dispatchPage(String strPageid)
{
- debugPrintln("PAGE: " + strPageid);
+ dispatchPrintln(F("PAGE"), strPageid);
if(strPageid.length() == 0) {
} else {
if(strPageid.toInt() <= 250) haspSetPage(strPageid.toInt());
}
- String strPayload = String(haspGetPage());
- mqttSendState("page", strPayload.c_str());
+ String strPage((char *)0);
+ strPage.reserve(128);
+ strPage = haspGetPage();
+#if HASP_USE_MQTT
+ mqttSendState("page", strPage.c_str());
+#endif
}
void dispatchClearPage(String strPageid)
{
- debugPrintln("Clear Page: " + strPageid);
+ dispatchPrintln(F("CLEAR"), strPageid);
if(strPageid.length() == 0) {
haspClearPage(haspGetPage());
@@ -130,30 +163,33 @@ void dispatchDim(String strDimLevel)
{
// Set the current state
if(strDimLevel.length() != 0) guiSetDim(strDimLevel.toInt());
- debugPrintln("DIM: " + strDimLevel);
+ dispatchPrintln(F("DIM"), strDimLevel);
// Return the current state
String strPayload = String(guiGetDim());
+#if HASP_USE_MQTT
mqttSendState("dim", strPayload.c_str());
+#endif
}
void dispatchBacklight(String strPayload)
{
strPayload.toUpperCase();
- debugPrintln("LIGHT: " + strPayload);
+ dispatchPrintln(F("LIGHT"), strPayload);
// Set the current state
if(strPayload.length() != 0) guiSetBacklight(isON(strPayload.c_str()));
// Return the current state
strPayload = getOnOff(guiGetBacklight());
+#if HASP_USE_MQTT
mqttSendState("light", strPayload.c_str());
+#endif
}
void dispatchCommand(String cmnd)
{
- // cmnd.toLowerCase();
- debugPrintln("CMND: " + cmnd);
+ dispatchPrintln(F("CMND"), cmnd);
if(cmnd.startsWith(F("page "))) {
cmnd = cmnd.substring(5, cmnd.length());
@@ -236,18 +272,24 @@ void dispatchJsonl(char * strPayload)
void dispatchIdle(const __FlashStringHelper * state)
{
+#if HASP_USE_MQTT
mqttSendState(String(F("idle")).c_str(), String(state).c_str());
+#endif
}
void dispatchReboot(bool saveConfig)
{
if(saveConfig) configWriteConfig();
+#if HASP_USE_MQTT
mqttStop(); // Stop the MQTT Client first
+#endif
debugStop();
delay(250);
wifiStop();
- debugPrintln(F("STOP: Properly Rebooting the MCU now!"));
- debugPrintln(F("-------------------------------------"));
+ // debugPrintln(F("STOP: Properly Rebooting the MCU now!"));
+ // debugPrintln(F("-------------------------------------"));
+ Log.notice(F("STOP: Properly Rebooting the MCU now!"));
+ Log.verbose(F("-------------------------------------"));
ESP.restart();
delay(5000);
}
@@ -256,5 +298,7 @@ void dispatchButton(uint8_t id, char * event)
{
char buffer[128];
snprintf_P(buffer, sizeof(buffer), PSTR("INPUT%d"), id);
+#if HASP_USE_MQTT
mqttSendState(buffer, event);
+#endif
}
\ No newline at end of file
diff --git a/src/hasp_gui.h b/src/hasp_gui.h
index d40bc61a..c0289f3f 100644
--- a/src/hasp_gui.h
+++ b/src/hasp_gui.h
@@ -16,7 +16,7 @@ void guiTakeScreenshot(ESP8266WebServer & client);
void guiTakeScreenshot(WebServer & client);
#endif // ESP32
-void guiSetup(TFT_eSPI & screen, JsonObject settings);
+void guiSetup(JsonObject settings);
void guiLoop(void);
void guiStop(void);
diff --git a/src/hasp_http.cpp b/src/hasp_http.cpp
index 73618c78..62d9aaf9 100644
--- a/src/hasp_http.cpp
+++ b/src/hasp_http.cpp
@@ -1,4 +1,5 @@
-//#include "webServer.h"
+#if 0
+
#include "Arduino.h"
#include "ArduinoJson.h"
//#include "Update.h"
@@ -18,12 +19,449 @@
#include "hasp_dispatch.h"
#include "hasp.h"
+#ifdef ESP32
+#include
+#include
+#elif defined(ESP8266)
+#include
+#include
+#endif
+#include
+
+AsyncWebServer webServer(80);
+
#if defined(ARDUINO_ARCH_ESP32)
#include "SPIFFS.h"
#endif
#include
#include
+bool httpEnable = true;
+bool webServerStarted = false;
+uint16_t httpPort = 80;
+FS * filesystem = &SPIFFS;
+File fsUploadFile;
+char httpUser[32] = "";
+char httpPassword[32] = "";
+// HTTPUpload * upload;
+#define HTTP_PAGE_SIZE (6 * 256)
+
+const char MAIN_MENU_BUTTON[] PROGMEM =
+ "
";
+const char MIT_LICENSE[] PROGMEM = "MIT License";
+
+const char HTTP_DOCTYPE[] PROGMEM =
+ "";
+const char HTTP_META_GO_BACK[] PROGMEM = "";
+const char HTTP_HEADER[] PROGMEM = "%s";
+const char HTTP_STYLE[] PROGMEM =
+ "";
+const char HTTP_SCRIPT[] PROGMEM = "";
+const char HTTP_HEADER_END[] PROGMEM =
+ "";
+
+// Additional CSS style to match Hass theme
+const char HASP_STYLE[] PROGMEM =
+ "";
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// URL for auto-update "version.json"
+const char UPDATE_URL[] PROGMEM = "http://haswitchplate.com/update/version.json";
+// Default link to compiled Arduino firmware image
+String espFirmwareUrl = "http://haswitchplate.com/update/HASwitchPlate.ino.d1_mini.bin";
+// Default link to compiled Nextion firmware images
+String lcdFirmwareUrl = "http://haswitchplate.com/update/HASwitchPlate.tft";
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+String getOption(int value, String label, bool selected)
+{
+ char buffer[128];
+ snprintf_P(buffer, sizeof(buffer), PSTR("
"), value,
+ (selected ? PSTR(" selected") : ""), label.c_str());
+ return buffer;
+}
+String getOption(String value, String label, bool selected)
+{
+ char buffer[128];
+ snprintf_P(buffer, sizeof(buffer), PSTR("
"), value.c_str(),
+ (selected ? PSTR(" selected") : ""), label.c_str());
+ return buffer;
+}
+
+bool httpIsAuthenticated(AsyncWebServerRequest * request, const String & page)
+{
+ if(httpPassword[0] != '\0') { // Request HTTP auth if httpPassword is set
+ if(!request->authenticate(httpUser, httpPassword)) {
+ request->requestAuthentication();
+ return false;
+ }
+ }
+
+ char buffer[128];
+ snprintf(buffer, sizeof(buffer), PSTR("HTTP: Sending %s page to client connected from: %s"), page.c_str(),
+ request->client()->remoteIP().toString().c_str());
+ debugPrintln(buffer);
+ return true;
+}
+
+void webSendFooter(AsyncResponseStream * response)
+{
+ response->print(F("
"));
+}
+
+void webHandleRoot(AsyncWebServerRequest * request)
+{
+ if(!httpIsAuthenticated(request, F("root"))) return;
+ AsyncResponseStream * response = request->beginResponseStream("text/html");
+
+ String nodename((char *)0);
+ nodename.reserve(128);
+ nodename = httpGetNodename();
+
+ response->print(F("
"));
+ response->print(nodename);
+ response->print(F("
"));
+
+ response->print(F("
"));
+ response->print(
+ F("
"));
+ response->print(F("
"));
+
+ response->print(
+ F("
"));
+
+ if(SPIFFS.exists(F("/edit.htm.gz"))) {
+ response->print(F("
"));
+ }
+
+ response->print(
+ F("
"));
+
+ webSendFooter(response);
+ request->send(response);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void webHandleHaspConfig(AsyncWebServerRequest * request)
+{ // http://plate01/config/http
+ if(!httpIsAuthenticated(request, F("config/hasp"))) return;
+ AsyncResponseStream * response = request->beginResponseStream("text/html");
+
+ DynamicJsonDocument settings(256);
+ haspGetConfig(settings.to
());
+
+ String nodename((char *)0);
+ nodename.reserve(128);
+ nodename = httpGetNodename();
+
+ response->print(F(""));
+ response->print(nodename);
+ response->print(F("
"));
+
+ response->print(F("
"));
+
+ response->print(F(""));
+
+ response->print(
+ F(""));
+
+ webSendFooter(response);
+ request->send(response);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void webHandleScreenshot(AsyncWebServerRequest * request)
+{ // http://plate01/screenshot
+ if(!httpIsAuthenticated(request, F("screenshot"))) return;
+
+ if(request->hasArg(F("q"))) {
+ guiTakeScreenshot(request);
+ } else {
+ AsyncResponseStream * response = request->beginResponseStream("text/html");
+
+ String nodename((char *)0);
+ nodename.reserve(128);
+ nodename = httpGetNodename();
+
+ response->print(F(""));
+ response->print(nodename);
+ response->print(F("
"));
+
+ response->print(F("
"));
+ response->print(F(""));
+ // response->print( FPSTR(MAIN_MENU_BUTTON);
+
+ webSendFooter(response);
+ request->send(response);
+ }
+}
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void httpHandleNotFound(AsyncWebServerRequest * request)
+{ // webServer 404
+ // if(handleFileRead(webServer.uri())) return;
+
+ debugPrintln(String(F("HTTP: Sending 404 to client connected from: ")) + request->client()->remoteIP().toString());
+
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+
+ httpMessage += F("File Not Found\n\nURI: ");
+ httpMessage += request->url();
+ httpMessage += F("\nMethod: ");
+ httpMessage += (request->method() == HTTP_GET) ? F("GET") : F("POST");
+ httpMessage += F("\nArguments: ");
+ httpMessage += request->args();
+ httpMessage += "\n";
+ for(uint8_t i = 0; i < request->args(); i++) {
+ httpMessage += " " + request->argName(i) + ": " + request->arg(i) + "\n";
+ }
+ request->send(404, F("text/plain"), httpMessage);
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void webHandleSaveConfig()
+{
+ // if(!httpIsAuthenticated(F("saveConfig"))) return;
+
+ configWriteConfig();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void webHandleFirmware()
+{
+ // if(!httpIsAuthenticated(F("firmware"))) return;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void httpSetup(const JsonObject & settings)
+{
+ if(WiFi.getMode() == WIFI_AP) {
+ debugPrintln(F("HTTP: Wifi access point"));
+ // webServer.on(F("/"), webHandleWifiConfig);
+ } else {
+
+ webServer.on(String(F("/")).c_str(), HTTP_GET, webHandleRoot);
+ webServer.on(String(F("/config/hasp")).c_str(), webHandleHaspConfig);
+ webServer.on(String(F("/screenshot")).c_str(), webHandleScreenshot);
+
+ webServer.onNotFound(httpHandleNotFound);
+
+ webServer.begin();
+
+ httpReconnect();
+ debugPrintln(F("HTTP: Setup Complete"));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void httpReconnect()
+{
+ if(!httpEnable) return;
+
+ if(webServerStarted) {
+ webServer.end();
+ webServerStarted = false;
+ debugPrintln(F("HTTP: Server stoped"));
+ } else if(WiFi.status() == WL_CONNECTED || WiFi.getMode() == WIFI_AP) {
+
+ /*
+ if(WiFi.getMode() == WIFI_AP) {
+ webServer.on(F("/"), webHandleWifiConfig);
+ webServer.on(F("/config"), webHandleConfig);
+ webServer.onNotFound(httpHandleNotFound);
+ } else {
+ }
+ */
+ webServer.begin();
+ webServerStarted = true;
+
+ debugPrintln(String(F("HTTP: Server started @ http://")) +
+ (WiFi.getMode() == WIFI_AP ? WiFi.softAPIP().toString() : WiFi.localIP().toString()));
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void httpLoop()
+{
+ // if(httpEnable) webServer.handleClient();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void httpEverySecond()
+{
+ if(httpEnable && !webServerStarted) httpReconnect();
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+bool httpGetConfig(const JsonObject & settings)
+{
+ settings[FPSTR(F_CONFIG_ENABLE)] = httpEnable;
+ settings[FPSTR(F_CONFIG_PORT)] = httpPort;
+ settings[FPSTR(F_CONFIG_USER)] = httpUser;
+ settings[FPSTR(F_CONFIG_PASS)] = httpPassword;
+
+ configOutput(settings);
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+bool httpSetConfig(const JsonObject & settings)
+{
+ configOutput(settings);
+ bool changed = false;
+
+ changed |= configSet(httpPort, settings[FPSTR(F_CONFIG_PORT)], PSTR("httpPort"));
+
+ if(!settings[FPSTR(F_CONFIG_USER)].isNull()) {
+ changed |= strcmp(httpUser, settings[FPSTR(F_CONFIG_USER)]) != 0;
+ strncpy(httpUser, settings[FPSTR(F_CONFIG_USER)], sizeof(httpUser));
+ }
+
+ if(!settings[FPSTR(F_CONFIG_PASS)].isNull()) {
+ changed |= strcmp(httpPassword, settings[FPSTR(F_CONFIG_PASS)]) != 0;
+ strncpy(httpPassword, settings[FPSTR(F_CONFIG_PASS)], sizeof(httpPassword));
+ }
+
+ return changed;
+}
+
+#else
+
+//#include "webServer.h"
+#include "Arduino.h"
+#include "ArduinoJson.h"
+#include "ArduinoLog.h"
+#include "lvgl.h"
+#include "StringStream.h"
+
+#ifdef ESP32
+#include "Update.h"
+#endif
+
+#include "hasp_conf.h"
+
+//#include "hasp_log.h"
+#include "hasp_gui.h"
+#include "hasp_hal.h"
+#include "hasp_debug.h"
+#include "hasp_http.h"
+#include "hasp_wifi.h"
+#include "hasp_spiffs.h"
+#include "hasp_config.h"
+#include "hasp_dispatch.h"
+#include "hasp.h"
+
+#include "hasp_conf.h"
+#if HASP_USE_MQTT
+#include "hasp_mqtt.h"
+#endif
+
+#if defined(ARDUINO_ARCH_ESP32)
+#include "SPIFFS.h"
+#include
+#endif
+#include
+#include
+
bool httpEnable = true;
bool webServerStarted = false;
uint16_t httpPort = 80;
@@ -52,7 +490,7 @@ const char MIT_LICENSE[] PROGMEM = "MIT License";
const char HTTP_DOCTYPE[] PROGMEM =
"";
-const char HTTP_META_GO_BACK[] PROGMEM = "";
+const char HTTP_META_GO_BACK[] PROGMEM = "";
const char HTTP_HEADER[] PROGMEM = "%s";
const char HTTP_STYLE[] PROGMEM =
"";
+ "1px solid red;}input[type=checkbox]{width:20px;}input[type=radio]{width:20px;}";
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -94,6 +532,15 @@ String lcdFirmwareUrl = "http://haswitchplate.com/update/HASwitchPlate.tft";
////////////////////////////////////////////////////////////////////////////////////////////////////
void webHandleHaspConfig();
+static inline String httpGetNodename()
+{
+#if HASP_USE_MQTT > 0
+ return mqttGetNodename();
+#else
+ return "na";
+#endif
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////
bool httpIsAuthenticated(const String & page)
{
@@ -104,10 +551,10 @@ bool httpIsAuthenticated(const String & page)
}
}
- char buffer[128];
- snprintf(buffer, sizeof(buffer), PSTR("HTTP: Sending %s page to client connected from: %s"), page.c_str(),
- webServer.client().remoteIP().toString().c_str());
- debugPrintln(buffer);
+ {
+ Log.verbose(F("HTTP: Sending %s page to client connected from: %s"), page.c_str(),
+ webServer.client().remoteIP().toString().c_str());
+ }
return true;
}
@@ -152,9 +599,9 @@ void webSendPage(String & nodename, uint32_t httpdatalength, bool gohome = false
contentLength += sizeof(HTTP_END) - 1;
contentLength += sizeof(HTTP_FOOTER) - 1;
- snprintf_P(buffer, sizeof(buffer), PSTR("HTTP: Sending page with %u static and %u dynamic bytes"), contentLength,
- httpdatalength);
- debugPrintln(buffer);
+ if(httpdatalength > HTTP_PAGE_SIZE) {
+ Log.warning(F("HTTP: Sending page with %u static and %u dynamic bytes"), contentLength, httpdatalength);
+ }
webServer.setContentLength(contentLength + httpdatalength);
webServer.send_P(200, PSTR("text/html"), HTTP_DOCTYPE); // 122
@@ -171,7 +618,7 @@ void webSendPage(uint32_t httpdatalength, bool gohome = false)
{
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
webSendPage(nodename, httpdatalength, gohome);
}
@@ -181,7 +628,7 @@ void webHandleRoot()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -218,7 +665,7 @@ void httpHandleReboot()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -241,16 +688,22 @@ void webHandleScreenshot()
{ // http://plate01/screenshot
if(!httpIsAuthenticated(F("screenshot"))) return;
- if(webServer.hasArg(F("q"))) {
- webServer.setContentLength(122 + 320 * 240 * 2);
- webServer.send(200, PSTR("image/bmp"), "");
+ if(webServer.hasArg(F("a")) && webServer.arg(F("a")) == F("next")) {
+ uint8_t page = haspGetPage();
+ haspSetPage(page + 1);
+ }
+ if(webServer.hasArg(F("a")) && webServer.arg(F("a")) == F("prev")) {
+ uint8_t page = haspGetPage();
+ haspSetPage(page - 1);
+ }
+ if(webServer.hasArg(F("q"))) {
guiTakeScreenshot(webServer);
} else {
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -258,10 +711,16 @@ void webHandleScreenshot()
httpMessage += nodename;
httpMessage += F("
");
+ httpMessage +=
+ F("");
httpMessage += F("
");
- httpMessage += F("");
+ httpMessage +=
+ F("");
+ httpMessage += F("");
+ httpMessage += F("");
httpMessage += FPSTR(MAIN_MENU_BUTTON);
webSendPage(nodename, httpMessage.length(), false);
@@ -279,7 +738,7 @@ void webHandleAbout()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -295,15 +754,18 @@ void webHandleAbout()
httpMessage += FPSTR(MIT_LICENSE);
httpMessage += F("zi Font Engine
Copyright© 2020 Francis Van Roie");
httpMessage += FPSTR(MIT_LICENSE);
- httpMessage += F("TFT_eSPI Library
Copyright© 2017 Bodmer (https://github.com/Bodmer) All "
+ httpMessage += F("TFT_eSPI Library
Copyright© 2020 Bodmer (https://github.com/Bodmer) All "
"rights reserved.FreeBSD License");
httpMessage +=
F("includes parts from the Adafruit_GFX libraryCopyright© 2012 Adafruit Industries. "
"All rights reservedBSD License
");
- httpMessage += F("ArduinoJson
Copyright© 2014-2019 Benoit BLANCHON");
+ httpMessage += F("ArduinoJson
Copyright© 2014-2020 Benoit BLANCHON");
httpMessage += FPSTR(MIT_LICENSE);
httpMessage += F("PubSubClient
Copyright© 2008-2015 Nicholas O'Leary");
httpMessage += FPSTR(MIT_LICENSE);
+ httpMessage += F("ArduinoLog
Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, "
+ "dhylands, Josha blemasle, mfalkvidd");
+ httpMessage += FPSTR(MIT_LICENSE);
httpMessage += F("Syslog
Copyright© 2016 Martin Sloup");
httpMessage += FPSTR(MIT_LICENSE);
httpMessage += F("QR Code generator
Copyright© Project Nayuki");
@@ -326,7 +788,7 @@ void webHandleInfo()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -342,7 +804,31 @@ void webHandleInfo()
httpMessage += F(" ");
httpMessage += __TIME__;
httpMessage += F(" CET
Uptime: ");
- httpMessage += String(long(millis() / 1000));
+
+ unsigned long time = millis() / 1000;
+ uint16_t day = time / 86400;
+ time = time % 86400;
+ uint8_t hour = time / 3600;
+ time = time % 3600;
+ uint8_t min = time / 60;
+ time = time % 60;
+ uint8_t sec = time;
+
+ if(day > 0) {
+ httpMessage += String(day);
+ httpMessage += F("d ");
+ }
+ if(day > 0 || hour > 0) {
+ httpMessage += String(hour);
+ httpMessage += F("h ");
+ }
+ if(day > 0 || hour > 0 || min > 0) {
+ httpMessage += String(min);
+ httpMessage += F("m ");
+ }
+ httpMessage += String(sec);
+ httpMessage += F("s");
+
httpMessage += F("
Free Memory: ");
httpMessage += spiffsFormatBytes(ESP.getFreeHeap());
httpMessage += F("
Memory Fragmentation: ");
@@ -359,7 +845,8 @@ void webHandleInfo()
httpMessage += mem_mon.frag_pct;
// httpMessage += F("
LCD Model: ")) + String(LV_HASP_HOR_RES_MAX) + " x " +
- // String(LV_HASP_VER_RES_MAX); httpMessage += F("
LCD Version: ")) + String(lcdVersion);
+ // String(LV_HASP_VER_RES_MAX); httpMessage += F("
LCD Version: ")) +
+ // String(lcdVersion);
httpMessage += F("LCD Active Page: ");
httpMessage += String(haspGetPage());
@@ -367,7 +854,23 @@ void webHandleInfo()
httpMessage += F("
SSID: ");
httpMessage += String(WiFi.SSID());
httpMessage += F("Signal Strength: ");
- httpMessage += String(WiFi.RSSI());
+
+ int8_t rssi = WiFi.RSSI();
+ httpMessage += String(rssi);
+ httpMessage += F("dBm (");
+
+ if(rssi >= -50) {
+ httpMessage += F("Excellent)");
+ } else if(rssi >= -60) {
+ httpMessage += F("Good)");
+ } else if(rssi >= -70) {
+ httpMessage += F("Fair)");
+ } else if(rssi >= -80) {
+ httpMessage += F("Weak)");
+ } else {
+ httpMessage += F("Very Bad)");
+ }
+
httpMessage += F("IP Address: ");
httpMessage += String(WiFi.localIP().toString());
httpMessage += F("Gateway: ");
@@ -377,7 +880,8 @@ void webHandleInfo()
httpMessage += F("MAC Address: ");
httpMessage += String(WiFi.macAddress());
- /* Mqtt Stats */
+/* Mqtt Stats */
+#if HASP_USE_MQTT > 0
httpMessage += F("
MQTT Status: ");
if(mqttIsConnected()) { // Check MQTT connection
httpMessage += F("Connected");
@@ -387,14 +891,11 @@ void webHandleInfo()
}
httpMessage += F("
MQTT ClientID: ");
httpMessage += nodename;
+#endif
/* ESP Stats */
- httpMessage += F("
ESP Chip Id: ");
-#if defined(ARDUINO_ARCH_ESP32)
- httpMessage += String(ESP.getChipRevision());
-#else
- httpMessage += String(ESP.getChipId());
-#endif
+ httpMessage += F("
MCU Model: ");
+ httpMessage += halGetChipModel();
httpMessage += F("
CPU Frequency: ");
httpMessage += String(ESP.getCpuFreqMHz());
httpMessage += F("MHz
Flash Chip Size: ");
@@ -505,32 +1006,76 @@ bool handleFileRead(String path)
return false;
}
-/*
-void handleFirmwareUpdate()
+static unsigned long htppLastLoopTime = 0;
+void webUploadProgress()
+{
+ if(millis() - htppLastLoopTime >= 1250) {
+ Log.verbose(F(" * Uploaded %u bytes"), upload->totalSize + upload->currentSize);
+ htppLastLoopTime = millis();
+ }
+}
+
+void webUpdatePrintError()
+{
+ String output((char *)0);
+ output.reserve(128);
+ StringStream stream((String &)output);
+ Update.printError(stream);
+ Log.error(F("HTTP: %s"), output.c_str());
+}
+
+void webUpdateReboot()
+{
+ Log.notice(F("Update Success: %u bytes received. Rebooting..."), upload->totalSize);
+
+ String nodename((char *)0);
+ nodename.reserve(128);
+ nodename = httpGetNodename();
+
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("
");
+ httpMessage += nodename;
+ httpMessage += F("
");
+ httpMessage += F("Upload complete. Rebooting device, please wait...");
+
+ webSendPage(nodename, httpMessage.length(), true);
+ webServer.sendContent(httpMessage);
+ httpMessage.clear();
+ webSendFooter();
+
+ delay(250);
+ dispatchReboot(true); // Save the current config
+ delay(5000);
+}
+
+void webHandleFirmwareUpdate()
{
upload = &webServer.upload();
if(upload->status == UPLOAD_FILE_START) {
- if(!httpIsAuthenticated(F("firmwareupdate"))) return false;
- Serial.printf("Update: %s\n", upload->filename.c_str());
- if(!Update.begin(UPDATE_SIZE_UNKNOWN)) { // start with max available size
- Update.printError(Serial);
+ if(!httpIsAuthenticated(F("update"))) return;
+ Log.notice(F("Update: %s"), upload->filename.c_str());
+ // WiFiUDP::stopAll();
+ uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
+ // if(!Update.begin(UPDATE_SIZE_UNKNOWN)) { // start with max available size
+ if(!Update.begin(maxSketchSpace)) { // start with max available size
+ webUpdatePrintError();
}
} else if(upload->status == UPLOAD_FILE_WRITE) {
- // flashing firmware to /
-if(Update.write(upload->buf, upload->currentSize) != upload->currentSize) {
- Update.printError(Serial);
-}
-}
-else if(upload->status == UPLOAD_FILE_END)
-{
- if(Update.end(true)) { // true to set the size to the current progress
- Serial.printf("Update Success: %u\nRebooting...\n", upload->totalSize);
- } else {
- Update.printError(Serial);
+ // flashing firmware to ESP
+ if(Update.write(upload->buf, upload->currentSize) != upload->currentSize) {
+ webUpdatePrintError();
+ } else {
+ webUploadProgress();
+ }
+ } else if(upload->status == UPLOAD_FILE_END) {
+ if(Update.end(true)) { // true to set the size to the current progress
+ webUpdateReboot();
+ } else {
+ webUpdatePrintError();
+ }
}
}
-}
-*/
void handleFileUpload()
{
@@ -549,25 +1094,22 @@ void handleFileUpload()
}
if(filename.length() < 32) {
fsUploadFile = filesystem->open(filename, "w");
- filename = String(F("handleFileUpload Name: ")) + filename;
- debugPrintln(filename);
+ Log.notice(F("handleFileUpload Name: %s"), filename.c_str());
} else {
- filename = String(F("%sFilename is too long: ")) + filename;
- errorPrintln(filename);
+ Log.error(F("Filename %s is too long"), filename.c_str());
}
} else if(upload->status == UPLOAD_FILE_WRITE) {
// DBG_OUTPUT_PORT.print("handleFileUpload Data: "); debugPrintln(upload.currentSize);
if(fsUploadFile) {
- fsUploadFile.write(upload->buf, upload->currentSize);
- char buffer[128];
- sprintf_P(buffer, PSTR(" * Uploaded %u bytes"), upload->totalSize + upload->currentSize);
- debugPrintln(buffer);
+ if(fsUploadFile.write(upload->buf, upload->currentSize) != upload->currentSize) {
+ Log.error(F("HTTP: Failed to write received data to file"));
+ } else {
+ webUploadProgress(); // Moved to httpEverySecond Loop
+ }
}
} else if(upload->status == UPLOAD_FILE_END) {
if(fsUploadFile) {
- char buffer[128];
- sprintf_P(buffer, PSTR("Uploaded %s (%u bytes)"), fsUploadFile.name(), upload->totalSize);
- debugPrintln(buffer);
+ Log.verbose(F("Uploaded %s (%u bytes)"), fsUploadFile.name(), upload->totalSize);
fsUploadFile.close();
}
@@ -589,7 +1131,7 @@ void handleFileDelete()
return webServer.send_P(500, mimetype, PSTR("BAD ARGS"));
}
String path = webServer.arg(0);
- debugPrintln(String(F("handleFileDelete: ")) + path);
+ Log.verbose(F("handleFileDelete: %s"), path.c_str());
if(path == "/") {
return webServer.send_P(500, mimetype, PSTR("BAD PATH"));
}
@@ -609,7 +1151,7 @@ void handleFileCreate()
return webServer.send(500, PSTR("text/plain"), PSTR("BAD ARGS"));
}
String path = webServer.arg(0);
- debugPrintln(String(F("handleFileCreate: ")) + path);
+ Log.verbose(F("handleFileCreate: %s"), path.c_str());
if(path == "/") {
return webServer.send(500, PSTR("text/plain"), PSTR("BAD PATH"));
}
@@ -636,7 +1178,7 @@ void handleFileList()
}
String path = webServer.arg(F("dir"));
- debugPrintln(String(F("handleFileList: ")) + path);
+ Log.verbose(F("handleFileList: %s"), path.c_str());
path.clear();
#if defined(ARDUINO_ARCH_ESP32)
@@ -703,8 +1245,10 @@ void webHandleConfig()
if(save == String(PSTR("hasp"))) {
haspSetConfig(settings.as());
+#if HASP_USE_MQTT > 0
} else if(save == String(PSTR("mqtt"))) {
mqttSetConfig(settings.as());
+#endif
} else if(save == String(PSTR("gui"))) {
guiSetConfig(settings.as());
@@ -730,7 +1274,7 @@ void webHandleConfig()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -778,7 +1322,7 @@ void webHandleMqttConfig()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
DynamicJsonDocument settings(256);
mqttGetConfig(settings.to());
@@ -832,7 +1376,7 @@ void webHandleGuiConfig()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -907,7 +1451,7 @@ void webHandleWifiConfig()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -949,7 +1493,7 @@ void webHandleHttpConfig()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -988,7 +1532,7 @@ void webHandleDebugConfig()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -997,11 +1541,41 @@ void webHandleDebugConfig()
httpMessage += F("
");
httpMessage += F("");
+
+ httpMessage += F("Syslog Hostame (optional)
Syslog Port (optional) Syslog Facility Syslog Protocol () == 0) httpMessage += F(" checked");
+ httpMessage += F(">IETF (RFC 5424) () == 1) httpMessage += F(" checked");
+ httpMessage += F(">BSD (RFC 3164)");
+
+ httpMessage += F("");
httpMessage +=
PSTR("");
@@ -1022,7 +1596,7 @@ void webHandleHaspConfig()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -1122,7 +1696,7 @@ void httpHandleNotFound()
{ // webServer 404
if(handleFileRead(webServer.uri())) return;
- debugPrintln(String(F("HTTP: Sending 404 to client connected from: ")) + webServer.client().remoteIP().toString());
+ Log.notice(F("HTTP: Sending 404 to client connected from: %s"), webServer.client().remoteIP().toString().c_str());
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -1152,6 +1726,31 @@ void webHandleSaveConfig()
void webHandleFirmware()
{
if(!httpIsAuthenticated(F("firmware"))) return;
+
+ String nodename((char *)0);
+ nodename.reserve(128);
+ nodename = httpGetNodename();
+
+ String httpMessage((char *)0);
+ httpMessage.reserve(HTTP_PAGE_SIZE);
+ httpMessage += F("");
+ httpMessage += nodename;
+ httpMessage += F("
");
+
+ httpMessage += F("");
+
+ httpMessage += F("");
+
+ httpMessage += FPSTR(MAIN_MENU_BUTTON);
+
+ webSendPage(nodename, httpMessage.length(), false);
+ webServer.sendContent(httpMessage);
+ httpMessage.clear();
+ webSendFooter();
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1161,7 +1760,7 @@ void httpHandleEspFirmware()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -1177,7 +1776,7 @@ void httpHandleEspFirmware()
httpMessage.clear();
webSendFooter();
- debugPrintln(String(F("HTTP: Attempting ESP firmware update from: ")) + String(webServer.arg("espFirmware")));
+ Log.notice(F("HTTP: Attempting ESP firmware update from: %s"), webServer.arg("espFirmware").c_str());
// espStartOta(webServer.arg("espFirmware"));
}
@@ -1190,7 +1789,7 @@ void httpHandleResetConfig()
String nodename((char *)0);
nodename.reserve(128);
- nodename = mqttGetNodename();
+ nodename = httpGetNodename();
String httpMessage((char *)0);
httpMessage.reserve(HTTP_PAGE_SIZE);
@@ -1234,8 +1833,10 @@ void httpHandleResetConfig()
////////////////////////////////////////////////////////////////////////////////////////////////////
void httpSetup(const JsonObject & settings)
{
+ httpSetConfig(settings);
+
if(WiFi.getMode() == WIFI_AP) {
- debugPrintln(F("HTTP: Wifi access point"));
+ Log.notice(F("HTTP: Wifi access point"));
webServer.on(F("/"), webHandleWifiConfig);
} else {
@@ -1258,7 +1859,8 @@ void httpSetup(const JsonObject & settings)
webServer.on(F("/edit"), HTTP_DELETE, handleFileDelete);
// first callback is called after the request has ended with all parsed arguments
// second callback handles file uploads at that location
- webServer.on(F("/edit"), HTTP_POST, []() { webServer.send(200, "text/plain", ""); }, handleFileUpload);
+ webServer.on(
+ F("/edit"), HTTP_POST, []() { webServer.send(200, "text/plain", ""); }, handleFileUpload);
// get heap status, analog input value and all GPIO statuses in one json call
/*webServer.on(F("/all"), HTTP_GET, []() {
String json;
@@ -1292,6 +1894,8 @@ void httpSetup(const JsonObject & settings)
webServer.on(F("/saveConfig"), webHandleSaveConfig);
webServer.on(F("/resetConfig"), httpHandleResetConfig);
webServer.on(F("/firmware"), webHandleFirmware);
+ webServer.on(
+ F("/update"), HTTP_POST, []() { webServer.send(200, "text/plain", ""); }, webHandleFirmwareUpdate);
webServer.on(F("/espfirmware"), httpHandleEspFirmware);
webServer.on(F("/reboot"), httpHandleReboot);
webServer.onNotFound(httpHandleNotFound);
@@ -1303,7 +1907,7 @@ void httpSetup(const JsonObject & settings)
webServer.onNotFound(httpHandleNotFound);
httpReconnect();
- debugPrintln(F("HTTP: Setup Complete"));
+ Log.verbose(F("HTTP: Setup Complete"));
}
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1314,22 +1918,13 @@ void httpReconnect()
if(webServerStarted) {
webServer.stop();
webServerStarted = false;
- debugPrintln(F("HTTP: Server stoped"));
+ Log.warning(F("HTTP: Server stoped"));
} else if(WiFi.status() == WL_CONNECTED || WiFi.getMode() == WIFI_AP) {
-
- /*
- if(WiFi.getMode() == WIFI_AP) {
- webServer.on(F("/"), webHandleWifiConfig);
- webServer.on(F("/config"), webHandleConfig);
- webServer.onNotFound(httpHandleNotFound);
- } else {
- }
- */
webServer.begin();
webServerStarted = true;
-
- debugPrintln(String(F("HTTP: Server started @ http://")) +
- (WiFi.getMode() == WIFI_AP ? WiFi.softAPIP().toString() : WiFi.localIP().toString()));
+ Log.notice(
+ F("HTTP: Server started @ http://%s"),
+ (WiFi.getMode() == WIFI_AP ? WiFi.softAPIP().toString().c_str() : WiFi.localIP().toString().c_str()));
}
}
@@ -1340,7 +1935,7 @@ void httpLoop()
}
////////////////////////////////////////////////////////////////////////////////////////////////////
-void httpEverySecond()
+void httpEvery5Seconds()
{
if(httpEnable && !webServerStarted) httpReconnect();
}
@@ -1377,4 +1972,6 @@ bool httpSetConfig(const JsonObject & settings)
}
return changed;
-}
\ No newline at end of file
+}
+
+#endif
\ No newline at end of file
diff --git a/src/hasp_log.cpp b/src/hasp_log.cpp
index 02048709..77108129 100644
--- a/src/hasp_log.cpp
+++ b/src/hasp_log.cpp
@@ -1,5 +1,6 @@
#include "hasp_conf.h"
#include
+#include "ArduinoLog.h"
#if defined(ARDUINO_ARCH_ESP8266)
#include
@@ -17,10 +18,10 @@
void debugPrintln(String & debugText)
{
- serialPrintln(debugText);
+ serialPrintln(debugText, LOG_LEVEL_NOTICE);
#if HASP_USE_SYSLOG != 0
- syslogSend(0, debugText.c_str());
+ syslogSend(LOG_INFO, debugText.c_str());
#endif
}
@@ -34,10 +35,10 @@ void debugPrintln(const __FlashStringHelper * debugText)
void debugPrintln(const char * debugText)
{
- serialPrintln(debugText);
+ serialPrintln(debugText, LOG_LEVEL_NOTICE);
#if HASP_USE_SYSLOG != 0
- syslogSend(0, debugText);
+ syslogSend(LOG_INFO, debugText);
#endif
}
@@ -45,10 +46,10 @@ void errorPrintln(String debugText)
{
char buffer[128];
sprintf_P(buffer, debugText.c_str(), PSTR("[ERROR] "));
- serialPrintln(buffer);
+ serialPrintln(buffer, LOG_LEVEL_ERROR);
#if HASP_USE_SYSLOG != 0
- syslogSend(2, buffer);
+ syslogSend(LOG_ERR, buffer);
#endif
}
@@ -56,9 +57,9 @@ void warningPrintln(String debugText)
{
char buffer[128];
sprintf_P(buffer, debugText.c_str(), PSTR("[WARNING] "));
- serialPrintln(buffer);
+ serialPrintln(buffer, LOG_LEVEL_WARNING);
#if HASP_USE_SYSLOG != 0
- syslogSend(1, buffer);
+ syslogSend(LOG_WARNING, buffer);
#endif
}
\ No newline at end of file
diff --git a/src/hasp_mqtt.cpp b/src/hasp_mqtt.cpp
index fac72f2d..a44868a6 100644
--- a/src/hasp_mqtt.cpp
+++ b/src/hasp_mqtt.cpp
@@ -1,5 +1,13 @@
+#include "hasp_conf.h"
+#if HASP_USE_MQTT
+
#include
#include "ArduinoJson.h"
+#include "ArduinoLog.h"
+#include "PubSubClient.h"
+
+#include "hasp_conf.h"
+#include "hasp_mqtt.h"
#if defined(ARDUINO_ARCH_ESP32)
#include
@@ -8,9 +16,8 @@
#include
#include
#endif
-#include
-#include "hasp_log.h"
+//#include "hasp_log.h"
#include "hasp_hal.h"
#include "hasp_debug.h"
#include "hasp_config.h"
@@ -32,12 +39,13 @@ String mqttCommandTopic; // MQTT topic for incoming panel commands
String mqttGroupCommandTopic; // MQTT topic for incoming group panel commands
String mqttStatusTopic; // MQTT topic for publishing device connectivity state
String mqttSensorTopic; // MQTT topic for publishing device information in JSON format
-*/
+
String mqttLightCommandTopic; // MQTT topic for incoming panel backlight on/off commands
String mqttLightStateTopic; // MQTT topic for outgoing panel backlight on/off state
String mqttLightBrightCommandTopic; // MQTT topic for incoming panel backlight dimmer commands
String mqttLightBrightStateTopic; // MQTT topic for outgoing panel backlight dimmer state
// String mqttMotionStateTopic; // MQTT topic for outgoing motion sensor state
+*/
#ifdef MQTT_NODENAME
char mqttNodeName[16] = MQTT_NODENAME;
@@ -51,9 +59,11 @@ char mqttGroupName[16] = MQTT_GROUPNAME;
char mqttGroupName[16] = "";
#endif
-String mqttClientId((char *)0); // Auto-generated MQTT ClientID
-String mqttNodeTopic((char *)0);
-String mqttGroupTopic((char *)0);
+// String mqttClientId((char *)0); // Auto-generated MQTT ClientID
+// String mqttNodeTopic((char *)0);
+// String mqttGroupTopic((char *)0);
+char mqttNodeTopic[24];
+char mqttGroupTopic[24];
bool mqttEnabled;
////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -99,29 +109,24 @@ void IRAM_ATTR mqttSendState(const char * subtopic, const char * payload)
// light = 0/1
// brightness = 100
- // char mqttPayload[128 * 5];
-
if(mqttClient.connected()) {
- char mqttTopic[128];
- snprintf_P(mqttTopic, sizeof(mqttTopic), PSTR("%sstate/%s"), mqttNodeTopic.c_str(), subtopic);
- mqttClient.publish(mqttTopic, payload);
+ char topic[128];
+ snprintf_P(topic, sizeof(topic), PSTR("%sstate/%s"), mqttNodeTopic, subtopic);
+ mqttClient.publish(topic, payload);
+ Log.notice(F("MQTT OUT: %s = %s"), topic, payload);
- String msg((char *)0);
- msg.reserve(512);
+ // String msg((char *)0);
+ /* msg.reserve(256 + 128);
msg = F("MQTT OUT: ");
msg += mqttTopic;
msg += " = ";
msg += payload;
debugPrintln(msg);
+ msg.clear();
+ */
} else {
- errorPrintln(F("MQTT: %sNot connected"));
+ Log.error(F("MQTT: Not connected"));
}
-
- // as json
- // snprintf_P(mqttTopic, sizeof(mqttTopic), PSTR("%sstate/json"), mqttNodeTopic.c_str());
- // snprintf_P(mqttPayload, sizeof(mqttPayload), PSTR("{\"%s\":\"%s\"}"), subtopic, payload);
- // mqttClient.publish(mqttTopic, mqttPayload);
- // debugPrintln(String(F("MQTT OUT: ")) + String(mqttTopic) + " = " + String(mqttPayload));
}
void IRAM_ATTR mqttSendNewValue(uint8_t pageid, uint8_t btnid, const char * attribute, String txt)
@@ -162,7 +167,7 @@ void mqttStatusUpdate()
mqttStatusPayload += "{";
mqttStatusPayload += F("\"status\":\"available\",");
- mqttStatusPayload += F("\"espVersion\":\"");
+ mqttStatusPayload += F("\"version\":\"");
mqttStatusPayload += buffer;
mqttStatusPayload += F("\",");
/* if(updateEspAvailable) {
@@ -183,31 +188,24 @@ void mqttStatusUpdate()
} else {
mqttStatusPayload += F("\"updateLcdAvailable\":false,");
}*/
- mqttStatusPayload += F("\"espUptime\":");
+ mqttStatusPayload += F("\"uptime\":");
mqttStatusPayload += String(long(millis() / 1000));
mqttStatusPayload += F(",");
- mqttStatusPayload += F("\"signalStrength\":");
+ mqttStatusPayload += F("\"rssi\":");
mqttStatusPayload += String(WiFi.RSSI());
mqttStatusPayload += F(",");
- mqttStatusPayload += F("\"haspIP\":\"");
+ mqttStatusPayload += F("\"ip\":\"");
mqttStatusPayload += WiFi.localIP().toString();
mqttStatusPayload += F("\",");
mqttStatusPayload += F("\"heapFree\":");
mqttStatusPayload += String(ESP.getFreeHeap());
mqttStatusPayload += F(",");
- mqttStatusPayload += F("\"heapFragmentation\":");
+ mqttStatusPayload += F("\"heapFrag\":");
mqttStatusPayload += String(halGetHeapFragmentation());
mqttStatusPayload += F(",");
mqttStatusPayload += F("\"espCore\":\"");
mqttStatusPayload += halGetCoreVersion();
mqttStatusPayload += F("\"");
-
-#if defined(ARDUINO_ARCH_ESP8266)
- mqttStatusPayload += F(",");
- mqttStatusPayload += F("\"Vcc\":\"");
- mqttStatusPayload += (float)ESP.getVcc() / 1000;
- mqttStatusPayload += F("\"");
-#endif
mqttStatusPayload += "}";
// mqttClient.publish(mqttSensorTopic, mqttStatusPayload);
@@ -223,11 +221,22 @@ void mqttStatusUpdate()
void mqttCallback(char * topic, byte * payload, unsigned int length)
{ // Handle incoming commands from MQTT
payload[length] = '\0';
- String strTopic = topic;
- // strTopic: homeassistant/haswitchplate/devicename/command/p[1].b[4].txt
- // strPayload: "Lights On"
- // subTopic: p[1].b[4].txt
+ String strTopic((char *)0);
+ strTopic.reserve(MQTT_MAX_PACKET_SIZE);
+
+ Log.notice(F("MQTT IN: %s = %s"), topic, (char *)payload);
+
+ /* Debug feedback */
+ /* strTopic = F("MQTT IN: '");
+ strTopic += topic;
+ strTopic += F("' : '");
+ strTopic += (char *)payload;
+ strTopic += F("'");
+ debugPrintln(strTopic); */
+
+ /* Reset the actual topic */
+ strTopic = topic;
// Incoming Namespace (replace /device/ with /group/ for group commands)
// '[...]/device/command' -m '' = No command requested, respond with mqttStatusUpdate()
@@ -244,12 +253,10 @@ void mqttCallback(char * topic, byte * payload, unsigned int length)
// '[...]/device/command/p[1].b[4].txt' -m '' = nextionGetAttr("p[1].b[4].txt")
// '[...]/device/command/p[1].b[4].txt' -m '"Lights On"' = nextionSetAttr("p[1].b[4].txt", "\"Lights On\"")
- debugPrintln(String(F("MQTT IN: '")) + strTopic + "' : '" + (char *)payload + "'");
-
if(strTopic.startsWith(mqttNodeTopic)) {
- strTopic = strTopic.substring(mqttNodeTopic.length(), strTopic.length());
+ strTopic = strTopic.substring(strlen(mqttNodeTopic), strTopic.length());
} else if(strTopic.startsWith(mqttGroupTopic)) {
- strTopic = strTopic.substring(mqttGroupTopic.length(), strTopic.length());
+ strTopic = strTopic.substring(strlen(mqttGroupTopic), strTopic.length());
} else {
return;
}
@@ -278,77 +285,124 @@ void mqttCallback(char * topic, byte * payload, unsigned int length)
return;
}
+ /*
String strPayload = (char *)payload;
- if(strTopic == mqttLightBrightCommandTopic) { // change the brightness from the light topic
- int panelDim = map(strPayload.toInt(), 0, 255, 0, 100);
- // nextionSetAttr("dim", String(panelDim));
- // nextionSendCmd("dims=dim");
- // mqttClient.publish(mqttLightBrightStateTopic, strPayload);
- } else if(strTopic == mqttLightCommandTopic &&
- strPayload == F("OFF")) { // set the panel dim OFF from the light topic, saving current dim level first
- // nextionSendCmd("dims=dim");
- // nextionSetAttr("dim", "0");
- mqttClient.publish(mqttLightStateTopic.c_str(), PSTR("OFF"));
- } else if(strTopic == mqttLightCommandTopic &&
- strPayload == F("ON")) { // set the panel dim ON from the light topic, restoring saved dim level
- // nextionSendCmd("dim=dims");
- mqttClient.publish(mqttLightStateTopic.c_str(), PSTR("ON"));
- }
+ if(strTopic == mqttLightBrightCommandTopic) { // change the brightness from the light topic
+ int panelDim = map(strPayload.toInt(), 0, 255, 0, 100);
+ // nextionSetAttr("dim", String(panelDim));
+ // nextionSendCmd("dims=dim");
+ // mqttClient.publish(mqttLightBrightStateTopic, strPayload);
+ } else if(strTopic == mqttLightCommandTopic &&
+ strPayload == F("OFF")) { // set the panel dim OFF from the light topic, saving current dim level
+ first
+ // nextionSendCmd("dims=dim");
+ // nextionSetAttr("dim", "0");
+ mqttClient.publish(mqttLightStateTopic.c_str(), PSTR("OFF"));
+ } else if(strTopic == mqttLightCommandTopic &&
+ strPayload == F("ON")) { // set the panel dim ON from the light topic, restoring saved dim level
+ // nextionSendCmd("dim=dims");
+ mqttClient.publish(mqttLightStateTopic.c_str(), PSTR("ON"));
+ }
+ */
- if(strTopic == F("status") &&
- strPayload == F("OFF")) { // catch a dangling LWT from a previous connection if it appears
+ // catch a dangling LWT from a previous connection if it appears
+ if(strTopic == F("status") && strcmp_P((char *)payload, PSTR("OFF")) == 0) {
char topicBuffer[128];
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%sstatus"), mqttNodeTopic.c_str());
+ snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%sstatus"), mqttNodeTopic);
mqttClient.publish(topicBuffer, "ON", true);
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("MQTT: binary_sensor state: [%sstatus] : ON"),
- mqttNodeTopic.c_str());
- debugPrintln(topicBuffer);
+ Log.notice(F("MQTT: binary_sensor state: [status] : ON"));
+ // snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("MQTT: binary_sensor state: [%sstatus] : ON"),
+ // mqttNodeTopic); debugPrintln(topicBuffer);
return;
}
}
+void mqttSubscribeTo(const char * format, const char * data)
+{
+ char buffer[128];
+ char topic[128];
+ snprintf_P(topic, sizeof(topic), format, data);
+ if(mqttClient.subscribe(topic)) {
+ Log.verbose(F("MQTT: * Subscribed to %s"), topic);
+
+ // snprintf_P(buffer, sizeof(buffer), PSTR("MQTT: * Subscribed to %s"), topic);
+ // debugPrintln(buffer);
+ } else {
+ Log.error(F("MQTT: Failed to subscribe to %s"), topic);
+
+ // snprintf_P(buffer, sizeof(buffer), PSTR("MQTT: %%sFailed to subscribe to %s"), topic);
+ // errorPrintln(buffer);
+ }
+}
+
void mqttReconnect()
{
static uint8_t mqttReconnectCount = 0;
bool mqttFirstConnect = true;
- String nodeName((char *)0);
- nodeName.reserve(128);
- nodeName = haspGetNodename();
- char topicBuffer[128];
+ char mqttClientId[128];
+ char buffer[128];
- // Generate an MQTT client ID as haspNode + our MAC address
- mqttClientId.reserve(128);
- mqttClientId = nodeName;
- mqttClientId += F("-");
- mqttClientId += wifiGetMacAddress(3, "");
- WiFi.macAddress();
-
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("hasp/%s/"), mqttNodeName);
- mqttNodeTopic = topicBuffer;
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("hasp/%s/"), mqttGroupName);
- mqttGroupTopic = topicBuffer;
-
- // haspSetPage(0);
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("MQTT: Attempting connection to broker %s as clientID %s"),
- mqttServer, mqttClientId.c_str());
- debugPrintln(topicBuffer);
+ snprintf(mqttClientId, sizeof(mqttClientId), PSTR("%s-%s"), mqttNodeName, wifiGetMacAddress(3, "").c_str());
+ snprintf_P(mqttNodeTopic, sizeof(mqttNodeTopic), PSTR("hasp/%s/"), mqttNodeName);
+ snprintf_P(mqttGroupTopic, sizeof(mqttGroupTopic), PSTR("hasp/%s/"), mqttGroupName);
// Attempt to connect and set LWT and Clean Session
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%sstatus"), mqttNodeTopic.c_str());
- if(!mqttClient.connect(mqttClientId.c_str(), mqttUser, mqttPassword, topicBuffer, 0, false, "OFF", true)) {
+ snprintf_P(buffer, sizeof(buffer), PSTR("%sstatus"), mqttNodeTopic);
+ if(!mqttClient.connect(mqttClientId, mqttUser, mqttPassword, buffer, 0, false, "OFF", true)) {
// Retry until we give up and restart after connectTimeout seconds
mqttReconnectCount++;
+ snprintf_P(buffer, sizeof(buffer), PSTR("MQTT: %%s"));
+ switch(mqttClient.state()) {
+ case MQTT_CONNECTION_TIMEOUT:
+ strcat_P(buffer, PSTR("Server didn't respond within the keepalive time"));
+ break;
+ case MQTT_CONNECTION_LOST:
+ strcat_P(buffer, PSTR("Network connection was broken"));
+ break;
+ case MQTT_CONNECT_FAILED:
+ strcat_P(buffer, PSTR("Network connection failed"));
+ break;
+ case MQTT_DISCONNECTED:
+ strcat_P(buffer, PSTR("Client is disconnected cleanly"));
+ break;
+ case MQTT_CONNECTED:
+ strcat_P(buffer, PSTR("(Client is connected"));
+ break;
+ case MQTT_CONNECT_BAD_PROTOCOL:
+ strcat_P(buffer, PSTR("Server doesn't support the requested version of MQTT"));
+ break;
+ case MQTT_CONNECT_BAD_CLIENT_ID:
+ strcat_P(buffer, PSTR("Server rejected the client identifier"));
+ break;
+ case MQTT_CONNECT_UNAVAILABLE:
+ strcat_P(buffer, PSTR("Server was unable to accept the connection"));
+ break;
+ case MQTT_CONNECT_BAD_CREDENTIALS:
+ strcat_P(buffer, PSTR("Username or Password rejected"));
+ break;
+ case MQTT_CONNECT_UNAUTHORIZED:
+ strcat_P(buffer, PSTR("Client was not authorized to connect"));
+ break;
+ default:
+ strcat_P(buffer, PSTR("Unknown failure"));
+ }
+ Log.warning(buffer);
+ // errorPrintln(buffer);
- Serial.print(String(F("failed, rc=")));
- Serial.print(mqttClient.state());
- // Wait 5 seconds before retrying
- // delay(50);
+ if(mqttReconnectCount > 50) {
+ Log.error(F("MQTT: %sRetry count exceeded, rebooting..."));
+ // errorPrintln(F("MQTT: %sRetry count exceeded, rebooting..."));
+ dispatchReboot(false);
+ }
return;
}
- debugPrintln(F("MQTT: MQTT Client is Connected"));
+ Log.notice(F("MQTT: [SUCCESS] Connected to broker %s as clientID %s"), mqttServer, mqttClientId);
+ /* snprintf_P(buffer, sizeof(buffer), PSTR("MQTT: [SUCCESS] Connected to broker %s as clientID %s"), mqttServer,
+ mqttClientId);
+ debugPrintln(buffer); */
haspReconnect();
/*
@@ -374,46 +428,24 @@ void mqttReconnect()
// Attempt to connect to broker, setting last will and testament
// Subscribe to our incoming topics
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%scommand/#"), mqttGroupTopic.c_str());
- if(mqttClient.subscribe(topicBuffer)) {
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("MQTT: * Subscribed to %scommand/#"),
- mqttGroupTopic.c_str());
- debugPrintln(topicBuffer);
- }
+ mqttSubscribeTo(PSTR("%scommand/#"), mqttGroupTopic);
+ mqttSubscribeTo(PSTR("%scommand/#"), mqttNodeTopic);
+ mqttSubscribeTo(PSTR("%slight/#"), mqttNodeTopic);
+ mqttSubscribeTo(PSTR("%sbrightness/#"), mqttNodeTopic);
+ mqttSubscribeTo(PSTR("%sstatus"), mqttNodeTopic);
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%scommand/#"), mqttNodeTopic.c_str());
- if(mqttClient.subscribe(topicBuffer)) {
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("MQTT: * Subscribed to %scommand/#"),
- mqttNodeTopic.c_str());
- debugPrintln(topicBuffer);
- }
-
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%slight/#"), mqttNodeTopic.c_str());
- if(mqttClient.subscribe(topicBuffer)) {
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("MQTT: * Subscribed to %slight/#"), mqttNodeTopic.c_str());
- debugPrintln(topicBuffer);
- }
-
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%sbrightness/#"), mqttNodeTopic.c_str());
- if(mqttClient.subscribe(topicBuffer)) {
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("MQTT: * Subscribed to %sbrightness/#"),
- mqttNodeTopic.c_str());
- debugPrintln(topicBuffer);
- }
-
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%sstatus"), mqttNodeTopic.c_str());
- if(mqttClient.subscribe(topicBuffer)) {
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("MQTT: * Subscribed to %sstatus"), mqttNodeTopic.c_str());
- debugPrintln(topicBuffer);
- }
// Force any subscribed clients to toggle OFF/ON when we first connect to
// make sure we get a full panel refresh at power on. Sending OFF,
// "ON" will be sent by the mqttStatusTopic subscription action.
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%sstatus"), mqttNodeTopic.c_str());
- mqttClient.publish(topicBuffer, mqttFirstConnect ? "OFF" : "ON", true); //, 1);
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("MQTT: binary_sensor state: [%sstatus] : %s"),
- mqttNodeTopic.c_str(), mqttFirstConnect ? PSTR("OFF") : PSTR("ON"));
- debugPrintln(topicBuffer);
+ snprintf_P(buffer, sizeof(buffer), PSTR("%sstatus"), mqttNodeTopic);
+ mqttClient.publish(buffer, mqttFirstConnect ? "OFF" : "ON", true); //, 1);
+
+ Log.notice(F("MQTT: binary_sensor state: [%sstatus] : %s"), mqttNodeTopic,
+ mqttFirstConnect ? PSTR("OFF") : PSTR("ON"));
+
+ /* snprintf_P(buffer, sizeof(buffer), PSTR("MQTT: binary_sensor state: [%sstatus] : %s"), mqttNodeTopic,
+ mqttFirstConnect ? PSTR("OFF") : PSTR("ON"));
+ debugPrintln(buffer); */
mqttFirstConnect = false;
mqttReconnectCount = 0;
@@ -421,10 +453,6 @@ void mqttReconnect()
void mqttSetup(const JsonObject & settings)
{
- mqttClientId.reserve(128);
- mqttNodeTopic.reserve(128);
- mqttGroupTopic.reserve(128);
-
mqttSetConfig(settings);
mqttEnabled = strcmp(mqttServer, "") != 0 && mqttPort > 0;
@@ -433,17 +461,20 @@ void mqttSetup(const JsonObject & settings)
mqttClient.setServer(mqttServer, 1883);
mqttClient.setCallback(mqttCallback);
- debugPrintln(F("MQTT: Setup Complete"));
+ Log.notice(F("MQTT: Setup Complete"));
+ // debugPrintln(F("MQTT: Setup Complete"));
}
-void mqttLoop(bool wifiIsConnected)
+void mqttLoop()
{
if(!mqttEnabled) return;
+ mqttClient.loop();
+}
- if(wifiIsConnected && !mqttClient.connected())
- mqttReconnect();
- else
- mqttClient.loop();
+void mqttEvery5Seconds(bool wifiIsConnected)
+{
+ if(!mqttEnabled) return;
+ if(wifiIsConnected && !mqttClient.connected()) mqttReconnect();
}
String mqttGetNodename()
@@ -461,14 +492,15 @@ void mqttStop()
if(mqttClient.connected()) {
char topicBuffer[128];
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%sstatus"), mqttNodeTopic.c_str());
+ snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%sstatus"), mqttNodeTopic);
mqttClient.publish(topicBuffer, "OFF");
- snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%ssensor"), mqttNodeTopic.c_str());
+ snprintf_P(topicBuffer, sizeof(topicBuffer), PSTR("%ssensor"), mqttNodeTopic);
mqttClient.publish(topicBuffer, "{\"status\": \"unavailable\"}");
mqttClient.disconnect();
- debugPrintln(F("MQTT: Disconnected from broker"));
+ Log.notice(F("MQTT: Disconnected from broker"));
+ // debugPrintln(F("MQTT: Disconnected from broker"));
}
}
@@ -528,3 +560,5 @@ bool mqttSetConfig(const JsonObject & settings)
return changed;
}
+
+#endif // HASP_USE_MQTT
diff --git a/src/hasp_spiffs.cpp b/src/hasp_spiffs.cpp
index 5273ebc5..a257e2ab 100644
--- a/src/hasp_spiffs.cpp
+++ b/src/hasp_spiffs.cpp
@@ -1,8 +1,9 @@
#include
#include "ArduinoJson.h"
+#include "ArduinoLog.h"
#include "hasp_conf.h"
-#include "hasp_log.h"
+//#include "hasp_log.h"
#include "hasp_spiffs.h"
#if HASP_USE_SPIFFS
@@ -14,24 +15,20 @@
void spiffsList()
{
- char buffer[128];
- debugPrintln(PSTR("FILE: Listing files on the internal flash:"));
+ Log.verbose(F("FILE: Listing files on the internal flash:"));
#if defined(ARDUINO_ARCH_ESP32)
File root = SPIFFS.open("/");
File file = root.openNextFile();
while(file) {
- snprintf(buffer, sizeof(buffer), PSTR("FILE: * %s (%u bytes)"), file.name(), (uint32_t)file.size());
- debugPrintln(buffer);
+ Log.verbose(F("FILE: * %s (%u bytes)"), file.name(), (uint32_t)file.size());
file = root.openNextFile();
}
#endif
#if defined(ARDUINO_ARCH_ESP8266)
Dir dir = SPIFFS.openDir("/");
while(dir.next()) {
- snprintf(buffer, sizeof(buffer), PSTR("FILE: * %s (%u bytes)"), dir.fileName().c_str(),
- (uint32_t)dir.fileSize());
- debugPrintln(buffer);
+ Log.notice(F("FILE: * %s (%u bytes)"), dir.fileName().c_str(), (uint32_t)dir.fileSize());
}
#endif
}
@@ -41,17 +38,14 @@ void spiffsSetup()
// no SPIFFS settings, as settings depend on SPIFFS
#if HASP_USE_SPIFFS
- char buffer[128];
#if defined(ARDUINO_ARCH_ESP8266)
if(!SPIFFS.begin()) {
#else
if(!SPIFFS.begin(true)) {
#endif
- snprintf(buffer, sizeof(buffer), PSTR("FILE: %%sSPI flash init failed. Unable to mount FS."));
- errorPrintln(buffer);
+ Log.error(F("FILE: SPI flash init failed. Unable to mount FS."));
} else {
- snprintf(buffer, sizeof(buffer), PSTR("FILE: SPI Flash FS mounted"));
- debugPrintln(buffer);
+ Log.notice(F("FILE: SPI Flash FS mounted"));
}
#endif
}
diff --git a/src/hasp_wifi.cpp b/src/hasp_wifi.cpp
index b5d0abe1..cd0a1fbe 100644
--- a/src/hasp_wifi.cpp
+++ b/src/hasp_wifi.cpp
@@ -1,19 +1,24 @@
#include
#include "ArduinoJson.h"
+#include "ArduinoLog.h"
#include "hasp_conf.h"
#include "hasp_wifi.h"
-#include "hasp_mqtt.h"
#include "hasp_http.h"
#include "hasp_mdns.h"
-#include "hasp_log.h"
+//#include "hasp_log.h"
#include "hasp_debug.h"
#include "hasp_config.h"
#include "hasp_dispatch.h"
#include "hasp_gui.h"
#include "hasp.h"
+#include "hasp_conf.h"
+#if HASP_USE_MQTT
+#include "hasp_mqtt.h"
+#endif
+
#if defined(ARDUINO_ARCH_ESP32)
#include
#else
@@ -61,16 +66,15 @@ String wifiGetMacAddress(int start, const char * seperator)
void wifiConnected(IPAddress ipaddress)
{
- bool isConnected = WiFi.status() == WL_CONNECTED;
char buffer[128];
- snprintf_P(buffer, sizeof(buffer), PSTR("WIFI: Received IP address %s"), ipaddress.toString().c_str());
- debugPrintln(buffer);
- snprintf_P(buffer, sizeof(buffer), PSTR("WIFI: Connected = %s"), isConnected ? PSTR("yes") : PSTR("no"));
- debugPrintln(buffer);
+ bool isConnected = WiFi.status() == WL_CONNECTED;
+
+ Log.notice(F("WIFI: Received IP address %s"), ipaddress.toString().c_str());
+ Log.verbose(F("WIFI: Connected = %s"), isConnected ? PSTR("yes") : PSTR("no"));
if(isConnected) {
- /* mqttReconnect();
- haspReconnect();*/
+ // mqttReconnect();
+ // haspReconnect();
httpReconnect();
// mdnsStart();
}
@@ -81,19 +85,15 @@ void wifiDisconnected(const char * ssid, uint8_t reason)
char buffer[128];
wifiReconnectCounter++;
if(wifiReconnectCounter > 45) {
- snprintf_P(buffer, sizeof(buffer), PSTR("WIFI: %%s Retries exceed %u: Rebooting..."), wifiReconnectCounter);
- errorPrintln(buffer);
+ Log.error(F("WIFI: Retries exceed %u: Rebooting..."), wifiReconnectCounter);
dispatchReboot(false);
}
- snprintf_P(buffer, sizeof(buffer), PSTR("WIFI: Disconnected from %s (Reason: %d)"), ssid, reason);
- debugPrintln(buffer);
+ Log.warning(F("WIFI: Disconnected from %s (Reason: %d)"), ssid, reason);
}
void wifiSsidConnected(const char * ssid)
{
- char buffer[128];
- snprintf_P(buffer, sizeof(buffer), PSTR("WIFI: Connected to SSID %s. Requesting IP..."), ssid);
- debugPrintln(buffer);
+ Log.notice(F("WIFI: Connected to SSID %s. Requesting IP..."), ssid);
wifiReconnectCounter = 0;
}
@@ -156,16 +156,13 @@ void wifiSetup(JsonObject settings)
// dnsServer.start(DNS_PORT, "*", apIP);
IPAddress IP = WiFi.softAPIP();
- sprintf_P(buffer, PSTR("WIFI: Temporary Access Point %s password: %s"), apSsdid.c_str(), PSTR("haspadmin"));
- debugPrintln(buffer);
- sprintf_P(buffer, PSTR("WIFI: AP IP address : %s"), IP.toString().c_str());
- debugPrintln(buffer);
+ Log.warning(F("WIFI: Temporary Access Point %s password: %s"), apSsdid.c_str(), PSTR("haspadmin"));
+ Log.warning(F("WIFI: AP IP address : %s"), IP.toString().c_str());
// httpReconnect();
} else {
WiFi.mode(WIFI_STA);
- snprintf_P(buffer, sizeof(buffer), PSTR("WIFI: Connecting to : %s"), wifiSsid);
- debugPrintln(buffer);
+ Log.notice(F("WIFI: Connecting to : %s"), wifiSsid);
#if defined(ARDUINO_ARCH_ESP8266)
// wifiEventHandler[0] = WiFi.onStationModeConnected(wifiSTAConnected);
@@ -219,7 +216,7 @@ bool wifiSetConfig(const JsonObject & settings)
void wifiStop()
{
- debugPrintln(F("WIFI: Stopped"));
+ Log.warning(F("WIFI: Stopped"));
WiFi.mode(WIFI_OFF);
WiFi.disconnect();
}
\ No newline at end of file