Last active
January 22, 2025 08:01
-
-
Save jterrace/f412fdfac90687719cf3016ff968cc0b to your computer and use it in GitHub Desktop.
node-red code to pull calendar and push to eink
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Formats the given Date and returns map with format string parts. | |
const makeTimeFormatMap = function(date) { | |
const tz = Intl.DateTimeFormat().resolvedOptions().locale; | |
const dateTimeFormat = new Intl.DateTimeFormat(tz, { | |
month: 'short', | |
day: 'numeric', | |
weekday: 'short', | |
hour: 'numeric', | |
minute: 'numeric', | |
hour12: true, | |
}); | |
const partsMap = {}; | |
dateTimeFormat.formatToParts(date).map(({type, value}) => { | |
partsMap[type] = value | |
}) | |
partsMap.dayPeriod = partsMap.dayPeriod[0].toLowerCase(); | |
return partsMap; | |
}; | |
// Makes a Date from a date/time string. | |
const makeDate = function(dateString) { | |
if (dateString.includes("T")) { | |
return new Date(dateString); | |
} | |
// All day events just show up as "YYYY-MM-DD" with no | |
// time zone, so parse manually to make sure it's in "local" | |
// time zone. | |
var b = dateString.split(/\D/); | |
return new Date(b[0], b[1]-1, b[2]); | |
}; | |
// Returns an array of dates between the two time strings. | |
const getDaysArray = function (start, end) { | |
const days = []; | |
for (var dt = makeDate(start); dt <= makeDate(end); dt.setDate(dt.getDate() + 1)) { | |
days.push(new Date(dt)); | |
} | |
return days; | |
}; | |
const addEvent = function(events_by_date, date, dateStr, eventValue) { | |
events_by_date[date] = events_by_date[date] || {dateStr: dateStr, events: []}; | |
if (eventValue === null) return; | |
events_by_date[date].events.push(eventValue); | |
}; | |
const today = new Date(new Date().toDateString()); | |
const todayParts = makeTimeFormatMap(today); | |
const todayStr = `${todayParts.weekday} ${todayParts.month} ${todayParts.day}`; | |
const by_date = {}; | |
addEvent(by_date, today, todayStr, null); | |
for (const [calname, cal] of Object.entries(msg.payload)) { | |
for (const event of cal.events) { | |
const days = getDaysArray(event.start, event.end); | |
node.warn(days); | |
if (days.length == 1) { | |
const ts = days[0]; | |
const formatParts = makeTimeFormatMap(ts); | |
const dateStr = `${formatParts.weekday} ${formatParts.month} ${formatParts.day}`; | |
const timeStr = `${formatParts.hour}:${formatParts.minute}${formatParts.dayPeriod}`; | |
const dayDate = new Date(ts.toDateString()); | |
addEvent(by_date, dayDate, dateStr, timeStr + ' ' + event.summary); | |
continue; | |
} | |
// Multi day events end at midnight the day after, lop it off. | |
days.pop(); | |
for (const day of days) { | |
const dayDate = new Date(day.toDateString()); | |
if (dayDate < today) continue; | |
const formatParts = makeTimeFormatMap(day); | |
const dateStr = `${formatParts.weekday} ${formatParts.month} ${formatParts.day}`; | |
addEvent(by_date, dayDate, dateStr, event.summary); | |
} | |
} | |
} | |
node.warn(by_date); | |
const drawPayloads = []; | |
var largeSize = 30; | |
const sortedByDate = [...Object.keys(by_date)].sort(function (a, b) { | |
const x = new Date(a); | |
const y = new Date(b); | |
return x < y ? -1 : x > y ? 1 : 0; | |
}); | |
for (const dt of sortedByDate) { | |
drawPayloads.push( | |
{ | |
type: "text", | |
value: by_date[dt].dateStr, | |
font: "ppb.ttf", | |
x: 5, | |
size: largeSize, | |
color: "red" | |
}); | |
largeSize = 25; | |
if (by_date[dt].events.length > 0) { | |
drawPayloads.push( | |
{ | |
type: "multiline", | |
value: by_date[dt].events.join('|'), | |
delimiter: '|', | |
font: "rbm.ttf", | |
offset_y: 30, | |
x: 10, | |
size: 20, | |
y_padding: 5, | |
color: "black", | |
anchor: "la" | |
}); | |
} | |
} | |
node.warn(drawPayloads); | |
return {payload: drawPayloads }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Dear Jeff. Thanks a lot for the new skript...the both (or more?) calender words great. I spend now a lot of time in changing the 12h to 24h and the language...after a few hours trying (I´m not a programmer - only a user) I aked chatgpt...and this gave me a simple answer... and now it works perfekt: The only change that is nessesary is in row 3: change the value of "const tz":
here the example (see also the comments for the 12h to 24h-Change):
// Formats the given Date and returns map with format string parts.
const makeTimeFormatMap = function (date) {
const tz = "de-DE"; // Set locale to German
const dateTimeFormat = new Intl.DateTimeFormat(tz, {
month: 'short',
day: 'numeric',
weekday: 'short',
hour: 'numeric',
minute: 'numeric',
hour12: false, // For AM/PM format (can be removed if 24h format is preferred)
});
const partsMap = {};
dateTimeFormat.formatToParts(date).map(({ type, value }) => {
partsMap[type] = value;
});
partsMap.dayPeriod = partsMap.dayPeriod ? partsMap.dayPeriod[0].toLowerCase() : ''; // Adjust for AM/PM
return partsMap;
};
Later I had to adjust the writing: in Germany we do the day first, then the month...
I also had to adjust the size (thats what most people have to do to make it fit to their display) of the text an spaces between the lines because i only use a 1,54" display - i want to mount it into a electric-Socket in the bathroom...
Thanks a lot...