Merge branch 'dev' of https://github.com/aircoookie/WLED into dev
Conflicts: wled00/NodeStruct.h wled00/data/index.htm wled00/data/index.js wled00/fcn_declare.h wled00/html_ui.h wled00/json.cpp wled00/udp.cpp wled00/wled.cpp wled00/wled.h
This commit is contained in:
commit
cb38976162
@ -2,6 +2,11 @@
|
|||||||
|
|
||||||
### Development versions after 0.11.1 release
|
### Development versions after 0.11.1 release
|
||||||
|
|
||||||
|
#### Build 2103090
|
||||||
|
|
||||||
|
- Added Auto Node discovery (PR #1683)
|
||||||
|
- Added tooltips to quick color selectors for accessibility
|
||||||
|
|
||||||
#### Build 2103060
|
#### Build 2103060
|
||||||
|
|
||||||
- Auto start field population in bus config
|
- Auto start field population in bus config
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
#include "NodeStruct.h"
|
|
||||||
|
|
||||||
String getNodeTypeDisplayString(uint8_t nodeType) {
|
|
||||||
switch (nodeType)
|
|
||||||
{
|
|
||||||
case NODE_TYPE_ID_ESP8266: return F("ESP8266");
|
|
||||||
case NODE_TYPE_ID_ESP32: return F("ESP32");
|
|
||||||
}
|
|
||||||
return "Undefined";
|
|
||||||
}
|
|
||||||
|
|
||||||
NodeStruct::NodeStruct() :
|
|
||||||
age(0), nodeType(0), build(0)
|
|
||||||
{
|
|
||||||
for (uint8_t i = 0; i < 4; ++i) { ip[i] = 0; }
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef DATASTRUCTS_NODESTRUCT_H
|
#ifndef WLED_NODESTRUCT_H
|
||||||
#define DATASTRUCTS_NODESTRUCT_H
|
#define WLED_NODESTRUCT_H
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* NodeStruct from the ESP Easy project (https://github.com/letscontrolit/ESPEasy)
|
* NodeStruct from the ESP Easy project (https://github.com/letscontrolit/ESPEasy)
|
||||||
@ -8,27 +8,27 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <IPAddress.h>
|
#include <IPAddress.h>
|
||||||
|
|
||||||
|
#define NODE_TYPE_ID_UNDEFINED 0
|
||||||
#define NODE_TYPE_ID_UNDEFINED 0
|
#define NODE_TYPE_ID_ESP8266 82
|
||||||
#define NODE_TYPE_ID_ESP8266 1
|
#define NODE_TYPE_ID_ESP32 32
|
||||||
#define NODE_TYPE_ID_ESP32 2
|
|
||||||
|
|
||||||
String getNodeTypeDisplayString(uint8_t nodeType);
|
|
||||||
|
|
||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
* NodeStruct
|
* NodeStruct
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
struct NodeStruct
|
struct NodeStruct
|
||||||
{
|
{
|
||||||
NodeStruct();
|
|
||||||
|
|
||||||
String nodeName;
|
String nodeName;
|
||||||
IPAddress ip;
|
IPAddress ip;
|
||||||
uint8_t unit;
|
uint8_t unit;
|
||||||
uint8_t age;
|
uint8_t age;
|
||||||
uint8_t nodeType;
|
uint8_t nodeType;
|
||||||
uint32_t build;
|
uint32_t build;
|
||||||
|
|
||||||
|
NodeStruct() : age(0), nodeType(0), build(0)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < 4; ++i) { ip[i] = 0; }
|
||||||
|
}
|
||||||
};
|
};
|
||||||
typedef std::map<uint8_t, NodeStruct> NodesMap;
|
typedef std::map<uint8_t, NodeStruct> NodesMap;
|
||||||
|
|
||||||
#endif // DATASTRUCTS_NODESTRUCT_H
|
#endif // WLED_NODESTRUCT_H
|
||||||
|
@ -233,6 +233,13 @@
|
|||||||
#define JSON_BUFFER_SIZE 16384
|
#define JSON_BUFFER_SIZE 16384
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Maximum size of node map (list of other WLED instances)
|
||||||
|
#ifdef ESP8266
|
||||||
|
#define WLED_MAX_NODES 15
|
||||||
|
#else
|
||||||
|
#define WLED_MAX_NODES 150
|
||||||
|
#endif
|
||||||
|
|
||||||
//this is merely a default now and can be changed at runtime
|
//this is merely a default now and can be changed at runtime
|
||||||
#ifndef LEDPIN
|
#ifndef LEDPIN
|
||||||
#define LEDPIN 2
|
#define LEDPIN 2
|
||||||
|
@ -90,9 +90,10 @@ button {
|
|||||||
|
|
||||||
#namelabel {
|
#namelabel {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: calc(var(--bh) + 5px);
|
bottom: calc(var(--bh) + 6px);
|
||||||
right: 4px;
|
right: 4px;
|
||||||
color: var(--c-6);
|
color: var(--c-6);
|
||||||
|
cursor: pointer;
|
||||||
writing-mode: vertical-rl;
|
writing-mode: vertical-rl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -377,6 +378,14 @@ button {
|
|||||||
z-index: 2;
|
z-index: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ndlt {
|
||||||
|
margin: 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.valtd i {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
#roverstar {
|
#roverstar {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: calc(var(--th) + 5px);
|
top: calc(var(--th) + 5px);
|
||||||
@ -406,6 +415,10 @@ button {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#kn td {
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
#lv {
|
#lv {
|
||||||
max-width: 600px;
|
max-width: 600px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -1040,6 +1053,12 @@ input[type="text"].fnd:not(:placeholder-shown) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media all and (max-width: 770px) {
|
||||||
|
#buttonNodes {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media all and (max-width: 1249px) {
|
@media all and (max-width: 1249px) {
|
||||||
#buttonPcm, #buttonNo {
|
#buttonPcm, #buttonNo {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -24,9 +24,9 @@
|
|||||||
<button id="buttonSync" onclick="toggleSync()"><i class="icons"></i><p class="tab-label">Sync</p></button>
|
<button id="buttonSync" onclick="toggleSync()"><i class="icons"></i><p class="tab-label">Sync</p></button>
|
||||||
<button id="buttonSr" onclick="toggleLiveview()"><i class="icons"></i><p class="tab-label">Peek</p></button>
|
<button id="buttonSr" onclick="toggleLiveview()"><i class="icons"></i><p class="tab-label">Peek</p></button>
|
||||||
<button id="buttonI" onclick="toggleInfo()"><i class="icons"></i><p class="tab-label">Info</p></button>
|
<button id="buttonI" onclick="toggleInfo()"><i class="icons"></i><p class="tab-label">Info</p></button>
|
||||||
|
<button id="buttonNodes" onclick="toggleNodes()"><i class="icons"></i><p class="tab-label">Nodes</p></button></div>
|
||||||
<button onclick="window.location.href = '/settings';"><i class="icons"></i><p class="tab-label">Config</p></button>
|
<button onclick="window.location.href = '/settings';"><i class="icons"></i><p class="tab-label">Config</p></button>
|
||||||
<button id="buttonPcm" onclick="togglePcMode(true)"><i class="icons"></i><p class="tab-label">PC Mode</p></button>
|
<button id="buttonPcm" onclick="togglePcMode(true)"><i class="icons"></i><p class="tab-label">PC Mode</p></button>
|
||||||
<button id="buttonNo" onclick="toggleNodes()"><i class="icons"></i><p class="tab-label">Nodes</p></button>
|
|
||||||
</div>
|
</div>
|
||||||
<div id="briwrap">
|
<div id="briwrap">
|
||||||
<p class="hd">Brightness</p>
|
<p class="hd">Brightness</p>
|
||||||
@ -78,17 +78,17 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="qcs-w">
|
<div id="qcs-w">
|
||||||
<div class="qcs" onclick="pC('#ff0000');" style="background-color:#ff0000;"></div>
|
<div class="qcs" onclick="pC('#ff0000');" title="Red" style="background-color:#ff0000;"></div>
|
||||||
<div class="qcs" onclick="pC('#ffa000');" style="background-color:#ffa000;"></div>
|
<div class="qcs" onclick="pC('#ffa000');" title="Orange" style="background-color:#ffa000;"></div>
|
||||||
<div class="qcs" onclick="pC('#ffc800');" style="background-color:#ffc800;"></div>
|
<div class="qcs" onclick="pC('#ffc800');" title="Yellow" style="background-color:#ffc800;"></div>
|
||||||
<div class="qcs" onclick="pC('#ffe0a0');" style="background-color:#ffe0a0;"></div>
|
<div class="qcs" onclick="pC('#ffe0a0');" title="Warm White" style="background-color:#ffe0a0;"></div>
|
||||||
<div class="qcs" onclick="pC('#ffffff');" style="background-color:#ffffff;"></div>
|
<div class="qcs" onclick="pC('#ffffff');" title="White" style="background-color:#ffffff;"></div>
|
||||||
<div class="qcs qcsb" onclick="pC('#000000');" style="background-color:#000000;"></div><br>
|
<div class="qcs qcsb" onclick="pC('#000000');" title="Black" style="background-color:#000000;"></div><br>
|
||||||
<div class="qcs" onclick="pC('#ff00ff');" style="background-color:#ff00ff;"></div>
|
<div class="qcs" onclick="pC('#ff00ff');" title="Pink" style="background-color:#ff00ff;"></div>
|
||||||
<div class="qcs" onclick="pC('#0000ff');" style="background-color:#0000ff;"></div>
|
<div class="qcs" onclick="pC('#0000ff');" title="Blue" style="background-color:#0000ff;"></div>
|
||||||
<div class="qcs" onclick="pC('#00ffc8');" style="background-color:#00ffc8;"></div>
|
<div class="qcs" onclick="pC('#00ffc8');" title="Cyan" style="background-color:#00ffc8;"></div>
|
||||||
<div class="qcs" onclick="pC('#08ff00');" style="background-color:#08ff00;"></div>
|
<div class="qcs" onclick="pC('#08ff00');" title="Green" style="background-color:#08ff00;"></div>
|
||||||
<div class="qcs" onclick="pC('rnd');" style="background-color:var(--c-3); padding: 4px 8px; transform: translateY(-10px);">R</div>
|
<div class="qcs" onclick="pC('rnd');" title="Random" style="background-color:var(--c-3); padding: 4px 8px; transform: translateY(-10px);">R</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="csl">
|
<div id="csl">
|
||||||
<button class="xxs cl btn" onclick="selectSlot(0);">1</button>
|
<button class="xxs cl btn" onclick="selectSlot(0);">1</button>
|
||||||
@ -205,7 +205,7 @@
|
|||||||
|
|
||||||
<div id="connind"></div>
|
<div id="connind"></div>
|
||||||
<div id="toast"></div>
|
<div id="toast"></div>
|
||||||
<div id="namelabel"></div>
|
<div id="namelabel" onclick="toggleNodes()"></div>
|
||||||
<div id="info" class="modal">
|
<div id="info" class="modal">
|
||||||
<div id="imgw">
|
<div id="imgw">
|
||||||
<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=">
|
||||||
@ -213,15 +213,18 @@
|
|||||||
<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="requestJson(null)">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="openGH()">WLED Wiki</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>
|
||||||
<span class="h">Made with <span id="heart">❤︎</span> by Aircoookie and the WLED community</span>
|
<span class="h">Made with <span id="heart">❤︎</span> by Aircoookie and the WLED community</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="nodes" class="modal">
|
<div id="nodes" class="modal">
|
||||||
|
<div id="ndlt">WLED instances</div>
|
||||||
<div id="kn">Loading...</div><br>
|
<div id="kn">Loading...</div><br>
|
||||||
<button class="btn infobtn" onclick="requestJson(null)">Refresh</button>
|
<button class="btn infobtn" onclick="loadNodes()">Refresh</button>
|
||||||
<button class="btn infobtn" onclick="toggleNodes()">Close</button><br>
|
<button class="btn infobtn" onclick="toggleNodes()">Close list</button><br>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="rover" class="modal">
|
<div id="rover" class="modal">
|
||||||
<i class="icons huge"></i><br>
|
<i class="icons huge"></i><br>
|
||||||
<div id="lv">?</div><br><br>
|
<div id="lv">?</div><br><br>
|
||||||
@ -231,6 +234,7 @@
|
|||||||
<button class="btn" onclick="setLor(2)">Override until reboot</button><br>
|
<button class="btn" onclick="setLor(2)">Override until reboot</button><br>
|
||||||
<span class="h">For best performance, it is recommended to turn off the streaming source when not in use.</span>
|
<span class="h">For best performance, it is recommended to turn off the streaming source when not in use.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<i id="roverstar" class="icons huge" onclick="setLor(0)"></i><br>
|
<i id="roverstar" class="icons huge" onclick="setLor(0)"></i><br>
|
||||||
<script src="iro.js"></script>
|
<script src="iro.js"></script>
|
||||||
<script src="rangetouch.js"></script>
|
<script src="rangetouch.js"></script>
|
||||||
|
@ -532,35 +532,6 @@ function populatePresets(fromls)
|
|||||||
populateQL();
|
populateQL();
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateNodes(i)
|
|
||||||
{
|
|
||||||
var cn="";
|
|
||||||
var urows="";
|
|
||||||
if (i.nodes) {
|
|
||||||
i.nodes.sort((a,b) => (a.name).localeCompare(b.name));
|
|
||||||
for (var x=0;x<i.nodes.length;x++) {
|
|
||||||
var o = i.nodes[x];
|
|
||||||
if (o.name) {
|
|
||||||
var url = `<button class="btn btna-icon tab" onclick="location.assign('http://${o.ip}');">${o.name}</button>`;
|
|
||||||
urows += inforow(url,`${o.type}<br><i>${o.build==0?"N/A":o.build}</i>`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i.nodes.length>0) {
|
|
||||||
var botButtons = d.querySelectorAll('.bot button');
|
|
||||||
for (btn of botButtons) {
|
|
||||||
btn.style.width = '20%';
|
|
||||||
}
|
|
||||||
d.getElementById('btnNodes').style.display = "inline";
|
|
||||||
} else
|
|
||||||
d.getElementById('btnNodes').style.display = "none";
|
|
||||||
}
|
|
||||||
cn += `<table class="infot">
|
|
||||||
${urows}
|
|
||||||
${inforow("Current node:",i.name)}
|
|
||||||
</table>`;
|
|
||||||
d.getElementById('kn').innerHTML = cn;
|
|
||||||
}
|
|
||||||
|
|
||||||
function populateInfo(i)
|
function populateInfo(i)
|
||||||
{
|
{
|
||||||
var cn="";
|
var cn="";
|
||||||
@ -684,6 +655,63 @@ function populateSegments(s)
|
|||||||
d.getElementById('rsbtn').style.display = (segCount > 1) ? "inline":"none";
|
d.getElementById('rsbtn').style.display = (segCount > 1) ? "inline":"none";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function btype(b) {
|
||||||
|
switch (b) {
|
||||||
|
case 2:
|
||||||
|
case 32: return "ESP32";
|
||||||
|
case 1:
|
||||||
|
case 82: return "ESP8266";
|
||||||
|
}
|
||||||
|
return "?";
|
||||||
|
}
|
||||||
|
|
||||||
|
function bname(o) {
|
||||||
|
if (o.name=="WLED") return o.ip;
|
||||||
|
return o.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateNodes(i,n)
|
||||||
|
{
|
||||||
|
var cn="";
|
||||||
|
var urows="";
|
||||||
|
var nnodes = 0;
|
||||||
|
if (n.nodes) {
|
||||||
|
n.nodes.sort((a,b) => (a.name).localeCompare(b.name));
|
||||||
|
for (var x=0;x<n.nodes.length;x++) {
|
||||||
|
var o = n.nodes[x];
|
||||||
|
if (o.name) {
|
||||||
|
var url = `<button class="btn btna-icon tab" onclick="location.assign('http://${o.ip}');">${bname(o)}</button>`;
|
||||||
|
urows += inforow(url,`${btype(o.type)}<br><i>${o.vid==0?"N/A":o.vid}</i>`);
|
||||||
|
nnodes++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nnodes == 0) cn += `No other instances found.`;
|
||||||
|
cn += `<table class="infot">${urows}${inforow("Current instance:",i.name)}</table>`;
|
||||||
|
d.getElementById('kn').innerHTML = cn;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadNodes()
|
||||||
|
{
|
||||||
|
var url = loc ? `http://${locip}/json/nodes` : '/json/nodes';
|
||||||
|
fetch(url, {
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
.then(res => {
|
||||||
|
if (!res.ok) {
|
||||||
|
showToast('Could not load Node list!', true);
|
||||||
|
}
|
||||||
|
return res.json();
|
||||||
|
})
|
||||||
|
.then(json => {
|
||||||
|
populateNodes(lastinfo, json);
|
||||||
|
})
|
||||||
|
.catch(function (error) {
|
||||||
|
showToast(error, true);
|
||||||
|
console.log(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function populateEffects()
|
function populateEffects()
|
||||||
{
|
{
|
||||||
var effects = eJson;
|
var effects = eJson;
|
||||||
@ -1060,7 +1088,6 @@ function requestJson(command, rinfo = true, verbose = true, callback = null) {
|
|||||||
pmtLast = pmt;
|
pmtLast = pmt;
|
||||||
lastinfo = info;
|
lastinfo = info;
|
||||||
if (isInfo) populateInfo(info);
|
if (isInfo) populateInfo(info);
|
||||||
populateNodes(info);
|
|
||||||
s = json.state;
|
s = json.state;
|
||||||
displayRover(info, s);
|
displayRover(info, s);
|
||||||
}
|
}
|
||||||
@ -1183,6 +1210,7 @@ function toggleLiveview() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toggleInfo() {
|
function toggleInfo() {
|
||||||
|
if (isNodes) toggleNodes();
|
||||||
isInfo = !isInfo;
|
isInfo = !isInfo;
|
||||||
if (isInfo) populateInfo(lastinfo);
|
if (isInfo) populateInfo(lastinfo);
|
||||||
d.getElementById('info').style.transform = (isInfo) ? "translateY(0px)":"translateY(100%)";
|
d.getElementById('info').style.transform = (isInfo) ? "translateY(0px)":"translateY(100%)";
|
||||||
@ -1190,10 +1218,11 @@ function toggleInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toggleNodes() {
|
function toggleNodes() {
|
||||||
|
if (isInfo) toggleInfo();
|
||||||
isNodes = !isNodes;
|
isNodes = !isNodes;
|
||||||
if (isNodes) populateNodes(lastinfo);
|
if (isNodes) loadNodes();
|
||||||
d.getElementById('nodes').style.transform = (isNodes) ? "translateY(0px)":"translateY(100%)";
|
d.getElementById('nodes').style.transform = (isNodes) ? "translateY(0px)":"translateY(100%)";
|
||||||
d.getElementById('buttonNo').className = (isNodes) ? "active":"";
|
d.getElementById('buttonNodes').className = (isNodes) ? "active":"";
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeSeg() {
|
function makeSeg() {
|
||||||
@ -1815,7 +1844,7 @@ function togglePcMode(fromB = false)
|
|||||||
d.getElementById('buttonPcm').className = (pcMode) ? "active":"";
|
d.getElementById('buttonPcm').className = (pcMode) ? "active":"";
|
||||||
d.getElementById('bot').style.height = (pcMode && !cfg.comp.pcmbot) ? "0":"auto";
|
d.getElementById('bot').style.height = (pcMode && !cfg.comp.pcmbot) ? "0":"auto";
|
||||||
sCol('--bh', d.getElementById('bot').clientHeight + "px");
|
sCol('--bh', d.getElementById('bot').clientHeight + "px");
|
||||||
d.getElementById('buttonNo').style.display = (pcMode) ? "":"none";
|
d.getElementById('buttonNodes').style.display = (pcMode) ? "":"none";
|
||||||
_C.style.width = (pcMode)?'100%':'400%';
|
_C.style.width = (pcMode)?'100%':'400%';
|
||||||
lastw = w;
|
lastw = w;
|
||||||
}
|
}
|
||||||
|
@ -174,7 +174,7 @@ void realtimeLock(uint32_t timeoutMs, byte md = REALTIME_MODE_GENERIC);
|
|||||||
void handleNotifications();
|
void handleNotifications();
|
||||||
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
|
void setRealtimePixel(uint16_t i, byte r, byte g, byte b, byte w);
|
||||||
void refreshNodeList();
|
void refreshNodeList();
|
||||||
void sendSysInfoUDP(uint8_t repeats=1);
|
void sendSysInfoUDP();
|
||||||
|
|
||||||
//um_manager.cpp
|
//um_manager.cpp
|
||||||
class Usermod {
|
class Usermod {
|
||||||
|
4362
wled00/html_ui.h
4362
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -483,6 +483,8 @@ void serializeInfo(JsonObject root)
|
|||||||
fs_info["u"] = fsBytesUsed / 1000;
|
fs_info["u"] = fsBytesUsed / 1000;
|
||||||
fs_info["t"] = fsBytesTotal / 1000;
|
fs_info["t"] = fsBytesTotal / 1000;
|
||||||
fs_info[F("pmt")] = presetsModifiedTime;
|
fs_info[F("pmt")] = presetsModifiedTime;
|
||||||
|
|
||||||
|
root[F("ndc")] = Nodes.size();
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
#ifdef WLED_DEBUG
|
#ifdef WLED_DEBUG
|
||||||
@ -543,26 +545,6 @@ void serializeInfo(JsonObject root)
|
|||||||
root[F("brand")] = "WLED";
|
root[F("brand")] = "WLED";
|
||||||
root[F("product")] = F("FOSS");
|
root[F("product")] = F("FOSS");
|
||||||
root["mac"] = escapedMac;
|
root["mac"] = escapedMac;
|
||||||
|
|
||||||
JsonArray nodes = root.createNestedArray("nodes");
|
|
||||||
IPAddress ip = Network.localIP();
|
|
||||||
for (NodesMap::iterator it = Nodes.begin(); it != Nodes.end(); ++it)
|
|
||||||
{
|
|
||||||
if (it->second.ip[0] != 0)
|
|
||||||
{
|
|
||||||
bool isThisUnit = it->first == ip[3];
|
|
||||||
|
|
||||||
if (isThisUnit) continue;
|
|
||||||
|
|
||||||
JsonObject node = nodes.createNestedObject();
|
|
||||||
node[F("name")] = it->second.nodeName;
|
|
||||||
node[F("type")] = getNodeTypeDisplayString(it->second.nodeType);
|
|
||||||
node[F("ip")] = it->second.ip.toString();
|
|
||||||
node[F("age")] = it->second.age;
|
|
||||||
node[F("build")] = it->second.build;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPaletteColors(JsonArray json, CRGBPalette16 palette)
|
void setPaletteColors(JsonArray json, CRGBPalette16 palette)
|
||||||
@ -727,6 +709,24 @@ void serializePalettes(JsonObject root, AsyncWebServerRequest* request)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void serializeNodes(JsonObject root)
|
||||||
|
{
|
||||||
|
JsonArray nodes = root.createNestedArray("nodes");
|
||||||
|
|
||||||
|
for (NodesMap::iterator it = Nodes.begin(); it != Nodes.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->second.ip[0] != 0)
|
||||||
|
{
|
||||||
|
JsonObject node = nodes.createNestedObject();
|
||||||
|
node[F("name")] = it->second.nodeName;
|
||||||
|
node[F("type")] = it->second.nodeType;
|
||||||
|
node[F("ip")] = it->second.ip.toString();
|
||||||
|
node[F("age")] = it->second.age;
|
||||||
|
node[F("vid")] = it->second.build;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void serveJson(AsyncWebServerRequest* request)
|
void serveJson(AsyncWebServerRequest* request)
|
||||||
{
|
{
|
||||||
byte subJson = 0;
|
byte subJson = 0;
|
||||||
@ -734,7 +734,8 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
if (url.indexOf("state") > 0) subJson = 1;
|
if (url.indexOf("state") > 0) subJson = 1;
|
||||||
else if (url.indexOf("info") > 0) subJson = 2;
|
else if (url.indexOf("info") > 0) subJson = 2;
|
||||||
else if (url.indexOf("si") > 0) subJson = 3;
|
else if (url.indexOf("si") > 0) subJson = 3;
|
||||||
else if (url.indexOf("palx") > 0) subJson = 4;
|
else if (url.indexOf("nodes") > 0) subJson = 4;
|
||||||
|
else if (url.indexOf("palx") > 0) subJson = 5;
|
||||||
else if (url.indexOf("live") > 0) {
|
else if (url.indexOf("live") > 0) {
|
||||||
serveLiveLeds(request);
|
serveLiveLeds(request);
|
||||||
return;
|
return;
|
||||||
@ -761,7 +762,9 @@ void serveJson(AsyncWebServerRequest* request)
|
|||||||
serializeState(doc); break;
|
serializeState(doc); break;
|
||||||
case 2: //info
|
case 2: //info
|
||||||
serializeInfo(doc); break;
|
serializeInfo(doc); break;
|
||||||
case 4: //palettes
|
case 4: //node list
|
||||||
|
serializeNodes(doc); break;
|
||||||
|
case 5: //palettes
|
||||||
serializePalettes(doc, request); break;
|
serializePalettes(doc, request); break;
|
||||||
default: //all
|
default: //all
|
||||||
JsonObject state = doc.createNestedObject("state");
|
JsonObject state = doc.createNestedObject("state");
|
||||||
|
@ -169,9 +169,14 @@ void handleNotifications()
|
|||||||
|
|
||||||
// WLED nodes info notifications
|
// WLED nodes info notifications
|
||||||
if (isSupp && udpIn[0] == 255 && udpIn[1] == 1 && len >= 40) {
|
if (isSupp && udpIn[0] == 255 && udpIn[1] == 1 && len >= 40) {
|
||||||
|
if (notifier2Udp.remoteIP() == Network.localIP()) return;
|
||||||
|
|
||||||
uint8_t unit = udpIn[39];
|
uint8_t unit = udpIn[39];
|
||||||
Nodes[unit].age = 0; // Create a new element when not present
|
|
||||||
NodesMap::iterator it = Nodes.find(unit);
|
NodesMap::iterator it = Nodes.find(unit);
|
||||||
|
if (it == Nodes.end() && Nodes.size() < WLED_MAX_NODES) { // Create a new element when not present
|
||||||
|
Nodes[unit].age = 0;
|
||||||
|
it = Nodes.find(unit);
|
||||||
|
}
|
||||||
|
|
||||||
if (it != Nodes.end()) {
|
if (it != Nodes.end()) {
|
||||||
for (byte x = 0; x < 4; x++) {
|
for (byte x = 0; x < 4; x++) {
|
||||||
@ -188,7 +193,7 @@ void handleNotifications()
|
|||||||
if (len >= 44)
|
if (len >= 44)
|
||||||
for (byte i=0; i<sizeof(uint32_t); i++)
|
for (byte i=0; i<sizeof(uint32_t); i++)
|
||||||
build |= udpIn[40+i]<<(8*i);
|
build |= udpIn[40+i]<<(8*i);
|
||||||
it->second.build = build;
|
it->second.build = build;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -411,11 +416,9 @@ void refreshNodeList()
|
|||||||
/*********************************************************************************************\
|
/*********************************************************************************************\
|
||||||
Broadcast system info to other nodes. (to update node lists)
|
Broadcast system info to other nodes. (to update node lists)
|
||||||
\*********************************************************************************************/
|
\*********************************************************************************************/
|
||||||
void sendSysInfoUDP(uint8_t repeats)
|
void sendSysInfoUDP()
|
||||||
{
|
{
|
||||||
if (!udpConnected || !repeats) {
|
if (!udp2Connected) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
IPAddress ip = Network.localIP();
|
IPAddress ip = Network.localIP();
|
||||||
|
|
||||||
@ -430,60 +433,29 @@ void sendSysInfoUDP(uint8_t repeats)
|
|||||||
// 44 bytes total
|
// 44 bytes total
|
||||||
|
|
||||||
// send my info to the world...
|
// send my info to the world...
|
||||||
for (;repeats--;)
|
uint8_t data[44] = {0};
|
||||||
{
|
data[0] = 255;
|
||||||
/*
|
data[1] = 1;
|
||||||
escapedMac // mac address
|
|
||||||
*/
|
for (byte x = 0; x < 4; x++) {
|
||||||
|
data[x + 2] = ip[x];
|
||||||
uint8_t data[44] = {0};
|
|
||||||
data[0] = 255;
|
|
||||||
data[1] = 1;
|
|
||||||
|
|
||||||
for (byte x = 0; x < 4; x++) {
|
|
||||||
data[x + 2] = ip[x];
|
|
||||||
}
|
|
||||||
memcpy((byte *)data + 6, serverDescription, 32);
|
|
||||||
#ifdef ESP8266
|
|
||||||
data[38] = NODE_TYPE_ID_ESP8266;
|
|
||||||
#elif defined(ARDUINO_ARCH_ESP32)
|
|
||||||
data[38] = NODE_TYPE_ID_ESP32;
|
|
||||||
#else
|
|
||||||
data[38] = NODE_TYPE_ID_UNDEFINED;
|
|
||||||
#endif
|
|
||||||
data[39] = ip[3]; // unit ID == last IP number
|
|
||||||
|
|
||||||
uint32_t build = VERSION;
|
|
||||||
for (byte i=0; i<sizeof(uint32_t); i++)
|
|
||||||
data[40+i] = (build>>(8*i)) & 0xFF;
|
|
||||||
|
|
||||||
IPAddress broadcastIP(255, 255, 255, 255);
|
|
||||||
notifier2Udp.beginPacket(broadcastIP, udpPort2);
|
|
||||||
notifier2Udp.write(data, sizeof(data));
|
|
||||||
notifier2Udp.endPacket();
|
|
||||||
|
|
||||||
if (repeats) delay(500);
|
|
||||||
}
|
}
|
||||||
|
memcpy((byte *)data + 6, serverDescription, 32);
|
||||||
|
#ifdef ESP8266
|
||||||
|
data[38] = NODE_TYPE_ID_ESP8266;
|
||||||
|
#elif defined(ARDUINO_ARCH_ESP32)
|
||||||
|
data[38] = NODE_TYPE_ID_ESP32;
|
||||||
|
#else
|
||||||
|
data[38] = NODE_TYPE_ID_UNDEFINED;
|
||||||
|
#endif
|
||||||
|
data[39] = ip[3]; // unit ID == last IP number
|
||||||
|
|
||||||
Nodes[ip[3]].age = 0; // Create new node when not already present.
|
uint32_t build = VERSION;
|
||||||
// store my own info also in the list
|
for (byte i=0; i<sizeof(uint32_t); i++)
|
||||||
NodesMap::iterator it = Nodes.find(ip[3]);
|
data[40+i] = (build>>(8*i)) & 0xFF;
|
||||||
|
|
||||||
if (it != Nodes.end())
|
IPAddress broadcastIP(255, 255, 255, 255);
|
||||||
{
|
notifier2Udp.beginPacket(broadcastIP, udpPort2);
|
||||||
for (byte x = 0; x < 4; x++) {
|
notifier2Udp.write(data, sizeof(data));
|
||||||
it->second.ip[x] = ip[x];
|
notifier2Udp.endPacket();
|
||||||
}
|
|
||||||
it->second.age = 0;
|
|
||||||
it->second.nodeName = serverDescription;
|
|
||||||
#ifdef ESP8266
|
|
||||||
it->second.nodeType = NODE_TYPE_ID_ESP8266;
|
|
||||||
#elif defined(ARDUINO_ARCH_ESP32)
|
|
||||||
it->second.nodeType = NODE_TYPE_ID_ESP32;
|
|
||||||
#else
|
|
||||||
it->second.nodeType = NODE_TYPE_ID_UNDEFINED;
|
|
||||||
#endif
|
|
||||||
it->second.unit = ip[3];
|
|
||||||
it->second.build = VERSION;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// version code in format yymmddb (b = daily build)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2103091
|
#define VERSION 2103100
|
||||||
|
|
||||||
//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
|
||||||
@ -117,9 +117,9 @@
|
|||||||
#include "FX.h"
|
#include "FX.h"
|
||||||
#include "ir_codes.h"
|
#include "ir_codes.h"
|
||||||
#include "const.h"
|
#include "const.h"
|
||||||
|
#include "NodeStruct.h"
|
||||||
#include "pin_manager.h"
|
#include "pin_manager.h"
|
||||||
#include "bus_manager.h"
|
#include "bus_manager.h"
|
||||||
#include "NodeStruct.h"
|
|
||||||
|
|
||||||
#ifndef CLIENT_SSID
|
#ifndef CLIENT_SSID
|
||||||
#define CLIENT_SSID DEFAULT_CLIENT_SSID
|
#define CLIENT_SSID DEFAULT_CLIENT_SSID
|
||||||
|
Loading…
Reference in New Issue
Block a user