Merge branch 'master' into dev

This commit is contained in:
Blaz Kristan 2022-01-01 16:36:06 +01:00
commit 1e947a34a8
12 changed files with 732 additions and 705 deletions

View File

@ -65,7 +65,8 @@ private:
{ 1, 0, 1, 1, 1, 1, 1 }, // 6 { 1, 0, 1, 1, 1, 1, 1 }, // 6
{ 1, 1, 1, 0, 0, 0, 0 }, // 7 { 1, 1, 1, 0, 0, 0, 0 }, // 7
{ 1, 1, 1, 1, 1, 1, 1 }, // 8 { 1, 1, 1, 1, 1, 1, 1 }, // 8
{ 1, 1, 1, 1, 0, 1, 1 } // 9 { 1, 1, 1, 1, 0, 1, 1 }, // 9
{ 0, 0, 0, 0, 0, 0, 0 } // blank
}; };
//String to reduce flash memory usage //String to reduce flash memory usage
@ -100,39 +101,39 @@ private:
switch (umSSDRDisplayMask[index]) { switch (umSSDRDisplayMask[index]) {
case 'h': case 'h':
timeVar = hourFormat12(localTime); timeVar = hourFormat12(localTime);
_showElements(&umSSDRHours, timeVar, 0); _showElements(&umSSDRHours, timeVar, 0, 1);
break; break;
case 'H': case 'H':
timeVar = hour(localTime); timeVar = hour(localTime);
_showElements(&umSSDRHours, timeVar, 0); _showElements(&umSSDRHours, timeVar, 0, 1);
break; break;
case 'k': case 'k':
timeVar = hour(localTime) + 1; timeVar = hour(localTime) + 1;
_showElements(&umSSDRHours, timeVar, 0); _showElements(&umSSDRHours, timeVar, 0, 0);
break; break;
case 'm': case 'm':
timeVar = minute(localTime); timeVar = minute(localTime);
_showElements(&umSSDRMinutes, timeVar, 0); _showElements(&umSSDRMinutes, timeVar, 0, 0);
break; break;
case 's': case 's':
timeVar = second(localTime); timeVar = second(localTime);
_showElements(&umSSDRSeconds, timeVar, 0); _showElements(&umSSDRSeconds, timeVar, 0, 0);
break; break;
case 'd': case 'd':
timeVar = day(localTime); timeVar = day(localTime);
_showElements(&umSSDRDays, timeVar, 0); _showElements(&umSSDRDays, timeVar, 0, 0);
break; break;
case 'M': case 'M':
timeVar = month(localTime); timeVar = month(localTime);
_showElements(&umSSDRMonths, timeVar, 0); _showElements(&umSSDRMonths, timeVar, 0, 0);
break; break;
case 'y': case 'y':
timeVar = second(localTime); timeVar = second(localTime);
_showElements(&umSSDRYears, timeVar, 0); _showElements(&umSSDRYears, timeVar, 0, 0);
break; break;
case 'Y': case 'Y':
timeVar = year(localTime); timeVar = year(localTime);
_showElements(&umSSDRYears, timeVar, 0); _showElements(&umSSDRYears, timeVar, 0, 0);
break; break;
case ':': case ':':
if (!colonsDone) { // only call _setColons once as all colons are printed when the first colon is found if (!colonsDone) { // only call _setColons once as all colons are printed when the first colon is found
@ -148,14 +149,16 @@ private:
void _setColons() { void _setColons() {
if ( umSSDRColonblink ) { if ( umSSDRColonblink ) {
if ( second(localTime) % 2 == 0 ) { if ( second(localTime) % 2 == 0 ) {
_showElements(&umSSDRColons, 0, 1); _showElements(&umSSDRColons, 0, 1, 0);
} }
} else { } else {
_showElements(&umSSDRColons, 0, 1); _showElements(&umSSDRColons, 0, 1, 0);
} }
} }
void _showElements(String *map, int timevar, bool isColon) { void _showElements(String *map, int timevar, bool isColon, bool removeZero
) {
if (!(*map).equals("") && !(*map) == NULL) { if (!(*map).equals("") && !(*map) == NULL) {
int length = String(timevar).length(); int length = String(timevar).length();
bool addZero = false; bool addZero = false;
@ -165,8 +168,16 @@ private:
} }
int timeArr[length]; int timeArr[length];
if(addZero) { if(addZero) {
timeArr[1] = 0; if(removeZero)
timeArr[0] = timevar; {
timeArr[1] = 10;
timeArr[0] = timevar;
}
else
{
timeArr[1] = 0;
timeArr[0] = timevar;
}
} else { } else {
int count = 0; int count = 0;
while (timevar) { while (timevar) {

View File

@ -355,8 +355,7 @@ uint8_t WS2812FX::getTargetFps() {
} }
void WS2812FX::setTargetFps(uint8_t fps) { void WS2812FX::setTargetFps(uint8_t fps) {
if (fps > 0 && fps <= 120) _targetFps = fps; if (fps > 0 && fps <= 120) _targetFps = fps;
//_targetFps = min(max((int)fps,1),120);
_frametime = 1000 / _targetFps; _frametime = 1000 / _targetFps;
} }

View File

@ -86,10 +86,9 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
Bus::setAutoWhiteMode(hw_led[F("rgbwm")] | Bus::getAutoWhiteMode()); Bus::setAutoWhiteMode(hw_led[F("rgbwm")] | Bus::getAutoWhiteMode());
CJSON(correctWB, hw_led["cct"]); CJSON(correctWB, hw_led["cct"]);
CJSON(cctFromRgb, hw_led[F("cr")]); CJSON(cctFromRgb, hw_led[F("cr")]);
CJSON(strip.cctBlending, hw_led[F("cb")]); CJSON(strip.cctBlending, hw_led[F("cb")]);
Bus::setCCTBlend(strip.cctBlending); Bus::setCCTBlend(strip.cctBlending);
strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS strip.setTargetFps(hw_led["fps"]); //NOP if 0, default 42 FPS
//strip.setTargetFps(hw_led["fps"].isNull() ? WLED_FPS : hw_led["fps"].as<byte>());
JsonArray ins = hw_led["ins"]; JsonArray ins = hw_led["ins"];
@ -371,7 +370,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
CJSON(timerMinutes[it], timer["min"]); CJSON(timerMinutes[it], timer["min"]);
CJSON(timerMacro[it], timer["macro"]); CJSON(timerMacro[it], timer["macro"]);
byte dowPrev = timerWeekday[it]; byte dowPrev = timerWeekday[it];
//note: act is currently only 0 or 1. //note: act is currently only 0 or 1.
//the reason we are not using bool is that the on-disk type in 0.11.0 was already int //the reason we are not using bool is that the on-disk type in 0.11.0 was already int
int actPrev = timerWeekday[it] & 0x01; int actPrev = timerWeekday[it] & 0x01;
@ -382,8 +381,15 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
if (act) timerWeekday[it]++; if (act) timerWeekday[it]++;
} }
if (it<8) { if (it<8) {
CJSON(timerMonth[it], timer[F("mon")]); JsonObject start = timer["start"];
CJSON(timerDay[it], timer[F("day")]); byte startm = start["mon"];
if (startm) timerMonth[it] = (startm << 4);
CJSON(timerDay[it], start["day"]);
JsonObject end = timer["end"];
CJSON(timerDayEnd[it], end["day"]);
byte endm = end["mon"];
if (startm) timerMonth[it] += endm & 0x0F;
if (!(timerMonth[it] & 0x0F)) timerMonth[it] += 12; //default end month to 12
} }
it++; it++;
} }
@ -745,8 +751,12 @@ void serializeConfig() {
timers_ins0["macro"] = timerMacro[i]; timers_ins0["macro"] = timerMacro[i];
timers_ins0[F("dow")] = timerWeekday[i] >> 1; timers_ins0[F("dow")] = timerWeekday[i] >> 1;
if (i<8) { if (i<8) {
timers_ins0[F("mon")] = timerMonth[i]; JsonObject start = timers_ins0.createNestedObject("start");
timers_ins0[F("day")] = timerDay[i]; start["mon"] = (timerMonth[i] >> 4) & 0xF;
start["day"] = timerDay[i];
JsonObject end = timers_ins0.createNestedObject("end");
end["mon"] = timerMonth[i] & 0xF;
end["day"] = timerDayEnd[i];
} }
} }

View File

@ -353,7 +353,7 @@ ${i+1}:
c += `<option value="7" ${t==7?"selected":""}>Analog</option>`; c += `<option value="7" ${t==7?"selected":""}>Analog</option>`;
c += `<option value="8" ${t==8?"selected":""}>Analog inverted</option>`; c += `<option value="8" ${t==8?"selected":""}>Analog inverted</option>`;
c += `</select>`; c += `</select>`;
c += `<span style="cursor: pointer;" onclick="off('${bt}')">&nbsp;&#215;</span><br>`; c += `<span style="cursor: pointer;" onclick="off('${bt}')">&nbsp;&#x2715;</span><br>`;
gId("btns").innerHTML = c; gId("btns").innerHTML = c;
} }
function tglSi(cs) { function tglSi(cs) {
@ -515,10 +515,10 @@ ${i+1}:
<option value=6>6-key black</option> <option value=6>6-key black</option>
<option value=7>9-key red</option> <option value=7>9-key red</option>
<option value=8>JSON remote</option> <option value=8>JSON remote</option>
</select><span style="cursor: pointer;" onclick="off('IR')">&nbsp;&#215;</span><br> </select><span style="cursor: pointer;" onclick="off('IR')">&nbsp;&#x2715;</span><br>
<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> <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> <a href="https://kno.wled.ge/interfaces/infrared/" target="_blank">IR info</a><br>
Relay GPIO: <input type="number" min="-1" max="33" name="RL" onchange="UI()" class="xs"> Invert <input type="checkbox" name="RM"><span style="cursor: pointer;" onclick="off('RL')">&nbsp;&#215;</span><br> Relay GPIO: <input type="number" min="-1" max="33" name="RL" onchange="UI()" class="xs"> Invert <input type="checkbox" name="RM"><span style="cursor: pointer;" onclick="off('RL')">&nbsp;&#x2715;</span><br>
<hr style="width:260px"> <hr style="width:260px">
<h3>Defaults</h3> <h3>Defaults</h3>
Turn LEDs on after power up/reset: <input type="checkbox" name="BO"><br> Turn LEDs on after power up/reset: <input type="checkbox" name="BO"><br>

View File

@ -7,6 +7,7 @@
<title>Time Settings</title> <title>Time Settings</title>
<script> <script>
var d=document; var d=document;
var ms=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
function H() function H()
{ {
window.open("https://kno.wled.ge/features/settings/#time-settings"); window.open("https://kno.wled.ge/features/settings/#time-settings");
@ -23,11 +24,14 @@
{ {
return d.getElementById(s); return d.getElementById(s);
} }
function gN(s) {
return d.getElementsByName(s)[0];
}
function expand(o,i) function expand(o,i)
{ {
o.classList.toggle("exp");
var t = gId("WD"+i); var t = gId("WD"+i);
t.style.display = t.style.display!=="none" ? "none" : ""; t.style.display = t.style.display!=="none" ? "none" : "";
o.innerHTML = t.style.display==="none" ? "&#128467;" : "&#x2715;";
} }
function Cs() function Cs()
{ {
@ -50,73 +54,52 @@
} }
function BTa() function BTa()
{ {
var ih="<tr><th>En.</th><th>Hour</th><th>Minute</th><th>Preset</th><th></th></tr>"; var ih="<thead><tr><th>En.</th><th>Hour</th><th>Minute</th><th>Preset</th><th></th></tr></thead>";
for (i=0;i<8;i++) { for (i=0;i<8;i++) {
ih+=`<tr><td><input name="W${i}" id="W${i}" type="hidden"><input id="W${i}0" type="checkbox"></td> ih+=`<tr><td><input name="W${i}" id="W${i}" type="hidden"><input id="W${i}0" type="checkbox"></td>
<td><input name="H${i}" class="xs" type="number" min="0" max="24"></td> <td><input name="H${i}" class="xs" type="number" min="0" max="24"></td>
<td><input name="N${i}" class="xs" type="number" min="0" max="59"></td> <td><input name="N${i}" class="xs" type="number" min="0" max="59"></td>
<td><input name="T${i}" class="s" type="number" min="0" max="250"></td> <td><input name="T${i}" class="s" type="number" min="0" max="250"></td>
<td><button type="button" class="sml" onclick="expand(this,${i})">&gt;</button></td></tr>`; <td><div id="CB${i}" onclick="expand(this,${i})" class="cal">&#128467;</div></td></tr>`;
ih+=`<tr><td colspan=5><div id="WD${i}" style="display:none;">`; ih+=`<tr><td colspan=5><div id="WD${i}" style="display:none;"><hr>Run on weekdays`;
ih+=`<input name="X${i}" id="TMX${i}" type="checkbox" onchange="tglDOW(${i},this.checked)"><label for="TMX${i}">Use DOW</label>`; ih+=`<table><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>`
ih+=`<table id="TT${i}" style="width:100%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>`
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></table><div id="TD${i}">Date: ih+=`</tr></table>from <select name="M${i}">`;
<select id="TMM${i}" name="M${i}" onchange="chkMon(this,${i})"> for (j=0;j<12;j++) ih+=`<option value="${j+1}">${ms[j]}</option>`;
<option value="0">Every month</option> ih+=`</select><input name="D${i}" class="xs" type="number" min="1" max="31"></input> to <select name="P${i}">`;
<option value="13">Odd month</option> for (j=0;j<12;j++) ih+=`<option value="${j+1}">${ms[j]}</option>`;
<option value="14">Even month</option> ih+=`</select><input name="E${i}" class="xs" type="number" min="1" max="31"></input>
<option value="1">Jan</option> <hr></div></td></tr>`;
<option value="2">Feb</option>
<option value="3">Mar</option>
<option value="4">Apr</option>
<option value="5">May</option>
<option value="6">Jun</option>
<option value="7">Jul</option>
<option value="8">Aug</option>
<option value="9">Sep</option>
<option value="10">Oct</option>
<option value="11">Nov</option>
<option value="12">Dec</option>
</select><select id="TMD${i}" name="D${i}">`;
for (j=1;j<32;j++) ih+=`<option value="${j}">${j}</option>`;
ih+="</select></div><hr></div></td></tr>";
} }
ih+=`<tr><td><input name="W8" id="W8" type="hidden"><input id="W80" type="checkbox"></td> ih+=`<tr><td><input name="W8" id="W8" type="hidden"><input id="W80" type="checkbox"></td>
<td>Sunrise<input name="H8" value="255" type="hidden"></td> <td>Sunrise<input name="H8" value="255" type="hidden"></td>
<td><input name="N8" class="xs" type="number" min="-59" max="59"></td> <td><input name="N8" class="xs" type="number" min="-59" max="59"></td>
<td><input name="T8" class="s" type="number" min="0" max="250"></td> <td><input name="T8" class="s" type="number" min="0" max="250"></td>
<td><button type="button" class="sml" onclick="expand(this,8)">&gt;</button></td></tr><tr><td colspan=5>`; <td><div onclick="expand(this,8)" class="cal">&#128467;</div></td></tr><tr><td colspan=5>`;
ih+=`<div id="WD8"style="display:none;"><table style="width:100%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>`; ih+=`<div id="WD8" style="display:none;"><hr><table><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>`;
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></table><hr></div></td></tr>"; ih+="</tr></table><hr></div></td></tr>";
ih+=`<tr><td><input name="W9" id="W9" type="hidden"><input id="W90" type="checkbox"></td> ih+=`<tr><td><input name="W9" id="W9" type="hidden"><input id="W90" type="checkbox"></td>
<td>Sunrise<input name="H9" value="255" type="hidden"></td> <td>Sunset<input name="H9" value="255" type="hidden"></td>
<td><input name="N9" class="xs" type="number" min="-59" max="59"></td> <td><input name="N9" class="xs" type="number" min="-59" max="59"></td>
<td><input name="T9" class="s" type="number" min="0" max="250"></td> <td><input name="T9" class="s" type="number" min="0" max="250"></td>
<td><button type="button" class="sml" onclick="expand(this,9)">&gt;</button></td></tr><tr><td colspan=5>`; <td><div onclick="expand(this,9)" class="cal">&#128467;</div></td></tr><tr><td colspan=5>`;
ih+=`<div id="WD9" style="display:none;"><table style="width:100%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>`; ih+=`<div id="WD9" style="display:none;"><hr><table><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>`;
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></table><hr></div></td></tr>"; ih+="</tr></table><hr></div></td></tr>";
gId("TMT").innerHTML=ih; gId("TMT").innerHTML=ih;
} }
function tglDOW(i,b)
{
gId("TT"+i).style.display = b ? "table" : "none";
gId("TD"+i).style.display = !b ? "block" : "none";
}
function chkMon(o,i)
{
const m31 = [1,3,5,7,8,10,12,0,13,14];
if (!m31.includes(parseInt(o.value)) && parseInt(gId("TMD"+i).value)>30) gId("TMD"+i).value="30";
if (parseInt(o.value)===2 && parseInt(gId("TMD"+i).value)>28) gId("TMD"+i).value="28";
}
function FC() function FC()
{ {
for(j=0;j<8;j++) for(i=0;i<10;i++)
{ {
for(i=0;i<10;i++) gId("W"+i+j).checked=gId("W"+i).value>>j&1; let wd = gId("W"+i).value;
tglDOW(j,gId('TMX'+j).checked); for(j=0;j<8;j++) {
gId("W"+i+j).checked=wd>>j&1;
}
if ((wd&127) != 127 || (i<8 && (gN("M"+i).value != 1 || gN("D"+i).value != 1 || gN("P"+i).value != 12 || gN("E"+i).value != 31))) {
expand(gId("CB"+i),i); //expand macros with custom DOW or date range set
}
} }
} }
function Wd() function Wd()
@ -154,7 +137,6 @@
//values injected by server while sending HTML //values injected by server while sending HTML
} }
</script> </script>
<!--script src="http://192.168.70.61/settings/settings.js?p=5"></script-->
<style>@import url("style.css");</style> <style>@import url("style.css");</style>
</head> </head>
<body onload="S()"> <body onload="S()">
@ -218,12 +200,12 @@
</div> </div>
Countdown Mode: <input type="checkbox" name="CE"><br> Countdown Mode: <input type="checkbox" name="CE"><br>
Countdown Goal:<br> Countdown Goal:<br>
Date: <nowrap>20<input name="CY" class="xs" type="number" min="0" max="99" required>-<input name="CI" class="xs" type="number" min="1" max="12" required>-<input name="CD" class="xs" type="number" min="1" max="31" required></nowrap><br> Date:&nbsp;<nowrap>20<input name="CY" class="xs" type="number" min="0" max="99" required>-<input name="CI" class="xs" type="number" min="1" max="12" required>-<input name="CD" class="xs" type="number" min="1" max="31" required></nowrap><br>
Time: <nowrap><input name="CH" class="xs" type="number" min="0" max="23" required>:<input name="CM" class="xs" type="number" min="0" max="59" required>:<input name="CS" class="xs" type="number" min="0" max="59" required></nowrap><br> Time:&nbsp;<nowrap><input name="CH" class="xs" type="number" min="0" max="23" required>:<input name="CM" class="xs" type="number" min="0" max="59" required>:<input name="CS" class="xs" type="number" min="0" max="59" required></nowrap><br>
<h3>Macro presets</h3> <h3>Macro presets</h3>
<b>Macros have moved!</b><br> <b>Macros have moved!</b><br>
<i>Presets now also can be used as macros to save both JSON and HTTP API commands.<br> <i>Presets now also can be used as macros to save both JSON and HTTP API commands.<br>
Just enter the preset id below!</i> Just enter the preset ID below!</i>
<i>Use 0 for the default action instead of a preset</i><br> <i>Use 0 for the default action instead of a preset</i><br>
Alexa On/Off Preset: <input name="A0" class="m" type="number" min="0" max="250" required> <input name="A1" class="m" type="number" min="0" max="250" required><br> Alexa On/Off Preset: <input name="A0" class="m" type="number" min="0" max="250" required> <input name="A1" class="m" type="number" min="0" max="250" required><br>
Countdown-Over Preset: <input name="MC" class="m" type="number" min="0" max="250" required><br> Countdown-Over Preset: <input name="MC" class="m" type="number" min="0" max="250" required><br>

View File

@ -92,6 +92,9 @@ input[type="checkbox"] {
transform: scale(1.5); transform: scale(1.5);
margin-right: 10px; margin-right: 10px;
} }
td input[type="checkbox"] {
margin-right: revert;
}
select { select {
margin: 2px; margin: 2px;
background: #333; background: #333;
@ -108,8 +111,12 @@ td {
.d5 { .d5 {
width: 4rem !important; width: 4rem !important;
} }
.exp { .cal {
transform: rotate(90deg); font-size:1.5rem;
cursor:pointer
}
#TMT table {
width: 100%;
} }
#toast { #toast {
opacity: 0; opacity: 0;

File diff suppressed because it is too large Load Diff

View File

@ -318,6 +318,32 @@ byte weekdayMondayFirst()
return wd; return wd;
} }
bool isTodayInDateRange(byte monthStart, byte dayStart, byte monthEnd, byte dayEnd)
{
if (monthStart == 0 || dayStart == 0) return true;
if (monthEnd == 0) monthEnd = monthStart;
if (dayEnd == 0) dayEnd = 31;
byte d = day(localTime);
byte m = month(localTime);
if (monthStart < monthEnd) {
if (m > monthStart && m < monthEnd) return true;
if (m == monthStart) return (d >= dayStart);
if (m == monthEnd) return (d <= dayEnd);
return false;
}
if (monthEnd < monthStart) { //range spans change of year
if (m > monthStart || m < monthEnd) return true;
if (m == monthStart) return (d >= dayStart);
if (m == monthEnd) return (d <= dayEnd);
return false;
}
//start month and end month are the same
if (dayEnd < dayStart) return (m != monthStart || (d <= dayEnd || d >= dayStart)); //all year, except the designated days in this month
return (m == monthStart && d >= dayStart && d <= dayEnd); //just the designated days this month
}
void checkTimers() void checkTimers()
{ {
if (lastTimerMinute != minute(localTime)) //only check once a new minute begins if (lastTimerMinute != minute(localTime)) //only check once a new minute begins
@ -334,12 +360,9 @@ void checkTimers()
&& (timerWeekday[i] & 0x01) //timer is enabled && (timerWeekday[i] & 0x01) //timer is enabled
&& (timerHours[i] == hour(localTime) || timerHours[i] == 24) //if hour is set to 24, activate every hour && (timerHours[i] == hour(localTime) || timerHours[i] == 24) //if hour is set to 24, activate every hour
&& timerMinutes[i] == minute(localTime) && timerMinutes[i] == minute(localTime)
&& ( (timerDay[i] == 0 && ((timerWeekday[i] >> weekdayMondayFirst()) & 0x01)) //timer should activate at current day of week && ((timerWeekday[i] >> weekdayMondayFirst()) & 0x01) //timer should activate at current day of week
|| (timerDay[i] > 0 && timerDay[i]==day(localTime) && && isTodayInDateRange(((timerMonth[i] >> 4) & 0x0F), timerDay[i], timerMonth[i] & 0x0F, timerDayEnd[i])
(timerMonth[i] == 0 || timerMonth[i]==month(localTime) || (timerMonth[i]==13 && month(localTime)%2) || (timerMonth[i]==14 && !(month(localTime)%2))) )
)
)
)
{ {
unloadPlaylist(); unloadPlaylist();
applyPreset(timerMacro[i]); applyPreset(timerMacro[i]);

View File

@ -107,7 +107,7 @@ int16_t loadPlaylist(JsonObject playlistObj, byte presetId) {
playlistRepeat = rep; playlistRepeat = rep;
if (playlistRepeat > 0) playlistRepeat++; //add one extra repetition immediately since it will be deducted on first start if (playlistRepeat > 0) playlistRepeat++; //add one extra repetition immediately since it will be deducted on first start
playlistEndPreset = playlistObj[F("end")] | 0; playlistEndPreset = playlistObj["end"] | 0;
shuffle = shuffle || playlistObj["r"]; shuffle = shuffle || playlistObj["r"];
if (shuffle) playlistOptions += PL_OPTION_SHUFFLE; if (shuffle) playlistOptions += PL_OPTION_SHUFFLE;

View File

@ -339,7 +339,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
char k[3]; k[2] = 0; char k[3]; k[2] = 0;
for (int i = 0; i<10; i++) { for (int i = 0; i<10; i++) {
k[1] = i+48;//ascii 0,1,2,3 k[1] = i+48;//ascii 0,1,2,3,...
k[0] = 'H'; //timer hours k[0] = 'H'; //timer hours
timerHours[i] = request->arg(k).toInt(); timerHours[i] = request->arg(k).toInt();
k[0] = 'N'; //minutes k[0] = 'N'; //minutes
@ -349,16 +349,15 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
k[0] = 'W'; //weekdays k[0] = 'W'; //weekdays
timerWeekday[i] = request->arg(k).toInt(); timerWeekday[i] = request->arg(k).toInt();
if (i<8) { if (i<8) {
k[0] = 'X'; //DOW k[0] = 'M'; //start month
if (!request->hasArg(k)) { timerMonth[i] = request->arg(k).toInt() & 0x0F;
k[0] = 'M'; //month timerMonth[i] <<= 4;
timerMonth[i] = request->arg(k).toInt(); k[0] = 'P'; //end month
k[0] = 'D'; //day timerMonth[i] += (request->arg(k).toInt() & 0x0F);
timerDay[i] = request->arg(k).toInt(); k[0] = 'D'; //start day
} else { timerDay[i] = request->arg(k).toInt();
timerMonth[i] = 0; k[0] = 'E'; //end day
timerDay[i] = 0; timerDayEnd[i] = request->arg(k).toInt();
}
} }
} }
} }

View File

@ -8,7 +8,7 @@
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2201011 #define VERSION 2201012
//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
@ -503,15 +503,17 @@ WLED_GLOBAL byte dP[] _INIT_N(({ 255, 255, 255, 255, 255, 255 }));
WLED_GLOBAL unsigned long countdownTime _INIT(1514764800L); WLED_GLOBAL unsigned long countdownTime _INIT(1514764800L);
WLED_GLOBAL bool countdownOverTriggered _INIT(true); WLED_GLOBAL bool countdownOverTriggered _INIT(true);
// timer //timer
WLED_GLOBAL byte lastTimerMinute _INIT(0); WLED_GLOBAL byte lastTimerMinute _INIT(0);
WLED_GLOBAL byte timerHours[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 })); WLED_GLOBAL byte timerHours[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }));
WLED_GLOBAL int8_t timerMinutes[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 })); WLED_GLOBAL int8_t timerMinutes[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }));
WLED_GLOBAL byte timerMacro[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 })); WLED_GLOBAL byte timerMacro[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }));
WLED_GLOBAL byte timerWeekday[] _INIT_N(({ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 })); // weekdays to activate on //weekdays to activate on, bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity
// bit pattern of arr elem: 0b11111111: sun,sat,fri,thu,wed,tue,mon,validity WLED_GLOBAL byte timerWeekday[] _INIT_N(({ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }));
WLED_GLOBAL byte timerMonth[] _INIT_N(({0,0,0,0,0,0,0,0})); //upper 4 bits start, lower 4 bits end month (default 28: start month 1 and end month 12)
WLED_GLOBAL byte timerDay[] _INIT_N(({0,0,0,0,0,0,0,0})); WLED_GLOBAL byte timerMonth[] _INIT_N(({28,28,28,28,28,28,28,28}));
WLED_GLOBAL byte timerDay[] _INIT_N(({1,1,1,1,1,1,1,1}));
WLED_GLOBAL byte timerDayEnd[] _INIT_N(({31,31,31,31,31,31,31,31}));
// blynk // blynk
WLED_GLOBAL bool blynkEnabled _INIT(false); WLED_GLOBAL bool blynkEnabled _INIT(false);

View File

@ -458,7 +458,7 @@ void getSettingsJS(byte subPage, char* dest)
memset(fpass,'*',l); memset(fpass,'*',l);
sappends('s',SET_F("MQPASS"),fpass); sappends('s',SET_F("MQPASS"),fpass);
sappends('s',SET_F("MQCID"),mqttClientID); sappends('s',SET_F("MQCID"),mqttClientID);
sappends('s',SET_F("MD"),mqttDeviceTopic); sappends('s',"MD",mqttDeviceTopic);
sappends('s',SET_F("MG"),mqttGroupTopic); sappends('s',SET_F("MG"),mqttGroupTopic);
sappend('c',SET_F("BM"),buttonPublishMqtt); sappend('c',SET_F("BM"),buttonPublishMqtt);
#endif #endif
@ -550,10 +550,10 @@ void getSettingsJS(byte subPage, char* dest)
k[0] = 'T'; sappend('v',k,timerMacro[i]); k[0] = 'T'; sappend('v',k,timerMacro[i]);
k[0] = 'W'; sappend('v',k,timerWeekday[i]); k[0] = 'W'; sappend('v',k,timerWeekday[i]);
if (i<8) { if (i<8) {
k[0] = 'X'; sappend('c',k,timerDay[i]==0); k[0] = 'M'; sappend('v',k,(timerMonth[i] >> 4) & 0x0F);
k[0] = 'M'; sappend('v',k,timerMonth[i]); k[0] = 'P'; sappend('v',k,timerMonth[i] & 0x0F);
k[0] = 'D'; sappend('v',k,timerDay[i]?timerDay[i]:1); k[0] = 'D'; sappend('v',k,timerDay[i]);
k[0] = 'E'; sappend('v',k,timerDayEnd[i]);
} }
} }
} }