mirror of
https://github.com/HASwitchPlate/openHASP.git
synced 2025-07-24 11:46:34 +00:00
Switch to ArduinoLog library
This commit is contained in:
parent
8a04961d0e
commit
3a965b18e5
166
src/ArduinoLog.cpp
Normal file
166
src/ArduinoLog.cpp
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
_ ___ ___ _ _ ___ _ _ ___ _ ___ ___
|
||||
/_\ | _ \ \| | | |_ _| \| |/ _ \| | / _ \ / __|
|
||||
/ _ \| / |) | |_| || || .` | (_) | |_| (_) | (_ |
|
||||
/_/ \_\_|_\___/ \___/|___|_|\_|\___/|____\___/ \___|
|
||||
|
||||
Log library for Arduino
|
||||
version 1.0.3
|
||||
https://github.com/thijse/Arduino-Log
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
|
||||
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<PGM_P>(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();
|
298
src/ArduinoLog.h
Normal file
298
src/ArduinoLog.h
Normal file
@ -0,0 +1,298 @@
|
||||
/*
|
||||
_ ___ ___ _ _ ___ _ _ ___ _ ___ ___
|
||||
/_\ | _ \ \| | | |_ _| \| |/ _ \| | / _ \ / __|
|
||||
/ _ \| / |) | |_| || || .` | (_) | |_| (_) | (_ |
|
||||
/_/ \_\_|_\___/ \___/|___|_|\_|\___/|____\___/ \___|
|
||||
|
||||
Log library for Arduino
|
||||
version 1.0.3
|
||||
https://github.com/thijse/Arduino-Log
|
||||
|
||||
Licensed under the MIT License <http://opensource.org/licenses/MIT>.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef LOGGING_H
|
||||
#define LOGGING_H
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
typedef void (*printfunction)(int level, Print *);
|
||||
|
||||
//#include <stdint.h>
|
||||
//#include <stddef.h>
|
||||
// *************************************************************************
|
||||
// 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 ;-) <br>
|
||||
* 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).<br>
|
||||
* 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 <class T, typename... Args> 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 <class T, typename... Args> 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 <class T, typename... Args> 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 <class T, typename... Args> 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 <class T, typename... Args> 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 <class T, typename... Args> 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 <class T> 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
|
@ -1,5 +1,6 @@
|
||||
#include "Arduino.h"
|
||||
#include "ArduinoJson.h"
|
||||
#include "ArduinoLog.h"
|
||||
#include <FS.h> // 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<String>(), passmask);
|
||||
output.replace(settings[F("mqtt")][F("pass")].as<String>(), passmask);
|
||||
output.replace(settings[F("wifi")][F("pass")].as<String>(), 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<JsonObject>());
|
||||
|
||||
#if HASP_USE_MQTT
|
||||
changed |= mqttGetConfig(settings[F("mqtt")].to<JsonObject>());
|
||||
#endif
|
||||
|
||||
#if HASP_USE_TELNET
|
||||
changed |= telnetGetConfig(settings[F("telnet")].to<JsonObject>());
|
||||
#endif
|
||||
|
||||
#if HASP_USE_MDNS
|
||||
changed |= mdnsGetConfig(settings[F("mdns")].to<JsonObject>());
|
||||
#endif
|
||||
|
||||
#if HASP_USE_HTTP
|
||||
changed |= httpGetConfig(settings[F("http")].to<JsonObject>());
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
changed |= debugGetConfig(settings[F("debug")].to<JsonObject>());
|
||||
changed |= guiGetConfig(settings[F("gui")].to<JsonObject>());
|
||||
changed |= haspGetConfig(settings[F("hasp")].to<JsonObject>());
|
||||
// changed |= otaGetConfig(settings[F("ota")].to<JsonObject>());
|
||||
// changed |= tftGetConfig(settings[F("tft")].to<JsonObject>());
|
||||
|
||||
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());
|
||||
}
|
@ -3,6 +3,8 @@
|
||||
#include "ArduinoJson.h"
|
||||
#include "lvgl.h"
|
||||
|
||||
#include "ArduinoLog.h"
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP8266)
|
||||
#include <ESP8266WiFi.h>
|
||||
#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 <Syslog.h>
|
||||
#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<uint16_t>();
|
||||
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<uint16_t>();
|
||||
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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
}
|
@ -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);
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
#include "hasp_conf.h"
|
||||
#include <Arduino.h>
|
||||
#include "ArduinoLog.h"
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP8266)
|
||||
#include <ESP8266WiFi.h>
|
||||
@ -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
|
||||
}
|
@ -1,5 +1,13 @@
|
||||
#include "hasp_conf.h"
|
||||
#if HASP_USE_MQTT
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "ArduinoJson.h"
|
||||
#include "ArduinoLog.h"
|
||||
#include "PubSubClient.h"
|
||||
|
||||
#include "hasp_conf.h"
|
||||
#include "hasp_mqtt.h"
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
#include <Wifi.h>
|
||||
@ -8,9 +16,8 @@
|
||||
#include <EEPROM.h>
|
||||
#include <ESP.h>
|
||||
#endif
|
||||
#include <PubSubClient.h>
|
||||
|
||||
#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
|
||||
|
@ -1,8 +1,9 @@
|
||||
#include <Arduino.h>
|
||||
#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
|
||||
}
|
||||
|
@ -1,19 +1,24 @@
|
||||
#include <Arduino.h>
|
||||
#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 <Wifi.h>
|
||||
#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();
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user