How to do an 'intelligent' timer switch?

Maybe someone could help with following task: I have a switch, just GPIO output with relay, operated by binary-sensor (also GPIO with button). Idea is to have following functionality:

  • short press switches the light on for some time, then switch it off after this time.
  • long press of button switches the light without time limit
  • short press when light is on, switches it off.
    I did it as follow:
binary_sensor:
  - platform: gpio 
    id: In5
	[...] some definitions regarding hardware input
    on_click:
    - min_length: 50ms
      max_length: 1000ms
      then:
        - if:
            condition:
                lambda: 'return id(Out_4).state;'
            then:
                - switch.turn_off: Out_4
            else:
                - switch.turn_on: Out_4
                - delay: 100s
                - switch.turn_off: Out_4
    - min_length: 1000ms
      max_length: 5000ms
      then:
        - switch.turn_on: Out_4  

And generally it works fine. But problem is with “untypical behavior” of users: e.g. when user do a short click, the he decide that he needs longer time and tries to swith it again, but without limit - no way! After first short click, delay is working and counts 100s. During this time you can switch it off, switch again by “long press”, but anyway after 100s light will be off.
Same situation in other story: somebody switch the light on, but only for short time, e.g. for 30 seconds. Then he switch the light off. But “delay” timer still works. When after one minute somebody else switch the light on, ot won’t be on for 100 seconds, it will be only 10 seconds, light will be switched off by previously run procedure!

So question: how to “break” already working delay procedure, or how to do whole procedure better? Needed solution seems to be quite typical, so I’m sure it should be well known, tried to google but found nothing.

You could use a script instead, this allows modes like HA automations where it can be set to restart.

Edit. I just want to note that, it’s my understanding that conditional statements should evaluate to true or false.

1 Like

You would have to put that in a script, since you can stop those (and check if its running).
Delay is async so will run all the time otherwise

@Mikefila Didnt see you typing :smiley: Sorry!

2 Likes

lol no worries

Done, works perfect! :slight_smile:

script:
  - id: timer_schody
    then:
      - switch.turn_on: Out_4
      - delay: 100s
      - switch.turn_off: Out_4     

switch:
  - platform: gpio 
      id: In5
      on_click:
      - min_length: 50ms
        max_length: 1000ms
        then:
          - if:
              condition:
                  lambda: 'return id(Out_4).state;'
              then:
                  - switch.turn_off: Out_4
                  - script.stop: timer_schody
              else:
                  - script.execute: timer_schody
      - min_length: 1000ms
        max_length: 5000ms
        then:
          - script.stop: timer_schody
          - switch.turn_on: Out_4      

Thank you both for good hint!

4 Likes

Hi Jarek,

I ran into exactly the same problem. In my case it’s a heater.
I am still rather new to this YAML coding and I don’t get that part where you refer to “id: In5” …
I still need/want to create that binary_sensor same as you did in your first example
Can you pls share the full YAML code as an example?
I can’t get it to work based on this snippet

Regards,
Erwin

This is all pretty basic yaml that is used everywhere and why copying it might seem helpful but, its not. id: In5 is the id and what you will use very frequently so each sensor or whatever you make has it’s own unique identification. Here he chose to make the id of his binary sensor “In5” If you need to make a binary sensor or a regular sensor, the best place to find out how to do that is buy referring to the Docs https://esphome.io/ Theres a table of contents or the search bar that you can find the pages for binary sensor. It explains and gives you examples of how to setup a binary sensor as well as all the different things you can do to customize how your sensor interacts with its surroundings. It takes time, work, and effort but this is where you start learning how to make things with your personality on them instead of copying chunks of code you don’t understand and settling with sloppy seconds. Theres a whole community of people here and willing to help but, you gotta make an effort.

@Fallingway24 filled out the topic (thx!). Above there is all needed code, only begin of section “switch” was not present, I have added it in the meantime.
id: In5 is just an identifier of my input. Same as Out_4, which is an id of output.