Automation Condition using rain sensor value for the last certain period?

I guess i’m confused. Here you are posting this:

But then this is your screenshot:

Have you taken recent screenshots? Is that the correct rain sensor?

Yes that is the correct rain sensor, I only have 1 rain sensor.
I believe since the info on the graph is using HH:mm format then it round up the minute.

yes but your picture should match what’s stored in the object. That’s what doesn’t make sense. Have you cleared your cache and refreshed your browser?

NM, i Just noticed the 36 seconds at the top of the image. I’m confused as to what the problem is then. It appears as if everything is in order and working correctly. Your times are 7 hours apart, the objects match. What’s the problem?

22 - 14 is around 8am. your last update in utc is 12 am + your 7 hour offset is equal to about 8 am.

You can’t always assume the “xx hours ago” is the last time the state actually changed. In the picture, there are 20 hours from 12:37 AM to 10:08 PM. Sometimes the “xx hours ago” is how many hours ago HA was restarted. I see this all the time. In fact, you can see it in his second picture, where the start of the ‘off’ period was still 12:37 AM, yet the “xx hours ago” said “36 seconds ago”, because he had just restarted HA.

I understand that, I’m trying to understand what @swoofz’s problem actually is. Everything I see in this thread looks correct, except swoofz is saying it’s not. I think there is a disconnect here that I’m trying to root out.

my last changed was 12:36AM local time but somehow HA stored that in UTC, that’s the problem.

Having this issue, I’m thinking of publishing MQTT messages for last changed of on and off of the rain sensor in local time and refer that in the condition whenever needed.

Any thoughts? Thanks.

Yep. Totally agree.

@swoofz last changed does not mean last time it switched from wet to dry. it could have gone from dry to dry. Sensors do that, they report all the time. If they report the same state, it gets updated… The graph shows the state changes, not the updates.

so this was the automation I tried at 7am just to test the condition :

- alias: Test Condition
  trigger:
    platform: mqtt
    topic: 'home/OpenMQTTGWDev/433toMQTT'
    payload: '10839684'
  condition:
    condition: template
    value_template: >
    {{ is_state('binary_sensor.rain_sensor','off') and
       (now() - states.binary_sensor.rain_sensor.last_changed).total_seconds() > 2 * 60 * 60}}
  action:
    - service: switch.turn_on
      data:
        entity_id: switch.Sprinkler_1

the automation above didn’t work while the fact that my sensor has been in off state since 12:36AM, around 6hrs past the last change from on to off until I tried the condition.

Binary sensor state : {{ states.binary_sensor.rain_sensor.state }}
Is state off : {{ is_state('binary_sensor.rain_sensor','off') }}
Last Changed : {{states.binary_sensor.rain_sensor.last_changed }}
Time now : {{ now() }}

Time difference : {{states.binary_sensor.rain_sensor.last_changed - now()}}

Time difference in seconds : {{ (now() - states.binary_sensor.rain_sensor.last_changed).total_seconds()}}

Condition :
{{ is_state('binary_sensor.rain_sensor','off') and (now() - states.binary_sensor.rain_sensor.last_changed).total_seconds() > 2 * 60 * 60 }}

The result :

Binary sensor state : off
Is state off : True
Last Changed : 2018-07-10 00:36:14.380060+00:00
Time now : 2018-07-10 07:57:10.929243+07:00

Time difference : -1 day, 23:39:03.450182

Time difference in seconds : 1256.549959

Condition :
False

You can see that using the approach above, the difference from last changed to now() is only 1256 seconds or almost 21 minutes while the fact it should be around 6hrs. Last switch from on to off was at 12:36 local time but the value is store in UTC instead of local time.

any other way I can track the last change from on to off / wet to dry or the other way around without using last_changed? Thanks.

Right, but you restarted at 7 am right? So the last updated changed to 7am when you restarted. Just like when you restarted at 10:45pm and it changed:

My point is, your automation will work if you leave it and it actually changes from x to dry and you don’t restart.

EDIT: Looking at the dev docs too, this statement is false too, so disregard that:

right, I did restart after each change of the code on automation.

So, HA didn’t refer to the actual last state change from on to off (12:36AM as shown in the graph) but will always refer last state change after restart?

Only with last_changed and last_updated.

You can use the history statistics to do this and ignore restarts:

Set it up to look for 2 hours behind for ‘off’. If the sensor is off for the full 2 hours, start the sprinkler.

Probably overkill. You could just leave it how you got it, it will only screw up for the first 2 hours after a restart… if no water was detected.

I think you’re getting fooled by the picture. I think that picture may leave out some details. E.g., when HA restarts, I think the sensor might be going to a state of ‘unknown’. It also may go from None to it’s real value at a restart. Try doing this from your ssh shell:

grep 'new_state=<state binary_sensor\.rain_sensor=' home-assistant.log

Or

grep -o 'new_state=<state binary_sensor\.rain_sensor=[^;]*' home-assistant.log

Hopefully that will tell you what’s really happening with the state of your sensor.

1 Like

Thanks @petro, @pnbruckner , I’ll try to explore the history stats and hope can come up with a solution…

2 Likes

So, because I was curious, some more details/background:

When you look at the device_tracker entity in the frontend, like this:

image

The “4 hours ago” probably comes from states.device_tracker.xxx.last_changed. And as we’ve discussed, this doesn’t go any further back than the last HA restart. (More on that below.) However, the bar graph, and the times shown when hovering the mouse over one of the time periods, comes (effectively) from GET /api/history/period/<timestamp>. You can see this if you look at home-assistant.log when you click on the entity and that window opens:

2018-07-11 15:43:07 INFO (MainThread) [homeassistant.components.http.view] Serving /api/config/entity_registry/device_tracker.phillip_bruckner to xx.xx.xx.xx (auth: True)
2018-07-11 15:43:07 INFO (MainThread) [homeassistant.components.http.view] Serving /api/history/period/2018-07-11T20:42:50.654Z to xx.xx.xx.xx (auth: True)
2018-07-11 15:43:07 DEBUG (Thread-2) [homeassistant.components.recorder.util] converting 0 rows to native objects took 0.023312s
2018-07-11 15:43:07 DEBUG (Thread-2) [homeassistant.components.history] get_significant_states took 0.039570s

So, basically, that information comes from querying the database for entity state changes during the last 24 hour period.

Regarding states.device_tracker.xxx.last_changed, when HA starts, the recorder component is used to retrieve the last state of the entity. The entity is then added to the state machine with that state. However, this creates a state “change”, from None, to the retrieved state. Since that’s a state change, last_changed is updated accordingly. I suppose it might be nice if last_changed was someone set according to the last state change recorded in the database, which would then make it agree with the bar graph. But, I guess it just doesn’t work that way. And there may be other, less obvious reasons, why it shouldn’t.

So, bottom line, I think @petro’s idea of creating and using a history statistics sensor is the right idea.

1 Like

Nice investigation. I’m wondering if a custom component could be built to do an query and find the true last_changed on a sensor/device.

I did my rain sensor so that rather than setting a timer to cancel, it publishes a timestamp for when I want it to cancel to MQTT with retain set. That way, my rain sensor survives reboots, reloads, or whatever. I check every 15 minutes (I think) to see if the current time matches or is after the time set and if it is, I cancel the rain sensor. It’s also templated so that different amounts of rain give different delay values. I love this program!!!