ESPHome delayed_on_off

Hi,

I have made a raindrop sensor with the ESPHome binary sensor

Have two questions about it.

First question.
Is this:

filters:
      - delayed_on_off:
          time_on: 3s
          time_off: 120s

the same as:

filters:
      - delayed_on: 3s
      - delayed_off: 120s

Which one is the best to use? and what is the difference?

I want to give the raindrop sensor some time to dry, so it is not flapping between wet and dry. If it is dry for 2 minutes, i think it will keep it dry till the next rain drops. But i have a problem with that, see next question.

This is the sensor code, works, except for one thing, see next question:
binary_sensor:

  - platform: gpio
    device_class: moisture
    pin:
      number: GPIO5
      inverted: true
    name: raining
    id: raining
    filters:
      - delayed_on: 3s
      - delayed_off: 120s

The next question. I have the problem that when the ESP is restarted and the raindrop sensor is dry, the binary_sensor state is unknown after boot.
When delayed_off is < 5s (not sure if it is exactly below 5) than this problem is solved.
The sensor is dry after boot.
Sensor is only unknown on boot with a long delayed_off filter. It keeps unknown, till there is a state change.

I also experimented with on_boot. Did not solve the problem

  on_boot:
    priority: 200
    then:
      - delay: 130s   < does not work, with or without delay. always unknown after boot 
      - lambda: |-
          if (id(raining).state) {
            id(raining).publish_state(true);
          } else {
            id(raining).publish_state(false);
          } 

and also tried with publish_initial_state, did not solve the problem, still unknow after boot when delayed_off is more than approximately 5sec

Welcome to the HA forum!

First answer:

No, they are not the same.
delayed_on and delayed_off will just delay publishing the state by the specified time.
delayed_on_off requires the state to stay the same for the specified time before it is published.

Which one is best to use depends on your requirements.

Second answer:

As delayed_off is templatable, you could use a lambda to set the time dynamically. First time after boot it’s (maybe 100ms) and on subsequent passed it’s set to 120s.

      delayed_off: !lambda |-
        static int delay = 0;
        if (delay == 0) {
          delay = 100;  // return 0.1  seconds in ms
        } else {
          delay = 120000;  // return 2 minutes in ms
        }
        return delay;

I have not tested the above, so let me know if it works for you.

PS. Maybe the settle filter will suit your usecase better?

1 Like

This is working with your template, when the sensor boots, it is publishing its state now. It is not unknown when the sensor boots any more.

Tested the sensor, it works as expected now.
When the sensor is wet for 3seconds it is publishing ON.
When it stays dry for 120seconds is publishing OFF.

So if i understand the template
it sets delay to 0, and if it is 0 it sets the delay to 100ms onboot and it is publishing the OFF state because it is OFF for 100ms, and after that, is sets the delay to 120 because delay is not 0 any more (it is 100ms) seconds?
Never thought about that solution :slight_smile:

Thanks!

You got it. The delay variable is static, so it’ll be zero after boot, but subsequently it’ll contain the last delay in ms.

It’s a bit of a kludge, but if it works :wink:

I saw publish_initial_state in the advanced variables for a binary sensor. Also for delay you could do delay_on_off if you want state reported after delay or use settle to do same thing but report in the beginning