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 }}"