123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- /*
- Elements.ino, Example for the AutoConnect library.
- Copyright (c) 2020, Hieromon Ikasamo
- https://github.com/Hieromon/AutoConnect
- This software is released under the MIT License.
- https://opensource.org/licenses/MIT
- This example demonstrates the typical behavior of AutoConnectElement.
- It also represents a basic structural frame for saving and reusing
- values entered in a custom web page into flash.
- */
- #if defined(ARDUINO_ARCH_ESP8266)
- #include <ESP8266WiFi.h>
- #include <ESP8266WebServer.h>
- using WebServerClass = ESP8266WebServer;
- #elif defined(ARDUINO_ARCH_ESP32)
- #include <WiFi.h>
- #include <WebServer.h>
- #include <SPIFFS.h>
- using WebServerClass = WebServer;
- #endif
- #include <AutoConnect.h>
- /*
- AC_USE_SPIFFS indicates SPIFFS or LittleFS as available file systems that
- will become the AUTOCONNECT_USE_SPIFFS identifier and is exported as shown
- the valid file system. After including AutoConnect.h, the Sketch can determine
- whether to use FS.h or LittleFS.h by AUTOCONNECT_USE_SPIFFS definition.
- */
- #include <FS.h>
- #if defined(ARDUINO_ARCH_ESP8266)
- #ifdef AUTOCONNECT_USE_SPIFFS
- FS& FlashFS = SPIFFS;
- #else
- #include <LittleFS.h>
- FS& FlashFS = LittleFS;
- #endif
- #elif defined(ARDUINO_ARCH_ESP32)
- #include <SPIFFS.h>
- fs::SPIFFSFS& FlashFS = SPIFFS;
- #endif
- #define CONFIG_FILE "/elements.json"
- #define USERNAME "username_you_wish" // For HTTP authentication
- #define PASSWORD "password_you_wish" // For HTTP authentication
- static const char PAGE_ELEMENTS[] PROGMEM = R"(
- {
- "uri": "/elements",
- "title": "Elements",
- "menu": true,
- "element": [
- {
- "name": "tablecss",
- "type": "ACStyle",
- "value": "table{font-family:arial,sans-serif;border-collapse:collapse;width:100%;color:black;}td,th{border:1px solid #dddddd;text-align:center;padding:8px;}tr:nth-child(even){background-color:#dddddd;}"
- },
- {
- "name": "text",
- "type": "ACText",
- "value": "AutoConnect element behaviors collection",
- "style": "font-family:Arial;font-size:18px;font-weight:400;color:#191970"
- },
- {
- "name": "check",
- "type": "ACCheckbox",
- "value": "check",
- "label": "Check",
- "labelposition": "infront",
- "checked": true
- },
- {
- "name": "input",
- "type": "ACInput",
- "label": "Text input",
- "placeholder": "This area accepts hostname patterns",
- "pattern": "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$"
- },
- {
- "name": "pass",
- "type": "ACInput",
- "label": "Password",
- "apply": "password"
- },
- {
- "name": "number",
- "type": "ACInput",
- "label": "Number",
- "value": "3",
- "apply": "number",
- "pattern": "\\d*"
- },
- {
- "name": "hr",
- "type": "ACElement",
- "value": "<hr style=\"height:1px;border-width:0;color:gray;background-color:#52a6ed\">",
- "posterior": "par"
- },
- {
- "name": "radio",
- "type": "ACRadio",
- "value": [
- "Button-1",
- "Button-2",
- "Button-3"
- ],
- "label": "Radio buttons",
- "arrange": "vertical",
- "checked": 1
- },
- {
- "name": "select",
- "type": "ACSelect",
- "option": [
- "Option-1",
- "Option-2",
- "Option-3"
- ],
- "label": "Select",
- "selected": 2
- },
- {
- "name": "table",
- "type": "ACElement",
- "value": "<table><tr><th>Board</th><th>Platform</th></tr><tr><td>NodeMCU</td><td>Espressif8266</td></tr><tr><td>ESP32-DevKitC</td><td>Espressif32</td></tr></table>",
- "posterior": "par"
- },
- {
- "name": "upload",
- "type": "ACFile",
- "label": "Upload:",
- "store": "fs"
- },
- {
- "name": "load",
- "type": "ACSubmit",
- "value": "Load",
- "uri": "/elements"
- },
- {
- "name": "save",
- "type": "ACSubmit",
- "value": "Save",
- "uri": "/save"
- },
- {
- "name": "adjust_width",
- "type": "ACElement",
- "value": "<script type=\"text/javascript\">window.onload=function(){var t=document.querySelectorAll(\"input[type='text']\");for(i=0;i<t.length;i++){var e=t[i].getAttribute(\"placeholder\");e&&t[i].setAttribute(\"size\",e.length*.8)}};</script>"
- }
- ]
- }
- )";
- static const char PAGE_SAVE[] PROGMEM = R"(
- {
- "uri": "/save",
- "title": "Elements",
- "menu": false,
- "element": [
- {
- "name": "caption",
- "type": "ACText",
- "format": "Elements have been saved to %s",
- "style": "font-family:Arial;font-size:18px;font-weight:400;color:#191970"
- },
- {
- "name": "validated",
- "type": "ACText",
- "style": "color:red"
- },
- {
- "name": "echo",
- "type": "ACText",
- "style": "font-family:monospace;font-size:small;white-space:pre;"
- },
- {
- "name": "ok",
- "type": "ACSubmit",
- "value": "OK",
- "uri": "/elements"
- }
- ]
- }
- )";
- WebServerClass server;
- AutoConnect portal(server);
- AutoConnectConfig config;
- AutoConnectAux elementsAux;
- AutoConnectAux saveAux;
- void setup() {
- delay(1000);
- Serial.begin(115200);
- Serial.println();
- // Responder of root page handled directly from WebServer class.
- server.on("/", []() {
- String content = "Place the root page with the sketch application. ";
- content += AUTOCONNECT_LINK(COG_24);
- server.send(200, "text/html", content);
- });
- // Load a custom web page described in JSON as PAGE_ELEMENT and
- // register a handler. This handler will be invoked from
- // AutoConnectSubmit named the Load defined on the same page.
- elementsAux.load(FPSTR(PAGE_ELEMENTS));
- elementsAux.on([] (AutoConnectAux& aux, PageArgument& arg) {
- if (portal.where() == "/elements") {
- // Use the AutoConnect::where function to identify the referer.
- // Since this handler only supports AutoConnectSubmit called the
- // Load, it uses the uri of the custom web page placed to
- // determine whether the Load was called me or not.
- FlashFS.begin();
- File param = FlashFS.open(CONFIG_FILE, "r");
- if (param) {
- aux.loadElement(param, { "text", "check", "input", "input", "pass", "number", "radio", "select" } );
- param.close();
- }
- FlashFS.end();
- }
- return String();
- });
- saveAux.load(FPSTR(PAGE_SAVE));
- saveAux.on([] (AutoConnectAux& aux, PageArgument& arg) {
- // You can validate input values before saving with
- // AutoConnectInput::isValid function.
- // Verification is using performed regular expression set in the
- // pattern attribute in advance.
- AutoConnectInput& input = elementsAux["input"].as<AutoConnectInput>();
- aux["validated"].value = input.isValid() ? String() : String("Input data pattern missmatched.");
- // The following line sets only the value, but it is HTMLified as
- // formatted text using the format attribute.
- aux["caption"].value = CONFIG_FILE;
- #if defined(ARDUINO_ARCH_ESP8266)
- FlashFS.begin();
- #elif defined(ARDUINO_ARCH_ESP32)
- FlashFS.begin(true);
- #endif
- File param = FlashFS.open(CONFIG_FILE, "w");
- if (param) {
- // Save as a loadable set for parameters.
- elementsAux.saveElement(param, { "text", "check", "input", "pass", "number", "radio", "select" });
- param.close();
- // Read the saved elements again to display.
- param = FlashFS.open(CONFIG_FILE, "r");
- aux["echo"].value = param.readString();
- param.close();
- }
- else {
- aux["echo"].value = "Filesystem failed to open.";
- }
- FlashFS.end();
- return String();
- });
- portal.join({ elementsAux, saveAux });
- config.auth = AC_AUTH_BASIC;
- config.authScope = AC_AUTHSCOPE_AUX;
- config.username = USERNAME;
- config.password = PASSWORD;
- config.ticker = true;
- portal.config(config);
- portal.begin();
- }
- void loop() {
- portal.handleClient();
- }
|