Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
583fdd0
add 8 more macro slots
benjamw Nov 30, 2025
9740a29
convert to vectors
benjamw Dec 1, 2025
5cde8b8
implement suggestions
benjamw Dec 2, 2025
492972e
Update wled00/cfg.cpp
benjamw Dec 2, 2025
017a062
more suggestions
benjamw Dec 2, 2025
383440c
Merge branch 'more_macros' of github.com:benjamw/WLED into more_macros
benjamw Dec 2, 2025
acf0153
UI fixes
benjamw Dec 2, 2025
a1b5cb8
no eeprom compatibility
benjamw Dec 3, 2025
053a18c
tighten up code
benjamw Dec 3, 2025
5092f18
fix sunrise/sunset issue
benjamw Dec 3, 2025
e93732a
fix issue with sunrise/sunset/regular selector
benjamw Dec 12, 2025
7943559
preset dropdowns
benjamw Dec 12, 2025
36fa6a7
sort before use
benjamw Dec 12, 2025
b38df55
delete timer when preset = 0
benjamw Dec 15, 2025
b2103ad
truncate long names and add sort options
benjamw Dec 15, 2025
460c0da
html updates
benjamw Dec 16, 2025
7668967
Merge with main
benjamw Dec 16, 2025
0a167e8
fix save bug
benjamw Dec 16, 2025
69ae2e1
make boxes a bit darker
benjamw Dec 17, 2025
c2a3269
add fallback if localStorage is empty
benjamw Jan 6, 2026
83d185a
Merge branch 'main' into more_macros
benjamw Feb 20, 2026
8122f90
remove sort option
benjamw Feb 20, 2026
7fded88
code rabbit suggested fixes
benjamw Feb 20, 2026
465667d
remove css
benjamw Feb 20, 2026
7473aa3
restyling
benjamw Feb 20, 2026
2679217
common
benjamw Feb 20, 2026
cd24fe9
dry preset loading
benjamw Feb 20, 2026
93ba3b3
revert missing const
benjamw Feb 20, 2026
0a4df0b
update deep sleep usermod with new timer struct
benjamw Feb 20, 2026
fdc01f2
tabs
benjamw Feb 20, 2026
2bd27b8
Revert "tabs"
benjamw Feb 20, 2026
2060a6f
remove unneeded clamp checks
benjamw Feb 20, 2026
40dde13
leave index alone
benjamw Feb 20, 2026
d6a4379
remove useless check
benjamw Feb 21, 2026
d34eb43
fix up await functions
benjamw Feb 21, 2026
f7495e6
only fetch localstorage
benjamw Feb 22, 2026
eba81ee
inline single line function
benjamw Mar 6, 2026
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
39 changes: 20 additions & 19 deletions usermods/deep_sleep/deep_sleep.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,28 +89,29 @@ class DeepSleepUsermod : public Usermod {
int currentWeekday = weekdayMondayFirst(); // 1=Monday ... 7=Sunday
int minDifference = INT_MAX;

for (uint8_t i = 0; i < 8; i++) {
// check if timer is enabled and date is in range, also wakes up if no macro is used
if ((timerWeekday[i] & 0x01) && isTodayInDateRange(((timerMonth[i] >> 4) & 0x0F), timerDay[i], timerMonth[i] & 0x0F, timerDayEnd[i])) {
for (size_t i = 0; i < timers.size(); i++) {
const Timer& t = timers[i];
// only regular enabled timers with valid date range can be used for wake scheduling
if (!t.isEnabled() || !t.isRegular()) continue;
if (!isTodayInDateRange(t.monthStart, t.dayStart, t.monthEnd, t.dayEnd)) continue;

// if timer is enabled (bit0 of timerWeekday) and date is in range, check all weekdays it is set for
for (int dayOffset = 0; dayOffset < 7; dayOffset++) {
int checkWeekday = ((currentWeekday + dayOffset) % 7); // 1-7, check all weekdays starting from today
if (checkWeekday == 0) {
checkWeekday = 7; // sunday is 7 not 0
}
// check all weekdays for the current timer, starting from today
for (int dayOffset = 0; dayOffset < 7; dayOffset++) {
int checkWeekday = (currentWeekday + dayOffset) % 7; // 1-7, check all weekdays starting from today
if (checkWeekday == 0) {
checkWeekday = 7; // sunday is 7 not 0
}

int targetHour = timerHours[i];
int targetMinute = timerMinutes[i];
if ((timerWeekday[i] >> (checkWeekday)) & 0x01) {
if (dayOffset == 0 && (targetHour < currentHour || (targetHour == currentHour && targetMinute <= currentMinute)))
continue; // skip if time has already passed today
int targetHour = t.hour;
int targetMinute = t.minute;
if ((t.weekdays >> checkWeekday) & 0x01) {
if (dayOffset == 0 && (targetHour < currentHour || (targetHour == currentHour && targetMinute <= currentMinute)))
continue; // skip if time has already passed today

int timeDifference = calculateTimeDifference(currentHour, currentMinute, targetHour + (dayOffset * 24), targetMinute);
if (timeDifference < minDifference) {
minDifference = timeDifference;
wakeupPreset = timerMacro[i];
}
int timeDifference = calculateTimeDifference(currentHour, currentMinute, targetHour + (dayOffset * 24), targetMinute);
if (timeDifference < minDifference) {
minDifference = timeDifference;
wakeupPreset = t.preset;
}
}
}
Expand Down
83 changes: 36 additions & 47 deletions wled00/cfg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,37 +689,28 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
CJSON(macroCountdown, cntdwn["macro"]);
setCountdown();

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
CJSON(timerHours[it], timer[F("hour")]);
CJSON(timerMinutes[it], timer["min"]);
CJSON(timerMacro[it], timer["macro"]);

byte dowPrev = timerWeekday[it];
//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
int actPrev = timerWeekday[it] & 0x01;
CJSON(timerWeekday[it], timer[F("dow")]);
if (timerWeekday[it] != dowPrev) { //present in JSON
timerWeekday[it] <<= 1; //add active bit
int act = timer["en"] | actPrev;
if (act) timerWeekday[it]++;
}
if (it<8) {
JsonObject start = timer["start"];
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
JsonArray timersArray = tm["ins"];
if (!timersArray.isNull()) {
clearTimers();
for (JsonObject timer : timersArray) {
uint8_t h = timer[F("hour")] | 0;
int8_t m = timer[F("min")] | 0;
uint8_t p = timer[F("macro")] | 0;
uint8_t dow = timer[F("dow")] | 127;
uint8_t wd = (dow << 1) | ((timer[F("en")] | 0) ? 1 : 0);
uint8_t ms = 1, me = 12, ds = 1, de = 31;
JsonObject start = timer[F("start")];
if (!start.isNull()) {
ms = start[F("mon")] | 1;
ds = start[F("day")] | 1;
}
JsonObject end = timer[F("end")];
if (!end.isNull()) {
me = end[F("mon")] | 12;
de = end[F("day")] | 31;
}
addTimer(p, h, m, wd, ms, me, ds, de);
}
it++;
}

JsonObject ota = doc["ota"];
Expand Down Expand Up @@ -1216,23 +1207,21 @@ void serializeConfig(JsonObject root) {
cntdwn["macro"] = macroCountdown;

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

for (unsigned i = 0; i < 10; 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) {
JsonObject start = timers_ins0.createNestedObject("start");
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];
}
for (size_t i = 0; i < ::timers.size(); i++) {
const Timer& t = ::timers[i];
if (t.preset == 0 && t.hour == 0 && t.minute == 0) continue;
JsonObject ti = timers_ins.createNestedObject();
ti[F("en")] = t.isEnabled() ? 1 : 0;
ti[F("hour")] = t.hour;
ti[F("min")] = t.minute;
ti[F("macro")] = t.preset;
ti[F("dow")] = t.weekdays >> 1;
JsonObject start = ti.createNestedObject(F("start"));
start[F("mon")] = t.monthStart;
start[F("day")] = t.dayStart;
JsonObject end = ti.createNestedObject(F("end"));
end[F("mon")] = t.monthEnd;
end[F("day")] = t.dayEnd;
}

JsonObject ota = root.createNestedObject("ota");
Expand Down
2 changes: 2 additions & 0 deletions wled00/const.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ constexpr size_t FIXED_PALETTE_COUNT = DYNAMIC_PALETTE_COUNT + FASTLED_PALETTE_C
#define WLED_MAX_RMT_CHANNELS 0 // ESP8266 does not have RMT nor I2S
#define WLED_MAX_I2S_CHANNELS 0
#define WLED_MAX_ANALOG_CHANNELS 5
#define WLED_MAX_TIMERS 16 // reduced limit for ESP8266 due to memory constraints
#define WLED_PLATFORM_ID 0 // used in UI to distinguish ESP types, needs a proper fix!
#else
#if !defined(LEDC_CHANNEL_MAX) || !defined(LEDC_SPEED_MODE_MAX)
Expand Down Expand Up @@ -86,6 +87,7 @@ constexpr size_t FIXED_PALETTE_COUNT = DYNAMIC_PALETTE_COUNT + FASTLED_PALETTE_C
//#define WLED_MAX_ANALOG_CHANNELS 16
#define WLED_PLATFORM_ID 4 // used in UI to distinguish ESP type in UI, needs a proper fix!
#endif
#define WLED_MAX_TIMERS 64 // maximum number of timers
#define WLED_MAX_DIGITAL_CHANNELS (WLED_MAX_RMT_CHANNELS + WLED_MAX_I2S_CHANNELS)
#endif
// WLED_MAX_BUSSES was used to define the size of busses[] array which is no longer needed
Expand Down
2 changes: 1 addition & 1 deletion wled00/data/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function loadJS(FILE_URL, async = true, preGetV = undefined, postGetV = undefine
scE.setAttribute("type", "text/javascript");
scE.setAttribute("async", async);
d.body.appendChild(scE);
// success event
// success event
scE.addEventListener("load", () => {
//console.log("File loaded");
if (preGetV) preGetV();
Expand Down
Loading
Loading