Sync segment options.
Freeze effect. Repeat last segment until end.
This commit is contained in:
parent
c27117e99e
commit
1270f2d577
@ -239,8 +239,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
|
||||
CJSON(receiveNotificationColor, if_sync_recv["col"]);
|
||||
CJSON(receiveNotificationEffects, if_sync_recv["fx"]);
|
||||
CJSON(receiveGroups, if_sync_recv["grp"]);
|
||||
CJSON(receiveSegmentOptions, if_sync_recv["seg"]);
|
||||
//! following line might be a problem if called after boot
|
||||
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
||||
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects || receiveSegmentOptions);
|
||||
|
||||
JsonObject if_sync_send = if_sync["send"];
|
||||
prev = notifyDirectDefault;
|
||||
@ -628,6 +629,7 @@ void serializeConfig() {
|
||||
if_sync_recv["col"] = receiveNotificationColor;
|
||||
if_sync_recv["fx"] = receiveNotificationEffects;
|
||||
if_sync_recv["grp"] = receiveGroups;
|
||||
if_sync_recv["seg"] = receiveSegmentOptions;
|
||||
|
||||
JsonObject if_sync_send = if_sync.createNestedObject("send");
|
||||
if_sync_send[F("dir")] = notifyDirect;
|
||||
|
@ -609,11 +609,12 @@ input[type=range]:active + .sliderbubble {
|
||||
width: 216px;
|
||||
}
|
||||
.btn-xs {
|
||||
width: 39px;
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
margin: 2px 0 0 0;
|
||||
}
|
||||
.btn-pl-add {
|
||||
margin-left: 9px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
|
||||
@ -645,7 +646,7 @@ input[type=range]:active + .sliderbubble {
|
||||
.sel-pl {
|
||||
width: 192px;
|
||||
background-position: 168px 16px;
|
||||
margin: 8px 7px 0 0;
|
||||
margin: 8px 3px 0 0;
|
||||
}
|
||||
|
||||
.sel-ple {
|
||||
|
@ -141,7 +141,7 @@
|
||||
<div id="Effects" class="tabcontent">
|
||||
<p class="labels">Effect speed</p>
|
||||
<div class="staytop">
|
||||
<i class="icons slider-icon"></i>
|
||||
<i class="icons slider-icon" onclick="tglFreeze()"></i>
|
||||
<div class="sliderwrap il">
|
||||
<input id="sliderSpeed" class="noslide" onchange="setSpeed()" oninput="updateTrail(this)" max="255" min="0" type="range" value="128" />
|
||||
<output class="sliderbubble hidden"></output>
|
||||
|
@ -603,7 +603,6 @@ function populateSegments(s)
|
||||
</tr>
|
||||
</table>
|
||||
<div class="h" id="seg${i}len"></div>
|
||||
<button class="btn btn-i btn-xs del" id="segd${i}" onclick="delSeg(${i})"><i class="icons btn-icon"></i></button>
|
||||
<label class="check revchkl">
|
||||
Reverse direction
|
||||
<input type="checkbox" id="seg${i}rev" onchange="setRev(${i})" ${inst.rev ? "checked":""}>
|
||||
@ -614,6 +613,10 @@ function populateSegments(s)
|
||||
<input type="checkbox" id="seg${i}mi" onchange="setMi(${i})" ${inst.mi ? "checked":""}>
|
||||
<span class="checkmark schk"></span>
|
||||
</label>
|
||||
<div class="del">
|
||||
<button class="btn btn-i btn-xs" id="segr${i}" title="Repeat until end" onclick="rptSeg(${i})"><i class="icons btn-icon"></i></button>
|
||||
<button class="btn btn-i btn-xs" id="segd${i}" title="Delete" onclick="delSeg(${i})"><i class="icons btn-icon"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div><br>`;
|
||||
}
|
||||
@ -629,8 +632,10 @@ function populateSegments(s)
|
||||
for (var i = 0; i <= lSeg; i++) {
|
||||
updateLen(i);
|
||||
updateTrail(d.getElementById(`seg${i}bri`));
|
||||
if (segCount < 2) d.getElementById(`segd${lSeg}`).style.display = "none";
|
||||
d.getElementById(`segr${i}`).style.display = "none";
|
||||
}
|
||||
if (segCount < 2) d.getElementById(`segd${lSeg}`).style.display = "none";
|
||||
if (!noNewSegs && (cfg.comp.seglen?parseInt(d.getElementById(`seg${lSeg}s`).value):0)+parseInt(d.getElementById(`seg${lSeg}e`).value)<ledCount) d.getElementById(`segr${lSeg}`).style.display = "inline";
|
||||
d.getElementById('rsbtn').style.display = (segCount > 1) ? "inline":"none";
|
||||
}
|
||||
|
||||
@ -1542,6 +1547,13 @@ function setSegBri(s){
|
||||
requestJson(obj);
|
||||
}
|
||||
|
||||
function tglFreeze(s=null)
|
||||
{
|
||||
var obj = {"seg": {"frz": "t"}}; // toggle
|
||||
if (s!==null) obj.id = s;
|
||||
requestJson(obj);
|
||||
}
|
||||
|
||||
function setX(ind = null) {
|
||||
if (ind === null) {
|
||||
ind = parseInt(d.querySelector('#fxlist input[name="fx"]:checked').value);
|
||||
|
@ -5,7 +5,8 @@ function gId(s)
|
||||
{
|
||||
return d.getElementById(s);
|
||||
}
|
||||
function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings");}function B(){window.open("/settings","_self");}
|
||||
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.DA.value == 1) d.Sf.DA.value = 0; if (d.Sf.EU.value == 1) d.Sf.EU.value = 0;}
|
||||
else if (d.Sf.DI.value == 5568) {if (d.Sf.DA.value == 0) d.Sf.DA.value = 1; if (d.Sf.EU.value == 0) d.Sf.EU.value = 1;} }
|
||||
function FC()
|
||||
@ -82,6 +83,7 @@ UDP Port: <input name="UP" type="number" min="1" max="65535" class="d5" required
|
||||
</tr>
|
||||
</table><br>
|
||||
Receive: <input type="checkbox" name="RB">Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox" name="RX">Effects<br>
|
||||
<input type="checkbox" name="SO">Segment options<br>
|
||||
Send notifications on direct change: <input type="checkbox" name="SD"><br>
|
||||
Send notifications on button press or IR: <input type="checkbox" name="SB"><br>
|
||||
Send Alexa notifications: <input type="checkbox" name="SA"><br>
|
||||
@ -117,45 +119,45 @@ DMX mode:
|
||||
<option value=5>Dimmer + Multi RGB</option>
|
||||
<option value=6>Multi RGBW</option>
|
||||
</select><br>
|
||||
<a href="https://github.com/Aircoookie/WLED/wiki/E1.31-DMX" target="_blank">E1.31 info</a><br>
|
||||
<a href="https://kno.wled.ge/interfaces/e1.31-dmx/" target="_blank">E1.31 info</a><br>
|
||||
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>
|
||||
<h3>Alexa Voice Assistant</h3>
|
||||
Emulate Alexa device: <input type="checkbox" name="AL"><br>
|
||||
Alexa invocation name: <input name="AI" maxlength="32">
|
||||
Alexa invocation name: <input type="text" name="AI" maxlength="32">
|
||||
<h3>Blynk</h3>
|
||||
<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>
|
||||
Host: <input name="BH" maxlength="32">
|
||||
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://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info</a>
|
||||
<i>Clear the token field to disable. </i><a href="https://kno.wled.ge/interfaces/blynk/" target="_blank">Setup info</a>
|
||||
<h3>MQTT</h3>
|
||||
Enable MQTT: <input type="checkbox" name="MQ"><br>
|
||||
Broker: <input name="MS" maxlength="32">
|
||||
Broker: <input type="text" name="MS" maxlength="32">
|
||||
Port: <input name="MQPORT" type="number" min="1" max="65535" class="d5"><br>
|
||||
<b>The MQTT credentials are sent over an unsecured connection.<br>
|
||||
Never use the MQTT password for another service!</b><br>
|
||||
Username: <input name="MQUSER" maxlength="40"><br>
|
||||
Username: <input type="text" name="MQUSER" maxlength="40"><br>
|
||||
Password: <input type="password" name="MQPASS" maxlength="64"><br>
|
||||
Client ID: <input name="MQCID" maxlength="40"><br>
|
||||
Device Topic: <input name="MD" maxlength="32"><br>
|
||||
Group Topic: <input name="MG" maxlength="32"><br>
|
||||
Client ID: <input type="text" name="MQCID" maxlength="40"><br>
|
||||
Device Topic: <input type="text" name="MD" maxlength="32"><br>
|
||||
Group Topic: <input type="text" name="MG" maxlength="32"><br>
|
||||
Publish on button press: <input type="checkbox" name="BM"><br>
|
||||
<i>Reboot required to apply changes. </i><a href="https://github.com/Aircoookie/WLED/wiki/MQTT" target="_blank">MQTT info</a>
|
||||
<i>Reboot required to apply changes. </i><a href="https://kno.wled.ge/interfaces/mqtt/" target="_blank">MQTT info</a>
|
||||
<h3>Philips Hue</h3>
|
||||
<i>You can find the bridge IP and the light number in the 'About' section of the hue app.</i><br>
|
||||
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>
|
||||
Hue Bridge IP:<br>
|
||||
<input name="H0" type="number" min="0" max="255" > .
|
||||
<input name="H1" type="number" min="0" max="255" > .
|
||||
<input name="H2" type="number" min="0" max="255" > .
|
||||
<input name="H3" type="number" min="0" max="255" ><br>
|
||||
<input name="H0" type="number" class="s" min="0" max="255" > .
|
||||
<input name="H1" type="number" class="s" min="0" max="255" > .
|
||||
<input name="H2" type="number" class="s" min="0" max="255" > .
|
||||
<input name="H3" type="number" class="s" min="0" max="255" ><br>
|
||||
<b>Press the pushlink button on the bridge, after that save this page!</b><br>
|
||||
(when first connecting)<br>
|
||||
Hue status: <span class="sip"> Disabled in this build </span><hr>
|
||||
|
@ -244,7 +244,7 @@ type="button" onclick="Save()">Save</button></form></body></html>)=====";
|
||||
// Autogenerated from wled00/data/settings_sync.htm, do not edit!!
|
||||
const char PAGE_settings_sync[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=500">
|
||||
<meta charset="utf-8"><title>Sync Settings</title><script>
|
||||
var d=document;function gId(e){return d.getElementById(e)}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#sync-settings")}function B(){window.open("/settings","_self")}function adj(){6454==d.Sf.DI.value?(1==d.Sf.DA.value&&(d.Sf.DA.value=0),1==d.Sf.EU.value&&(d.Sf.EU.value=0)):5568==d.Sf.DI.value&&(0==d.Sf.DA.value&&(d.Sf.DA.value=1),0==d.Sf.EU.value&&(d.Sf.EU.value=1))}function FC(){for(j=0;j<8;j++)gId("G"+(j+1)).checked=gId("GS").value>>j&1,gId("R"+(j+1)).checked=gId("GR").value>>j&1}function GC(){var e=0,d=0,n=1;for(j=0;j<8;j++)e+=gId("G"+(j+1)).checked*n,d+=gId("R"+(j+1)).checked*n,n*=2;gId("GS").value=e,gId("GR").value=d}function SP(){var e=d.Sf.DI.value;gId("xp").style.display=e>0?"none":"block",e>0&&(d.Sf.EP.value=e)}function SetVal(){switch(parseInt(d.Sf.EP.value)){case 5568:d.Sf.DI.value=5568;break;case 6454:d.Sf.DI.value=6454;break;case 4048:d.Sf.DI.value=4048}SP(),FC()}function S(){GetV(),SetVal()}function GetV() {
|
||||
var d=document;function gId(e){return d.getElementById(e)}function H(){window.open("https://kno.wled.ge/interfaces/udp-notifier/")}function B(){window.open("/settings","_self")}function adj(){6454==d.Sf.DI.value?(1==d.Sf.DA.value&&(d.Sf.DA.value=0),1==d.Sf.EU.value&&(d.Sf.EU.value=0)):5568==d.Sf.DI.value&&(0==d.Sf.DA.value&&(d.Sf.DA.value=1),0==d.Sf.EU.value&&(d.Sf.EU.value=1))}function FC(){for(j=0;j<8;j++)gId("G"+(j+1)).checked=gId("GS").value>>j&1,gId("R"+(j+1)).checked=gId("GR").value>>j&1}function GC(){var e=0,d=0,n=1;for(j=0;j<8;j++)e+=gId("G"+(j+1)).checked*n,d+=gId("R"+(j+1)).checked*n,n*=2;gId("GS").value=e,gId("GR").value=d}function SP(){var e=d.Sf.DI.value;gId("xp").style.display=e>0?"none":"block",e>0&&(d.Sf.EP.value=e)}function SetVal(){switch(parseInt(d.Sf.EP.value)){case 5568:d.Sf.DI.value=5568;break;case 6454:d.Sf.DI.value=6454;break;case 4048:d.Sf.DI.value=4048}SP(),FC()}function S(){GetV(),SetVal()}function GetV() {
|
||||
%CSS%%SCSS%</head><body onload="S()"><form
|
||||
id="form_s" name="Sf" method="post" onsubmit="GC()"><div class="helpB"><button
|
||||
type="button" onclick="H()">?</button></div><button type="button" onclick="B()">
|
||||
@ -268,11 +268,12 @@ name="R5"></td><td><input type="checkbox" id="R6" name="R6"></td><td><input
|
||||
type="checkbox" id="R7" name="R7"></td><td><input type="checkbox" id="R8"
|
||||
name="R8"></td></tr></table><br>Receive: <input type="checkbox" name="RB">
|
||||
Brightness, <input type="checkbox" name="RC">Color, and <input type="checkbox"
|
||||
name="RX">Effects<br>Send notifications on direct change: <input
|
||||
type="checkbox" name="SD"><br>Send notifications on button press or IR: <input
|
||||
type="checkbox" name="SB"><br>Send Alexa notifications: <input type="checkbox"
|
||||
name="SA"><br>Send Philips Hue change notifications: <input type="checkbox"
|
||||
name="SH"><br>Send Macro notifications: <input type="checkbox" name="SM"><br>
|
||||
name="RX">Effects<br><input type="checkbox" name="SO">Segment options<br>
|
||||
Send notifications on direct change: <input type="checkbox" name="SD"><br>
|
||||
Send notifications on button press or IR: <input type="checkbox" name="SB"><br>
|
||||
Send Alexa notifications: <input type="checkbox" name="SA"><br>
|
||||
Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
||||
Send Macro notifications: <input type="checkbox" name="SM"><br>
|
||||
Send notifications twice: <input type="checkbox" name="S2"><br><i>
|
||||
Reboot required to apply changes.</i><h3>Instance List</h3>
|
||||
Enable instance list: <input type="checkbox" name="NL"><br>
|
||||
@ -292,43 +293,44 @@ Disabled</option><option value="1">Single RGB</option><option value="2">
|
||||
Single DRGB</option><option value="3">Effect</option><option value="4">Multi RGB
|
||||
</option><option value="5">Dimmer + Multi RGB</option><option value="6">
|
||||
Multi RGBW</option></select><br><a
|
||||
href="https://github.com/Aircoookie/WLED/wiki/E1.31-DMX" target="_blank">
|
||||
E1.31 info</a><br>Timeout: <input name="ET" type="number" min="1" max="65000"
|
||||
required> ms<br>Force max brightness: <input type="checkbox" name="FB"><br>
|
||||
href="https://kno.wled.ge/interfaces/e1.31-dmx/" target="_blank">E1.31 info</a>
|
||||
<br>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><h3>Alexa Voice Assistant</h3>Emulate Alexa device: <input
|
||||
type="checkbox" name="AL"><br>Alexa invocation name: <input name="AI"
|
||||
maxlength="32"><h3>Blynk</h3><b>
|
||||
type="checkbox" name="AL"><br>Alexa invocation name: <input type="text"
|
||||
name="AI" maxlength="32"><h3>Blynk</h3><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>Host:
|
||||
<input 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://github.com/Aircoookie/WLED/wiki/Blynk" target="_blank">Setup info
|
||||
</a><h3>MQTT</h3>Enable MQTT: <input type="checkbox" name="MQ"><br>Broker:
|
||||
<input name="MS" maxlength="32"> Port: <input name="MQPORT" type="number"
|
||||
<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><h3>
|
||||
MQTT</h3>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><b>
|
||||
The MQTT credentials are sent over an unsecured connection.<br>
|
||||
Never use the MQTT password for another service!</b><br>Username: <input
|
||||
name="MQUSER" maxlength="40"><br>Password: <input type="password" name="MQPASS"
|
||||
maxlength="64"><br>Client ID: <input name="MQCID" maxlength="40"><br>
|
||||
Device Topic: <input name="MD" maxlength="32"><br>Group Topic: <input name="MG"
|
||||
maxlength="32"><br>Publish on button press: <input type="checkbox" name="BM">
|
||||
<br><i>Reboot required to apply changes. </i><a
|
||||
href="https://github.com/Aircoookie/WLED/wiki/MQTT" target="_blank">MQTT info
|
||||
</a><h3>Philips Hue</h3><i>
|
||||
type="text" name="MQUSER" maxlength="40"><br>Password: <input type="password"
|
||||
name="MQPASS" maxlength="64"><br>Client ID: <input type="text" name="MQCID"
|
||||
maxlength="40"><br>Device Topic: <input type="text" name="MD" maxlength="32">
|
||||
<br>Group Topic: <input type="text" name="MG" maxlength="32"><br>
|
||||
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><h3>
|
||||
Philips Hue</h3><i>
|
||||
You can find the bridge IP and the light number in the 'About' section of the hue app.
|
||||
</i><br>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>Hue Bridge IP:<br><input name="H0"
|
||||
type="number" min="0" max="255"> . <input name="H1" type="number" min="0"
|
||||
max="255"> . <input name="H2" type="number" min="0" max="255"> . <input
|
||||
name="H3" type="number" min="0" max="255"><br><b>
|
||||
type="number" class="s" min="0" max="255"> . <input name="H1" type="number"
|
||||
class="s" min="0" max="255"> . <input name="H2" type="number" class="s" min="0"
|
||||
max="255"> . <input name="H3" type="number" class="s" min="0" max="255"><br><b>
|
||||
Press the pushlink button on the bridge, after that save this page!</b><br>
|
||||
(when first connecting)<br>Hue status: <span class="sip">Disabled in this build
|
||||
</span><hr><button type="button" onclick="B()">Back</button><button
|
||||
|
4363
wled00/html_ui.h
4363
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -37,6 +37,24 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
stop = (len > 0) ? start + len : seg.stop;
|
||||
}
|
||||
|
||||
// multiply segment 0 (?) if requested untill all LEDs are used
|
||||
bool repeat = elem["rpt"] | false;
|
||||
if (repeat && stop>0) {
|
||||
elem.remove("id"); // remove for recursive call
|
||||
elem.remove("rpt"); // remove for recursive call
|
||||
elem.remove("n"); // remove for recursive call
|
||||
uint16_t len = stop - start;
|
||||
for (byte i=id+1; i<strip.getMaxSegments(); i++) {
|
||||
start = start + len;
|
||||
if (start >= strip.getLengthTotal()) break;
|
||||
elem["start"] = start;
|
||||
elem["stop"] = start + len;
|
||||
elem["rev"] = !elem["rev"]; // alternate reverse on even/odd segments
|
||||
deserializeSegment(elem, i, presetId); // recursive call with new id
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (elem["n"]) {
|
||||
// name field exists
|
||||
if (seg.name) { //clear old name
|
||||
@ -65,6 +83,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
uint16_t grp = elem["grp"] | seg.grouping;
|
||||
uint16_t spc = elem[F("spc")] | seg.spacing;
|
||||
uint16_t of = seg.offset;
|
||||
if (!(elem[F("spc")].isNull() && elem["grp"].isNull())) effectChanged = true; //send UDP
|
||||
|
||||
uint16_t len = 1;
|
||||
if (stop > start) len = stop - start;
|
||||
@ -87,6 +106,9 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
bool on = elem["on"] | seg.getOption(SEG_OPTION_ON);
|
||||
if (elem["on"].is<const char*>() && elem["on"].as<const char*>()[0] == 't') on = !on;
|
||||
seg.setOption(SEG_OPTION_ON, on, id);
|
||||
bool frz = elem["frz"] | seg.getOption(SEG_OPTION_FREEZE);
|
||||
if (elem["frz"].is<const char*>() && elem["frz"].as<const char*>()[0] == 't') frz = !seg.getOption(SEG_OPTION_FREEZE);
|
||||
seg.setOption(SEG_OPTION_FREEZE, frz, id);
|
||||
|
||||
uint8_t cctPrev = seg.cct;
|
||||
seg.setCCT(elem["cct"] | seg.cct, id);
|
||||
@ -152,10 +174,12 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
seg.setOption(SEG_OPTION_REVERSED, elem["rev"] | seg.getOption(SEG_OPTION_REVERSED));
|
||||
seg.setOption(SEG_OPTION_MIRROR , elem[F("mi")] | seg.getOption(SEG_OPTION_MIRROR ));
|
||||
|
||||
if (!(elem[F("sel")].isNull() && elem["rev"].isNull() && elem["on"].isNull() && elem[F("mi")].isNull())) effectChanged = true; //send UDP
|
||||
|
||||
//temporary, strip object gets updated via colorUpdated()
|
||||
if (id == strip.getMainSegmentId()) {
|
||||
byte effectPrev = effectCurrent;
|
||||
if (getVal(elem["fx"], &effectCurrent, 1, strip.getModeCount())) { //load effect ('r' random, '~' inc/dec, 0-255 exact value)
|
||||
if (getVal(elem["fx"], &effectCurrent, 1, strip.getModeCount())) { //load effect ('r' random, '~' inc/dec, 1-255 exact value)
|
||||
if (!presetId && effectCurrent != effectPrev) unloadPlaylist(); //stop playlist if active and FX changed manually
|
||||
}
|
||||
effectSpeed = elem[F("sx")] | effectSpeed;
|
||||
@ -164,7 +188,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
} else { //permanent
|
||||
byte fx = seg.mode;
|
||||
byte fxPrev = fx;
|
||||
if (getVal(elem["fx"], &fx, 1, strip.getModeCount())) { //load effect ('r' random, '~' inc/dec, 0-255 exact value)
|
||||
if (getVal(elem["fx"], &fx, 1, strip.getModeCount())) { //load effect ('r' random, '~' inc/dec, 1-255 exact value)
|
||||
strip.setMode(id, fx);
|
||||
if (!presetId && seg.mode != fxPrev) unloadPlaylist(); //stop playlist if active and FX changed manually
|
||||
}
|
||||
@ -223,12 +247,13 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
|
||||
}
|
||||
strip.setPixelSegment(255);
|
||||
strip.trigger();
|
||||
} else { //return to regular effect
|
||||
} else if (!elem["frz"] && iarr.isNull()) { //return to regular effect
|
||||
seg.setOption(SEG_OPTION_FREEZE, false);
|
||||
}
|
||||
return; // seg.differs(prev);
|
||||
}
|
||||
|
||||
// deserializes WLED state (fileDoc points to doc object if called from web server)
|
||||
bool deserializeState(JsonObject root, byte callMode, byte presetId)
|
||||
{
|
||||
strip.applyToAllSelected = false;
|
||||
@ -391,6 +416,7 @@ void serializeSegment(JsonObject& root, WS2812FX::Segment& seg, byte id, bool fo
|
||||
root[F("spc")] = seg.spacing;
|
||||
root[F("of")] = seg.offset;
|
||||
root["on"] = seg.getOption(SEG_OPTION_ON);
|
||||
root["frz"] = seg.getOption(SEG_OPTION_FREEZE);
|
||||
byte segbri = seg.opacity;
|
||||
root["bri"] = (segbri) ? segbri : 255;
|
||||
root["cct"] = seg.cct;
|
||||
|
@ -85,7 +85,7 @@ void colorUpdated(int callMode)
|
||||
bool someSel = false;
|
||||
|
||||
if (callMode == CALL_MODE_NOTIFICATION) {
|
||||
someSel = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
||||
someSel = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects || receiveSegmentOptions);
|
||||
}
|
||||
|
||||
//Notifier: apply received FX to selected segments only if actually receiving FX
|
||||
|
@ -217,7 +217,8 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
|
||||
receiveNotificationBrightness = request->hasArg(F("RB"));
|
||||
receiveNotificationColor = request->hasArg(F("RC"));
|
||||
receiveNotificationEffects = request->hasArg(F("RX"));
|
||||
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);
|
||||
receiveSegmentOptions = request->hasArg(F("SO"));
|
||||
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects || receiveSegmentOptions);
|
||||
notifyDirectDefault = request->hasArg(F("SD"));
|
||||
notifyDirect = notifyDirectDefault;
|
||||
notifyButton = request->hasArg(F("SB"));
|
||||
@ -753,7 +754,7 @@ bool handleSet(AsyncWebServerRequest *request, const String& req, bool apply)
|
||||
strip.applyToAllSelected = true;
|
||||
strip.setColor(2, t[0], t[1], t[2], t[3]);
|
||||
} else {
|
||||
selseg.setColor(2,((t[0] << 16) + (t[1] << 8) + t[2] + (t[3] << 24)), selectedSeg); // defined above (SS=)
|
||||
selseg.setColor(2, RGBW32(t[0], t[1], t[2], t[3]), selectedSeg); // defined above (SS=)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* UDP sync notifier / Realtime / Hyperion / TPM2.NET
|
||||
*/
|
||||
|
||||
#define WLEDPACKETSIZE 39
|
||||
#define WLEDPACKETSIZE (40+(MAX_NUM_SEGMENTS*3))
|
||||
#define UDP_IN_MAXSIZE 1472
|
||||
#define PRESUMED_NETWORK_DELAY 3 //how many ms could it take on avg to reach the receiver? This will be added to transmitted times
|
||||
|
||||
@ -42,8 +42,8 @@ void notify(byte callMode, bool followUp)
|
||||
//0: old 1: supports white 2: supports secondary color
|
||||
//3: supports FX intensity, 24 byte packet 4: supports transitionDelay 5: sup palette
|
||||
//6: supports timebase syncing, 29 byte packet 7: supports tertiary color 8: supports sys time sync, 36 byte packet
|
||||
//9: supports sync groups, 37 byte packet 10: supports CCT, 39 byte packet
|
||||
udpOut[11] = 10;
|
||||
//9: supports sync groups, 37 byte packet 10: supports CCT, 39 byte packet 11: per segment options, variable packet length (40+MAX_NUM_SEGMENTS*3)
|
||||
udpOut[11] = 11;
|
||||
udpOut[12] = colSec[0];
|
||||
udpOut[13] = colSec[1];
|
||||
udpOut[14] = colSec[2];
|
||||
@ -85,6 +85,14 @@ void notify(byte callMode, bool followUp)
|
||||
udpOut[37] = strip.hasCCTBus() ? 0 : 255; //check this is 0 for the next value to be significant
|
||||
udpOut[38] = mainseg.cct;
|
||||
|
||||
udpOut[39] = strip.getMaxSegments();
|
||||
for (uint8_t i = 0; i < strip.getMaxSegments(); i++) {
|
||||
WS2812FX::Segment &selseg = strip.getSegment(i);
|
||||
udpOut[40+i*3] = selseg.options & 0x0F; //only take into account mirrored, selected, on, reversed
|
||||
udpOut[41+i*3] = selseg.spacing;
|
||||
udpOut[42+i*3] = selseg.grouping;
|
||||
}
|
||||
|
||||
IPAddress broadcastIp;
|
||||
broadcastIp = ~uint32_t(Network.subnetMask()) | uint32_t(Network.gatewayIP());
|
||||
|
||||
@ -282,6 +290,20 @@ void handleNotifications()
|
||||
//apply effects from notification
|
||||
if (version < 200 && (receiveNotificationEffects || !someSel))
|
||||
{
|
||||
if (currentPlaylist>=0) unloadPlaylist();
|
||||
if (version>10) {
|
||||
if (receiveSegmentOptions) {
|
||||
// will not sync start & stop
|
||||
uint8_t srcSegs = udpIn[39];
|
||||
if (srcSegs > strip.getMaxSegments()) srcSegs = strip.getMaxSegments();
|
||||
for (uint8_t i = 0; i < srcSegs; i++) {
|
||||
WS2812FX::Segment& selseg = strip.getSegment(i);
|
||||
for (uint8_t j = 0; j<4; j++) selseg.setOption(j, (udpIn[40+i*3] >> j) & 0x01); //only take into account mirrored, selected, on, reversed
|
||||
selseg.spacing = udpIn[41+i*3];
|
||||
selseg.grouping = udpIn[42+i*3];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (udpIn[8] < strip.getModeCount()) effectCurrent = udpIn[8];
|
||||
effectSpeed = udpIn[9];
|
||||
if (version > 2) effectIntensity = udpIn[16];
|
||||
|
@ -305,6 +305,7 @@ WLED_GLOBAL uint8_t receiveGroups _INIT(0x01); // sync receiv
|
||||
WLED_GLOBAL bool receiveNotificationBrightness _INIT(true); // apply brightness from incoming notifications
|
||||
WLED_GLOBAL bool receiveNotificationColor _INIT(true); // apply color
|
||||
WLED_GLOBAL bool receiveNotificationEffects _INIT(true); // apply effects setup
|
||||
WLED_GLOBAL bool receiveSegmentOptions _INIT(false); // apply segment options
|
||||
WLED_GLOBAL bool notifyDirect _INIT(false); // send notification if change via UI or HTTP API
|
||||
WLED_GLOBAL bool notifyButton _INIT(false); // send if updated by button or infrared remote
|
||||
WLED_GLOBAL bool notifyAlexa _INIT(false); // send notification if updated via Alexa
|
||||
|
@ -465,6 +465,7 @@ void getSettingsJS(byte subPage, char* dest)
|
||||
sappend('c',SET_F("RB"),receiveNotificationBrightness);
|
||||
sappend('c',SET_F("RC"),receiveNotificationColor);
|
||||
sappend('c',SET_F("RX"),receiveNotificationEffects);
|
||||
sappend('c',SET_F("SO"),receiveSegmentOptions);
|
||||
sappend('c',SET_F("SD"),notifyDirectDefault);
|
||||
sappend('c',SET_F("SB"),notifyButton);
|
||||
sappend('c',SET_F("SH"),notifyHue);
|
||||
|
Loading…
Reference in New Issue
Block a user