Setting Up an Output Controlled By a Binary Sensor

I need some help setting up an output controlled by a binary sensor. I’m using an esp8266 with a float sensor to detect the water level in a sump well. I’ve been able to configure a binary sensor to detect when the switch in the sump float is open/closed. This area of the code works well. The sensor is seen in HA and performs the way I expect.

I’m trying to add an LED to indicate when the sump float switch is closed. I’ve configured Pin D1 as an output for the LED. I thought adding on_turn_on: and on_turn_off: commands to the binary sensor would work but the ESPHome editor indicates there’s an error.

I need guidance on how to achieve the desired outcome. Would you mind looking over my code and suggesting how an LED connected to a GPIO pin can be turned on/off when the binary sensor is true/false.

Here is the full code I’m trying to use;

esphome:
  name: sump-water-level-monitor

esp8266:
  board: esp01_1m
  
# WiFi connection, replace these with values for your WiFi.
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# Enable logging
logger:

# Enable Home Assistant API
api:

# Enable over-the-air updates.
ota:
    password: !secret ota_password

# Enable Web server.
web_server:
  port: 80

# Sync time with Home Assistant.
time:
  - platform: homeassistant
    id: homeassistant_time

# Text sensors with general information.
text_sensor:
  # Expose ESPHome version as sensor.
  - platform: version
    name: sump_water_level_monitor ESPHome Version
  # Expose WiFi information as sensors.
  - platform: wifi_info
    ip_address:
      name: sump_water_level_monitor IP
    ssid:
      name: sump_water_level_monitor SSID
    bssid:
      name: sump_water_level_monitor BSSID

# Exposed switches.
# Switch to restart the door-contact-garage.   
switch:
  - platform: restart
    name: "sump_water_level_monitor Restart"

# Enable On-Board Status LED.
status_led:
  pin:
    number: GPIO2
    inverted: true

sensor:
  # Uptime sensor.
  - platform: uptime
    name: sump_water_level_monitor Uptime

  # WiFi Signal sensor.
  - platform: wifi_signal
    name: sump_water_level_monitor WiFi Signal
    update_interval: 60s
  
# Define output for "Sump High Level Alarm"
output:
  - platform: esp8266_pwm
    id: alarm_led
    pin:
      # Pin D1
      number: GPIO5
      inverted: true

binary_sensor:
  - platform: gpio
    pin:
      # Pin D3
      inverted: true
      number: GPIO0
      mode:
        input: true
        pullup: true
    name: "Sump Water Level Monitor"
    device_class: moisture
    on_turn_on:
      - output.turn_on: alarm_led
    on_turn_off:
      - output.turn_off: alarm_led

Here’s the section I’m having trouble with;

    on_turn_on:
      - output.turn_on: alarm_led
    on_turn_off:
      - output.turn_off: alarm_led

The last four lines are where the ESPHome editor indicates there’s an error. What’s not clear is what the error is?

Any help would be appreciated.

on_turn_on is not available for binary sensors. You will need to add an id to the binary sensor

id: sump_sensor
on_state:
  then:
    - lambda: |-
        if (id(sump_sensor).state) {
          id(alarm_led).turn_on();
        } else {
          id(alarm_led).turn_off();
        }

@Mikefila, worked perfectly! Thank you so much. I’ve learned a little more about coding and how these great little esp8266’s work.

Here’s the revised code and working code, should anyone be interested.

esphome:
  name: sump-water-level-monitor

esp8266:
  board: esp01_1m
  
# WiFi connection, replace these with values for your WiFi.
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# Enable logging
logger:

# Enable Home Assistant API
api:

# Enable over-the-air updates.
ota:
    password: !secret ota_password

# Enable Web server.
web_server:
  port: 80

# Sync time with Home Assistant.
time:
  - platform: homeassistant
    id: homeassistant_time

# Text sensors with general information.
text_sensor:
  # Expose ESPHome version as sensor.
  - platform: version
    name: sump_water_level_monitor ESPHome Version
  # Expose WiFi information as sensors.
  - platform: wifi_info
    ip_address:
      name: sump_water_level_monitor IP
    ssid:
      name: sump_water_level_monitor SSID
    bssid:
      name: sump_water_level_monitor BSSID

# Exposed switches.
# Switch to restart the door-contact-garage.   
switch:
  - platform: restart
    name: "sump_water_level_monitor Restart"

# Enable On-Board Status LED.
status_led:
  pin:
    # Pin D4
    number: GPIO2
    inverted: true

sensor:
  # Uptime sensor.
  - platform: uptime
    name: sump_water_level_monitor Uptime

  # WiFi Signal sensor.
  - platform: wifi_signal
    name: sump_water_level_monitor WiFi Signal
    update_interval: 60s
  
# Define output for "Sump High Level Alarm"
output:
  - platform: esp8266_pwm
    id: alarm_led
    pin:
      # Pin D2
      number: GPIO4

binary_sensor:
  - platform: gpio
    pin:
      # Pin D3
      inverted: true
      number: GPIO0
      mode:
        input: true
        pullup: true
    name: "Sump Water Level Monitor"
    id: sump_sensor
    device_class: moisture
    on_state:
      then:
        - lambda: |-
            if (id(sump_sensor).state) {
              id(alarm_led).turn_on();
            } else {
              id(alarm_led).turn_off();
            }
1 Like

Is there anyway of making the LED flash when it’s turned on?

Try

    on_state:
      - while:
          condition:
            binary_sensor.is_on: sump_sensor
          then:
            - output.turn_on: alarm_led
            - delay: 500ms
            - output.turn_off: alarm_led
            - delay: 500ms

@Mikefila, thank you! Works perfect.

Ops! Spoke to soon!

If the LED is on when the sensor returns to false, then it stays on. I think there needs to be an else followed by an output.turn_off. I tried adding an else after the last line of code but the compiler complains of an error.

    on_state:
      - while:
          condition:
            binary_sensor.is_on: sump_sensor
          then:
            - output.turn_on: alarm_led
            - delay: 500ms
            - output.turn_off: alarm_led
            - delay: 500ms
      else:
         - output.turn_off: alarm_led

I think if the action in a script, it will run one full cycle when the sensor goes off

script:
  - id: my_script
    mode: single
    then:
      - output.turn_on: alarm_led
      - delay: 500ms
      - output.turn_off: alarm_led

And use

    on_state:
      - while:
          condition:
            binary_sensor.is_on: sump_sensor
          then:
            - script.execute: my_script
            - delay: 1100ms

edited to reflect change noted below

I added the script then changed the on_state code to match above. The editor complains unable to find action with name ‘script.turn_on’

I’m going to try script.execute after I eat dinner!

that’s it script.execute: my_script

Yes sir, it is!

script.execute: my_script did the trick. I’m going to tinker a little with timing but otherwise it’s great.

Thank you for helping me understand the direction I needed to move. Very helpful.

EDIT: For those who may be interested, here is the final code for my High Water level sensor/alarm;

esphome:
  name: sump-water-level-monitor

esp8266:
  board: esp01_1m
  
# WiFi connection, replace these with values for your WiFi.
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

# Enable logging
logger:

# Enable Home Assistant API
api:

# Enable over-the-air updates.
ota:
    password: !secret ota_password

# Enable Web server.
web_server:
  port: 80

# Sync time with Home Assistant.
time:
  - platform: homeassistant
    id: homeassistant_time

# Text sensors with general information.
text_sensor:
  # Expose ESPHome version as sensor.
  - platform: version
    name: sump_water_level_monitor ESPHome Version
  # Expose WiFi information as sensors.
  - platform: wifi_info
    ip_address:
      name: sump_water_level_monitor IP
    ssid:
      name: sump_water_level_monitor SSID
    bssid:
      name: sump_water_level_monitor BSSID

# Exposed switches.
# Switch to restart the door-contact-garage.   
switch:
  - platform: restart
    name: "sump_water_level_monitor Restart"

# Enable On-Board Status LED.
status_led:
  pin:
    # Pin D4
    number: GPIO2
    inverted: true

sensor:
  # Uptime sensor.
  - platform: uptime
    name: sump_water_level_monitor Uptime

  # WiFi Signal sensor.
  - platform: wifi_signal
    name: sump_water_level_monitor WiFi Signal
    update_interval: 60s
  
# Define output for "Sump High Level Alert"
output:
  - platform: esp8266_pwm
    id: alarm_led
    pin:
      # Pin D2
      number: GPIO4

# Define Water Level Sensor Input
binary_sensor:
  - platform: gpio
    pin:
      # Pin D3
      inverted: true
      number: GPIO0
      mode:
        input: true
        pullup: true
    name: "Sump Water Level Monitor"
    id: sump_sensor
    device_class: moisture
    on_state:
      - while:
          condition:
            binary_sensor.is_on: sump_sensor
          then:
            - script.execute: flash_led
            - delay: 500ms

# Flash High Water Level Alert LED
script:
  - id: flash_led
    mode: single
    then:
      - output.turn_on: alarm_led
      - delay: 250ms
      - output.turn_off: alarm_led