Embedded HTML in sketch to make SPIFFS data upload optional

This commit is contained in:
cschwinne 2017-02-01 21:25:09 +01:00
parent 05a757ede3
commit 31dd40fa9e
5 changed files with 438 additions and 5 deletions

View File

@ -29,10 +29,12 @@ Quick start guide:
1. Make sure your ESP module has a min. 4MB SPI flash module. (currently working on supporting 1MB modules) 1. Make sure your ESP module has a min. 4MB SPI flash module. (currently working on supporting 1MB modules)
Connect a WS2812B RGB led strip to GPIO2. Optionally connect a NO-pushbutton to GPIO0 (internal pull-up) and ground. Connect a WS2812B RGB led strip to GPIO2. Optionally connect a NO-pushbutton to GPIO0 (internal pull-up) and ground.
2. Follow a guide to setup your Arduino client (I am using version 1.6.9) with the ESP8266 libraries. 2. Follow a guide to setup your Arduino client (I am using version 1.8.1) with the ESP8266 libraries.
For current compiles I use an old version from 15th August 2016. For current compiles I use an old version from 15th August 2016.
3. You will also need the ESP8266 SPIFFS sketch data uploader. (currently working on making this step unnecessary) 3. You will also need the ESP8266 SPIFFS sketch data uploader. (currently working on making this step unnecessary)
-> In the newest commit this step is not essential (HTML included in sketch), but recommended, since otherwise you have to upload the pictures manually to /edit SPIFFS
-> The software will always use the HTML files in SPIFFS. If they are not existing, it will fallback to the sketch embedded HTML files.
4. In file "wled00.ino", change the LED count to the amount you connected. Proceed to flash the sketch and the SPIFFS data. 4. In file "wled00.ino", change the LED count to the amount you connected. Proceed to flash the sketch and the SPIFFS data.
You should also change the access point and OTA update passphrases for added security (you can change them later, this is just the "factory default"). You should also change the access point and OTA update passphrases for added security (you can change them later, this is just the "factory default").

219
wled00/htmls00.h Normal file

File diff suppressed because one or more lines are too long

210
wled00/htmls01.h Normal file
View File

@ -0,0 +1,210 @@
/*
* Settings html
*/
const char PAGE_settings[] PROGMEM = R"=====(
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Settings</title>
<script>
function GetCurrent()
{
var request = new XMLHttpRequest();
request.onreadystatechange = function()
{
if (this.readyState == 4) {
if (this.status == 200) {
if (this.responseXML != null) {
document.S_form.CSSID.value = this.responseXML.getElementsByTagName('cssid')[0].innerHTML;
document.S_form.CPASS.value = this.responseXML.getElementsByTagName('cpass')[0].innerHTML; //fake pass like ******
document.S_form.CSIP0.value = this.responseXML.getElementsByTagName('csips')[0].innerHTML;
document.S_form.CSIP1.value = this.responseXML.getElementsByTagName('csips')[1].innerHTML;
document.S_form.CSIP2.value = this.responseXML.getElementsByTagName('csips')[2].innerHTML;
document.S_form.CSIP3.value = this.responseXML.getElementsByTagName('csips')[3].innerHTML;
document.S_form.CSGW0.value = this.responseXML.getElementsByTagName('csgws')[0].innerHTML;
document.S_form.CSGW1.value = this.responseXML.getElementsByTagName('csgws')[1].innerHTML;
document.S_form.CSGW2.value = this.responseXML.getElementsByTagName('csgws')[2].innerHTML;
document.S_form.CSGW3.value = this.responseXML.getElementsByTagName('csgws')[3].innerHTML;
document.S_form.CSSN0.value = this.responseXML.getElementsByTagName('cssns')[0].innerHTML;
document.S_form.CSSN1.value = this.responseXML.getElementsByTagName('cssns')[1].innerHTML;
document.S_form.CSSN2.value = this.responseXML.getElementsByTagName('cssns')[2].innerHTML;
document.S_form.CSSN3.value = this.responseXML.getElementsByTagName('cssns')[3].innerHTML;
document.S_form.CMDNS.value = this.responseXML.getElementsByTagName('cmdns')[0].innerHTML;
document.S_form.APSSID.value = this.responseXML.getElementsByTagName('apssid')[0].innerHTML;
document.S_form.APHSSID.checked = (this.responseXML.getElementsByTagName('aphssid')[0].innerHTML)!=0?true:false;
document.S_form.APPASS.value = this.responseXML.getElementsByTagName('appass')[0].innerHTML; //fake pass like ******
document.S_form.APCHAN.value = this.responseXML.getElementsByTagName('apchan')[0].innerHTML;
document.S_form.DESC.value = this.responseXML.getElementsByTagName('desc')[0].innerHTML;
document.S_form.CLDFR.value = this.responseXML.getElementsByTagName('cldef')[0].innerHTML;
document.S_form.CLDFG.value = this.responseXML.getElementsByTagName('cldef')[1].innerHTML;
document.S_form.CLDFB.value = this.responseXML.getElementsByTagName('cldef')[2].innerHTML;
document.S_form.CLDFA.value = this.responseXML.getElementsByTagName('cldfa')[0].innerHTML;
document.S_form.FXDEF.value = this.responseXML.getElementsByTagName('fxdef')[0].innerHTML;
document.S_form.SXDEF.value = this.responseXML.getElementsByTagName('sxdef')[0].innerHTML;
document.S_form.GCBRI.checked = (this.responseXML.getElementsByTagName('gcbri')[0].innerHTML)!=0?true:false;
document.S_form.GCRGB.checked = (this.responseXML.getElementsByTagName('gcrgb')[0].innerHTML)!=0?true:false;
document.S_form.BTNON.checked = (this.responseXML.getElementsByTagName('btnon')[0].innerHTML)!=0?true:false;
document.S_form.TFADE.checked = (this.responseXML.getElementsByTagName('tfade')[0].innerHTML)!=0?true:false;
document.S_form.TDLAY.value = this.responseXML.getElementsByTagName('tdlay')[0].innerHTML;
document.S_form.TLBRI.value = this.responseXML.getElementsByTagName('tlbri')[0].innerHTML;
document.S_form.TLDUR.value = this.responseXML.getElementsByTagName('tldur')[0].innerHTML;
document.S_form.TLFDE.checked = (this.responseXML.getElementsByTagName('tlfde')[0].innerHTML)!=0?true:false;
document.S_form.NUDPP.value = this.responseXML.getElementsByTagName('nudpp')[0].innerHTML;
document.S_form.NRCVE.checked = (this.responseXML.getElementsByTagName('nrcve')[0].innerHTML)!=0?true:false;
document.S_form.NRBRI.value = this.responseXML.getElementsByTagName('nrbri')[0].innerHTML;
document.S_form.NSDIR.checked = (this.responseXML.getElementsByTagName('nsdir')[0].innerHTML)!=0?true:false;
document.S_form.NSBTN.checked = (this.responseXML.getElementsByTagName('nsbtn')[0].innerHTML)!=0?true:false;
document.S_form.NSFWD.checked = (this.responseXML.getElementsByTagName('nsfwd')[0].innerHTML)!=0?true:false;
document.S_form.NTPON.checked = (this.responseXML.getElementsByTagName('ntpon')[0].innerHTML)!=0?true:false;
document.getElementsByClassName("times")[0].innerHTML = this.responseXML.getElementsByTagName('times')[0].innerHTML;
document.S_form.NOOTA.checked = (this.responseXML.getElementsByTagName('noota')[0].innerHTML)!=0?true:false;
document.S_form.NORAP.checked = (this.responseXML.getElementsByTagName('norap')[0].innerHTML)!=0?true:false;
document.getElementsByClassName("sip")[0].innerHTML = this.responseXML.getElementsByTagName('sip')[0].innerHTML;
document.getElementsByClassName("sip")[1].innerHTML = this.responseXML.getElementsByTagName('sip')[1].innerHTML;
document.getElementsByClassName("msg")[0].innerHTML = this.responseXML.getElementsByTagName('msg')[0].innerHTML;
}
}
}
}
// send HTTP request
request.open("GET", "/get-settings", true);
request.send(null);
}
function OpenMain()
{
window.open("/","_self");
}
</script>
<style>
body {
line-height: 150%;
}
</style>
</head>
<body onload="GetCurrent()" class=" __plain_text_READY__">
<h1>WLED Settings</h1>
<form id="form_s" name="S_form" action="set-settings" method="post">
<input type="submit" name="SUBM" value="Save">
<input type="button" name="BACK" value="Back" onclick="OpenMain()">
<h2>WiFi setup</h2>
<h3>Connect to existing network</h3>
Network SSID (leave empty to not connect): <br> <input name="CSSID" maxlength="32"> <br>
Network password: <br> <input type="password" name="CPASS" maxlength="63"> <br>
Static IP (leave at 0.0.0.0 for DHCP): <br>
<input name="CSIP0" maxlength="3" size="2"> .
<input name="CSIP1" maxlength="3" size="2"> .
<input name="CSIP2" maxlength="3" size="2"> .
<input name="CSIP3" maxlength="3" size="2"> <br>
Static gateway: <br>
<input name="CSGW0" maxlength="3" size="2"> .
<input name="CSGW1" maxlength="3" size="2"> .
<input name="CSGW2" maxlength="3" size="2"> .
<input name="CSGW3" maxlength="3" size="2"> <br>
Static subnet mask: <br>
<input name="CSSN0" maxlength="3" size="2"> .
<input name="CSSN1" maxlength="3" size="2"> .
<input name="CSSN2" maxlength="3" size="2"> .
<input name="CSSN3" maxlength="3" size="2"> <br>
mDNS address (leave empty for no mDNS): <br/>
http:// <input name="CMDNS" maxlength="32"> .local <br>
Client IP: <span class="sip"> Not connected </span> <br>
<h3>Configure Access Point</h3>
AP SSID (leave empty for no AP): <br> <input name="APSSID" maxlength="32"> <br>
Hide AP SSID: <input type="checkbox" name="APHSSID" value="0"> <br>
AP password (leave empty for open): <br> <input type="password" name="APPASS" maxlength="63"> <br>
AP channel: <input name="APCHAN" maxlength="2" size="2"> <br>
AP IP: <span class="sip"> Not active </span> <br>
<h2>Application setup</h2>
<h3>Web setup</h3>
Server description: <input name="DESC" maxlength="32"> <br>
<h3>LED setup</h3>
Default RGB color:
<input name="CLDFR" maxlength="3" size="2">
<input name="CLDFG" maxlength="3" size="2">
<input name="CLDFB" maxlength="3" size="2"> <br>
Default brightness: <input name="CLDFA" maxlength="3" size="2"> (0-255) <br>
Default effect ID: <input name="FXDEF" maxlength="3" size="2"> <br>
Default effect speed: <input name="SXDEF" maxlength="3" size="2"> <br>
Ignore and use current color, brightness and effects: <input type="checkbox" name="CBEOR" value="0"> <br>
Use Gamma correction for brightness: <input type="checkbox" name="GCBRI" value="0"> <br>
Use Gamma correction for color: <input type="checkbox" name="GCRGB" value="0"> <br>
Brightness factor: <input name="NRBRI" maxlength="3" size="2"> % <br>
<h3>Button setup</h3>
On/Off button enabled: <input type="checkbox" name="BTNON" value="0"> <br>
<h3>Transitions</h3>
Fade: <input type="checkbox" name="TFADE" value="0"> <br>
Transition Delay: <input name="TDLAY" maxlength="5" size="2"> ms <br>
<h3>Timed light</h3>
Target brightness: <input name="TLBRI" maxlength="3" size="2"> (0-255) <br>
Change after: <input name="TLDUR" maxlength="3" size="2"> min <br>
Fade: <input type="checkbox" name="TLFDE" value="0"> <br>
<h3>Daisy chain</h3>
UDP Port: <input name="NUDPP" maxlength="5" size="2"><br>
Receive notifications: <input type="checkbox" name="NRCVE" value="0"> <br>
Send notifications on direct change: <input type="checkbox" name="NSDIR" value="0"> <br>
Send notifications on button press: <input type="checkbox" name="NSBTN" value="0"> <br>
Send nightlight notifications: <input type="checkbox" name="NSFWD" value="0"> <br>
<h3>Time</h3>
<b>Warning! Using NTP usually results in a complete system crash after 1-48 hours. <br>
Please only enable it if you are willing to experiment with it. </b> <br>
Get time from NTP server: <input type="checkbox" name="NTPON" value="0"> <br>
Current local time is <span class="times">unknown</span> <br>
<h3>Security</h3>
OTA locked: <input type="checkbox" name="NOOTA" value="0"> <br>
Passphrase: <input type="password" name="OPASS" maxlength="32"> <br>
To enable OTA, for security reasons you need to also enter the correct password! <br>
The password may/should be changed when OTA is enabled. <br>
Disable OTA when not in use, otherwise an attacker could reflash device software! <br> <br>
Disable recovery AP (<i>Not implemented</i>): <input type="checkbox" name="NORAP" value="0"> <br>
In case of a connection error there will be no wireless recovery possible! <br>
Completely disables all Access Point functions. <br> <br>
Factory reset: <input type="checkbox" name="RESET" value="0"> <br>
All EEPROM content (settings) will be erased. <br> <br>
HTTP traffic is not encrypted. An attacker in the same network could intercept form data!<br>
<h3>About</h3>
WLED version 0.3pd <br>
(c) 2016-2017 Christian Schwinne <br>
<i>Licensed under the MIT license</i> <br>
<i>Uses libraries:</i> <br>
<i>ESP8266 Arduino Core</i> <br>
<i>WS2812FX by kitesurfer1404 (Aircoookie fork)</i> <br>
<i>Timezone library by JChristensen</i> <br>
Server message: <span class="msg"> XML response error! </span>
<br><br>
<input type="submit" name="SUBM" value="Save">
<input type="button" name="BACK" value="Back" onclick="OpenMain()">
</form>
</body>
</html>
)=====";
/*
* Settings set html
*/
const char PAGE_settingssaved[] PROGMEM = R"=====(
<!DOCTYPE html>
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Saved Settings</title>
<script>
function OpenMain()
{
window.open("/","_self");
}
function OpenReboot()
{
window.open("/reset","_self");
}
</script>
</head><body>
<div align="center">
<h2>Settings saved.</h2>
<p>If you made changes to WiFi configuration, please reboot.</p><br>
<input type="button" name="BACK" value="Close" onclick="OpenMain()">
<input type="button" name="BACK" value="Reboot" onclick="OpenReboot()">
</div></body>
</html>
)=====";

View File

@ -15,6 +15,8 @@
#include <Time.h> #include <Time.h>
#include <TimeLib.h> #include <TimeLib.h>
#include <Timezone.h> #include <Timezone.h>
#include "htmls00.h"
#include "htmls01.h"
//to toggle usb serial debug (un)comment following line //to toggle usb serial debug (un)comment following line
//#define DEBUG //#define DEBUG

View File

@ -70,7 +70,7 @@ void wledInit()
//SERVER INIT //SERVER INIT
//settings page //settings page
server.on("/settings", HTTP_GET, [](){ server.on("/settings", HTTP_GET, [](){
if(!handleFileRead("/settings.htm")) server.send(404, "text/plain", "FileNotFound"); if(!handleFileRead("/settings.htm")) server.send(200, "text/html", PAGE_settings);
}); });
server.on("/button.png", HTTP_GET, [](){ server.on("/button.png", HTTP_GET, [](){
if(!handleFileRead("/button.png")) server.send(404, "text/plain", "FileNotFound"); if(!handleFileRead("/button.png")) server.send(404, "text/plain", "FileNotFound");
@ -82,7 +82,7 @@ void wledInit()
if(!handleFileRead("/favicon.ico")) server.send(404, "text/plain", "FileNotFound"); if(!handleFileRead("/favicon.ico")) server.send(404, "text/plain", "FileNotFound");
}); });
server.on("/", HTTP_GET, [](){ server.on("/", HTTP_GET, [](){
if(!handleFileRead("/index.htm")) server.send(404, "text/plain", "FileNotFound"); if(!handleFileRead("/index.htm")) server.send(200, "text/html", PAGE_index);
}); });
server.on("/reset", HTTP_GET, [](){ server.on("/reset", HTTP_GET, [](){
server.send(200, "text/plain", "Rebooting... Go to main page when lights turn on."); server.send(200, "text/plain", "Rebooting... Go to main page when lights turn on.");
@ -90,11 +90,11 @@ void wledInit()
}); });
server.on("/set-settings", HTTP_POST, [](){ server.on("/set-settings", HTTP_POST, [](){
handleSettingsSet(); handleSettingsSet();
if(!handleFileRead("/settingssaved.htm")) server.send(404, "text/plain", "SettingsSaved"); if(!handleFileRead("/settingssaved.htm")) server.send(200, "text/html", PAGE_settingssaved);
}); });
if (!ota_lock){ if (!ota_lock){
server.on("/edit", HTTP_GET, [](){ server.on("/edit", HTTP_GET, [](){
if(!handleFileRead("/edit.htm")) server.send(404, "text/plain", "FileNotFound"); if(!handleFileRead("/edit.htm")) server.send(200, "text/html", PAGE_edit);
}); });
server.on("/edit", HTTP_PUT, handleFileCreate); server.on("/edit", HTTP_PUT, handleFileCreate);
server.on("/edit", HTTP_DELETE, handleFileDelete); server.on("/edit", HTTP_DELETE, handleFileDelete);