Skip to content

Instantly share code, notes, and snippets.

@bruxy70
Last active January 8, 2024 11:45
Show Gist options
  • Save bruxy70/b55acd9d69de4b8d8880f63e6dcb44cd to your computer and use it in GitHub Desktop.
Save bruxy70/b55acd9d69de4b8d8880f63e6dcb44cd to your computer and use it in GitHub Desktop.
blueprint:
name: Create Calendar Events with Offset Holidays in Week
description: Copy Events (in the next 365 days) from one local calendar to another. Look
in the holidays calendar and shift events for each public holiday in the week
before the event.
domain: script
source_url: https://gist.github.com/bruxy70/b55acd9d69de4b8d8880f63e6dcb44cd
input: {}
fields:
source_calendar:
name: Source calendar
description: Calendar with the events to be copied from
required: true
selector:
entity:
filter:
integration: local_calendar
destination_calendar:
name: Destination calendar
description: Calendar for the events to be copied to
required: true
selector:
entity:
filter:
integration: local_calendar
public_holidays:
name: Public Holidays
description: Calendar with the public holidays to be avoided
required: true
selector:
entity:
filter:
integration: holidays
sequence:
- service: calendar.get_events
data:
duration:
days: 365
target:
entity_id: '{{ source_calendar }}'
response_variable: source
- service: calendar.get_events
data:
duration:
days: 365
target:
entity_id: '{{ destination_calendar }}'
response_variable: destination
- service: calendar.get_events
data:
duration:
days: 365
target:
entity_id: '{{ public_holidays }}'
response_variable: holidays
- variables:
holiday_dates: |-
{%- set ns = namespace(dates={}) %}
{%- if holidays[public_holidays]["events"] %}
{%- for event in holidays[public_holidays]["events"] %}
{%- set ns.dates = dict(ns.dates, **{event.start:event.summary}) %}
{%- endfor %}
{%- endif %}
{{ ns.dates}}
destination_dates: |-
{%- set ns = namespace(dates={}) %}
{%- if destination[destination_calendar]["events"]%}
{%- for event in destination[destination_calendar]["events"] %}
{%- set ns.dates = dict(ns.dates, **{event.start:event.summary}) %}
{%- endfor %}
{%- endif %}
{{ ns.dates}}
- repeat:
for_each: '{{ source[source_calendar]["events"] }}'
sequence:
- variables:
offset: >-
{%- set ns = namespace(offset=0,in_week=False,found=False) %}
{%- set collection_date = strptime(repeat.item.start,"%Y-%m-%d").date() %}
{%- for i in range(collection_date.weekday()+1) %}
{%- set d = ( collection_date + timedelta( days=-i) ).isoformat() %}
{%- if d in holiday_dates %}
{%- set ns.in_week = true %}
{%- set ns.offset = ns.offset + 1 %}
{%- endif %}
{%- endfor %}
{%- if ns.in_week %}
{# Increase offset until we find a date that is not public holiday #}
{%- for _ in range(7) if not ns.found %}
{%- set start = strptime(repeat.item.start,"%Y-%m-%d").date() %}
{%- set d = ( start + timedelta( days=ns.offset) ).isoformat() %}
{%- if d in holiday_dates %}
{%- set ns.offset = ns.offset + 1 %}
{% else %}
{%- set ns.found = true %}
{%- endif %}
{% endfor %}
{%- endif %}
{{ ns.offset }}
start_date: >-
{%- set start = strptime(repeat.item.start,"%Y-%m-%d").date() %}
{{ (start + timedelta(days=offset)).isoformat() }}
end_date: >-
{%- set end = strptime(repeat.item.end,"%Y-%m-%d").date() %}
{{ (end + timedelta(days=offset)).isoformat() }}
summary: "{{ repeat.item.summary }}"
- if:
- condition: template
value_template: "{{ start_date not in destination_dates }}"
then:
- service: calendar.create_event
data:
summary: "{{ summary }}"
start_date: "{{ start_date }}"
end_date: " {{ end_date }}"
target:
entity_id: "{{ destination_calendar }}"
mode: single
icon: mdi:calendar-blank-multiple
@bruxy70
Copy link
Author

bruxy70 commented Jan 8, 2024

Thanks for this contribution, I have updated the blueprint to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment