ESPHome on esp8266 tacktile button changes state but I want switch based on binary sensor

I have an Ikea lamp that has a microswitch type button which when clicked toggles the state of the light which I read with a binary sensor.
this is the config I have now:

esphome:
    name: cagelamp1
    area: Living Room
    platform: esp8266
    board: nodemcuv2

wifi:
  ssid: SSID
  password: password

captive_portal:

web_server:
  port: 80
  ota: true
  local: true

switch:
- platform: gpio
  pin: D5
  id: click
  name: "On/Off"
  on_turn_on:
  - delay: 500ms
  - switch.turn_off: click

binary_sensor:
- platform: gpio
  device_class: light
  pin: 
    number: D2
    inverted: true
    mode:
      input: true
      pullup: True
  name: "Cage Light"
  filters:
   - delayed_on: 100ms
   - delayed_off: 100ms

So switch is D5, binary sensor is D2
What I cannot do is to make such cagelamp1.yaml file that I have only one visible switch, which, when pressed will cause D5 to turn on for 500ms and then turn off, and this visible switch to read the state of D2, and stay with the state of D2 and not the state of D5.

I tried with different lambdas, but I did not make it work, so I pasted here only the basic code to be easier to understand.

So, D2 the binary_sensor is wired to the actual micro-switch, correct?

What is D5, the gpio switch wired to? Does this go to a relay?

Unfortunately there is no template light in ESPHome. So use the template switch:


output:
  - platform: gpio # not exposed to HA
    pin: D5
    id: light_button

button:
  - platform: output
    internal: true # not exposed to HA
    id: toggle_light
    output: light_button
    duration: 500ms

binary_sensor:
  - platform: gpio
    internal: true # not exposed to HA
    pin: 
      number: D2
      inverted: true
      mode:
        input: true
        pullup: True
    id: light_state
    filters:
     - delayed_on: 100ms
     - delayed_off: 100ms

switch:
  - platform: template
    name: "Cage Light"
    lambda: |-
      if (id(light_state).state) {
        return true;
      } else {
        return false;
      }
    turn_on_action:
      - button.press: toggle_light
    turn_off_action:
      - button.press: toggle_light

You could do this without the button:


output:
  - platform: gpio # not exposed to HA
    pin: D5
    id: light_button

binary_sensor:
  - platform: gpio
    internal: true # not exposed to HA
    pin: 
      number: D2
      inverted: true
      mode:
        input: true
        pullup: True
    id: light_state
    filters:
     - delayed_on: 100ms
     - delayed_off: 100ms

switch:
  - platform: template
    name: "Cage Light"
    lambda: |-
      if (id(light_state).state) {
        return true;
      } else {
        return false;
      }
    turn_on_action:
      - output.turn_on: light_button
      - delay: 500ms
      - output.turn_off: light_button
    turn_off_action:
      - output.turn_on: light_button
      - delay: 500ms
      - output.turn_off: light_button

You can turn this switch into a light in home assistant.

1 Like

D2 is an input, that senses the voltage, when the light is actually running
D5 is the switch pin that is parallel to the hardware switch

Very good looking, but I will have to verify it with a multimeter, when the family is not sleeping and I can take it.

I also did create a variant, much worse looking and I was going to paste it here, because it has a bug: if the physical button is pressed, the light will light up, the binary sensor will detect it, it will trigger the template switch to show that it is on and it will turn on the click switch which will turn off the light:

switch:
  - platform: gpio
    pin: D5
    id: click
    internal: false
    name: "On/Off"
    on_turn_on:
    - delay: 500ms
    - switch.turn_off: click

  - platform: template
    name: Cage light main switch
    id: light_state
    lambda: |-
      if (id(light_sensor).state) {
        return true;
      } else {
        return false;
      }
    turn_on_action:
      - switch.turn_on: click
    turn_off_action:
      - switch.turn_on: click

binary_sensor:
- platform: gpio
  device_class: light
  pin: 
    number: D2
    inverted: true
    mode:
      input: true
      pullup: True
  name: "Cage Light"
  id: light_sensor
  filters:
   - delayed_on: 100ms
   - delayed_off: 100ms
  on_press:
      then:
        - switch.turn_on: light_state
  on_release:
      then:
        - switch.turn_off: light_state

I think your version “without button” will not have this problem, right?

Neither of my versions will have that issue.

1 Like