Water Valve with limit switches for open and closed

See code below. What I am trying to do is determine when the valve is open or closed and NOT stuck in between. The valve has two limit switches. One for when the valve is closed and one for when it is open. One I get everything to work I will hide the two gpio binary sensors. The code passes the validate but dows not compile. I am a true novice but I love Home Assistant and refuse to give up. Any pointers would be welcome.

  - platform: gpio
    name: "Valve Open"
    id: valve_open
    device_class: opening
    internal: false
    pin:
      number: GPIO26
      inverted: true
      mode:
        input: true
  - platform: gpio
    name: "Valve Closed"
    id: valve_closed
    device_class: opening
    internal: false
    pin:
      number: GPIO36
      inverted: false
      mode:
        input: true

sensor:
  - platform: uptime
    name: "${friendly_name} Uptime"

  - platform: template
    name: "Water Valve"
    lambda: |-
       if (id(valve_closed).state) && (id(valve_open).!state) {
         return closed;
       } else if (id(valve_closed).!state) && (id(valve_open).state) {
         return open;
       }
       else {
        return null;
       }
    update_interval: 30s

OK, I figured out most of what I was doing wrong. I needed to combine my if && statements by adding parenthesis. I also needed to remove the !state and use == true. The next problem I am running into is the compliler complaining about my return states not be declared in this scope.

First my code then the error.

  - platform: gpio
    name: "Valve Open"
    id: valve_open
    device_class: opening
    internal: false
    pin:
      number: GPIO26
      inverted: true
      mode:
        input: true
  - platform: gpio
    name: "Valve Closed"
    id: valve_closed
    device_class: opening
    internal: false
    pin:
      number: GPIO36
      inverted: false
      mode:
        input: true



sensor:
  - platform: uptime
    name: "${friendly_name} Uptime"

  - platform: template
    name: "Water Valve"
    lambda: |-
       if ((id(valve_closed).state == true) && (id(valve_open).state == false)) {
         return closed;
       } else if ((id(valve_closed).state == false) && (id(valve_open).state == true)) {
         return open;
       }
       else {
        return null;
       }
    update_interval: 30s

Here is the error I am receiving.

config/esphome/basement-leak-detector.yaml: In lambda function:
/config/esphome/basement-leak-detector.yaml:127:16: error: 'closed' was not declared in this scope
          return closed;
                ^~~~~~
/config/esphome/basement-leak-detector.yaml:127:16: note: suggested alternative: 'close'
          return closed;
                ^~~~~~
                close
/config/esphome/basement-leak-detector.yaml:129:16: error: could not convert 'open' from 'int(const char*, int, ...)' to 'esphome::optional<float>'
          return open;
                ^~~~
/config/esphome/basement-leak-detector.yaml:132:15: error: 'null' was not declared in this scope
         return null;
               ^~~~
/config/esphome/basement-leak-detector.yaml:132:15: note: suggested alternative: 'poll'
         return null;
               ^~~~
               poll
*** [/data/basement-leak-detector/.pioenvs/basement-leak-detector/src/main.cpp.o] Error 1
========================== [FAILED] Took 4.16 seconds ==========================

Any help would be appreciated.

I would expect to see something before the first line… i.e. binary sensor etc.

Suggest you check that it will compile with just the valve_open and valve_close and check logs to ensure a value is showing up. Then build up the lambda slowly until you find the point it fails.

Somebody smarter than me might see the error… but not me…

OK, a little bit closer now… FYI the binary_sensor works by itself perfectly.

Here is my code

  - platform: gpio
    name: "Valve Open"
    id: valve_open
    device_class: opening
    internal: false
    pin:
      number: GPIO26
      inverted: true
      mode:
        input: true
  - platform: gpio
    name: "Valve Closed"
    id: valve_closed
    device_class: opening
    internal: false
    pin:
      number: GPIO36
      inverted: false
      mode:
        input: true



sensor:
  - platform: uptime
    name: "${friendly_name} Uptime"

  - platform: template
    name: "Water Valve"
    id: water_valve
    lambda: |-
       if ((id(valve_closed).state == true) && (id(valve_open).state == false)) {
         return id(water_valve).state = "closed";
       } else if ((id(valve_closed).state == false) && (id(valve_open).state == true)) {
         return id(water_valve).state = "open";
       }
       else {
        return id(water_valve).state = "moving_or_stuck";
       }
    update_interval: 30s

Here is my latest error…

Compiling /data/basement-leak-detector/.pioenvs/basement-leak-detector/src/main.cpp.o
/config/esphome/basement-leak-detector.yaml: In lambda function:
/config/esphome/basement-leak-detector.yaml:128:37: error: cannot convert 'const char [7]' to 'float' in assignment
          return id(water_valve).state = "closed";
                                     ^~~~~~~~
/config/esphome/basement-leak-detector.yaml:130:37: error: cannot convert 'const char [5]' to 'float' in assignment
          return id(water_valve).state = "open";
                                     ^~~~~~
/config/esphome/basement-leak-detector.yaml:133:36: error: cannot convert 'const char [16]' to 'float' in assignment
         return id(water_valve).state = "moving_or_stuck";
                                    ^~~~~~~~~~~~~~~~~
*** [/data/basement-leak-detector/.pioenvs/basement-leak-detector/src/main.cpp.o] Error 1
========================== [FAILED] Took 4.21 seconds ==========================

How can I get the sensor to return text. Do I have to make a declaration? Almost there.
Thanks

I figured it out. Needed to change to a text_sensor. Yay me :slight_smile: Hopefully this helps the next newbie that is dealing with limit switches.

1 Like

Hi Mr. Dave, could i possibly get your code’s final version?

I am truly sorry I missed your post. Let me know if you still need the code.

Dang! What a jerk waiting 6 months to answer!

Im JK!! Hey, it happens to all of at one point or another.

I didnt see anywhere were you mentioned the valve your using or posting a link to it… I assume it is a ball valve with 4 or 5 wires and outputs digital signals to show the valve state? Something like this?

Care to share any good or bad feedback on whichever valve you’re using?

OK truly my bad I did not have notifications even enabled No wonder why I wasn’t getting notifications.

Here is my code incase it will help someone.

esphome:
name: sonoff-4chpro-1
friendly_name: Sonoff_4CHPRO_1
##################### Note the 433MHz will not work at this time. Bummer but really no loss. DCT 3-13-2023
esp8266:
board: esp01_1m

Enable logging

logger:

Enable Home Assistant API

api:
encryption:
key: “**********************”

ota:

  • platform: esphome
    password: “**********************”

wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password

Enable fallback hotspot (captive portal) in case wifi connection fails

ap:
ssid: “Sonoff-4Chpro-1 Fallback Hotspot”
password: “*****************”

captive_portal:

Device Specific Config

binary_sensor:

  • platform: gpio
    pin:
    number: GPIO0
    allow_other_uses: true
    mode: INPUT_PULLUP
    inverted: True
    name: button_1
    on_press:

    • switch.toggle: “relay_1”
  • platform: gpio
    pin:
    number: GPIO9
    allow_other_uses: true
    mode: INPUT_PULLUP
    inverted: True
    name: button_2
    on_press:

    • switch.toggle: “relay_2”
  • platform: gpio
    pin:
    number: GPIO10
    allow_other_uses: true
    mode: INPUT_PULLUP
    inverted: True
    name: button_3
    on_press:

    • switch.toggle: “relay_3”
  • platform: gpio
    pin:
    number: GPIO14
    allow_other_uses: true
    mode: INPUT_PULLUP
    inverted: True
    name: button_4
    on_press:

    • switch.toggle: “relay_4”
  • platform: gpio
    pin:
    number: GPIO0
    allow_other_uses: true
    mode: INPUT_PULLUP
    inverted: True
    name: “Sonoff 4CH Pro Button 1”

  • platform: gpio
    pin:
    number: GPIO9
    allow_other_uses: true
    mode: INPUT_PULLUP
    inverted: True
    name: “Sonoff 4CH Pro Button 2”

  • platform: gpio
    pin:
    number: GPIO10
    allow_other_uses: true
    mode: INPUT_PULLUP
    inverted: True
    name: “Sonoff 4CH Pro Button 3”

  • platform: gpio
    pin:
    number: GPIO14
    allow_other_uses: true
    mode: INPUT_PULLUP
    inverted: True
    name: “Sonoff 4CH Pro Button 4”

  • platform: status
    name: “Sonoff 4CH Pro Status”

switch:

  • platform: gpio
    name: “Relay 1”
    pin: GPIO12
    id: “relay_1”
  • platform: gpio
    name: “Relay 2”
    pin: GPIO5
    id: “relay_2”
  • platform: gpio
    name: “Relay 3”
    pin: GPIO4
    id: “relay_3”
  • platform: gpio
    name: “Relay 4”
    pin: GPIO15
    id: “relay_4”

I set the status_led inverted: False so that the light would be on when there is no errors and blink off when there are

status_led:
pin:
number: GPIO13
inverted: False

Once again, very sorry I wasn’t paying attention.

It’s all good man and it better not ever happen again or else im going to send your manager a strongly worded letter that outlines my dissapointment and i may possibly just rage quit too!! ; ) lol

So, it sounds like everything is up and working correctly now?? It also sounds like you might have picked up that incurable illness of Smart Home Addiction too… Just be brave and keep fighting buddy!

1 Like