Stumped on Simple Aqara Vibration Automation

Hey Guys, I’m hoping someone can help me with a simple automation I’m trying to figure out. I’m new to HA and I’ve been able to wrap my head around integration but I’m still having trouble with automation.

I picked up an Aqara vibration sensor and got it connected to HA through Deconz and a Conbee ii adapter and it is working perfectly.

I just wanted to play with this device and use it to try and learn how to create automations and thought I’d start with an easy first automation that has turned out to not be so easy.

My idea was to put the sensor on the container my dog’s food goes into and then configure the sensor to send me a notification at 6pm if no vibration has been detected for 24 hours. My dog gets fed once a day at dinner time so this is essentially a reminder to feed him if I’ve forgotten, which has never happened BTW but I just thought it would be a simple automation to get me started.

I’m used to doing automations in Alexa so all these triggers and options are complicated. I tried to configure it with a trigger of Time at 6pm and then a condition type of Device with the sensor selected with the condition “not detecting vibration” and a duration of 24 hours, then i configured a call service to announce “feed the dog” over all my alexa devices.

I have a feeling this config is somewhat backwards, as in i might not get a result until 6pm tomorrow when I actually want to take take into account vibration from the last 24 hours not the coming 24 hours… and this is where I start to get lost because I can’t figure out how to retroactively monitor that duration of time.

Does that make sense to anyone???

Cheers,

Ted
(HA Core 2022.5.4 - HA Supervisor 2022.05.02 - HA OS 8.0)

I don’t think so, but I see a different problem if you want only get notified, if there was no vibration for the last 24 hours. Each time you fill up the food box the state of the vibration sensor changes and breaks your condition.
So what about a very basic automation: Every day at 6 o’clock you will be asked if you already feeded the dog.

Small addition:

You can easily verify the time difference in Dev. Tools.


{% set sensor = states.binary_sensor.vibrationssensor.last_changed %}
{{ now()}} // time now
{{ sensor |as_local() }} // vibration sensor last_changed
{{ now() - sensor }} // time difference


results in:

(Just now the cat jumped on the bed, so the time difference is only a few seconds).

For all the time stuff see here: https://www.home-assistant.io/docs/configuration/templating/#time

Thanks for the quick reply and suggestions, I’ll have a look at this but I may have bitten off more than I can chew.

I didn’t think about the fact that I would throw off the automation every time I refill the dog food container but it’s a large container that I fill with a 1.5 month supply of food so it only gets refilled a few times a year. Also I’m just doing this as a “learning” project and don’t intend to rely on the automation to feed my dog ha ha ha.

Cheers,

Ted

I think @pedolsky was on the right track. You don’t need an automation to do this.

Step 1
Create a template sensor that calculates how long ago you last fed the dog. Essentially now() - vibration sensor.last_changed. Here’s an example that returns the number of seconds since my bedroom thermostat last updated. Test it out in developer tools / templates and once perfected create the sensor.


sensor:
  - platform: template
    sensors:
      zwave_bedroom_thermostat_latency:
        unit_of_measurement: secs
        value_template: >-
          {%- if as_timestamp(states("sensor.bedroom_thermostat_last_updated"),0) == 0 %}
          0
          {%- else %}
          {{ ((as_timestamp(now(), 0) | int(0)) - as_timestamp(states('sensor.bedroom_thermostat_last_updated'),0) | int(0)) }}
          {%- endif %}

Step 2 - create a binary sensor that is False/Off if your dog feeding latency exceeds your threshold. This one goes off after 1200 seconds.


binary_sensor:
  - platform: template
    sensors:
      zwave_bedroom_thermostat_online:
        value_template: >-
          {{ ( 1200 - (states('sensor.zwave_bedroom_thermostat_latency') | int(0))) > 0 }}

Step 3 - create an alert to notify yourself.


alert:
  zwave_bedroom_thermostat:
    name: zwave bedroom_thermostat alert
    message: '{{ state_attr("zone.home","friendly_name") }} zwave bedroom_thermostat offline - Latency: {{ states("sensor.zwave_bedroom_thermostat_latency") }} Node {{ states("sensor.zwave_bedroom_thermostat_node_status") }}'
    done_message: '{{ state_attr("zone.home","friendly_name") }} zwave bedroom_thermostat online'
    entity_id: binary_sensor.zwave_bedroom_thermostat_online
    state: "off”
    repeat: 240
    can_acknowledge: true
    skip_first: false
    notifiers:
      - sms_notifiers_all

The automation as you described is how you’d normally approach this. Only a state condition would be my choice, not a device condition. The delay in the condition would do as you’d expect. I do now know why other posters would revert to scrpting or other sensors for this.

There is a problem though, which all of these other solutions also do not solve. Home Assistant has a bad habit of needing a restart for a lot of stuff. That restart usually also means the sensor is unavailable for a short time during the reboot. That is a state change. So every restart would lead to a hungry dog that day, because the sensor wasn’t off for a little while :upside_down_face:

As you feed the dog in the evening, I do not know why you’s set 24 hours though. It would also mean that if you fed the dog after the notification, you wouln’t get a notification next day (since feeding was 23:50 ago. I’d use a couple of hours as you do not feed the dog at night or in the morning. It would also limit the reboot problem to use a much shorter delay.

alias: Feed the dog
description: ''
mode: single
trigger:
  - platform: time
    at: '18:00:00'
condition:
  - condition: state
    entity_id: binary_sensor.vibration_feeder
    state: 'off'
    for:
      hours: 2
      minutes: 0
      seconds: 0
action:
  - service: notify.mobile_app_me
    data:
      message: Feed the dog

If you want to avoid the reboot problem, there’s also another quite simple solution, but it requires more automations:
One automation puts out the notification at 18:00, no conditions (the one above, without the condition).
Another automation: when the vibration sensor detects movement, turn the first automation off.
And the last automation, at midnight turn the first automation on again.

2 Likes

This also solves another potential problem that wasn’t yet mentioned. If someone happens to bump the bowl during the day for whatever reason the timer will reset to 24 hours. By just watching the expected 2 hour feeding period you eliminate this.

Although personally I would tweak your automation slightly to make it automation reload resilient. A 2 hour wait is quite a while considering that the automation is stopped if automations are reloaded (which as a reminder happens every time you make a change in the automation editor). Therefore I would do it like this:

alias: Feed the dog
description: ''
mode: single
trigger:
  - platform: time
    at: '20:00:00'
condition: >-
  {{ is_state('binary_sensor.vibration_feeder', 'off') and
    now() > states.binary_sensor.vibration_feeder.last_changed + timedelta(hours=2) }}
action:
  - service: notify.mobile_app_me
    data:
      message: Feed the dog

This triggers at the time you want the notification and only sends it if the feeder sensor has been off for at least 2 hours. Does the same thing as yours but still works if you were editing your automations from 18:00:00 to 20:00:00.

I think I’m missing something since I’m not sure how turning off the automation that simply puts up a notification at exactly 18:00:00 (no condition) helps.

But I think there’s a much cleaner way to do this now thanks to recent changes. Just make a trigger template sensor like this:

template:
- trigger:
    platform: state
    entity_id: binary_sensor.vibration_feeder
    not_from: unknown
    to: 'on'
  sensor:
    name: Last changed vibration feeder
    unique_id: last_changed_vibration_feeder
    state: "{{ states.binary_sensor.vibration_feeder.last_changed }}"
    device_class: timestamp

Then in my automation above replace states.binary_sensor.vibration_feeder.last_changed with states('sensor.last_changed_vibration_feeder') | as_datetime.

This works because of two changes in 2022.5:

  1. not_from allows us to ignore state changes that occurred immediately following startup (the state goes from unknown to either on or off).
  2. Trigger template sensors now have persistent state. So this datetime value will survive restarts.

About turning the automation on and off: Basically I replaced your sensor with the on/off state of the automation itself to remember if feeding occurred. If the automation is turned off, feeding was done that day and the automation won’t fire to give a notification. The last automation is to reset for the next day, so turning the automation on says: feeding needs to happen again, if not the notification will trigger.

The not_from is a useful construct but not very much needed here, because 99 out of 100 the state will go from unknown to off and then later from off to on. Unless you are tinkering with Home assistent while the vibration occurs. Most likely in that case you will not see the vibration at all anyway.

What I do not get is how the last_changed construct helps from a reboot. Are the changes to unknown and off during reboot not reflected in that? I know the on/off state of the automation is restored after reloads of automations and reboots, so that construct is safe.

As for the first automation I proposed not being reload resilient - I believe that is not true. If the automation is long running due to a delay period then you are absolutely right. Then the reload will stop the automation and not continue when the reload is done. But this automation is short running. Afaik it will do exactly as your sensor or script does when evaluating the condition, namely see how long ago the last change occurred. This is not a delay, but a “for duration” in a condition. It will be checked at 18:00 hours alone.

1 Like

After a reboot the sensors go from unknown to on or off. My trigger sensor ignores this state change since it has not_from: unknown. And it ignores any transitions to off since it has to: 'on'. So it only captures the last_changed value when the vibration sensor changes to on and not from a reboot.

There’s only one restore state mechanism in HA. Automations use it and now trigger template sensors use it too. It’s just as safe. Give it a try though if you don’t believe me. I use it all over now. I had invented my own “restore state” mechanism for trigger template entities so I was happy to refactor that out in places.

Oh right, I was thinking trigger with a for. I basically only use template conditions so I forgot how the condition with a for works. You’re right, yours works fine for this and is easier to read :+1:

I understands triggers are ignored that go from unknown to on, as are any triggers to anything other than on, but how should "{{ states.binary_sensor.vibration_feeder.last_changed }}" know to ignore those timestamps too? There can be only one “last_changed” in the (current) states? So if the last change before now was one from unknown to off, it is still the last one even if it did not trigger anything that time. The template would still capture how long the sensor was off, not counting the unknown or off before that.

Ah, scratch that - it finally get it now. It is the sensor itself that remembers it. Duh! Learned something useful today. Thx. That is indeed the most resilient solution.

1 Like

Well I just want to start by thanking everyone for their input, I’m just blown away by everyone’s willingness to help this stoned hacker realize his stupid automation ideas HA HA HA HA.

Everyone provided great input and I think I’ve figure out a very simple plan to make this automation work. I appreciate the amount of instructions that people gave me but again I’m a noob and most of these suggestions are beyond my understanding. i thought about your suggestions and made some modifications to my automation that I think should solve all the problems.

I left the trigger as time and set it to 4:30pm. I always feed the dog between 5 and 7 so under conditions i choose device as the type, condition set to not detecting vibration and set the duration to 3 hours. Then when those 3 hours are up i have a service call to announce “Feed the dog” over the home alexa devices. I haven’t tested it yet but I think this will work, at 4:30 it starts monitoring for vibrations and if none are detected by 7:30 it will alert me that I haven’t fed him yet.

This should help to avoid any issues with restarting the server and refilling the dog food bin as long as I do those tasks outside of the 3 hour window. And I was able to accomplish this without writing any YAML ha ha ha, hopefully it works tonight.

Cheers,

Ted

1 Like