I keep seeing questions about calculating days away from a calendar date. Here’s a “simple” template that will solve that problem for anyone.
{% set midnight = today_at() %}
{% set event = state_attr('calendar.xxx', 'start_time') | as_datetime | as_local %}
{% set delta = event - midnight %}
{% if delta.days == 0 %}
Today
{% elif delta.days == 1 %}
Tomorrow
{% elif delta.days == 2 %}
Day After Tomorrow
{% else %}
In {{ delta.days }} Days
{% endif %}
Explanation
This first line grabs the current day and sets the timestamp to midnight. I.E. The first second of today, 00:00:00.
{% set midnight = today_at() %}
The second line is your event. You’ll have to make this line yourself. I can help if you post an image of your calendar entity from the Developer tools States page. Make sure to include attributes in the image.
{% set event = <THIS WILL CHANGE DEPENDING ON YOUR SETUP> %}
The third line calculates an offset as an object. This offset contains the number of days, hours, minutes, seconds, etc.
{% set delta = event - midnight %}
The last section is an if statement code block. It checks to see what day it is and properly sets the name. Based on the previous statement: “if the event occurs today, the delta will be zero. If it occurs tomorrow the delta will be 1, etc.” the if statement will be:
{% if delta.days == 0 %}
Today
{% elif delta.days == 1 %}
Tomorrow
{% elif delta.days == 2 %}
Day After Tomorrow
{% else %}
In {{ delta.days }} Days
{% endif %}
If you like to have short and concise templates, you can simplify this using a list:
{% set values = [ 'Today', 'Tomorrow', 'Day After Tomorrow' ] %}
{{ values.get(delta.days, 'In %s Days'%delta.days) }}
Making a template sensor
1. Integrate sensor.date**
sensor:
- platform: time_date
display_options:
- 'date'
2. Create your template sensor. (as an if statement) ***
template:
- sensor:
- name: Event Day
state: >
{% set t = now() %}
{% set midnight = today_at() %}
{% set event = state_attr('calendar.xxx', 'start_time') | as_datetime | as_local %}
{% set delta = event - midnight %}
{% if delta.days == 0 %}
Today
{% elif delta.days == 1 %}
Tomorrow
{% elif delta.days == 2 %}
Day After Tomorrow
{% else %}
In {{ delta.days }} Days
{% endif %}
or
2. Create your template sensor. (using a list) ***
template:
- sensor:
- name: Event Day
state: >
{% set t = now() %}
{% set midnight = today_at() %}
{% set event = state_attr('calendar.xxx', 'start_time') | as_datetime | as_local %}
{% set delta = event - midnight %}
{% set values = {0: 'Today', 1:'Tomorrow', 2:'Day After Tomorrow'} %}
{{ values.get(delta.days, 'In %s Days'%delta.days) }}
** If you already have a template section in configuration.yaml, do not duplicate it. Simply copy and paste the code blocks without the template:
line into your current sensor section.
*** The template sensor will update every day at midnight. The {% set t = now() %} sensor will update every minute. Because we attach this to our template, it forces our template to update at that time. The sensor will also update if the calendar date changes.