The use of the ESP8266 in the world of IoT

User avatar
By mrlightsman
#82013 I am working on a very similar project. I have managed to use json and SPIFFS to take data from my input text on the webserver page and store it in SPIFFS. I can then use the data in my sketch and it is non-volatile, in that I can use it even after power down/power up of the ESP.

What I cannot figure out is how to autofill the input text, using the value parameter, with a variable from the sketch.


In the listed code, I use the webserver input to populate the variable ap_SSID, ap_Password, and Local_Device_One. What I would like to have happen is when the webpage is invoked at a later date is for the text input to be autofilled with the values held by these three variables.

I've seen conversations about using a javascript, I just don't have enough knowledge to decipher and apply them to my setting. Any help is appreciated. Thank you.

Here is my code (trimmed to the conversation).

Code: Select all#include <FS.h>
#include <arduino.h>
#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WebServer.h>


ESP8266WiFiMulti wifiMulti;
ESP8266WebServer server(80);

String webPage; //to store html code from htmlpage

//Variable for sample action
char Local_Device_One[25];

 
//Define the local IP variables
char ap_SSID[15] = "New Box"; //SSID for ESP when in AP mode
char ap_Password[9] = "password";          //Password for ESP when in AP mode

const char htmlPage[]PROGMEM=R"=====(
<!DOCTYPE html>
<html>
<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">
<link rel=\"icon\" href=\"data:,\">

<style>body { text-align: center; font-family: \"Trebuchet MS\", Arial;}
table { border-collapse:collapse; width:35%; margin-left:auto; margin-right:auto; }
th { padding:12px; background-color: #0043af; color: white; }
tr { border:1px solid #ddd; padding:12px; }
tr:hover { background-color: #bcbcbc; }
td { border: none; padding:12px; }

.button {background-color: #195B6A; border: none; color: white; padding: 12px 40px;
text-align: center; font-family: \"Trebuchet MS\", Arial;
text-direction: none; font-size: 30px; margin: 2px; cursor: pointer;}

server.send(200,"</style></head><body><h1>Device Configuration Portal</h1>

<FORM METHOD="POST"action="/">

<h3>Access Point Credentials</h3>
<table>
<tr><th>Name</th><td><input type="text" name="custom_ap_SSID" value=ap_SSID></td></tr>
<tr><th>Password</th><td><input type="text" name="custom_ap_Password" value=ap_Password></td></tr>
<tr><th>Device One</th><td><input type="text" name="custom_Local_Device_One" value="Local_Device_One"></td></tr>
</table>
<input type="submit" value="Submit Changes">
</form>
</body>
</html>
)=====";

void handleConfigurationPage() {
  webPage=htmlPage;

 server.arg("custom_ap_SSID").toCharArray(ap_SSID,15);
 server.arg("custom_ap_Password").toCharArray(ap_Password,9);
 server.arg("custom_Local_Device_One").toCharArray(Local_Device_One,25);

 Serial.println("Text Received, contents:");
 Serial.println("AP SSID");
 Serial.println(ap_SSID);
 Serial.println("AP Password:");
 Serial.println(ap_Password);
 Serial.println("Local Device one is:");
 Serial.println(Local_Device_One);

 server.send(200,"text/html",webPage);

   //save the custom parameters to FS
    Serial.println("saving config");
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();
    json["ap_SSID"] = ap_SSID;
    json["ap_Password"] = ap_Password;
    json["Local_Device_One"] = Local_Device_One;

        File configFile = SPIFFS.open("/config.json", "w");
    if (!configFile) {
      Serial.println("failed to open config file for writing");
    }

    json.prettyPrintTo(Serial);
    json.printTo(configFile);
    configFile.close();
    //end save
}

void setupWifi() {
//  WiFi.mode(WIFI_STA);
  wifiMulti.addAP("SSID1", "PW1");
  wifiMulti.addAP("SSID2", "PW2");
  wifiMulti.addAP("SSID3", "PW3");
  wifiMulti.addAP("SSID4", "PW4");

  Serial.println("Connecting Wifi...");
  while (wifiMulti.run() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("Connected to SSID: ");
  Serial.println(WiFi.SSID());
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void setup() {
  Serial.begin(115200);
//  Serial.println();


//  SPIFFS.format();  //clean FS, for testing

  //read configuration from FS json
  Serial.println("mounting FS...");

  if (SPIFFS.begin()) {
    Serial.println("mounted file system");
    if (SPIFFS.exists("/config.json")) {
      //file exists, reading and loading
      Serial.println("reading config file");
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        Serial.println("opened config file");
        size_t size = configFile.size();
        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject(buf.get());
        json.printTo(Serial);
        if (json.success()) {
          Serial.println("\nparsed json");

          strcpy(ap_SSID, json["ap_SSID"]);
          strcpy(ap_Password, json["ap_Password"]);
          strcpy(Local_Device_One, json["Local_Device_One"]);
          //add other variables here

        } else {
          Serial.println("failed to load json config");
        }
      }
    }
  } else {
    Serial.println("failed to mount FS");
  }
  //end read
 
  setupWifi();

  server.on("/", handleConfigurationPage);
  server.begin();
  Serial.println("HTTP Server Started");

}
void loop() {
  server.handleClient();
}
User avatar
By mrlightsman
#82093 So I have done a little more work with this. Here is how I've been able to get data from a text input box on a website and use it in my sketch.

The typical html code for an input text box might look something like this:
Code: Select all<input type="text" name="custom_Name" value="Name Here">

Which creates an input box, custom_Name, and displays an initial value of "Name Here."


What I wanted to do was to have the initial value be that of a variable defined in my sketch. In order to do this, I found I had to nullify the quotes and break up the code. For this project, I build the webpage html in a sting then do a server.send command at the end.


In this example, I have a char name[9] that I plan to populate. Here is what the above code looks like so that it will display the value of name as the initial value of the textbox:
Code: Select all  webPage += "<input type=\"text\" name=\"custom_Name\" value=\"";
  webPage += name;
  webPage += "\">";

In this case, you will see I had to nullify the " of the original html and breakout the lines so I could display the variable.


Finally, in order to use my newly acquired text input data, I use the server.arg technique to write custom_Name into name:
Code: Select allserver.arg("custom_Name").toCharArray(name,9);


char name now contains the data from the text input box and can be used within your sketch as needed.

I hope my learning experience is helpful to others.
User avatar
By rudy
#82095 I had posted an example on a similar question.
viewtopic.php?p=80684#p80684

The web page is stored using the rawliteral method that you were using in your initial post. The page is rendered and then AJAX is used to populate the displayed variables shown on the page.

I didn't like the String method you ended up using. Memory usage was one concern, but the main one for me was the readability of the html code.

This was the best example I had at the time. It is an application I use and has a lot more stuff in it. I would have preferred to create and example only demonstrating a single page and the variable display and updating, but I was short on time.

The code is for a relay time clock to control the block heater for my car. I can set the on and off times, and if the timer is enabled. It saves the values in a structure to the simulated eeprom. If you look at it, there are multiple file with different tabs. The web.h one is the one with the web page code.
User avatar
By davydnorris
#82102 If you're already storing the data as a json document in your SPIFFS, then why don't you simply use a fetch of the json in your html page?

Create a small JavaScript action for onLoad that requests the json file from the embedded server and parses it into default values on the page, and create a handler function in your embedded server to return the SPIFFS copy of the json, or an empty json doc if you haven't saved.

That's what I do for my config pages (I don't use SPIFFS to store but I send as json)