On_press not firing on 1st boot?

I have an ESPHome connected with inputs for hot water and heating zone demands. I have an output for the boiler “demand signal”.

The 3 input pins increment a number by 1,2,4 when pressed.



#HW Demand Input
binary_sensor:
  - platform: gpio
    device_class: heat
    pin:
      number: 14
      inverted: true
      mode:
        input: true
        pullup: true
    name: HW Demand
    id: HW_Demand    
    filters:
      - delayed_on_off: 100ms
    on_press:
    #1st bit in state table
      then:
        - number.set:
            id: InputState
            value: !lambda 'return id(InputState).state + 1;'
    on_release:
      then:
        - number.set:
            id: InputState
            value: !lambda 'return id(InputState).state - 1;'


#CH1 Demand input
  - platform: gpio
    device_class: heat
    pin:
      number: 12
      inverted: true
      mode:
        input: true
        pullup: true
    name: CH1 Demand
    id: CH1_Demand    
    filters:
      - delayed_on_off: 100ms
    on_press:
    #2nd bit in state table
      then:
        - number.set:
            id: InputState
            value: !lambda 'return id(InputState).state + 2;'
    on_release:
      then:
        - number.set:
            id: InputState
            value: !lambda 'return id(InputState).state - 2;'

#CH2 Demand input    
  - platform: gpio
    device_class: heat
    pin:
      number: 13
      inverted: true
      mode:
        input: true
        pullup: true
    name: CH2 Demand
    id: CH2_Demand    
    filters:
      - delayed_on_off: 100ms    
    on_press:
    #3rd bit in state table
      then:
        - number.set:
            id: InputState
            value: !lambda 'return id(InputState).state + 4;'
    on_release:
      then:
        - number.set:
            id: InputState
            value: !lambda 'return id(InputState).state - 4;'

These inputs are effectively creating a state table, which I then test within the “InputState” number definition to switch 2 outputs - one to fire the boiler, one to set a PWM output which controls the boiler flow temperature via a digital potentiometer.


number:
  - platform: template
    name: InputState
    id: InputState
    min_value: 0
    max_value: 32
    step: 1
    restore_value: true
    optimistic: true
    on_value:
#switch boiler demand on for whichever states need it if any inputs are high. Off if not
      -  if:
          condition:
              or:  
                - and:
                  - lambda: 'return x >= 1;'
                  - lambda: 'return x <= 15;'
                - lambda: 'return x == 18;'
                - lambda: 'return x == 20;'
                - lambda: 'return x == 22;'
                - lambda: 'return x == 24;'
                - lambda: 'return x == 26;'
                - lambda: 'return x == 28;'
                - lambda: 'return x == 30;'

          then:
            switch.turn_on: Boiler_Demand
          else:  
            switch.turn_off: Boiler_Demand

#set boiler flow temp hot when we're heating the cylinder and set away mode
      -  if: 
          condition:
            or:
                - lambda: 'return x == 1;'
                - lambda: 'return x == 8;'
                - lambda: 'return x == 9;'
                - lambda: 'return x == 24;'
          then:
            light.turn_on: 
              id: BoilerTemp
              brightness: !lambda |-
                return id(Boiler_High_Temp).state / 100.0;

          else:
            light.turn_on:
              id: BoilerTemp
              brightness: !lambda |-
                return id(Boiler_Low_Temp).state / 100.0;

This all works fine, apart from on 1st boot.

If the inputs are “on” during boot, then the “on_press” of the inputs does not appear to fire and “InputState” remains as 0. If I then switch the input “off” and back on again then the on_release and on_press events are registered.

Not quite sure where the problem is? Is it becase “InputState” has not been initialised when the input is evaluated?

Any ideas on how to resolve? Cheers.

on_press is looking for a state change, specifically the lead edge of the signal on_release would be the trailing edge. As would be created by a button press.

This automation will be triggered when the button is first pressed down, or in other words on the leading edge of the signal.

If the state is on no change occurred, you could use on_boot with a condition if the switch is on, to run the actions from on_press

1 Like

Thank you for the explanation. I added the actions to on_boot and that works. However I end up duplicating all the logic for all inputs in that section. Is there a more elegant way of doing this? Ideas that come to mind are

Is there a way of pretending the input starts at 0 and then triggering the switch evaluation?
Move all the input checking into a continuous while loop rather than an on_press event?

One possible solution is to use a script.

1 Like

Thanks both. I’ve ended up removing most of the logic from the input on_value events and putting all the processing in a script.