Custom Holiday Sensor

I wanted to be able to have automations set off based on the type of Holiday, such as setting the outside lights to all green for Saint Patrick’s Day. I searched around and could not find another integration that would work for me but if there’s a better way to do this, please let me know. It has some limitations as it stands right now and technically can only report one holiday name after a match is found.

Basically, you can add the holiday information to a array and the sensor will report that holiday name, if it is a holiday. It can be a specific month, day, and/or year, including a specific day of the week and number of weeks into the month. A good example of this is Thanksgiving takes place on the 4rd Thursday of the month of November.

Hopefully this can help someone else. I’d love to expand on this more and improve it.

sensor:
  - platform: template
    sensors:
      holiday_name:
        unique_id: "holiday_name"
        friendly_name: "Holiday Name"
        value_template: >
          {% set holidays=[
          {"name":"Thanksgiving","month":11,"day":null,"year":null,"dow":3, "num_of_dow":4},
          {"name":"New Years","month":1,"day":1,"year":null,"dow":null, "num_of_dow":null},
          {"name":"4th of July","month":7,"day":4,"year":null,"dow":null, "num_of_dow":null},
          {"name":"Halloween","month":10,"day":31,"year":null,"dow":null, "num_of_dow":null},
          {"name":"Saint Patrick's Day","month":3,"day":17,"year":null,"dow":null, "num_of_dow":null}
          ]
          %}
          {% set holidays= (holidays | sort(attribute='Month')) %}
          {% set thisholiday = namespace(name='') %}
          {% for holiday in holidays -%}
           {%- if thisholiday.name | length == 0 and (holiday.month != undefined or holiday.day != undefined or holiday.year != undefined or holiday.dow != undefined or holiday.num_of_dow !=undefined)  %}
            {%- if now().month == holiday.month and (now().day == holiday.day or holiday.day == undefined) and (holiday.dow==now().weekday() or holiday.dow == undefined) and (holiday.num_of_dow == undefined or (now().day>=((holiday.num_of_dow-1)*7) and now().day<(holiday.num_of_dow*7))) %}
              {% set thisholiday.name = holiday.name %}
            {%- endif%}
           {%- endif%}
          {%- endfor %}
          {{thisholiday.name}}
          
binary_sensor:
  - platform: template
    sensors:
      holiday_on:
        unique_id: "holiday_on"
        friendly_name: "Holiday Today"
        value_template: "{{states('sensor.holiday_name') | length != 0 }}"
1 Like

Thank you! I was looking to do exactly the same and have been able to use your template.

1 Like

There is also a custom component for showing the next holiday for your country and the remaining days.

Hey found this and its awesome, my templating skills are terrible and i just dont understand it i guess. Just wondering how you allow for 2 months . We like to start xmas lights in november

{"name":"Christmas","month":11,12 "day":null,"year":null,"dow":null, "num_of_dow":null}

You’re close! You would just need to add an entry for each month like this:

{"name":"November","month":11, "day":null,"year":null,"dow":null, "num_of_dow":null}
{"name":"December","month":12, "day":null,"year":null,"dow":null, "num_of_dow":null}

Ahhh ok gotcha!
Thank you again for getting back to me so quickly!

How would you do something like Memorial Day (the last monday in May?) “num_of_dow”:4 generally works except when there are 5 weeks in may.

Check out easy_time… does the calcs for you. GitHub - Petro31/easy-time-jinja: Easy Time calculations for Home Assistant templates

For Memorial Day I am taking the first Monday in June then subtracting 7 days.

1 Like

for some reason this is not working? I have no idea how to fix it as well

Can you share the code you have?