Release of v0.7.0

Substantial optimizations of mobile UI
Added option to save current preset cycle as boot default
Added option not to use first LED in strip
Realtime UI error now includes source IP address
Removed /down and /cleareeprom pages
Fixed bug (turning receiveDirect off would crash on UDP packet)
This commit is contained in:
cschwinne 2018-06-24 01:20:15 +02:00
parent 5d8d12bc89
commit 094bdf02c4
21 changed files with 503 additions and 1671 deletions

View File

@ -2,29 +2,28 @@
WLED is a fast and (relatively) secure implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B) LEDs! WLED is a fast and (relatively) secure implementation of an ESP8266/ESP32 webserver to control NeoPixel (WS2812B) LEDs!
### Features: (V0.6.4) ### Features: (V0.7.0)
- RGB, HSB, and brightness sliders - RGB, HSB, and brightness sliders
- All new, mobile-friendly web UI!
- Settings page - configuration over network - Settings page - configuration over network
- Access Point and station mode - automatic failsafe AP - Access Point and station mode - automatic failsafe AP
- WS2812FX library integrated for over 50 special effects! - WS2812FX library integrated for over 50 special effects (+Custom Theater Chase)!
- Secondary color support lets you use even more effect combinations - Secondary color support lets you use even more effect combinations
- Alexa smart home device server (including dimming) - Alexa smart home device server (including dimming)
- Beta syncronization to Philips hue lights - Beta syncronization to Philips hue lights
- Support for RGBW strips - Support for RGBW strips
- 25 user presets! Save your favorite colors and effects and apply them easily! Now supports cycling through them. - 25 user presets! Save colors and effects and apply them easily! Supports cycling through them.
- HTTP request API for simple integration - HTTP request API for simple integration
- Macro functions to automatically execute API calls - Macro functions to automatically execute API calls
- Nightlight function (gradually dims down) - Nightlight function (gradually dims down)
- Notifier function (multiple ESPs sync color via UDP broadcast) - Notifier function (multiple ESPs sync color via UDP broadcast)
- Support for power pushbutton - Support for power pushbutton
- Custom Theater Chase
- Support for the Adalight serial ambilight protocol! - Support for the Adalight serial ambilight protocol!
- Full OTA software update capability (HTTP and ArduinoOTA) - Full OTA software update capability (HTTP and ArduinoOTA)
- Password protected OTA page for added security (OTA lock) - Password protected OTA page for added security (OTA lock)
- NTP and configurable analog clock function - NTP and configurable analog clock function
- Support for the Cronixie Clock kit by Diamex - Support for the Cronixie Clock kit by Diamex
- Realtime UDP Packet Control (WARLS, DRGB, DRGBW) possible - Realtime UDP Packet Control (Hyperion, WARLS, DRGB, DRGBW)
- Client HTML UI controlled, customizable themes
### Quick start guide and documentation: ### Quick start guide and documentation:

View File

@ -37,8 +37,8 @@
#define CALL_MODE(n) (this->*_mode[n])(); #define CALL_MODE(n) (this->*_mode[n])();
void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t pin) { void WS2812FX::init(bool supportWhite, uint16_t countPixels, uint8_t pin,bool skipFirst) {
begin(supportWhite,countPixels,pin); begin(supportWhite,countPixels,pin,skipFirst);
for (int i=0; i < _led_count; i++) _locked[i] = false; for (int i=0; i < _led_count; i++) _locked[i] = false;
WS2812FX::setBrightness(_brightness); WS2812FX::setBrightness(_brightness);
show(); show();
@ -2032,6 +2032,7 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
if (_reverseMode) i = _led_count - 1 -i; if (_reverseMode) i = _led_count - 1 -i;
if (!_cronixieMode) if (!_cronixieMode)
{ {
if (_skipFirstMode) {i++;if(i==1)setPixelColorRaw(0,0,0,0,0);}
if (_rgbwMode) if (_rgbwMode)
{ {
bus->SetPixelColor(i, RgbwColor(r,g,b,w)); bus->SetPixelColor(i, RgbwColor(r,g,b,w));
@ -2050,27 +2051,27 @@ void WS2812FX::setPixelColor(uint16_t i, byte r, byte g, byte b, byte w)
byte wCorr = (int)(((double)((_color_sec>>24) & 0xFF))*_cronixieSecMultiplier); byte wCorr = (int)(((double)((_color_sec>>24) & 0xFF))*_cronixieSecMultiplier);
for (int j=o; j< o+19; j++) for (int j=o; j< o+19; j++)
{ {
setPixelColorRaw(j,rCorr,gCorr,bCorr,wCorr); setPixelColorRaw((_skipFirstMode)?j+1:j,rCorr,gCorr,bCorr,wCorr);
} }
} else } else
{ {
for (int j=o; j< o+19; j++) for (int j=o; j< o+19; j++)
{ {
setPixelColorRaw(j,0,0,0,0); setPixelColorRaw((_skipFirstMode)?j+1:j,0,0,0,0);
} }
} }
switch(_cronixieDigits[i]) switch(_cronixieDigits[i])
{ {
case 0: setPixelColorRaw(o+5,r,g,b,w); break; case 0: setPixelColorRaw((_skipFirstMode)?o+6:o+5,r,g,b,w); break;
case 1: setPixelColorRaw(o+0,r,g,b,w); break; case 1: setPixelColorRaw((_skipFirstMode)?o+1:o+0,r,g,b,w); break;
case 2: setPixelColorRaw(o+6,r,g,b,w); break; case 2: setPixelColorRaw((_skipFirstMode)?o+7:o+6,r,g,b,w); break;
case 3: setPixelColorRaw(o+1,r,g,b,w); break; case 3: setPixelColorRaw((_skipFirstMode)?o+2:o+1,r,g,b,w); break;
case 4: setPixelColorRaw(o+7,r,g,b,w); break; case 4: setPixelColorRaw((_skipFirstMode)?o+8:o+7,r,g,b,w); break;
case 5: setPixelColorRaw(o+2,r,g,b,w); break; case 5: setPixelColorRaw((_skipFirstMode)?o+3:o+2,r,g,b,w); break;
case 6: setPixelColorRaw(o+8,r,g,b,w); break; case 6: setPixelColorRaw((_skipFirstMode)?o+9:o+8,r,g,b,w); break;
case 7: setPixelColorRaw(o+3,r,g,b,w); break; case 7: setPixelColorRaw((_skipFirstMode)?o+4:o+3,r,g,b,w); break;
case 8: setPixelColorRaw(o+9,r,g,b,w); break; case 8: setPixelColorRaw((_skipFirstMode)?o+10:o+9,r,g,b,w); break;
case 9: setPixelColorRaw(o+4,r,g,b,w); break; case 9: setPixelColorRaw((_skipFirstMode)?o+5:o+4,r,g,b,w); break;
default: break; default: break;
} }
} }
@ -2134,17 +2135,19 @@ void WS2812FX::clear()
bus->ClearTo(RgbColor(0)); bus->ClearTo(RgbColor(0));
} }
void WS2812FX::begin(bool supportWhite, uint16_t countPixels, uint8_t pin) void WS2812FX::begin(bool supportWhite, uint16_t countPixels, uint8_t pin, bool skipFirst)
{ {
if (supportWhite == _rgbwMode && countPixels == _led_count && _locked != NULL) return; if (supportWhite == _rgbwMode && countPixels == _led_count && _locked != NULL) return;
_rgbwMode = supportWhite; _rgbwMode = supportWhite;
_skipFirstMode = skipFirst;
_led_count = countPixels; _led_count = countPixels;
_cc_i2 = _led_count -1; _cc_i2 = _led_count -1;
if (_skipFirstMode) _led_count++;
uint8_t ty = 1; uint8_t ty = 1;
if (supportWhite) ty =2; if (supportWhite) ty =2;
bus->Begin((NeoPixelType)ty, countPixels, pin); bus->Begin((NeoPixelType)ty, _led_count, pin);
if (_locked != NULL) delete _locked; if (_locked != NULL) delete _locked;
_locked = new bool[countPixels]; _locked = new bool[_led_count];
} }
//For some reason min and max are not declared here //For some reason min and max are not declared here

View File

@ -199,6 +199,7 @@ class WS2812FX {
_counter_ccStep = 0; _counter_ccStep = 0;
_fastStandard = false; _fastStandard = false;
_reverseMode = false; _reverseMode = false;
_skipFirstMode = false;
_locked = NULL; _locked = NULL;
_cronixieDigits = new byte[6]; _cronixieDigits = new byte[6];
bus = new NeoPixelWrapper(); bus = new NeoPixelWrapper();
@ -208,7 +209,7 @@ class WS2812FX {
show(void), show(void),
setPixelColor(uint16_t i, byte r, byte g, byte b), setPixelColor(uint16_t i, byte r, byte g, byte b),
setPixelColor(uint16_t i, byte r, byte g, byte b, byte w), setPixelColor(uint16_t i, byte r, byte g, byte b, byte w),
init(bool supportWhite, uint16_t countPixels, uint8_t pin), init(bool supportWhite, uint16_t countPixels, uint8_t pin, bool skipFirst),
service(void), service(void),
start(void), start(void),
stop(void), stop(void),
@ -277,7 +278,7 @@ class WS2812FX {
NeoPixelWrapper *bus; NeoPixelWrapper *bus;
void void
begin(bool supportWhite, uint16_t countPixels, uint8_t pin), begin(bool supportWhite, uint16_t countPixels, uint8_t pin, bool skipFirst),
clear(void), clear(void),
setPixelColor(uint16_t i, uint32_t c), setPixelColor(uint16_t i, uint32_t c),
setPixelColorRaw(uint16_t i, byte r, byte g, byte b, byte w), setPixelColorRaw(uint16_t i, byte r, byte g, byte b, byte w),
@ -348,6 +349,7 @@ class WS2812FX {
bool bool
_triggered, _triggered,
_rgbwMode, _rgbwMode,
_skipFirstMode,
_fastStandard, _fastStandard,
_reverseMode, _reverseMode,
_cronixieMode, _cronixieMode,

View File

@ -1,6 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head><meta charset="utf-8"> <head><meta charset="utf-8"><meta name="theme-color" content="#fff">
<link rel='shortcut icon' type='image/x-icon' href='/favicon.ico'/> <link rel='shortcut icon' type='image/x-icon' href='/favicon.ico'/>
<title>WLED 0.7.0</title> <title>WLED 0.7.0</title>
<script> <script>
@ -33,6 +33,7 @@
aC = w.getPropertyValue("--aCol"); aC = w.getPropertyValue("--aCol");
bC = w.getPropertyValue("--bCol"); bC = w.getPropertyValue("--bCol");
dC = w.getPropertyValue("--dCol"); dC = w.getPropertyValue("--dCol");
d.querySelector("meta[name=theme-color]").setAttribute("content",bC);
CV(0); CV(0);
setInterval('GIO()', 5000); setInterval('GIO()', 5000);
GIO(); GIO();
@ -197,6 +198,7 @@
function SwFX(s) function SwFX(s)
{ {
var n=Cf.TX.selectedIndex+s; var n=Cf.TX.selectedIndex+s;
if (n==-1||n==58) return;
Cf.TX.selectedIndex =n; Cf.TX.selectedIndex =n;
if (n < 0) Cf.TX.selectedIndex = 0; if (n < 0) Cf.TX.selectedIndex = 0;
if (n > 57) Cf.TX.selectedIndex = 53; if (n > 57) Cf.TX.selectedIndex = 53;
@ -352,11 +354,12 @@
</script> </script>
<style> <style>
:root { :root {
--aCol: #0ac; --aCol: #D9B310;
--bCol: #124; --bCol: #0B3C5D;
--cCol: #334; --cCol: #1D2731;
--dCol: #288; --dCol: #328CC1;
--sCol: #FF00FF; --sCol: #000;
--tCol: #328CC1;
--cFn: Verdana; --cFn: Verdana;
} }
.ctrl_box { .ctrl_box {

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@
window.location = "/settings"; window.location = "/settings";
} }
function RP() { function RP() {
top.location.href=top.location.href; top.location.href="/";
} }
</script> </script>
<style> <style>

View File

@ -19,6 +19,9 @@
margin: 0; margin: 0;
background-attachment: fixed; background-attachment: fixed;
} }
html {
--h:11.55vh;
}
button { button {
background: var(--bCol); background: var(--bCol);
color: var(--tCol); color: var(--tCol);
@ -27,13 +30,23 @@
display: inline-block; display: inline-block;
filter: drop-shadow( -5px -5px 5px var(--sCol) ); filter: drop-shadow( -5px -5px 5px var(--sCol) );
font-size: 8vmin; font-size: 8vmin;
height:13.86vh; height:var(--h);
width: 95%; width: 95%;
margin-top: 2.4vh; margin-top: 2.4vh;
} }
</style> </style>
<script>
function BB()
{
if (window.frameElement) {
document.getElementById("b").style.display = "none";
document.documentElement.style.setProperty('--h',"13.86vh");
}
}
</script>
</head> </head>
<body> <body onload="BB()">
<form action="/"><button type=submit id="b">Back</button></form>
<form action="/settings/wifi"><button type="submit">WiFi Setup</button></form> <form action="/settings/wifi"><button type="submit">WiFi Setup</button></form>
<form action="/settings/leds"><button type="submit">LED Preferences</button></form> <form action="/settings/leds"><button type="submit">LED Preferences</button></form>
<form action="/settings/ui"><button type="submit">User Interface</button></form> <form action="/settings/ui"><button type="submit">User Interface</button></form>

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -7,15 +7,15 @@ body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);
const char PAGE_settings0[] PROGMEM = R"=====( const char PAGE_settings0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html> <html><head><title>WLED Settings</title>
<head>
<title>WLED Settings</title>
)====="; )=====";
const char PAGE_settings1[] PROGMEM = R"=====( const char PAGE_settings1[] PROGMEM = R"=====(
body{text-align:center;background:var(--cCol);height:100%;margin:0;background-attachment:fixed}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:8vmin;height:13.86vh;width:95%;margin-top:2.4vh}</style> body{text-align:center;background:var(--cCol);height:100%;margin:0;background-attachment:fixed}html{--h:11.55vh}button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),Helvetica,sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:8vmin;height:var(--h);width:95%;margin-top:2.4vh}</style>
<script>function BB(){if(window.frameElement){document.getElementById("b").style.display="none";document.documentElement.style.setProperty("--h","13.86vh")}};</script>
</head> </head>
<body> <body onload=BB()>
<form action=/><button type=submit id=b>Back</button></form>
<form action=/settings/wifi><button type=submit>WiFi Setup</button></form> <form action=/settings/wifi><button type=submit>WiFi Setup</button></form>
<form action=/settings/leds><button type=submit>LED Preferences</button></form> <form action=/settings/leds><button type=submit>LED Preferences</button></form>
<form action=/settings/ui><button type=submit>User Interface</button></form> <form action=/settings/ui><button type=submit>User Interface</button></form>
@ -28,8 +28,7 @@ body{text-align:center;background:var(--cCol);height:100%;margin:0;background-at
const char PAGE_settings_wifi0[] PROGMEM = R"=====( const char PAGE_settings_wifi0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html> <html><head>
<head>
<title>WiFi Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#wifi-settings");}function B(){window.history.back();}function GetV(){var d = document; <title>WiFi Settings</title><script>function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#wifi-settings");}function B(){window.history.back();}function GetV(){var d = document;
)====="; )=====";
const char PAGE_settings_wifi1[] PROGMEM = R"=====( const char PAGE_settings_wifi1[] PROGMEM = R"=====(
@ -104,6 +103,7 @@ Default secondary RGB(W):<br>
<input name="SB" type="number" min="0" max="255" required> <input name="SB" type="number" min="0" max="255" required>
<input name="SW" type="number" min="0" max="255" required><br> <input name="SW" type="number" min="0" max="255" required><br>
Ignore and use current color, brightness and effects: <input type="checkbox" name="IS"><br> Ignore and use current color, brightness and effects: <input type="checkbox" name="IS"><br>
Save current preset cycle configuration as boot default: <input type="checkbox" name="PC"><br>
Turn on after power up/reset: <input type="checkbox" name="BO"><br> Turn on after power up/reset: <input type="checkbox" name="BO"><br>
Use Gamma correction for brightness: <input type="checkbox" name="GB"><br> Use Gamma correction for brightness: <input type="checkbox" name="GB"><br>
Use Gamma correction for color: <input type="checkbox" name="GC"><br> Use Gamma correction for color: <input type="checkbox" name="GC"><br>
@ -120,7 +120,8 @@ Fade down: <input type="checkbox" name="TW"><br>
<h3>Advanced</h3> <h3>Advanced</h3>
Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br> Reverse LED order (rotate 180): <input type="checkbox" name="RV"><br>
Init LEDs after WiFi: <input type="checkbox" name="EI"><br> Init LEDs after WiFi: <input type="checkbox" name="EI"><br>
WARLS offset: <input name="WO" type="number" min="-255" max="255" required><hr> WARLS offset: <input name="WO" type="number" min="-255" max="255" required><br>
Skip first LED: <input type="checkbox" name="SL"><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button> <button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form> </form>
</body> </body>
@ -129,8 +130,7 @@ WARLS offset: <input name="WO" type="number" min="-255" max="255" required><hr>
const char PAGE_settings_ui0[] PROGMEM = R"=====( const char PAGE_settings_ui0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html> <html><head>
<head>
<title>UI Settings</title><script> <title>UI Settings</title><script>
function gId(s){return document.getElementById(s);}function S(){GetV();Ct();}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");}function B(){window.history.back();}function Ct(){if (gId("co").selected){gId("cth").style.display="block";}else{gId("cth").style.display="none";}}function GetV(){var d = document; function gId(s){return document.getElementById(s);}function S(){GetV();Ct();}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings");}function B(){window.history.back();}function Ct(){if (gId("co").selected){gId("cth").style.display="block";}else{gId("cth").style.display="none";}}function GetV(){var d = document;
)====="; )=====";
@ -146,9 +146,9 @@ User Interface Mode:
<option value="0" selected>Auto</option> <option value="0" selected>Auto</option>
<option value="1">Classic</option> <option value="1">Classic</option>
<option value="2">Mobile</option> <option value="2">Mobile</option>
</select><br><br> </select><br>
Server description: <input name="DS" maxlength="32"><br><br>
<i>The following options are for the classic UI!</i><br> <i>The following options are for the classic UI!</i><br>
Server description: <input name="DS" maxlength="32"><br>
Use HSB sliders instead of RGB by default: <input type="checkbox" name="MD"><br> Use HSB sliders instead of RGB by default: <input type="checkbox" name="MD"><br>
Color Theme: Color Theme:
<select name="TH" onchange="Ct()"> <select name="TH" onchange="Ct()">
@ -214,6 +214,8 @@ Emulate Alexa device: <input type="checkbox" name="AL"><br>
Alexa invocation name: <input name="AI" maxlength="32"><br> Alexa invocation name: <input name="AI" maxlength="32"><br>
<h3>Philips Hue</h3> <h3>Philips Hue</h3>
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br> <i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
Poll Hue light <input name="HL" type="number" min="1" max="99" required> every <input name="HI" type="number" min="100" max="65000" required> ms: <input type="checkbox" name="HP"><br>
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
Hue Bridge IP:<br> Hue Bridge IP:<br>
<input name="H0" type="number" min="0" max="255" required> . <input name="H0" type="number" min="0" max="255" required> .
<input name="H1" type="number" min="0" max="255" required> . <input name="H1" type="number" min="0" max="255" required> .
@ -221,8 +223,6 @@ Hue Bridge IP:<br>
<input name="H3" type="number" min="0" max="255" required><br> <input name="H3" type="number" min="0" max="255" required><br>
<b>Press the pushlink button on the bridge, after that save this page!</b><br> <b>Press the pushlink button on the bridge, after that save this page!</b><br>
(when first connecting)<br> (when first connecting)<br>
Poll Hue light <input name="HL" type="number" min="1" max="99" required> every <input name="HI" type="number" min="100" max="65000" required> ms: <input type="checkbox" name="HP"><br>
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
Hue status: <span class="hms"> Internal ESP Error! </span><hr> Hue status: <span class="hms"> Internal ESP Error! </span><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save</button> <button type="button" onclick="B()">Back</button><button type="submit">Save</button>
</form> </form>

View File

@ -9,7 +9,7 @@ const char PAGE_msg0[] PROGMEM = R"=====(
<!DOCTYPE html> <!DOCTYPE html>
<html><head> <html><head>
<title>WLED Message</title> <title>WLED Message</title>
<script>function B(){window.history.back()};function RS(){window.location = "/settings";}function RP(){top.location.href=top.location.href;}</script> <script>function B(){window.history.back()};function RS(){window.location = "/settings";}function RP(){top.location.href="/";}</script>
)====="; )=====";
const char PAGE_msg1[] PROGMEM = R"=====( const char PAGE_msg1[] PROGMEM = R"=====(
button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%;margin:0;background-attachment:fixed}</style> button{background:var(--bCol);color:var(--tCol);font-family:var(--cFn),sans-serif;border:.3ch solid var(--bCol);display:inline-block;filter:drop-shadow(-5px -5px 5px var(--sCol));font-size:20px;margin:8px;margin-top:12px}body{font-family:var(--cFn),sans-serif;text-align:center;background:var(--cCol);color:var(--tCol);line-height:200%;margin:0;background-attachment:fixed}</style>

View File

@ -90,8 +90,8 @@ WebServer::~WebServer() {
void WebServer::begin() { void WebServer::begin() {
_currentStatus = HC_NONE; _currentStatus = HC_NONE;
_server.begin(); _server.begin();
if(!_headerKeysCount) //if(!_headerKeysCount)
collectHeaders(0, 0); //collectHeaders(0, 0);
} }
bool WebServer::authenticate(const char * username, const char * password){ bool WebServer::authenticate(const char * username, const char * password){
@ -408,15 +408,13 @@ String WebServer::header(String name) {
return String(); return String();
} }
void WebServer::collectHeaders(const char* headerKeys[], const size_t headerKeysCount) { //Modified by Aircoookie to work for WLED
_headerKeysCount = headerKeysCount + 1; void WebServer::collectHeaders(String headerKey) {
if (_currentHeaders) _headerKeysCount = 2;
delete[]_currentHeaders; if (_currentHeaders) delete[]_currentHeaders;
_currentHeaders = new RequestArgument[_headerKeysCount]; _currentHeaders = new RequestArgument[2];
_currentHeaders[0].key = AUTHORIZATION_HEADER; _currentHeaders[0].key = AUTHORIZATION_HEADER;
for (int i = 1; i < _headerKeysCount; i++){ _currentHeaders[1].key = headerKey;
_currentHeaders[i].key = headerKeys[i-1];
}
} }
String WebServer::header(int i) { String WebServer::header(int i) {

View File

@ -105,7 +105,7 @@ public:
String argName(int i); // get request argument name by number String argName(int i); // get request argument name by number
int args(); // get arguments count int args(); // get arguments count
bool hasArg(String name); // check if argument exists bool hasArg(String name); // check if argument exists
void collectHeaders(const char* headerKeys[], const size_t headerKeysCount); // set the request headers to collect void collectHeaders(String headerKey); // set the request headers to collect
String header(String name); // get request header value by name String header(String name); // get request header value by name
String header(int i); // get request header value by number String header(int i); // get request header value by number
String headerName(int i); // get request header name by number String headerName(int i); // get request header name by number

View File

@ -7,6 +7,10 @@
* @author Christian Schwinne * @author Christian Schwinne
*/ */
//ESP8266-01 got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.3.0 and the setting 512K(64K SPIFFS).
//Uncomment the following line to disable some features (currently Mobile UI) to compile for ESP8266-01
//#define WLED_FLASH_512K_MODE
#include <Arduino.h> #include <Arduino.h>
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
#include <WiFi.h> #include <WiFi.h>
@ -33,7 +37,7 @@
#include "WS2812FX.h" #include "WS2812FX.h"
//version in format yymmddb (b = daily build) //version in format yymmddb (b = daily build)
#define VERSION 1805311 #define VERSION 1806240
const String versionString = "0.7.0"; const String versionString = "0.7.0";
//AP and OTA default passwords (change them!) //AP and OTA default passwords (change them!)
@ -72,7 +76,7 @@ IPAddress staticSubnet(255, 255, 255, 0);
IPAddress staticDNS(8, 8, 8, 8); //only for NTP IPAddress staticDNS(8, 8, 8, 8); //only for NTP
bool useHSB = true, useHSBDefault = true, useRGBW = false, autoRGBtoRGBW = false; bool useHSB = true, useHSBDefault = true, useRGBW = false, autoRGBtoRGBW = false;
bool turnOnAtBoot = true; bool turnOnAtBoot = true;
bool initLedsLast = false; bool initLedsLast = false, skipFirstLed = false;
byte bootPreset = 0; byte bootPreset = 0;
byte colS[]{255, 159, 0}; byte colS[]{255, 159, 0};
byte colSecS[]{0, 0, 0}; byte colSecS[]{0, 0, 0};
@ -214,10 +218,12 @@ byte presetCycleMin = 1, presetCycleMax = 5;
uint16_t presetCycleTime = 1250; uint16_t presetCycleTime = 1250;
unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin; unsigned long presetCycledTime = 0; byte presetCycCurr = presetCycleMin;
bool presetApplyBri = true, presetApplyCol = true, presetApplyFx = true; bool presetApplyBri = true, presetApplyCol = true, presetApplyFx = true;
bool saveCurrPresetCycConf = false;
uint32_t arlsTimeoutMillis = 2500; uint32_t arlsTimeoutMillis = 2500;
bool arlsTimeout = false; bool arlsTimeout = false;
bool receiveDirect = true, enableRealtimeUI = false; bool receiveDirect = true, enableRealtimeUI = false;
IPAddress realtimeIP = (0,0,0,0);
unsigned long arlsTimeoutTime = 0; unsigned long arlsTimeoutTime = 0;
byte auxTime = 0; byte auxTime = 0;
unsigned long auxStartTime = 0; unsigned long auxStartTime = 0;
@ -300,14 +306,6 @@ String txd = "Please disable OTA Lock in security settings!";
void serveMessage(int,String,String,int=255); void serveMessage(int,String,String,int=255);
void down()
{
briT = 0;
setAllLeds();
DEBUG_PRINTLN("MODULE TERMINATED");
while (1) {delay(1000);}
}
void reset() void reset()
{ {
briT = 0; briT = 0;

View File

@ -214,6 +214,20 @@ void saveSettingsToEEPROM()
EEPROM.write(2201,enableRealtimeUI); EEPROM.write(2201,enableRealtimeUI);
EEPROM.write(2202,uiConfiguration); EEPROM.write(2202,uiConfiguration);
EEPROM.write(2203,autoRGBtoRGBW); EEPROM.write(2203,autoRGBtoRGBW);
EEPROM.write(2204,skipFirstLed);
if (saveCurrPresetCycConf)
{
EEPROM.write(2205,presetCyclingEnabled);
EEPROM.write(2206,(presetCycleTime >> 0) & 0xFF);
EEPROM.write(2207,(presetCycleTime >> 8) & 0xFF);
EEPROM.write(2208,presetCycleMin);
EEPROM.write(2209,presetCycleMax);
EEPROM.write(2210,presetApplyBri);
EEPROM.write(2211,presetApplyCol);
EEPROM.write(2212,presetApplyFx);
saveCurrPresetCycConf = false;
}
EEPROM.commit(); EEPROM.commit();
} }
@ -425,7 +439,25 @@ void loadSettingsFromEEPROM(bool first)
receiveDirect = !EEPROM.read(2200); receiveDirect = !EEPROM.read(2200);
enableRealtimeUI = EEPROM.read(2201); enableRealtimeUI = EEPROM.read(2201);
uiConfiguration = EEPROM.read(2202); uiConfiguration = EEPROM.read(2202);
#ifdef WLED_FLASH_512K_MODE
uiConfiguration = 1;
//force default UI since mobile is unavailable
#endif
autoRGBtoRGBW = EEPROM.read(2203); autoRGBtoRGBW = EEPROM.read(2203);
skipFirstLed = EEPROM.read(2204);
if (EEPROM.read(2210) || EEPROM.read(2211) || EEPROM.read(2212))
{
presetCyclingEnabled = EEPROM.read(2205);
presetCycleTime = ((EEPROM.read(2206) << 0) & 0xFF) + ((EEPROM.read(2207) << 8) & 0xFF00);
presetCycleMin = EEPROM.read(2208);
presetCycleMax = EEPROM.read(2209);
presetApplyBri = EEPROM.read(2210);
presetApplyCol = EEPROM.read(2211);
presetApplyFx = EEPROM.read(2212);
}
bootPreset = EEPROM.read(389); bootPreset = EEPROM.read(389);
wifiLock = EEPROM.read(393); wifiLock = EEPROM.read(393);

View File

@ -167,6 +167,7 @@ String getSettings(byte subPage)
resp += ds + "RV" + c + reverseMode +";"; resp += ds + "RV" + c + reverseMode +";";
resp += ds + "EI" + c + initLedsLast +";"; resp += ds + "EI" + c + initLedsLast +";";
resp += ds + "WO" + v + arlsOffset +";"; resp += ds + "WO" + v + arlsOffset +";";
resp += ds + "SL" + c + skipFirstLed +";";
} }
if (subPage == 3) if (subPage == 3)

View File

@ -121,6 +121,7 @@ void handleSettingsSet(byte subPage)
if (ledCount > 600) ledCount = 600; if (ledCount > 600) ledCount = 600;
#endif #endif
} }
ccIndex2 = ledCount -1;
useRGBW = server.hasArg("EW"); useRGBW = server.hasArg("EW");
autoRGBtoRGBW = server.hasArg("AW"); autoRGBtoRGBW = server.hasArg("AW");
if (server.hasArg("IS")) //ignore settings and save current brightness, colors and fx as default if (server.hasArg("IS")) //ignore settings and save current brightness, colors and fx as default
@ -194,6 +195,7 @@ void handleSettingsSet(byte subPage)
if (i >= 0 && i <= 255) effectIntensityDefault = i; if (i >= 0 && i <= 255) effectIntensityDefault = i;
} }
} }
saveCurrPresetCycConf = server.hasArg("PC");
turnOnAtBoot = server.hasArg("BO"); turnOnAtBoot = server.hasArg("BO");
if (server.hasArg("BP")) if (server.hasArg("BP"))
{ {
@ -231,6 +233,7 @@ void handleSettingsSet(byte subPage)
int i = server.arg("WO").toInt(); int i = server.arg("WO").toInt();
if (i >= -255 && i <= 255) arlsOffset = i; if (i >= -255 && i <= 255) arlsOffset = i;
} }
skipFirstLed = server.hasArg("SL");
if (server.hasArg("BF")) if (server.hasArg("BF"))
{ {
int i = server.arg("BF").toInt(); int i = server.arg("BF").toInt();
@ -386,7 +389,7 @@ void handleSettingsSet(byte subPage)
} }
} }
saveSettingsToEEPROM(); saveSettingsToEEPROM();
if (subPage == 2) strip.init(useRGBW,ledCount,PIN); if (subPage == 2) strip.init(useRGBW,ledCount,PIN,skipFirstLed);
} }
bool handleSet(String req) bool handleSet(String req)

View File

@ -10,7 +10,7 @@ void wledInit()
#ifdef ARDUINO_ARCH_ESP32 #ifdef ARDUINO_ARCH_ESP32
if (ledCount > 600) ledCount = 600; if (ledCount > 600) ledCount = 600;
#endif #endif
if (!EEPROM.read(397)) strip.init(EEPROM.read(372),ledCount,PIN); //quick init if (!EEPROM.read(397)) strip.init(EEPROM.read(372),ledCount,PIN,EEPROM.read(2204)); //quick init
Serial.begin(115200); Serial.begin(115200);
Serial.setTimeout(50); Serial.setTimeout(50);
@ -164,10 +164,6 @@ void wledInit()
server.on("/freeheap", HTTP_GET, [](){ server.on("/freeheap", HTTP_GET, [](){
server.send(200, "text/plain", (String)ESP.getFreeHeap()); server.send(200, "text/plain", (String)ESP.getFreeHeap());
}); });
server.on("/pdebug", HTTP_GET, [](){
server.send(200, "text/plain", (String)presetCycleTime);
});
server.on("/power", HTTP_GET, [](){ server.on("/power", HTTP_GET, [](){
String val = (String)(int)strip.getPowerEstimate(ledCount,strip.getColor(),strip.getBrightness()); String val = (String)(int)strip.getPowerEstimate(ledCount,strip.getColor(),strip.getBrightness());
@ -199,8 +195,6 @@ void wledInit()
server.on("/edit", HTTP_POST, [](){ server.send(200, "text/plain", ""); }, handleFileUpload); server.on("/edit", HTTP_POST, [](){ server.send(200, "text/plain", ""); }, handleFileUpload);
server.on("/list", HTTP_GET, handleFileList); server.on("/list", HTTP_GET, handleFileList);
#endif #endif
server.on("/down", HTTP_GET, down);
server.on("/cleareeprom", HTTP_GET, clearEEPROM);
//init ota page //init ota page
httpUpdater.setup(&server); httpUpdater.setup(&server);
} else } else
@ -208,12 +202,6 @@ void wledInit()
server.on("/edit", HTTP_GET, [](){ server.on("/edit", HTTP_GET, [](){
serveMessage(500, "Access Denied", txd, 254); serveMessage(500, "Access Denied", txd, 254);
}); });
server.on("/down", HTTP_GET, [](){
serveMessage(500, "Access Denied", txd, 254);
});
server.on("/cleareeprom", HTTP_GET, [](){
serveMessage(500, "Access Denied", txd, 254);
});
server.on("/update", HTTP_GET, [](){ server.on("/update", HTTP_GET, [](){
serveMessage(500, "Access Denied", txd, 254); serveMessage(500, "Access Denied", txd, 254);
}); });
@ -231,8 +219,14 @@ void wledInit()
server.send(404, "text/plain", "Not Found"); server.send(404, "text/plain", "Not Found");
} }
}); });
#ifndef ARDUINO_ARCH_ESP32
const char * headerkeys[] = {"User-Agent"}; const char * headerkeys[] = {"User-Agent"};
server.collectHeaders(headerkeys,sizeof(char*)); server.collectHeaders(headerkeys,sizeof(char*));
#else
String ua = "User-Agent";
server.collectHeaders(ua);
#endif
if (!initLedsLast) strip.service(); if (!initLedsLast) strip.service();
//init Alexa hue emulation //init Alexa hue emulation
@ -273,7 +267,7 @@ void wledInit()
void initStrip() void initStrip()
{ {
// Initialize NeoPixel Strip and button // Initialize NeoPixel Strip and button
if (initLedsLast) strip.init(useRGBW,ledCount,PIN); if (initLedsLast) strip.init(useRGBW,ledCount,PIN,skipFirstLed);
strip.setReverseMode(reverseMode); strip.setReverseMode(reverseMode);
strip.setColor(0); strip.setColor(0);
strip.setBrightness(255); strip.setBrightness(255);
@ -319,7 +313,13 @@ void initCon()
} }
int fail_count = 0; int fail_count = 0;
if (clientSSID.length() <1 || clientSSID.equals("Your_Network")) fail_count = apWaitTimeSecs*2; if (clientSSID.length() <1 || clientSSID.equals("Your_Network")) fail_count = apWaitTimeSecs*2;
#ifndef ARDUINO_ARCH_ESP32
WiFi.hostname(serverDescription);
#endif
WiFi.begin(clientSSID.c_str(), clientPass.c_str()); WiFi.begin(clientSSID.c_str(), clientPass.c_str());
#ifdef ARDUINO_ARCH_ESP32
WiFi.setHostname(serverDescription.c_str());
#endif
unsigned long lastTry = 0; unsigned long lastTry = 0;
bool con = false; bool con = false;
while(!con) while(!con)
@ -400,6 +400,21 @@ void serveIndexOrWelcome()
} }
} }
void serveRealtimeError(bool settings)
{
String mesg = "The ";
mesg += (settings)?"settings":"WLED";
mesg += " UI is not available while receiving real-time data (UDP from ";
mesg += realtimeIP[0];
for (int i = 1; i < 4; i++)
{
mesg += ".";
mesg += realtimeIP[i];
}
mesg += ").";
server.send(200, "text/plain", mesg);
}
void serveIndex() void serveIndex()
{ {
bool serveMobile = false; bool serveMobile = false;
@ -424,7 +439,7 @@ void serveIndex()
server.sendContent_P(PAGE_index3); server.sendContent_P(PAGE_index3);
} }
} else { } else {
server.send(200, "text/plain", "The WLED UI is not available while receiving real-time data."); serveRealtimeError(false);
} }
} }
@ -509,7 +524,7 @@ void serveSettings(byte subPage)
default: server.sendContent_P(PAGE_settings1); default: server.sendContent_P(PAGE_settings1);
} }
} else { } else {
server.send(200, "text/plain", "The settings are not available while receiving real-time data."); serveRealtimeError(true);
} }
} }
@ -540,7 +555,7 @@ String getBuildInfo()
#else #else
info += "strip-pin: gpio2\r\n"; info += "strip-pin: gpio2\r\n";
#endif #endif
info += "build-type: dev\r\n"; info += "build-type: src\r\n";
return info; return info;
} }

View File

@ -81,8 +81,10 @@ void handleNotifications()
uint16_t packetSize = notifierUdp.parsePacket(); uint16_t packetSize = notifierUdp.parsePacket();
//hyperion / raw RGB //hyperion / raw RGB
if (!packetSize && receiveDirect && udpRgbConnected) { if (!packetSize && udpRgbConnected) {
packetSize = rgbUdp.parsePacket(); packetSize = rgbUdp.parsePacket();
if (!receiveDirect) return;
realtimeIP = rgbUdp.remoteIP();
if (packetSize > 1026 || packetSize < 3) return; if (packetSize > 1026 || packetSize < 3) return;
byte udpIn[packetSize]; byte udpIn[packetSize];
rgbUdp.read(udpIn, packetSize); rgbUdp.read(udpIn, packetSize);
@ -153,6 +155,7 @@ void handleNotifications()
} }
} else if (udpIn[0] > 0 && udpIn[0] < 4 && receiveDirect) //1 warls //2 drgb //3 drgbw } else if (udpIn[0] > 0 && udpIn[0] < 4 && receiveDirect) //1 warls //2 drgb //3 drgbw
{ {
realtimeIP = notifierUdp.remoteIP();
if (packetSize > 1) { if (packetSize > 1) {
if (udpIn[1] == 0) if (udpIn[1] == 0)
{ {