How to only read a sensor at a specific time

Hi,

I have a problem with the ultrasonic sensor in my watertank giving very unstable readings when the sun is on the tank, i guess the humidity and temp inside tank are very high then. How would i force the sensor only to be updated at say midnight?

The sensor is an nodemcu based ultrasonic sensor running via esphome, i know you can set sample rate duration in the nodemcu but i want sample time.

I also tried setting up a time triggered input_binary sensor but couldnt get the syntax right to copy the actual sensor reading to it.

Any help appreciated…

1 Like

I would use a filter on your sensor that only passes the value on at certain times during the day otherwise it would just pass the current state. Solution requires time: component be used to provide current time if you’re not already using that of course.

Hi,
Interesting reading up on the filters, (I didnt know they existed) however i dont see a time triggered filter?
How would you use this?

If I only wanted something done at a certain time, I wouldn’t use a sensor, I’d use an automation and one or more input_[number, text, boolean] values to which I could set my value(s).

Yea, thats kind of what I tried but couldnt get the code right, any examples ?

Where are you getting the data for the input/sensor?

Edit: I haven’t actually done this, but the more I think about it, the more I think it’s actually not possible. Sensors are the only things that ‘get’, so I don’t think you can do this in an automation.

I like @micque’s solution of having a condition in the value_template, but that doesn’t stop the sensor from retrieving the value to be run through the template as often as it ever did. You won’t actually be able to control when it tries to retrieve its value, it’s just that the state will only change based on the template’s time condition.

  value_template: >
    {%- if (states('sensor.time') > "13:00") and (states('sensor.time') < "14:00") -%}
      {{ some new sensor value }}
    {%- else -%}
      {{ states('sensor.whatever_sensor_this_is_so_the_value_remains_unchanged') }}
    {%- endif -%}

Use a lambda filter which allows you to create an if then else statement. I’m out of pocket right now but can create a sample for you when I get home if you would like.

Yes please, that would be great thank you.

I happened to be reading the template sensor manual page, and I found this, it’s the answer to your question!

We have a sensor that doesn’t use any entities. It’ll never get triggered to update because it doesn’t reference any other entity’s state

sensor:
  - platform: template
    sensors:
      nonsmoker:
        value_template: "{{ (( as_timestamp(now()) - as_timestamp(strptime('06.07.2018', '%d.%m.%Y')) ) / 86400 ) | round(2) }}"
        entity_id: []
        friendly_name: 'Not smoking'
        unit_of_measurement: "Days"

Then we have an automation that updates that sensor under specific arbitrary conditions:

automation:
  - alias: 'nonsmoker_update'
    trigger:
      - platform: time_pattern
        minutes: '/5'
    action:
      - service: homeassistant.update_entity
        entity_id: sensor.nonsmoker

Yea, I dont necessarily need to stop the sensor retrieving values, this work around will work.
But as I am still a bit of a noob its the syntax of what goes here {{ some new sensor value }} where I am stuck…

Why don’t you post what you had so far and we can tweak it.

This is what I was playing with in my configuration.yaml file but clearly my syntax is wrong

sensor:
  - platform: template
    sensors:
      watertank_reading:
        value_template: "{{% if (states('sensor.time') = "23:00") -%}
      {{ watertank_reading = states.sensor.tank_sensor.state }}"

Sure, your syntax may not be perfect, but it helps me to get the idea of what you want to accomplish. Seeing this, I’d go back to my original suggestion of just taking the sensor value at 23:00 and sticking it in an input field, either input_number or input_text depending on what type of value that sensor has.

input_number:
  tank_sensor:
    name: 'Water tank sensor value at 23:00'
    
automation:
  trigger:
    - platform: time
      at: '23:00:00'
  action:
    - service: input_number.set_value
      data_template:
        entity_id: input_number.tank_sensor
        value: '{{ states("sensor.tank_sensor") }}'
1 Like

I get the error…

Invalid config for [input_number]: required key not provided @ data[‘input_number’][‘tank_sensor’][‘max’]. Got None
required key not provided @ data[‘input_number’][‘tank_sensor’][‘min’]. Got None. (See /config/configuration.yaml, line 282). Please check the docs at https://home-assistant.io/components/input_number/

I just wrote that off the cuff I guess I didn’t define some required attributes for the input_number. You should read that documentation it links to.

OK finally home. So this is if you want to change the sensor value via code in esphome.

First create a global to handle the startup condition.

globals:
  - id: first_read
    type: boolean
    initial_value: 'true'

Then create a time component. This one runs off the HA clock

time:
  # time based on Home Assistant time
  id: ha_time
  platform: homeassistant
  timezone: "whereever"

Then in the ultrasonic sensor code do the following (filters is the focus here)

sensor:
  - id: water_tank
    platform: ultrasonic
    trigger_pin: 25
    echo_pin: 26
    name: Tank Level
    filters:
      lambda: |-
        auto now = id(ha_time).now(); // local time
        if ((now.hour >= 22 && now.hour < 6) || id(first_read)) return x;
        else return id(water_tank).state;
        id(first_read) = false;

So what this will do is from 10pm to 6am the sensor will send the actual reading through to be published to HA. The rest of the time the sensor will send the stored value (probably the value read at 6am). The first_read boolean ensures that you get at least one reading no matter when the system starts. If you need to do some additional processing on the reading “x” you can add any math you want before returning the value;

If you decide to pursue this and need some additional help let me know. Otherwise for future coding it’s a great technique for allowing test data to be injected into your system through a sensor.

Oh wow, thank you for your time and effort !
Just to clarify, does all this code go into my esphome node?

Yes this is code that would go into your node. This would not change how you’re currently publishing to ha.

OK, re-uploaded the node and rebooted HA but were still getting varying results for the tank level every minute or so…?

Did you put your correct time zone in? If not my fault for not putting that out.