ESP32利用WebServer进行设备配置

发布于:2024-10-15 ⋅ 阅读:(44) ⋅ 点赞:(0)

目标需求

利用esp32的WebServer功能,展示一个网页,对里面的参数进行配置,并以json文本格式保存到flash里面。

1、定义HTML

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <title>采集器配置</title>
    <link rel="stylesheet" href="http://www.kanzz.net/res/eve.css">
</head>
<body>
<form id="config-form" autocomplete="off">
            <div class="form-item">
                <label for="versioin">软件版本:</label>
                <input type="text" id="versioin" name="versioin" value="%VERSION%" value="1.0">
            </div>
            <div class="form-item">
                <label for="sn">编号:</label>
                <input type="text" id="sn" name="sn" value="%SN%" required>
            </div>
            <div class="form-item">
                <label for="ip">IP 地址:</label>
                <input type="text" id="ip" name="ip" value="%MYIP%" required>
            </div>
            <div class="form-item">
                <label for="mask">子网掩码:</label>
                <input type="text" id="mask" name="mask" value="%MYMASK%" required>
            </div>
            <div class="form-item">
                <label for="gateway">网关:</label>
                <input type="text" id="gateway" name="gateway" value="%GATEWAY%" required>
            </div>
            <div class="form-item">
                <label for="ssid">WiFi SSID:</label>
                <input type="text" id="ssid" name="ssid" value="%SSID%" required>
            </div>
            <div class="form-item">
                <label for="wifipwd">WiFi Password:</label>
                <input type="text" id="wifipwd" name="wifipwd" value="%WIFIPWD%">
            </div>
            <div class="form-item">
                <label for="waittime">拉取时间(秒):</label>
                <input type="text" id="waittime" name="waittime" value="%WAITTIME%">
            </div>
            <div class="form-item">
                <label for="apiurl">推送接⼝:</label>
                <input type="text" id="apiurl" name="apiurl" value="%APIURL%">
            </div>
            <div class="form-item">
                <label for="appid">AppID:</label>
                <input type="text" id="appid" name="appid" value="%APPID%">
            </div>
            <div class="form-item">
                <label for="secret">Secret:</label>
                <input type="text" id="secret" name="secret" value="%SECRET%">
            </div>
            <div class="form-item">
                <button type="submit">保存配置</button>
            </div>
        </form>
</body>
</html>
)rawliteral";
const char info_html[] PROGMEM = R"rawliteral(
        <!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
            <title>采集器配置</title>
            <link rel="stylesheet" href="http://www.kanzz.net/res/eve.css">
        </head>
        <body>
            <div style="margin:100px auto;width:400px;">
                <div style="color: #060;font-size: 16px;line-height: 30px;margin: 20px 0;">修改完成!</div>
                <div class="button"><button id="back" style="width: 160px;height: 40px;line-height: 30px;border: 1px solid #999;color: #fff;background-color: #5cd6b2;border: none;border-radius: 4px;box-shadow: 4px 4px 4px #999;cursor: pointer;">返回</button></div>
            </div>
            <script>        
                document.getElementById('back').addEventListener('click', function(event) {
                    location.href = '/';
                })
            </script>
        </body>
        </html>
)rawliteral";

其中定义了一些变量,展示页面的时候会用变量来替代,如:

<div class="form-item">
    <label for="ssid">WiFi SSID:</label>
    <input type="text" id="ssid" name="ssid" value="%SSID%" required>
</div>

代码中的 value="%SSID%"

2、安装ESPAsyncWebServer

3、定义JSON字符串

String jsonStr = "{\"version\": \"1.1\", \"sn\":\"2021\", \"mask\":\"255.255.255.0\", \"gateway\":\"192.168.0.1\", \"waittime\":\"0.5\", \"apiurl\":\"https://\", \"appid\":\"appid12345\", \"secret\":\"secret\"}";

4、读取Flash中的JSON文件

String readJsonFile()
{
  File configFile = SPIFFS.open("/config.json", FILE_READ);
  if (!configFile) {
    Serial.println("Failed to open config file");
    return "";
  }
  if(configFile.available())
  {
    String line = configFile.readString();
    configFile.close();
    return line;
  }
}

5、保存JSON文件到Flash中

void saveJsonFile()
{
  File configFile = SPIFFS.open("/config.json", "w");
  if (!configFile) {
    Serial.println("Failed to open config file for writing");
    return;
  }
  configFile.println(jsonStr);
  configFile.close();
  Serial.println("Config file saved");
}

6、处理HTML模板中的变量

String processor(const String& var)
{
  jsonConfig config = transTojson();
  if (var == "VERSION")
  {
    return config.version;
  }
  if (var == "SN")
  {
    return config.sn;
  }
  if (var == "MYIP")
  {
    return ip;
  }
  if (var == "MYMASK")
  {
    return config.mask;
  }
  if (var == "GATEWAY")
  {
    return config.gateway;
  }
  if (var == "SSID")
  {
    return ssid;
  }
  if (var == "WIFIPWD")
  {
    return password;
  }
  if (var == "WAITTIME")
  {
    return config.waittime;
  }
  if (var == "APIURL")
  {
    return config.apiurl;
  }
  if (var == "APPID")
  {
    return config.appid;
  }
  if (var == "SECRET")
  {
    return config.secret;
  }
  return String();
}

7、WebServer的监听

  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });
server.on("/save", HTTP_POST, [](AsyncWebServerRequest *request){
    String version, sn, mask, gateway, waittime, apiurl, appid, secret;
    if (request->hasParam("version", true)) {
        version = request->getParam("version", true)->value();
    } else {
        version = "-";
    }
    if (request->hasParam("sn", true)) {
        sn = request->getParam("sn", true)->value();
    } else {
        sn = "-";
    }
    if (request->hasParam("mask", true)) {
        mask = request->getParam("mask", true)->value();
    } else {
        mask = "-";
    }
    if (request->hasParam("gateway", true)) {
        gateway = request->getParam("gateway", true)->value();
    } else {
        gateway = "-";
    }
    if (request->hasParam("waittime", true)) {
        waittime = request->getParam("waittime", true)->value();
    } else {
        waittime = "-";
    }
    if (request->hasParam("apiurl", true)) {
        apiurl = request->getParam("apiurl", true)->value();
    } else {
        apiurl = "-";
    }
    if (request->hasParam("appid", true)) {
        appid = request->getParam("appid", true)->value();
    } else {
        appid = "-";
    }
    if (request->hasParam("secret", true)) {
        secret = request->getParam("secret", true)->value();
    } else {
        secret = "-";
    }
    jsonStr = "{\"version\": \"" + version + "\", \"sn\":\"" + sn + "\", \"mask\":\"" + mask + "\", \"gateway\":\"" + gateway + "\", \"waittime\":\"" + waittime + "\", \"apiurl\":\"" + apiurl + "\", \"appid\":\"" + appid + "\", \"secret\":\"" + secret + "\"}";
    saveJsonFile();
    delay(100);
    request->send_P(200, "text/html", info_html);
  });

根据逻辑整合起来后,测试成功!


网站公告

今日签到

点亮在社区的每一天
去签到