This is a HomeAssistant component for tracking birthdays, where the state of each birthday is equal to how many days are left. All birthdays are updated at midnight.
Integration
Set up the component:
# Example configuration.yaml entry
birthdays:
- name: 'Frodo Baggins'
date_of_birth: 1921-09-22
- name: 'Bilbo Baggins'
date_of_birth: 1843-09-22
- name: Elvis
date_of_birth: 1935-01-08
icon: 'mdi:music'
You can also add a custom unique_id
and attributes to each birthday, for instance to add an icon or other metadata.
- unique_id: bond_james_bond
name: James Bond
date_of_birth: 1920-05-25
icon: 'mdi:pistol'
attributes:
occupation: "Agent"
license_to_kill: "Yes"
- unique_id: einstein
name: 'Albert Einstein'
date_of_birth: 1879-03-14
icon: 'mdi:lightbulb-on'
attributes:
occupation: 'Theoretical physicist'
iq: 'Genius level'
sense_of_humor: 'Einsteinian'
Restart homeassistant
All entities that do not have a specified unique_id
are exposed using the format birthdays.{name}
. Any character that does not fit the pattern a-z
, A-Z
, 0-9
, or _
will be changed. For instance Frodo Baggins
will get entity_id frodo_baggins
, and Swedish names like Sven-Göran Eriksson
will get entity_id sven_goran_eriksson
.
You can add a unique id and custom attributes to each birthday, for instance to add an icon or other metadata.
To do this, add a dictionary under the attributes
key in the configuration (see example above). The dictionary can contain any key-value pairs you want, and will be exposed as attributes on the entity.
Fetching the attributes can be done using state_attr
in a template, for instance {{ state_attr('birthdays.einstein', 'occupation') }}
will return Theoretical physicist
.
Attributes to an entity can also be a template. To do calculations based on data from the entity, use the this
-keyword.
Be aware that if a template that cannot be correctly parsed it can lead to the entity not being loaded,
so if your entity is suddenly gone after adding a templated attribute, please check the logs.
Example calculating age in number of days:
birthdays:
- name: 'Frodo Baggins'
date_of_birth: 1921-09-22
attributes:
days_since_birth: '{{ ((as_timestamp(now()) - as_timestamp(this.date_of_birth)) | int /60/1440) | int }}'
Properties of this
that can be used:
Note: Don't use this.extra_state_attributes
, as that might trigger an infinite loop.
It is possible to add global attributes that will be added to all birthdays. Global attributes work just the same as other attributes, and can thus also be templated.
This example will add the attribute days_since_birth
on all entities:
# Example configuration.yaml entry
birthdays:
config:
attributes:
days_since_birth: '{{ ((as_timestamp(now()) - as_timestamp(this.date_of_birth)) | int /60/1440) | int }}'
birthdays:
- name: 'Frodo Baggins'
date_of_birth: 1921-09-22
- name: 'Bilbo Baggins'
date_of_birth: 1843-09-22
- name: Elvis
date_of_birth: 1935-01-08
icon: 'mdi:music'
Note that global attributes will be overridden by entity specific attributes.
All birthdays are updated at midnight, and when a birthday occurs an event is sent on the HA bus that can be used for automations. The event is called birthday
and contains the data name
and age
. Note that there will be two events fired if two persons have the same birthday.
Sending a push notification for each birthday (with PushBullet) looks like this:
automation:
trigger:
platform: event
event_type: 'birthday'
action:
service: notify.pushbullet
data_template:
title: 'Birthday!'
message: "{{ trigger.event.data.name }} turns {{ trigger.event.data.age }} today!"
If you want to trigger an automation based on a specific name or age, you can use the following:
automation:
trigger:
platform: event
event_type: 'birthday'
event_data:
name: Kalle
# age: 40
action:
service: notify.pushbullet
data_template:
title: 'Birthday!'
message: "{{ trigger.event.data.name }} turns {{ trigger.event.data.age }} today!"
If you want to have a notification sent to you at a specific time (instead of midnight), you can use a custom templated sensor and a time trigger. Create the sensor:
template:
- sensor:
- name: "Next birthday"
unique_id: next_birthday
state: >
{%- set ns = namespace(days=365) -%}
{%- for birthday in states.birthdays -%}
{%- set daysLeft = birthday.state | int -%}
{%- if daysLeft < ns.days -%}
{%- set ns.days = daysLeft -%}
{%- endif -%}
{%- endfor -%}
{{ ns.days }}
attributes:
names: >
{%- set ns = namespace(days=365, names=[]) -%}
{%- for birthday in states.birthdays -%}
{%- set daysLeft = birthday.state | int -%}
{%- if daysLeft < ns.days -%}
{%- set ns.days = daysLeft -%}
{%- endif -%}
{%- endfor -%}
{%- for birthday in states.birthdays -%}
{%- set daysLeft = birthday.state | int -%}
{%- if daysLeft == ns.days -%}
{%- set ns.names = ns.names + [birthday.attributes.friendly_name] -%}
{%- endif -%}
{%- endfor -%}
{{ns.names | join(', ')}}
ages: >
{%- set ns = namespace(days=365, ages=[]) -%}
{%- for birthday in states.birthdays -%}
{%- set daysLeft = birthday.state | int -%}
{%- if daysLeft < ns.days -%}
{%- set ns.days = daysLeft -%}
{%- endif -%}
{%- endfor -%}
{%- for birthday in states.birthdays -%}
{%- set daysLeft = birthday.state | int -%}
{%- if daysLeft == ns.days -%}
{%- set ns.ages = ns.ages + [birthday.attributes.age_at_next_birthday] -%}
{%- endif -%}
{%- endfor -%}
{{ns.ages | join(', ')}}
birthday_message: >
{%- set ns = namespace(days=365, messages=[]) -%}
{%- for birthday in states.birthdays -%}
{%- set daysLeft = birthday.state | int -%}
{%- if daysLeft < ns.days -%}
{%- set ns.days = daysLeft -%}
{%- endif -%}
{%- endfor -%}
{%- for birthday in states.birthdays -%}
{%- set daysLeft = birthday.state | int -%}
{%- if daysLeft == ns.days -%}
{%- set ns.messages = ns.messages + [birthday.attributes.friendly_name + ' fyller ' + (birthday.attributes.age_at_next_birthday | string) + ' idag!'] -%}
{%- endif -%}
{%- endfor -%}
{{ns.messages | join('\n')}}
and the automation:
automation:
alias: Happy birthday
trigger:
- platform: time
at: '19:00:00'
condition:
- condition: state
entity_id: sensor.next_birthday
state: '0'
action:
- service: persistent_notification.create
data_template:
title: 'Birthday!'
message: "{{ state_attr('sensor.next_birthday', 'birthday_message') }}"
I use the birthdays as a simple entity list in lovelace, given the above example I use:
# Example use in lovelace
- type: entities
title: Birthdays
show_header_toggle: false
entities:
- birthdays.frodo_baggins
- birthdays.bilbo_baggins
- birthdays.elvis
Another possibility is to use the auto-entities card. This allows you to sort the birthdays entered, an example:
# Example using auto-entities
- type: custom:auto-entities
show_empty: false
card:
title: Verjaardagen
type: entities
card_mod:
style: |
#states > * {
margin: 0 !important;
}
filter:
include:
- entity_id: birthdays*
sort:
method: state
ignore_case: false
reverse: false
numeric: true