My automation does not trigger

I have the following sensor:

  - platform: template    # determine if today is selected as a watering day for program 1
    sensors:
      irrigation_watering_day:
        entity_id: sun.sun
        value_template:  >-
          {% set sensor_names = [ 'monday', 'tuesday', 'wednesday','thursday','friday','saturday','sunday'] %}
          {% set today_name = sensor_names[now().weekday()] %}
          {% set entity_id = 'input_boolean.'+today_name %}
          {{ is_state(entity_id, 'on') }}

And the following automation:

automation:
  - alias: Irrigation.Irrigate
    trigger:
      platform: state
      entity_id: sensor.irrigation_watering_day
      to: 'True'
    action:
      - service: homeassistant.turn_on
        data:
          entity_id: script.rainbird_irrigate

But for some reason it never triggers even though the state of the sensor is set to True.

The automation is triggered when sensor.irrigation_watering_day changes its state from False to True. That sensor is based on the state of several input_booleans, one input_boolean per day of the week. If you have several consecutive days set to True, the automation will never trigger because the sensor’s state is always True, it never changes its state from False to True.

There are other quirks like the use of sun.sun to serve as the sensor’s listener (strange choice) and the use of homeassistant.turn_on to run a script.

You can eliminate the sensor and simply use this one automation:

  - alias: Irrigation.Irrigate
    trigger:
      platform: state
      entity_id: sensor.date
    condition:
      condition: template
      value_template:  >-
        {% set entity_id = 'input_boolean.' ~ now().timestamp() | timestamp_custom('%A') | lower %}
        {{ is_state(entity_id, 'on') }}
    action:
      service: script.rainbird_irrigate

This automation triggers at the start of every new day (i.e. moments after midnight) then the condition computes the current day’s name, appends it to “input_boolean.” then determines if that input_boolean is on. If it is, the automation executes the action which is to call the script.

This automation’s trigger needs modification because you probably don’t want the irrigation script to run shortly after midnight. At what time do you want to run the irrigation script?


EDIT
Correction. Removed extraneous ) after the word entity_id in the last line of the template.

1 Like

well I had this as well in there:

    condition:
    - condition: state
      entity_id: 'sensor.irrigation_watering_day'
      state: 'True'
    - condition: template
      value_template: "{{ states('sensor.history_rainy_past_two_days') | int < states('input_number.irrigation_rainthreshold') | int }}"
    - condition: template
      value_template: "{{ states('sensor.time') == states('input_datetime.irrigation_auto_time')[0:5] }}"

It checks if it rained in the past 2 days and compares the hours amount (from history) to the threshold I selected via lovelace.

Then it checks current time vs time I selected via lovelace (removed the seocds since sensor.time has no seconds).

Is that correct?

Shouldn't it be:
    action:
      - service: homeassistant.turn_on
        data:
          entity_id: script.rainbird_irrigate

So everything works in my code except for this part:

- condition: template
      value_template: "{{ states('sensor.time') == states('input_datetime.irrigation_auto_time')[0:5] }}"

These are the two sensors:

sensor:
  - platform: time_date
    display_options:
      - 'time'
      - 'date'

and

  irrigation_auto_time:
    name: Automation Time
    has_date: false
    has_time: true
    initial: '20:00:00'

Yes. You can call a script like that provided you don’t intend to pass it any variables.

It’s not included in your first post so no one could know that it was also present. It’s important to share all the details in order to get the most complete answers.

I will need to see the entire automation before I can resolve that. I don’t know if you are using the automation I suggested, with a new trigger and the added conditions, or something completely different.

Here is my automation:

automation:
  - alias: Irrigation.Irrigate
    trigger:
      - platform: state
        entity_id: sensor.date, input_boolean.monday, input_boolean.tuesday, input_boolean.wednesday, input_boolean.thursday, input_boolean.friday, input_boolean.saturday, input_boolean.sunday, input_datetime.irrigation_auto_time
    condition:
      - condition: template
        value_template:  >-
            {% set entity_id = 'input_boolean.' ~ now().timestamp() | timestamp_custom('%A') | lower %}
            {{ is_state(entity_id, 'on') }}
      - condition: template
        value_template: "{{ states('sensor.history_rainy_past_two_days') | int < states('input_number.irrigation_rainthreshold') | int }}"
      - condition: template
        value_template: "{{ states('sensor.time') == states('input_datetime.irrigation_auto_time')[0:5] }}"

Then here are all the elements that feed this automation:

input_boolean:
  monday:
    name: 1_Monday
    initial: off
  tuesday:
    name: 2_Tuesday
    initial: on
  wednesday:
    name: 3_Wednesday
    initial: off
  thursday:
    name: 4_Thursday
    initial: on
  friday:
    name: 5_Friday
    initial: off
  saturday:
    name: 6_Saturday
    initial: on
  sunday:
    name: 7_Sunday
    initial: on

input_number:
  irrigation_rainthreshold:
    name: Threshold
    unit_of_measurement: hours
    initial: 2
    min: 1
    max: 12
    step: 1  

input_datetime:
  irrigation_auto_time:
    name: Automation Time
    has_date: false
    has_time: true
    initial: '20:00:00'

sensor:
  - platform: time_date
    display_options:
      - 'time'
      - 'date'

  - platform: history_stats
    name: history_rainy_past_two_days_rainsensor
    entity_id: binary_sensor.rainsensor
    state: 'on'
    type: time
    end: '{{ now() }}'
    duration:
      days: 2
  
  - platform: history_stats
    name: history_rainy_past_two_days_ecobee
    entity_id:  weather.my_ecobee3
    state: 'rainy'
    type: time
    end: '{{ now() }}'
    duration:
      days: 2

  - platform: template
    sensors:
      history_rainy_past_two_days:
        entity_id: sensor.date, sun.sun
        friendly_name: "Rain in the Past 2 Days"
        value_template: "{{ ((states('sensor.history_rainy_past_two_days_rainsensor') | float + states('sensor.history_rainy_past_two_days_ecobee') | float) / 2) | round }}"
        unit_of_measurement: "h"

Now I understand why the action isn’t executed.

The following condition means the action will be executed only if the current time it matches the input_datetime whose default value is 20:00:00.

{{ states('sensor.time') == states('input_datetime.irrigation_auto_time')[0:5] }}

That’s fine but look at what triggers the automation. It triggers when any of the input_booleans change state, which could be at any time and unlikely to occur precisely at 20:00:00, and sensor.date which changes at midnight, never at 20:00:00. In a nutshell, the triggers never occur at 20:00:00 so the condition will never be met and the action is never executed.

Because you want this automation to run at a given time (determined by the input_datetime) the automation must be evaluated every minute. Therefore the simplest solution is to use a Template Trigger that checks if the current time matches the specified time. In other words, the condition you defined ought to be the automation’s trigger.

The resulting automation looks very similar to the original one I proposed. I had mentioned that it would need a more appropriate trigger than simply using sensor.date and now it does:

automation:
  - alias: Irrigation.Irrigate
    trigger:
      - platform: template
        value_template: >-
          {{ states('sensor.time') == states('input_datetime.irrigation_auto_time')[0:5] }}
    condition:
      - condition: template
        value_template:  >-
          {% set entity_id = 'input_boolean.' ~ now().timestamp() | timestamp_custom('%A') | lower %}
          {{ is_state(entity_id, 'on') }}
      - condition: template
        value_template: >-
          {{ states('sensor.history_rainy_past_two_days') | int < states('input_number.irrigation_rainthreshold') | int }}
    action:
      service: script.rainbird_irrigate

So what will trigger this automation? It will trigger when sensor.time changes state so that’s every minute. It will also trigger when the input_datetime changes state (i.e. you change the desired irrigation time).

It will only proceed to evaluating the conditions if the current time matches the specified irrigation time. If it’s a match, it checks if the today’s input_boolean is enabled and if recent rainfall is less than the threshold value. If both conditions are met, it calls the irrigation script.

NOTE
The two Template Conditions could be combined into one but sometimes, in the interests of clarity, it’s advantageous to keep them separate.

Ah makes sense! Just tested and it worked! Thanks!

1 Like

Does anyone know why this doesn’t trigger, I want to find out if the date part of my timestamp is equal to today:

{% if (as_timestamp(now() | timestamp_custom('%m/%d/%Y'))) == (state_attr('input_datetime.irrigation_side_lastwatered', 'timestamp') | int | timestamp_custom('%m/%d/%Y')) %}

When you define a Template Trigger, on startup Home Assistant will inspect the template and identify all the entities in it. Then it creates “listeners” that monitor the entities for state-changes. When an entity changes state, the listener detects it and triggers the Template Trigger.

This occurs only for entities it can locate within the template. It does not monitor changes to functions in the template.

Your template contains one entity called input_datetime.irrigation_side_lastwatered. That’s the only thing that serves as a trigger source in that template. now() is a function and is not monitored. Given that the only entity is an input_datetime that probably isn’t changed very often, that explains why the Template Trigger is rarely ever (or seemingly never) triggered.

I fixed it, my braces were incorrect.

(as_timestamp(now() | timestamp_custom(’%m/%d/%Y’)))

Should be:

(as_timestamp(now()) | timestamp_custom(’%m/%d/%Y’))

You can streamline it like this:

{% if now().timestamp() | timestamp_custom('%m/%d/%Y') == 
   state_attr('input_datetime.irrigation_side_lastwatered', 'timestamp') | timestamp_custom('%m/%d/%Y') %}

now() has a built-in timestamp() method ( so there’s no need to use as_timestamp) and the result of acquiring the input_datetime’s timestamp attribute is already a floating-point value so there’s no need to convert it using an int filter.

If you’re using this in a Template Trigger, it will still only trigger when the input_datetime changes. If you’re using it in a Template Condition, it’ll be fine.

1 Like

Yes that is what I want, it’s to show an appropriate output message based on input_datetime. So it should trigger only when input_datetime changes.

If today you set the input_datetime to 06/16/2020, when that day arrives, it won’t trigger. That’s because the now() function is never evaluated periodically.

It will only trigger when you change the input_datetime. So for that if statement to evaluate to true, you would have to change the input_datetime to the current day, on the current day.

I’ll test it for a few days and see but so far it does change the output as needed.

For instance I just irrigated and it updated properly.

Look at the timestamp under the front yard button.

So I’ve tested it for the past few days and all is working as needed thus far.

For my own education, can you post the entire trigger of whatever automation is using that template? Thank you.

sure…

This is one of the buttons:
     irrig_side_last_irrigation:
        entity_id: sensor.date, sun.sun, switch.irrig_front_side_yard
        friendly_name: "Days Since Last Irrigation"
        value_template:  >-
            {% if (((as_timestamp(now()) - state_attr('input_datetime.irrigation_side_lastwatered', 'timestamp')) / 86400)|round) == 0 %}
              {% if (as_timestamp(now()) | timestamp_custom('%m/%d/%Y')) == (state_attr('input_datetime.irrigation_side_lastwatered', 'timestamp') | timestamp_custom('%m/%d/%Y'))  %}
                Today at {{ (state_attr('input_datetime.irrigation_side_lastwatered', 'timestamp') | int | timestamp_custom('%-I:%M %p', True)) }}
              {% else %}
                Yesterday at {{ (state_attr('input_datetime.irrigation_side_lastwatered', 'timestamp') | int | timestamp_custom('%-I:%M %p', True)) }}
              {% endif %}
            {% else %}
              {{ ((as_timestamp(now()) - state_attr('input_datetime.irrigation_side_lastwatered', 'timestamp')) / 86400)|round }}d ago
            {% endif %}

I don’t think you can do that. (nested if’s)
I see Teras is comming, he can probably clarify