Home > OS >  Refresh div every second
Refresh div every second

Time:07-06

this is the source code of a webpage made for an ESP8266 Web server ("@t", "@a", "@p" and "@h" are replaced by actual values using a C function):

<!DOCTYPE html>
<html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Weather Station</title>
    <style>
            html{
            font-family: Helvetica;
            display: inline-block;
            margin: 0px auto;
            text-align: center;
            }
            body{
            margin-top: 50px;
            }
            h1{
            color: #444444;
            margin: 50px auto 30px;
            }
            p{
            font-size: 24px;
            color: #444444;
            margin-bottom: 10px;
            }
    </style>
    
    </head>
    <body>
        <div id="webpage\">
        <h1>Weather Station</h1>
        <p>Temperature: @t &deg;C</p>
        <p>Humidity: @h %</p>
        <p>Pressure: @p hPa</p>
        <p>Altitude: @a m</p>
        </div>
    </body>
</html>

Is it possible to refresh just that one div (the values part) in the source? Thanks.

EDIT: if anyone is curious about how everything works, this is the main source file:

// SPDX-License-Identifier: GPL-3.0-or-later
/*  

Copyright (c) 2022 Nicolò Cantori

Module Name:

    main.cpp

Abstract:

    Main module for weather station Wi-Fi server.

Author:

    Nicolò Cantori (ncant)      03-July-2022

Revision History:

--*/

#include <Arduino.h>
#include <ESP8266WebServer.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include "data.hpp"

#define SEA_LEVEL_PRESSURE_HPA (1013.25)

void handle_OnConnect();
void handle_NotFound();

Adafruit_BME280 bme;

float temperature, humidity, pressure, altitude;

//-- Put your SSID & password here: ----------------------------------------
const char* ssid  = "Wi-Fi_Test";
const char* psw   = "nicolo04";
//--------------------------------------------------------------------------

ESP8266WebServer server(80);

String webpage_buf = "";


void setup()
{
    Serial.begin(9600);
    delay(100);

    // Build & store our webpage into a String variable:

    Serial.println("Starting up. Please wait...");

    for (unsigned int i = 0; i < webpage_html_len; i  )
    {
        webpage_buf  = (char)webpage_html[i];
    }

    // Initialize sensor:
    bme.begin(0x76);

    // Connect to local Wi-Fi network:

    Serial.print("Connecting to "); Serial.print(ssid);
    WiFi.begin(ssid, psw);

    // Check if board is connected to Wi-Fi network:

   while (WiFi.status() != WL_CONNECTED)
   {
        delay(1000);
        Serial.print(".");
   }

    // Done.

    Serial.println("\nWi-Fi connection enstablished!");
    Serial.print("Got IP: "); Serial.println(WiFi.localIP());
    
    server.on("/", handle_OnConnect);
    server.onNotFound(handle_NotFound);

    server.begin();
    Serial.println("HTTP server is up.");
}


void loop()
{
    server.handleClient();
}


String SendHTML(
    const float temperature,
    const float humidity,
    const float pressure,
    const float altitude
    )

/*  

Routine Description:

    Makes a webpage using the given arguments.

--*/

{
    webpage_buf.replace("@t", String(temperature));
    webpage_buf.replace("@h", String(humidity));
    webpage_buf.replace("@p", String(pressure));
    webpage_buf.replace("@a", String(altitude));

    return webpage_buf;
}


void handle_OnConnect()
{
    temperature = bme.readTemperature();
    humidity    = bme.readHumidity();
    pressure    = bme.readPressure() / 100.0F;
    altitude    = bme.readAltitude(SEA_LEVEL_PRESSURE_HPA);

    server.send(200, "text/html", SendHTML(temperature,
                                           humidity,
                                           pressure,
                                           altitude));
}


void handle_NotFound()
{
    server.send(200, "text/plain", "Not Found.");
}

data.hpp contains the converted webpage data instead:

// SPDX-License-Identifier: GPL-3.0-or-later
/*  

Copyright (c) 2022 Nicolò Cantori

Module Name:

    data.hpp

Abstract:

    Webpage Unicode data blob.

Author:

    Nicolò Cantori (ncant)      03-July-2022

Revision History:

--*/

#pragma once

unsigned char webpage_html[] = {
  0x3c, 0x21, 0x44, 0x4f, 0x43, 0x54, 0x59, 0x50, 0x45, 0x20, 0x68, 0x74,
  0x6d, 0x6c, 0x3e, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c, 0x20, 0x6c,
  0x61, 0x6e, 0x67, 0x3d, 0x22, 0x65, 0x6e, 0x22, 0x3e, 0x0d, 0x0a, 0x20,
  0x20, 0x20, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x68, 0x65,
  0x61, 0x64, 0x3e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x3c, 0x6d, 0x65, 0x74, 0x61, 0x20, 0x63, 0x68, 0x61, 0x72, 0x73,
  0x65, 0x74, 0x3d, 0x22, 0x55, 0x54, 0x46, 0x2d, 0x38, 0x22, 0x3e, 0x0d,
  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x6d, 0x65,
  0x74, 0x61, 0x20, 0x6e, 0x61, 0x6d, 0x65, 0x3d, 0x22, 0x76, 0x69, 0x65,
  0x77, 0x70, 0x6f, 0x72, 0x74, 0x22, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x65,
  0x6e, 0x74, 0x3d, 0x22, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x64, 0x65,
  0x76, 0x69, 0x63, 0x65, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x20,
  0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x2d, 0x73, 0x63, 0x61, 0x6c,
  0x65, 0x3d, 0x31, 0x22, 0x3e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x3c, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x57, 0x65,
  0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f,
  0x6e, 0x3c, 0x2f, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x3e, 0x0d, 0x0a, 0x20,
  0x20, 0x20, 0x20, 0x3c, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x0d, 0x0a,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x68, 0x74, 0x6d, 0x6c, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d,
  0x66, 0x61, 0x6d, 0x69, 0x6c, 0x79, 0x3a, 0x20, 0x48, 0x65, 0x6c, 0x76,
  0x65, 0x74, 0x69, 0x63, 0x61, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x64, 0x69, 0x73, 0x70,
  0x6c, 0x61, 0x79, 0x3a, 0x20, 0x69, 0x6e, 0x6c, 0x69, 0x6e, 0x65, 0x2d,
  0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67,
  0x69, 0x6e, 0x3a, 0x20, 0x30, 0x70, 0x78, 0x20, 0x61, 0x75, 0x74, 0x6f,
  0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x74, 0x65, 0x78, 0x74, 0x2d, 0x61, 0x6c, 0x69, 0x67,
  0x6e, 0x3a, 0x20, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0d, 0x0a,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x62, 0x6f, 0x64, 0x79, 0x7b, 0x0d, 0x0a, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61,
  0x72, 0x67, 0x69, 0x6e, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x35, 0x30,
  0x70, 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x68, 0x31, 0x7b, 0x0d,
  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x34, 0x34, 0x34,
  0x34, 0x34, 0x34, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e,
  0x3a, 0x20, 0x35, 0x30, 0x70, 0x78, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x20,
  0x33, 0x30, 0x70, 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x70, 0x7b,
  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a,
  0x20, 0x32, 0x34, 0x70, 0x78, 0x3b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f,
  0x72, 0x3a, 0x20, 0x23, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x3b, 0x0d,
  0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x6d, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x2d, 0x62, 0x6f, 0x74, 0x74,
  0x6f, 0x6d, 0x3a, 0x20, 0x31, 0x30, 0x70, 0x78, 0x3b, 0x0d, 0x0a, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d,
  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c,
  0x65, 0x3e, 0x0d, 0x0a, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x21,
  0x2d, 0x2d, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x73, 0x63, 0x72,
  0x69, 0x70, 0x74, 0x20, 0x74, 0x79, 0x70, 0x65, 0x20, 0x3d, 0x20, 0x22,
  0x74, 0x65, 0x78, 0x74, 0x2f, 0x4a, 0x61, 0x76, 0x61, 0x73, 0x63, 0x72,
  0x69, 0x70, 0x74, 0x22, 0x3e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
  0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x28,
  0x74, 0x29, 0x20, 0x7b, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d,
  0x65, 0x6f, 0x75, 0x74, 0x28, 0x22, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69,
  0x6f, 0x6e, 0x2e, 0x72, 0x65, 0x6c, 0x6f, 0x61, 0x64, 0x28, 0x74, 0x72,
  0x75, 0x65, 0x29, 0x3b, 0x22, 0x2c, 0x20, 0x74, 0x29, 0x3b, 0x0d, 0x0a,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x7d, 0x0d, 0x0a, 0x20,
  0x20, 0x20, 0x20, 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e,
  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x2d, 0x3e, 0x0d, 0x0a, 0x20,
  0x20, 0x20, 0x20, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x2f, 0x68,
  0x65, 0x61, 0x64, 0x3e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x62,
  0x6f, 0x64, 0x79, 0x20, 0x6f, 0x6e, 0x6c, 0x6f, 0x61, 0x64, 0x20, 0x3d,
  0x20, 0x22, 0x4a, 0x61, 0x76, 0x61, 0x53, 0x63, 0x72, 0x69, 0x70, 0x74,
  0x3a, 0x41, 0x75, 0x74, 0x6f, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68,
  0x28, 0x31, 0x30, 0x30, 0x30, 0x29, 0x3b, 0x22, 0x3e, 0x0d, 0x0a, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x64, 0x69, 0x76, 0x20,
  0x69, 0x64, 0x3d, 0x22, 0x77, 0x65, 0x62, 0x70, 0x61, 0x67, 0x65, 0x5c,
  0x22, 0x3e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x3c, 0x68, 0x31, 0x3e, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20,
  0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3c, 0x2f, 0x68, 0x31, 0x3e,
  0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x70,
  0x3e, 0x54, 0x65, 0x6d, 0x70, 0x65, 0x72, 0x61, 0x74, 0x75, 0x72, 0x65,
  0x3a, 0x20, 0x40, 0x74, 0x20, 0x26, 0x64, 0x65, 0x67, 0x3b, 0x43, 0x3c,
  0x2f, 0x70, 0x3e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x20, 0x3c, 0x70, 0x3e, 0x48, 0x75, 0x6d, 0x69, 0x64, 0x69, 0x74, 0x79,
  0x3a, 0x20, 0x40, 0x68, 0x20, 0x25, 0x3c, 0x2f, 0x70, 0x3e, 0x0d, 0x0a,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x70, 0x3e, 0x50,
  0x72, 0x65, 0x73, 0x73, 0x75, 0x72, 0x65, 0x3a, 0x20, 0x40, 0x70, 0x20,
  0x68, 0x50, 0x61, 0x3c, 0x2f, 0x70, 0x3e, 0x0d, 0x0a, 0x20, 0x20, 0x20,
  0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x70, 0x3e, 0x41, 0x6c, 0x74, 0x69,
  0x74, 0x75, 0x64, 0x65, 0x3a, 0x20, 0x40, 0x61, 0x20, 0x6d, 0x3c, 0x2f,
  0x70, 0x3e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  0x3c, 0x2f, 0x64, 0x69, 0x76, 0x3e, 0x0d, 0x0a, 0x20, 0x20, 0x20, 0x20,
  0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x0d, 0x0a, 0x3c, 0x2f, 0x68,
  0x74, 0x6d, 0x6c, 0x3e
};

unsigned int webpage_html_len = 1168;

CodePudding user response:

You can have the web server return 2 pages. The main index page and a second page that returns the data as JSON. The main page can use Javascript to periodically load the 2nd page and update the fields in the main page.

Change the fields to spans to be updateable

    <p>Temperature: <span id="temperature"></span> &deg;C</p>
    <p>Humidity: <span id="humidity"></span> %</p>
    <p>Pressure: <span id="pressure"></span> hPa</p>
    <p>Altitude: <span id="altitude"></span> m</p>

Then add the JS to fetch the data and update spans periodically

<script>
    const update = () => {
        // Get the JSON data and set spans with the data
        fetch('http://127.0.0.1/get_data.json')
          .then(response => response.json())
          .then(data => {
              document.getElementById("temperature").textContent = data.temperature;
              document.getElementById("humidity").textContent = data.humidity;
             // Repeat for others....
        });
    }
    // Update every 10 seconds
    setInterval(update, 10000);
    // Initial update
    update();
</script>

Then modify your server to return 2 pages. The first is the main page with the above stuff added. The second should be the data in JSON format.

void send_main_page() {
  server.send(200, "text/html", [text for main page as above]);
}

void send_data() {
  // Read data from sensors and build JSON string
  String json = "{\"temperature\":"
  json  = bme.readTemperature();
  json  = ",\"humidity\":";
  json  = bme.readHumidity();
  // finish others
  json  = "}";
  // You can also use a JSON library to build the JSON
  server.send(200, "application/json", json);
}

void setup(void){
  // Setup server....

  server.on("/", send_main_page);
  server.on("/get_data.json", send_data);

  // Finish setup
}

The JSON can look something like this:

{
    "temperature": 32.0,
    "humidity": 50.0,
    "pressure": 20.0,
    "altitude": 10.0
}

This is just a rough outline and off the top of my head, so there's probably plenty to fix.

  •  Tags:  
  • html
  • Related