Read the statement by Michael Teeuw here.
2.32.0 Calendar module limitDays and excludedEvents stopped working
-
@AndyHazz found it…
comparing date AND TIME oops…
edit modules/default/calendar/calendar.js
approx line 708
change the lines marked below with //if (this.config.limitDays > 0) { let newEvents = []; let lastDate = today.clone().subtract(1, "days").startOf('day'); // add .startOf('day'), note dot let days = 0; for (const ev of events) { let eventDate = this.timestampToMoment(ev.startDate).startOf('day'); // add .startOf('day'), note dot -
@sdetweil nice! Yes that’s fixed the limitDays issue for me …
Now, how about part 2 of my issue, the excludedEvents config? The first event showing for me is titled ‘Tutor time’ despite that string being excluded. I’ve tried other terms with/without spaces and nothing seems to work to exclude events any more?
-
@AndyHazz working on it
-
@AndyHazz ok, got it too… this one looks like a javascript difference in scopes…
I added the Log.debug lines, they are not important
modules/default/calendar/calendarfetcherutils.js , starting line 18 (4 changes total)
see // change this lineshouldEventBeExcluded (config, title) { let result = { // change this line excluded: false, until: null }; for (let f in config.excludedEvents) { let filter = config.excludedEvents[f], // this line uses the same variable name, filter, now we have two, testTitle = title.toLowerCase(), until = null, useRegex = false, regexFlags = "g"; if (filter instanceof Object) { if (typeof filter.until !== "undefined") { until = filter.until; } if (typeof filter.regex !== "undefined") { useRegex = filter.regex; } // If additional advanced filtering is added in, this section // must remain last as we overwrite the filter object with the // filterBy string if (filter.caseSensitive) { filter = filter.filterBy; testTitle = title; } else if (useRegex) { filter = filter.filterBy; testTitle = title; regexFlags += "i"; } else { filter = filter.filterBy.toLowerCase(); } } else { filter = filter.toLowerCase(); } Log.debug("should be excluded ", testTitle, filter, useRegex, regexFlags) if (CalendarFetcherUtils.titleFilterApplies(testTitle, filter, useRegex, regexFlags)) { if (until) { result.until = until; // change this line } else { Log.debug("event should be excluded = true,", testTitle ) result.excluded = true; // change this line } Log.debug("filter applies result =", result) break; } } Log.debug("filter applies returning =", result) return result; // change this line }, -
@sdetweil perhaps I’m missing something, but that’s not working for me - it’s made no difference, excluded events are still appearing … I’ve double checked and can’t spot anything amiss, I’ve made the 4 changes from ‘filter’ to ‘result’?
-
@AndyHazz hm…
my config parm for excluded EventsI added one event for saturday… without excluded it shows, with excluded it doesn’t
excludedEvents: [ 'Birthday' ],I checked the changed lines and only see those 4
- is old line
+ is new line* until: the date until the event should be excluded. */ shouldEventBeExcluded (config, title) { - let filter = { + let result = { excluded: false, until: null }; @@ -52,17 +52,20 @@ const CalendarFetcherUtils = { } else { filter = filter.toLowerCase(); } if (CalendarFetcherUtils.titleFilterApplies(testTitle, filter, useRegex, regexFlags)) { if (until) { - filter.until = until; + result.until = until; } else { - filter.excluded = true; + result.excluded = true; } break; } } - return filter; + return result; }, -
@sdetweil yep that’s what I’ve got, copying below in case I’m missing something …
I’ve also added your debug messages back in and changed Log.debug to console.log (as I still can’t get any debug logs from docker but I do get console.log messages from other modules) but nothing comes out in the console log - seems odd that all these changes have had zero effect, am I missing something that might be needed to get these changes to kick in?
shouldEventBeExcluded (config, title) { let result = { // CHANGED excluded: false, until: null }; for (let f in config.excludedEvents) { let filter = config.excludedEvents[f], testTitle = title.toLowerCase(), until = null, useRegex = false, regexFlags = "g"; if (filter instanceof Object) { if (typeof filter.until !== "undefined") { until = filter.until; } if (typeof filter.regex !== "undefined") { useRegex = filter.regex; } // If additional advanced filtering is added in, this section // must remain last as we overwrite the filter object with the // filterBy string if (filter.caseSensitive) { filter = filter.filterBy; testTitle = title; } else if (useRegex) { filter = filter.filterBy; testTitle = title; regexFlags += "i"; } else { filter = filter.filterBy.toLowerCase(); } } else { filter = filter.toLowerCase(); } console.log("should be excluded ", testTitle, filter, useRegex, regexFlags) if (CalendarFetcherUtils.titleFilterApplies(testTitle, filter, useRegex, regexFlags)) { if (until) { result.until = until; // CHANGED } else { console.log("event should be excluded = true,", testTitle ) result.excluded = true; // CHANGED } console.log("filter applies result =", result) break; } } console.log("filter applies returning =", result) return result; // CHANGED },p.s. just spotted comment on line 12 😅
TODO This seems like an overly complicated way to exclude events based on the title. -
@AndyHazz note that the excluded events is an ARRAY (so for loop to look thru them )
test ALL til find one that is true (CalendarFetcherUtils.titleFilterApplies returns true) , or notAND the item in the array can be an object with more specific controls, or a string
MM doc entries on separate lines
[ 'Birthday', // text 'Hide This Event', // text {filterBy: 'Payment', until: '6 days', caseSensitive: true}, // complex, but text {filterBy: '^[0-9]{1,}.*', regex: true} // complex, uses regex ]AND the list/array can be a MIX of those things,
and the string test is the test string is SOMEWHERE in the title, doesn’t have to BE the entire title
-
@sdetweil fair enough, complexity no doubt warranted!
Perhaps is there any reason why shouldEventBeExcluded function might not be getting called at all for me? I’m stumped why after making all these changes including console.log messages, nothing is appearing any different -
-
@AndyHazz can’t think of any, MM is case sensitive, some times people get the case wrong and we don’t report unexpected parms or missing parms…
but you’ve been using that so, it doesn’t shouldn’t be an issue for you
-
@AndyHazz I copied your post in exactly, i reverted back to 2.32 original first
and got the right debug and results
[2025-07-09 16:27:38.473] [DEBUG] Processing entry…
[2025-07-09 16:27:38.473] [DEBUG] title: Dad’s Birthday
[2025-07-09 16:27:38.473] [LOG] should be excluded dad’s birthday birthday false g
[2025-07-09 16:27:38.473] [LOG] event should be excluded = true, dad’s birthday
[2025-07-09 16:27:38.473] [LOG] filter applies result = { excluded: true, until: null }
[2025-07-09 16:27:38.473] [LOG] filter applies returning = { excluded: true, until: null } -
@AndyHazz and
the fetcherutils processes this exclude list very early after getting the events parsed
// loop thru the parsed data, one event at a time Object.entries(data).forEach(([key, event]) => { Log.debug("Processing entry..."); const title = CalendarFetcherUtils.getTitleFromEvent(event); Log.debug(`title: ${title}`); // Return quickly if event should be excluded. let { excluded, eventFilterUntil } = this.shouldEventBeExcluded(config, title); if (excluded) { return; } -
@sdetweil should I see a console message from loader.js about calendarfetcherutils.js being loaded?
I see
Load script: modules/default/calendar/calendar.js Load script: modules/default/calendar/calendarutils.jsbut no mention in the console of calendarfetcherutils.js
-
@AndyHazz no.
-
@sdetweil I’ve no idea then, but if you were able to reproduce the issue I had, and then fix it on your end, I probably just messed something up somewhere and without any access to logs on my docker setup that may remain a mystery … I’ve just had another go at trying to figure out what that may be, no luck.
No rush at all but I guess if you’re happy with the fix it’ll show up in a new MM version at some point and I’ll update to that.
-
@AndyHazz next release isn’t til Oct 1
-
@AndyHazz weird…
-
@AndyHazz would you be willing to test another implementation of the limitDays code fix
another author has changed the code quite a bit,
copy the existing calendar.js so not losing what you have
new codeif (this.config.limitDays > 0 && events.length>0) { // line 708 // Group all events by date, events on the same date will be in a list with the key being the date. Log.info("limitdays starting, events list length=", events.length) const eventsByDate = Object.groupBy(events, (ev) => this.timestampToMoment(ev.startDate).format("YYYY-MM-DD")); Log.info("eventsByDate keys=",Object.keys(eventsByDate)) const newEvents = []; let currentDate = moment().subtract(1,'days'); let daysCollected = 0; while (daysCollected < this.config.limitDays) { const dateStr = currentDate.format("YYYY-MM-DD"); Log.info("limitDays checking=",dateStr) // Check if there are events on the currentDate if (eventsByDate[dateStr]) Log.info("eventsByDate[",dateStr,"] length=",eventsByDate[dateStr].length) if (eventsByDate[dateStr] && eventsByDate[dateStr].length > 0) { // If there are any events today then get all those events and select the currently active events and the events that are starting later in the day. newEvents.push(...eventsByDate[dateStr].filter((ev) => this.timestampToMoment(ev.endDate).isAfter(moment()))); // Since we found a day with events, increase the daysCollected by 1 daysCollected++; Log.info("limitDays, found day with events, count=",daysCollected) } // Search for the next day currentDate.add(1, "day"); } Log.info("limitDays done") events = newEvents; }this line is unchanged after replacing above code
Log.info(`slicing events total maxcount=${this.config.maximumEntries}`); // this line is unchanged -
@sdetweil no problem, that new code seems to work fine for me.
However, I don’t seem to have a great setup for testing - after making the changes, I can load up MM in my remote/laptop browser and immediately see the changes working, but if I try and refresh the electron browser on the raspberry pi running my mirror (using MMM-Remote-Control), it seems to take ages, crash, and then reverts the code back to the docker image default 😮💨
I can see this in the docker container logs so I reckon it’s reverting any changes I make there?
[entrypoint 18:36:04.283] [INFO] copy default modules [entrypoint 18:36:04.918] [INFO] copy css files > magicmirror@2.32.0 start > node --run start:x11 -
@AndyHazz said in 2.32.0 Calendar module limitDays and excludedEvents stopped working:
I can see this in the docker container logs so I reckon it’s reverting any changes I make there?
yes it overrides the default modules but you can change this behavior
Hello! It looks like you're interested in this conversation, but you don't have an account yet.
Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.
With your input, this post could be even better 💗
Register Login