Last "disconnected" state and "connected" state

Hey all,

I have an automation that notifies me via email whenever HA reconnects to the internet, after a disconnection :

alias: HA Healthcheck
description: ""
triggers:
  - trigger: state
    entity_id:
      - binary_sensor.8_8_8_8
    id: Internet Reconnection
    from: "off"
    to: "on"
conditions: []
actions:
  - if:
      - condition: trigger
        id:
          - Internet Reconnection
    then:
      - action: notify.gmail
        metadata: {}
        data:
          message: >-
            HA System is now reconnected to the internet.
          title: ⚠️🚨 HA Reconnected ⚠️🚨

So basically, when the binary sensor, 8.8.8.8, changes to “on”, internet connectivity has been re-established. What I’d also like to know is when the disconnection happened, ie. when was 8.8.8.8 last in the “off” state - having this timestamp in the email alert will be super helpful.

Thanks!

I’m not sure this is correct but I believe it’s

{{ trigger.from_state.attributes.last_changed }}
1 Like

Thanks for the reply - how’s that different from

{{ trigger.from_state.last_changed }}

from_state is a state object in itself and so one may directly reference the last_changed attribute that way instead of having attributes.last_changed?

This worked for me : {{ trigger.from_state.last_changed }}

Hello Vish2024,

Look in the trace of an automation run from this.

1 Like

Oh yes I see them in traces :+1:

1 Like

Quick follow up question - how does one compute the following duration : trigger.to_state.last_changed - trigger.from_state.last_changed? This should give me the duration for which HA was disconnected before reconnecting again, which I think helps to include in the notification email.

Here’s my attempt :

{{ trigger.to_state.last_changed.timestamp() | timestamp_custom('%H:%M:%S') - trigger.from_state.last_changed.timestamp() | timestamp_custom('%-H:%M:%S') }}

This gave me the following error :

Error rendering data template: TypeError: unsupported operand type(s) for -: ‘str’ and ‘str’

Thanks!

{{ (trigger.to_state.last_changed.timestamp()  - trigger.from_state.last_changed.timestamp()) | timestamp_custom('%-H:%M:%S') }}

Not sure I got it correct since I posted this from my phone.

No worries - I see how the timestamp() syntax works now.

While this isn’t giving me any syntax error, the calculation seems really off.

Here’s my action yaml:

sequence:
      - action: notify.gmail
        metadata: {}
        data:
          message: >-
            Disconnected at : {{
            trigger.from_state.last_changed.timestamp() |
            timestamp_custom('%Y-%m-%d %-H:%M:%S') }} and then connected at {{
            trigger.to_state.last_changed.timestamp() |
            timestamp_custom('%Y-%m-%d %-H:%M:%S') }}; Disconnection duration :
            {{ (trigger.to_state.last_changed.timestamp()
            -trigger.from_state.last_changed.timestamp()) |
            timestamp_custom('%-H:%M:%S') }}
          title: ⚠️🚨 HA Reconnected ⚠️🚨

Here’s an email alert from a test I just did :

Disconnected at : 2025-11-05 10:25:10 and then connected at 2025-11-05 10:26:29; Disconnection duration : 05:31:19

The timestamps are accurate but the duration value is off. If I remove custom timestamp and just do this :

{{ (trigger.to_state.last_changed - trigger.from_state.last_changed) }}

I get correct values but it also throws me those enormous millisecond strings that I’d rather not lay my eyes on.

I appreciate the help.

I don’t understand that…
Perhaps they need to be int casted. But that shouldn’t be needed.

sequence:
      - action: notify.gmail
        metadata: {}
        data:
          message: >-
            Disconnected at : {{
            trigger.from_state.last_changed.timestamp() |
            timestamp_custom('%Y-%m-%d %-H:%M:%S') }} and then connected at {{
            trigger.to_state.last_changed.timestamp() |
            timestamp_custom('%Y-%m-%d %-H:%M:%S') }}; Disconnection duration :
            {{ (trigger.to_state.last_changed.timestamp() | int
            -trigger.from_state.last_changed.timestamp() | int) |
            timestamp_custom('%-H:%M:%S') }}
          title: ⚠️🚨 HA Reconnected ⚠️🚨

You could also use the other one you had working.

{{ ((trigger.to_state.last_changed - trigger.from_state.last_changed) / 60 ) | int }} minutes