Lambda template prolbem (multiple

Hi. I have two sensors (one ultrasonic and one luxmeter) connected to my esp32. I’m trying to get ESP to evaluate the state of both and then loop a scipt that will turn on and off a switch until the luxmeter registers a value above 200.

sensor:
  - platform: bh1750
    name: "BH1750 Illuminance"
    id: "luxmeter"
    update_interval: 1s
    on_value:
      then:
      - if:
          condition:
            lambda: 'return id(luxmeter).state < 200 && return id(ultra).state < 0.5;'
          then:
            - script.execute: script_led
            - delay: 0.5s
          else:
      - script.stop: script_led

  - platform: ultrasonic
    trigger_pin: GPIO05
    echo_pin: GPIO18
    name: "Ultrasonic Sensor"
    id: "ultra"
    update_interval: 0.25s

switch:
  - platform: gpio
    id: "green_led_switch_esp32"
    name: "green_led_esp32" 
    pin: GPIO26

script:
  - id: script_led
    mode: queued
    then: 
      - switch.turn_on: "green_led_switch_esp32"
      - delay: 0.5s
      - switch.turn_off: "green_led_switch_esp32"

I’m getting the following error:

/config/esphome/esp32-1.yaml:149:28: error: expected primary-expression before '<' token
       if (id(luxmeter).state) < 500 and (id(ultra).state) < 0.5 {
                            ^
/config/esphome/esp32-1.yaml:155:11: error: expected primary-expression before 'switch'
         - switch.turn_on: "green_led_switch_esp32"
           ^
/config/esphome/esp32-1.yaml:154:7: warning: label 'turn_on_action' defined but not used [-Wunused-label]
       turn_on_action:
       ^
/config/esphome/esp32-1.yaml: In lambda function:
/config/esphome/esp32-1.yaml:50:38: error: expected primary-expression before 'return'
             lambda: 'return id(luxmeter).state < 30 && return id(ultra).state < 0.5;'
                                      ^
/config/esphome/esp32-1.yaml:50:38: error: expected ';' before 'return'
/config/esphome/esp32-1.yaml: In lambda function:
/config/esphome/esp32-1.yaml:156:3: warning: control reaches end of non-void function [-Wreturn-type]
*** [/data/esp32-1/.pioenvs/esp32-1/src/main.cpp.o] Error 1
========================= [FAILED] Took 19.53 seconds =========================

I’m completely new to writing lambdas so I can’t really tell what the issue is. Any ideas?

You have to put a ‘-’ before the lambda statement. And you can only have one “return”

     - if:
          condition:
          - lambda: 'return id(luxmeter).state < 200 && id(ultra).state < 0.5;'
          then:
2 Likes

That fixed it, thanks. I initially copied the code from the ESPhome docs but it doesn’t mention anything about a dash before lambda:

From the docs

on_...:
  then:
    - if:
        condition:
          lambda: 'return id(some_sensor).state < 30;'
        then:
          - logger.log: "The sensor value is below 30!"
          - light.turn_on: my_light
          - delay: 5s
        else:
          - logger.log: "The sensor value is above 30!"
    - light.turn_off: my_light

Any idea why it is so?

Well, I just checked my yaml’s and I have both with and without the dash :grinning:, and they are both working. So the real problem was the wrong construction in the lambda self.

All right. I have a couple of follow up questions regarding the lambda:

  1. What would I write if I wanted the lambda to return the actual sensor value instead of the boolean value(which I assume is the case above)?
  2. How would I write intervals. Say for example: 50 < id(x).state < 200 ? I tried writing the following:
    on_value:
      then:
      - if:
          condition:
          - lambda: 'return 50 < id(luxmeter).state < 200 && id(ultra).state < 0.5;'
          then:
            - script.execute: script_light
            - delay: 0.5s
          else:
      - script.stop: script_light

ESPhome message:

/config/esphome/esp32-1.yaml: In lambda function:
/config/esphome/esp32-1.yaml:50:35: warning: comparison of constant '200' with boolean expression is always true [-Wbool-compare]
           - lambda: 'return 50 < id(luxmeter).state < 200 && id(ultra).state < 0.5;'
                                   ^
/config/esphome/esp32-1.yaml:50:17: warning: comparisons like 'X<=Y<=Z' do not have their mathematical meaning [-Wparentheses]
           - lambda: 'return 50 < id(luxmeter).state < 200 && id(ultra).state < 0.5;

Well lambda’s are just C/C++ statements, so maybe it is better to spend some time on the basics of the if- statement and combining conditions within the if-statement. There is a lot of information on the internet :slight_smile: A small spoiler: if you want to test an interval you have to test both boundaries separately and combine them with a AND in the same if-statement.

1 Like