Using and Altering Delay_off in Binary Sensors

The bottom line is I want to be able to edit delays on some binary sensors. I’ve looked over the docs on delayed_off and that tells how to set it at compile time. I’ve looked at the API info on Binary Sensors and I can’t find what I want there, either, for use in a lambda. I realize that it’s a filter, and there is the function add_filter() in the API, but there is no apparent way to remove a filter or edit one.

From what I can tell, it seems the only way to change the delay value is at compile time. (It looks to me like the entire purpose is to debounce a switch, so I can understand why it would not seem to be needed to be editable.) So I don’t expect a way to edit this value later. (I want to use a Number Template so I can change the value as needed. I’m using this to control vent fans and other devices that would need to stay on for a limited time after an entity is switched off.)

This one is probably a job for a script in restart mode.

delay: is templateable

If you haven’t discovered scripts yet they are pretty flexible.

I didn’t get hits on “restart mode.” Is it anything more complex than just having to restart the device so the new values take effect?

(Still looking over the rest of the info.)

It’s this bit which shows the general approach.

script:
  - id: hallway_light_script
    mode: restart     # Light will be kept on during 1 minute since
                      # the latest time the script is executed
    then:
      - light.turn_on: hallway_light
      - delay: 1 min
      - light.turn_off: hallway_light

...
  on_...:           # can be called from different wall switches
    - script.execute: hallway_light_script

It looks like this will do exactly what I want. I realized, after looking over the link, I had looked at automations and at delay, but had ruled it out, thinking, “What happens if the switch is turned off, then on again - how will that effect the delay?”

So I want to rephrase this to be sure I understand what’s happening.

In the script example above, when hallway_light_script is called, it will turn on the light for 1 minute, then turn it off. BUT - the restart mode will keep it on for 1 minute after the last time the script is called. So the restart will reset the 1 minute timer every time the script is called.

If I write a script like this, when a switch is turned off, it will keep track of if it is turned on and back off again, later.

This would do a lot of what I need, with one issue. Instead of turning a device on or off, I’d like to just publish a value - could be a number, string, or boolean, that such a script could change, that I can publish so it can be read by HA, but so it can’t be changed from an external agent.

For instance, add a boolean, “Switch1_delay.” It turns on when I turn the switch on and Switch1_delay = true, but then, when I turn the switch off, after the delay is done, instead of turning something on or off, it would change Switch1_delay to false. (But I also have to be sure Switch1_delay is published, but can’t be changed by HA or anything else.)

That’s right. I used to do it like this until I saw the restart mode approach.

substitutions:
  auto_off_after_x_mins: 45min

switch:
# Relay itself
  - platform: gpio
    name: ${friendly_name}
    pin: GPIO14
    id: relay
    restore_mode: ALWAYS_OFF
    on_turn_on: # Action when relay is turned on
      - script.execute: led_power_on
      - script.stop: auto_off_timer # Stop any existing count down timers
      - script.execute: auto_off_timer # Start new timer to turn of power to glue gun after some time.

script:
  - id: auto_off_timer # Turn off after some time.
    then:
      - delay: ${auto_off_after_x_mins}
      - switch.turn_off: relay

You can do whatever you like in the script, like publish a state:

    # Turn off the "Fresh data recieved sensors"
      - binary_sensor.template.publish:
          id: water_tank_level_recieved
          state: OFF

    #Publish battery level to the end of day sensor since it will be our last update.
      - lambda: return id(end_of_day_battery_percent).publish_state(id(batt_level).state);