How to tell if a sensor is offline?

I have a temperature sensor on a Wemos D1 Mini that uses deep sleep. It wakes every 30-seconds to publish the temperature every 10 seconds. Works great. However, when I remove the power to the Wemos, the last value is in the states (<>).tab of Home Assistant. So, if the last read before removing power from the Wemos is 79°F, that’s what the state shows for that sensor forever.

How do I know when a sensor is offline? I can’t use Last Will because every time the deep-sleep sleeps, the connection is lost and the last will message gets sent.

Do a test every 1 min (or less often) to see when it was lay changed. That’s what I do. It obviously depends on whether the value changes a lot or not.

Are you using esphome?

There’s a status sensor but it wont tell the difference between sleep and off-line. So Trigger it on state unavailable for > 1 min. Slightly easier than checking last_changed

My mailbox sensor only wakes every 12 hours (or if mail arrives) so I use this to monitor it’s connection:

- id: mailbox_connection_monitor
  alias: 'Mailbox Connection Monitor'
  initial_state: true
  trigger:
    platform: state
    entity_id: binary_sensor.mailbox_status
    to: 'off'
    for:
      hours: 14
  action:
  - service: notify.telegram_system
    data:
      title: '*ALERT*'
      message: "Communication lost to mailbox sensor."
'''
1 Like

Thanks, I’ll probably try a combination of both ideas.
I did think of monitoring the battery voltage and sending an offline message when it gets below 3V. (I’ll need to see how low the battery can go before the ESP shuts down).

ping sensor?

I use expire_after for some of my rflink sensors, don’t know if that’s what you’re looking for.
Have to say that’s not a standard feature yet, but it’s easy to add.

Cool idea. How would I do that? Automation?

I also thought of sending a toggled flag, 1,0,1,0,1,0 with each sensor reading, so if I could figure out how to detect that the flag isn’t toggling any longer??

That works. I pulled the power from the sensor and after the expire_after time, the sensor value went to “unknown”. So, in my automation, how do I test for a value of “unknown”, or alternately a non-zero value. (Wait, that won’t work in the winter…).

Addendum:

Here’s what I’ve tried in my automations.yaml:

- alias: Check Test Temperature
  initial_state: true
  trigger:
    platform: time
    seconds: '/10'
  condition:
    condition: template
    value_template: '{{ sensor.test_temperature != "unknown" }}'
  action:
    service: notify.test_data
    data:
      message: "{{ (now().month) }}-{{ (now().day) }}-{{ (now().year) }}, {{ (now().hour) }}:{{ (now().minute) }}:{{ (now().second) }}, {{states('sensor.test_temperature')}}"

But now, action: is never triggered.
any tips to make this work would be appreciated.

Something like this

- alias: ab2
  initial_state: true
  trigger:
    - platform: state
      entity_id: sensor.test_temperature
      to: 'unknown'
  action:

And don’t worry, it should work all year round :wink:

It might be at least because you need to use time_pattern trigger.
And your template condition doesn’t look right either, it should be something like

is_state('sensor.test_temperature', 'unknown')

You might find it beneficial to use Developer tools to check your templates.

Please read this docs, there is plenty of useful information in there.

Don’t think it’s the best solution, but anyway - google’s your friend mate.

If you cannot detect if you have a new reading, how an additional flag in each reading would help? :wink:

How do I test for is not state?

I do appreciate the help.

It’s still not working for me. The problem is, and I probably wasn’t clear on this, I want to record data as long as the sensor value is not ‘unknown’. Testing for ‘not’ is what got me looking toward a value template.

Thanks for the tip to use the template tool. As I’ve said before, Templates are my weakest area of knowledge in Home Assistant. I never know when and what kind of template to use - it just hasn’t clicked yet.

At any rate, in platform: state, to ‘unknown’ gives me nothing, while from ‘unknown’ records everything, including the ‘unknown’ values every ten seconds.

My thinking was that every ten seconds I would check the state of a different topic, say ‘sensor.test_nodeonline’. It should be different from the last read. But I am just grasping now.

states(‘sensor.test_temperature’) != ‘unknown’

Try this

- alias: Check Test Temperature
  initial_state: true
  trigger:
    # react on every state change
    platform: state
    entity_id: sensor.test_temperature
  condition:
    # but only send proper (non-unknown) values
    condition: template
    value_template: '{{ trigger.to_state.state != "unknown" }}'
  action:
    service: notify.test_data
    data:
      message: "{{ (now().month) }}-{{ (now().day) }}-{{ (now().year) }}, {{ (now().hour) }}:{{ (now().minute) }}:{{ (now().second) }}, {{trigger.to_state.state}}"

The term topic applies to MQTT, not your case as far as I can see… sorry for nitpicking :wink:

Thanks for persisting with me here.
Your suggested code does not work- the action is never triggered.

I am a bit confused with the {{trigger.to_state.state}} at the end. Does that mean that the action is only triggered with a state change?

You need to learn some debugging technique.
First of all, in a template editor try to paste the message’s template (defining trigger before it) and see if it works as you expect.
Then comment out the condition section to see if that stops the action block from executing.

yeah. as per

Thank you for pushing me to use the tools I have.

Here is the working code:

- alias: Check Test Temperature
  initial_state: true
  trigger:
    platform: state
    entity_id: sensor.test_temperature
  condition:
    # Send proper (non-unknown) values
    condition: template
    value_template: '{{ trigger.to_state.state != "unknown" }}'
  action:
    service: notify.test_data
    data:
      message: "{{ (now().month) }}-{{ (now().day) }}-{{ (now().year) }}, {{ (now().hour) }}:{{ (now().minute) }}:{{ (now().second) }}, {{states('sensor.test_temperature')}}"

What I never figured out was how to define a trigger in the Template Editor.

In your action, replace data with data_template for your templated data to be retrieved, else you’ll just get plain text, I.e. “now().month” instead of the actual month

Well, my code works… Help me understand what you are thinking? As I said above, templating is my weakest understanding of Home Assistant, so any input is appreciated.

Here is what I am getting- date, time, temperature:

6-6-2019, 7:52:15, 83.19
6-6-2019, 7:52:35, 83.19
6-6-2019, 7:52:56, 83.30
6-6-2019, 7:53:17, 83.07
6-6-2019, 7:53:37, 83.07

here is the answer. the rule is if it’s a template, change XXX to XXX_template or it won’t work.

in template editor you just declare trigger variable (a Python dictionary) and add whatever your template uses, in your case for condition:

{% set trigger = {"to_state":{"state":"123"}} %}

It’s actually described here at the very bottom of that paragraph so not very obvious :wink:

Triggers are starting to make sense. I did some experiments with:

{% set trigger = {"to_state":{"state":"0"}} %}
value_template: '{{ trigger.to_state.state != "unknown" }}'

So, if I set state to anything except “unknown”, it resolves to True, and if I set it to “unknown” it resolves as “False”. And, in my automation, if the trigger resolves to true, then the action is executed.

here is the answer. the rule is if it’s a template, change XXX to XXX_template or it won’t work.

message: and message_template: both work the same in my tests. What makes the data into a template? It just looks like data to me.

that’s how condition works. keep on practicing

in case of service calls there is a service and data for it.
both things are template-able, i.e you can put a code to generate service name or some of the data.

if you want to dynamically change service’s name, you should use service_template instead of service, something like

service_template: input_boolean.turn_{{ "on" if trigger.to_state.state != "unknown" else "off"}}

If you want to compose service’s data during runtime (i.e not hard-code it), you should use data_template instead of data

data_template:
  message: >
    The sensor is {{trigger.to_state.state}}

and you can combine them.