Merge remote-tracking branch 'origin/ac_main' into mdev
This commit is contained in:
@@ -522,7 +522,7 @@ function loadFXData(callback = null)
|
||||
fxdata = json||[];
|
||||
// add default value for Solid
|
||||
fxdata.shift()
|
||||
fxdata.unshift("@;!;0");
|
||||
fxdata.unshift(";!;0");
|
||||
})
|
||||
.catch((e)=>{
|
||||
fxdata = [];
|
||||
@@ -658,7 +658,7 @@ function populateInfo(i)
|
||||
}
|
||||
var vcn = "Kuuhaku";
|
||||
if (i.ver.startsWith("0.14.")) vcn = "Hoshi";
|
||||
if (i.ver.includes("-bl")) vcn = "Supāku";
|
||||
// if (i.ver.includes("-bl")) vcn = "Supāku";
|
||||
if (i.cn) vcn = i.cn;
|
||||
|
||||
//WLEDMM: add total heap and total PSRAM, and build number, add bin name
|
||||
@@ -667,6 +667,7 @@ function populateInfo(i)
|
||||
cn += `v${i.ver} <i>"${vcn}"</i><p>(WLEDMM_${i.ver}_${i.rel}.bin)</p><p><em>build ${i.vid}</em></p><table>
|
||||
${urows}
|
||||
${urows===""?'':'<tr><td colspan=2><hr style="height:1px;border-width:0;color:gray;background-color:gray"></td></tr>'}
|
||||
${i.opt&0x100?inforow("Debug","<button class=\"btn btn-xs\" onclick=\"requestJson({'debug':"+(i.opt&0x0080?"false":"true")+"});\"><i class=\"icons "+(i.opt&0x0080?"on":"off")+"\"></i></button>"):''}
|
||||
${inforow("Build",i.vid)}
|
||||
${inforow("Signal strength",i.wifi.signal +"% ("+ i.wifi.rssi, " dBm)")}
|
||||
${inforow("Uptime",getRuntimeStr(i.uptime))}
|
||||
@@ -861,7 +862,7 @@ function populateEffects()
|
||||
if (ef.name.indexOf("RSVD") < 0) {
|
||||
if (Array.isArray(fxdata) && fxdata.length>id) {
|
||||
if (fxdata[id].length==0) fd = ";;!;1d"
|
||||
else fd = fxdata[id].substr(1);
|
||||
else fd = fxdata[id];
|
||||
let eP = (fd == '')?[]:fd.split(";"); // effect parameters
|
||||
let p = (eP.length<3 || eP[2]==='')?[]:eP[2].split(","); // palette data
|
||||
if (p.length>0 && (p[0] !== "" && !isNumeric(p[0]))) nm += "🎨"; // effects using palette
|
||||
@@ -1390,38 +1391,30 @@ function readState(s,command=false)
|
||||
function setEffectParameters(idx)
|
||||
{
|
||||
if (!(Array.isArray(fxdata) && fxdata.length>idx)) return;
|
||||
var controlDefined = (fxdata[idx].substr(0,1) == "@");
|
||||
var effectPar = fxdata[idx].substr(1);
|
||||
var controlDefined = fxdata[idx].length;
|
||||
var effectPar = fxdata[idx];
|
||||
var effectPars = (effectPar == '')?[]:effectPar.split(";");
|
||||
var slOnOff = (effectPars.length==0 || effectPars[0]=='')?[]:effectPars[0].split(",");
|
||||
var coOnOff = (effectPars.length<2 || effectPars[1]=='')?[]:effectPars[1].split(",");
|
||||
var paOnOff = (effectPars.length<3 || effectPars[2]=='')?[]:effectPars[2].split(",");
|
||||
|
||||
// set html slider items on/off
|
||||
//var nSliders = Math.min(7,Math.floor(gId("sliders").children.length)); // div for each slider + filter + options
|
||||
let nSliders = 5;
|
||||
var sldCnt = 0;
|
||||
for (let i=0; i<nSliders; i++) {
|
||||
var slider = gId("slider" + i);
|
||||
var label = gId("sliderLabel" + i);
|
||||
// if (not controlDefined and for AC speed or intensity and for SR alle sliders) or slider has a value
|
||||
// if (not controlDefined and for AC speed or intensity and for SR all sliders) or slider has a value
|
||||
if ((!controlDefined && i < ((idx<128)?2:nSliders)) || (slOnOff.length>i && slOnOff[i] != "")) {
|
||||
//if (slOnOff.length>i && slOnOff[i].indexOf("=")>0) {
|
||||
// // embeded default values
|
||||
// var dPos = slOnOff[i].indexOf("=");
|
||||
// slOnOff[i] = slOnOff[i].substring(0,dPos);
|
||||
//}
|
||||
if (slOnOff.length>i && slOnOff[i]!="!") label.innerHTML = slOnOff[i];
|
||||
else if (i==0) label.innerHTML = "Effect speed";
|
||||
else if (i==1) label.innerHTML = "Effect intensity";
|
||||
else label.innerHTML = "Custom" + (i-1);
|
||||
sldCnt++;
|
||||
slider.classList.remove("hide");
|
||||
} else {
|
||||
slider.classList.add("hide");
|
||||
}
|
||||
}
|
||||
if (slOnOff.length>5) {
|
||||
if (slOnOff.length>5) { // up to 3 checkboxes
|
||||
gId('fxopt').classList.remove('fade');
|
||||
for (let i = 0; i<3; i++) {
|
||||
if (5+i<slOnOff.length && slOnOff[5+i]!=='') {
|
||||
@@ -1465,7 +1458,7 @@ function setEffectParameters(idx)
|
||||
hide = false;
|
||||
if (!cslCnt || oCsel==i) selectSlot(i); // select 1st displayed slot or old one
|
||||
cslCnt++;
|
||||
} else if (!controlDefined /*|| paOnOff.length>0*/) { // if no controls then all buttons should be shown for color 1..3
|
||||
} else if (!controlDefined) { // if no controls then all buttons should be shown for color 1..3
|
||||
btn.style.display = "inline";
|
||||
btn.innerHTML = `${i+1}`;
|
||||
hide = false;
|
||||
@@ -1492,13 +1485,16 @@ function setEffectParameters(idx)
|
||||
if (paOnOff.length>0 && paOnOff[0] != "!") pall.innerHTML = paOnOff[0];
|
||||
else pall.innerHTML = '<i class="icons sel-icon" onclick="tglHex()"></i> Color palette';
|
||||
} else {
|
||||
// disable palett list
|
||||
// disable palette list
|
||||
pall.innerHTML = '<i class="icons sel-icon" onclick="tglHex()"></i> Color palette not used';
|
||||
palw.style.display = "none";
|
||||
}
|
||||
// not all color selectors shown, hide palettes created from color selectors
|
||||
for (let e of (gId('pallist').querySelectorAll('.lstI')||[])) {
|
||||
if (cslCnt < 3 && e.querySelector('.lstIname').innerText.indexOf("* C")>=0) e.classList.add('hide'); else e.classList.remove('hide');
|
||||
let fltr = "* C";
|
||||
if (cslCnt==1 && csel==0) fltr = "* Colors";
|
||||
else if (cslCnt==2) fltr = "* Colors Only";
|
||||
if (cslCnt < 3 && e.querySelector('.lstIname').innerText.indexOf(fltr)>=0) e.classList.add('hide'); else e.classList.remove('hide');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
function addPanel(i=0) {
|
||||
let p = gId("panels");
|
||||
if (p.children.length >= maxPanels) return;
|
||||
let b = `<div id="pnl${i}">${i===0?"":'<hr style="width:260px">'}Panel ${i}<br>1<sup>st</sup> LED: <select name="P${i}B">
|
||||
let b = `<div id="pnl${i}">${i===0?"":'<hr class="sml">'}Panel ${i}<br>1<sup>st</sup> LED: <select name="P${i}B">
|
||||
<option value="0">Top</option>
|
||||
<option value="1">Bottom</option>
|
||||
</select><select name="P${i}R">
|
||||
@@ -134,11 +134,11 @@ Serpentine: <input type="checkbox" name="P${i}S"></div>`;
|
||||
<option value="1">Vertical</option>
|
||||
</select><br>
|
||||
Serpentine: <input type="checkbox" name="PS">
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
<i>A matrix is made of 1 or more physical LED panels of the same dimensions.<br>
|
||||
Panels should be arranged from top-left to bottom-right order, starting with lower panel number on the left (or top if transposed).<br>
|
||||
Each panel can have different LED orientation and/or starting point and/or layout.</i><br>
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
<h3>LED panel layout</h3>
|
||||
<div id="panels">
|
||||
</div>
|
||||
|
||||
@@ -323,7 +323,7 @@
|
||||
if (n==1) {
|
||||
// npm run build has trouble minimizing spaces inside string
|
||||
var cn = `<div class="iST">
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
${i+1}:
|
||||
<select name="LT${i}" onchange="UI(true)">
|
||||
<option value="22" selected>WS281x</option>
|
||||
@@ -389,7 +389,7 @@ ${i+1}:
|
||||
if (i >= 10) return;
|
||||
|
||||
var b = `<div class="com_entry">
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
${i+1}: Start: <input type="number" name="XS${i}" id="xs${i}" class="l starts" min="0" max="65535" value="${start}" oninput="UI();" required="">
|
||||
Length: <input type="number" name="XC${i}" id="xc${i}" class="l" min="1" max="65535" value="${len}" required="" oninput="UI()">
|
||||
<div style="display:inline">Color Order:
|
||||
@@ -595,7 +595,7 @@ Length: <input type="number" name="XC${i}" id="xc${i}" class="l" min="1" max="65
|
||||
</div>
|
||||
<h3>Hardware setup</h3>
|
||||
<div id="mLC">LED outputs:</div>
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
<button type="button" id="+" onclick="addLEDs(1,false)">+</button>
|
||||
<button type="button" id="-" onclick="addLEDs(-1,false)">-</button><br>
|
||||
LED Memory Usage: <span id="m0">0</span> / <span id="m1">?</span> B<br>
|
||||
@@ -604,19 +604,19 @@ Length: <input type="number" name="XC${i}" id="xc${i}" class="l" min="1" max="65
|
||||
⚠ You might run into stability or lag issues.<br>
|
||||
Use less than <span id="wreason">800 LEDs per output</span> for the best experience!<br>
|
||||
</div>
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
Make a segment for each output: <input type="checkbox" name="MS"><br>
|
||||
Custom bus start indices: <input type="checkbox" onchange="tglSi(this.checked)" id="si"><br>
|
||||
Use global LED buffer: <input type="checkbox" name="LD"><br>
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
<div id="color_order_mapping">
|
||||
Color Order Override:
|
||||
<div id="com_entries"></div>
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
<button type="button" id="com_add" onclick="addCOM()">+</button>
|
||||
<button type="button" id="com_rem" onclick="remCOM()">-</button><br>
|
||||
</div>
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
<div id="btns"></div>
|
||||
Touch threshold: <input type="number" class="s" min="0" max="100" name="TT" required><br>
|
||||
<div id="irOnOff2">
|
||||
@@ -637,7 +637,7 @@ Length: <input type="number" name="XC${i}" id="xc${i}" class="l" min="1" max="65
|
||||
<div id="json" style="display:none;">JSON file: <input type="file" name="data" accept=".json"><button type="button" class="sml" onclick="uploadFile('/ir.json')">Upload</button><br></div>
|
||||
<a href="https://kno.wled.ge/interfaces/infrared/" target="_blank">IR info</a><br>
|
||||
Relay GPIO: <input type="number" min="-1" max="48" name="RL" onchange="UI()" class="xs"> Invert <input type="checkbox" name="RM"><span style="cursor: pointer;" onclick="off('RL')"> ✕</span><br>
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
<h3>Defaults</h3>
|
||||
Turn LEDs on after power up/reset: <input type="checkbox" name="BO"><br>
|
||||
Default brightness: <input name="CA" type="number" class="m" min="0" max="255" required> (0-255)<br><br>
|
||||
@@ -683,7 +683,7 @@ Length: <input type="number" name="XC${i}" id="xc${i}" class="l" min="1" max="65
|
||||
<option value="3">None (not recommended)</option>
|
||||
</select><br>
|
||||
Target refresh rate: <input type="number" class="s" min="1" max="120" name="FR" required> FPS
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
<div id="cfg">Config template: <input type="file" name="data2" accept=".json"><button type="button" class="sml" onclick="loadCfg(d.Sf.data2)">Apply</button><br></div>
|
||||
<hr>
|
||||
<button type="button" onclick="B()">Back</button><button type="submit">Save</button>
|
||||
|
||||
@@ -7,22 +7,8 @@
|
||||
<title>Sync Settings</title>
|
||||
<script>var d=document;
|
||||
var loc = false, locip;
|
||||
function gId(s)
|
||||
{
|
||||
return d.getElementById(s);
|
||||
}
|
||||
|
||||
function hideNoDMX(){gId("dmxOnOff2").style.display="none";}
|
||||
function hideALEXA(){gId("aleOnOff").style.display="none";}
|
||||
function hideNoALEXA(){gId("aleOnOff2").style.display="none";}
|
||||
function hideBLYNK(){gId("blyOnOff").style.display="none";}
|
||||
function hideNoBLYNK(){gId("blyOnOff2").style.display="none";}
|
||||
function hideMQTT(){gId("mqtOnOff").style.display="none";}
|
||||
function hideNoMQTT(){gId("mqtOnOff2").style.display="none";}
|
||||
function hideHUE(){gId("hueOnOff").style.display="none";}
|
||||
function hideNoHUE(){gId("hueOnOff2").style.display="none";}
|
||||
function hideNoLOX(){gId("loxOnOff2").style.display="none";}
|
||||
|
||||
function gId(s){return d.getElementById(s);}
|
||||
function toggle(el){gId(el).classList.toggle("hide"); gId('No'+el).classList.toggle("hide");}
|
||||
function H(){window.open("https://kno.wled.ge/interfaces/udp-notifier/");}
|
||||
function B(){window.open("/settings","_self");}
|
||||
function adj(){if (d.Sf.DI.value == 6454) {if (d.Sf.EU.value == 1) d.Sf.EU.value = 0;}
|
||||
@@ -93,11 +79,11 @@
|
||||
<h2>Sync setup</h2>
|
||||
<h3>WLED Broadcast</h3>
|
||||
UDP Port: <input name="UP" type="number" min="1" max="65535" class="d5" required><br>
|
||||
2nd Port: <input name="U2" type="number" min="1" max="65535" class="d5" required><br><br>
|
||||
<input name="GS" id="GS" type="number" style="display: none;"> <!-- hidden inputs for bitwise group checkboxes -->
|
||||
2nd Port: <input name="U2" type="number" min="1" max="65535" class="d5" required><br>
|
||||
<h3>Sync grups</h3>
|
||||
<input name="GS" id="GS" type="number" style="display: none;"><!-- hidden inputs for bitwise group checkboxes -->
|
||||
<input name="GR" id="GR" type="number" style="display: none;">
|
||||
<table style="margin: 0 auto;">
|
||||
<tr><td colspan="9" style="text-align:center">Sync groups</td></tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>1</td>
|
||||
@@ -141,9 +127,11 @@ Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
||||
Send Macro notifications: <input type="checkbox" name="SM"><br>
|
||||
UDP packet retransmissions: <input name="UR" type="number" min="0" max="30" class="d5" required><br><br>
|
||||
<i>Reboot required to apply changes. </i>
|
||||
<hr class="sml">
|
||||
<h3>Instance List</h3>
|
||||
Enable instance list: <input type="checkbox" name="NL"><br>
|
||||
Make this instance discoverable: <input type="checkbox" name="NB">
|
||||
<hr class="sml">
|
||||
<h3>Realtime</h3>
|
||||
Receive UDP realtime: <input type="checkbox" name="RD"><br>
|
||||
Use main segment only: <input type="checkbox" name="MO"><br><br>
|
||||
@@ -175,37 +163,38 @@ Timeout: <input name="ET" type="number" min="1" max="65000" required> ms<br>
|
||||
Force max brightness: <input type="checkbox" name="FB"><br>
|
||||
Disable realtime gamma correction: <input type="checkbox" name="RG"><br>
|
||||
Realtime LED offset: <input name="WO" type="number" min="-255" max="255" required>
|
||||
<div id="dmxOnOff2">
|
||||
<br><em style="color:darkorange">This firmware build does not include DMX output support. <br></em>
|
||||
</div>
|
||||
<hr class="sml">
|
||||
<h3>Alexa Voice Assistant</h3>
|
||||
<div id="aleOnOff2">
|
||||
<em style="color:darkorange">This firmware build does not include Alexa support. <br></em>
|
||||
<div id="NoAlexa" class="hide">
|
||||
<em style="color:#fa0;">This firmware build does not include Alexa support.<br></em><br>
|
||||
</div>
|
||||
<div id="aleOnOff">
|
||||
<div id="Alexa">
|
||||
Emulate Alexa device: <input type="checkbox" name="AL"><br>
|
||||
Alexa invocation name: <input type="text" name="AI" maxlength="32"><br>
|
||||
Also emulate devices to call the first <input name="AP" type="number" class="s" min="0" max="9" required> presets
|
||||
Also emulate devices to call the first <input name="AP" type="number" class="s" min="0" max="9" required> presets<br><br>
|
||||
</div>
|
||||
<h3>Blynk</h3>
|
||||
<div id="blyOnOff2">
|
||||
<em style="color:darkorange">This firmware build does not include Blynk support. <br></em>
|
||||
<hr class="sml">
|
||||
<div style="color: #fa0;">⚠ <b>Blynk, MQTT and Hue sync all connect to external hosts!<br>
|
||||
This may impact the responsiveness of WLED.</b><br>
|
||||
</div>
|
||||
<b>Blynk, MQTT and Hue sync all connect to external hosts!<br>
|
||||
This may impact the responsiveness of the ESP8266.</b><br>
|
||||
For best results, only use one of these services at a time.<br>
|
||||
(alternatively, connect a second ESP to them and use the UDP sync)<br><br>
|
||||
<div id="blyOnOff">
|
||||
(alternatively, connect a second ESP to them and use the UDP sync)
|
||||
<hr class="sml">
|
||||
<h3>Blynk</h3>
|
||||
<div id="NoBlynk" class="hide">
|
||||
<em style="color:#fa0;">This firmware build does not include Blynk support.<br></em>
|
||||
</div>
|
||||
<div id="Blynk">
|
||||
Host: <input type="text" name="BH" maxlength="32">
|
||||
Port: <input name="BP" type="number" min="1" max="65535" value="80" class="d5"><br>
|
||||
Device Auth token: <input name="BK" maxlength="33"><br>
|
||||
<i>Clear the token field to disable. </i><a href="https://kno.wled.ge/interfaces/blynk/" target="_blank">Setup info</a>
|
||||
</div>
|
||||
<h3>MQTT</h3>
|
||||
<div id="mqtOnOff2">
|
||||
<em style="color:darkorange">This firmware build does not include MQTT support. <br></em>
|
||||
<div id="NoMQTT" class="hide">
|
||||
<em style="color:#fa0;">This firmware build does not include MQTT support.<br></em>
|
||||
</div>
|
||||
<div id="mqtOnOff">
|
||||
<div id="MQTT">
|
||||
Enable MQTT: <input type="checkbox" name="MQ"><br>
|
||||
Broker: <input type="text" name="MS" maxlength="32">
|
||||
Port: <input name="MQPORT" type="number" min="1" max="65535" class="d5"><br>
|
||||
@@ -220,10 +209,10 @@ Publish on button press: <input type="checkbox" name="BM"><br>
|
||||
<i>Reboot required to apply changes. </i><a href="https://kno.wled.ge/interfaces/mqtt/" target="_blank">MQTT info</a>
|
||||
</div>
|
||||
<h3>Philips Hue</h3>
|
||||
<div id="hueOnOff2">
|
||||
<em style="color:darkorange">This firmware build does not include Philips Hue support. <br></em>
|
||||
<div id="NoHue" class="hide">
|
||||
<em style="color:#fa0;">This firmware build does not include Philips Hue support.<br></em>
|
||||
</div>
|
||||
<div id="hueOnOff">
|
||||
<div id="Hue">
|
||||
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
||||
Poll Hue light <input name="HL" type="number" min="1" max="99" > every <input name="HI" type="number" min="100" max="65000"> ms: <input type="checkbox" name="HP"><br>
|
||||
Then, receive <input type="checkbox" name="HO"> On/Off, <input type="checkbox" name="HB"> Brightness, and <input type="checkbox" name="HC"> Color<br>
|
||||
@@ -236,8 +225,6 @@ Hue Bridge IP:<br>
|
||||
(when first connecting)<br>
|
||||
</div>
|
||||
Hue status: <span class="sip"> Disabled in this build </span>
|
||||
<div id="loxOnOff2">
|
||||
<br><em style="color:darkorange">This firmware build does not include Loxone Lighting support. <br></em>
|
||||
</div>
|
||||
<h3>Serial</h3>
|
||||
Baud rate:
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
}
|
||||
function addField(k,f,o,a=false) { //key, field, (sub)object, isArray
|
||||
if (isO(o)) {
|
||||
urows += '<hr style="width:260px">';
|
||||
urows += '<hr class="sml">';
|
||||
for (const [s,v] of Object.entries(o)) {
|
||||
// possibility to nest objects (only 1 level)
|
||||
if (f!=='unknown' && !k.includes(":")) addField(k+":"+f,s,v);
|
||||
@@ -249,7 +249,7 @@
|
||||
<i style="color: orange;">(only changable on ESP32, change requires reboot!)</i><br>
|
||||
SDA:<input type="number" min="-1" max="48" name="SDA" onchange="check(this,'if')" class="s" placeholder="SDA">
|
||||
SCL:<input type="number" min="-1" max="48" name="SCL" onchange="check(this,'if')" class="s" placeholder="SCL">
|
||||
<hr style="width:260px">
|
||||
<hr class="sml">
|
||||
Global SPI GPIOs (HW)<br>
|
||||
<i style="color: orange;">(only changable on ESP32, change requires reboot!)</i><br>
|
||||
MOSI:<input type="number" min="-1" max="48" name="MOSI" onchange="check(this,'if')" class="s" placeholder="MOSI">
|
||||
|
||||
@@ -13,6 +13,9 @@ body {
|
||||
hr {
|
||||
border-color: #666;
|
||||
}
|
||||
hr.sml {
|
||||
width: 260px;
|
||||
}
|
||||
a, a:hover {
|
||||
color: #28f;
|
||||
text-decoration: none;
|
||||
@@ -52,6 +55,9 @@ button.sml {
|
||||
position: absolute;
|
||||
width: 60px;
|
||||
}
|
||||
.hide {
|
||||
display: none;
|
||||
}
|
||||
input {
|
||||
background: #333;
|
||||
color: #fff;
|
||||
|
||||
Reference in New Issue
Block a user