Incerased max segments.

Removed v2 JSON API.
Replaced col[] array handling.
Settings UI optimisations.
Increased DEBUG output period to 60s.
This commit is contained in:
Blaz Kristan 2021-06-19 18:06:30 +02:00
parent 3acc521741
commit 75bf758042
12 changed files with 774 additions and 779 deletions

View File

@ -53,13 +53,13 @@
/* 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 18 #define MAX_NUM_SEGMENTS 24
/* 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 4096 #define MAX_SEGMENT_DATA 4096
#else #else
#define MAX_NUM_SEGMENTS 24 #define MAX_NUM_SEGMENTS 32
#define MAX_NUM_TRANSITIONS 24 #define MAX_NUM_TRANSITIONS 24
#define MAX_SEGMENT_DATA 20480 #define MAX_SEGMENT_DATA 20480
#endif #endif

View File

@ -269,7 +269,7 @@
// Maximum size of node map (list of other WLED instances) // Maximum size of node map (list of other WLED instances)
#ifdef ESP8266 #ifdef ESP8266
#define WLED_MAX_NODES 15 #define WLED_MAX_NODES 24
#else #else
#define WLED_MAX_NODES 150 #define WLED_MAX_NODES 150
#endif #endif

View File

@ -1032,8 +1032,6 @@ function cmpP(a, b)
function handleJson(s) function handleJson(s)
{ {
if (!s) return false; if (!s) return false;
var e1 = gId('fxlist');
var e2 = gId('selectPalette');
isOn = s.on; isOn = s.on;
gId('sliderBri').value= s.bri; gId('sliderBri').value= s.bri;
@ -1069,6 +1067,7 @@ function handleJson(s)
b = i.col[e][2]; b = i.col[e][2];
if (isRgbw) w = i.col[e][3]; if (isRgbw) w = i.col[e][3];
} else { } else {
// unsigned long RGBW (@blazoncek v2 experimental API implementation)
r = (i.col[e]>>16) & 0xFF; r = (i.col[e]>>16) & 0xFF;
g = (i.col[e]>> 8) & 0xFF; g = (i.col[e]>> 8) & 0xFF;
b = (i.col[e] ) & 0xFF; b = (i.col[e] ) & 0xFF;
@ -1086,28 +1085,6 @@ function handleJson(s)
selectedPal = i.pal; selectedPal = i.pal;
selectedFx = i.fx; selectedFx = i.fx;
/*/--- AC addition ---//
// unfortunately this will trigger JSON request loop due to onchange event on input elements
// and it may not be necessary with websockes
// Effects
var selFx = e1.querySelector(`input[name="fx"][value="${i.fx}"]`);
if (selFx) selFx.checked = true;
else location.reload(); //effect list is gone (e.g. if restoring tab). Reload.
var selElement = e1.querySelector('.selected');
if (selElement) selElement.classList.remove('selected');
var selectedEffect = e1.querySelector(`.lstI[data-id="${i.fx}"]`);
if (selectedEffect) selectedEffect.classList.add('selected');
// Palettes
var selPa = e2.querySelector(`input[name="palette"][value="${i.pal}"]`);
if (selPa) selPa.checked = true;
selElement = e2.querySelector('.selected');
if (selElement) selElement.classList.remove('selected');
e2.querySelector(`.lstI[data-id="${i.pal}"]`).classList.add('selected');
//--- AC addition ---/*/
displayRover(lastinfo, s); displayRover(lastinfo, s);
clearErrorToast(); clearErrorToast();

View File

@ -46,13 +46,15 @@
var ih="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Preset</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>"; var ih="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Preset</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>";
for (i=0;i<8;i++) for (i=0;i<8;i++)
{ {
ih+="<tr><td><input name=\"W"+i+"\" id=\"W"+i+"\" type=\"number\" style=\"display:none\"><input id=\"W"+i+"0\" type=\"checkbox\"></td><td><input name=\"H"+i+"\" class=\"small\" type=\"number\" min=\"0\" max=\"24\"></td><td><input name=\"N"+i+"\" class=\"small\" type=\"number\" min=\"0\" max=\"59\"></td><td><input name=\"T"+i+"\" class=\"small\" type=\"number\" min=\"0\" max=\"250\"></td>"; ih+="<tr><td><input name=\"W"+i+"\" id=\"W"+i+"\" type=\"number\" style=\"display:none\"><input id=\"W"+i+"0\" type=\"checkbox\"></td><td><input name=\"H"+i+"\" class=\"small\" type=\"number\" min=\"0\" max=\"24\"></td><td><input name=\"N"+i+"\" class=\"small\" type=\"number\" min=\"0\" max=\"59\"></td><td><input name=\"T"+i+"\" class=\"med\" type=\"number\" min=\"0\" max=\"250\"></td>";
for (j=1;j<8;j++) ih+="<td><input id=\"W"+i+j+"\" type=\"checkbox\"></td>"; for (j=1;j<8;j++) ih+="<td><input id=\"W"+i+j+"\" type=\"checkbox\"></td>";
ih+="</tr>";
} }
ih+="<tr><td><input name=\"W8\" id=\"W8\" type=\"number\" style=\"display:none\"><input id=\"W80\" type=\"checkbox\"></td><td>Sunrise<input name=\"H8\" class=\"small\" value=\"255\" type=\"hidden\"></td><td><input name=\"N8\" class=\"small\" type=\"number\" min=\"-59\" max=\"59\"></td><td><input name=\"T8\" class=\"small\" type=\"number\" min=\"0\" max=\"250\"></td>"; ih+="<tr><td><input name=\"W8\" id=\"W8\" type=\"number\" style=\"display:none\"><input id=\"W80\" type=\"checkbox\"></td><td>Sunrise<input name=\"H8\" class=\"small\" value=\"255\" type=\"hidden\"></td><td><input name=\"N8\" class=\"small\" type=\"number\" min=\"-59\" max=\"59\"></td><td><input name=\"T8\" class=\"med\" type=\"number\" min=\"0\" max=\"250\"></td>";
for (j=1;j<8;j++) ih+="<td><input id=\"W8"+j+"\" type=\"checkbox\"></td>"; for (j=1;j<8;j++) ih+="<td><input id=\"W8"+j+"\" type=\"checkbox\"></td>";
ih+="<tr><td><input name=\"W9\" id=\"W9\" type=\"number\" style=\"display:none\"><input id=\"W90\" type=\"checkbox\"></td><td>Sunset<input name=\"H9\" class=\"small\" value=\"255\" type=\"hidden\"></td><td><input name=\"N9\" class=\"small\" type=\"number\" min=\"-59\" max=\"59\"><td><input name=\"T9\" class=\"small\" type=\"number\" min=\"0\" max=\"250\"></td>"; ih+="</tr><tr><td><input name=\"W9\" id=\"W9\" type=\"number\" style=\"display:none\"><input id=\"W90\" type=\"checkbox\"></td><td>Sunset<input name=\"H9\" class=\"small\" value=\"255\" type=\"hidden\"></td><td><input name=\"N9\" class=\"small\" type=\"number\" min=\"-59\" max=\"59\"></td><td><input name=\"T9\" class=\"med\" type=\"number\" min=\"0\" max=\"250\"></td>";
for (j=1;j<8;j++) ih+="<td><input id=\"W9"+j+"\" type=\"checkbox\"></td>"; for (j=1;j<8;j++) ih+="<td><input id=\"W9"+j+"\" type=\"checkbox\"></td>";
ih+="</tr>";
gId("TMT").innerHTML=ih; gId("TMT").innerHTML=ih;
} }
function FC() function FC()
@ -84,11 +86,11 @@
td = tr.insertCell(0); td = tr.insertCell(0);
td.innerHTML = `Button ${i}:`; td.innerHTML = `Button ${i}:`;
td = tr.insertCell(1); td = tr.insertCell(1);
td.innerHTML = `<input name="MP${i}" type="number" min="0" max="250" value="${p}" required>`; td.innerHTML = `<input name="MP${i}" type="number" class=\"med\" min="0" max="250" value="${p}" required>`;
td = tr.insertCell(2); td = tr.insertCell(2);
td.innerHTML = `<input name="ML${i}" type="number" min="0" max="250" value="${l}" required>`; td.innerHTML = `<input name="ML${i}" type="number" class=\"med\" min="0" max="250" value="${l}" required>`;
td = tr.insertCell(3); td = tr.insertCell(3);
td.innerHTML = `<input name="MD${i}" type="number" min="0" max="250" value="${d}" required>`; td.innerHTML = `<input name="MD${i}" type="number" class=\"med\" min="0" max="250" value="${d}" required>`;
} }
function GetV() function GetV()
{ {
@ -132,8 +134,8 @@
</select><br> </select><br>
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br> UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> seconds (max. 18 hours)<br>
Current local time is <span class="times">unknown</span>.<br> Current local time is <span class="times">unknown</span>.<br>
Latitude (N): <input name="LT" type="number" min="-66.6" max="66.6" step="0.01"> Latitude (N): <input name="LT" type="number" class="big" min="-66.6" max="66.6" step="0.01">
Longitude (E): <input name="LN" type="number" min="-180" max="180" step="0.01"> Longitude (E): <input name="LN" type="number" class="big" min="-180" max="180" step="0.01">
<div id="sun" class="times"></div> <div id="sun" class="times"></div>
<h3>Clock</h3> <h3>Clock</h3>
Clock Overlay: Clock Overlay:

View File

@ -45,7 +45,10 @@ input[type="number"] {
margin: 2px; margin: 2px;
} }
input[type="number"].big { input[type="number"].big {
width: 80px; width: 70px;
}
input[type="number"].med {
width: 55px;
} }
input[type="number"].small { input[type="number"].small {
width: 40px; width: 40px;

View File

@ -102,7 +102,7 @@ void handleIR();
void deserializeSegment(JsonObject elem, byte it, byte presetId = 0); void deserializeSegment(JsonObject elem, byte it, byte presetId = 0);
bool deserializeState(JsonObject root, byte presetId = 0); bool deserializeState(JsonObject root, byte presetId = 0);
void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset = false, bool segmentBounds = true, uint8_t versionAPI = 1); void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset = false, bool segmentBounds = true);
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, uint8_t versionAPI = 1); void serveJson(AsyncWebServerRequest* request, uint8_t versionAPI = 1);

View File

@ -42,7 +42,7 @@ function B(){window.history.back()}function U(){document.getElementById("uf").st
.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}#msg{display:none} .bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}#msg{display:none}
</style></head><body><h2>WLED Software Update</h2><form method="POST" </style></head><body><h2>WLED Software Update</h2><form method="POST"
action="/update" id="uf" enctype="multipart/form-data" onsubmit="U()"> action="/update" id="uf" enctype="multipart/form-data" onsubmit="U()">
Installed version: 0.12.2-bl3<br>Download the latest binary: <a Installed version: 0.12.2-bl4<br>Download the latest binary: <a
href="https://github.com/Aircoookie/WLED/releases" target="_blank"><img href="https://github.com/Aircoookie/WLED/releases" target="_blank"><img
src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"> src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square">
</a><br><input type="file" class="bt" name="update" required><br><input </a><br><input type="file" class="bt" name="update" required><br><input

View File

@ -6,7 +6,7 @@
*/ */
// Autogenerated from wled00/data/style.css, do not edit!! // Autogenerated from wled00/data/style.css, do not edit!!
const char PAGE_settingsCss[] PROGMEM = R"=====(<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}hr{border-color:#666}button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;border-radius:24px;display:inline-block;font-size:20px;margin:12px 8px 8px;padding:8px 12px;min-width:48px;cursor:pointer}.toprow{top:0;position:sticky;background-color:#222;z-index:1}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input[type=number]{width:4em;font-size:medium;margin:2px}input[type=number].big{width:80px}input[type=number].small{width:40px}select{margin:2px;font-size:medium}input[type=checkbox]{-ms-transform:scale(2);-moz-transform:scale(2);-webkit-transform:scale(2);-o-transform:scale(2);transform:scale(2);margin-right:10px}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}td{padding:2px}.d5{width:4.5em!important}#toast{opacity:0;background-color:#444;border-radius:5px;bottom:64px;color:#fff;font-size:17px;padding:16px;pointer-events:none;position:fixed;text-align:center;z-index:5;transform:translateX(-50%%);max-width:90%%;left:50%%}#toast.show{opacity:1;background-color:#264;animation:fadein .5s,fadein .5s 2.5s reverse}#toast.error{opacity:1;background-color:#b21;animation:fadein .5s}</style>)====="; const char PAGE_settingsCss[] PROGMEM = R"=====(<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}hr{border-color:#666}button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;border-radius:24px;display:inline-block;font-size:20px;margin:12px 8px 8px;padding:8px 12px;min-width:48px;cursor:pointer}.toprow{top:0;position:sticky;background-color:#222;z-index:1}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input[type=number]{width:4em;font-size:medium;margin:2px}input[type=number].big{width:70px}input[type=number].med{width:55px}input[type=number].small{width:40px}select{margin:2px;font-size:medium}input[type=checkbox]{-ms-transform:scale(2);-moz-transform:scale(2);-webkit-transform:scale(2);-o-transform:scale(2);transform:scale(2);margin-right:10px}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}td{padding:2px}.d5{width:4.5em!important}#toast{opacity:0;background-color:#444;border-radius:5px;bottom:64px;color:#fff;font-size:17px;padding:16px;pointer-events:none;position:fixed;text-align:center;z-index:5;transform:translateX(-50%%);max-width:90%%;left:50%%}#toast.show{opacity:1;background-color:#264;animation:fadein .5s,fadein .5s 2.5s reverse}#toast.error{opacity:1;background-color:#b21;animation:fadein .5s}</style>)=====";
// Autogenerated from wled00/data/settings.htm, do not edit!! // Autogenerated from wled00/data/settings.htm, do not edit!!
@ -311,7 +311,7 @@ type="submit">Save</button></form></body></html>)=====";
// Autogenerated from wled00/data/settings_time.htm, do not edit!! // Autogenerated from wled00/data/settings_time.htm, do not edit!!
const char PAGE_settings_time[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=500"> const char PAGE_settings_time[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=500">
<meta charset="utf-8"><title>Time Settings</title><script> <meta charset="utf-8"><title>Time Settings</title><script>
var d=document;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings")}function B(){window.open("/settings","_self")}function S(){BTa(),GetV(),Cs(),FC()}function gId(t){return d.getElementById(t)}function Cs(){gId("cac").style.display="none",gId("coc").style.display="block",gId("ccc").style.display="none",gId("ca").selected&&(gId("cac").style.display="block"),gId("cc").selected&&(gId("coc").style.display="none",gId("ccc").style.display="block"),gId("cn").selected&&(gId("coc").style.display="none")}function BTa(){var t="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Preset</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>";for(i=0;i<8;i++)for(t+='<tr><td><input name="W'+i+'" id="W'+i+'" type="number" style="display:none"><input id="W'+i+'0" type="checkbox"></td><td><input name="H'+i+'" class="small" type="number" min="0" max="24"></td><td><input name="N'+i+'" class="small" type="number" min="0" max="59"></td><td><input name="T'+i+'" class="small" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W'+i+j+'" type="checkbox"></td>';for(t+='<tr><td><input name="W8" id="W8" type="number" style="display:none"><input id="W80" type="checkbox"></td><td>Sunrise<input name="H8" class="small" value="255" type="hidden"></td><td><input name="N8" class="small" type="number" min="-59" max="59"></td><td><input name="T8" class="small" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W8'+j+'" type="checkbox"></td>';for(t+='<tr><td><input name="W9" id="W9" type="number" style="display:none"><input id="W90" type="checkbox"></td><td>Sunset<input name="H9" class="small" value="255" type="hidden"></td><td><input name="N9" class="small" type="number" min="-59" max="59"><td><input name="T9" class="small" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W9'+j+'" type="checkbox"></td>';gId("TMT").innerHTML=t}function FC(){for(j=0;j<8;j++)for(i=0;i<10;i++)gId("W"+i+j).checked=gId("W"+i).value>>j&1}function Wd(){for(a=[0,0,0,0,0,0,0,0,0,0],i=0;i<10;i++){for(m=1,j=0;j<8;j++)a[i]+=gId("W"+i+j).checked*m,m*=2;gId("W"+i).value=a[i]}}function addRow(t,e,n,i){var d=gId("macros"),a=d.rows.length,l=d.insertRow(a);document.createElement("td");l.insertCell(0).innerHTML=`Button ${t}:`,l.insertCell(1).innerHTML=`<input name="MP${t}" type="number" min="0" max="250" value="${e}" required>`,l.insertCell(2).innerHTML=`<input name="ML${t}" type="number" min="0" max="250" value="${n}" required>`,l.insertCell(3).innerHTML=`<input name="MD${t}" type="number" min="0" max="250" value="${i}" required>`}function GetV() { var d=document;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#time-settings")}function B(){window.open("/settings","_self")}function S(){BTa(),GetV(),Cs(),FC()}function gId(t){return d.getElementById(t)}function Cs(){gId("cac").style.display="none",gId("coc").style.display="block",gId("ccc").style.display="none",gId("ca").selected&&(gId("cac").style.display="block"),gId("cc").selected&&(gId("coc").style.display="none",gId("ccc").style.display="block"),gId("cn").selected&&(gId("coc").style.display="none")}function BTa(){var t="<tr><th>Active</th><th>Hour</th><th>Minute</th><th>Preset</th><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr>";for(i=0;i<8;i++){for(t+='<tr><td><input name="W'+i+'" id="W'+i+'" type="number" style="display:none"><input id="W'+i+'0" type="checkbox"></td><td><input name="H'+i+'" class="small" type="number" min="0" max="24"></td><td><input name="N'+i+'" class="small" type="number" min="0" max="59"></td><td><input name="T'+i+'" class="med" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W'+i+j+'" type="checkbox"></td>';t+="</tr>"}for(t+='<tr><td><input name="W8" id="W8" type="number" style="display:none"><input id="W80" type="checkbox"></td><td>Sunrise<input name="H8" class="small" value="255" type="hidden"></td><td><input name="N8" class="small" type="number" min="-59" max="59"></td><td><input name="T8" class="med" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W8'+j+'" type="checkbox"></td>';for(t+='</tr><tr><td><input name="W9" id="W9" type="number" style="display:none"><input id="W90" type="checkbox"></td><td>Sunset<input name="H9" class="small" value="255" type="hidden"></td><td><input name="N9" class="small" type="number" min="-59" max="59"></td><td><input name="T9" class="med" type="number" min="0" max="250"></td>',j=1;j<8;j++)t+='<td><input id="W9'+j+'" type="checkbox"></td>';t+="</tr>",gId("TMT").innerHTML=t}function FC(){for(j=0;j<8;j++)for(i=0;i<10;i++)gId("W"+i+j).checked=gId("W"+i).value>>j&1}function Wd(){for(a=[0,0,0,0,0,0,0,0,0,0],i=0;i<10;i++){for(m=1,j=0;j<8;j++)a[i]+=gId("W"+i+j).checked*m,m*=2;gId("W"+i).value=a[i]}}function addRow(t,e,n,i){var d=gId("macros"),a=d.rows.length,s=d.insertRow(a);document.createElement("td");s.insertCell(0).innerHTML=`Button ${t}:`,s.insertCell(1).innerHTML=`<input name="MP${t}" type="number" class="med" min="0" max="250" value="${e}" required>`,s.insertCell(2).innerHTML=`<input name="ML${t}" type="number" class="med" min="0" max="250" value="${n}" required>`,s.insertCell(3).innerHTML=`<input name="MD${t}" type="number" class="med" min="0" max="250" value="${i}" required>`}function GetV() {
%CSS%%SCSS%<link href="/skin.css" %CSS%%SCSS%<link href="/skin.css"
rel="stylesheet"></head><body onload="S()"><form id="form_s" name="Sf" rel="stylesheet"></head><body onload="S()"><form id="form_s" name="Sf"
method="post" onsubmit="Wd()"><div class="toprow"><div class="helpB"><button method="post" onsubmit="Wd()"><div class="toprow"><div class="helpB"><button
@ -331,11 +331,12 @@ CA-Saskatchewan</option><option value="16">ACST</option><option value="17">
ACST/ACDT</option><option value="18">HST (Hawaii)</option></select><br> ACST/ACDT</option><option value="18">HST (Hawaii)</option></select><br>
UTC offset: <input name="UO" type="number" min="-65500" max="65500" required> UTC offset: <input name="UO" type="number" min="-65500" max="65500" required>
seconds (max. 18 hours)<br>Current local time is <span class="times">unknown seconds (max. 18 hours)<br>Current local time is <span class="times">unknown
</span>.<br>Latitude (N): <input name="LT" type="number" min="-66.6" max="66.6" </span>.<br>Latitude (N): <input name="LT" type="number" class="big"
step="0.01"> Longitude (E): <input name="LN" type="number" min="-180" max="180" min="-66.6" max="66.6" step="0.01"> Longitude (E): <input name="LN"
step="0.01"><div id="sun" class="times"></div><h3>Clock</h3>Clock Overlay: type="number" class="big" min="-180" max="180" step="0.01"><div id="sun"
<select name="OL" onchange="Cs()"><option value="0" id="cn" selected="selected"> class="times"></div><h3>Clock</h3>Clock Overlay: <select name="OL"
None</option><option value="1" id="ca">Analog Clock</option><option value="2"> onchange="Cs()"><option value="0" id="cn" selected="selected">None</option>
<option value="1" id="ca">Analog Clock</option><option value="2">
Single Digit Clock</option><option value="3" id="cc">Cronixie Clock</option> Single Digit Clock</option><option value="3" id="cc">Cronixie Clock</option>
</select><br><div id="coc">First LED: <input name="O1" type="number" min="0" </select><br><div id="coc">First LED: <input name="O1" type="number" min="0"
max="255" required> Last LED: <input name="O2" type="number" min="0" max="255" max="255" required> Last LED: <input name="O2" type="number" min="0" max="255"
@ -392,7 +393,7 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
<h3>Software Update</h3><button type="button" onclick="U()">Manual OTA Update <h3>Software Update</h3><button type="button" onclick="U()">Manual OTA Update
</button><br>Enable ArduinoOTA: <input type="checkbox" name="AO"><br><h3>About </button><br>Enable ArduinoOTA: <input type="checkbox" name="AO"><br><h3>About
</h3><a href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a> </h3><a href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a>
version 0.12.2-bl3<br><br><a version 0.12.2-bl4<br><br><a
href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits" href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits"
target="_blank">Contributors, dependencies and special thanks</a><br> target="_blank">Contributors, dependencies and special thanks</a><br>
A huge thank you to everyone who helped me create WLED!<br><br> A huge thank you to everyone who helped me create WLED!<br><br>

File diff suppressed because it is too large Load Diff

View File

@ -64,7 +64,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
int rgbw[] = {0,0,0,0}; int rgbw[] = {0,0,0,0};
bool colValid = false; bool colValid = false;
if (colarr[i].is<unsigned long>()) { if (colarr[i].is<unsigned long>()) {
// unsigned long RGBW // unsigned long RGBW (@blazoncek v2 experimental API implementation)
uint32_t colX = colarr[i]; uint32_t colX = colarr[i];
rgbw[0] = (colX >> 16) & 0xFF; rgbw[0] = (colX >> 16) & 0xFF;
rgbw[1] = (colX >> 8) & 0xFF; rgbw[1] = (colX >> 8) & 0xFF;
@ -351,8 +351,10 @@ bool deserializeState(JsonObject root, byte presetId)
return stateResponse; return stateResponse;
} }
void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset, bool segmentBounds, uint8_t versionAPI) void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool forPreset, bool segmentBounds)
{ {
uint8_t versionAPI = root["ver"] | 1;
root["id"] = id; root["id"] = id;
if (segmentBounds) { if (segmentBounds) {
root[F("start")] = seg.start; root[F("start")] = seg.start;
@ -368,8 +370,9 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool fo
if (seg.name != nullptr) root["n"] = String(seg.name); if (seg.name != nullptr) root["n"] = String(seg.name);
JsonArray colarr = root.createNestedArray("col"); JsonArray colarr = root.createNestedArray("col");
/*
if (versionAPI>1) { if (versionAPI>1) {
// if we want to sqeeze a few more segments on 8266 we need to use v2 experimental API
for (uint8_t i = 0; i < 3; i++) for (uint8_t i = 0; i < 3; i++)
{ {
if (id==strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment if (id==strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment
@ -379,26 +382,30 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool fo
colarr.add((unsigned long)seg.colors[i]); colarr.add((unsigned long)seg.colors[i]);
} }
} else { } else {
*/
// to conserve RAM we will serialize the col array manually
// this will reduce RAM footprint from ~300 bytes to 84 bytes per segment
char colstr[70] = "["; //max len 68 (5 chan, all 255)
for (uint8_t i = 0; i < 3; i++) for (uint8_t i = 0; i < 3; i++)
{ {
JsonArray colX = colarr.createNestedArray(); char tmpcol[22];
if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment
{ {
if (i == 0) { byte* c = (i == 0)? col:colSec;
colX.add(col[0]); colX.add(col[1]); colX.add(col[2]); if (strip.isRgbw) colX.add(col[3]); if (strip.isRgbw) sprintf_P(tmpcol, PSTR("[%d,%d,%d,%d]"), c[0], c[1], c[2], c[3]);
else sprintf_P(tmpcol, PSTR("[%d,%d,%d]"), c[0], c[1], c[2]);
} else { } else {
colX.add(colSec[0]); colX.add(colSec[1]); colX.add(colSec[2]); if (strip.isRgbw) colX.add(colSec[3]); uint32_t c = seg.colors[i];
if (strip.isRgbw) sprintf_P(tmpcol, PSTR("[%d,%d,%d,%d]"), (c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF, (c >> 24) & 0xFF);
else sprintf_P(tmpcol, PSTR("[%d,%d,%d]"), (c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF);
} }
} else { strcat(colstr, i<2 ? strcat_P(tmpcol, PSTR(",")) : tmpcol);
colX.add((seg.colors[i] >> 16) & 0xFF);
colX.add((seg.colors[i] >> 8) & 0xFF);
colX.add((seg.colors[i]) & 0xFF);
if (strip.isRgbw)
colX.add((seg.colors[i] >> 24) & 0xFF);
} }
strcat_P(colstr, PSTR("]"));
root["col"] = serialized(colstr);
/*
} }
} */
root["fx"] = seg.mode; root["fx"] = seg.mode;
root[F("sx")] = seg.speed; root[F("sx")] = seg.speed;
root[F("ix")] = seg.intensity; root[F("ix")] = seg.intensity;
@ -451,25 +458,29 @@ void serializeState(JsonObject root, bool forPreset, bool includeBri, bool segme
root[F("mainseg")] = strip.getMainSegmentId(); root[F("mainseg")] = strip.getMainSegmentId();
/*
// the following is an UGLY construct that does the job // the following is an UGLY construct that does the job
#ifdef ESP8266 #ifdef ESP8266
// use rev:2 API if more than 12 segments on ESP8266 // use rev:2 API if more than 16 segments on ESP8266
uint8_t tooMany = 0; uint8_t tooMany = 0;
for(uint8_t i=0; i < strip.getMaxSegments(); i++) if ((strip.getSegment(i)).isActive()) tooMany++; for(uint8_t i=0; i < strip.getMaxSegments(); i++) if ((strip.getSegment(i)).isActive()) tooMany++;
if (tooMany<13) if (tooMany<17)
#endif #endif
root.remove("rev"); // remove API revision if ESP32 or ESP8266 with less than 13 segments root.remove("rev"); // remove API revision if ESP32 or ESP8266 with less than 13 segments
*/
uint8_t versionAPI = root["rev"] | 1; uint8_t versionAPI = root["rev"] | 1;
JsonArray seg = root.createNestedArray("seg"); JsonArray seg = root.createNestedArray("seg");
for (byte s = 0; s < strip.getMaxSegments(); s++) for (byte s = 0; s < strip.getMaxSegments(); s++)
{ {
WS2812FX::Segment sg = strip.getSegment(s); WS2812FX::Segment sg = strip.getSegment(s);
// TODO: add logic to stop at 12 segments if using versionAPI==1 on ESP8266 // TODO: add logic to stop at 16 segments if using versionAPI==1 on ESP8266
if (sg.isActive()) if (sg.isActive())
{ {
JsonObject seg0 = seg.createNestedObject(); JsonObject seg0 = seg.createNestedObject();
serializeSegment(seg0, sg, s, forPreset, segmentBounds, versionAPI); if (versionAPI>1) seg0["ver"] = versionAPI; // temporary hack segment
serializeSegment(seg0, sg, s, forPreset, segmentBounds);
if (versionAPI>1) seg[0].remove("ver"); // remove hack
} else if (forPreset && segmentBounds) { //disable segments not part of preset } else if (forPreset && segmentBounds) { //disable segments not part of preset
JsonObject seg0 = seg.createNestedObject(); JsonObject seg0 = seg.createNestedObject();
seg0["stop"] = 0; seg0["stop"] = 0;
@ -861,6 +872,8 @@ void serveJson(AsyncWebServerRequest* request, uint8_t versionAPI)
} }
} }
DEBUG_PRINTF("JSON buffer size: %ld for request: %d\n", doc.memoryUsage(), subJson);
response->setLength(); response->setLength();
request->send(response); request->send(response);
} }

View File

@ -271,7 +271,7 @@ void WLED::loop()
// DEBUG serial logging // DEBUG serial logging
#ifdef WLED_DEBUG #ifdef WLED_DEBUG
if (millis() - debugTime > 9999) { if (millis() - debugTime > 59999) {
DEBUG_PRINTLN(F("---DEBUG INFO---")); DEBUG_PRINTLN(F("---DEBUG INFO---"));
DEBUG_PRINT(F("Runtime: ")); DEBUG_PRINTLN(millis()); DEBUG_PRINT(F("Runtime: ")); DEBUG_PRINTLN(millis());
DEBUG_PRINT(F("Unix time: ")); toki.printTime(toki.getTime()); DEBUG_PRINT(F("Unix time: ")); toki.printTime(toki.getTime());

View File

@ -8,7 +8,7 @@
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2106181 #define VERSION 2106191
//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