Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 10 additions & 5 deletions wled00/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -682,8 +682,8 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
JsonArray timers = tm["ins"];
uint8_t it = 0;
for (JsonObject timer : timers) {
if (it > 9) break;
if (it<8 && timer[F("hour")]==255) it=8; // hour==255 -> sunrise/sunset
if (it > 17) break;
if (it<16 && timer[F("hour")]==255) it=16; // hour==255 -> sunrise/sunset
CJSON(timerHours[it], timer[F("hour")]);
CJSON(timerMinutes[it], timer["min"]);
CJSON(timerMacro[it], timer["macro"]);
Expand All @@ -698,7 +698,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
int act = timer["en"] | actPrev;
if (act) timerWeekday[it]++;
}
if (it<8) {
if (it<16) {
JsonObject start = timer["start"];
byte startm = start["mon"];
if (startm) timerMonth[it] = (startm << 4);
Expand All @@ -711,6 +711,11 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
}
it++;
}

// Clear enabled bit for any timers that have no macro set
for (unsigned i = 0; i < 18; i++) {
if (timerMacro[i] == 0) timerWeekday[i] = timerWeekday[i] & 0b11111110;
}

JsonObject ota = doc["ota"];
const char* pwd = ota["psk"]; //normally not present due to security
Expand Down Expand Up @@ -1207,15 +1212,15 @@ void serializeConfig(JsonObject root) {

JsonArray timers_ins = timers.createNestedArray("ins");

for (unsigned i = 0; i < 10; i++) {
for (unsigned i = 0; i < 18; i++) {
if (timerMacro[i] == 0 && timerHours[i] == 0 && timerMinutes[i] == 0) continue; // sunrise/sunset get saved always (timerHours=255)
JsonObject timers_ins0 = timers_ins.createNestedObject();
timers_ins0["en"] = (timerWeekday[i] & 0x01);
timers_ins0[F("hour")] = timerHours[i];
timers_ins0["min"] = timerMinutes[i];
timers_ins0["macro"] = timerMacro[i];
timers_ins0[F("dow")] = timerWeekday[i] >> 1;
if (i<8) {
if (i<16) {
JsonObject start = timers_ins0.createNestedObject("start");
start["mon"] = (timerMonth[i] >> 4) & 0xF;
start["day"] = timerDay[i];
Expand Down
39 changes: 20 additions & 19 deletions wled00/data/settings_time.htm
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
function BTa()
{
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<16;i++) {
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="N${i}" class="xs" type="number" min="0" max="59"></td>
Expand All @@ -43,41 +43,42 @@
ih+=`</select><input name="E${i}" class="xs" type="number" min="1" max="31"></input>
<hr></div></td></tr>`;
}
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><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><div id="CB8" onclick="expand(this,8)" class="cal">&#128197;</div></td></tr><tr><td colspan=5>`;
ih+=`<div id="WD8" style="display:none;background-color:#444;"><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>`;
ih+=`<tr><td><input name="W16" id="W16" type="hidden"><input id="W160" type="checkbox"></td>
<td>Sunrise<input name="H16" value="255" type="hidden"></td>
<td><input name="N16" class="xs" type="number" min="-59" max="59"></td>
<td><input name="T16" class="s" type="number" min="0" max="250"></td>
<td><div id="CB16" onclick="expand(this,16)" class="cal">&#128197;</div></td></tr><tr><td colspan=5>`;
ih+=`<div id="WD16" style="display:none;background-color:#444;"><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="W16${j}" type="checkbox"></td>`;
ih+="</tr></table><hr></div></td></tr>";
ih+=`<tr><td><input name="W9" id="W9" type="hidden"><input id="W90" type="checkbox"></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="T9" class="s" type="number" min="0" max="250"></td>
<td><div id="CB9" onclick="expand(this,9)" class="cal">&#128197;</div></td></tr><tr><td colspan=5>`;
ih+=`<div id="WD9" style="display:none;background-color:#444;"><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>`;
ih+=`<tr><td><input name="W17" id="W17" type="hidden"><input id="W170" type="checkbox"></td>
<td>Sunset<input name="H17" value="255" type="hidden"></td>
<td><input name="N17" class="xs" type="number" min="-59" max="59"></td>
<td><input name="T17" class="s" type="number" min="0" max="250"></td>
<td><div id="CB17" onclick="expand(this,17)" class="cal">&#128197;</div></td></tr><tr><td colspan=5>`;
ih+=`<div id="WD17" style="display:none;background-color:#444;"><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="W17${j}" type="checkbox"></td>`;
ih+="</tr></table><hr></div></td></tr>";
gId("TMT").innerHTML=ih;
}
function FC()
{
for(i=0;i<10;i++)
for(i=0;i<18;i++)
{
let wd = gId("W"+i).value;
for(j=0;j<8;j++) {
gId("W"+i+j).checked=wd>>j&1;
}
if ((wd&254) != 254 || (i<8 && (gN("M"+i).value != 1 || gN("D"+i).value != 1 || gN("P"+i).value != 12 || gN("E"+i).value != 31))) {
// there is a bug in this IF clause that doesn't seem to work as expected
if ((wd&254) != 254 || (i<16 && (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()
{
a = [0,0,0,0,0,0,0,0,0,0];
for (i=0; i<10; i++) {
a = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
for (i=0; i<18; i++) {
m=1;
for(j=0;j<8;j++) { a[i]+=gId(("W"+i)+j).checked*m; m*=2;}
gId("W"+i).value=a[i];
Expand Down
26 changes: 13 additions & 13 deletions wled00/ntp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ void checkTimers()
if (!hour(localTime) && minute(localTime)==1) calculateSunriseAndSunset();

DEBUG_PRINTF_P(PSTR("Local time: %02d:%02d\n"), hour(localTime), minute(localTime));
for (unsigned i = 0; i < 8; i++)
for (unsigned i = 0; i < 16; i++)
{
if (timerMacro[i] != 0
&& (timerWeekday[i] & 0x01) //timer is enabled
Expand All @@ -396,30 +396,30 @@ void checkTimers()
}
// sunrise macro
if (sunrise) {
time_t tmp = sunrise + timerMinutes[8]*60; // NOTE: may not be ok
time_t tmp = sunrise + timerMinutes[16]*60; // NOTE: may not be ok
DEBUG_PRINTF_P(PSTR("Trigger time: %02d:%02d\n"), hour(tmp), minute(tmp));
if (timerMacro[8] != 0
if (timerMacro[16] != 0
&& hour(tmp) == hour(localTime)
&& minute(tmp) == minute(localTime)
&& (timerWeekday[8] & 0x01) //timer is enabled
&& ((timerWeekday[8] >> weekdayMondayFirst()) & 0x01)) //timer should activate at current day of week
&& (timerWeekday[16] & 0x01) //timer is enabled
&& ((timerWeekday[16] >> weekdayMondayFirst()) & 0x01)) //timer should activate at current day of week
{
applyPreset(timerMacro[8]);
DEBUG_PRINTF_P(PSTR("Sunrise macro %d triggered."),timerMacro[8]);
applyPreset(timerMacro[16]);
DEBUG_PRINTF_P(PSTR("Sunrise macro %d triggered."),timerMacro[16]);
}
}
// sunset macro
if (sunset) {
time_t tmp = sunset + timerMinutes[9]*60; // NOTE: may not be ok
time_t tmp = sunset + timerMinutes[17]*60; // NOTE: may not be ok
DEBUG_PRINTF_P(PSTR("Trigger time: %02d:%02d\n"), hour(tmp), minute(tmp));
if (timerMacro[9] != 0
if (timerMacro[17] != 0
&& hour(tmp) == hour(localTime)
&& minute(tmp) == minute(localTime)
&& (timerWeekday[9] & 0x01) //timer is enabled
&& ((timerWeekday[9] >> weekdayMondayFirst()) & 0x01)) //timer should activate at current day of week
&& (timerWeekday[17] & 0x01) //timer is enabled
&& ((timerWeekday[17] >> weekdayMondayFirst()) & 0x01)) //timer should activate at current day of week
{
applyPreset(timerMacro[9]);
DEBUG_PRINTF_P(PSTR("Sunset macro %d triggered."),timerMacro[9]);
applyPreset(timerMacro[17]);
DEBUG_PRINTF_P(PSTR("Sunset macro %d triggered."),timerMacro[17]);
}
}
}
Expand Down
15 changes: 11 additions & 4 deletions wled00/set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -545,9 +545,16 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
i++;
}

char k[3]; k[2] = 0;
for (int i = 0; i<10; i++) {
k[1] = i+48;//ascii 0,1,2,3,...
char k[5]; k[4] = 0; //null terminate buffer
for (int i = 0; i<18; i++) {
if (i<10) {
k[1] = i+48;//ascii 0-9
k[2] = 0;
} else {
k[1] = '1'; //tens digit
k[2] = 48+(i-10); //ones digit for 10-17
k[3] = 0;
}
k[0] = 'H'; //timer hours
timerHours[i] = request->arg(k).toInt();
k[0] = 'N'; //minutes
Expand All @@ -556,7 +563,7 @@ void handleSettingsSet(AsyncWebServerRequest *request, byte subPage)
timerMacro[i] = request->arg(k).toInt();
k[0] = 'W'; //weekdays
timerWeekday[i] = request->arg(k).toInt();
if (i<8) {
if (i<16) {
k[0] = 'M'; //start month
timerMonth[i] = request->arg(k).toInt() & 0x0F;
timerMonth[i] <<= 4;
Expand Down
14 changes: 7 additions & 7 deletions wled00/wled.h
Original file line number Diff line number Diff line change
Expand Up @@ -818,15 +818,15 @@ WLED_GLOBAL bool countdownOverTriggered _INIT(true);

//timer
WLED_GLOBAL byte lastTimerMinute _INIT(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 byte timerMacro[] _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, 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, 0, 0, 0, 0, 0, 0, 0, 0 }));
WLED_GLOBAL byte timerMacro[] _INIT_N(({ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }));
//weekdays to activate on, 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 timerWeekday[] _INIT_N(({ 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 }));
//upper 4 bits start, lower 4 bits end month (default 28: start month 1 and end month 12)
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}));
WLED_GLOBAL byte timerMonth[] _INIT_N(({28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28}));
WLED_GLOBAL byte timerDay[] _INIT_N(({1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}));
WLED_GLOBAL byte timerDayEnd[] _INIT_N(({31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31}));
WLED_GLOBAL bool doAdvancePlaylist _INIT(false);

//improv
Expand Down
7 changes: 7 additions & 0 deletions wled00/wled_eeprom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,13 @@ void loadSettingsFromEEPROM()
if (timerWeekday[i] == 0) timerWeekday[i] = 255;
if (timerMacro[i] == 0) timerWeekday[i] = timerWeekday[i] & 0b11111110;
}

// Timers 8-17 are stored in cfg.json, not EEPROM, but still need default initialization
// Clear enabled bit for timers with no macro set
for (int i = 8; i < 18; ++i)
{
if (timerMacro[i] == 0) timerWeekday[i] = timerWeekday[i] & 0b11111110;
}
}

if (lastEEPROMversion > 8)
Expand Down
19 changes: 13 additions & 6 deletions wled00/xml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,16 +585,23 @@ void getSettingsJS(byte subPage, Print& settingsScript)
settingsScript.printf_P(PSTR("addRow(%d,%d,%d,%d);"), i++, button.macroButton, button.macroLongPress, button.macroDoublePress);
}

char k[4];
k[2] = 0; //Time macros
for (int i = 0; i<10; i++)
char k[5];
k[4] = 0; //Time macros - null terminate the buffer
for (int i = 0; i<18; i++)
{
k[1] = 48+i; //ascii 0,1,2,3
if (i<8) { k[0] = 'H'; printSetFormValue(settingsScript,k,timerHours[i]); }
if (i<10) {
k[1] = 48+i; //ascii 0-9
k[2] = 0;
} else {
k[1] = '1'; //tens digit
k[2] = 48+(i-10); //ones digit for 10-17
k[3] = 0;
}
if (i<16) { k[0] = 'H'; printSetFormValue(settingsScript,k,timerHours[i]); }
k[0] = 'N'; printSetFormValue(settingsScript,k,timerMinutes[i]);
k[0] = 'T'; printSetFormValue(settingsScript,k,timerMacro[i]);
k[0] = 'W'; printSetFormValue(settingsScript,k,timerWeekday[i]);
if (i<8) {
if (i<16) {
k[0] = 'M'; printSetFormValue(settingsScript,k,(timerMonth[i] >> 4) & 0x0F);
k[0] = 'P'; printSetFormValue(settingsScript,k,timerMonth[i] & 0x0F);
k[0] = 'D'; printSetFormValue(settingsScript,k,timerDay[i]);
Expand Down