Edit Calendar Entry

Look for them in the Entities list or in the States tool of Developer Tools.

They are not there. My Easy time macro must not be working

Test one of the templates using the macros in the Template editor tool…

{% from 'easy_time.jinja' import easter %}
{{ easter() }}

That correctly returns 3/31/24. I was trying to use the friendly name like “New Years Day” in the states tab. So I could run the Trash script to create the calendar entries?

Have you confirmed that the sensors exist?

If the sensors don’t exist, your next step is to figure out why and correct it.

If they do exist, the next step is to add the label to each of the sensors that affect your trash pickup.

The sensors do exist as it returns 3/31/24 for easter.
Do I add the label to the holidays in the template.yaml see code below 2nd line below state: >

# Trash Holidays: new years, independ, memorial, labor, christ, thanks
template:
  - trigger:
      - platform: time
        at: "00:01:00"
      - platform: state
        entity_id: input_button.update_holiday_sensors
      - platform: homeassistant
        event: start

    # FIXED DATE

    sensor:
      - name: "New Years Day"
        unique_id: "37319374975705055206"
        state: >
          {% from 'easy_time.jinja' import month_day %}
          {%- set holiday= expand(label_entities('Trash Collection Holidays')) %}
          {{ (month_day(1, 1)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_day %}
            {%- set x = ((month_day(1, 1)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

No, labels are handled through the frontend.

Appreciate your patience. I think the issue is I don’t have any sensors. Can you explain what the difference between the template.yaml file and sensor.yaml file? Do I need both? Putting your code in the template.yaml file does not create a sensor but does allow the developer tools/template editor to show that easy time jinja is working by returning 3/31/24 for easter with the code

{% from 'easy_time.jinja' import easter %}
{{ easter() }}

How do I create your custom sensors?
Once I create the custom sensors I can label them with “Trash Collection Holidays” with the new feature in HA UI that allows organization.

Not for this. Technically, you don’t need either of them; they are just an organizational tool.
There are a number of ways to split the configuration. Personally, I prefer Packages.

Assuming you have properly merged them in your configuration.yaml file, the sensor.yaml file is for configuring entities under the Sensor integration and template.yaml is for entities under the Template integration. While it is possible to create template sensors under the Sensor integration, this is not the preferred method and it they do not support all the current features and abilities. The sensor configuration I shared uses a trigger (which is not supported by the Sensor integration) and follows the syntax for the Template integration.

You copy the entire configuration in Post #8 and paste it into you template.yaml file.

Then you need to go to the Server Controls and either Restart Home Assistant or reload Template Entities. If you haven’t restarted since you first added anything into that file, you need to restart. If there are other things in that file that have already been properly loaded, you can just scroll down the list to Template Entities and click to reload just the Template integration.

The sensors do not exist despite placing your code in Post #8 in template.yaml and rebooting Home Assistant. Easy Time Jinja is in config/custom_template/easy_time.jinja.

I decided to start over and restore my proxmox backup to a date before I started messing with this. I added experimental to HACS and then installed the easy_time.jinja with the link vs manually installing. Added you template.yaml file code and added it the config.yaml file. By some miracle the sensors showed up and I can now label them.

After enabling the experimental setting in HACS I noticed my Frigate, Mushroom and Battery Card frontends don’t load. I get the error You have 3 Lovelace elements that are not loaded properly in Lovelace. I can redownload the frontends and the error goes away but comes back after a reboot. Any ideas on how to fix it.

The HACS errors are gone don’t know what I did to fix it.

Now that I have sensors created I was thinking about other use cases.
Labeling holidays that are days off from work and then send notification to turn my alarm off and then back on again the next day.

Do you have a script that I could modify that would add holidays to a calendar with a certain label? I’ve tried to adapt your current script but by jinja is very limited at this time. Thanks

This is what I have so far but I’m not get each entry in the array to print

{%- set ns = namespace(work_holiday= [] ) %} 
{%- set holiday= expand(label_entities('Work Holiday')) %}
{%- for i in holiday %}
  {{ state_attr( 'holiday [i]', 'friendly_name') }}
  {{ states('holiday [i]') }}
{%- endfor %}

Result type: string

None unknown None unknown None unknown None unknown None unknown None unknown

This template listens for the following state changed events:

* **Entity**: holiday [i]
* **Entity**: sensor.christmas
* **Entity**: sensor.independence_day
* **Entity**: sensor.labor_day
* **Entity**: sensor.memorial_day
* **Entity**: sensor.new_years_day
* **Entity**: sensor.thanksgiving

I think what you were going for is:

{%- set ns = namespace(work_holiday= [] ) %} 
{%- set holiday= label_entities('Work Holidays') %}
{%- for i in holiday %}
  {{ state_attr( i, 'friendly_name') }}
  {{ states(i) }}
{%- endfor %}

Be aware that you cannot use a simple loop like that for a Repeat for Each action to populate calendar event entries. You defined a namespace, but you did not use it so the loop is just returning a block of text. Repeat for each requires an actual list/array of simple objects like strings, lists, or dictionaries.

alias: Calendar - Populate Holiday Calendar
sequence:
  - variables:
      date_list: >
        {%- set ns = namespace(holidays= []) %} 
        {%- set holiday= expand(label_entities('Work Holidays')) %}
        {# Loop through holiday sensor state objects and create a list of dicts with required calendar event data#}
        {%- for each in holiday %}
          {%- set date = each.state%}
          {%- set isoweekday = (date|as_datetime|as_local).isoweekday() %}
          {%- if isoweekday not in [6, 7] %}{# Only create Cal event if on a weekday #} 
             {%- set ns.holidays=ns.holidays + [
              {"summary": each.attributes.friendly_name,
              "description": "Work Holiday",
              "start_date": date,
              "end_date": (date|as_datetime|as_local + timedelta(days=1)).date()|string}] %}
          {%- endif %}
        {%- endfor %}
        {{ ns.holidays | sort(attribute="start_date")| rejectattr("start_date", "lt", today_at()|string) | list }}
  - repeat:
      for_each: "{{date_list}}"
      sequence:
        - service: calendar.create_event
          data:
            summary: "{{ repeat.item.summary }}"
            description: "{{ repeat.item.description }}"
            start_date: "{{ repeat.item.start_date }}"
            end_date: "{{ repeat.item.end_date }}"
          target:
            entity_id: calendar.work_holidays
        - delay: 2
mode: single
icon: mdi:calendar-edit-outline

EDIT: Fixed variable names in service call and end_date template.

1 Like

if you’re interested in editing local calendar events, vote for it here:

1 Like

Thanks for the update on the code will give it try after I get the sensors working again.

I noticed that you edited the Easy Time Version to fix the ‘Variable Date’ section. When I copy the new code into the template.yaml and restart HA I get unavailable for the state of any of the sensors.
The log file shows

Logger: homeassistant.config
Source: config.py:622
First occurred: 2:28:06 PM (7 occurrences)
Last logged: 2:42:47 PM

Invalid config for 'template' at template.yaml, line 2: 'template' is an invalid option for 'template', check: template

Not sure what’s wrong.

# Trash Holidays: new years, independ, memorial, labor, christ, thanks
template:
  - trigger:
      - platform: time
        at: "00:01:00"
      - platform: state
        entity_id: input_button.update_holiday_sensors
      - platform: homeassistant
        event: start

    # FIXED DATE

    sensor:
      - name: "New Years Day"
        unique_id: "37319374975705055206"
        state: >
          {% from 'easy_time.jinja' import month_day %}
          {{ (month_day(1, 1)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_day %}
            {%- set x = ((month_day(1, 1)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: "Dia de Los Reyes"
        unique_id: "1984497531937520705056"
        state: >
          {% from 'easy_time.jinja' import month_day %}
          {{ (month_day(1, 6)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_day %}
            {%- set x = ((month_day(1, 6)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: "Valentines Day"
        unique_id: "22719844595073910047"
        state: >
          {% from 'easy_time.jinja' import month_day %}
          {{ (month_day(2, 14)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_day %}
            {%- set x = ((month_day(2, 14)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: "Saint Patricks Day"
        unique_id: "44595073912271980047"
        state: >
          {% from 'easy_time.jinja' import month_day %}
          {{ (month_day(3, 17)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_day %}
            {%- set x = ((month_day(3, 17)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: Halloween
        unique_id: "947396278926815041"
        state: >
          {% from 'easy_time.jinja' import month_day %}
          {{ (month_day(10, 31)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_day %}
            {%- set x = ((month_day(10, 31)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: Dia de Muertos
        unique_id: "9750858485431103467"
        state: >
          {% from 'easy_time.jinja' import month_day %}
          {{ (month_day(11, 2)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_day %}
            {%- set x = ((month_day(11, 2)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: Rex Manning Day
        unique_id: "4690662543745975107"
        state: >
          {% from 'easy_time.jinja' import month_day %}
          {{ (month_day(4, 8)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_day %}
            {%- set x = ((month_day(4, 8)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: Christmas
        unique_id: "14318885502034384968"
        state: >
          {% from 'easy_time.jinja' import month_day %}
          {{ (month_day(12, 25)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_day %}
            {%- set x = ((month_day(12, 25)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: "Veterans Day"
        unique_id: "31975705053740693752"
        state: >
          {% from 'easy_time.jinja' import month_day %}
          {{ (month_day(11, 11)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_day %}
            {%- set x = ((month_day(11, 11)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: Independence Day
        unique_id: "9084317551034684857"
        state: >
          {% from 'easy_time.jinja' import month_day %}
          {{ (month_day(7,4)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_day %}
            {%- set x = ((month_day(7, 4)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      # VARIABLE DATE

      ## MONTH WEEK DAY

      - name: "Martin Luther King Jr"
        unique_id: "496217893819475026"
        state: >
          {% from 'easy_time.jinja' import month_week_day %}
          {{ (month_week_day(1, 3, 1)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_week_day %}
            {%- set x = ((month_week_day(1, 3, 1)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: "Mothers Day"
        unique_id: "749819475062189326"
        state: >
          {% from 'easy_time.jinja' import month_week_day %}
          {{ (month_week_day(5, 2, 7)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_week_day %}
            {%- set x = ((month_week_day(5, 2, 7)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: "Fathers Day"
        unique_id: "962741899473268150"
        state: >
          {# third Sunday of June #}
          {% from 'easy_time.jinja' import month_week_day %}
          {{ (month_week_day(6, 3, 7)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_week_day %}
            {%- set x = ((month_week_day(6, 3, 7)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: Thanksgiving
        unique_id: "69425309251060427914"
        state: >
          {# 3rd Thursday in November #}
          {% from 'easy_time.jinja' import month_week_day %}
          {{ (month_week_day(11, 4, 4)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_week_day %}
            {%- set x = ((month_week_day(11, 4, 4)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: Memorial Day
        unique_id: "20611770923315821822"
        state: >
          {# last Monday in May #}
          {% from 'easy_time.jinja' import last_day_in_month %}
          {{ (last_day_in_month(5, 1)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import last_day_in_month %}
            {%- set x = ((last_day_in_month(5, 1)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
          availability: "{{ now() is defined }}"

      - name: Labor Day
        unique_id: "78754309251267813130"
        state: >
          {# 1st Monday in September #}
          {% from 'easy_time.jinja' import month_week_day %}
          {{ (month_week_day(9, 1, 1)|as_datetime).date() }}
        attributes:
          days_until: >
            {%- from 'easy_time.jinja' import month_week_day %}
            {%- set x = ((month_week_day(9, 1, 1)|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      ## LUNAR-DERIVED

      - name: "Mardi Gras"
        unique_id: "734459509122779462132"
        state: >
          {% from 'easy_time.jinja' import easter %}
          {{ (easter()|as_datetime - timedelta(days=47)).date() }}
        attributes:
          days_until: >
            {% from 'easy_time.jinja' import easter %}
            {% set x = ((easter()|as_datetime 
            - timedelta(days=47)) - today_at()).days%}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

      - name: "Easter"
        unique_id: "189497506268132794"
        state: >
          {% from 'easy_time.jinja' import easter %}
          {{ easter() }}
        attributes:
          days_until: >
            {% from 'easy_time.jinja' import easter %}
            {% set x = ((easter()|as_datetime) - today_at()).days %}
            {{ iif(x < 1, x + 365, x) }}
        availability: "{{ now() is defined }}"

    # SEASONS
    binary_sensor:
      - name: Christmas Season
        unique_id: christmas_season_0001
        state: |
          {% set n = now() %}
          {% set offset = 'T00:00:00-05:00' %}
          {{  (states('sensor.thanksgiving')~offset)|as_datetime <= n or 
          n < (states('sensor.dia_de_los_reyes')~offset)|as_datetime }}

You copied the template: top-level key, which isn’t needed in your template.yaml file.

The normal (but unenforced) convention on this forum is to post YAML configuration as-if it is being used in the configuration.yaml file. Users who elect to split their configuration assume the responsibility to modify examples to meet their own needs, since there is no way for anyone else to know exactly how they have set up their splitting and merging.

1 Like

Your knowledge of HA and jinja are impressive. There are so many little issues that are difficult to be aware of and updates to keep track of. Any recommended reading on Jinja other than . The script works great. I just have to figure out how to run it on Dec 31 each year.

There’s no single source that covers all the things you can do with templates in HA, but make sure to check out:

Home Assistant Templating: This is the the most comprehensive source for HA-specific functions.

Forum members have been working on some cookbook-type articles. So far there is only one in the basic templates section: Community Cookbook - Templating - Getting Time and Date

Jinja for Ninjas: @skalavala has put together a well organized tutorial and group of examples. It’s been a while since this was updated, so there are better/easier ways to do some of the things shown, but it’s still a good source.

Many Python methods also to work in templates. I’ve never seen a complete list of which methods work and which don’t… But the Official Python docs have come in handy for me multiple times to figure out what’s going on in templates posted by some of the more advanced users on this forum.

1 Like

Thanks for the great links.

I notice these errors in my logs. Do you think it’s an issue in the template.yaml file you created?

Logger: homeassistant.components.template.template_entity
Source: components/template/template_entity.py:197
integration: Template (documentation, issues)
First occurred: 9:31:43 PM (1 occurrences)
Last logged: 9:31:43 PM

TemplateError('TypeError: '<=' not supported between instances of 'NoneType' and 'datetime.datetime'') while processing template 'Template<template=({% set n = now() %} {% set offset = 'T00:00:00-05:00' %} {{ (states('sensor.thanksgiving')~offset)|as_datetime <= n or n < (states('sensor.dia_de_los_reyes')~offset)|as_datetime }}) renders=4>' for attribute '_state' in entity 'binary_sensor.christmas_season'

Logger: homeassistant.helpers.event
Source: helpers/template.py:587
First occurred: 9:31:43 PM (1 occurrences)
Last logged: 9:31:43 PM

Error while processing template: Template<template=({% set n = now() %} {% set offset = 'T00:00:00-05:00' %} {{ (states('sensor.thanksgiving')~offset)|as_datetime <= n or n < (states('sensor.dia_de_los_reyes')~offset)|as_datetime }}) renders=2>
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 585, in async_render
    render_result = _render_with_context(self.template, compiled, **kwargs)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 2600, in _render_with_context
    return template.render(**kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.12/site-packages/jinja2/environment.py", line 1304, in render
    self.environment.handle_exception()
  File "/usr/local/lib/python3.12/site-packages/jinja2/environment.py", line 939, in handle_exception
    raise rewrite_traceback_stack(source=source)
  File "<template>", line 3, in top-level template code
TypeError: '<=' not supported between instances of 'NoneType' and 'datetime.datetime'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 713, in async_render_to_info
    render_info._result = self.async_render(
                          ^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/template.py", line 587, in async_render
    raise TemplateError(err) from err
homeassistant.exceptions.TemplateError: TypeError: '<=' not supported between instances of 'NoneType' and 'datetime.datetime'

Fixed the template error by commenting out the seasons sensor.

# SEASONS
#binary_sensor:
#  - name: Christmas Season
#    unique_id: christmas_season_0001
#    state: |
#      {% set n = now() %}
#      {% set offset = 'T00:00:00-05:00' %}
#      {{  (states('sensor.thanksgiving')~offset)|as_datetime <= n or
#     n < (states('sensor.dia_de_los_reyes')~offset)|as_datetime }}