Automating Holidays with Home Assistant
The Problem
Home Assistant can tell you if it's Thanksgiving if you have a calendar plugin configured with Thanksgiving scheduled. But the included Calendar plugin doesn't have that pre-scheduled, and what if you don't want to use a Cloud calendar service? The date sensor isn't very good with date math, and getting "Thanksgiving" to a date is difficult because it's not a fixed day.
The Solution
Template Sensors and Date Math
I found most of this on the Home Assistant Forums, but I've lost the link.
The YAML to the left will set a "holiday-season" sensor's state to "christmas" between the day after Thanksgiving and Jan 5th.
It'll set the state to "halloween" in October.
Otherwise it sets the state to "none". Simple enough.
- trigger:
- platform: time_pattern
# This will update every night
hours: '0'
minutes: '0'
- platform: event
event_type: event_template_reloaded
- platform: homeassistant
event: start
sensor:
- name: "holiday-season"
state: >
{%- set today = now().date() -%}
{%- set month, week, day = 11, 4, 3 -%}
{%- set temp = today.replace(month=month, day=1) -%}
{%- set adjust = (day - temp.weekday()) % 7 -%}
{%- set temp = temp + timedelta(days=adjust) -%}
{%- set thanksgiving = temp + timedelta(weeks = week - 1) -%}
{%- set jan6th = temp.replace(month=1, day=6) -%}
{% if today <= jan6th or today > thanksgiving -%}
{%- set season = "christmas" -%}
christmas
{%- elif today.month == 10 -%}
{%- set season = "halloween" -%}
halloween
{%- else -%}
{%- set season = "none" -%}
none
{%- endif -%}
Example Use-Cases
Dashboards
Using the Card Mod plugin, you can style dashboard cards and use this sensor to change your themes.
How this works in the Lovelace dashboard
type: markdown
content: |-
## Holiday Mode
{% set season = states('sensor.holiday_season') %}
{% if season == 'christmas' %}
### 🎄🎅❄ Christmas ❄🎅🎄
{% elif season == 'halloween' %}
### 🦇🎃👻 Halloween 👻🎃🦇
{% else %}
### 🗿🌴🍹 Default 🍹🌴🗿
{% endif %}
card_mod:
style: |
ha-card {
{% set season = states('sensor.holiday_season') %}
{% if season == 'christmas' %}
background-color: #0F8A5F;
background-image: url("data:image/svg+xml,%3Csvg version='1.1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px' viewBox='0 0 50 50' style='enable-background:new 0 0 50 50%3B' xml:space='preserve'%3E%3Cstyle type='text/css'%3E.st1%7Bopacity:0.3%3Bfill:%23FFFFFF%3B%7D.st3%7Bopacity:0.1%3Bfill:%23FFFFFF%3B%7D%3C/style%3E%3Ccircle class='st1' cx='5' cy='8' r='1'/%3E%3Ccircle class='st1' cx='38' cy='3' r='1'/%3E%3Ccircle class='st1' cx='12' cy='4' r='1'/%3E%3Ccircle class='st1' cx='16' cy='16' r='1'/%3E%3Ccircle class='st1' cx='47' cy='46' r='1'/%3E%3Ccircle class='st1' cx='32' cy='10' r='1'/%3E%3Ccircle class='st1' cx='3' cy='46' r='1'/%3E%3Ccircle class='st1' cx='45' cy='13' r='1'/%3E%3Ccircle class='st1' cx='10' cy='28' r='1'/%3E%3Ccircle class='st1' cx='22' cy='35' r='1'/%3E%3Ccircle class='st1' cx='3' cy='21' r='1'/%3E%3Ccircle class='st1' cx='26' cy='20' r='1'/%3E%3Ccircle class='st1' cx='30' cy='45' r='1'/%3E%3Ccircle class='st1' cx='15' cy='45' r='1'/%3E%3Ccircle class='st1' cx='34' cy='36' r='1'/%3E%3Ccircle class='st1' cx='41' cy='32' r='1'/%3E%3C/svg%3E");
animation: animatedBackground 10s linear infinite;
}
@keyframes animatedBackground {
0% {
background-position: 0 0;
}
100% {
background-position: 0px 300px;
}
}
{%elif season == 'halloween' %}
// color: black;
//background-color: #E66B09;
overflow: hidden;
background: linear-gradient(0deg, #000000 15%, #E66B09 98%, #000000 0%);
}
{% endif %}
Selecting a Scene
Using scenes whenever possible, rather than trying to capture everything manually is the best way to handle lighting and switches and such. In this case, rather than activating a scene, trigger an automation that activates the appropriate scene.
This also works for playlists, videos, whatever.
YAML version
alias: Activate Default Bar Scene
sequence:
- choose:
- conditions:
- condition: state
entity_id: sensor.holiday_season
state: christmas
sequence:
- service: scene.turn_on
target:
entity_id: scene.bsow_bar_christmas_scene
metadata: {}
- conditions:
- condition: state
entity_id: sensor.holiday_season
state: halloween
sequence:
- service: scene.turn_on
target:
entity_id: scene.bsow_bar_halloween_scene
metadata: {}
default:
- service: scene.turn_on
target:
entity_id: scene.bsow_bar_default_scene
metadata: {}
mode: single
icon: mdi:palette-swatch-variant