Created
January 6, 2026 20:28
-
-
Save gbasile/e35bc2b5ecdefe77a374567c2d79d813 to your computer and use it in GitHub Desktop.
Blueprint Calendar
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
| blueprint: | |
| name: Giuseppe MatrixLed Calendar Notifier | |
| description: "Displays upcoming calendar events on AWTRIX LED matrix displays. | |
| **Features:** | |
| - Monitors multiple calendars simultaneously | |
| - Shows all upcoming events within a configurable time window | |
| - Displays day-of-month icons (1-31) for each event | |
| - Automatically calculates and displays age for birthday events (e.g., 'Birthday 1984' becomes 'Birthday 41') | |
| - Smart time display: shows time for timed events, omits for all-day events | |
| - Updates every 5 minutes and on Home Assistant restart | |
| - Unique MQTT topics for each event to avoid conflicts | |
| **Calendar Support:** | |
| Tested with [Google Calendar](https://www.home-assistant.io/integrations/google), but should work with any Home Assistant calendar integration. | |
| **Icon Support:** | |
| Uses day-of-month icons (11543-11571) from the AWTRIX icon library. Custom icons can be configured via the default_icon setting." | |
| domain: automation | |
| input: | |
| awtrix: | |
| name: AWTRIX Device | |
| description: Select the Awtrix device | |
| selector: | |
| device: | |
| integration: mqtt | |
| manufacturer: Blueforcer | |
| model: AWTRIX 3 | |
| multiple: true | |
| app_name: | |
| name: Awtrix Application name | |
| description: This is the app name listed in the MQTT topic - it should be unique | |
| selector: | |
| text: | |
| multiple: false | |
| multiline: false | |
| default: calendar_notifier | |
| calendar: | |
| name: Calendar with schedule | |
| description: Select one or more calendars to monitor | |
| default: [] | |
| selector: | |
| entity: | |
| domain: calendar | |
| multiple: true | |
| hours_before: | |
| name: Number of Hours before Event | |
| description: Number of hours to start notify before actual event | |
| selector: | |
| number: | |
| max: 96.0 | |
| min: 0.0 | |
| unit_of_measurement: hours | |
| mode: box | |
| step: 1.0 | |
| default: 15 | |
| default_icon: | |
| name: A default icon name | |
| description: A default icon name to use for calendar events. Default - empty. | |
| default: "" | |
| duration: | |
| name: Duration (in seconds) | |
| description: Sets how long the app or notification should be displayed. | |
| default: "10" | |
| lifetime: | |
| name: Lifetime of the app (in seconds) | |
| description: | |
| Removes the custom app when there is no update after the given | |
| time in seconds. Keep this value higher than 59 seconds to get the AWTRIX | |
| app automatically deleted when disabling the automation. | |
| default: "70" | |
| push_icon: | |
| name: Icon Mode | |
| description: | |
| "Please select the pushIcon setting for the icon\n\n - `0` Icon | |
| doesn't move\n\n - `1` Icon moves with text and will not appear again\n\n | |
| \ - `2` Icon moves with text but appears again when the text starts to scroll | |
| again\n" | |
| selector: | |
| select: | |
| options: | |
| - label: Icon doesn't move (default) | |
| value: "0" | |
| - label: Icon moves with text and will not appear again | |
| value: "1" | |
| - label: | |
| Icon moves with text but appears again when the text starts to | |
| scroll again | |
| value: "2" | |
| custom_value: false | |
| multiple: false | |
| sort: false | |
| source_url: https://raw.githubusercontent.com/Brunas/HomeAssistant/master/blueprints/automation/awtrix_calendar_notifier.yaml | |
| mode: single | |
| variables: | |
| device_ids: !input awtrix | |
| app_name: !input app_name | |
| devices_topics: "{%- macro get_device_topic(device_id) -%} | |
| {%- set topic_entities = device_entities(device_id) | select('search','device_topic') | list -%} | |
| {%- if topic_entities | length > 0 -%} | |
| {{- states(topic_entities[0]) -}} | |
| {%- endif -%} | |
| {%- endmacro -%} | |
| {%- set ns = namespace(devices=[]) -%} | |
| {%- for device_id in device_ids -%} | |
| {%- set device = get_device_topic(device_id) | replace(' ','') -%} | |
| {%- if device -%} | |
| {%- set ns.devices = ns.devices + [device] -%} | |
| {%- endif -%} | |
| {%- endfor -%} | |
| {{- ns.devices | reject('match','unavailable') | list -}}" | |
| calendar: !input calendar | |
| hours_before: !input hours_before | |
| default_icon: !input default_icon | |
| duration: !input duration | |
| lifetime: !input lifetime | |
| push_icon: !input push_icon | |
| trigger: | |
| - platform: time_pattern | |
| minutes: /5 | |
| - platform: homeassistant | |
| event: start | |
| condition: [] | |
| action: | |
| - repeat: | |
| for_each: "{{ calendar }}" | |
| sequence: | |
| - variables: | |
| calendar_entity: "{{ repeat.item }}" | |
| calendar_index: "{{ repeat.index }}" | |
| - service: calendar.get_events | |
| target: | |
| entity_id: "{{ calendar_entity }}" | |
| data: | |
| start_date_time: "{{ now() }}" | |
| duration: | |
| hours: "{{ hours_before }}" | |
| response_variable: agenda | |
| - repeat: | |
| for_each: "{{ agenda[calendar_entity].events }}" | |
| sequence: | |
| - variables: | |
| event_start_str: "{{ repeat.item.start }}" | |
| event_summary: "{{ repeat.item.summary }}" | |
| is_all_day: "{{ repeat.item.all_day | default(false) or ('T' not in repeat.item.start) }}" | |
| icon: >- | |
| {%- set event_start = as_datetime(repeat.item.start) %} | |
| {%- set day_of_month = event_start.day %} | |
| {%- if day_of_month == 1 %}11543 | |
| {%- elif day_of_month == 2 %}11544 | |
| {%- elif day_of_month == 3 %}11545 | |
| {%- elif day_of_month == 4 %}11546 | |
| {%- elif day_of_month == 5 %}11547 | |
| {%- elif day_of_month == 6 %}11548 | |
| {%- elif day_of_month == 7 %}11549 | |
| {%- elif day_of_month == 8 %}11572 | |
| {%- elif day_of_month == 9 %}11550 | |
| {%- elif day_of_month == 10 %}11551 | |
| {%- elif day_of_month == 11 %}11552 | |
| {%- elif day_of_month == 12 %}11553 | |
| {%- elif day_of_month == 13 %}11554 | |
| {%- elif day_of_month == 14 %}11555 | |
| {%- elif day_of_month == 15 %}11556 | |
| {%- elif day_of_month == 16 %}11557 | |
| {%- elif day_of_month == 17 %}11558 | |
| {%- elif day_of_month == 18 %}11542 | |
| {%- elif day_of_month == 19 %}11559 | |
| {%- elif day_of_month == 20 %}11560 | |
| {%- elif day_of_month == 21 %}11561 | |
| {%- elif day_of_month == 22 %}11562 | |
| {%- elif day_of_month == 23 %}11563 | |
| {%- elif day_of_month == 24 %}11564 | |
| {%- elif day_of_month == 25 %}11565 | |
| {%- elif day_of_month == 26 %}11566 | |
| {%- elif day_of_month == 27 %}11567 | |
| {%- elif day_of_month == 28 %}11568 | |
| {%- elif day_of_month == 29 %}11569 | |
| {%- elif day_of_month == 30 %}11570 | |
| {%- elif day_of_month == 31 %}11571 | |
| {%- else %}{{ default_icon }} | |
| {%- endif %} | |
| processed_message: >- | |
| {%- set year_matches = event_summary | regex_findall('\\b(19\\d{2}|20\\d{2})\\b') %} | |
| {%- if year_matches | length > 0 %} | |
| {%- set birth_year = year_matches[0] | int %} | |
| {%- set current_year = now().year %} | |
| {%- set age = current_year - birth_year %} | |
| {{- event_summary | regex_replace('\\b(19\\d{2}|20\\d{2})\\b', age | string) }} | |
| {%- else %} | |
| {{- event_summary }} | |
| {%- endif %} | |
| event_text: >- | |
| {%- if is_all_day %} | |
| {{- processed_message }} | |
| {%- else %} | |
| {%- set event_start = as_datetime(repeat.item.start) %} | |
| {{- event_start.strftime('%H:%M') }} {{ processed_message }} | |
| {%- endif %} | |
| app_topic: "{{ app_name }}_cal{{ calendar_index }}_{{ repeat.index }}" | |
| - choose: | |
| - conditions: "{{ devices_topics | length > 0 }}" | |
| sequence: | |
| - repeat: | |
| for_each: "{{ devices_topics }}" | |
| sequence: | |
| - service: mqtt.publish | |
| data: | |
| qos: 0 | |
| retain: false | |
| topic: "{{ repeat.item }}/custom/{{ app_topic }}" | |
| payload: >- | |
| {"icon":"{{ icon }}", | |
| "text":"{{ event_text }}", | |
| "pushIcon":"{{ push_icon }}", | |
| "repeat":1,"textCase":2,"textOffset":33,"duration":{{ duration }},"lifetime":{{ lifetime }}} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment