|
| 1 | +#include "thing/Portal.h" |
| 2 | +#include "third-party/arduino-json-5.6.7/include/ArduinoJson.h" |
| 3 | + |
| 4 | +namespace thing { |
| 5 | + |
| 6 | +Portal::Portal(const Config& config) : config_(config), callback_([](const Config&){}) {} |
| 7 | + |
| 8 | +void Portal::Start() { |
| 9 | + server_.on("/", [&] () { |
| 10 | + static const PROGMEM char page[] = R"( |
| 11 | + <head> |
| 12 | + <script> |
| 13 | + function fetch_config() { |
| 14 | + document.getElementById('loading').style.display='inline' |
| 15 | + var xhr = new XMLHttpRequest(); |
| 16 | + xhr.open("GET", "/config", true); |
| 17 | + xhr.onreadystatechange = function () { |
| 18 | + if (xhr.readyState==4 && xhr.status==200) { |
| 19 | + populate_values(JSON.parse(xhr.responseText)); |
| 20 | + document.getElementById('loading').style.display='none' |
| 21 | + } |
| 22 | + } |
| 23 | + xhr.send(); |
| 24 | + } |
| 25 | + function populate_values(config) { |
| 26 | + document.getElementById('host').value = config.host; |
| 27 | + document.getElementById('auth').value = config.auth; |
| 28 | + document.getElementById('path').value = config.path; |
| 29 | + document.getElementById('ssid').value = config.wifi_ssid; |
| 30 | + document.getElementById('key').value = config.wifi_key; |
| 31 | + } |
| 32 | + function build_config() { |
| 33 | + var config = { |
| 34 | + host : document.getElementById('host').value, |
| 35 | + auth : document.getElementById('auth').value, |
| 36 | + path : document.getElementById('path').value, |
| 37 | + wifi_ssid : document.getElementById('ssid').value, |
| 38 | + wifi_key : document.getElementById('key').value |
| 39 | + }; |
| 40 | + return config; |
| 41 | + } |
| 42 | + function send_config() { |
| 43 | + document.getElementById('saving').style.display='inline' |
| 44 | + var xhr = new XMLHttpRequest(); |
| 45 | + xhr.open("POST", "/config", true); |
| 46 | + xhr.send("config=" + JSON.stringify(build_config())); |
| 47 | + xhr.onreadystatechange = function () { |
| 48 | + if (xhr.readyState==4 && xhr.status==200) { |
| 49 | + document.getElementById('saving').style.display='none' |
| 50 | + } |
| 51 | + } |
| 52 | + } |
| 53 | + </script> |
| 54 | + </head> |
| 55 | + <body> |
| 56 | + <div>Host: <input id='host'></div> |
| 57 | + <div>Auth: <input id='auth'></div> |
| 58 | + <div>Path: <input id='path'></div> |
| 59 | + <div>Wifi SSID: <input id='ssid'></div> |
| 60 | + <div>Wifi Key: <input id='key'></div> |
| 61 | + <div><button onclick='send_config();'>Save</button></div> |
| 62 | + <div id='loading'>Loading....</div> |
| 63 | + <div id='saving' style='display:none'>Saving....</div> |
| 64 | + <script>fetch_config();</script> |
| 65 | + </body> |
| 66 | + )"; |
| 67 | + static const PROGMEM char type[] = "text/html"; |
| 68 | + |
| 69 | + server_.send_P(200, type, page); |
| 70 | + }); |
| 71 | + |
| 72 | + server_.on("/config", [&] () { |
| 73 | + DynamicJsonBuffer jsonBuffer; |
| 74 | + if (server_.method() == HTTP_GET) { |
| 75 | + JsonObject& root = jsonBuffer.createObject(); |
| 76 | + root["host"] = config_.host.c_str(); |
| 77 | + root["auth"] = config_.auth.c_str(); |
| 78 | + root["path"] = config_.path.c_str(); |
| 79 | + root["wifi_ssid"] = config_.wifi_ssid.c_str(); |
| 80 | + root["wifi_key"] = config_.wifi_key.c_str(); |
| 81 | + |
| 82 | + String buffer; |
| 83 | + root.printTo(buffer); |
| 84 | + server_.send(200, "application/json", buffer); |
| 85 | + } else if (server_.method() == HTTP_POST) { |
| 86 | + if (!server_.hasArg("config")) { |
| 87 | + server_.send(500, "text/plain", "Missing config.\r\n"); |
| 88 | + return; |
| 89 | + } |
| 90 | + String config = server_.arg("config"); |
| 91 | + JsonObject& root = jsonBuffer.parseObject(config.c_str()); |
| 92 | + config_.host = root["host"].asString(); |
| 93 | + config_.auth = root["auth"].asString(); |
| 94 | + config_.path = root["path"].asString(); |
| 95 | + config_.wifi_ssid = root["wifi_ssid"].asString(); |
| 96 | + config_.wifi_key = root["wifi_key"].asString(); |
| 97 | + callback_(config_); |
| 98 | + server_.send(200, "text/plain", ""); |
| 99 | + } |
| 100 | + }); |
| 101 | + server_.begin(); |
| 102 | +} |
| 103 | + |
| 104 | +void Portal::Loop() { |
| 105 | + server_.handleClient(); |
| 106 | +} |
| 107 | + |
| 108 | +void Portal::NotifyOnUpdate(std::function<void(const Config& config)> callback) { |
| 109 | + callback_ = callback; |
| 110 | +} |
| 111 | + |
| 112 | +}; |
0 commit comments