cotestatnt / esp-fs-webserver

ESP32/ESP8266 webserver, WiFi manager and web editor Arduino library
MIT License
105 stars 27 forks source link

How to show json value to custom html page? #31

Closed arimukhlas closed 10 months ago

arimukhlas commented 11 months ago

Hi @cotestatnt

I want to show json value to customElement.h every first time I open the page. I found this from you and I follow the instruction

so I add handler and function to customHTML.ino like this

#include <esp-fs-webserver.h>   // https://github.com/cotestatnt/esp-fs-webserver

#include <FS.h>
#include <LittleFS.h>
#define FILESYSTEM LittleFS

#ifndef LED_BUILTIN
#define LED_BUILTIN 2
#endif

// Set this to 1 if you want clear the /config.json file at startup
#define CLEAR_OTIONS 0

struct tm sysTime;

// Test "options" values
uint8_t ledPin = LED_BUILTIN;
bool boolVar = true;
uint32_t longVar = 1234567890;
float floatVar = 15.5F;
String stringVar = "Test option String";

// ThingsBoard varaibles
String tb_deviceToken = "xxxxxxxxxxxxxxxxxxx";
String tb_device_key = "xxxxxxxxxxxxxxxxxxx";
String tb_secret_key = "xxxxxxxxxxxxxxxxxxx";
String tb_serverIP = "192.168.1.1";
uint16_t tb_port = 8181;

// Var labels (in /setup webpage)
#define LED_LABEL "The LED pin number"
#define BOOL_LABEL "A bool variable"
#define LONG_LABEL "A long variable"
#define FLOAT_LABEL "A float variable"
#define STRING_LABEL "A String variable"

#define TB_SERVER "ThingsBoard server address"
#define TB_PORT "ThingsBoard server port"
#define TB_DEVICE_TOKEN "ThingsBoard device token"
#define TB_DEVICE_KEY "Provisioning device key"
#define TB_SECRET_KEY "Provisioning secret key"

// Timezone definition to get properly time from NTP server
#define MYTZ "CET-1CEST,M3.5.0,M10.5.0/3"
struct tm Time;

#ifdef ESP8266
ESP8266WebServer server(80);
#elif defined(ESP32)
WebServer server(80);
#endif

FSWebServer myWebServer(FILESYSTEM, server);

#include "customElements.h"

////////////////////////////////  Filesystem  /////////////////////////////////////////
void startFilesystem() {
  // FILESYSTEM INIT
  if ( FILESYSTEM.begin()) {
    File root = FILESYSTEM.open("/", "r");
    File file = root.openNextFile();
    while (file) {
      const char* fileName = file.name();
      size_t fileSize = file.size();
      Serial.printf("FS File: %s, size: %lu\n", fileName, (long unsigned)fileSize);
      file = root.openNextFile();
    }
    Serial.println();
  }
  else {
    Serial.println(F("ERROR on mounting filesystem. It will be formmatted!"));
    FILESYSTEM.format();
    ESP.restart();
  }
}

bool loadOptions() {
  if (FILESYSTEM.exists(myWebServer.configFile())) {
    File file = FILESYSTEM.open(myWebServer.configFile(), "r");
    DynamicJsonDocument doc(file.size() * 1.33);
    if (!file)
      return false;

    DeserializationError error = deserializeJson(doc, file);
    if (error)
      return false;

    ledPin = doc[LED_LABEL];
    boolVar = doc[BOOL_LABEL];
    longVar = doc[LONG_LABEL];
    floatVar = doc[FLOAT_LABEL]["value"];
    stringVar = doc[STRING_LABEL].as<String>();

    tb_deviceToken = doc[TB_DEVICE_TOKEN].as<String>();
    tb_device_key = doc[TB_DEVICE_KEY].as<String>();
    tb_secret_key = doc[TB_SECRET_KEY].as<String>();
    tb_serverIP = doc[TB_SERVER].as<String>();
    tb_port = doc[TB_PORT];

    file.close();

    Serial.println();
    Serial.printf("LED pin value: %d\n", ledPin);
    Serial.printf("Bool value: %d\n", boolVar);
    Serial.printf("Long value: %ld\n",longVar);
    Serial.printf("Float value: %d.%d\n", (int)floatVar, (int)(floatVar*1000)%1000);
    Serial.println(stringVar);
    return true;
  }
  else
    Serial.println(F("Configuration file not exist"));
  return false;
}

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

  // FILESYSTEM INIT
  startFilesystem();

  // Load configuration (if not present, default will be created when webserver will start)
#if CLEAR_OPTIONS
  if (myWebServer.clearOptions())
    ESP.restart();
#endif
  if (loadOptions())
    Serial.println(F("Application option loaded\n\n"));
  else
    Serial.println(F("Application options NOT loaded!\n\n"));

  // Configure /setup page and start Web Server

  // Add a new options box
  myWebServer.addOptionBox("My Options");
  myWebServer.addOption(LED_LABEL, ledPin);
  myWebServer.addOption(LONG_LABEL, longVar);
  // Float fields can be configured with min, max and step properties
  myWebServer.addOption(FLOAT_LABEL, floatVar, 0.0, 100.0, 0.01);
  myWebServer.addOption(STRING_LABEL, stringVar);
  myWebServer.addOption(BOOL_LABEL, boolVar);

  // Add a new options box
  myWebServer.addOptionBox("ThingsBoard");
  myWebServer.addOption(TB_SERVER, tb_serverIP);
  myWebServer.addOption(TB_PORT, tb_port);
  myWebServer.addOption(TB_DEVICE_KEY, tb_device_key);
  myWebServer.addOption(TB_SECRET_KEY, tb_secret_key);
  myWebServer.addOption(TB_DEVICE_TOKEN, tb_deviceToken);

  // Add a new options box with custom code injected
  myWebServer.addOptionBox("Custom HTML");
  // How many times you need (for example one in different option box)
  myWebServer.addHTML(custom_html, "fetch-test", /*overwite*/ true);
  // Only once (CSS and Javascript will be appended to head and body)
  myWebServer.addCSS(custom_css, /*overwite*/ false);
  myWebServer.addJavascript(custom_script, /*overwite*/ false);

  // Try to connect to stored SSID, start AP if fails after timeout
  IPAddress myIP = myWebServer.startWiFi(15000, "ESP_AP", "123456789" );
  myWebServer.addHandler("/getValues", HTTP_GET, getActualValue);

  // Start webserver
  if (myWebServer.begin()) {
    Serial.print(F("\nESP Web Server started on IP Address: "));
    Serial.println(myIP);
    Serial.println(F("Open /setup page to configure optional parameters"));
    Serial.println(F("Open /edit page to view and edit files"));
    Serial.println(F("Open /update page to upload firmware and filesystem updates\n\n"));
  }
}

void loop() {
  myWebServer.run();
}

void getActualValue() {
  StaticJsonDocument<256> doc;
  String payload;
  doc["sunrise"] = "08:00";
  doc["sunset"] = "20:00";
  doc["automatic"] = true;
  serializeJsonPretty(doc, payload);
  // Send payoad to client
  myWebServer.webserver->send(200, "text/json", payload);
}

and add script to customElement.h like this

static const char custom_html[] PROGMEM = R"EOF(
<main onload="getActualValues()">
  <h3>Test Static Json Value</h3>
  <p id="sunrise-actual">xxxx</p> 
  <p id="sunset-actual">xxxx</p> 
</main>
)EOF";

static const char custom_css[] PROGMEM = R"EOF(
pre{
    font-family: Monaco,Menlo,Consolas,'Courier New',monospace;
    color: #333;
    line-height: 20px;
    background-color: #f5f5f5;
    border: 1px solid rgba(0,0,0,0.15);
    border-radius: 6px;
    overflow-y: scroll;
    min-height: 350px;
    font-size: 85%;
}
.select{
  width: 25%;
  height:40px;
  padding-top: 10px;
  padding-left: 20px;
  border:1px solid #ccc;
  border-radius: 6px;
  box-shadow: 0 1px 2px 0 rgba(220, 220, 230, 0.5);
}
.body{
  background-color: cadetblue;
}
)EOF";

static const char custom_script[] PROGMEM = R"EOF(
function fetchEndpoint() {
  var mt = $('httpmethod').options[$('httpmethod').selectedIndex].text;
  var url = $('url').value + mt.toLowerCase();
  var bd = (mt != 'GET') ? 'body: ""' : '';
  var options = {
    method: mt,
    bd
  };
  fetch(url, options)
  .then(response => response.text())
  .then(txt => {
    $('payload').innerHTML = txt;
  });
}

$('fetch').addEventListener('click', fetchEndpoint);

function getActualValues() {
      fetch("/getValues")

      .then(response => response.json())
      .then(data => {
        console.log(data);
        document.getElementById("sunrise-actual").innerHTML = data.sunrise;
        document.getElementById("sunset-actual").innerHTML = data.sunset;
      })
    }

)EOF";

but nothing happen. So Is it correct that the steps I have used?

arimukhlas commented 10 months ago

case close, I use this on script.

on sketch

myWebServer.addHandler("/getValues", HTTP_GET, getActualValue);

...

void getActualValue() {
  StaticJsonDocument<256> doc;
  String payload;
  doc["sunrise"] = "08:00";
  doc["sunset"] = "20:00";
  serializeJsonPretty(doc, payload);
  myWebServer.webserver->send(200, "text/json", payload);
}

on additional js script

setInterval(getActualValues,5000);

function getActualValues() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var data = JSON.parse(this.responseText);
      document.getElementById("sunrise-actual").innerHTML = data.sunrise;
      document.getElementById("sunset-actual").innerHTML = data.sunset;
    }
  };
  xhttp.open("GET", "/getValues2", true);
  xhttp.send();
}