Daily agenda view module of MagicMirror².

This is a sibling module of [MMM-CalendarExt3](https://github.com/MMRIZE/MMM-CalendarExt3). This module is made to be an alternative to my previous module MMM-CalendarExt2, especially daily, current and upcoming views.
CX2.calendar. (It means the calendar module is REQUIRED to use this module.)CX3MMM-CalendarExt3. But of course, you can use them together.
config.js.cd ~/MagicMirror/modules
git clone https://github.com/MMRIZE/MMM-CalendarExt3Agenda
cd MMM-CalendarExt3Agenda
npm install --omit=dev
Note: npm install is necessary to install the submodule.
cd ~/MagicMirror/modules/MMM-CalendarExt3Agenda
git pull
npm install --omit=dev
When some submodule is not updated, try this.
cd ~/MagicMirror/modules/MMM-CalendarExt3Agenda
git submodule update --init --recursive
If you want to return to 1.4.6 version,
cd ~/MagicMirror/modules/MMM-CalendarExt3Agenda
git switch --detach dev-1.4.6
Anyway, even this simplest will work.
{
module: "MMM-CalendarExt3Agenda",
position: "top_left",
},
More conventional;
{
module: "MMM-CalendarExt3Agenda",
position: "top_left",
header: "My Agenda",
config: {
instanceId: "basicCalendar",
locale: 'de-DE',
firstDayOfWeek: 1,
startDayIndex: -1,
endDayIndex: 10,
calendarSet: ['us_holiday', 'abfall', 'mytest'],
...
}
},
You need setup default calendar configuration also.
/* default/calendar module configuration */
{
module: "calendar",
position: "top_left",
config: {
broadcastPastEvents: true, // <= IMPORTANT to see past events
calendars: [
{
url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics",
name: "us_holiday", // <-- specify calendar name
color: "skyblue", // <-- if you don't want to get color, just remove this line.
broadcastPastEvents: true, // <-- need to broadcast past events
maximalNumberOfDays: 30, // <-- how old events would be broadcasted
maximumEntries: 100, // <-- assign enough number to prevent truncating new events by old events.
symbol: 'camera', // <-- when you want to display simbol. If you don't want, just set as `symbol:[],`
},
...
All the properties are omittable, and if omitted, a default value will be applied.
| property | default | description |
|---|---|---|
startDayIndex |
0 | Begining day of the view from today. -1 means yesterday. 0 would be today. |
endDayIndex |
10 | Ending day of the view from today. 10 means 10 days after. |
locale |
(language of MM config) |
de or ko-KR or ja-Jpan-JP-u-ca-japanese-hc-h12. It defines how to handle and display your date-time values by the locale. When omitted, the default language config value of MM. |
calendarSet |
[] | When you want to display only selected calendars, fulfil this array with the targeted calendar name(of the default calendar module). |
e.g) calendarSet: ['us_holiday', 'office'],
[] or null will allow all the calendars. |
|instanceId | (auto-generated) | When you want more than 1 instance of this module, each instance would need this value to distinguish each other. If you don't assign this property, the identifier of the module instance will be assigned automatically but not recommended to use it. (Hard to guess the auto-assigned value.)|
|firstDayOfWeek| 1 | Monday is the first day of the week according to the international standard ISO 8601, but in the US, Canada, Japan and some cultures, it's counted as the second day of the week. If you want to start the week from Monday, set this property to 1. If you want Sunday, set 0.
Sunday:0, Monday:1, Tuesday:2, ..., Saturday:6
This option is only for using calendarweek (CW) showing. That is hidden by default, so you can ignore this.|
|minimalDaysOfNewYear | 4 | ISO 8601 also says each week's year is the Gregorian year in which the Thursday falls. The first week of the year, hence, always contains 4 January. However, the US (Yes, it is.) system differs from standards. In the US, containing 1 January defines the first week. In that case, set this value to 1. And under some other culture, you might need to modify this.
This option is only for using calendarweek (CW) showing. That is hidden by default, so you can ignore this.|
|cellDateOptions | {month: 'short',
day: 'numeric'} | The format of day cell date. It varies by the locale and this option.
locale:'en-US', the default displaying will be Jun 1.
See options |
|eventTimeOptions | {timeStyle: 'short'} | The format of event time. It varies by the locale and this option.
locale:'en-US', the default displaying will be 3:45 pm.
See options |
|eventFilter| callback function | See the Filtering part.|
|eventTransformer| callback function | See the Transforming part.|
|displayRepeatingCountTitle | true | When true, allows the full event title to be visible (no overflow clipping) in fullday event cells. Intended for use with eventTransformer to append a repeating count (e.g. number of years) to anniversary-style events. |
|waitFetch| 5000 | (ms) waiting the fetching of last calendar to prevent flickering view by too frequent fetching. |
|refreshInterval| 1800000 | (ms) refresh view by force if you need it. |
|animationSpeed | 1000 | (ms) Refreshing the view smoothly. |
|useSymbol | true | Whether to show font-awesome symbold instead of simple dot icon. |
|eventNotification| 'CALENDAR_EVENTS' | A carrier notification of event source.|
|eventPayload | callback function | A converter for event payload before using it.|
|useWeather | true | Whether to show forecasted weather information of default weather module. |
|weatherLocationName | null | When you have multi forecasting instances of several locations, you can describe specific weather location to show. |
|weatherNotification| 'WEATHER_UPDATED' | A carrier notification of weather forecasting source |
|weatherPayload | callback function | A converter for weather foracasting payload before using it. |
|showMiniMonthCalendar | true | Show mini monthly calendar. |
|showMiniMonthCalendarMonths | 1 | Number of months to show in the mini calendar (1–6). Useful at the end of a month to already see the next one. |
|miniMonthTitleOptions | { month: 'long', year: 'numeric' } | Title of month calendar (e.g. Aug. 2022) |
|miniMonthWeekdayOptions | { weekday: 'short' } | A name of weekday of month calendar (e.g. Mon) |
|onlyEventDays | 0 | 0 or false show empty days, N:Integer bigger than 0 will show N days which have event(s) in that day.|
|showMultidayEventsOnce | false | When true, each multiday event appears only once in the visible range (pinned to its first visible day) instead of repeating on every day it spans. |
|multidayRangeLabelOptions | { month: 'short', day: 'numeric' } | Format for the date range label shown on a multiday event when showMultidayEventsOnce is enabled. See Intl.DateTimeFormat options. |
|skipDuplicated | true | On true, duplicated events(same title, same start/end) from any calendars will be skipped except one. |
|relativeNamedDayOptions| { style: 'long' } | A name of the relative name (e.g. "Today" or "In 2 days" |
CALENDAR_EVENTSAny module which can emit this notification could become the source of this module. Generally, the default calendar module would be.
WEATHER_UPDATEDAny module which can emit this notification could become the source of weather forecasting. Generally, the default weather module would be.
CX3A_GET_CONFIG payload: { callback }You can get config information of current view. The result will be obtained by the callback function.
this.sendNotification('CX3A_GET_CONFIG', {
callback: (result) => {
console.log(result.locale)
}
})
CX3A_SET_CONFIG payload: { ...configObj, callback }You can override or set new config by this notification.
CX3A_RESET payload: { callback }You can restore the original config.
The next example shows a glance of the next week's schedule by notification chain.
this.sendNotification('CX3A_GET_CONFIG', {
callback: (current) => {
this.sendNotification('CX3A_SET_CONFIG', {
startDayIndex: current.startDayIndex + 7,
endDayIndex: current.endDayIndex + 7,
})
setTimeout(() => {
this.sendNotification('CX3A_RESET')
}, 60_000)
}
})
Nothing yet. (Does it need?)
You can handle almost all of the visual things with CSS. See the MMM-CalendarExt3Agenda.css and override your needs into your custom.css.
- CX3A, CX3A_{instanceId} : The root selector. Each instance of this module will have CX3A_{instanceId} as another root selector. With this CSS selector, you can assign individual look to each instance.
.cell : Every day cell has this selector. Each cell could have these class name together by its condition..today, .thisMonth, .thisYear.year_2022, .month_12, .date_25, .weekday_0, .week_52.cellHeader, .cellFooter : Parts of day cell. .cellHeader would have .cellHeaderMain and .cellHeaderSub as children..cellHeader.cellHeaderMain.cellDay.dateParts.cellDate.dateParts.cw (hidden by default).cellHeaderSub.cellWeather.maxTemp.temperature.minTemp.temperature.wi.cellBody (events would be located here).cellFooter (currently not used)
.cellDay, .cellDate : Displaying date of the cell. The date would have many parts of date/hour information(.dateParts).
.event : Every event has this selector. Each event could have these class name together by its condition.
.calendar_{calendarName}, {class} : Orginal calendar.passed, .future, .current,.multiday, .singleday, .fulldayAnd event also has dataSet (data-*) as its attributes. (e.g. data-title="...", data-start-date="...") You can use these attributes also.
.event.headline.symbol.time.startTime.dateParts.time.endTime.dateParts.title.description.locationEach event component would be shown/hidden by the virtues of events. Of course, you can redeclare its behaviours with CSS.
Each event object has this structure.
{
"title": "Leeds United - Chelsea",
"startDate": 1650193200000,
"endDate": 1650199500000,
"fullDayEvent": false,
"class": "PUBLIC",
"location": false,
"geo": false,
"description": "...",
"today": false,
"symbol": ["calendar-alt"],
"calendarName": "tottenham",
"color": "gold",
"calendarSeq": 1, // This would be the order from `calendarSet` of configuration
"isPassed": true,
"isCurrent": false,
"isFuture": false,
"isFullday": false,
"isMultiday": false
}
You can use these values to handle events.
You can filter each event by its condition.
eventFilter: (ev) => {
if (ev.isFullday) return false
return true
}
This example shows how you can filter out 'fullday' events.
You can manipulate or change the properties of the event.
eventTransformer: (ev) => {
if (ev.title.search('John') > -1) ev.color = 'blue'
return ev
}
This example shows how you can transform the color of events when the event title has specific text.
You can convert or transform the payload of incoming notification instantly before used in this module. It would be convenient when conversion or manipulating payload from uncompatible module.
weatherPayload: (payload) => {
if (Array.isArray(payload?.forecastArray)) {
payload.forecastArray = payload.forecastArray.map((f) => {
f.maxTemperature = Math.round(f.maxTemperature * 9 / 5 + 32)
f.minTemperature = Math.round(f.minTemperature * 9 / 5 + 32)
return f
})
}
return payload
},
This example show how to transform Celcius temperature to Fahrenheit units. (Original default weather module has a bug to deliver Fahrenheit temperature of broadcasted forecasts.)
calendar or equiva$ claude mcp add MMM-CalendarExt3Agenda \
-- python -m otcore.mcp_server <graph>