Sensor Template Lambda 'if' issues

Can’t figure out what I’m doing wrong here.

Attempting to calculate the AQI from an SDS011. I have that working and returning good data for PM2.5 and PM10.0. Trying to add a Template Sensor to calculate the AQI for each. I’m sure I don’t have the ‘lambda’ configured correctly. Just can’t figure out where. The config compiles fine without this Template. Am I close here or should I trash it and start over?

- platform: template
  name: "SDS011 PM2.5µm 24 Hour AQI"
  id: SDS011_PM25_AQI
  unit_of_measurement: 'AQI'
  update_interval: 60min
  state_class: measurement
  icon: mdi:chemical-weapon
  lambda: |-
    if (id(PM2524Hour).state) > 300.0 and (id(PM2524Hour).state) < 500.0
    {
      return (((500.0 - 301.0)/(500.4 - 250.5)) * ((id(PM2524Hour).state) - 250.5) + 301.0);}
    if (id(PM2524Hour).state) > 200.0 and (id(PM2524Hour).state) <= 300.0
    {
      return (((300.0 - 201.0)/(250.4 - 150.5)) * ((id(PM2524Hour).state) - 150.5) + 201.0);}
    if (id(PM2524Hour).state) > 150.0 and (id(PM2524Hour).state) <= 200.0
    {
      return (((200.0 - 151.0)/(150.4 - 55.5)) * ((id(PM2524Hour).state) - 55.5) + 151.0);}
    if (id(PM2524Hour).state) > 100.0 and (id(PM2524Hour).state) <= 150.0
    {
      return (((150.0 - 101.0)/(55.4 - 35.5)) * ((id(PM2524Hour).state) - 35.5) + 101.0);}
    if (id(PM2524Hour).state) > 50.0 and (id(PM2524Hour).state) <= 100.0
    {
      return (((100.0 - 51.0)/(35.4 - 12.1)) * ((id(PM2524Hour).state) - 12.1) + 51.0);}
    else
    {
      return (((50.0 - 0.0)/(12.0 - 0.0)) * ((id(PM2524Hour).state) - 0.0) + 0.0);}

Compile errors are as follows. Searching shows it’s a common error but nothing I’ve found has fixed it.

/config/esphome/testnodemcu.yaml: In lambda function:
/config/esphome/testnodemcu.yaml:161:30: error: expected primary-expression before '>' token
     if (id(PM2524Hour).state) > 300.0 and (id(PM2524Hour).state) < 500.0
                              ^
/config/esphome/testnodemcu.yaml:162:7: error: expected ';' before '{' token
     {
       ^
/config/esphome/testnodemcu.yaml:164:30: error: expected primary-expression before '>' token
     if (id(PM2524Hour).state) > 200.0 and (id(PM2524Hour).state) <= 300.0
                              ^
/config/esphome/testnodemcu.yaml:165:7: error: expected ';' before '{' token
     {
       ^
/config/esphome/testnodemcu.yaml:167:30: error: expected primary-expression before '>' token
     if (id(PM2524Hour).state) > 150.0 and (id(PM2524Hour).state) <= 200.0
                              ^
/config/esphome/testnodemcu.yaml:168:7: error: expected ';' before '{' token
     {
       ^
/config/esphome/testnodemcu.yaml:170:30: error: expected primary-expression before '>' token
     if (id(PM2524Hour).state) > 100.0 and (id(PM2524Hour).state) <= 150.0
                              ^
/config/esphome/testnodemcu.yaml:171:7: error: expected ';' before '{' token
     {
       ^
/config/esphome/testnodemcu.yaml:173:30: error: expected primary-expression before '>' token
     if (id(PM2524Hour).state) > 50.0 and (id(PM2524Hour).state) <= 100.0
                              ^
/config/esphome/testnodemcu.yaml:174:7: error: expected ';' before '{' token
     {
       ^
/config/esphome/testnodemcu.yaml:179:3: warning: control reaches end of non-void function [-Wreturn-type]
 
   ^
*** [/data/testnodemcu/.pioenvs/testnodemcu/src/main.cpp.o] Error 1
1 Like

Try this:

lambda: |-
    if (id(PM2524Hour).state) > 300.0 and (id(PM2524Hour).state) < 500.0 {
      return (((500.0 - 301.0)/(500.4 - 250.5)) * ((id(PM2524Hour).state) - 250.5) + 301.0);
      }

    else if (id(PM2524Hour).state) > 200.0 and (id(PM2524Hour).state) <= 300.0 {
      return (((300.0 - 201.0)/(250.4 - 150.5)) * ((id(PM2524Hour).state) - 150.5) + 201.0);
      }

    else if (id(PM2524Hour).state) > 150.0 and (id(PM2524Hour).state) <= 200.0 {
      return (((200.0 - 151.0)/(150.4 - 55.5)) * ((id(PM2524Hour).state) - 55.5) + 151.0);
      }

    else if (id(PM2524Hour).state) > 100.0 and (id(PM2524Hour).state) <= 150.0 {
      return (((150.0 - 101.0)/(55.4 - 35.5)) * ((id(PM2524Hour).state) - 35.5) + 101.0);
      }

    else if (id(PM2524Hour).state) > 50.0 and (id(PM2524Hour).state) <= 100.0 {
      return (((100.0 - 51.0)/(35.4 - 12.1)) * ((id(PM2524Hour).state) - 12.1) + 51.0);
      }

    else {
      return (((50.0 - 0.0)/(12.0 - 0.0)) * ((id(PM2524Hour).state) - 0.0) + 0.0);
    }

The position of the braces isn’t that important, I’ve used the convention shown in the ESPHome docs, but using else if probably is.

Thanks for the tip. Unfortunately I get the exact same compile error. I’m sure the 'else’s need to be there (C++ :roll_eyes: ). I’m sure I had them in there at some iteration of attempts.

An if in c++ must be like this.

if (  <logic statement  ) {

}

So your statement should be

 if ( (id(PM2524Hour).state) > 300.0 and (id(PM2524Hour).state) < 500.0)
    {
...

Note the extra parenthesis just after the if and before the curly bracket.
I have not testet to compile. So I hope that solves it.

/Mattias

1 Like

That was it. Missing one set of parenthesis in each ‘if’ statement. Thanks

Glad I could help.

/Mattias