From 168be0558683e864b5ea88d66b9ea486a1d67831 Mon Sep 17 00:00:00 2001 From: Gregg Date: Sat, 5 Mar 2022 10:03:13 -0600 Subject: [PATCH] Progress on SpanWebLog() --- src/HAP.cpp | 21 +++++++++++++--- src/HomeSpan.cpp | 63 +++++++++++++++++++++++++++++++++++++++--------- src/HomeSpan.h | 46 ++++++++++++++++++++--------------- src/Settings.h | 2 ++ 4 files changed, 99 insertions(+), 33 deletions(-) diff --git a/src/HAP.cpp b/src/HAP.cpp index 98383e2..c343d4b 100644 --- a/src/HAP.cpp +++ b/src/HAP.cpp @@ -342,7 +342,7 @@ void HAPClient::processRequest(){ return; } - if(!strncmp(body,"GET /status ",12)){ // GET STATUS - AN OPTIONAL, NON-HAP-R2 FEATURE + if(homeSpan.webLog && !strncmp(body,homeSpan.webLog->statusURL.c_str(),homeSpan.webLog->statusURL.length())){ // GET STATUS - AN OPTIONAL, NON-HAP-R2 FEATURE getStatusURL(); return; } @@ -1268,21 +1268,36 @@ int HAPClient::getStatusURL(){ String response="HTTP/1.1 200 OK\r\nContent-type: text/html\r\n\r\n"; response+="HomeSpan Status\n"; - response+="\n"; response+="\n"; response+="

" + String(homeSpan.displayName) + "

\n"; response+="\n"; response+="\n"; - response+="\n"; + response+="\n"; response+="\n"; response+="\n"; response+="\n"; response+="\n"; response+="\n"; + response+="\n"; response+="
Up Time:" + String(uptime) + "
Boot Time:" + String(homeSpan.bootTime) + "
Boot Time:" + String(homeSpan.webLog->bootTime) + "
ESP32 Board:" + String(ARDUINO_BOARD) + "
Arduino-ESP Version:" + String(ARDUINO_ESP_VERSION) + "
ESP-IDF Version:" + String(ESP_IDF_VERSION_MAJOR) + "." + String(ESP_IDF_VERSION_MINOR) + "." + String(ESP_IDF_VERSION_PATCH) + "
HomeSpan Version:" + String(HOMESPAN_VERSION) + "
Sketch Version:" + String(homeSpan.getSketchVersion()) + "
Max Log Entries:" + String(homeSpan.webLog->maxEntries) + "
\n"; + response+="

"; + + if(homeSpan.webLog->maxEntries>0){ + response+="\n"; + int lastIndex=homeSpan.webLog->nEntries-homeSpan.webLog->maxEntries; + if(lastIndex<0) + lastIndex=0; + for(int i=homeSpan.webLog->nEntries-1;i>=lastIndex;i--){ + response+=""; + } + + response+="
EntryUp TimeLog TimeMessage
" + String(i+1) + "" + "TBD1" "" + "TBD2" + "" + String(homeSpan.webLog->log[i%homeSpan.webLog->maxEntries].message) + "
\n"; + } + response+=""; LOG2("\n>>>>>>>>>> "); diff --git a/src/HomeSpan.cpp b/src/HomeSpan.cpp index 2942197..69a6948 100644 --- a/src/HomeSpan.cpp +++ b/src/HomeSpan.cpp @@ -560,17 +560,9 @@ void Span::checkConnect(){ } } - if(timeServer){ - Serial.printf("Acquiring Time from %s... ",timeServer,timeZone); - configTzTime(timeZone,timeServer); - struct tm timeinfo; - if(getLocalTime(&timeinfo)){ - strftime(bootTime,sizeof(bootTime),"%c",&timeinfo); - Serial.printf("%s\n\n",bootTime); - } else { - Serial.printf("Can't access Time Server - time-keeping disabled!\n\n"); - timeServer=NULL; - } + if(webLog){ + Serial.printf("Web Logging enabled at http://%s.local:%d%swith max number of entries=%d\n\n",hostName,tcpPortNum,webLog->statusURL.c_str()+4,webLog->maxEntries); + webLog->initTime(); } Serial.printf("Starting HAP Server on port %d supporting %d simultaneous HomeKit Controller Connections...\n",tcpPortNum,maxConnections); @@ -1933,3 +1925,52 @@ SpanUserCommand::SpanUserCommand(char c, const char *s, void (*f)(const char *, homeSpan.UserCommands[c]=this; } + +/////////////////////////////// +// SpanWebLog // +/////////////////////////////// + +SpanWebLog::SpanWebLog(uint16_t maxEntries, const char *serv, const char *tz, const char *url){ + this->maxEntries=maxEntries; + timeServer=serv; + timeZone=tz; + statusURL="GET /" + String(url) + " "; + log = (log_t *)calloc(maxEntries,sizeof(log_t)); +} + +/////////////////////////////// + +void SpanWebLog::initTime(){ + if(!timeServer) + return; + + Serial.printf("Acquiring Time from %s (%s)... ",timeServer,timeZone); + configTzTime(timeZone,timeServer); + struct tm timeinfo; + if(getLocalTime(&timeinfo)){ + strftime(bootTime,sizeof(bootTime),"%c",&timeinfo); + Serial.printf("%s\n\n",bootTime); + homeSpan.reserveSocketConnections(1); + timeInit=true; + } else { + Serial.printf("Can't access Time Server (or Time Zone improperly specified) - time-keeping not initialized!\n\n"); + } +} + +/////////////////////////////// + +void SpanWebLog::addLog(const char *m){ + if(maxEntries==0) + return; + + int index=nEntries%maxEntries; + + log[index].upTime=esp_timer_get_time()/1e6; + if(timeInit) + getLocalTime(&log[index].clockTime); + else + log[index].clockTime.tm_year=0; + log[index].message=m; + + nEntries++; +} diff --git a/src/HomeSpan.h b/src/HomeSpan.h index c8cf736..362fa7e 100644 --- a/src/HomeSpan.h +++ b/src/HomeSpan.h @@ -95,6 +95,28 @@ struct SpanBuf{ // temporary storage buffer for us /////////////////////////////// +struct SpanWebLog{ // optional web status/log data + uint16_t maxEntries; // max number of log entries; + int nEntries=0; // total cumulative number of log entries + const char *timeServer; // optional time server to use for acquiring clock time + const char *timeZone; // optional time-zone specification + boolean timeInit=false; // flag to indicate time has been initialized + char bootTime[33]="Unknown"; // boot time + String statusURL; // URL of status log + + struct log_t { // log entry type + uint32_t upTime; // number of seconds since booting + struct tm clockTime; // clock time + const char *message; // pointers to log entries of arbitrary size + } *log=NULL; // array of log entries + + SpanWebLog(uint16_t maxEntries, const char *serv, const char *tz, const char *url); + void initTime(); + void addLog(const char *m); +}; + +/////////////////////////////// + struct Span{ const char *displayName; // display name for this device - broadcast as part of Bonjour MDNS @@ -114,10 +136,6 @@ struct Span{ nvs_handle charNVS; // handle for non-volatile-storage of Characteristics data nvs_handle wifiNVS=0; // handle for non-volatile-storage of WiFi data char pairingCodeCommand[12]=""; // user-specified Pairing Code - only needed if Pairing Setup Code is specified in sketch using setPairingCode() - const char *timeZone=NULL; // optional time-zone specification - const char *timeServer=NULL; // optional time server to use for acquiring clock time - char bootTime[33]="Unknown"; // boot time - SpanWebLog *webLog=NULL; // optional web status/log boolean connected=false; // WiFi connection status unsigned long waitTime=60000; // time to wait (in milliseconds) between WiFi connection attempts @@ -145,6 +163,7 @@ struct Span{ Blinker statusLED; // indicates HomeSpan status PushButton controlButton; // controls HomeSpan configuration and resets Network network; // configures WiFi and Setup Code via either serial monitor or temporary Access Point + SpanWebLog *webLog=NULL; // optional web status/log SpanConfig hapConfig; // track configuration changes to the HAP Accessory database; used to increment the configuration number (c#) when changes found vector Accessories; // vector of pointers to all Accessories @@ -204,7 +223,10 @@ struct Span{ void deleteStoredValues(){processSerialCommand("V");} // deletes stored Characteristic values from NVS void enableOTA(boolean auth=true){otaEnabled=true;otaAuth=auth;reserveSocketConnections(1);} // enables Over-the-Air updates, with (auth=true) or without (auth=false) authorization password - void setTimeServer(const char *serv, const char *tz){timeServer=serv;timeZone=tz;reserveSocketConnections(1);} // sets optional time server and time zone + + void enableWebLog(uint16_t maxEntries=0, const char *serv=NULL, const char *tz="UTC", const char *url=DEFAULT_WEBLOG_URL){ // enable Web Logging + webLog=new SpanWebLog(maxEntries, serv, tz, url); + } [[deprecated("Please use reserveSocketConnections(n) method instead.")]] void setMaxConnections(uint8_t n){requestedMaxCon=n;} // sets maximum number of simultaneous HAP connections @@ -679,20 +701,6 @@ struct SpanUserCommand { SpanUserCommand(char c, const char *s, void (*f)(const char *, void *), void *arg); }; -/////////////////////////////// - -struct SpanWebLog{ // optional web status/log data - int maxEntries; // max number of log entries; -1 = do not create log or status; 0 = create status but no log; 1..N = create status and log with N entries - int nEntries=0; // current number of log entries - - struct log_t { // log entry type - uint32_t upTime; // number of seconds since booting - struct tm clockTime; // clock time - char *message; // pointers to log entries of arbitrary size - } *log=NULL; // array of log entries - -}; - ///////////////////////////////////////////////// #include "Span.h" diff --git a/src/Settings.h b/src/Settings.h index 1c73c56..6c975cc 100644 --- a/src/Settings.h +++ b/src/Settings.h @@ -81,6 +81,8 @@ #define DEFAULT_TCP_PORT 80 // change with homeSpan.setPort(port); +#define DEFAULT_WEBLOG_URL "status" // change with optional fourth argument in homeSpan.enableWebLog() + ///////////////////////////////////////////////////// // STATUS LED SETTINGS //