Automation every x amount of time according to mqtt variable

Hello, I am trying to make an automation as follows:

I get some data by mqtt:

sensor:
  - platform: mqtt
    name: 'cats last fed mqtt'
    state_topic: 'home/catfeeder/lastfed'
  - platform: mqtt
    name: 'catfeeder remaining'
    state_topic: 'home/catfeeder/remaining'   
    availability_topic: 'home/catfeeder/LWT'
    payload_available: "Online"
    payload_not_available: "Offline"
    unit_of_measurement: 'g'
  - platform: template
    sensors:
      cats_fed:
        friendly_name: "Cats Fed at:"
        value_template: "{{ as_timestamp(states.sensor.cats_last_fed_mqtt.state) | timestamp_custom(' %d/%m %H:%M ')  }}"

What matters to me from there are two pieces of information: state_topic: 'home/catfeeder/remaining and value_template: "{{ as_timestamp(states.sensor.cats_last_fed_mqtt.state) | timestamp_custom(' %d/%m %H:%M ') }}"

My automation should run if ā€œremainingā€ is less than ā€œxā€ value and 4h or x hours have passed since ā€œlastfedā€.

Iā€™m not at all familiar with the Home Assistant environment, and tried something like this, but I know it doesnā€™t make sense:

alias: Alimentar Gatos
description: ''
trigger:
  - platform: state
    entity_id: sensor.catfeeder_remaining
    from: '1'
    to: '10'
condition:
  - condition: state
    entity_id: sensor.cats_fed
    state: '>4'
action:
  - service: script.57658975357
mode: single

I hope you can give me some tip.

Hi and welcome to the community :slight_smile:

I am not 100% sure if I fully understood your request.
So you automation should run when:
a) the ā€˜sensor.catfeeder_remainingā€™ is lower than 10
OR
b) lastfed is longer than X hours ago

a) is very simple to implement via a numeric state trigger:
Automation Trigger - Home Assistant #Numeric State

      - id: 'remaining_low' 
        platform: numeric_state
        entity_id: sensor.catfeeder_remaining
        below: 10  

for b) I would recommend to create a template binary_sensor. (You have created a ā€œnormalā€ sensor holding a formatted time value. This is fine if you would like to show it somewhere in your UI, but for automations I think the binary_sensor would be the better approach.

  - platform: template
    binary_sensors:
      cats_fed:
        friendly_name: "Need to feed"
        # 4hours = 14400 seconds
        value_template: "{{ (as_timestamp(now()) - as_timestamp(states.sensor.cats_last_fed_mqtt.state) | float)  > 14400  }}"

This leads us to an automation looking like:

alias: Alimentar Gatos
description: ''
trigger:
  - id: 'remaining_low' 
    platform: numeric_state
    entity_id: sensor.catfeeder_remaining
    below: 10 
  - platform: state
    entity_id: sensor.cats_fed
    to: 'on'
action:
  - service: script.57658975357
mode: single

ah one secondā€¦I think i now understood more better.
We are:

a) the ā€˜sensor.catfeeder_remainingā€™ is lower than 10 and the last time automation was executed (fed was done) > 4 hours
OR
b) lastfed is longer than X hours (assumable > 4hours) hours ago.

In this case we should slightly modify:

alias: Alimentar Gatos
description: ''
trigger:
  - id: 'remaining_low' 
    platform: numeric_state
    entity_id: sensor.catfeeder_remaining
    below: 10 
  - id: 'always_after_x' 
    #x (at the moment 4hours) can be adjusted within the sensor to a value you like to have.
    platform: state
    entity_id: sensor.cats_fed
    to: 'on'
condition:
  - condition: or
    conditions:
       - condition: and
         conditions:
             - condition: trigger
               id: 'remaining_low'
             - condition: template # last executed 4 hours (= 14400 seconds) ago
               value_template: "{{ as_timestamp(now()) - as_timestamp(state_attr('automation.alimentar_Gatos', 'last_triggered')) | float > 14400 }}"
       - condition: trigger
         id: 'always_after_x' 
action:
  - service: script.57658975357
mode: single

Thank you very much for your reply. You did all the work for me. I donā€™t quite understand why in the condition you use ā€˜andā€™ and ā€˜orā€™ and not just use the condition as ā€˜templateā€™ . I use googe translate since my english is not good

For future reference, you can replace this:

{{ as_timestamp(now()) - as_timestamp(state_attr('automation.alimentar_gatos', 'last_triggered')) | float > 14400 }}

with this:

{{ now() - state_attr('automation.alimentar_gatos', 'last_triggered') > timedelta(hours=4) }}

The difference is that the first one converts datetime objects into timestamps and then subtracts them whereas the second one subtracts datetime objects directly.

1 Like