On_Boot interfering with Sensor:On_Value_Range?

I’m working on a simple air quality sensor with a “dummy light” for easy reading. When the device boots up, I want the light to turn blue until it finishes its first reading, then it should correspond to the command in the value_range under the sensor.

Unfortunately, it appears that sometimes when the device re-reads, it’s running the on_boot routine again, and switching the light back to blue. Then when the on_value routine runs, but it hasn’t actually moved out of range, the light is just staying blue until the reading moves it into another range. What’s the best way to remedy? Should I just do a nested If-Then on the reading to run commands based on result?

On_boot:

esphome:
  name: kk-air-quality-sensor-3
  friendly_name: KK Air Quality Sensor 3
  on_boot:
    priority: 600
    then:
      #turn on blue light
      - light.turn_on:
          id: status_light
          brightness: 50%
          red: 0.0
          green: 0.0
          blue: 1.0

sensor > on.value

sensor:
  - platform: sds011
    update_interval: 2min
    pm_2_5:
      name: "PM 2.5µm"
      id: "pm25"
      filters:
        offset: 1 #this was to test issues coming from a 0 value
      on_value_range:
        - above: 0.0
          below: 11.9
          then:
            #green
            - light.turn_on:
                id: status_light
                brightness: 50%
                red: 0.0
                green: 1.0
                blue: 0.0
        - above: 12
          below: 34.9
          then:
            #yellow
            - light.turn_on:
                id: status_light
                brightness: 50%
                red: 1.0
                green: 1.0
                blue: 0.0
        - above: 35
          below: 54.9
          then:
            #orange
            - light.turn_on:
                id: status_light
                brightness: 50%
                red: 1.0
                green: 0.65
                blue: 0.0
    #etc, etc, etc

The time between booting and obtaining a sensor value is ridiculously short and if you were doing the automation correctly to begin with, that blue light would would turn On then Off in probably 1 second or less. Also, as it explains in the documentation…
"
“On startup, the last state before reboot is restored and if the value crossed the boundary during the boot process, the trigger is also executed.”

So, the whole on_boot is kind of of pointless…

The on_boot action isnt happening after or outside of the initial on_boot actions when it boots up.

That’s exactly what’s supposed to happen and that’s basically word for word how on_value_range is explained in the documentation.

“This trigger will only trigger when the new value is inside the range and the previous value was outside the range. On startup, the last state before reboot is restored and if the value crossed the boundary during the boot process, the trigger is also executed.”

So, what exactly are you trying to do? Turn on an led each time it updates and then turn it off afterwards?

So then look at what automation options you have.
You know that it updates every 2min because thats the interval you set it to. Thats kind of a clue…

Welcome @mgit22.

It could be that there is a 30sec warm-up period before the first sensor reading which is coming into play too.

“If update_interval is between 1-30 minutes, the SDS011 periodically turns on for 30s before each measurement.”

I know some of these devices need to warm up a bit before they can reliabily read.

To be clear, I’m very new to this. I’m about 2 days in–and actually quite happy I already have the base function working and properly calculating AQI from the PM2.5 reading. I’m just trying to get the nuanced function worked out here.

The current on_boot to blue light is really a placeholder for later functions (received power, wi-fi connected, etc) as a boot order until everything is fully up and it starts getting readings.

The time between booting and obtaining a sensor value is ridiculously short and if you were doing the automation correctly to begin with, that blue light would would turn On then Off in probably 1 second or less. Also, as it explains in the documentation…

This doesn’t seem true in the case of the SDS011. I’d say it’s typically about 30+ seconds or so before it’s getting a value. My understanding is that’s a default of the sensor, but I could be wrong.

That’s exactly what’s supposed to happen and that’s basically word for word how on_value_range is explained in the documentation.

I understand that, and that’s why I phrased it that way. The problem here is the only time I’m ever calling the blue light is in the On_Boot, but somehow it’s going back to blue periodically even after obtaining a sensor value.

I’d think that can only happen 1 of 2 ways:

  1. Somehow it’s calling on_boot again.
  2. the state called in on_boot isn’t actually overwritten by the on_value_range, but is being “layered” in?

Are either of those 2 possible?

So, what exactly are you trying to do? Turn on an led each time it updates and then turn it off afterwards?

The LED isn’t ever supposed to go off.

On_Boot: Blue just to show functional operation. I originally had this higher Prio, but lowered to see if that was causing issue.
On_value_range: every time it crosses a value threshold, it changes to the range color and stays there until the range changes. (this corresponds to the standard PM2.5/AQI color ranges).

Thanks! I’m loving the opportunities that ESPHome opens up. I’m about 2 weeks in on HA and maybe 2 days on ESPHome.

It could be that there is a 30sec warm-up period before the first sensor reading which is coming into play too.

Yep, that seems to be the case with the warm-up period and I’m good with that. That’s actually why I wanted the blue light on_boot (and possibly other function later) to visually troubleshoot if something goes wrong.

What’s weird here is that after I am getting values back and execute the related on_value_range code to get a new LED color, it occasionally reverts back to blue. The only time blue is called is in the On_Boot, so that leaves me a bit confused…

1 Like

You could add an uptime sensor just to double check you’re not actually getting unplanned reboots (from say brownouts).

I’ve never seen people have issues with false triggers of on_boot. It should be solid.

Have you integrated the device with HA yet? You could be getting API reboots every 15min if not.

Yep, it’s integrated. The “Portable” appears to be working fine, but the “Intake” is still dropping to blue. I’d think it could have something to do with the intake value being so low, but it initially turns green fine and I have the range starting at -1.

Perhaps I do need to look at adding an uptime sensor (changes are pain since I added the neopixels and I can’t OTA due to size now). Are sensor values typically stored in memory, though? I would think if it’s browning out, it would come back to a null value and still run the routine again after obtaining?

1 Like

The sensor doesnt need a “warm up” time. That 1-30min/30second turn on time is its pre-configured discontinuous mode and that 30s is how long it turns on each minute. The sensor itself is capable of taking a reading every 1 second.

What type of light are you using here? How is it configured in esphome?

Single neopixel.

#neopixel config
light:
  - platform: neopixelbus
    type: GRB
    variant: WS2811
    pin: GPIO15
    num_leds: 1
    name: "StatusLED"
    id: status_light

I’m able to address & control it directly through dashboard. It generally changes properly when crossing the on_value_range threshholds, but the reverting back to blue is the issue here.

My overall use-case is this:

I live in Chiang Mai, Thailand and the air gets pretty terrible around here this time of year. We’re with a childrens’ home foundation, and I’m trying to come up with cost-effective solutions for our kids (and at-risk neighbors) to have air filtration and the means of measuring. I’ve already got a pretty good filtration system designed, just trying to get the indicator piece.

I do have a small display too, but trying to use the dummy-light as a 100% clear & notable indication of when they should have the filtration running. Note that when these go out, they won’t have wi-fi so I won’t have means of monitoring remotely.

I’m not sure about this particular model but for sure some similar ones need some time for the fan to warm up.

time for the “fan to warm up”? Like I said earlier, nothing needs to warm up and the fan especially doesn’t need to warm up if you can even make sense of that. The fan does 2 things, the fan passes air/particulates across the laser when it takes a measurement and when it’s in default mode, taking one measurement per second, the fan also helps to cool the device. Instead of pointing to some random dude in a forum who is wrong too, all you or anyone else should have done is just read the data sheet and then all this misinformation would stop being spread all over.

Everyone keeps quoting this 30 seconds as “warm up time” or this is a new one, “the data needs 30 seconds to stabilize” The only thing needing stabilized is that person’s medication.

All BS and nonsense because no one can do 5 minutes of reading. If anyone had done the reading they’d know the 30 seconds was just an example they use in the data sheet.

Not sure who hurt you, or why you’re so upset about this. Again, I’m new to all this…

But this is from the manufacturer’s own guide regarding their laser sensor protocol.


source: NovaFitness Laser Dust Sensor Control Protocol V1.3

My understanding is it’s fine to work without a [trigger warning] “warmup period” if you are continuously reading. Once you stop polling, the fan and laser stop and will optimally need a [trigger warning] “warmup time” to provide stable data.

Though we’re off-topic from the original question of the optimal way of changing LED color based on current value (range) even if it didn’t move outside. I’m thinking maybe just a nested if-then lambda. I’ll start looking at that (while still confused about the blue LED)

1 Like

The other data sheet doesn’t say that. Why they’re different, i’m not sure.

try this.

sensor:
  - platform: sds011
    update_interval: 2min
    pm_2_5:
      name: "PM 2.5µm"
      id: "pm25"
      filters:
        offset: 1 #this was to test issues coming from a 0 value
      on_value_range:
        - above: 0.0
          below: 11.9
          then:
            #green
            - light.control:
                id: status_light
                brightness: 50%
                red: 0.0
                green: 1.0
                blue: 0.0
        - above: 12
          below: 34.9
          then:
            #yellow
            - light.control:
                id: status_light
                brightness: 50%
                red: 1.0
                green: 1.0
                blue: 0.0
        - above: 35
          below: 54.9
          then:
            #orange
            - light.control:
                id: status_light
                brightness: 50%
                red: 1.0
                green: 0.65
                blue: 0.0      

The difference in publications doesn’t surprise me. Could’ve been different engineers, or one is just standard (safest) practice, but not necessary in all cases.

try this.

I see, so maybe do “control” changes instead of just turning it on each time. So power it on during boot, then just push changes on range change. I’ll give it a shot, thanks.

it’s Blue because you’re setting it to Blue on_boot while at the same time it’s restoring the last sensor value/color that was saved before reboot. You’re basically telling it to go Left and Right at the same time.

remove that on_boot section… Whatever the last state/color it was on will be the color set on_boot.

light.control Action
This Action is a generic call to change the state of a light - it is essentially just a combination of the turn_on and turn_off calls.

it basically does a on/off or resets the light each time the color values are changed.

How is the on_boot command not getting overwritten by the On_Value_Range?

If the On_Boot is called, that means the system restarted, right?

And if so, it should have forgotten the sensor values, correct? Which means any value read in the sensor should trigger the on_value_range like it crossed for the first time?

I would ask if maybe it doesn’t call the execution if it boots within the range, but it will go to Green first, then fallback.

…while at the same time it’s restoring the last sensor value/color that was saved before reboot…

Is it actually restoring the sensor value? If so, isn’t there a way to just to disable that and then the problem would be solved as it would trigger the on_value_range call every time

I’m not sure why exactly but these little bugs/quirks with the light component have been around for a while.

I think it has something to do with this.

" All percentage options accept values in the range 0% to 100% or 0.0 to 1.0 , and default to not changing the current value (which might be the value from before the light was last turned off). To reset values, explicitly set them to zero."

That makes sense in my head if I’m strictly running procedures based on the light’s state. But I can’t wrap my head around why it wouldn’t go back to green when it’s running based on the on_value_range under a sensor.

This is the logic in my head.

  1. Boot-up. On_boot tells the light to turn blue (all sensors states are null until called)
  2. Sensor value is returned (let’s assume pm25 = 2, so should be in green range).
  3. On_value_range is triggered for the first time, light is changed to green.
  4. Sensor returns again and pm25 = 5. No change since still in range.
  5. REBOOT
  6. Due to quirk, light value is retained as “green” but sensors are cleared and we return to step 1. (on_boot makes light turns blue, then should call on_value_range again when populated for first time).

The only thing that makes sense is that the sensor state is somehow being retained? So when it goes back it’s not seeing as a change. but everything I’ve read said it should clear. If that’s not the case, is there a way to tell it just not to save the state of the sensor?

They’re not Null values. Your on_boot action is happening at the same time the sensors are initialized, not before.

Interesting… So if that’s the case, moving the priority up (not down) should help as it would call before it initializes the sensors. I’ve tried between 0-500, but maybe I need to go 700 (appears as though sensors come online at 600)

I’ll give that a shot next. Otherwise, I think it might be fixable with In_Range conditions versus the on_value_range call. I really want to keep the on_boot as a just-in-case-i-want-visual-troubleshooting-lights-later-on deal.