ESP32 turns off when light sensor = 0 lux

Hey all, wondering if you might be able to help explain this bizarre behavior.

My custom light sensor (Adafruit Qt Py ESP32-S2 + VEML7700 Ambient Light Sensor) works great when the sun is out, but as soon as the sun goes down, and the sensor value drops to 0 lux, the ESP32 disconnects from WiFi and becomes unavailable in Home Assistant. It doesn’t come back online until the sun comes out the next day. I’ve swapped out identical components and the issue persists… Maybe it has something to do with the power save modes on the VEML? I can’t see logs on this particular board, so its kinda hard to tell.

Worth noting: I programmed the Qt Py’s onboard LED to turn green when it is connected to WiFi, and red when it is disconnected. This works, again, until the lux sensor value drops to 0. Then the LED just turns off – every once in a while it will flash purple (like it does on every reboot) so I think it may be rebooting constantly. But when the sun comes out or the room gets lit, tada it all pops back on – LED turns red for a few seconds, then green once it’s re-connected to WiFi.

Am I missing something in my code, or is this common for a sensor reporting zero?

.yaml file:

esphome:
  name: qtpy-lux-sensor-67a8
  includes:
    - veml7700_custom_sensor.h
  libraries:
    - Wire
    - SPI
    - AdaFruit/Adafruit BusIO
    - AdaFruit VEML7700=https://github.com/adafruit/Adafruit_VEML7700

esp32:
  board: adafruit_qtpy_esp32s2
  variant: ESP32S2
  framework:
    type: arduino
    version: 2.0.3
    platform_version: 5.0.0

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: ""

ota:
  password: !secret ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  fast_connect: true
  power_save_mode: none

web_server:
  id: component_web_server
  port: 80

switch:
  - platform: gpio
    pin: GPIO38
    name: "NeoPixel Power"
    restore_mode: ALWAYS_ON
    internal: true

light:
  - platform: neopixelbus
    type: GRB
    variant: WS2811
    num_leds: 1
    name: "NeoPixel LED"
    pin: GPIO39
    id: neopixel
    
i2c:
  sda: GPIO41
  scl: GPIO40
  scan: true

sensor:  
  - platform: wifi_signal
    name: "WiFi Signal Strength"
    update_interval: 60s
    
  - platform: custom
    lambda: |-
      auto veml7700 = new VEML7700CustomSensor();
      App.register_component(veml7700);
      return {veml7700, veml7700->lux_sensor, veml7700->white_sensor, veml7700->als_sensor};

    sensors:
    - name: "Light" #required/hidden
      internal: true
    - name: "Illuminance"
      device_class: illuminance
      unit_of_measurement: Lux
      accuracy_decimals: 0
    - name: "White" #hidden
      device_class: illuminance
      unit_of_measurement: Lux
      accuracy_decimals: 0
      internal: true
    - name: "ALS" #hidden
      device_class: illuminance
      unit_of_measurement: Lux
      accuracy_decimals: 0
      internal: true

interval:
  - interval: 5s
    then:
      if:
        condition:
          wifi.connected:
        then:
          - script.execute: green
        else:
          - script.execute: red

script:
  - id: green
    then:
      - light.turn_on: 
          id: neopixel
          transition_length: 0.5s
          red: 0
          green: 1
          blue: 0

  - id: red
    then:
      - light.turn_on: 
          id: neopixel
          transition_length: 0.5s
          red: 1
          green: 0
          blue: 0

custom sensor file:

#include "esphome.h"
#include "Adafruit_VEML7700.h"

// Requires this lib installed: $ platformio lib --global install "Adafruit BusIO"
// based on https://github.com/adafruit/Adafruit_VEML7700/blob/5c4a5a50236c202dd7edafdb2b4913f754845261/examples/veml7700_test/veml7700_test.ino

class VEML7700CustomSensor : public PollingComponent, public Sensor {
    public:
    Adafruit_VEML7700 veml = Adafruit_VEML7700();
    
    Sensor *lux_sensor = new Sensor();
    Sensor *white_sensor = new Sensor();
    Sensor *als_sensor = new Sensor();
    
    VEML7700CustomSensor() : PollingComponent(15000) {}
    
    void setup() override {
        Wire.begin();
        veml.begin();
        veml.setGain(VEML7700_GAIN_1);
        veml.setIntegrationTime(VEML7700_IT_800MS);
        veml.powerSaveEnable(false);
        // veml.setPowerSaveMode(VEML7700_POWERSAVE_MODE4);
        //veml.setLowThreshold(10000);
        //veml.setHighThreshold(20000);
        //veml.interruptEnable(true);
    }
    
    void update() override {
        float lux = veml.readLux(VEML_LUX_AUTO);
        float white = veml.readWhite();
        float als = veml.readALS();
        //ESP_LOGD("VEML7700", "The value of sensor lux is: %.0f", lux);
        //ESP_LOGD("VEML7700", "The value of sensor white is: %.0f", white);
        //ESP_LOGD("VEML7700", "The value of sensor ALS is: %.0f", als);
        lux_sensor->publish_state(lux);
        white_sensor->publish_state(white);
        als_sensor->publish_state(als);
    }
};

This is not an answer, just a semi-validation, as your config and include-code looks a lot like my own.
In my case I tied a VEML7700 to a ESP8266, and it’s been grand for a couple years now.
So, FWIW, I don’t see any glaring errors or problems with your code/config.
Sorry that doesn’t help solve the problem, but I hope it helps by saying this does look like it should work fine, and that you’ve done well.
My prediction is that it will take a lot of eyes, and someone will see the subtle hook in there which is causing the trouble. And you’re in the right place - as there are good eyes here.

Can you capture some of the serial port’s logs, perhaps? If it’s in a reboot loop, the log output would provide a hint as to what’s causing it.

I’m thinking it has something to do with the VEML returning a zero value for lux. Whenever that happens (ie, at night) the ESP shuts down. But if I shine a flashlight at the sensor, it will power right back up.