Lambda Calls .state: Retrieve the current state of the binary sensor

I am trying to determine the state of a “my_binary_sensor” within a ESPhome script.
My goal is to set the colour of WS2812 LED within a script instead of determining it before calling the script.
As you can see in the program, in the creation o f"my_binary_sensor" I set parameter couleur [1,0,0] or [0,1,0] before executing the script. Using on_press/on_release (I don’t understand why using theses, this is not a button, but it works for me) I execute the script with proper parameter.

Every minute (using time:) I wish to flash the LED with the colour according to the state of “my_binary_sensor”.

By, determining the state of my_binary_sensor, within the script, and setting the colors accordingly, this will ensure that every time I execute the script, I will always get the same result.
Here is my code:

# Spare Unit

substitutions:
  devicename: d1mini-06
  friendly_name: Spare D1mini-06
  comment: Spare
  esp_id: D1Mini_06
  board_type: nodemcuv2


esphome: 
  friendly_name: ${friendly_name}
  comment: ${comment}

esp8266:
  board: ${board_type}

packages:
  base:  !include
    file: package/basic.yaml           
    vars: 
      Uptime_update_inverval: 10min
         
light:
- platform: neopixelbus        # Configure WS2812 LED
  name: "Status LED"          # (Un)/comment to make visable in Home Assistant and local WEB
  id: activity_led
  variant: WS2812
  pin: D6
  num_leds: 2
  flash_transition_length: 1500ms
  type: GRB
  restore_mode: ALWAYS_OFF

binary_sensor:
  - platform: homeassistant    
    id: my_binary_sensor
    entity_id: input_boolean.msg_flag_contact_ss_porte_av
    on_press:
       - lambda: |-
          std::vector<float> couleur{0, 1, 0};
          id(my_script)->execute(couleur);
    on_release:
       - lambda: |-
          std::vector<float> couleur{1, 0, 0};
          id(my_script)->execute(couleur);

time:
  - platform: sntp
    id: timer
    on_time:
      # Every minute      
      - seconds: 0
        minutes: /1
        then:
          - logger.log: "Entering the on_time block"
          - repeat:
              count: 2           
              then:
                #- logger.log: "Entering the repeat block"
                - lambda: |-
                    std::vector<float> couleur{.1, 0,0};
                    id(my_script)->execute(couleur);                                   
                - delay: 1s               


script:
  - id: my_script
    parameters:
      couleur: float[]
    then: 
      - if:
          condition:
            lambda: return (id(my_binary_sensor).state));
          then:         
            - logger.log: "ON"
          else:
            - logger.log: "OFF"
  
      - light.turn_on:
          id:           activity_led
          brightness:   100%
          red:          !lambda return couleur[0] ;
          green:        !lambda return couleur[1] ;      
          blue:         !lambda return couleur[2] ;  
          flash_length: 2s

While “install” the program, I get the following error

/config/esphome/d1mini-06.yaml: In lambda function:
/config/esphome/d1mini-06.yaml:74:39: error: expected ';' before ')' token
   74 |             lambda: return (id(my_binary_sensor).state));
      |                                       ^
      |                                       ;
/config/esphome/d1mini-06.yaml:74:39: error: expected primary-expression before ')' token

I read the documentation many time but either did not understand / figure out how to fix it.
Any suggestion how to fix this problem would be appreciate.

Don’t you have too many closing brackets here? Delete a ) from the end.

Thank you very much, I spend hours on this issue, you find out the solution in a few minutes.
Here is my corrected and working script code

script:
  - id: my_script
    parameters:
      couleur: float[]
    then: 
      - if:
          condition:
            lambda: return (id(my_binary_sensor).state);
          then:         
            - logger.log: "my_binary_sensor is ON"           
          else:
            - logger.log: "my_binary_sensor is OFF"  
      - light.turn_on:
          id:           activity_led
          brightness:   100%
          red:          !lambda return couleur[0] ;
          green:        !lambda return couleur[1] ;      
          blue:         !lambda return couleur[2] ;  
          flash_length: 2s

Now I am left with discovering how to assign value 0 or 1 based on “my_binary_sensor”.state.
This would replace the lines

          red:          !lambda return couleur[0] ;
          green:        !lambda return couleur[1] ; 
``

I really means discovering, not being a programmer it is try and errors until I find a solution or until I ask for help (example the following is not from me, it was a solution provided by a community member.
           - lambda: |-
                std::vector<float> couleur{1, 0,0};
                id(my_script)->execute(couleur);
I gave a try with the example form the documentation without success. 
```.
    lambda: |-
      if (id(some_binary_sensor).state) {
        return 42.0;
      } else {
        return 0.0;
      }

I would appreciate, if you could give some advise swhere to start.

1 Like

From the outside, this looks like quite an overly complicated way to flash a light every minute either green or red conditional on the state of a binary sensor.

Are you planning on expanding this to a more complex usecase?

This is a subset of a larger project. To be included in my RFID card reader.
I need to display on the ESP32, running the RFID reader, the status of different devices that are activated by different RFID tags. Feedback to user at time of activation and periodically afterward

This will be displayed periodically (using on_time), I need to know the status at this time, not onky when the state change.

I prefer to use re-usable code (script) instead of repeating over and over.
Thank you for your help, I will close this file as resolved since you answered my first issue,

1 Like