diff --git a/html/console_main.js b/html/console_main.js
new file mode 100644
index 0000000..5ec7309
--- /dev/null
+++ b/html/console_main.js
@@ -0,0 +1,42 @@
+ console_url = "/console/text";
+
+ onLoad(function() {
+ fetchText(100, true);
+
+ $("#reset-button").addEventListener("click", function(e) {
+ e.preventDefault();
+ var co = $("#console");
+ co.innerHTML = "";
+ ajaxSpin('POST', "/console/reset",
+ function(resp) { showNotification("uC reset"); co.textEnd = 0; },
+ function(s, st) { showWarning("Error resetting uC"); }
+ );
+ });
+
+ $("#clear-button").addEventListener("click", function(e) {
+ e.preventDefault();
+ var co = $("#console");
+ co.innerHTML = "";
+ });
+
+ ajaxJson('GET', "/console/baud",
+ function(data) { $("#baud-sel").value = data.rate; },
+ function(s, st) { showNotification(st); }
+ );
+
+ bnd($("#baud-sel"), "change", function(ev) {
+ ev.preventDefault();
+ var baud = $("#baud-sel").value;
+ ajaxSpin('POST', "/console/baud?rate="+baud,
+ function(resp) { showNotification("" + baud + " baud set"); },
+ function(s, st) { showWarning("Error setting baud rate: " + st); }
+ );
+ });
+
+ consoleSendInit();
+
+ addClass($('html')[0], "height100");
+ addClass($('body')[0], "height100");
+ addClass($('#layout'), "height100");
+ addClass($('#layout'), "flex-vbox");
+ });
diff --git a/html/flash/flash.html b/html/flash/flash.html
new file mode 100644
index 0000000..0ab1aa5
--- /dev/null
+++ b/html/flash/flash.html
@@ -0,0 +1,73 @@
+
+
+ esp-link
+
+
+
+
+
+
+
+
+
+
+
+
+
Upgrade firmware
+
+
+
+
+
+
+
+
HTTP authentication
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/html/flash/flash.js b/html/flash/flash.js
new file mode 100644
index 0000000..7fb783a
--- /dev/null
+++ b/html/flash/flash.js
@@ -0,0 +1,227 @@
+onLoad(function() {
+ bnd($("#auth-form"), "submit", changeAuth);
+ bnd($("#flash-start"), "click", startUpload);
+ bnd($("#flash-stop"), "click", stopUpload);
+ nextFlash();
+ fetchAuth();
+});
+
+// disable START button, enable STOP button, show spinner
+function flash_start()
+{
+ var cb = $("#flash-start");
+ addClass(cb, "pure-button-disabled");
+ cb.setAttribute("disabled", "");
+ var cb = $("#flash-stop");
+ removeClass(cb, "pure-button-disabled");
+ cb.removeAttribute("disabled");
+ $("#firmware-spinner").removeAttribute("hidden");
+ $("#progressbar").value = 0;
+ $("#up-count").innerHTML = '0 %';
+ $("#progress").removeAttribute("hidden");
+}
+
+// enable START button, disable STOP button, hide spinner
+function flash_stop()
+{
+ var cb = $("#flash-start");
+ removeClass(cb, "pure-button-disabled");
+ cb.removeAttribute("disabled");
+ var cb = $("#flash-stop");
+ addClass(cb, "pure-button-disabled");
+ cb.setAttribute("disabled", "true");
+ $("#firmware-spinner").setAttribute("hidden","true");
+ $("#progress").setAttribute("hidden","true");
+}
+
+function displayAuth(data) {
+ Object.keys(data).forEach(function (v) {
+ el = $("#" + v);
+ if (el != null) {
+ if (el.nodeName === "INPUT") el.value = data[v];
+ else el.innerHTML = data[v];
+ return;
+ }
+
+ el = document.querySelector('input[name="' + v + '"]');
+ if (el == null)
+ el = document.querySelector('select[name="' + v + '"]');
+
+ if (el != null) {
+ if (el.type == "checkbox") {
+ el.checked = data[v] == "enabled";
+ } else el.value = data[v];
+ }
+ });
+
+ $("#auth-spinner").setAttribute("hidden", "");
+ $("#auth-form").removeAttribute("hidden");
+}
+
+function fetchAuth() {
+ ajaxJson("GET", "/flash/auth", displayAuth, function () {
+ window.setTimeout(fetchAuth, 1000);
+ });
+}
+
+function showFlash(data) {
+ el = $("#firmware-name");
+ if (el != null) el.innerHTML = data;
+
+ $("#firmware-spinner").setAttribute("hidden", "");
+ $("#firmware-form").removeAttribute("hidden");
+}
+
+function nextFlash() {
+ ajaxReq("GET", "/flash/next", showFlash, function () {
+ window.setTimeout(nextFlash, 1000);
+ });
+}
+
+function showFlash2(data) {
+ el = $("#firmware-name");
+ if (el != null)
+ {
+ if(el.innerHTML != data) showNotification("Firmware successfully updated");
+ else showWarning("Flashing seems to have failed and it reverted to the old firmware?");
+ el.innerHTML = data;
+ }
+ // show uploading form
+ $("#firmware-spinner").setAttribute("hidden", "");
+ $("#firmware-form").removeAttribute("hidden");
+}
+
+// waiting module to come up after reboot
+function checkFlash() {
+ ajaxReq("GET", "/flash/next", showFlash2, function () {
+ window.setTimeout(checkFlash, 1000);
+ });
+}
+
+function nextReboot() {
+ // hide uploading form
+ $("#firmware-spinner").removeAttribute("hidden");
+ $("#firmware-form").setAttribute("hidden","");
+ ajaxReq("GET", "/flash/reboot",
+ function(data)
+ {
+ showNotification("Waiting for ESP module to reboot");
+ window.setTimeout(checkFlash, 4000);
+ },
+ function (s,st)
+ {
+ showWarning("ERROR - "+st);
+ // show uploading form
+ $("#firmware-spinner").setAttribute("hidden", "");
+ $("#firmware-form").removeAttribute("hidden");
+ }
+ );
+}
+
+function changeAuth(e) {
+ e.preventDefault();
+ var url = "/flash/auth?1=1";
+ var i, inputs = document.querySelectorAll("#" + e.target.id + " input,select");
+ for (i = 0; i < inputs.length; i++)
+ {
+ if (inputs[i].type == "checkbox")
+ {
+ var val = (inputs[i].checked) ? 1 : 0;
+ url += "&" + inputs[i].name + "=" + val;
+ }
+ else url += "&" + inputs[i].name + "=" + inputs[i].value;
+ };
+
+ hideWarning();
+ var n = e.target.id.replace("-form", "");
+ var cb = $("#" + n + "-button");
+ addClass(cb, "pure-button-disabled");
+ ajaxSpin("POST", url, function (resp) {
+ showNotification("Settings updated");
+ removeClass(cb, "pure-button-disabled");
+ }, function (s, st) {
+ showWarning("Error: " + st);
+ removeClass(cb, "pure-button-disabled");
+ window.setTimeout(fetchAuth, 100);
+ });
+}
+
+function errUpload(evt)
+{
+ flash_stop();
+}
+
+function startUpload()
+{
+ hideWarning();
+ var file_input = $("#firmware_file");
+ if(file_input.files.length==0)
+ {
+ alert("Please choose a file");
+ return;
+ }
+ var progressBar = $("#progressbar");
+ flash_start();
+ var xhr = j();
+ xhr.upload.onabort = errUpload;
+ xhr.upload.onerror = errUpload;
+ xhr.upload.ontimeout = errUpload;
+ xhr.upload.onprogress = function (e) {
+ if (e.lengthComputable)
+ {
+ progressBar.max = e.total;
+ progressBar.value = e.loaded;
+ $("#up-count").innerHTML = Math.floor((e.loaded / e.total) * 100) + '%';
+ }
+ }
+ xhr.upload.onloadstart = function (e) {
+ progressBar.value = 0;
+ }
+ xhr.upload.onloadend = function (e) {
+ progressBar.value = e.loaded;
+ }
+ xhr.onreadystatechange = function() {
+ if (xhr.readyState != 4) return;
+ clearTimeout(timeout);
+ if (xhr.status >= 200 && xhr.status < 300)
+ {
+ //console.log("XHR done:", method, url, "->", xhr.status);
+ flash_stop();
+ showNotification("Firmware updated - now rebooting");
+ window.setTimeout(nextReboot, 3000);
+ }
+ else
+ {
+ console.log("XHR ERR : POST /flash/upload -> ", xhr.status, xhr.responseText, xhr);
+ flash_stop();
+ showWarning("ERROR = " + xhr.responseText);
+ }
+ }
+ xhr.open("POST", "/flash/upload", true);
+ xhr.setRequestHeader('Content-Type', "application/octet-stream");
+ xhr.setRequestHeader('Content-Disposition', 'attachment; filename="' + $("#firmware-name").innerHTML + '"');
+ var timeout = setTimeout(function() {
+ xhr.abort();
+ console.log("XHR abort: POST /flash/upload");
+ xhr.status = 599;
+ xhr.responseText = "request time-out";
+ }, 9000);
+ //console.log("XHR send:", method, url);
+ try
+ {
+ xhr.send(file_input.files[0]);
+ }
+ catch(err)
+ {
+ console.log("XHR EXEC : POST /flash/upload -> ", err);
+ flash_stop();
+ showWarning("Error = " + err);
+ }
+}
+
+function stopUpload()
+{
+ if(req) req.abort();
+ req = null;
+ flash_stop();
+}
\ No newline at end of file
diff --git a/html/home.js b/html/home.js
new file mode 100644
index 0000000..f32c6e6
--- /dev/null
+++ b/html/home.js
@@ -0,0 +1,8 @@
+onLoad(function() {
+ makeAjaxInput("system", "description");
+ makeAjaxInput("system", "name");
+ fetchPins();
+ getWifiInfo();
+ getSystemInfo();
+ bnd($("#pinform"), "submit", setPins);
+});
diff --git a/html/log_main.js b/html/log_main.js
new file mode 100644
index 0000000..c5f1ce4
--- /dev/null
+++ b/html/log_main.js
@@ -0,0 +1,31 @@
+ console_url = "/log/text";
+
+ onLoad(function() {
+ fetchText(100, false);
+
+ $("#refresh-button").addEventListener("click", function(e) {
+ e.preventDefault();
+ fetchText(100, false);
+ });
+
+ $("#reset-button").addEventListener("click", function (e) {
+ e.preventDefault();
+ var co = $("#console");
+ co.innerHTML = "";
+ ajaxSpin('POST', "/log/reset",
+ function (resp) { showNotification("Resetting esp-link"); co.textEnd = 0; fetchText(2000, false); },
+ function (s, st) { showWarning("Error resetting esp-link"); }
+ );
+ });
+
+ ["auto", "off", "on0", "on1"].forEach(function(mode) {
+ bnd($('#dbg-'+mode), "click", function(el) {
+ ajaxJsonSpin('POST', "/log/dbg?mode="+mode,
+ function(data) { showNotification("UART mode " + data.mode); showDbgMode(data.mode); },
+ function(s, st) { showWarning("Error setting UART mode: " + st); }
+ );
+ });
+ });
+
+ ajaxJson('GET', "/log/dbg", function(data) { showDbgMode(data.mode); }, function() {});
+ });