Since Home Assistant version 2025.12 the pinkywafer/Anniversaries integration is broken and it seems it is no longer maintained. I liked what it did, so I created a template blueprint to mimic its most common functionality.
The blueprint has the same attributes so it can be used as a drop in replacement for most common uses. However, since the entities are no longer made by the anniversaries integration, you might need labels to target the ones from the blueprint if you want to find them easily.
- It keeps track of the number of days until a special yearly event, and the number of years.
- If you do not know the start year, you can specify any year and set the flag that you do not know the exact year it started.
- It will create calendar entrires in a calendar if you like that. The default calendar is calendar.anniversaries. If the calendar does not exists, no entries are made. Each anniversary is created only once and never deleted unless you do so yourself. If the information that is used for the calendar item changes, a new item is created.
Please note that blueprint template sensors are still in the experimental phase. At some point they will hopefully move to the UI (petro is hard at work to make this possible). But snce the integration broke I deciced to post it anyway. More information on how they are used is here:
- In your config directory, check for a blueprint folder. If it is not there, create one.
- In the blueprint folder, create a folder named edwin_d
- In that folder, place a file names anniversary.yaml and put the below blueprint code in it.
blueprint:
name: Anniversary
description: >
Keep track of important dates.
domain: template
input:
sensor_name:
name: Name
description: Name of the special date to remember.
selector:
text:
special_date:
name: Special date
description: The date to remember (e.g. wedding anniversary).
selector:
text:
year_unknown:
name: Year unknown
description: |
If the year of the special date is unknown then the year will be ignored
and the number of years will not be calculated.
default: false
selector:
boolean:
calendar_entity:
name: Calendar entity
description: |
Calendar to put an appointment in if the calendar exists.
Each anniversary is created only once and never deleted unless you do so yourself.
If the information that is used for the calendar item changes, a new item is created.
default: 'calendar.anniversaries'
selector:
entity:
domain: binary_sensor
variables:
i_sensor_name: !input sensor_name
i_special_date: !input special_date
i_year_unknown: !input year_unknown
i_calendar: !input calendar_entity
trigger:
- trigger: time
at: "00:00:00"
- trigger: homeassistant
event: start
- trigger: event
event_type: event_template_reloaded
actions:
- variables:
today: "{{- today_at() -}}"
spec: "{{- strptime(i_special_date, '%Y-%m-%d') | as_local -}}"
nextd: |
{%- set today_date = today | as_datetime | as_local -%}
{%- set spec_date = spec | as_datetime | as_local -%}
{%- if spec_date.month == 2 and spec_date.day == 29 -%}
{%- set next = spec_date.replace(year=today_date.year, day=28) + timedelta(days=1) -%}
{%- if next < today_date -%}
{%- set next = spec_date.replace(year=today_date.year+1, day=28) + timedelta(days=1) -%}
{%- endif -%}
{%- else -%}
{%- set next = spec_date.replace(year=today_date.year) -%}
{%- if next < today_date -%}
{%- set next = spec_date.replace(year=today_date.year+1) -%}
{%- endif -%}
{%- endif -%}
{{- next -}}
anniv: "{{ nextd if i_year_unknown else spec }}"
days_until: "{{ (nextd | as_datetime | as_local - today | as_datetime | as_local).days }}"
total_days: "{{ (today | as_datetime | as_local - spec | as_datetime | as_local).days }}"
weeks_until: "{{ days_until // 7 }}"
yr: |
{%- set today_date = today | as_datetime | as_local -%}
{%- set spec_date = spec | as_datetime | as_local -%}
{%- if spec_date.month == 2 and spec_date.day == 29 -%}
{%- set curr_date = spec_date.replace(year=today_date.year, day=28) + timedelta(days=1) -%}
{%- else -%}
{%- set curr_date = spec_date.replace(year=today_date.year) -%}
{%- endif -%}
{{ curr_date.year - spec_date.year - (1 if curr_date > today_date else 0) }}
yr_at_anniv: "{{ yr + (1 if days_until else 0) }}"
cal: "{{ i_calendar if i_calendar else 'calendar.anniversaries' }}"
ent_id: |
{%- set id = 'sensor.template_' ~ i_sensor_name | slugify -%}
{{- this.entity_id if this is defined and this.entity_id is defined else
id if states(id) != 'unknown' else
'sensor.' ~ i_sensor_name | slugify -}}
calitem: |
{%- set calitem = none -%}
{%- if states(cal) != 'unknown' -%}
{%- set calitem = [ cal, nextd[0:10], i_sensor_name, yr_at_anniv ]|join(',') -%}
{%- endif -%}
{{- calitem -}}
- if:
- condition: template
value_template: |
{{ has_value(cal) and
calitem != state_attr(ent_id, 'last_created_event') }}
then:
- action: calendar.create_event
metadata: {}
target:
entity_id: "{{ cal }}"
data:
summary: |
{{ i_sensor_name ~
('' if i_year_unknown else
' (' ~ yr_at_anniv ~')') }}
start_date: "{{ nextd[0:10] }}"
end_date: "{{ (((nextd | as_datetime | as_local) + timedelta(days=1)) | string)[0:10] }}"
sensor:
name: "{{ i_sensor_name }}"
icon: |
{{ 'mdi:calendar' if weeks_until else
'mdi:calendar-alert' if days_until else
'mdi:cake-variant' }}
unit_of_measurement: "d"
device_class: duration
state: "{{ days_until }}"
attributes:
years_at_anniversary: "{{ none if i_year_unknown else yr_at_anniv }}"
current_years: "{{ none if i_year_unknown else yr }}"
days_since_date: "{{ none if i_year_unknown else total_days }}"
date: "{{ anniv | as_datetime | as_local }}"
next_date: "{{ nextd | as_datetime | as_local }}"
weeks_remaining: "{{ weeks_until }}"
last_created_event: |
{{ calitem if has_value(cal) else
state_attr(ent_id, 'last_created_event') }}
Sensors can only be made in yaml at this time. The look like this (ignore errors from Studio Code, the helper does not understand blueprint sensors):
template:
- use_blueprint:
path: edwin_d/anniversary.yaml
input:
sensor_name: Birthday Mickey Mouse
special_date: "1928-11-18"
year_unknown: false
calendar_entity: calendar.disney
unique_id: birthday_mickey_mouse
- use_blueprint:
path: edwin_d/anniversary.yaml
input:
sensor_name: Sinterklaas
special_date: "1970-12-05"
year_unknown: true
calendar_entity: calendar.anniversaries
unique_id: sinterklaas
Note that the blueprint relies on the entity_id of the sensor it creates to prevent duplicates on calendar entities. I tried to replicate what the sensor does to generate the id (it seems to rely on unique_id somehow). If you have trouble with this, try to use the settings of the entity to regenerate the unique id. That should fix it.
This topic was made a wiki, so any one can improve on it.