async-web-server-esp32

nazarijtipusak080/server-esp32/async-web-server-esp32

No description
async-web-server-esp32
@/async-web-server-esp32
INETjesuso/esp32-wifi/esp32-inet
CONNpulse
Establish the connection
TITLEstring
HTML Title
OPstring
Operation to be done on the web server
STYLEstring
HTML code to style the web server
RUNpulse
async-web-server-esp32
IP
DONE
CMD
INET
CONN
TITLE
OP
STYLE
RUN
CMDstring
DONEpulse
Pulse when get the IP address
IPxod/net/ip-address
IP address for the web server
To use the node in your project you should have the nazarijtipusak080/server-esp32 library installed. Use the “File → Add Library” menu item in XOD IDE if you don’t have it yet. See Using libraries for more info.

C++ implementation

#pragma XOD require "https://github.com/me-no-dev/ESPAsyncWebServer"
#pragma XOD require "https://github.com/me-no-dev/AsyncTCP"

#pragma XOD error_raise enable

#include <WiFi.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>

AsyncWebServer server(80);

// Змінна для збереження останньої команди
String receivedCommand = "";

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="data:,">
  %TITLE%
  %STYLE%
</head>
<body>
  <h2>ESP32 Command Server</h2>
  <p>Введіть команду:</p>
  <input id="cmd" placeholder="Команда..." />
  <button onclick="sendCmd()">Надіслати</button>
  <hr>
  <b>Остання команда:</b> <span id="operation">%OPERATION%</span>

<script>
function sendCmd(){
  var c = document.getElementById("cmd").value;
  var xhttp = new XMLHttpRequest();
  xhttp.open("GET", "/set?cmd=" + encodeURIComponent(c), true);
  xhttp.send();
}

setInterval(function(){
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("operation").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "/operation", true);
  xhttp.send();
}, 2000);
</script>
</body>
</html>
)rawliteral";

namespace input {
    String operation = "";
    String style = "";
    String title = "";
}

String processor(const String& var){
  if (var == "TITLE") return input::title;
  if (var == "STYLE") return input::style;
  if (var == "OPERATION") return input::operation;
  return String();
}

node {
    void evaluate(Context ctx) {
        // --- Ініціалізація сервера ---
        if (isInputDirty<input_CONN>(ctx)) {
            auto tt = getValue<input_TITLE>(ctx);
            char _tt[length(tt) + 1] = {0};
            dump(tt, _tt);
            input::title = String("<title>") + String(_tt) + String("</title>");

            auto st = getValue<input_STYLE>(ctx);
            char _st[length(st) + 1] = {0};
            dump(st, _st);
            input::style = String(_st);

            auto op = getValue<input_OP>(ctx);
            char _op[length(op) + 1] = {0};
            dump(op, _op);
            input::operation = String(_op);

            // --- Маршрути ---
            server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
                request->send_P(200, "text/html", index_html, processor);
            });

            server.on("/operation", HTTP_GET, [](AsyncWebServerRequest *request){
                request->send_P(200, "text/plain", input::operation.c_str());
            });

            server.on("/set", HTTP_GET, [](AsyncWebServerRequest *request){
                if (request->hasParam("cmd")) {
                    receivedCommand = request->getParam("cmd")->value();
                    input::operation = receivedCommand;
                    request->send(200, "text/plain", "OK");
                } else {
                    request->send(400, "text/plain", "Missing cmd parameter");
                }
            });

            server.begin();

            // IP-адреса
            emitValue<output_IP>(ctx, WiFi.localIP());
            emitValue<output_DONE>(ctx, 1);
        }

        // --- Зміна OP вручну ---
        if (isInputDirty<input_RUN>(ctx)) {
            auto op = getValue<input_OP>(ctx);
            char _op[length(op) + 1] = {0};
            dump(op, _op);
            input::operation = String(_op);
        }

        // --- Якщо прийшла команда ---
        if (receivedCommand.length() > 0) {
            emitValue<output_CMD>(ctx, receivedCommand.c_str());
            receivedCommand = "";
        }
    }
}