Can comparing dates really be this difficult?

I don’t have a programming background but I’ve been able to copy & paste my way into a Home Assistant config that I’m pretty proud of. However, I can’t for the life of me find an example of what I’m trying to do and each attempt to play with date comparison ends in failure and frustration. Maybe there’s a better way to setup my automation that someone can recommend but here’s the basics:

END RESULT:
At 8pm every day send me a notification if tomorrow is trash day and I need to take the bins out.

INFO:
Our trash is usually on the same day of the week however holidays can shift it and the recycling comes every other week. They also periodically do specific types of pickups (batteries, large yard waste, etc) so I wanted to use the Recollect Waste sensor instead of setting up a repeating notification every Thursday.

PROGRESS:
I have the Recollect Waste sensor successfully integrated as sensor.recollect_waste and that sensor’s state is the date of the next pickup. It also has an attribute called pickup_types which lists the types of things being picked up (trash, recycling, yard waste, compost, etc).

Tinkering with the template dev tools I can get today’s date and I can get the date of the next pickup with:

{{ states('sensor.date') }}
{{ states('sensor.recollect_waste') }}

which outputs:
2021-01-19
2021-01-21

PROBLEM
What (I think) I need is to be able to compare tomorrow’s date to the recollect waste sensor and use that as a condition in an automation which would look something like this:

Trigger: current time is 20:00
Condition: tomorrow’s date = states(‘sensor.recollect_waste’)
Action: notify my phone to take out {{ state_attr('sensor.recollect_waste', 'pickup_types') }}

Is there not something as simple as states(‘sensor.date’, ‘tomorrow’) or states(‘sensor.date’) + 1 or something? I’ve seen a few posts that talk about casting the date as an int which uses Sunday as 0 and Saturday as 7 and then comparing the casted integers to one another. Wasn’t able to follow exactly what was going on but refuse to believe that’s the simplest way of referencing the date of the day after today. Thanks.

1 Like

{{ now().weekday() }} returns current day as number (between 1 and 7 I believe). Is that of any use for you?

Edit: Ok, I just reread your post and that on it’s own won’t be any useful. What you basically want is
IF sensor.date + 1 == sensor.recollect_waste THEN notify
correct?

That’s exactly the logic I think I want, just cant figure out out to get it there. It looks like {{ now().day }} returns the date of the month IE if today is Wednesday the 19th then I get 19.

You should be able to use this as an template trigger for an automation:

(( as_timestamp(strptime(states(sensor.recollect_waste), "%d.%m.%Y")) - as_timestamp(now())) / 86400 ) | round(0) == 0 and now().hour == 20

1 Like
automation:
  - alias: "Trash Notifier"
    description: "Description"
    mode: single
    trigger:
      - platform: template
        value_template: "{{ (( as_timestamp(strptime(states(sensor.recollect_waste), "%d.%m.%Y")) - as_timestamp(now())) / 86400 ) | round(0) == 0 and now().hour == 20 }}"
    action:
      - service: notify.me
        data:
          message: Get your lazy a** off the couch!
      - delay:
          minutes: 60
1 Like

use this as a condition with your current trigger:

- condition: template
  value_template: >
    {{ (now().date() + timedelta(days=1)) | string == state_attr('sensor.recollect_waste', 'pickup_types') }}

It adds 1 day to the current date, then compares it to your waste pickup day.

2 Likes

Super helpful, thank you @petro

1 question and 1 revision to that line of code.

Is the pipe operator being used to cast a date object as a string? Is that Jinja? Python? YAML? Just trying to better understand what’s going on so I can write it from scratch next time.

I think this will give me the solution I’m looking for (your code was comparing the pickup types not the pickup date):

- condition: template
  value_template: >
    {{ (now().date() + timedelta(days=1)) | string == states('sensor.recollect_waste') }}

Hopefully this is helpful to others in the future. Thanks again y’all.

{{ now() + timedelta(days=1) }}

google python datetime lots of way to manipulate datetime and as_timestamp in HA. In fact, google python types and functions. If you can do it in python you can genrally do it in HA templates.

EDIT: Typed up whilst @petro was typing

EDIT EDIT : the ‘|’ is a filter but in this case, yes, it is casting from type to type for comparison purposes. Play with the Developer Tools->Templates in the front end.

Yes and yes.

Filters are jinja. The syntax in the quotes parenthesis are also jinja, but they are python objects. Normal jinja doesn’t have datetime and timedelta objects. They were extended into the HA jinja environment.

1 Like

This is true, I retract my python assertion on technical accuracy grounds - but ostensibly the two are closely related

Well, you aren’t wrong. Keep your statement because they are python objects and the syntax is identical between the 2. There’s a small subset of things that the objects can do in python that cannot be done in jinja.

1 Like

I’m humbled Sir. :ok_hand: