cotestatnt / esp-fs-webserver Goto Github PK
View Code? Open in Web Editor NEWESP32/ESP8266 webserver, WiFi manager and web editor Arduino library
License: MIT License
ESP32/ESP8266 webserver, WiFi manager and web editor Arduino library
License: MIT License
Hi @cotestatnt
I tried turning off the wifi network router for a long time, so esp8266 would be WiFi.status() != WL_CONNECTED
I noticed if the esp8266 doesn't connect then it will try to reconnect, and if it fails then it will go into WIFI_AP mode
so wifi network 'ESP_AP' will reappear
but when my laptop is connected to the 'ESP_AP' of esp8266, I'm having trouble opening the web-based configuration on 192.168.4.1
but when i turn on wifi network router, web based configuration can open
is there a blocking function that makes the web based configuration unopenable??
Thanks
I tried to compile the gpio_list-example for ESP32
and got this error
exit status 1
could not convert '{"input", "INPUT 2", 2, 0}' from '' to 'gpio_type'
first I thought this might be because the declaring of the array
gpio_type gpios[NUM_GPIOS] = {
{"input", "INPUT 2", 2 },
{"input", "INPUT 4", 4},
{"input", "INPUT 5", 5},
{"output", "OUTPUT 6", 6},
{"output", "OUTPUT 7", 7},
{"output", "LED BUILTIN", 3} // Led ON with signal HIGH (ESP32-C3)
};
is missing the fourth parameter
bool level = LOW;
// Define a struct for store all info about each gpio
struct gpio_type {
const char* type;
const char* label;
int pin;
bool level = LOW;
};
but this was mot the problem
I got the same compiler-error-message after adding the fourth parameter
gpio_type gpios[NUM_GPIOS] = {
{"input", "INPUT 2", 2, LOW},
{"input", "INPUT 4", 4, LOW},
{"input", "INPUT 5", 5, LOW},
{"output", "OUTPUT 6", 6, LOW},
{"output", "OUTPUT 7", 7, LOW},
{"output", "LED BUILTIN", 3, LOW} // Led ON with signal HIGH (ESP32-C3)
};
the astonishing thing is if I compile for an ESP8266 it does compile and the serial monitor shows how the ESP8266 connects to my WiFi but then the IP-adress is unavailable
Here is the compilerlog
gpio_list-ESP32-004:49:1: error: could not convert '{"input", "INPUT 2", 2, 0}' from '<brace-enclosed initializer list>' to 'gpio_type' }; ^ gpio_list-ESP32-004:49:1: error: could not convert '{"input", "INPUT 4", 4, 0}' from '<brace-enclosed initializer list>' to 'gpio_type' gpio_list-ESP32-004:49:1: error: could not convert '{"input", "INPUT 5", 5, 0}' from '<brace-enclosed initializer list>' to 'gpio_type' gpio_list-ESP32-004:49:1: error: could not convert '{"output", "OUTPUT 6", 6, 0}' from '<brace-enclosed initializer list>' to 'gpio_type' gpio_list-ESP32-004:49:1: error: could not convert '{"output", "OUTPUT 7", 7, 0}' from '<brace-enclosed initializer list>' to 'gpio_type' gpio_list-ESP32-004:49:1: error: could not convert '{"output", "LED BUILTIN", 3, 0}' from '<brace-enclosed initializer list>' to 'gpio_type' Mehrere Bibliotheken wurden für "WiFi.h" gefunden Benutzt: C:\Users\dipl-\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WiFi Nicht benutzt: E:\Arduino-funktioniert\arduino-1.8.19-windows-2022-01-30\arduino-1.8.19\libraries\WiFi Mehrere Bibliotheken wurden für "ArduinoJson.h" gefunden Benutzt: F:\myData\Arduino\libraries\ArduinoJson Nicht benutzt: E:\Arduino-funktioniert\arduino-1.8.19-windows-2022-01-30\arduino-1.8.19\libraries\ArduinoJson Mehrere Bibliotheken wurden für "WebSocketsServer.h" gefunden Benutzt: F:\myData\Arduino\libraries\WebSockets Nicht benutzt: E:\Arduino-funktioniert\arduino-1.8.19-windows-2022-01-30\arduino-1.8.19\libraries\WebSockets Bibliothek WebSockets in Version 2.3.6 im Ordner: F:\myData\Arduino\libraries\WebSockets wird verwendet Bibliothek WiFi in Version 1.0 im Ordner: C:\Users\dipl-\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WiFi wird verwendet Bibliothek WiFiClientSecure in Version 1.0 im Ordner: C:\Users\dipl-\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WiFiClientSecure wird verwendet Bibliothek esp-fs-webserver in Version 1.1.3 im Ordner: F:\myData\Arduino\libraries\esp-fs-webserver wird verwendet Bibliothek FS in Version 1.0 im Ordner: C:\Users\dipl-\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\FS wird verwendet Bibliothek ArduinoJson in Version 6.19.4 im Ordner: F:\myData\Arduino\libraries\ArduinoJson wird verwendet Bibliothek WebServer in Version 1.0 im Ordner: C:\Users\dipl-\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\WebServer wird verwendet Bibliothek ESPmDNS in Version 1.0 im Ordner: C:\Users\dipl-\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\ESPmDNS wird verwendet Bibliothek HTTPUpdateServer in Version 1.0 im Ordner: C:\Users\dipl-\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\HTTPUpdateServer wird verwendet Bibliothek SPIFFS in Version 1.0 im Ordner: C:\Users\dipl-\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\SPIFFS wird verwendet Bibliothek Update in Version 1.0 im Ordner: C:\Users\dipl-\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\Update wird verwendet Bibliothek DNSServer in Version 1.1.0 im Ordner: C:\Users\dipl-\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.6\libraries\DNSServer wird verwendet Bibliothek LittleFS_esp32 in Version 1.0.6 im Ordner: F:\myData\Arduino\libraries\LittleFS_esp32 wird verwendet exit status 1 could not convert '{"input", "INPUT 2", 2, 0}' from '<brace-enclosed initializer list>' to 'gpio_type'
best regards Stefan
Hi @cotestatnt
setInterval(function ( ) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("label1").innerHTML = this.responseText;
}
};
xhttp.open("GET", "/temperature", true);
xhttp.send();
}, 5000 ) ;
but fail. Can you give me a hint to do that??
Thanks
I am using arduino-cli and ESP32-S3 D1 Mini
I was unable to change Options Box Label in your example CustomHTML.ino.
Even if I use the #define CLEAR_OTIONS 1 the label did not changed.
I have to get rid of the config.json (actually I rename it) in order to see my new labels.
In config.json I have noticed that options labels seems to be saved EX:"param-box1": "Mes Options".
Exception are "Setup" and "Update&FS"
This is confusing.
hello
i am using ace on ESP8266 / ESP32 webserver
for wifi relais switches
i would like to ad live html preview to the ace code text editor (tryit codepen jsfiddle alike)
like https://github.com/geard-dev/web-based-live-code-editor
demo https://live-editor.js.org/html.html
but i do not now how to implement it in my editor code
is there anyone that can help me?
Greet Luberth
https://github.com/ldijkman/randomnerd_esp32_wifi_manager/tree/main/LAB_Experiments
<!DOCTYPE html>
<html lang="en">
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Electra's ESP Editor</title>
<link rel="apple-touch-icon" href="/ace.ico" type="image/x-icon">
<link rel="shortcut icon" href="/ace.ico" type="image/x-icon">
<link rel="icon" href="/ace.ico" type="image/x-icon">
<style type="text/css" media="screen">
label {
font-size: 12px;
font-family: sans-serif
}
.cm {
z-index: 300;
position: absolute;
left: 5px;
border: 1px solid #444;
background-color: #f5f5f5;
display: none;
box-shadow: 0 0 10px rgba(0, 0, 0, .4);
font-size: 12px;
font-family: sans-serif;
font-weight: 700
}
.cm ul {
list-style: none;
top: 0;
left: 0;
margin: 0;
padding: 0
}
.cm li {
position: relative;
min-width: 60px;
cursor: pointer
}
.cm span {
color: #444;
display: inline-block;
padding: 6px
}
.cm li:hover {
background: #444
}
.cm li:hover span {
color: #eee
}
.tvu li,
.tvu ul {
padding: 0;
margin: 0;
list-style: none
}
.tvu input {
position: absolute;
opacity: 0
}
.tvu {
font: 400 12px Verdana, Arial, Sans-serif;
-moz-user-select: none;
-webkit-user-select: none;
user-select: none;
color: #444;
line-height: 16px
}
.tvu span {
margin-bottom: 5px;
padding: 0 0 0 18px;
cursor: pointer;
display: inline-block;
height: 16px;
vertical-align: middle;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAQAAAC1+jfqAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADoSURBVBgZBcExblNBGAbA2ceegTRBuIKOgiihSZNTcC5LUHAihNJR0kGKCDcYJY6D3/77MdOinTvzAgCw8ysThIvn/VojIyMjIyPP+bS1sUQIV2s95pBDDvmbP/mdkft83tpYguZq5Jh/OeaYh+yzy8hTHvNlaxNNczm+la9OTlar1UdA/+C2A4trRCnD3jS8BB1obq2Gk6GU6QbQAS4BUaYSQAf4bhhKKTFdAzrAOwAxEUAH+KEM01SY3gM6wBsEAQB0gJ+maZoC3gI6iPYaAIBJsiRmHU0AALOeFC3aK2cWAACUXe7+AwO0lc9eTHYTAAAAAElFTkSuQmCC) no-repeat;
background-position: 0 0
}
.tvu span:hover {
text-decoration: underline
}
@media screen and (-webkit-min-device-pixel-ratio:0) {
.tvu {
-webkit-animation: webkit-adjacent-element-selector-bugfix infinite 1s
}
@-webkit-keyframes webkit-adjacent-element-selector-bugfix {
from {
padding: 0
}
to {
padding: 0
}
}
}
#uploader {
position: absolute;
top: 0;
right: 0;
left: 0;
height: 28px;
line-height: 24px;
padding-left: 10px;
background-color: #444;
color: #eee
}
#tree {
position: absolute;
top: 28px;
bottom: 0;
left: 0;
width: 160px;
padding: 8px
}
#editor,
#preview {
position: absolute;
top: 28px;
right: 0;
bottom: 0;
left: 160px;
border-left: 1px solid #eee
}
#preview {
background-color: #eee;
padding: 5px
}
#loader {
position: absolute;
top: 36%;
right: 40%
}
.loader {
z-index: 10000;
border: 8px solid #b5b5b5;
border-top: 8px solid #3498db;
border-bottom: 8px solid #3498db;
border-radius: 50%;
width: 240px;
height: 240px;
animation: spin 2s linear infinite;
display: none
}
@keyframes spin {
0% {
transform: rotate(0)
}
100% {
transform: rotate(360deg)
}
}
</style>
<script>
function ge(e) {
return document.getElementById(e)
}
function ce(e) {
return document.createElement(e)
}
function sortByKey(e, t) {
return e.sort((function(e, n) {
var a = e[t],
i = n[t];
return i > a ? -1 : a > i ? 1 : 0
}))
}
function createFileUploader(e, t, n) {
var a = /(iPhone)*(OS ([7-9]|1[0-1])_)/i.test(navigator.userAgent);
function i(e, n) {
200 != e ? alert("ERROR[" + e + "]: " + n) : t.refreshPath(d.value)
}
var o = ce("button");
o.innerHTML = "Root Dir", ge(e).appendChild(o);
var c = ce("input");
c.type = "file", c.multiple = !1, c.name = "data", c.id = "upload-select", ge(e).appendChild(c);
var d = ce("input");
d.id = "upload-path", d.type = "text", d.name = "path", d.defaultValue = "/", ge(e).appendChild(d);
var s = ce("button");
s.innerHTML = "Upload", ge(e).appendChild(s);
var r = ce("button");
r.innerHTML = "Create", ge(e).appendChild(r);
var l = ce("input");
l.id = "editor-filename", l.type = "text", l.disabled = !0, l.size = 20, ge(e).appendChild(l);
var u = ce("input");
u.id = "ipad-fix", u.name = "ipad-fix", u.type = "checkbox", u.checked = !!a;
var p = ce("label");
p.for = u.id, p.innerHTML = " Alt.";
var m = ce("button");
m.innerHTML = " Save ", ge(e).appendChild(m), ge(e).appendChild(p), ge(e).appendChild(u), r.onclick = function(e) {
(function(e) {
var t = new FormData;
t.append("path", e), requests.add("PUT", "/edit", t, i)
})(d.value), n.loadUrl(d.value), d.value = "/"
}, m.onclick = function(e) {
if (u.checked) {
var t = ace.edit("editor").getValue(),
a = new FormData;
a.append("rawname", l.value);
var o = 0;
const e = 4096;
for (var c = 0; c < t.length; c += e) {
var d = t.substring(c, c + e);
a.append("raw" + o, d), o++
}
requests.add("POST", "/edit", a, i)
} else n.execCommand("saveCommand")
}, o.onclick = function(e) {
t.refreshPath(d.value)
}, s.onclick = function(e) {
if (0 !== c.files.length) {
var t = new FormData;
t.append("data", c.files[0], d.value), requests.add("POST", "/edit", t, i), ge("upload-path").value = "/", ge("upload-select").value = ""
}
}, c.onchange = function(e) {
if (0 !== c.files.length) {
var t = c.files[0].name,
n = /(?:\.([^.]+))?$/.exec(t)[1],
a = /(.*)\.[^.]+$/.exec(t)[1];
void 0 !== typeof a && (t = a), d.value = "/" + t + "." + n
}
}
}
function createTree(e, t) {
function n(e) {
ge("editor-filename").value = e, ge("editor").style.display = "none", p.style.display = "block", p.innerHTML = '<img src="/edit?edit=' + e + "&_cb=" + Date.now() + '" style="max-width:100%; max-height:100%; margin:auto; display:block;" />'
}
function a(e, a) {
var i = ce("ul");
e.appendChild(i);
var o = ce("li");
i.appendChild(o), s(a) ? (o.innerHTML = "<span>Preview</span>", o.onclick = function(t) {
n(a), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e)
}) : d(a) && (o.innerHTML = "<span>Edit</span>", o.onclick = function(n) {
t.loadUrl(a), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e)
});
var l = ce("li");
i.appendChild(l), d(a) || s(a) || function(e) {
var t = /(?:.([^.]+))?$/.exec(e)[1];
if (void 0 !== typeof t) switch (t) {
case "ico":
case "gz":
case "zip":
case "wav":
case "mp3":
case "pdf":
return !0
}
return !1
}(a) ? (l.innerHTML = "<span>Download</span>", l.onclick = function(t) {
(function(e) {
ge("download-frame").src = "/edit?download=" + e
})(a), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e)
}) : c(a) && (i.appendChild(l), l.innerHTML = "<span>ChDir</span>", l.onclick = function(t) {
m.removeChild(m.childNodes[0]), u(m, a), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e)
});
var p = ce("li");
i.appendChild(p), p.innerHTML = "<span>Delete</span>", p.onclick = function(t) {
r(a), document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(e)
}
}
function i(e, t, n) {
var i = ce("div"),
o = document.body.scrollTop ? document.body.scrollTop : document.documentElement.scrollTop,
c = document.body.scrollLeft ? document.body.scrollLeft : document.documentElement.scrollLeft,
d = e.clientX + c,
s = e.clientY + o;
i.className = "cm", i.style.display = "block", i.style.left = d + "px", i.style.top = s + "px", a(i, t), document.body.appendChild(i);
var r = i.offsetWidth,
l = i.offsetHeight;
i.onmouseout = function(e) {
(e.clientX < d || e.clientX > d + r || e.clientY < s || e.clientY > s + l) && document.body.getElementsByClassName("cm").length > 0 && document.body.removeChild(i)
}
}
function o(e, a, o) {
var r = ce("li");
r.id = a;
var l = ce("span");
return l.innerHTML = a, r.appendChild(l), r.onclick = function(e) {
d(r.id.toLowerCase()) ? t.loadUrl(r.id) : s(r.id.toLowerCase()) ? n(r.id) : c(r.id) && (m.removeChild(m.childNodes[0]) && u(m, r.id.toLowerCase()))
}, r.oncontextmenu = function(e) {
e.preventDefault(), e.stopPropagation(), i(e, r.id)
}, r
}
function c(e) {
return -1 == e.indexOf(".")
}
function d(e) {
var t = /(?:.([^.]+))?$/.exec(e)[1];
if (void 0 !== typeof t) switch (t) {
case "txt":
case "htm":
case "html":
case "js":
case "css":
case "xml":
case "json":
case "conf":
case "ini":
case "h":
case "c":
case "cpp":
case "php":
case "hex":
case "ino":
case "pde":
return !0
}
return !1
}
function s(e) {
var t = /(?:.([^.]+))?$/.exec(e)[1];
if (void 0 !== typeof t) switch (t) {
case "png":
case "jpg":
case "gif":
case "bmp":
return !0
}
return !1
}
function r(e) {
var t = new FormData;
t.append("path", e), requests.add("DELETE", "/edit", t, (function(e, t) {
200 != e ? alert("ERROR[" + e + "]: " + t) : (m.removeChild(m.childNodes[0]), u(m, "/"))
}))
}
function l(e, t) {
return function(t, n) {
200 == t && function(e, t, n) {
sortByKey(n, "name");
var a = ce("ul");
e.appendChild(a);
for (var i = n.length, c = 0; i > c; c++) "file" === n[c].type && a.appendChild(o(0, n[c].name, n[c].size))
}(e, 0, JSON.parse(n))
}
}
function u(e, t) {
requests.add("GET", "/edit", {
list: t
}, l(e))
}
var p = ge("preview"),
m = ce("div");
return m.className = "tvu", ge(e).appendChild(m), this.refreshPath = function(e) {
m.removeChild(m.childNodes[0]), u(m, "/")
}, u(m, "/"), this
}
function createEditor(e, t, n, a, i) {
function o(e) {
var t = "plain",
n = /(?:.([^.]+))?$/.exec(e)[1];
if (void 0 !== typeof n) switch (n) {
case "txt":
case "hex":
case "conf":
t = "plain";
break;
case "htm":
t = "html";
break;
case "js":
t = "javascript";
break;
case "h":
case "c":
case "cpp":
t = "c_cpp";
break;
case "css":
case "scss":
case "php":
case "html":
case "json":
case "xml":
case "ini":
t = n
}
return t
}
function c(e, t) {
200 != e && alert("ERROR[" + e + "]: " + t)
}
function d(e, t) {
ge("preview").style.display = "none", ge("editor").style.display = "block", 200 == e ? s.setValue(t) : s.setValue(""), s.clearSelection()
}
void 0 === t && (t = "/my_edit.html"), void 0 === n && (n = o(t)), void 0 === a && (a = "monokai"), void 0 === i && (i = "text/" + n, "c_cpp" === n && (i = "text/plain"));
var s = ace.edit(e);
return "plain" !== n && s.getSession().setMode("ace/mode/" + n), s.setTheme("ace/theme/" + a), s.$blockScrolling = 1 / 0, s.getSession().setUseSoftTabs(!0), s.getSession().setTabSize(2), s.getSession().setUseWorker(!0), s.setHighlightActiveLine(!0), s.setShowPrintMargin(!1), s.commands.addCommand({
name: "saveCommand",
bindKey: {
win: "Ctrl-S",
mac: "Command-S"
},
exec: function(e) {
! function(e, t, n) {
var a = new FormData;
a.append("data", new Blob([t], {
type: n
}), e), requests.add("POST", "/edit", a, c)
}(t, e.getValue() + "", i)
},
readOnly: !1
}), s.commands.addCommand({
name: "undoCommand",
bindKey: {
win: "Ctrl-Z",
mac: "Command-Z"
},
exec: function(e) {
e.getSession().getUndoManager().undo(!1)
},
readOnly: !1
}), s.commands.addCommand({
name: "redoCommand",
bindKey: {
win: "Ctrl-Shift-Z",
mac: "Command-Shift-Z"
},
exec: function(e) {
e.getSession().getUndoManager().redo(!1)
},
readOnly: !1
}), s.loadUrl = function(e) {
ge("editor-filename").value = e, n = o(t = e), i = "text/" + n, "plain" !== n && s.getSession().setMode("ace/mode/" + n),
function(e) {
requests.add("GET", "/edit", {
edit: e
}, d)
}(t)
}, s
}
function onBodyLoad() {
var e = {},
t = (window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, (function(t, n, a) {
e[n] = a
})), createEditor("editor", e.file, e.lang, e.theme)),
n = createTree("tree", t);
window.define = ace.define, window.require = ace.require, ace.config.set("basePath", "/"), ace.config.set("workerPath", "/"), createFileUploader("uploader", n, t), void 0 === e.file && (e.file = "/my_edit.html"), t.loadUrl(e.file)
}
"undefined" == typeof XMLHttpRequest && (XMLHttpRequest = function() {
try {
return new ActiveXObject("Msxml2.XMLHTTP.6.0")
} catch (e) {}
try {
return new ActiveXObject("Msxml2.XMLHTTP.3.0")
} catch (e) {}
try {
return new ActiveXObject("Microsoft.XMLHTTP")
} catch (e) {}
throw new Error("This browser does not support XMLHttpRequest.")
});
var QueuedRequester = function() {
this.queue = [], this.running = !1, this.xmlhttp = null
};
QueuedRequester.prototype = {
_request: function(e) {
if (this.running = !0, !(!e instanceof Object)) {
var t = this;
ge("loader").style.display = "block";
var n = "";
if (e.params instanceof FormData) n = e.params;
else if (e.params instanceof Object)
for (var a in e.params) n += "" === n ? "GET" === e.method ? "?" : "" : "&", n += encodeURIComponent(a) + "=" + encodeURIComponent(e.params[a]);
this.xmlhttp = new XMLHttpRequest, this.xmlhttp.onreadystatechange = function(e, n) {
return function() {
4 == e.readyState && (ge("loader").style.display = "none", n.callback(e.status, e.responseText), 0 === t.queue.length && (t.running = !1), t.running && t._request(t.queue.shift()))
}
}(this.xmlhttp, e), "GET" === e.method ? (this.xmlhttp.open(e.method, e.url + n, !0), this.xmlhttp.send()) : (this.xmlhttp.open(e.method, e.url, !0), n instanceof String && this.xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"), this.xmlhttp.send(n))
}
},
stop: function() {
this.running && (this.running = !1), this.xmlhttp && this.xmlhttp.readyState < 4 && this.xmlhttp.abort()
},
add: function(e, t, n, a) {
this.queue.push({
url: t,
method: e,
params: n,
callback: a
}), this.running || this._request(this.queue.shift())
}
};
var requests = new QueuedRequester
</script>
<script id="ace" src="/acefull.js" charset="utf-8"></script>
<script>
if (void 0 === ace.edit) {
var script = document.createElement("script");
script.src = "/ace.js", script.async = !1, document.head.appendChild(script)
}
</script>
<body onload="onBodyLoad()">
<div id="loader" class="loader"></div>
<div id="uploader"></div>
<div id="tree"></div>
<div id="editor"></div>
<div id="preview" style="display:none"></div><iframe id="download-frame" style="display:none"></iframe>
above code results in next screenshot (running on ESP32 webserver http://garage.local/edit)
would like to have a live html preview panel added
like demo on https://github.com/geard-dev/web-based-live-code-editor
demo https://live-editor.js.org/html.html
Hi,
is there a way to set the default website to something else than /edit? For example to /index.html?
Hi @cotestatnt ,
I have some question,
After connected to SSID, we dont know the giving IP Address from router, is possible to add status of ESP? connected or not connected and IP address? so we can go back to the page if we know the IP.
Is possible to edit the Wifi Setup page? I read this but I fail, can you give hint more detail to generate setup_htm.h
Give me hint how to print or show value of variable on customElement.h? for example, I have x variable, and i want to show value of x to customHTML page.
Thanks, you are great!!
It seems that special characters in wifi password are not saved correctly.
i have a "&-" at the end of my password.
If i print out my PW in console
esp-fs-webserver/src/esp-fs-webserver.cpp
Line 158 in 4022ff9
It looks like the saving function has maybe an encoding problem. Like mentioned here?
tzapu/WiFiManager#804 (comment)
Hello,
i created a with addOptionBox like in the optionsExample.
is it possible to add multiple option sites with different settings?
I'm using Awtrix (which uses this library) to access it's webinterface but it does not work correctly with HTTPS and/or a subdirectory. I've explained the problem in the Awtrix issue below.
hi @cotestatnt
I want to add 2 custom addOptionBox,
I try this on sketch,
myWebServer.addOptionBox("Summary Result");
myWebServer.addHTML(custom_html1, "fetch-test", /*overwite*/ true);
myWebServer.addCSS(custom_css, /*overwite*/ false);
myWebServer.addJavascript(custom_script, /*overwite*/ false);
myWebServer.addOptionBox("About Me");
myWebServer.addHTML(custom_html2, "fetch-test", /*overwite*/ true);
myWebServer.addCSS(custom_css, /*overwite*/ false);
myWebServer.addJavascript(custom_script, /*overwite*/ false);
and this on customelement.h
static const char custom_html1[] PROGMEM = R"EOF(
<main class="container">
<article class="grid">
<div>
<p id="esp1">T E S T 1</p>
</div>
</article>
</main>
)EOF";
static const char custom_html2[] PROGMEM = R"EOF(
<main class="container">
<article class="grid">
<div>
<p id="esp2">T E S T 2</p>
</div>
</article>
</main>
)EOF";
but the page is only show on last option box
Is possible to add more than one custom_html on different optionBox?
thanks
Hello,
I can not run the customOptions example on wemos d1 mini.
This error is in serial monitor:
02:54:25.747 ->
02:54:25.747 -> AP mode.
02:54:25.747 -> Server IP address: 192.168.4.1
02:54:25.747 ->
02:54:25.794 ->
02:54:25.794 -> This are the current values stored:
02:54:25.794 ->
02:54:25.794 -> LED pin value: 2
02:54:25.794 -> Bool value: true
02:54:25.794 -> Long value: 1234567890
02:54:25.794 -> Float value: 15.500
02:54:25.794 -> String value: Test option String
02:54:25.794 -> Dropdown selected value: Monday
02:54:25.794 ->
02:54:25.794 -> Application option loaded
02:54:25.837 ->
02:54:25.837 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
02:54:25.837 ->
02:54:25.837 -> Exception (3):
02:54:25.837 -> epc1=0x4020a743 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4025145e depc=0x00000000
02:54:25.837 ->
02:54:25.837 -> >>>stack>>>
02:54:25.837 ->
02:54:25.837 -> ctx: cont
02:54:25.837 -> sp: 3ffffc90 end: 3fffffd0 offset: 0190
02:54:25.837 -> 3ffffe20: 00000000 000003e8 4021241c 00000000
02:54:25.837 -> 3ffffe30: 00000000 00000000 3fff10cc 00000007
02:54:25.837 -> 3ffffe40: 3ffffe80 00000009 00000020 40100b50
02:54:25.837 -> 3ffffe50: 00000010 00000020 3ffffee0 3ffffed0
02:54:25.837 -> 3ffffe60: 3ffeef40 c7efffff e54daff8 40209ce4
02:54:25.837 -> 3ffffe70: 00000000 00000000 00000000 00000007
02:54:25.883 -> 3ffffe80: 00000010 00000001 3ffffee0 40216133
02:54:25.883 -> 3ffffe90: e54daff8 00000001 3ffffee0 4021645c
02:54:25.883 -> 3ffffea0: 3fff005c 3ffe8a45 3fff005c 40100b1c
02:54:25.883 -> 3ffffeb0: 3ffe8a45 00000009 3ffffee0 3ffffed0
02:54:25.883 -> 3ffffec0: 3ffeef40 c7efffff e54daff8 40209cd1
02:54:25.883 -> 3ffffed0: e54daff8 47efffff 00000000 3ff00000
02:54:25.883 -> 3ffffee0: 3fff005c 0010001f 8900002d 3fff11ba
02:54:25.883 -> 3ffffef0: 3fff178c 3fff18cc feefef00 feefeffe
02:54:25.883 -> 3fffff00: 3fff18bc 3fff181c feefef20 feefeffe
02:54:25.883 -> 3fffff10: 4021a4ac 00000000 0064616f 00000000
02:54:25.930 -> 3fffff20: feefeffe feefeffe feefeffe feefeffe
02:54:25.930 -> 3fffff30: feefeffe feefeffe feefeffe 4021a8b0
02:54:25.930 -> 3fffff40: 00000000 000003e8 00000000 00000000
02:54:25.930 -> 3fffff50: 00000000 00000000 402126f4 00000000
02:54:25.930 -> 3fffff60: 00000000 3ffef16c 00000000 0010001f
02:54:25.930 -> 3fffff70: 00000000 00000000 00000000 feefeffe
02:54:25.930 -> 3fffff80: feefeffe 4021a97c 0104a8c0 feefeffe
02:54:25.930 -> 3fffff90: 3ffffed0 3ffffe80 feefeffe feefeffe
02:54:25.930 -> 3fffffa0: feefeffe feefeffe feefeffe 3ffef374
02:54:25.930 -> 3fffffb0: 3fffdad0 00000000 3ffef348 40217790
02:54:25.978 -> 3fffffc0: feefeffe feefeffe 3fffdab0 40100df5
02:54:25.978 -> <<<stack<<<
02:54:25.978 ->
02:54:25.978 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
02:54:25.978 ->
02:54:25.978 -> ets Jan 8 2013,rst cause:2, boot mode:(3,4)
02:54:25.978 ->
02:54:25.978 -> load 0x4010f000, len 3424, room 16
02:54:25.978 -> tail 0
02:54:25.978 -> chksum 0x2e
02:54:25.978 -> load 0x3fff20b8, len 40, room 8
02:54:25.978 -> tail 0
02:54:25.978 -> chksum 0x2b
02:54:25.978 -> csum 0x2b
02:54:25.978 -> v000607e0
02:54:25.978 -> ~ld
Thx for the help.
play with a ESP32-S3 N16R8
and setup FFAT 10MB partition.
and write dir and file (append 1 line / min )
/data/readings.csv
does THIS tool help me to DOWNLOAD that file via Browser?
the example FSBrowser i use, not even print that file (content)
my status : at GIT
THX for sharing your work
Hi @cotestatnt
I want to show json value to customElement.h every first time I open the page.
I found this from you and I follow the instruction
so I add handler and function to customHTML.ino like this
#include <esp-fs-webserver.h> // https://github.com/cotestatnt/esp-fs-webserver
#include <FS.h>
#include <LittleFS.h>
#define FILESYSTEM LittleFS
#ifndef LED_BUILTIN
#define LED_BUILTIN 2
#endif
// Set this to 1 if you want clear the /config.json file at startup
#define CLEAR_OTIONS 0
struct tm sysTime;
// Test "options" values
uint8_t ledPin = LED_BUILTIN;
bool boolVar = true;
uint32_t longVar = 1234567890;
float floatVar = 15.5F;
String stringVar = "Test option String";
// ThingsBoard varaibles
String tb_deviceToken = "xxxxxxxxxxxxxxxxxxx";
String tb_device_key = "xxxxxxxxxxxxxxxxxxx";
String tb_secret_key = "xxxxxxxxxxxxxxxxxxx";
String tb_serverIP = "192.168.1.1";
uint16_t tb_port = 8181;
// Var labels (in /setup webpage)
#define LED_LABEL "The LED pin number"
#define BOOL_LABEL "A bool variable"
#define LONG_LABEL "A long variable"
#define FLOAT_LABEL "A float variable"
#define STRING_LABEL "A String variable"
#define TB_SERVER "ThingsBoard server address"
#define TB_PORT "ThingsBoard server port"
#define TB_DEVICE_TOKEN "ThingsBoard device token"
#define TB_DEVICE_KEY "Provisioning device key"
#define TB_SECRET_KEY "Provisioning secret key"
// Timezone definition to get properly time from NTP server
#define MYTZ "CET-1CEST,M3.5.0,M10.5.0/3"
struct tm Time;
#ifdef ESP8266
ESP8266WebServer server(80);
#elif defined(ESP32)
WebServer server(80);
#endif
FSWebServer myWebServer(FILESYSTEM, server);
#include "customElements.h"
//////////////////////////////// Filesystem /////////////////////////////////////////
void startFilesystem() {
// FILESYSTEM INIT
if ( FILESYSTEM.begin()) {
File root = FILESYSTEM.open("/", "r");
File file = root.openNextFile();
while (file) {
const char* fileName = file.name();
size_t fileSize = file.size();
Serial.printf("FS File: %s, size: %lu\n", fileName, (long unsigned)fileSize);
file = root.openNextFile();
}
Serial.println();
}
else {
Serial.println(F("ERROR on mounting filesystem. It will be formmatted!"));
FILESYSTEM.format();
ESP.restart();
}
}
bool loadOptions() {
if (FILESYSTEM.exists(myWebServer.configFile())) {
File file = FILESYSTEM.open(myWebServer.configFile(), "r");
DynamicJsonDocument doc(file.size() * 1.33);
if (!file)
return false;
DeserializationError error = deserializeJson(doc, file);
if (error)
return false;
ledPin = doc[LED_LABEL];
boolVar = doc[BOOL_LABEL];
longVar = doc[LONG_LABEL];
floatVar = doc[FLOAT_LABEL]["value"];
stringVar = doc[STRING_LABEL].as<String>();
tb_deviceToken = doc[TB_DEVICE_TOKEN].as<String>();
tb_device_key = doc[TB_DEVICE_KEY].as<String>();
tb_secret_key = doc[TB_SECRET_KEY].as<String>();
tb_serverIP = doc[TB_SERVER].as<String>();
tb_port = doc[TB_PORT];
file.close();
Serial.println();
Serial.printf("LED pin value: %d\n", ledPin);
Serial.printf("Bool value: %d\n", boolVar);
Serial.printf("Long value: %ld\n",longVar);
Serial.printf("Float value: %d.%d\n", (int)floatVar, (int)(floatVar*1000)%1000);
Serial.println(stringVar);
return true;
}
else
Serial.println(F("Configuration file not exist"));
return false;
}
void setup() {
Serial.begin(115200);
// FILESYSTEM INIT
startFilesystem();
// Load configuration (if not present, default will be created when webserver will start)
#if CLEAR_OPTIONS
if (myWebServer.clearOptions())
ESP.restart();
#endif
if (loadOptions())
Serial.println(F("Application option loaded\n\n"));
else
Serial.println(F("Application options NOT loaded!\n\n"));
// Configure /setup page and start Web Server
// Add a new options box
myWebServer.addOptionBox("My Options");
myWebServer.addOption(LED_LABEL, ledPin);
myWebServer.addOption(LONG_LABEL, longVar);
// Float fields can be configured with min, max and step properties
myWebServer.addOption(FLOAT_LABEL, floatVar, 0.0, 100.0, 0.01);
myWebServer.addOption(STRING_LABEL, stringVar);
myWebServer.addOption(BOOL_LABEL, boolVar);
// Add a new options box
myWebServer.addOptionBox("ThingsBoard");
myWebServer.addOption(TB_SERVER, tb_serverIP);
myWebServer.addOption(TB_PORT, tb_port);
myWebServer.addOption(TB_DEVICE_KEY, tb_device_key);
myWebServer.addOption(TB_SECRET_KEY, tb_secret_key);
myWebServer.addOption(TB_DEVICE_TOKEN, tb_deviceToken);
// Add a new options box with custom code injected
myWebServer.addOptionBox("Custom HTML");
// How many times you need (for example one in different option box)
myWebServer.addHTML(custom_html, "fetch-test", /*overwite*/ true);
// Only once (CSS and Javascript will be appended to head and body)
myWebServer.addCSS(custom_css, /*overwite*/ false);
myWebServer.addJavascript(custom_script, /*overwite*/ false);
// Try to connect to stored SSID, start AP if fails after timeout
IPAddress myIP = myWebServer.startWiFi(15000, "ESP_AP", "123456789" );
myWebServer.addHandler("/getValues", HTTP_GET, getActualValue);
// Start webserver
if (myWebServer.begin()) {
Serial.print(F("\nESP Web Server started on IP Address: "));
Serial.println(myIP);
Serial.println(F("Open /setup page to configure optional parameters"));
Serial.println(F("Open /edit page to view and edit files"));
Serial.println(F("Open /update page to upload firmware and filesystem updates\n\n"));
}
}
void loop() {
myWebServer.run();
}
void getActualValue() {
StaticJsonDocument<256> doc;
String payload;
doc["sunrise"] = "08:00";
doc["sunset"] = "20:00";
doc["automatic"] = true;
serializeJsonPretty(doc, payload);
// Send payoad to client
myWebServer.webserver->send(200, "text/json", payload);
}
and add script to customElement.h like this
static const char custom_html[] PROGMEM = R"EOF(
<main onload="getActualValues()">
<h3>Test Static Json Value</h3>
<p id="sunrise-actual">xxxx</p>
<p id="sunset-actual">xxxx</p>
</main>
)EOF";
static const char custom_css[] PROGMEM = R"EOF(
pre{
font-family: Monaco,Menlo,Consolas,'Courier New',monospace;
color: #333;
line-height: 20px;
background-color: #f5f5f5;
border: 1px solid rgba(0,0,0,0.15);
border-radius: 6px;
overflow-y: scroll;
min-height: 350px;
font-size: 85%;
}
.select{
width: 25%;
height:40px;
padding-top: 10px;
padding-left: 20px;
border:1px solid #ccc;
border-radius: 6px;
box-shadow: 0 1px 2px 0 rgba(220, 220, 230, 0.5);
}
.body{
background-color: cadetblue;
}
)EOF";
static const char custom_script[] PROGMEM = R"EOF(
function fetchEndpoint() {
var mt = $('httpmethod').options[$('httpmethod').selectedIndex].text;
var url = $('url').value + mt.toLowerCase();
var bd = (mt != 'GET') ? 'body: ""' : '';
var options = {
method: mt,
bd
};
fetch(url, options)
.then(response => response.text())
.then(txt => {
$('payload').innerHTML = txt;
});
}
$('fetch').addEventListener('click', fetchEndpoint);
function getActualValues() {
fetch("/getValues")
.then(response => response.json())
.then(data => {
console.log(data);
document.getElementById("sunrise-actual").innerHTML = data.sunrise;
document.getElementById("sunset-actual").innerHTML = data.sunset;
})
}
)EOF";
but nothing happen. So Is it correct that the steps I have used?
the function: myWebServer.addOption(LONG_LABEL, longVar); could save data to fs and could be loaded later, but when i use saveOptions();
it work as follow code : // Config file will be opened on the first time we call this method
..
myWebServer.saveOptionValue(LONG_LABEL, longVar);
..
Serial.println(F("Application options saved."));
It seem not take effectect, is there somthing wrong in code:?
my code is as follow:
void loop() {
myWebServer.run();
if (! digitalRead(BTN_SAVE)) {
//
loadOptions();
Serial.printf("Application option loaded after web requestlongVar =%d\n",longVar);
longVar++;
Serial.printf("finished add n option loaded after web requestlongVar =%d\n",longVar);
//
saveOptions();
Serial.printf("---------------------\n");
//
loadOptions();
Serial.printf("Application option loaded after web requestlongVar =%d\n",longVar);
longVar++;
Serial.printf("finished add n option loaded after web requestlongVar =%d\n",longVar);
//把longVar 保存的config文件中
saveOptions();
Serial.printf("========================\n");
}
delay(1000);
}
===========
Serial output:
This are the current values stored:
LED pin value: 2
Bool value: true
Long value: 1010
Float value: 15.500
String value: Test option String
Dropdown selected value: Monday
This are the current values stored:
LED pin value: 2
Bool value: true
Long value: 1010
Float value: 15.500
String value: Test option String
Dropdown selected value: Monday
Hi cotestatnt , many thanks for this library very useful for every developer .
i Am developing with esp32 wroom dev my small project .
I did install your ESP-FS-webserver and it worked like a charm . on my first install
BUT suddenly something strange happened . ?
i have not change board ,partitions, on my arduino ide keeps the same as when it worked like a charm .
The code i am uploading is yours .inos from EXAMPLES .
When it opens /edit it shows everything but the files , and also indicates FS INIT ERROR .
i am using the handleformdata example .
So i did install simpleserver and also the same FS INIT ERROR
I did use other esp32 out of the package and the same FS INIT ERROR
I did replace all library with fresh download new ones and the same . FS INIT ERROR
I test it with mozzilla , safari , edge , many browsers just in case but FS INIT ERROR
So i decided to upload spiffs test and runs ok , even lists my files meaning data files of your library .
i also uploaded de FS library FSBROWSER that also use ACE and it does shows the files , but it hangs .
So i have being the last 3 days trying to solve this so i can continue with my development but i am stucked on this mysterious situation that i cant not understand .
If you could be kind , and at least tell me where to go , check, replace, look , or any idea about my situation i will much appreciate ,
Many thanks in advance in case you have the time for an answer to me ,
Denis Thornhill
Is there actually a possibility to update files on filesystem via OTA?
It would be helpfull to transfer the web pages also via OTA.
Is it possible to get the ACE file browser source?
I need to change something.
Hi @cotestatnt
I have followed the instructions on this link
but I am getting an error
but the error still exist, can you give a hint?
[FEATURE REQUEST]
I love your lib, and i implement much options with it.
But due the ammount of options the access to the filesystem is horrible.
With all addOption and getOptionValue i get a total of 85 times opening the config.json file. Wich cause in a boottime of arround 25 seconds only for these operations on a ESP32 with maximum clock of 240mhz.
is it possible to open the file and create the JsonDocument once?
I've tried several of the examples and they all seem to crash and reboot... I've tried with and without config.json files, empty file, just an empty json object... all result in the same failure.
Hard resetting via RTS pin...
--- Terminal on /dev/cu.wchusbserial10 | 115200 8-N-1
--- Available filters and text transformations: colorize, debug, default, direct, esp32_exception_decoder, hexlify, log2file, nocontrol, printable, send_on_enter, time
--- More details at https://bit.ly/pio-monitor-filters
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H
/
|__ favicon.ico (1150 bytes)
|__ index.htm (2004 bytes)
/css
|__ pico.fluid.classless.css.gz (5387 bytes)
/img
|__ espressif.jpg (34305 bytes)
/setup
|__ config.json (0 bytes)
[E][.pio/libdeps/esp32dev/esp-fs-webserver/src/esp-fs-webserver.cpp:228] startWiFi(): Failed to deserialize file, may be corrupted
EmptyInput
[I][.pio/libdeps/esp32dev/esp-fs-webserver/src/esp-fs-webserver.cpp:208] startAP(): AP mode.
Server IP address: 8.8.8.8Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC : 0x400dad5b PS : 0x00060130 A0 : 0x800dc2d5 A1 : 0x3ffb2110
A2 : 0x00000038 A3 : 0x3ffb2148 A4 : 0x3f4012b1 A5 : 0x3f41161f
A6 : 0x00000000 A7 : 0x3f400317 A8 : 0x80167520 A9 : 0x3ffb2100
A10 : 0x00000001 A11 : 0x00000000 A12 : 0x00000000 A13 : 0x00000000
A14 : 0xffffbfff A15 : 0x3f4012b1 SAR : 0x00000013 EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000040 LBEG : 0x400e8ccc LEND : 0x400e8d12 LCOUNT : 0x0000003c
Backtrace: 0x400dad58:0x3ffb2110 0x400dc2d2:0x3ffb2140 0x400dc3a3:0x3ffb2190 0x400d23e6:0x3ffb2230 0x400df0de:0x3ffb2290
ELF file SHA256: 89734c2ea7361308
Rebooting...
Hi,
I wanna try the simpleServer example with an ESP32 and I get the compile error:
invalid conversion from 'const char*' to 'int' [-fpermissive]
at the line
myWebServer.addHandler("/led", HTTP_GET, handleLed);
Where is my mistake?
I use Lolin wemos d1 mini pro v2.0.0 (esp8266)
arduino IDE 1.8.19
whit the same sketch using esp-fs-webserver version 1.1.7 I have no problem at all, everithing working well
but with the last version of esp-fs-webserver 2.0.7 just after loading the sketch on the micro it start to reset every minute
this is the output from serial monitor:
Deserializing JSON..
--------------- CUT HERE FOR EXCEPTION DECODER ---------------
Exception (28):
epc1=0x40218534 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
stack>>>
ctx: cont
sp: 3ffffd30 end: 3fffffd0 offset: 0150
3ffffe80: 40224800 0104a8c0 c28f5c28 00641888
3ffffe90: 40224800 00000000 00000001 3fff1df4
3ffffea0: 3fff1dd4 3fff1de4 3fff1e11 3fff29e0
3ffffeb0: 3fff25dc 3fff25dc 3fff25dc 402185d2
3ffffec0: 3fff25dc 3fff25dc 3fff4a50 40217034
3ffffed0: 3fff4104 3fffff00 3fff4a4c 40216430
3ffffee0: 3fff25dc 3fff25dc 00000001 402142b9
3ffffef0: 00000000 3fff4a4c 00000001 3f000000
3fffff00: 3fff0000 00000000 3fff2608 40215104
3fffff10: 0000562d 3fff2608 00000001 402154a4
3fffff20: 3fffdad0 00000000 3fff2284 4021049d
3fffff30: 402243f0 00000000 00001388 40222872
3fffff40: 3fffdad0 00000000 3fff42d4 3fff29e0
3fffff50: 3fffdad0 3fff25dc 3fff2280 402156fc
3fffff60: 3fffdad0 00000000 3fff2280 40210643
3fffff70: 3fff1dd4 3fff1dc0 3fff29b4 4020a333
3fffff80: 00000000 01040000 00005460 40224800
3fffff90: 0104a8c0 feefeffe feefeffe 3fff29e0
3fffffa0: 3fffdad0 00000000 3fff29b4 3fff29e0
3fffffb0: 3fffdad0 00000000 3fff29b4 402201c4
3fffffc0: feefeffe feefeffe 3fffdab0 401012e1
<<<stack<<<
--------------- CUT HERE FOR EXCEPTION DECODER ---------------
ets Jan 8 2013,rst cause:2, boot mode:(3,6)
load 0x4010f000, len 3424, room 16
tail 0
chksum 0x2e
load 0x3fff20b8, len 40, room 8
tail 0
chksum 0x2b
csum 0x2b
v0006bf80
~ld
I already tryed to use some espedient found on the net like reducing power of wifi or other stuffs but no one working
do you have any suggestion?
when you setup a connection to wifi everithing is fine but if you need to switch to another wifi end the name of new wifi is shorter than the previous one there is a problem because the last part of previous name is attacced to new one
example:
first ssid name "abcdefghilmn"
sec. ssid name "123456"
the secon ssid name will be: "123456ghilmn"
so the result is no wifi found and go again on ap mode
Hi I made a small change to the code so that the correct littl-flsesystem-library is included on compiling
here is my modified version
I have tested it with an ESP32 and an ESP8266-board and it does compile and run as expected
the modification is here
#ifdef ESP8266
#include <LittleFS.h>
#define FILESYSTEM LittleFS
ESP8266WebServer server(80);
#elif defined(ESP32)
#include <LITTLEFS.h>
#define FILESYSTEM LITTLEFS
WebServer server(80);
#endif
full code is this
#include <esp-fs-webserver.h> // https://github.com/cotestatnt/esp-fs-webserver
#include <FS.h>
#ifndef LED_BUILTIN
#define LED_BUILTIN 2
#endif
// Test "options" values
bool boolVar = true;
uint32_t longVar = 1234567890;
String stringVar = "Test option String";
uint8_t ledPin = LED_BUILTIN;
int myTestVar1;
int myTestVar2;
int myTestVar3;
// Timezone definition to get properly time from NTP server
#define MYTZ "CET-1CEST,M3.5.0,M10.5.0/3"
struct tm Time;
#ifdef ESP8266
#include <LittleFS.h>
#define FILESYSTEM LittleFS
ESP8266WebServer server(80);
#elif defined(ESP32)
#include <LITTLEFS.h>
#define FILESYSTEM LITTLEFS
WebServer server(80);
#endif
FSWebServer myWebServer(FILESYSTEM, server);
//////////////////////////////// Filesystem /////////////////////////////////////////
void startFilesystem() {
Serial.println( F("(try to start FileSystem") );
// FILESYSTEM INIT
if ( FILESYSTEM.begin()) {
Serial.println( F("FILESYSTEM.begin() done") );
File root = FILESYSTEM.open("/", "r");
File file = root.openNextFile();
while (file) {
const char* fileName = file.name();
size_t fileSize = file.size();
Serial.printf("FS File: %s, size: %lu\n", fileName, (long unsigned)fileSize);
file = root.openNextFile();
}
Serial.println();
}
else {
Serial.println( F("ERROR on mounting filesystem. It will be formmatted!") );
FILESYSTEM.format();
Serial.println( F("formatting done ESP.restart()") );
ESP.restart();
}
}
//////////////////// Load application options from filesystem ////////////////////
bool loadApplicationConfig() {
StaticJsonDocument<1024> doc;
File file = FILESYSTEM.open("/config.json", "r");
if (file) {
Serial.println( F("successfully opened file config.json for read") );
DeserializationError error = deserializeJson(doc, file);
file.close();
if (!error) {
Serial.println(F("Deserializing config JSON.. successful"));
boolVar = doc["A bool var"];
stringVar = doc["A String var"].as<String>();
longVar = doc["A long var"];
ledPin = doc["LED Pin"];
serializeJsonPretty(doc, Serial);
Serial.println();
return true;
}
else {
Serial.println( F("Failed to deserialize JSON. File could be corrupted"));
Serial.println(error.c_str());
}
}
return false;
}
void setup() {
Serial.begin(115200);
Serial.println( F("Setup-Start") );
// FILESYSTEM INIT
startFilesystem();
// Try to connect to flash stored SSID, start AP if fails after timeout
IPAddress myIP = myWebServer.startWiFi(15000, "ESP8266_AP", "123456789" );
// Load configuration (if not present, default will be created when webserver will start)
if (loadApplicationConfig()) {
Serial.println( F("Application option loaded") );
}
else {
Serial.println( F("Application NOT loaded!") );
Serial.print( F("Open http://"));
Serial.print(myIP);
Serial.println( F("/setup to configure parameters") );
}
// Configure / setup page and start Web Server
myWebServer.addOption(FILESYSTEM, "LED Pin", ledPin);
myWebServer.addOption(FILESYSTEM, "A long var", longVar);
myWebServer.addOption(FILESYSTEM, "A String var", stringVar.c_str());
myWebServer.addOption(FILESYSTEM, "A bool var", boolVar);
myWebServer.addOption(FILESYSTEM, "my number 1", myTestVar1);
myWebServer.addOption(FILESYSTEM, "this testvar2", myTestVar2);
myWebServer.addOption(FILESYSTEM, "3 my 33 myTestVar3", myTestVar3);
if (myWebServer.begin()) {
Serial.print( F("ESP Web Server started on IP Address: ") );
Serial.println(myIP);
Serial.println();
Serial.println( F("Open ") );
Serial.print( F("http://") );
Serial.print(myIP);
Serial.println( F("/setup") );
Serial.println( F("to configure optional parameters") );
Serial.println();
Serial.println( F("Open ") );
Serial.print( F("http://") );
Serial.print(myIP);
Serial.println( F("/edit") );
Serial.println( F("to view and edit files") );
Serial.println();
Serial.println( F("Open ") );
Serial.print( F("http://") );
Serial.print(myIP);
Serial.println( F("/update") );
Serial.println( F("to upload firmware and filesystem updates"));
Serial.println();
Serial.println( F("start looping myWebServer.run()") );
}
}
void loop() {
myWebServer.run();
}
best regards Stefan
Hello cotestant.
thank you for this published project. Unfortunatly my knowledge is somehow to less to compile this project. I tested Arduino IDE and PlatformIO and goolged a lot. Found no workaround which worked.
Do you have a workaround for rookies?
Thanks
Ole
I figured I will open up a new issue with this. I was able to alter the code with your help so that the esp32 would connect to WIFI SSID that doesn't require a password. It worked perfectly. The issue now is it won't save that SSID or connect to it when I reset the esp32. Instead it sets up an AP right away after reset, as if there is no WIFI SSID stored that it can connect to.
how to use broadcastTXT... in esp-fs-webserver
Hi our community WIFI network does not require a password. Yet I am required to input a password when I try and connect to Wifi.
flatform espressif 5.3.0 mcu esp32-s2
arduino framework
src/main.cpp: In function 'void handleLed()':
src/main.cpp:88:44: error: 'class FSWebServer' has no member named 'getRequest'; did you mean 'handleRequest'?
WebServerClass* webRequest = myWebServer.getRequest();
Just discovered this awesome lib, until there was using ESPAsync, but will migrate to this one.
Would it be complicated to add option to have PEAP WiFi option? (adding one field on WebServer WiFi option)
We're in a company building where wifi is not open but works with PEAP, on Arduino ESP32 we just do something like that and it's working fine, not sure how to achieve here.
// we got PEAP Auth config?
if (EAPname!="" && EAPuser!="" && EAPpass!="" ) {
WiFi.begin(EAPname, WPA2_AUTH_PEAP, EAPuser, EAPuser, EAPpass);
// wait 30s to connect
if (!checkAPConnection(30)) {
Serial.print("Failed to connect using PEAP Auth, fallback to classic");
}
}
// in case PEAP failed or not configured, just use classic WiFi SSID/Pass
if (WiFi.status() != WL_CONNECTED) {
WiFi.begin(APname, APpass);
connected = checkAPConnection(45);
}
Thanks
How on earth do I disable the captive portal with this library? I'm using it in AP mode only, but it still presents the captive portal popup when I connect to it (which defaults to /setup) - but I want to disable this, I don't need it at all.
many thanks in advance
I am very intrested in your projject. But have no idea how to use it. Do you have more detailed help file?
Thanks.
Hi there.
For a project of mine it'd be great to also allow .yaml files in the editor.
I found the corresponding part in setup-ui/extras/edit.htm .
Can you supply an unminified version too?
Thanks and have a great day!
hi @cotestatnt
I have updated lib to 1.2.4
an error appears when I compile the esp8266 board
D:\Documents\Arduino\libraries\esp-fs-webserver-master\src\esp-fs-webserver.cpp: In member function 'bool FSWebServer::begin(const char*)':
D:\Documents\Arduino\libraries\esp-fs-webserver-master\src\esp-fs-webserver.cpp:125:16: error: 'using WebServerClass = using ESP8266WebServer = class esp8266webserver::ESP8266WebServerTemplate<WiFiServer>' {aka 'class esp8266webserver::ESP8266WebServerTemplate<WiFiServer>'} has no member named 'enableDelay'
125 | webserver->enableDelay(false);
| ^~~~~~~~~~~
.
.
.
exit status 1
Error compiling for board LOLIN(WEMOS) D1 R2 & mini.
I have also updated the board manager for esp8266, but the error still appears
is there any solution?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.