From 8f9133bcc27a430e642e1cd6181fd48c7b51c285 Mon Sep 17 00:00:00 2001 From: Andrew Williams Date: Sat, 30 Jan 2021 10:07:17 +0000 Subject: [PATCH] Improve webserver page --- data/index.html | 46 +++++++++++++ include/ESPTemplateProcessor.h | 116 +++++++++++++++++++++++++++++++++ platformio.ini | 1 + src/busylight.cpp | 58 ++++++++++++----- 4 files changed, 203 insertions(+), 18 deletions(-) create mode 100644 data/index.html create mode 100644 include/ESPTemplateProcessor.h diff --git a/data/index.html b/data/index.html new file mode 100644 index 0000000..a67ac0f --- /dev/null +++ b/data/index.html @@ -0,0 +1,46 @@ + + + + + + + ~LIST~ + + + \ No newline at end of file diff --git a/include/ESPTemplateProcessor.h b/include/ESPTemplateProcessor.h new file mode 100644 index 0000000..264507c --- /dev/null +++ b/include/ESPTemplateProcessor.h @@ -0,0 +1,116 @@ +#ifndef ESP_TEMPLATE_PROCESSOR_H +#define ESP_TEMPLATE_PROCESSOR_H + +#ifdef ESP8266 +#define WebServer ESP8266WebServer +#include +#else +#include +#endif + +#include + +typedef String ProcessorCallback(const String& key); + +class ESPTemplateProcessor { + public: + ESPTemplateProcessor(WebServer& _server) : + server(_server) + { + } + + bool send(const String& filePath, ProcessorCallback& processor, char bookend = '~', bool silentSerial = false) + { + // Open file. + if(!LittleFS.exists(filePath)) { + if(!silentSerial) { + Serial.print("Cannot process "); Serial.print(filePath); Serial.println(": Does not exist."); + } + return false; + } + + File file = LittleFS.open(filePath, "r"); + if (!file) { + if(!silentSerial) { + Serial.print("Cannot process "); Serial.print(filePath); Serial.println(": Failed to open."); + } + return false; + } + + server.setContentLength(CONTENT_LENGTH_UNKNOWN); + server.sendHeader("Content-Type","text/html",true); + server.sendHeader("Cache-Control","no-cache"); + server.send(200); + //server.sendContent() + + // Process! + static const uint16_t MAX = 100; + String buffer; + int bufferLen = 0; + String keyBuffer; + int val; + char ch; + while ((val = file.read()) != -1) { + ch = char(val); + + // Lookup expansion. + if (ch == bookend) { + // Clear out buffer. + server.sendContent(buffer); + buffer = ""; + bufferLen = 0; + + // Process substitution. + keyBuffer = ""; + bool found = false; + while (!found && (val = file.read()) != -1) { + ch = char(val); + if (ch == bookend) { + found = true; + } else { + keyBuffer += ch; + } + } + + // Check for bad exit. + if (val == -1 && !found) { + if(!silentSerial) { + Serial.print("Cannot process "); Serial.print(filePath); Serial.println(": Unable to parse."); + } + return false; + } + + // Get substitution + String processed = processor(keyBuffer); + if(!silentSerial) { + Serial.print("Lookup '"); Serial.print(keyBuffer); Serial.print("' received: "); Serial.println(processed); + } + server.sendContent(processed); + } else { + bufferLen++; + buffer += ch; + if (bufferLen >= MAX) { + server.sendContent(buffer); + bufferLen = 0; + buffer = ""; + } + } + } + + if (val == -1) { + server.sendContent(buffer); + server.sendContent(""); + return true; + } else { + if(!silentSerial) { + Serial.print("Failed to process '"); Serial.print(filePath); Serial.println("': Didn't reach the end of the file."); + } + } + } + + + private: + WebServer &server; +}; + +#endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 166f854..9e0da9b 100644 --- a/platformio.ini +++ b/platformio.ini @@ -11,6 +11,7 @@ [env:wemos-d1] platform = espressif8266 board = d1 +board_build.filesystem = littlefs upload_speed = 460800 framework = arduino lib_deps = diff --git a/src/busylight.cpp b/src/busylight.cpp index d5a3f5a..8d85afd 100644 --- a/src/busylight.cpp +++ b/src/busylight.cpp @@ -12,7 +12,9 @@ WiFiClientSecure wifi_secure; char current_state[20]; #ifdef ENABLE_WEBSERVER +#include #include +#include "ESPTemplateProcessor.h" ESP8266WebServer server; #endif @@ -71,7 +73,7 @@ bool Switch_Status(String name) { Serial.println("Switching to " + name); for(int j=0; j"); - strcat(buffer, statuses[j].name); - strcat(buffer, "
"); +String ProcessIndexPage(const String& var) { + Serial.println(current_state); + if (var == "LIST") { + String buffer; + for(int j=0; j"); - server.send(200, "text/html", buffer); } void StatusLookup() { - if (Switch_Status(server.uri().substring(1))) { - server.send(204, "text/plain", "OK"); + if (Switch_Status(server.uri().substring(1))) { + server.sendHeader("Location", String("/"), true); + server.send ( 302, "text/plain", ""); return; } server.send(404, "text/plain", "Missing"); @@ -139,13 +148,15 @@ void setup() Serial.begin(9600); Serial.println(""); Serial.println("---"); - + + // Define the output pins pinMode(RED_LED_PIN, OUTPUT); pinMode(GREEN_LED_PIN, OUTPUT); pinMode(BLUE_LED_PIN, OUTPUT); Serial.println("Config - Pins: (" + String(RED_LED_PIN) + "," + String(GREEN_LED_PIN) + "," + String(BLUE_LED_PIN) + "), PWM: " + String(PWM_MAX_VALUE)); - + + // Start Wifi WiFi.begin(WIFI_SSID, WIFI_PASS); Serial.print("Connecting to " + String(WIFI_SSID)); while(WiFi.status()!= WL_CONNECTED) @@ -157,6 +168,7 @@ void setup() Serial.print("IP Address: "); Serial.println(WiFi.localIP()); + // Disable inbuilt LED, and go 'offline' digitalWrite(LED_BUILTIN, LOW); Switch_Status("offline"); @@ -166,9 +178,19 @@ void setup() #endif #ifdef ENABLE_WEBSERVER - server.on("/",IndexPage); - server.on("/health", [](){server.send(200,"text/plain","OK");}); - server.on("/state", [](){server.send(200,"text/plain", current_state);}); + if(!LittleFS.begin()){ + Serial.println("An Error has occurred while mounting LittleFS"); + return; + } + server.on("/", HTTP_GET, [](){ + ESPTemplateProcessor(server).send(String("/index.html"), ProcessIndexPage); + }); + server.on("/health", HTTP_GET, [](){ + server.send(200,"text/plain","OK"); + }); + server.on("/state", HTTP_GET, [](){ + server.send(200,"text/plain", current_state); + }); server.onNotFound(StatusLookup); server.begin(); #endif