Only allow automation to trigger once a day?

I am getting this error and the automation doesn’t work:

In ‘condition’ (item 2 of 2):
In ‘template’ condition: TypeError: ‘<’ not supported between instances of ‘NoneType’ and ‘datetime.datetime’

First you said it was “solved” now you say “the automation doesn’t work”.

You haven’t explained what changed to transform success into failure.

right sorry to cause the confusion but basically I have tried to use the same condition on another automation as well.

This is the automation:

- id: livingroom_blinds_open_in_the_morning
  alias: Livingroom Blinds Open in the Morning
  initial_state: 'on'
  trigger:
  - platform: state
    entity_id: binary_sensor.livingroom_motion_detector
    to: 'on'
  condition:
    - condition: time
      after: '06:30:00'
      before: '12:00:00'
    - "{{ state_attr('automation.livingroom_blinds_open_in_the_morning', 'last_triggered') < today_at('06:30') }}"
  action:
  - service: cover.set_cover_position
    data:
      position: 100
    target:
      entity_id: cover.livingroom_blinds

Now this automation doesn’t work and throws the following error/warning:

2022-04-21 10:51:15 WARNING (MainThread) [homeassistant.components.automation] Error evaluating condition in 'Livingroom Blinds Open in the Morning':
In 'condition' (item 2 of 2):
  In 'template' condition: TypeError: '<' not supported between instances of 'NoneType' and 'datetime.datetime'

In the template condition, if the automation’s name is incorrect (in this case it appears to be correct) or the automation has never been triggered yet, the result of the state_attr() function will be none.

If you recall, I explained this in a previous post and described how a default filter can mitigate this situation.

ok thanks I have used the default filter and changed the condition to:

- "{{ state_attr('automation.livingroom_blinds_open_in_the_morning', 'last_triggered') | default(today_at(), true) < today_at('06:30') }}"

1 Like

so in the end I solved it completely differently. In configuration.yaml, a global boolean variable is defined. When the temperature drops once it reports. The transformation turns off. The boiler heats up above the set limit and the variable is switched on.

configuration.yaml

input_boolean:
  notify_boiler:
    name: NotifyBoiler
    initial: ON

automation on only sound:

talias: Teplota bojler 68
description: ''
trigger:
  - platform: time_pattern
    minutes: /1
condition:
  - condition: time
    after: '08:00:00'
    before: '22:00:00'
    weekday:
      - mon
      - tue
      - wed
      - thu
      - fri
      - sat
      - sun
  - condition: state
    entity_id: input_boolean.notify_boiler
    state: 'on'
  - condition: numeric_state
    entity_id: sensor.bojler
    below: '68'
action:
  - service: tts.voicerss_say
    data:
      entity_id: media_player.obyvaci_pokoj_speaker
      message: >-
        Voda v bojleru má nedostatečnou teplotu {{states('sensor.bojler')}}
        stupňů celsia. Šetřete teplou vodou!!
  - service: input_boolean.turn_off
    target:
      entity_id: input_boolean.notify_boiler
    data: {}
mode: single


automation reset event:

alias: Teplota bojler reset stavu
description: ''
trigger:
  - platform: time_pattern
    minutes: /10
condition:
  - condition: numeric_state
    entity_id: sensor.bojler
    above: '72'
action:
  - service: input_boolean.turn_on
    target:
      entity_id: input_boolean.notify_boiler
    data: {}
mode: single

thank you for the response :slight_smile:

Why have you chosen to use Time Pattern Triggers when the automation can clearly be triggered exclusively when desired events occur (and not needlessly and repeatedly every X minutes)?

I don’t know why yet, but the numerical condition doesn’t want me to work. The timer will check it safely. I know this is not the best solution.

So I am using the default filter but the automation keeps on triggering when the binary sensor turns to on I.e. when motion is detected.

Not sure if the condition is really working.

I think its new. Now you can add the action “Wait for time to pass (delay)”!

Working, but testing on automation show error:
“template value should be a string for dictionary value @ data[‘value_template’]. Got None”

Open Issue on GitHub: https://github.com/home-assistant/frontend/issues/12282

1 Like

I actually do this by creating a input_boolean helper. It turns off at midnight and turns on with the specific automation that should only be run once. Then use input_boolean’s state = off as a condition for it. :slight_smile:

To ensure an automation only executes once for any given day, simply use the following Template Condition.

condition:
  - "{{ state_attr(this.entity_id, 'last_triggered').date() < now().date() }}"
5 Likes

Good to know, thanks! I’ll implement this from now on :slight_smile:

Great, thanks for that. Do you have a solution if I want to retrieve the same automation once a day for two time slots?
To example:

  1. time slot 05:00 - 06:30 for me
  2. time slot 06:30 - 07:30 for my wife

I’m using the following template as a condition to see if the automation already has run that day. It basically converts the last triggered attribute to a y/m/d string and compares it to today’s date converted to a y/m/d string. This removes the remaining details from the date attribute. If you are not in UTC you also have to convert the last_triggered attribute to a local time. If the below condition is equel it means it already run that day.

{{ (state_attr('automation.morning_music_livingroom', 'last_triggered')|as_local).strftime('%Y-%m-%d')
  == now().date().strftime('%Y-%m-%d') }}

If you’re interested, you can reduce the template to this:

{{ (state_attr('automation.morning_music_livingroom', 'last_triggered')).astimezone() .date()
  == now().date() }}

Or just this:

{{ this.attributes.last_triggered.astimezone().date() == now().date() }}

EDIT

Correction. Adjust datetime for local timezone.

2 Likes

Hmm, that did not work for me.
Automation states for last_triggered date attribute have a long quotation e.g.“2024-02-13 10:49:51.748362+11:00”. I need to compare against only the date (yyyy-mm-dd) and not the rest, as I need to know if it already run today in my timezone and not UTC.

A datetime object’s date() method returns a date object (contains year, month, and day). What I overlooked to do was what your template did and that’s to initially convert UTC to local time.

I corrected the examples I had posted above.

I tested the first template using an automation that triggered yesterday and it correctly reported false today.

1 Like

I know it’s been a while, I was able to build a blueprint for this specific purpose:

Or you can try this excellent custom component: