mirror of
https://github.com/wled/WLED.git
synced 2025-07-18 16:26:32 +00:00
Reducing JSON buffer size requirements.
Increasing maximum number of segments.
This commit is contained in:
parent
0b75a7d0d3
commit
77d8a8e43d
@ -56,14 +56,14 @@
|
|||||||
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
|
/* each segment uses 52 bytes of SRAM memory, so if you're application fails because of
|
||||||
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
insufficient memory, decreasing MAX_NUM_SEGMENTS may help */
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#define MAX_NUM_SEGMENTS 13
|
#define MAX_NUM_SEGMENTS 18
|
||||||
/* How many color transitions can run at once */
|
/* How many color transitions can run at once */
|
||||||
#define MAX_NUM_TRANSITIONS 8
|
#define MAX_NUM_TRANSITIONS 8
|
||||||
/* How much data bytes all segments combined may allocate */
|
/* How much data bytes all segments combined may allocate */
|
||||||
#define MAX_SEGMENT_DATA 3072
|
#define MAX_SEGMENT_DATA 4096
|
||||||
#else
|
#else
|
||||||
#define MAX_NUM_SEGMENTS 18
|
#define MAX_NUM_SEGMENTS 24
|
||||||
#define MAX_NUM_TRANSITIONS 18
|
#define MAX_NUM_TRANSITIONS 24
|
||||||
#define MAX_SEGMENT_DATA 20480
|
#define MAX_SEGMENT_DATA 20480
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@
|
|||||||
|
|
||||||
// Size of buffer for API JSON object (increase for more segments)
|
// Size of buffer for API JSON object (increase for more segments)
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
#define JSON_BUFFER_SIZE 9120
|
#define JSON_BUFFER_SIZE 8192
|
||||||
#else
|
#else
|
||||||
#define JSON_BUFFER_SIZE 16384
|
#define JSON_BUFFER_SIZE 16384
|
||||||
#endif
|
#endif
|
||||||
|
@ -210,7 +210,7 @@
|
|||||||
<img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAggAAACMCAYAAAAZQlGEAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKLSURBVHhe7dgxjtwwEADBpf//5zUDwklnpzFAnKoSTigNFTT0AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDcOieX+G5nvNLaznil6f1Nv+/tz3c7+3tmen/Tpu/jbe877c85AQD+EQgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAQiAAACEQAIAQCABACAQAINY5+aHvdsYRazvjK9jfM7fvz/0+Y3+/2+336w8CABACAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAADEOudrfLczXmltZ3yF6fuwv2em9+d+n5ne3zT3cZfp+/AHAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAYp3zNb7bGUes7Yz8wO334fmeuf35bmd/z9y+v9ufzx8EACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAQiAAACEQAIAQCABACAQAIAQCABACAQCIdc4x3+2MV1rbGfmFpr+/6e/l9ue73fT+pt1+H2/bn+/lGX8QAIAQCABACAQAIAQCABACAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP/u8/kLYCqAxINTyZkAAAAASUVORK5CYII=">
|
<img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAggAAACMCAYAAAAZQlGEAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAKLSURBVHhe7dgxjtwwEADBpf//5zUDwklnpzFAnKoSTigNFTT0AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGDcOieX+G5nvNLaznil6f1Nv+/tz3c7+3tmen/Tpu/jbe877c85AQD+EQgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAQiAAACEQAIAQCABACAQAINY5+aHvdsYRazvjK9jfM7fvz/0+Y3+/2+336w8CABACAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAADEOudrfLczXmltZ3yF6fuwv2em9+d+n5ne3zT3cZfp+/AHAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAYp3zNb7bGUes7Yz8wO334fmeuf35bmd/z9y+v9ufzx8EACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAgBAIAEAIBAAiBAACEQAAAQiAAACEQAIAQCABACAQAIAQCABACAQCIdc4x3+2MV1rbGfmFpr+/6e/l9ue73fT+pt1+H2/bn+/lGX8QAIAQCABACAQAIAQCABACAQAIgQAAhEAAAEIgAAAhEACAEAgAQAgEACAEAgAQAgEACIEAAIRAAABCIAAAIRAAgBAIAEAIBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgP/u8/kLYCqAxINTyZkAAAAASUVORK5CYII=">
|
||||||
</div><br>
|
</div><br>
|
||||||
<div id="kv">Loading...</div><br>
|
<div id="kv">Loading...</div><br>
|
||||||
<button class="btn infobtn" onclick="requestJson(null)">Refresh</button>
|
<button class="btn infobtn" onclick="loadInfo()">Refresh</button>
|
||||||
<button class="btn infobtn" onclick="toggleInfo()">Close Info</button><br>
|
<button class="btn infobtn" onclick="toggleInfo()">Close Info</button><br>
|
||||||
<button class="btn infobtn" onclick="toggleNodes()">Instance List</button>
|
<button class="btn infobtn" onclick="toggleNodes()">Instance List</button>
|
||||||
<button class="btn infobtn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button><br>
|
<button class="btn infobtn" id="resetbtn" onclick="cnfReset()">Reboot WLED</button><br>
|
||||||
|
@ -26,6 +26,7 @@ var cfg = {
|
|||||||
theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}},
|
theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}},
|
||||||
comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, labels:true, pcmbot:false, pid:true}
|
comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, labels:true, pcmbot:false, pid:true}
|
||||||
};
|
};
|
||||||
|
var myWS, noWS = false;
|
||||||
|
|
||||||
var cpick = new iro.ColorPicker("#picker", {
|
var cpick = new iro.ColorPicker("#picker", {
|
||||||
width: 260,
|
width: 260,
|
||||||
@ -51,7 +52,7 @@ var cpick = new iro.ColorPicker("#picker", {
|
|||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
function handleVisibilityChange() {if (!d.hidden && new Date () - lastUpdate > 3000) requestJson(null);}
|
function handleVisibilityChange() {if (!d.hidden && new Date () - lastUpdate > 3000) requestJson({'v':true,'rev':2},false);}
|
||||||
function sCol(na, col) {d.documentElement.style.setProperty(na, col);}
|
function sCol(na, col) {d.documentElement.style.setProperty(na, col);}
|
||||||
|
|
||||||
function applyCfg()
|
function applyCfg()
|
||||||
@ -191,8 +192,10 @@ function onLoad()
|
|||||||
loadPalettes(function() {
|
loadPalettes(function() {
|
||||||
loadFX(function() {
|
loadFX(function() {
|
||||||
loadPresets(function() {
|
loadPresets(function() {
|
||||||
requestJson(null, false, true, function() {
|
loadInfo(function() {
|
||||||
loadPalettesData();
|
requestJson({'v':true,'rev':2}, false, true, function() {
|
||||||
|
loadPalettesData();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -209,11 +212,13 @@ function onLoad()
|
|||||||
sl.addEventListener('touchend', toggleBubble);
|
sl.addEventListener('touchend', toggleBubble);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creatte UI update WS handler
|
// Create UI update WS handler
|
||||||
var mySocket = new WebSocket('ws://'+(loc?locip:window.location.hostname)+'/ws');
|
myWS = new WebSocket('ws://'+(loc?locip:window.location.hostname)+'/ws');
|
||||||
mySocket.onmessage = function(event) {
|
myWS.onopen = function () {
|
||||||
|
myWS.send("{'v':true,'rev':2}");
|
||||||
|
}
|
||||||
|
myWS.onmessage = function(event) {
|
||||||
var json = JSON.parse(event.data);
|
var json = JSON.parse(event.data);
|
||||||
//console.log(json);
|
|
||||||
if (handleJson(json.state)) updateUI(true);
|
if (handleJson(json.state)) updateUI(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -493,6 +498,40 @@ function populatePresets(fromls)
|
|||||||
populateQL();
|
populateQL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadInfo(callback=null)
|
||||||
|
{
|
||||||
|
var url = (loc?`http://${locip}`:'') + '/json/info';
|
||||||
|
fetch(url, {
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) showToast('Could not load Info!', true);
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(json => {
|
||||||
|
lastinfo = json;
|
||||||
|
var name = json.name;
|
||||||
|
d.getElementById('namelabel').innerHTML = name;
|
||||||
|
if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)";
|
||||||
|
if (json.live) name = "(Live) " + name;
|
||||||
|
if (loc) name = "(L) " + name;
|
||||||
|
d.title = name;
|
||||||
|
isRgbw = json.leds.wv;
|
||||||
|
ledCount = json.leds.count;
|
||||||
|
syncTglRecv = json.str;
|
||||||
|
maxSeg = json.leds.maxseg;
|
||||||
|
pmt = json.fs.pmt;
|
||||||
|
// d.getElementById('buttonNodes').style.display = (json.ndc > 0 && window.innerWidth > 770) ? "block":"none";
|
||||||
|
populateInfo(json);
|
||||||
|
if (callback) callback();
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
showToast(error, true);
|
||||||
|
console.log(error);
|
||||||
|
if (callback) callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function populateInfo(i)
|
function populateInfo(i)
|
||||||
{
|
{
|
||||||
var cn="";
|
var cn="";
|
||||||
@ -780,10 +819,16 @@ function genPalPrevCss(id)
|
|||||||
b = Math.random() * 255;
|
b = Math.random() * 255;
|
||||||
} else {
|
} else {
|
||||||
if (selColors) {
|
if (selColors) {
|
||||||
let pos = element[1] - 1;
|
let e = element[1] - 1;
|
||||||
r = selColors[pos][0];
|
if (Array.isArray(selColors[e])) {
|
||||||
g = selColors[pos][1];
|
r = selColors[e][0];
|
||||||
b = selColors[pos][2];
|
g = selColors[e][1];
|
||||||
|
b = selColors[e][2];
|
||||||
|
} else {
|
||||||
|
r = (selColors[e]>>16) & 0xFF;
|
||||||
|
g = (selColors[e]>> 8) & 0xFF;
|
||||||
|
b = (selColors[e] ) & 0xFF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index === false) {
|
if (index === false) {
|
||||||
@ -892,9 +937,12 @@ function updatePA(scrollto=false)
|
|||||||
|
|
||||||
function updateUI(scrollto=false)
|
function updateUI(scrollto=false)
|
||||||
{
|
{
|
||||||
|
noWS = (myWS.readyState === WebSocket.CLOSED);
|
||||||
|
|
||||||
d.getElementById('buttonPower').className = (isOn) ? "active":"";
|
d.getElementById('buttonPower').className = (isOn) ? "active":"";
|
||||||
d.getElementById('buttonNl').className = (nlA) ? "active":"";
|
d.getElementById('buttonNl').className = (nlA) ? "active":"";
|
||||||
d.getElementById('buttonSync').className = (syncSend) ? "active":"";
|
d.getElementById('buttonSync').className = (syncSend) ? "active":"";
|
||||||
|
d.getElementById('buttonNodes').style.display = (lastinfo.ndc > 0 && window.innerWidth > 770) ? "block":"none";
|
||||||
|
|
||||||
updateSelectedPalette(scrollto);
|
updateSelectedPalette(scrollto);
|
||||||
updateSelectedFx(scrollto);
|
updateSelectedFx(scrollto);
|
||||||
@ -944,13 +992,14 @@ function updateSelectedFx(scrollto=false)
|
|||||||
|
|
||||||
var selectedEffect = parent.querySelector(`.lstI[data-id="${selectedFx}"]`);
|
var selectedEffect = parent.querySelector(`.lstI[data-id="${selectedFx}"]`);
|
||||||
if (selectedEffect) selectedEffect.classList.add('selected');
|
if (selectedEffect) selectedEffect.classList.add('selected');
|
||||||
|
/*
|
||||||
if (scrollto && selectedEffect) {
|
if (scrollto && selectedEffect) {
|
||||||
selectedEffect.scrollIntoView({
|
selectedEffect.scrollIntoView({
|
||||||
behavior: 'smooth',
|
behavior: 'smooth',
|
||||||
block: 'center',
|
block: 'center',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayRover(i,s)
|
function displayRover(i,s)
|
||||||
@ -998,8 +1047,20 @@ function handleJson(s)
|
|||||||
var cd = d.getElementById('csl').children;
|
var cd = d.getElementById('csl').children;
|
||||||
for (let e = cd.length-1; e >= 0; e--)
|
for (let e = cd.length-1; e >= 0; e--)
|
||||||
{
|
{
|
||||||
cd[e].style.backgroundColor = "rgb(" + i.col[e][0] + "," + i.col[e][1] + "," + i.col[e][2] + ")";
|
var r,g,b,w;
|
||||||
if (isRgbw) whites[e] = parseInt(i.col[e][3]);
|
if (Array.isArray(i.col[e])) {
|
||||||
|
r = i.col[e][0];
|
||||||
|
g = i.col[e][1];
|
||||||
|
b = i.col[e][2];
|
||||||
|
if (isRgbw) w = i.col[e][3];
|
||||||
|
} else {
|
||||||
|
r = (i.col[e]>>16) & 0xFF;
|
||||||
|
g = (i.col[e]>> 8) & 0xFF;
|
||||||
|
b = (i.col[e] ) & 0xFF;
|
||||||
|
if (isRgbw) w = (i.col[e] >> 24) & 0xFF;
|
||||||
|
}
|
||||||
|
cd[e].style.backgroundColor = "rgb(" + r + "," + g + "," + b + ")";
|
||||||
|
if (isRgbw) whites[e] = parseInt(w);
|
||||||
selectSlot(csel);
|
selectSlot(csel);
|
||||||
}
|
}
|
||||||
d.getElementById('sliderSpeed').value = whites[csel];
|
d.getElementById('sliderSpeed').value = whites[csel];
|
||||||
@ -1010,6 +1071,8 @@ function handleJson(s)
|
|||||||
selectedPal = i.pal;
|
selectedPal = i.pal;
|
||||||
selectedFx = i.fx;
|
selectedFx = i.fx;
|
||||||
|
|
||||||
|
displayRover(lastinfo, s);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1029,6 +1092,7 @@ function requestJson(command, rinfo = true, verbose = true, callback = null)
|
|||||||
if (command)
|
if (command)
|
||||||
{
|
{
|
||||||
command.v = verbose;
|
command.v = verbose;
|
||||||
|
command.rev = 2;
|
||||||
command.time = Math.floor(Date.now() / 1000);
|
command.time = Math.floor(Date.now() / 1000);
|
||||||
req = JSON.stringify(command);
|
req = JSON.stringify(command);
|
||||||
}
|
}
|
||||||
@ -1061,8 +1125,8 @@ function requestJson(command, rinfo = true, verbose = true, callback = null)
|
|||||||
populatePresets(true);
|
populatePresets(true);
|
||||||
pmtLast = pmt;
|
pmtLast = pmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
var info = json.info;
|
var info = json.info;
|
||||||
|
/*
|
||||||
var name = info.name;
|
var name = info.name;
|
||||||
d.getElementById('namelabel').innerHTML = name;
|
d.getElementById('namelabel').innerHTML = name;
|
||||||
if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)";
|
if (name === "Dinnerbone") d.documentElement.style.transform = "rotate(180deg)";
|
||||||
@ -1074,10 +1138,10 @@ function requestJson(command, rinfo = true, verbose = true, callback = null)
|
|||||||
ledCount = info.leds.count;
|
ledCount = info.leds.count;
|
||||||
syncTglRecv = info.str;
|
syncTglRecv = info.str;
|
||||||
maxSeg = info.leds.maxseg;
|
maxSeg = info.leds.maxseg;
|
||||||
|
*/
|
||||||
pmt = info.fs.pmt;
|
pmt = info.fs.pmt;
|
||||||
if (!command && pmt != pmtLast) setTimeout(loadPresets,99);
|
if (!command && pmt != pmtLast) setTimeout(loadPresets,99);
|
||||||
pmtLast = pmt;
|
pmtLast = pmt;
|
||||||
d.getElementById('buttonNodes').style.display = (info.ndc > 0 && window.innerWidth > 770) ? "block":"none";
|
|
||||||
lastinfo = info;
|
lastinfo = info;
|
||||||
if (isInfo) populateInfo(info);
|
if (isInfo) populateInfo(info);
|
||||||
displayRover(info, s);
|
displayRover(info, s);
|
||||||
@ -1117,7 +1181,7 @@ function togglePower()
|
|||||||
isOn = !isOn;
|
isOn = !isOn;
|
||||||
var obj = {"on": isOn};
|
var obj = {"on": isOn};
|
||||||
obj.transition = parseInt(d.getElementById('cyctt').value*10);
|
obj.transition = parseInt(d.getElementById('cyctt').value*10);
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleNl()
|
function toggleNl()
|
||||||
@ -1126,7 +1190,7 @@ function toggleNl()
|
|||||||
if (nlA) showToast(`Timer active. Your light will turn ${nlTar > 0 ? "on":"off"} ${nlFade ? "over":"after"} ${nlDur} minutes.`);
|
if (nlA) showToast(`Timer active. Your light will turn ${nlTar > 0 ? "on":"off"} ${nlFade ? "over":"after"} ${nlDur} minutes.`);
|
||||||
else showToast('Timer deactivated.');
|
else showToast('Timer deactivated.');
|
||||||
var obj = {"nl": {"on": nlA}};
|
var obj = {"nl": {"on": nlA}};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleSync()
|
function toggleSync()
|
||||||
@ -1136,7 +1200,7 @@ function toggleSync()
|
|||||||
else showToast('This light and other lights in the network will no longer sync.');
|
else showToast('This light and other lights in the network will no longer sync.');
|
||||||
var obj = {"udpn": {"send": syncSend}};
|
var obj = {"udpn": {"send": syncSend}};
|
||||||
if (syncTglRecv) obj.udpn.recv = syncSend;
|
if (syncTglRecv) obj.udpn.recv = syncSend;
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleLiveview()
|
function toggleLiveview()
|
||||||
@ -1153,7 +1217,7 @@ function toggleInfo()
|
|||||||
{
|
{
|
||||||
if (isNodes) toggleNodes();
|
if (isNodes) toggleNodes();
|
||||||
isInfo = !isInfo;
|
isInfo = !isInfo;
|
||||||
if (isInfo) populateInfo(lastinfo);
|
if (isInfo) loadInfo();
|
||||||
d.getElementById('info').style.transform = (isInfo) ? "translateY(0px)":"translateY(100%)";
|
d.getElementById('info').style.transform = (isInfo) ? "translateY(0px)":"translateY(100%)";
|
||||||
d.getElementById('buttonI').className = (isInfo) ? "active":"";
|
d.getElementById('buttonI').className = (isInfo) ? "active":"";
|
||||||
}
|
}
|
||||||
@ -1266,14 +1330,14 @@ function selSegEx(s)
|
|||||||
{
|
{
|
||||||
var obj = {"seg":[]};
|
var obj = {"seg":[]};
|
||||||
for (let i=0; i<=lSeg; i++) obj.seg.push({"sel":(i==s)?true:false});
|
for (let i=0; i<=lSeg; i++) obj.seg.push({"sel":(i==s)?true:false});
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function selSeg(s)
|
function selSeg(s)
|
||||||
{
|
{
|
||||||
var sel = d.getElementById(`seg${s}sel`).checked;
|
var sel = d.getElementById(`seg${s}sel`).checked;
|
||||||
var obj = {"seg": {"id": s, "sel": sel}};
|
var obj = {"seg": {"id": s, "sel": sel}};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSeg(s)
|
function setSeg(s)
|
||||||
@ -1289,7 +1353,7 @@ function setSeg(s)
|
|||||||
obj.seg.grp = grp;
|
obj.seg.grp = grp;
|
||||||
obj.seg.spc = spc;
|
obj.seg.spc = spc;
|
||||||
}
|
}
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function delSeg(s)
|
function delSeg(s)
|
||||||
@ -1301,33 +1365,33 @@ function delSeg(s)
|
|||||||
expanded[s] = false;
|
expanded[s] = false;
|
||||||
segCount--;
|
segCount--;
|
||||||
var obj = {"seg": {"id": s, "stop": 0}};
|
var obj = {"seg": {"id": s, "stop": 0}};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setRev(s)
|
function setRev(s)
|
||||||
{
|
{
|
||||||
var rev = d.getElementById(`seg${s}rev`).checked;
|
var rev = d.getElementById(`seg${s}rev`).checked;
|
||||||
var obj = {"seg": {"id": s, "rev": rev}};
|
var obj = {"seg": {"id": s, "rev": rev}};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setMi(s)
|
function setMi(s)
|
||||||
{
|
{
|
||||||
var mi = d.getElementById(`seg${s}mi`).checked;
|
var mi = d.getElementById(`seg${s}mi`).checked;
|
||||||
var obj = {"seg": {"id": s, "mi": mi}};
|
var obj = {"seg": {"id": s, "mi": mi}};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSegPwr(s)
|
function setSegPwr(s)
|
||||||
{
|
{
|
||||||
var obj = {"seg": {"id": s, "on": !powered[s]}};
|
var obj = {"seg": {"id": s, "on": !powered[s]}};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSegBri(s)
|
function setSegBri(s)
|
||||||
{
|
{
|
||||||
var obj = {"seg": {"id": s, "bri": parseInt(d.getElementById(`seg${s}bri`).value)}};
|
var obj = {"seg": {"id": s, "bri": parseInt(d.getElementById(`seg${s}bri`).value)}};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setX(ind = null)
|
function setX(ind = null)
|
||||||
@ -1343,7 +1407,7 @@ function setX(ind = null)
|
|||||||
d.querySelector(`#fxlist .lstI[data-id="${ind}"]`).classList.add('selected');
|
d.querySelector(`#fxlist .lstI[data-id="${ind}"]`).classList.add('selected');
|
||||||
|
|
||||||
var obj = {"seg": {"fx": parseInt(ind)}};
|
var obj = {"seg": {"fx": parseInt(ind)}};
|
||||||
requestJson(obj);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPalette(paletteId = null)
|
function setPalette(paletteId = null)
|
||||||
@ -1358,32 +1422,32 @@ function setPalette(paletteId = null)
|
|||||||
|
|
||||||
d.querySelector(`#selectPalette .lstI[data-id="${paletteId}"]`).classList.add('selected');
|
d.querySelector(`#selectPalette .lstI[data-id="${paletteId}"]`).classList.add('selected');
|
||||||
var obj = {"seg": {"pal": paletteId}};
|
var obj = {"seg": {"pal": paletteId}};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setBri()
|
function setBri()
|
||||||
{
|
{
|
||||||
var obj = {"bri": parseInt(d.getElementById('sliderBri').value)};
|
var obj = {"bri": parseInt(d.getElementById('sliderBri').value)};
|
||||||
obj.transition = parseInt(d.getElementById('cyctt').value*10);
|
obj.transition = parseInt(d.getElementById('cyctt').value*10);
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSpeed()
|
function setSpeed()
|
||||||
{
|
{
|
||||||
var obj = {"seg": {"sx": parseInt(d.getElementById('sliderSpeed').value)}};
|
var obj = {"seg": {"sx": parseInt(d.getElementById('sliderSpeed').value)}};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setIntensity()
|
function setIntensity()
|
||||||
{
|
{
|
||||||
var obj = {"seg": {"ix": parseInt(d.getElementById('sliderIntensity').value)}};
|
var obj = {"seg": {"ix": parseInt(d.getElementById('sliderIntensity').value)}};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLor(i)
|
function setLor(i)
|
||||||
{
|
{
|
||||||
var obj = {"lor": i};
|
var obj = {"lor": i};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleCY()
|
function toggleCY()
|
||||||
@ -1395,14 +1459,14 @@ function toggleCY()
|
|||||||
obj.transition = parseInt(d.getElementById('cyctt').value*10);
|
obj.transition = parseInt(d.getElementById('cyctt').value*10);
|
||||||
}
|
}
|
||||||
|
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPreset(i)
|
function setPreset(i)
|
||||||
{
|
{
|
||||||
var obj = {"ps": i};
|
var obj = {"ps": i};
|
||||||
showToast("Loading preset " + pName(i) +" (" + i + ")");
|
showToast("Loading preset " + pName(i) +" (" + i + ")");
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveP(i)
|
function saveP(i)
|
||||||
@ -1439,7 +1503,7 @@ function saveP(i)
|
|||||||
if (pQN.length > 0) obj.ql = pQN;
|
if (pQN.length > 0) obj.ql = pQN;
|
||||||
|
|
||||||
showToast("Saving " + pN +" (" + pI + ")");
|
showToast("Saving " + pN +" (" + pI + ")");
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
if (obj.o) {
|
if (obj.o) {
|
||||||
pJson[pI] = obj;
|
pJson[pI] = obj;
|
||||||
delete pJson[pI].psave;
|
delete pJson[pI].psave;
|
||||||
@ -1458,7 +1522,7 @@ function saveP(i)
|
|||||||
function delP(i)
|
function delP(i)
|
||||||
{
|
{
|
||||||
var obj = {"pdel": i};
|
var obj = {"pdel": i};
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
delete pJson[i];
|
delete pJson[i];
|
||||||
populatePresets();
|
populatePresets();
|
||||||
}
|
}
|
||||||
@ -1563,7 +1627,7 @@ function setColor(sr)
|
|||||||
updateHex();
|
updateHex();
|
||||||
updateRgb();
|
updateRgb();
|
||||||
obj.transition = parseInt(d.getElementById('cyctt').value*10);
|
obj.transition = parseInt(d.getElementById('cyctt').value*10);
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
var hc = 0;
|
var hc = 0;
|
||||||
@ -1598,7 +1662,7 @@ function rSegs()
|
|||||||
bt.innerHTML = "Reset segments";
|
bt.innerHTML = "Reset segments";
|
||||||
var obj = {"seg":[{"start":0,"stop":ledCount,"sel":true}]};
|
var obj = {"seg":[{"start":0,"stop":ledCount,"sel":true}]};
|
||||||
for (let i=1; i<=lSeg; i++) obj.seg.push({"stop":0});
|
for (let i=1; i<=lSeg; i++) obj.seg.push({"stop":0});
|
||||||
requestJson(obj, false);
|
requestJson(obj, false, noWS);
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadPalettesData()
|
function loadPalettesData()
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
socket.onopen = function () {
|
socket.onopen = function () {
|
||||||
console.info("Live-Preview websocket is opened");
|
console.info("Live-Preview websocket is opened");
|
||||||
socket.send("{'lv':true}");
|
socket.send("{'lv':true,'rev':2}");
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.onclose = function () { console.info("Live-Preview websocket is closing"); }
|
socket.onclose = function () { console.info("Live-Preview websocket is closing"); }
|
||||||
|
@ -97,11 +97,11 @@ void handleIR();
|
|||||||
#include "FX.h"
|
#include "FX.h"
|
||||||
|
|
||||||
void deserializeSegment(JsonObject elem, byte it);
|
void deserializeSegment(JsonObject elem, byte it);
|
||||||
bool deserializeState(JsonObject root);
|
uint8_t deserializeState(JsonObject root);
|
||||||
void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset = false, bool segmentBounds = true);
|
void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset = false, bool segmentBounds = true, uint8_t versionAPI = 1);
|
||||||
void serializeState(JsonObject root, bool forPreset = false, bool includeBri = true, bool segmentBounds = true);
|
void serializeState(JsonObject root, bool forPreset = false, bool includeBri = true, bool segmentBounds = true);
|
||||||
void serializeInfo(JsonObject root);
|
void serializeInfo(JsonObject root);
|
||||||
void serveJson(AsyncWebServerRequest* request);
|
void serveJson(AsyncWebServerRequest* request, uint8_t versionAPI = 1);
|
||||||
bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0);
|
bool serveLiveLeds(AsyncWebServerRequest* request, uint32_t wsClient = 0);
|
||||||
|
|
||||||
//led.cpp
|
//led.cpp
|
||||||
|
@ -85,7 +85,7 @@ charset="utf-8"><meta name="theme-color" content="#222222"><title>
|
|||||||
WLED Live Preview</title><style>
|
WLED Live Preview</title><style>
|
||||||
body{margin:0}#canv{background:#000;filter:brightness(175%);width:100%;height:100%;position:absolute}
|
body{margin:0}#canv{background:#000;filter:brightness(175%);width:100%;height:100%;position:absolute}
|
||||||
</style></head><body><div id="canv"><script>
|
</style></head><body><div id="canv"><script>
|
||||||
console.info("Live-Preview websocket opening");var socket=new WebSocket("ws://"+document.location.host+"/ws");function updatePreview(e){var o="linear-gradient(90deg,",n=e.length;for(i=0;i<n;i++){var t=e[i];t.length>6&&(t=t.substring(2)),o+="#"+t,i<n-1&&(o+=",")}o+=")",document.getElementById("canv").style.background=o}socket.onopen=function(){console.info("Live-Preview websocket is opened"),socket.send("{'lv':true}")},socket.onclose=function(){console.info("Live-Preview websocket is closing")},socket.onerror=function(e){console.error("Live-Preview websocket error:",e)},socket.onmessage=function(e){try{var o=JSON.parse(e.data);o&&o.leds&&requestAnimationFrame((function(){updatePreview(o.leds)}))}catch(e){console.error("Live-Preview websocket error:",e)}}
|
console.info("Live-Preview websocket opening");var socket=new WebSocket("ws://"+document.location.host+"/ws");function updatePreview(e){var o="linear-gradient(90deg,",n=e.length;for(i=0;i<n;i++){var r=e[i];r.length>6&&(r=r.substring(2)),o+="#"+r,i<n-1&&(o+=",")}o+=")",document.getElementById("canv").style.background=o}socket.onopen=function(){console.info("Live-Preview websocket is opened"),socket.send("{'lv':true,'rev':2}")},socket.onclose=function(){console.info("Live-Preview websocket is closing")},socket.onerror=function(e){console.error("Live-Preview websocket error:",e)},socket.onmessage=function(e){try{var o=JSON.parse(e.data);o&&o.leds&&requestAnimationFrame((function(){updatePreview(o.leds)}))}catch(e){console.error("Live-Preview websocket error:",e)}}
|
||||||
</script></body></html>)=====";
|
</script></body></html>)=====";
|
||||||
|
|
||||||
|
|
||||||
|
2913
wled00/html_ui.h
2913
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
1636
wled00/json.cpp
1636
wled00/json.cpp
File diff suppressed because it is too large
Load Diff
@ -1,81 +1,81 @@
|
|||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Methods to handle saving and loading presets to/from the filesystem
|
* Methods to handle saving and loading presets to/from the filesystem
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool applyPreset(byte index)
|
bool applyPreset(byte index)
|
||||||
{
|
{
|
||||||
if (index == 0) return false;
|
if (index == 0) return false;
|
||||||
if (fileDoc) {
|
if (fileDoc) { // from POST "/json" handler (wled_server.cpp)
|
||||||
errorFlag = readObjectFromFileUsingId("/presets.json", index, fileDoc) ? ERR_NONE : ERR_FS_PLOAD;
|
errorFlag = readObjectFromFileUsingId("/presets.json", index, fileDoc) ? ERR_NONE : ERR_FS_PLOAD;
|
||||||
JsonObject fdo = fileDoc->as<JsonObject>();
|
JsonObject fdo = fileDoc->as<JsonObject>();
|
||||||
if (fdo["ps"] == index) fdo.remove("ps"); //remove load request for same presets to prevent recursive crash
|
if (fdo["ps"] == index) fdo.remove("ps"); //remove load request for same presets to prevent recursive crash
|
||||||
#ifdef WLED_DEBUG_FS
|
#ifdef WLED_DEBUG_FS
|
||||||
serializeJson(*fileDoc, Serial);
|
serializeJson(*fileDoc, Serial);
|
||||||
#endif
|
#endif
|
||||||
deserializeState(fdo);
|
deserializeState(fdo);
|
||||||
} else {
|
} else {
|
||||||
DEBUGFS_PRINTLN(F("Make read buf"));
|
DEBUGFS_PRINTLN(F("Make read buf"));
|
||||||
DynamicJsonDocument fDoc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument fDoc(JSON_BUFFER_SIZE);
|
||||||
errorFlag = readObjectFromFileUsingId("/presets.json", index, &fDoc) ? ERR_NONE : ERR_FS_PLOAD;
|
errorFlag = readObjectFromFileUsingId("/presets.json", index, &fDoc) ? ERR_NONE : ERR_FS_PLOAD;
|
||||||
JsonObject fdo = fDoc.as<JsonObject>();
|
JsonObject fdo = fDoc.as<JsonObject>();
|
||||||
if (fdo["ps"] == index) fdo.remove("ps");
|
if (fdo["ps"] == index) fdo.remove("ps");
|
||||||
#ifdef WLED_DEBUG_FS
|
#ifdef WLED_DEBUG_FS
|
||||||
serializeJson(fDoc, Serial);
|
serializeJson(fDoc, Serial);
|
||||||
#endif
|
#endif
|
||||||
deserializeState(fdo);
|
deserializeState(fdo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!errorFlag) {
|
if (!errorFlag) {
|
||||||
currentPreset = index;
|
currentPreset = index;
|
||||||
isPreset = true;
|
isPreset = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void savePreset(byte index, bool persist, const char* pname, JsonObject saveobj)
|
void savePreset(byte index, bool persist, const char* pname, JsonObject saveobj)
|
||||||
{
|
{
|
||||||
if (index == 0 || index > 250) return;
|
if (index == 0 || index > 250) return;
|
||||||
bool docAlloc = (fileDoc != nullptr);
|
bool docAlloc = (fileDoc != nullptr);
|
||||||
JsonObject sObj = saveobj;
|
JsonObject sObj = saveobj;
|
||||||
|
|
||||||
if (!docAlloc) {
|
if (!docAlloc) {
|
||||||
DEBUGFS_PRINTLN(F("Allocating saving buffer"));
|
DEBUGFS_PRINTLN(F("Allocating saving buffer"));
|
||||||
DynamicJsonDocument lDoc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument lDoc(JSON_BUFFER_SIZE);
|
||||||
sObj = lDoc.to<JsonObject>();
|
sObj = lDoc.to<JsonObject>();
|
||||||
if (pname) sObj["n"] = pname;
|
if (pname) sObj["n"] = pname;
|
||||||
DEBUGFS_PRINTLN(F("Save current state"));
|
DEBUGFS_PRINTLN(F("Save current state"));
|
||||||
serializeState(sObj, true);
|
serializeState(sObj, true);
|
||||||
currentPreset = index;
|
currentPreset = index;
|
||||||
|
|
||||||
writeObjectToFileUsingId("/presets.json", index, &lDoc);
|
writeObjectToFileUsingId("/presets.json", index, &lDoc);
|
||||||
} else { //from JSON API
|
} else { //from JSON API
|
||||||
DEBUGFS_PRINTLN(F("Reuse recv buffer"));
|
DEBUGFS_PRINTLN(F("Reuse recv buffer"));
|
||||||
sObj.remove(F("psave"));
|
sObj.remove(F("psave"));
|
||||||
sObj.remove(F("v"));
|
sObj.remove(F("v"));
|
||||||
|
|
||||||
if (!sObj["o"]) {
|
if (!sObj["o"]) {
|
||||||
DEBUGFS_PRINTLN(F("Save current state"));
|
DEBUGFS_PRINTLN(F("Save current state"));
|
||||||
serializeState(sObj, true, sObj["ib"], sObj["sb"]);
|
serializeState(sObj, true, sObj["ib"], sObj["sb"]);
|
||||||
currentPreset = index;
|
currentPreset = index;
|
||||||
}
|
}
|
||||||
sObj.remove("o");
|
sObj.remove("o");
|
||||||
sObj.remove("ib");
|
sObj.remove("ib");
|
||||||
sObj.remove("sb");
|
sObj.remove("sb");
|
||||||
sObj.remove(F("error"));
|
sObj.remove(F("error"));
|
||||||
sObj.remove(F("time"));
|
sObj.remove(F("time"));
|
||||||
|
|
||||||
writeObjectToFileUsingId("/presets.json", index, fileDoc);
|
writeObjectToFileUsingId("/presets.json", index, fileDoc);
|
||||||
}
|
}
|
||||||
presetsModifiedTime = now(); //unix time
|
presetsModifiedTime = now(); //unix time
|
||||||
updateFSInfo();
|
updateFSInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
void deletePreset(byte index) {
|
void deletePreset(byte index) {
|
||||||
StaticJsonDocument<24> empty;
|
StaticJsonDocument<24> empty;
|
||||||
writeObjectToFileUsingId("/presets.json", index, &empty);
|
writeObjectToFileUsingId("/presets.json", index, &empty);
|
||||||
presetsModifiedTime = now(); //unix time
|
presetsModifiedTime = now(); //unix time
|
||||||
updateFSInfo();
|
updateFSInfo();
|
||||||
}
|
}
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2103231
|
#define VERSION 2103250
|
||||||
|
|
||||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||||
//#define WLED_USE_MY_CONFIG
|
//#define WLED_USE_MY_CONFIG
|
||||||
|
@ -1,419 +1,419 @@
|
|||||||
#include "wled.h"
|
#include "wled.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Integrated HTTP web server page declarations
|
* Integrated HTTP web server page declarations
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//Is this an IP?
|
//Is this an IP?
|
||||||
bool isIp(String str) {
|
bool isIp(String str) {
|
||||||
for (size_t i = 0; i < str.length(); i++) {
|
for (size_t i = 0; i < str.length(); i++) {
|
||||||
int c = str.charAt(i);
|
int c = str.charAt(i);
|
||||||
if (c != '.' && (c < '0' || c > '9')) {
|
if (c != '.' && (c < '0' || c > '9')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool captivePortal(AsyncWebServerRequest *request)
|
bool captivePortal(AsyncWebServerRequest *request)
|
||||||
{
|
{
|
||||||
if (ON_STA_FILTER(request)) return false; //only serve captive in AP mode
|
if (ON_STA_FILTER(request)) return false; //only serve captive in AP mode
|
||||||
String hostH;
|
String hostH;
|
||||||
if (!request->hasHeader("Host")) return false;
|
if (!request->hasHeader("Host")) return false;
|
||||||
hostH = request->getHeader("Host")->value();
|
hostH = request->getHeader("Host")->value();
|
||||||
|
|
||||||
if (!isIp(hostH) && hostH.indexOf("wled.me") < 0 && hostH.indexOf(cmDNS) < 0) {
|
if (!isIp(hostH) && hostH.indexOf("wled.me") < 0 && hostH.indexOf(cmDNS) < 0) {
|
||||||
DEBUG_PRINTLN("Captive portal");
|
DEBUG_PRINTLN("Captive portal");
|
||||||
AsyncWebServerResponse *response = request->beginResponse(302);
|
AsyncWebServerResponse *response = request->beginResponse(302);
|
||||||
response->addHeader(F("Location"), F("http://4.3.2.1"));
|
response->addHeader(F("Location"), F("http://4.3.2.1"));
|
||||||
request->send(response);
|
request->send(response);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initServer()
|
void initServer()
|
||||||
{
|
{
|
||||||
//CORS compatiblity
|
//CORS compatiblity
|
||||||
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Origin"), "*");
|
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Origin"), "*");
|
||||||
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Methods"), "*");
|
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Methods"), "*");
|
||||||
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Headers"), "*");
|
DefaultHeaders::Instance().addHeader(F("Access-Control-Allow-Headers"), "*");
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||||
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send_P(200, "text/html", PAGE_liveviewws);
|
request->send_P(200, "text/html", PAGE_liveviewws);
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/liveview", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send_P(200, "text/html", PAGE_liveview);
|
request->send_P(200, "text/html", PAGE_liveview);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//settings page
|
//settings page
|
||||||
server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/settings", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveSettings(request);
|
serveSettings(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/favicon.ico", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
if(!handleFileRead(request, "/favicon.ico"))
|
if(!handleFileRead(request, "/favicon.ico"))
|
||||||
{
|
{
|
||||||
request->send_P(200, "image/x-icon", favicon, 156);
|
request->send_P(200, "image/x-icon", favicon, 156);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/sliders", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/sliders", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveIndex(request);
|
serveIndex(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/welcome", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/welcome", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveSettings(request);
|
serveSettings(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/reset", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/reset", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveMessage(request, 200,F("Rebooting now..."),F("Please wait ~10 seconds..."),129);
|
serveMessage(request, 200,F("Rebooting now..."),F("Please wait ~10 seconds..."),129);
|
||||||
doReboot = true;
|
doReboot = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/settings", HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on("/settings", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
serveSettings(request, true);
|
serveSettings(request, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/json", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/json", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveJson(request);
|
serveJson(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request) {
|
AsyncCallbackJsonWebHandler* handler = new AsyncCallbackJsonWebHandler("/json", [](AsyncWebServerRequest *request) {
|
||||||
bool verboseResponse = false;
|
uint8_t vAPI = 0;
|
||||||
{ //scope JsonDocument so it releases its buffer
|
{ //scope JsonDocument so it releases its buffer
|
||||||
DynamicJsonDocument jsonBuffer(JSON_BUFFER_SIZE);
|
DynamicJsonDocument jsonBuffer(JSON_BUFFER_SIZE);
|
||||||
DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject));
|
DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject));
|
||||||
JsonObject root = jsonBuffer.as<JsonObject>();
|
JsonObject root = jsonBuffer.as<JsonObject>();
|
||||||
if (error || root.isNull()) {
|
if (error || root.isNull()) {
|
||||||
request->send(400, "application/json", F("{\"error\":9}")); return;
|
request->send(400, "application/json", F("{\"error\":9}")); return;
|
||||||
}
|
}
|
||||||
fileDoc = &jsonBuffer;
|
fileDoc = &jsonBuffer; // used for applying presets (presets.cpp)
|
||||||
verboseResponse = deserializeState(root);
|
vAPI = deserializeState(root);
|
||||||
fileDoc = nullptr;
|
fileDoc = nullptr;
|
||||||
}
|
}
|
||||||
if (verboseResponse) { //if JSON contains "v"
|
if (vAPI>0) { //if JSON contains "v"
|
||||||
serveJson(request); return;
|
serveJson(request,vAPI); return;
|
||||||
}
|
}
|
||||||
request->send(200, "application/json", F("{\"success\":true}"));
|
request->send(200, "application/json", F("{\"success\":true}"));
|
||||||
});
|
});
|
||||||
server.addHandler(handler);
|
server.addHandler(handler);
|
||||||
|
|
||||||
server.on("/version", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/version", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send(200, "text/plain", (String)VERSION);
|
request->send(200, "text/plain", (String)VERSION);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/uptime", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/uptime", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send(200, "text/plain", (String)millis());
|
request->send(200, "text/plain", (String)millis());
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/freeheap", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/freeheap", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send(200, "text/plain", (String)ESP.getFreeHeap());
|
request->send(200, "text/plain", (String)ESP.getFreeHeap());
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/u", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/u", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send_P(200, "text/html", PAGE_usermod);
|
request->send_P(200, "text/html", PAGE_usermod);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/url", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/url", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
URL_response(request);
|
URL_response(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/teapot", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/teapot", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveMessage(request, 418, F("418. I'm a teapot."), F("(Tangible Embedded Advanced Project Of Twinkling)"), 254);
|
serveMessage(request, 418, F("418. I'm a teapot."), F("(Tangible Embedded Advanced Project Of Twinkling)"), 254);
|
||||||
});
|
});
|
||||||
|
|
||||||
//if OTA is allowed
|
//if OTA is allowed
|
||||||
if (!otaLock){
|
if (!otaLock){
|
||||||
#ifdef WLED_ENABLE_FS_EDITOR
|
#ifdef WLED_ENABLE_FS_EDITOR
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
server.addHandler(new SPIFFSEditor(WLED_FS));//http_username,http_password));
|
server.addHandler(new SPIFFSEditor(WLED_FS));//http_username,http_password));
|
||||||
#else
|
#else
|
||||||
server.addHandler(new SPIFFSEditor("","",WLED_FS));//http_username,http_password));
|
server.addHandler(new SPIFFSEditor("","",WLED_FS));//http_username,http_password));
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
server.on("/edit", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/edit", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveMessage(request, 501, "Not implemented", F("The FS editor is disabled in this build."), 254);
|
serveMessage(request, 501, "Not implemented", F("The FS editor is disabled in this build."), 254);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
//init ota page
|
//init ota page
|
||||||
#ifndef WLED_DISABLE_OTA
|
#ifndef WLED_DISABLE_OTA
|
||||||
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send_P(200, "text/html", PAGE_update);
|
request->send_P(200, "text/html", PAGE_update);
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){
|
server.on("/update", HTTP_POST, [](AsyncWebServerRequest *request){
|
||||||
if (Update.hasError())
|
if (Update.hasError())
|
||||||
{
|
{
|
||||||
serveMessage(request, 500, F("Failed updating firmware!"), F("Please check your file and retry!"), 254); return;
|
serveMessage(request, 500, F("Failed updating firmware!"), F("Please check your file and retry!"), 254); return;
|
||||||
}
|
}
|
||||||
serveMessage(request, 200, F("Successfully updated firmware!"), F("Please wait while the module reboots..."), 131);
|
serveMessage(request, 200, F("Successfully updated firmware!"), F("Please wait while the module reboots..."), 131);
|
||||||
doReboot = true;
|
doReboot = true;
|
||||||
},[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
|
},[](AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
|
||||||
if(!index){
|
if(!index){
|
||||||
DEBUG_PRINTLN(F("OTA Update Start"));
|
DEBUG_PRINTLN(F("OTA Update Start"));
|
||||||
#ifdef ESP8266
|
#ifdef ESP8266
|
||||||
Update.runAsync(true);
|
Update.runAsync(true);
|
||||||
#endif
|
#endif
|
||||||
Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000);
|
Update.begin((ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000);
|
||||||
}
|
}
|
||||||
if(!Update.hasError()) Update.write(data, len);
|
if(!Update.hasError()) Update.write(data, len);
|
||||||
if(final){
|
if(final){
|
||||||
if(Update.end(true)){
|
if(Update.end(true)){
|
||||||
DEBUG_PRINTLN(F("Update Success"));
|
DEBUG_PRINTLN(F("Update Success"));
|
||||||
} else {
|
} else {
|
||||||
DEBUG_PRINTLN(F("Update Failed"));
|
DEBUG_PRINTLN(F("Update Failed"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
#else
|
#else
|
||||||
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveMessage(request, 501, "Not implemented", F("OTA updates are disabled in this build."), 254);
|
serveMessage(request, 501, "Not implemented", F("OTA updates are disabled in this build."), 254);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
server.on("/edit", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/edit", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveMessage(request, 500, "Access Denied", F("Please unlock OTA in security settings!"), 254);
|
serveMessage(request, 500, "Access Denied", F("Please unlock OTA in security settings!"), 254);
|
||||||
});
|
});
|
||||||
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveMessage(request, 500, "Access Denied", F("Please unlock OTA in security settings!"), 254);
|
serveMessage(request, 500, "Access Denied", F("Please unlock OTA in security settings!"), 254);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_DMX
|
#ifdef WLED_ENABLE_DMX
|
||||||
server.on("/dmxmap", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/dmxmap", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
request->send_P(200, "text/html", PAGE_dmxmap , dmxProcessor);
|
request->send_P(200, "text/html", PAGE_dmxmap , dmxProcessor);
|
||||||
});
|
});
|
||||||
#else
|
#else
|
||||||
server.on("/dmxmap", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/dmxmap", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
serveMessage(request, 501, "Not implemented", F("DMX support is not enabled in this build."), 254);
|
serveMessage(request, 501, "Not implemented", F("DMX support is not enabled in this build."), 254);
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
|
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
|
||||||
if (captivePortal(request)) return;
|
if (captivePortal(request)) return;
|
||||||
serveIndexOrWelcome(request);
|
serveIndexOrWelcome(request);
|
||||||
});
|
});
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_WEBSOCKETS
|
#ifdef WLED_ENABLE_WEBSOCKETS
|
||||||
server.addHandler(&ws);
|
server.addHandler(&ws);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//called when the url is not defined here, ajax-in; get-settings
|
//called when the url is not defined here, ajax-in; get-settings
|
||||||
server.onNotFound([](AsyncWebServerRequest *request){
|
server.onNotFound([](AsyncWebServerRequest *request){
|
||||||
DEBUG_PRINTLN("Not-Found HTTP call:");
|
DEBUG_PRINTLN("Not-Found HTTP call:");
|
||||||
DEBUG_PRINTLN("URI: " + request->url());
|
DEBUG_PRINTLN("URI: " + request->url());
|
||||||
if (captivePortal(request)) return;
|
if (captivePortal(request)) return;
|
||||||
|
|
||||||
//make API CORS compatible
|
//make API CORS compatible
|
||||||
if (request->method() == HTTP_OPTIONS)
|
if (request->method() == HTTP_OPTIONS)
|
||||||
{
|
{
|
||||||
request->send(200); return;
|
request->send(200); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(handleSet(request, request->url())) return;
|
if(handleSet(request, request->url())) return;
|
||||||
#ifndef WLED_DISABLE_ALEXA
|
#ifndef WLED_DISABLE_ALEXA
|
||||||
if(espalexa.handleAlexaApiCall(request)) return;
|
if(espalexa.handleAlexaApiCall(request)) return;
|
||||||
#endif
|
#endif
|
||||||
if(handleFileRead(request, request->url())) return;
|
if(handleFileRead(request, request->url())) return;
|
||||||
request->send_P(404, "text/html", PAGE_404);
|
request->send_P(404, "text/html", PAGE_404);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void serveIndexOrWelcome(AsyncWebServerRequest *request)
|
void serveIndexOrWelcome(AsyncWebServerRequest *request)
|
||||||
{
|
{
|
||||||
if (!showWelcomePage){
|
if (!showWelcomePage){
|
||||||
serveIndex(request);
|
serveIndex(request);
|
||||||
} else {
|
} else {
|
||||||
serveSettings(request);
|
serveSettings(request);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request)
|
bool handleIfNoneMatchCacheHeader(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
AsyncWebHeader* header = request->getHeader("If-None-Match");
|
AsyncWebHeader* header = request->getHeader("If-None-Match");
|
||||||
if (header && header->value() == String(VERSION)) {
|
if (header && header->value() == String(VERSION)) {
|
||||||
request->send(304);
|
request->send(304);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setStaticContentCacheHeaders(AsyncWebServerResponse *response)
|
void setStaticContentCacheHeaders(AsyncWebServerResponse *response)
|
||||||
{
|
{
|
||||||
response->addHeader(F("Cache-Control"),"max-age=2592000");
|
response->addHeader(F("Cache-Control"),"max-age=2592000");
|
||||||
response->addHeader(F("ETag"), String(VERSION));
|
response->addHeader(F("ETag"), String(VERSION));
|
||||||
}
|
}
|
||||||
|
|
||||||
void serveIndex(AsyncWebServerRequest* request)
|
void serveIndex(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
if (handleFileRead(request, "/index.htm")) return;
|
if (handleFileRead(request, "/index.htm")) return;
|
||||||
|
|
||||||
if (handleIfNoneMatchCacheHeader(request)) return;
|
if (handleIfNoneMatchCacheHeader(request)) return;
|
||||||
|
|
||||||
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_index, PAGE_index_L);
|
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/html", PAGE_index, PAGE_index_L);
|
||||||
|
|
||||||
response->addHeader(F("Content-Encoding"),"gzip");
|
response->addHeader(F("Content-Encoding"),"gzip");
|
||||||
#ifndef WLED_DEBUG
|
#ifndef WLED_DEBUG
|
||||||
setStaticContentCacheHeaders(response);
|
setStaticContentCacheHeaders(response);
|
||||||
#endif
|
#endif
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String msgProcessor(const String& var)
|
String msgProcessor(const String& var)
|
||||||
{
|
{
|
||||||
if (var == "MSG") {
|
if (var == "MSG") {
|
||||||
String messageBody = messageHead;
|
String messageBody = messageHead;
|
||||||
messageBody += F("</h2>");
|
messageBody += F("</h2>");
|
||||||
messageBody += messageSub;
|
messageBody += messageSub;
|
||||||
uint32_t optt = optionType;
|
uint32_t optt = optionType;
|
||||||
|
|
||||||
if (optt < 60) //redirect to settings after optionType seconds
|
if (optt < 60) //redirect to settings after optionType seconds
|
||||||
{
|
{
|
||||||
messageBody += F("<script>setTimeout(RS,");
|
messageBody += F("<script>setTimeout(RS,");
|
||||||
messageBody +=String(optt*1000);
|
messageBody +=String(optt*1000);
|
||||||
messageBody += F(")</script>");
|
messageBody += F(")</script>");
|
||||||
} else if (optt < 120) //redirect back after optionType-60 seconds, unused
|
} else if (optt < 120) //redirect back after optionType-60 seconds, unused
|
||||||
{
|
{
|
||||||
//messageBody += "<script>setTimeout(B," + String((optt-60)*1000) + ")</script>";
|
//messageBody += "<script>setTimeout(B," + String((optt-60)*1000) + ")</script>";
|
||||||
} else if (optt < 180) //reload parent after optionType-120 seconds
|
} else if (optt < 180) //reload parent after optionType-120 seconds
|
||||||
{
|
{
|
||||||
messageBody += F("<script>setTimeout(RP,");
|
messageBody += F("<script>setTimeout(RP,");
|
||||||
messageBody += String((optt-120)*1000);
|
messageBody += String((optt-120)*1000);
|
||||||
messageBody += F(")</script>");
|
messageBody += F(")</script>");
|
||||||
} else if (optt == 253)
|
} else if (optt == 253)
|
||||||
{
|
{
|
||||||
messageBody += F("<br><br><form action=/settings><button class=\"bt\" type=submit>Back</button></form>"); //button to settings
|
messageBody += F("<br><br><form action=/settings><button class=\"bt\" type=submit>Back</button></form>"); //button to settings
|
||||||
} else if (optt == 254)
|
} else if (optt == 254)
|
||||||
{
|
{
|
||||||
messageBody += F("<br><br><button type=\"button\" class=\"bt\" onclick=\"B()\">Back</button>");
|
messageBody += F("<br><br><button type=\"button\" class=\"bt\" onclick=\"B()\">Back</button>");
|
||||||
}
|
}
|
||||||
return messageBody;
|
return messageBody;
|
||||||
}
|
}
|
||||||
return String();
|
return String();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl, byte optionT)
|
void serveMessage(AsyncWebServerRequest* request, uint16_t code, const String& headl, const String& subl, byte optionT)
|
||||||
{
|
{
|
||||||
messageHead = headl;
|
messageHead = headl;
|
||||||
messageSub = subl;
|
messageSub = subl;
|
||||||
optionType = optionT;
|
optionType = optionT;
|
||||||
|
|
||||||
request->send_P(code, "text/html", PAGE_msg, msgProcessor);
|
request->send_P(code, "text/html", PAGE_msg, msgProcessor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String settingsProcessor(const String& var)
|
String settingsProcessor(const String& var)
|
||||||
{
|
{
|
||||||
if (var == "CSS") {
|
if (var == "CSS") {
|
||||||
char buf[2048];
|
char buf[2048];
|
||||||
getSettingsJS(optionType, buf);
|
getSettingsJS(optionType, buf);
|
||||||
return String(buf);
|
return String(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WLED_ENABLE_DMX
|
#ifdef WLED_ENABLE_DMX
|
||||||
|
|
||||||
if (var == "DMXMENU") {
|
if (var == "DMXMENU") {
|
||||||
return String(F("<form action=/settings/dmx><button type=submit>DMX Output</button></form>"));
|
return String(F("<form action=/settings/dmx><button type=submit>DMX Output</button></form>"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
if (var == "SCSS") return String(FPSTR(PAGE_settingsCss));
|
if (var == "SCSS") return String(FPSTR(PAGE_settingsCss));
|
||||||
return String();
|
return String();
|
||||||
}
|
}
|
||||||
|
|
||||||
String dmxProcessor(const String& var)
|
String dmxProcessor(const String& var)
|
||||||
{
|
{
|
||||||
String mapJS;
|
String mapJS;
|
||||||
#ifdef WLED_ENABLE_DMX
|
#ifdef WLED_ENABLE_DMX
|
||||||
if (var == "DMXVARS") {
|
if (var == "DMXVARS") {
|
||||||
mapJS += "\nCN=" + String(DMXChannels) + ";\n";
|
mapJS += "\nCN=" + String(DMXChannels) + ";\n";
|
||||||
mapJS += "CS=" + String(DMXStart) + ";\n";
|
mapJS += "CS=" + String(DMXStart) + ";\n";
|
||||||
mapJS += "CG=" + String(DMXGap) + ";\n";
|
mapJS += "CG=" + String(DMXGap) + ";\n";
|
||||||
mapJS += "LC=" + String(ledCount) + ";\n";
|
mapJS += "LC=" + String(ledCount) + ";\n";
|
||||||
mapJS += "var CH=[";
|
mapJS += "var CH=[";
|
||||||
for (int i=0;i<15;i++) {
|
for (int i=0;i<15;i++) {
|
||||||
mapJS += String(DMXFixtureMap[i]) + ",";
|
mapJS += String(DMXFixtureMap[i]) + ",";
|
||||||
}
|
}
|
||||||
mapJS += "0];";
|
mapJS += "0];";
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return mapJS;
|
return mapJS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void serveSettings(AsyncWebServerRequest* request, bool post)
|
void serveSettings(AsyncWebServerRequest* request, bool post)
|
||||||
{
|
{
|
||||||
byte subPage = 0;
|
byte subPage = 0;
|
||||||
const String& url = request->url();
|
const String& url = request->url();
|
||||||
if (url.indexOf("sett") >= 0)
|
if (url.indexOf("sett") >= 0)
|
||||||
{
|
{
|
||||||
if (url.indexOf("wifi") > 0) subPage = 1;
|
if (url.indexOf("wifi") > 0) subPage = 1;
|
||||||
else if (url.indexOf("leds") > 0) subPage = 2;
|
else if (url.indexOf("leds") > 0) subPage = 2;
|
||||||
else if (url.indexOf("ui") > 0) subPage = 3;
|
else if (url.indexOf("ui") > 0) subPage = 3;
|
||||||
else if (url.indexOf("sync") > 0) subPage = 4;
|
else if (url.indexOf("sync") > 0) subPage = 4;
|
||||||
else if (url.indexOf("time") > 0) subPage = 5;
|
else if (url.indexOf("time") > 0) subPage = 5;
|
||||||
else if (url.indexOf("sec") > 0) subPage = 6;
|
else if (url.indexOf("sec") > 0) subPage = 6;
|
||||||
#ifdef WLED_ENABLE_DMX // include only if DMX is enabled
|
#ifdef WLED_ENABLE_DMX // include only if DMX is enabled
|
||||||
else if (url.indexOf("dmx") > 0) subPage = 7;
|
else if (url.indexOf("dmx") > 0) subPage = 7;
|
||||||
#endif
|
#endif
|
||||||
} else subPage = 255; //welcome page
|
} else subPage = 255; //welcome page
|
||||||
|
|
||||||
if (subPage == 1 && wifiLock && otaLock)
|
if (subPage == 1 && wifiLock && otaLock)
|
||||||
{
|
{
|
||||||
serveMessage(request, 500, "Access Denied", F("Please unlock OTA in security settings!"), 254); return;
|
serveMessage(request, 500, "Access Denied", F("Please unlock OTA in security settings!"), 254); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (post) { //settings/set POST request, saving
|
if (post) { //settings/set POST request, saving
|
||||||
if (subPage != 1 || !(wifiLock && otaLock)) handleSettingsSet(request, subPage);
|
if (subPage != 1 || !(wifiLock && otaLock)) handleSettingsSet(request, subPage);
|
||||||
|
|
||||||
char s[32];
|
char s[32];
|
||||||
char s2[45] = "";
|
char s2[45] = "";
|
||||||
|
|
||||||
switch (subPage) {
|
switch (subPage) {
|
||||||
case 1: strcpy_P(s, PSTR("WiFi")); strcpy_P(s2, PSTR("Please connect to the new IP (if changed)")); forceReconnect = true; break;
|
case 1: strcpy_P(s, PSTR("WiFi")); strcpy_P(s2, PSTR("Please connect to the new IP (if changed)")); forceReconnect = true; break;
|
||||||
case 2: strcpy_P(s, PSTR("LED")); break;
|
case 2: strcpy_P(s, PSTR("LED")); break;
|
||||||
case 3: strcpy_P(s, PSTR("UI")); break;
|
case 3: strcpy_P(s, PSTR("UI")); break;
|
||||||
case 4: strcpy_P(s, PSTR("Sync")); break;
|
case 4: strcpy_P(s, PSTR("Sync")); break;
|
||||||
case 5: strcpy_P(s, PSTR("Time")); break;
|
case 5: strcpy_P(s, PSTR("Time")); break;
|
||||||
case 6: strcpy_P(s, PSTR("Security")); strcpy_P(s2, PSTR("Rebooting, please wait ~10 seconds...")); break;
|
case 6: strcpy_P(s, PSTR("Security")); strcpy_P(s2, PSTR("Rebooting, please wait ~10 seconds...")); break;
|
||||||
case 7: strcpy_P(s, PSTR("DMX")); break;
|
case 7: strcpy_P(s, PSTR("DMX")); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcat_P(s, PSTR(" settings saved."));
|
strcat_P(s, PSTR(" settings saved."));
|
||||||
if (!s2[0]) strcpy_P(s2, PSTR("Redirecting..."));
|
if (!s2[0]) strcpy_P(s2, PSTR("Redirecting..."));
|
||||||
|
|
||||||
if (!doReboot) serveMessage(request, 200, s, s2, (subPage == 1 || subPage == 6) ? 129 : 1);
|
if (!doReboot) serveMessage(request, 200, s, s2, (subPage == 1 || subPage == 6) ? 129 : 1);
|
||||||
if (subPage == 6) doReboot = true;
|
if (subPage == 6) doReboot = true;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WLED_DISABLE_MOBILE_UI //disable welcome page if not enough storage
|
#ifdef WLED_DISABLE_MOBILE_UI //disable welcome page if not enough storage
|
||||||
if (subPage == 255) {serveIndex(request); return;}
|
if (subPage == 255) {serveIndex(request); return;}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
optionType = subPage;
|
optionType = subPage;
|
||||||
|
|
||||||
switch (subPage)
|
switch (subPage)
|
||||||
{
|
{
|
||||||
case 1: request->send_P(200, "text/html", PAGE_settings_wifi, settingsProcessor); break;
|
case 1: request->send_P(200, "text/html", PAGE_settings_wifi, settingsProcessor); break;
|
||||||
case 2: request->send_P(200, "text/html", PAGE_settings_leds, settingsProcessor); break;
|
case 2: request->send_P(200, "text/html", PAGE_settings_leds, settingsProcessor); break;
|
||||||
case 3: request->send_P(200, "text/html", PAGE_settings_ui , settingsProcessor); break;
|
case 3: request->send_P(200, "text/html", PAGE_settings_ui , settingsProcessor); break;
|
||||||
case 4: request->send_P(200, "text/html", PAGE_settings_sync, settingsProcessor); break;
|
case 4: request->send_P(200, "text/html", PAGE_settings_sync, settingsProcessor); break;
|
||||||
case 5: request->send_P(200, "text/html", PAGE_settings_time, settingsProcessor); break;
|
case 5: request->send_P(200, "text/html", PAGE_settings_time, settingsProcessor); break;
|
||||||
case 6: request->send_P(200, "text/html", PAGE_settings_sec , settingsProcessor); break;
|
case 6: request->send_P(200, "text/html", PAGE_settings_sec , settingsProcessor); break;
|
||||||
case 7: request->send_P(200, "text/html", PAGE_settings_dmx , settingsProcessor); break;
|
case 7: request->send_P(200, "text/html", PAGE_settings_dmx , settingsProcessor); break;
|
||||||
case 255: request->send_P(200, "text/html", PAGE_welcome); break;
|
case 255: request->send_P(200, "text/html", PAGE_welcome); break;
|
||||||
default: request->send_P(200, "text/html", PAGE_settings , settingsProcessor);
|
default: request->send_P(200, "text/html", PAGE_settings , settingsProcessor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
uint16_t wsLiveClientId = 0;
|
uint16_t wsLiveClientId = 0;
|
||||||
unsigned long wsLastLiveTime = 0;
|
unsigned long wsLastLiveTime = 0;
|
||||||
//uint8_t* wsFrameBuffer = nullptr;
|
//uint8_t* wsFrameBuffer = nullptr;
|
||||||
|
uint8_t vAPI = 2;
|
||||||
|
|
||||||
#define WS_LIVE_INTERVAL 40
|
#define WS_LIVE_INTERVAL 40
|
||||||
|
|
||||||
@ -27,7 +28,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
|||||||
//the whole message is in a single frame and we got all of it's data (max. 1450byte)
|
//the whole message is in a single frame and we got all of it's data (max. 1450byte)
|
||||||
if(info->opcode == WS_TEXT)
|
if(info->opcode == WS_TEXT)
|
||||||
{
|
{
|
||||||
bool verboseResponse = false;
|
uint8_t verboseResponse = 0;
|
||||||
{ //scope JsonDocument so it releases its buffer
|
{ //scope JsonDocument so it releases its buffer
|
||||||
DynamicJsonDocument jsonBuffer(JSON_BUFFER_SIZE);
|
DynamicJsonDocument jsonBuffer(JSON_BUFFER_SIZE);
|
||||||
DeserializationError error = deserializeJson(jsonBuffer, data, len);
|
DeserializationError error = deserializeJson(jsonBuffer, data, len);
|
||||||
@ -40,6 +41,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
|||||||
}
|
}
|
||||||
|
|
||||||
verboseResponse = deserializeState(root);
|
verboseResponse = deserializeState(root);
|
||||||
|
if (verboseResponse) vAPI = verboseResponse;
|
||||||
}
|
}
|
||||||
if (verboseResponse || millis() - lastInterfaceUpdate < 1900) sendDataWs(client); //update if it takes longer than 100ms until next "broadcast"
|
if (verboseResponse || millis() - lastInterfaceUpdate < 1900) sendDataWs(client); //update if it takes longer than 100ms until next "broadcast"
|
||||||
}
|
}
|
||||||
@ -79,6 +81,7 @@ void sendDataWs(AsyncWebSocketClient * client)
|
|||||||
{ //scope JsonDocument so it releases its buffer
|
{ //scope JsonDocument so it releases its buffer
|
||||||
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
DynamicJsonDocument doc(JSON_BUFFER_SIZE);
|
||||||
JsonObject state = doc.createNestedObject("state");
|
JsonObject state = doc.createNestedObject("state");
|
||||||
|
if (vAPI>1) state["rev"] = 2;
|
||||||
serializeState(state);
|
serializeState(state);
|
||||||
JsonObject info = doc.createNestedObject("info");
|
JsonObject info = doc.createNestedObject("info");
|
||||||
serializeInfo(info);
|
serializeInfo(info);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user