Znalazłem ten “magiczny” sposób, działa tak jak to sobie założyłem i jak chciałem żeby działał. Dzielę się swoją pracą, może komuś się przyda.
Zaczynamy od instalacji dodatku ALT + SHIFT + P
→ Install
→ node-red-contrib-html-pro
.
Kod FLOW do importu:
[
{
"id": "dcbd23739adda60d",
"type": "inject",
"z": "c617c3f41b6c4831",
"name": "Codziennie o 6:00",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "00 06 * * *",
"once": true,
"onceDelay": "0.1",
"topic": "",
"payload": "",
"payloadType": "date",
"x": 230,
"y": 5320,
"wires": [
[
"8b664a9fefb8fdfa"
]
]
},
{
"id": "8b664a9fefb8fdfa",
"type": "function",
"z": "c617c3f41b6c4831",
"name": "Ustaw start i end daty",
"func": "const now = new Date();\n\n// Ustaw start na dzisiaj, godzina 00:00:00\nconst startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);\nconst start = startDate.toISOString();\n\n// Ustaw end na 3 dni później, o 23:59:59\nconst endDate = new Date(startDate);\nendDate.setDate(endDate.getDate() + 3);\nendDate.setHours(23, 59, 59);\nconst end = endDate.toISOString();\n\nmsg.start = start;\nmsg.end = end;\nreturn msg;\n",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 395,
"y": 5340,
"wires": [
[
"695f194cdf1b97f0",
"bd6b2ce4300e5f74",
"058654d44cde1680"
]
],
"l": false
},
{
"id": "695f194cdf1b97f0",
"type": "http request",
"z": "c617c3f41b6c4831",
"name": "Kalendarz Familijny",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "bearer",
"senderr": false,
"headers": [],
"x": 570,
"y": 5300,
"wires": [
[
"fdede8368d9a2516"
]
]
},
{
"id": "bd6b2ce4300e5f74",
"type": "http request",
"z": "c617c3f41b6c4831",
"name": "Kalendarz Sprawdziany",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "bearer",
"senderr": false,
"headers": [],
"x": 590,
"y": 5340,
"wires": [
[
"fdede8368d9a2516"
]
]
},
{
"id": "fdede8368d9a2516",
"type": "join",
"z": "c617c3f41b6c4831",
"name": "Połącz wyniki kalendarzy",
"mode": "custom",
"build": "array",
"property": "payload",
"propertyType": "msg",
"key": "topic",
"joiner": "\\n",
"joinerType": "str",
"useparts": true,
"accumulate": false,
"timeout": "",
"count": "3",
"reduceRight": false,
"reduceExp": "",
"reduceInit": "",
"reduceInitType": "",
"reduceFixup": "",
"x": 880,
"y": 5340,
"wires": [
[
"8e8c3d1213f92cba"
]
]
},
{
"id": "8e8c3d1213f92cba",
"type": "function",
"z": "c617c3f41b6c4831",
"name": "Przetwarzanie wydarzeń",
"func": "const allEvents = [];\n\n// msg.payload to tablica z 2 tablicami wydarzeń\nfor (const events of msg.payload) {\n if (Array.isArray(events)) {\n allEvents.push(...events);\n }\n}\n\nconst now = new Date();\nconst today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\nconst oneDayMs = 24 * 60 * 60 * 1000;\n\nconst grouped = {0: [], 1: [], 2: []};\n\nfor (const event of allEvents) {\n let startDateStr = null;\n\n if (typeof event.start === 'string') {\n startDateStr = event.start;\n } else if (event.start && event.start.dateTime) {\n startDateStr = event.start.dateTime;\n } else if (event.start && event.start.date) {\n startDateStr = event.start.date;\n }\n\n if (!startDateStr || !event.summary) continue;\n\n const startDate = new Date(startDateStr);\n const diffMs = startDate.getTime() - today.getTime();\n const dayDiff = Math.floor(diffMs / oneDayMs);\n\n if (dayDiff >= 0 && dayDiff <= 2) {\n const time = (event.start && event.start.dateTime)\n ? startDate.toLocaleTimeString('pl-PL', { hour: '2-digit', minute: '2-digit' })\n : \"\";\n const line = time ? `${time} – ${event.summary}` : event.summary;\n grouped[dayDiff].push(line);\n }\n}\n\nfunction formatMessages(grouped) {\n let msgText = \"\";\n if (grouped[0].length) {\n msgText += \"Dzisiaj:\\n\" + grouped[0].join('\\n') + \"\\n\\n\";\n }\n if (grouped[1].length) {\n msgText += \"Jutro:\\n\" + grouped[1].join('\\n') + \"\\n\\n\";\n }\n if (grouped[2].length) {\n msgText += \"Pojutrze:\\n\" + grouped[2].join('\\n') + \"\\n\\n\";\n }\n if (!msgText) {\n msgText = \"Brak wydarzeń na najbliższe dni.\";\n }\n return msgText;\n}\n\nconst formatted = formatMessages(grouped);\n\nmsg.wiadomosc = {\n temat: \"Wydarzenia kalendarza\",\n tresc: formatted,\n typ: \"technical\"\n};\n\nreturn msg;\n",
"outputs": 1,
"timeout": "",
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 1150,
"y": 5340,
"wires": [
[
"df2d46dc2b60fedd"
]
]
},
{
"id": "df2d46dc2b60fedd",
"type": "debug",
"z": "c617c3f41b6c4831",
"name": "kal Wszystko",
"active": false,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "true",
"targetType": "full",
"statusVal": "",
"statusType": "auto",
"x": 1370,
"y": 5340,
"wires": []
},
{
"id": "058654d44cde1680",
"type": "http request",
"z": "c617c3f41b6c4831",
"name": "Kalendarz Prywatny",
"method": "GET",
"ret": "obj",
"paytoqs": "ignore",
"url": "",
"tls": "",
"persist": false,
"proxy": "",
"insecureHTTPParser": false,
"authType": "bearer",
"senderr": false,
"headers": [],
"x": 580,
"y": 5380,
"wires": [
[
"fdede8368d9a2516"
]
]
},
{
"id": "6db016f4a9942bdc",
"type": "inject",
"z": "c617c3f41b6c4831",
"name": "Codziennie o 20:00",
"props": [
{
"p": "payload"
}
],
"repeat": "",
"crontab": "00 20 * * *",
"once": true,
"onceDelay": "0.1",
"topic": "",
"payload": "",
"payloadType": "date",
"x": 240,
"y": 5360,
"wires": [
[
"8b664a9fefb8fdfa"
]
]
}
]
NOD Kalendarz NAZWA_KALENDARZA:
URL: https://ADRES_HOME_ASSISTANTA/api/calendars/calendar.NAZWA_KALENDARZA?start={{start}}&end={{end}}
jeżeli podajemy adres IP do HA to na końcu musi być port /:8123
NAZWA_KALENDARZA podajemy nazwę z HA, możemy ją sprawdzić w Narzędzia deweloperskie
→ Aktualne stany encji
w Filtr encji
wpisując calendar
TOKEN: musimy go utworzyć w HA Profil
→ Bezpieczeństwo
→ Długotrwałe tokeny dostępu
, jeden token powinien się nadać dla kilku kalendarzy.
Dodając lub odejmując kalendarz wpisujemy ilość kalendarzy w NODZIE Połącz wyniki kalendarzy
→ Send the message:
→ After a number of message parts
.
Powyższy kod pobiera dane kalendarza od godziny 00:00 dnia pierwszego do 23:59 dnia trzeciego, jeżeli chcemy aby podawało tylko wydarzenia aktywne od chwili wywołania to edytujemy NOD Ustaw start i end daty
i wklejamy poniższy kod.
const now = new Date();
const start = now.toISOString();
const endDate = new Date(now);
endDate.setDate(endDate.getDate() + 3);
const end = endDate.toISOString();
msg.start = start;
msg.end = end;
return msg;
Wyjściowy komunikat jest skonfigurowany tak aby działał z powiadomieniami utworzonymi przez @artur w poradniku Procesy z życia wzięte - Powiadomienia, typy powiadomień .