Sensor component not triggering "on_value" for adc sensor

Hi!

I’m trying to set up an esphome to sleep after taking a sensor read, but “on_value” never troggers, despite the sensor updating:

[D][api.connection:1321]: Home Assistant 2024.5.3 (192.168.100.81): Connected successfully
[D][sensor:093]: 'Moisture': Sending state 39.67285 % with 0 decimals of accuracy
[D][sensor:093]: 'Moisture': Sending state 0.00000 % with 0 decimals of accuracy

Am I missing something, or does the adc sensor platform not support updates? Thank you so much!

Here is the relevant part of my code, the rest is esphome boilerplate:

deep_sleep:
  id: deep_sleep_1
  sleep_duration: 2min

sensor:
  - platform: adc
    pin: A0
    id: moistaf
    name: "Moisture"
    update_interval: 10s
    unit_of_measurement: "%"
    filters:
    - median:
        window_size: 7
        send_every: 4
        send_first_at: 1
    - calibrate_linear:
        - 1.0 -> 0.00
        - 0.52 -> 100.00
    - lambda: if (x < 1) return 0; else return (x);
    accuracy_decimals: 0
    force_update: True
    on_value:
      then:
        - logger.log:
            format: ">>>>> Received deep sleep duration"
        - deep_sleep.enter: deep_sleep_1

Back with some more info, apparently the device was not updating correctly due to the deep_sleep, so I decided to make a toggle to prevent sleeping while a toggle is set in HAAS. I ran into another two issues though, below is my code trying to debug them:

  1. Even though I’m calling deep_sleep.prevent twice, once on boot and once inside the test_ota script, the device is always going into deep sleep
  2. binary_sensor.is_off: otamode always returns true/validates condition, despite being correctly set up in HAAS (toggle helper with the correct entity_id of input_boolean.soil_ota_mode_toggle)

Any ideas on what I’m missing?

Thank you!

substitutions:
  name: esphome-web-d1e7f6
  friendly_name: Soil2

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  name_add_mac_suffix: false
  project:
    name: esphome.web
    version: '1.0'
  on_boot:
    priority: -100.0
    then:
      - delay: 10s
      - deep_sleep.prevent: deep_sleep_1
      - delay: 2s
      - script.execute: test_ota

esp8266:
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API
api:

# Allow Over-The-Air updates
ota:
  safe_mode: True

# Allow provisioning Wi-Fi via serial
improv_serial:

wifi:
  # Set up a wifi access point
  ap: {}

# In combination with the `ap` this allows the user
# to provision wifi credentials to the device via WiFi AP.
captive_portal:

dashboard_import:
  package_import_url: github://esphome/example-configs/esphome-web/esp8266.yaml@main
  import_full_config: true

# To have a "next url" for improv serial
web_server:

binary_sensor:
  - platform: status
    name: "Soil Status"
  - platform: homeassistant
    id: otamode
    entity_id: input_boolean.soil_ota_mode_toggle

button:
  - platform: restart
    name: ${device_name} Restart

script:
  - id: test_ota
    mode: queued
    then:
      - logger.log: "Checking OTA Mode"
      - if:
          condition:
            binary_sensor.is_off: otamode
          then:
            - logger.log: 'OTA Mode OFF, allowing deep sleep'
            - deep_sleep.prevent: deep_sleep_1
          else:
            - logger.log: 'OTA Mode ON'
            - deep_sleep.prevent: deep_sleep_1
      - delay: 2s
      - script.execute: test_ota

deep_sleep:
  id: deep_sleep_1
  run_duration: 60s
  sleep_duration: 120s

sensor:
  - platform: adc
    pin: A0
    id: moistaf
    name: "Moisture"
    update_interval: 1s
    unit_of_measurement: "%"
    filters:
    - median:
        window_size: 7
        send_every: 4
        send_first_at: 1
    - calibrate_linear:
        - 1.0 -> 0.00
        - 0.52 -> 100.00
    - lambda: if (x < 1) return 0; else return (x);
    accuracy_decimals: 0
    force_update: True
    on_value:
      then:
        - script.execute: test_ota
        - delay: 10s
        - logger.log:
            format: ">>>>> Received deep sleep duration V6"
        - deep_sleep.enter: deep_sleep_1

Quick update as I’ve hacked at this some more.

I’ve added a guard against going into deep sleep before connecting to wifi, I figured the device was not getting provisioned and hence could not read the switch in HAAS.

The problem right now is, the device no longer connects to wifi. :face_exhaling:

It seems like whenever I add a deep_sleep entry, even without triggering it, wifi is disabled.

17:59:37][D][sensor:093]: 'Moisture': Sending state 0.00000 % with 0 decimals of accuracy
[17:59:37][D][main:332]: Checking OTA Mode
[17:59:37][D][main:337]: OTA Mode OFF, allowing deep sleep
[17:59:37][D][main:090]: Device not initilaized, postponing deep sleep
[17:59:37][D][main:114]: >>>>> Received deep sleep duration Debug vX2
[17:59:41][D][sensor:093]: 'Moisture': Sending state 0.00000 % with 0 decimals of accuracy
(this loops indefinitely)

Here is the latest code:

substitutions:
  name: esphome-web-d1e7f6
  friendly_name: SoilX2

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  name_add_mac_suffix: false
  project:
    name: esphome.web
    version: '1.0'

esp8266:
  board: esp01_1m

# Enable logging
logger:

# Enable Home Assistant API
api:

# Allow Over-The-Air updates
ota:

# Allow provisioning Wi-Fi via serial
improv_serial:

wifi:
  # Set up a wifi access point
  ap: {}
  on_connect:
    then:
      - globals.set:
          id: is_initialized
          value: 'true'

# In combination with the `ap` this allows the user
# to provision wifi credentials to the device via WiFi AP.
captive_portal:

dashboard_import:
  package_import_url: github://esphome/example-configs/esphome-web/esp8266.yaml@main
  import_full_config: true

# To have a "next url" for improv serial
web_server:

globals:
 - id: is_initialized
   type: bool
   restore_value: no
   initial_value: 'false'

deep_sleep:
  id: deep_sleep_handler
  run_duration: 60s
  sleep_duration: 120s

binary_sensor:
  - platform: status
    name: "Soil Status"
  - platform: homeassistant
    id: otamode
    entity_id: input_boolean.soil_ota_mode_toggle

script:
  - id: test_ota
    mode: queued
    then:
      - logger.log: "Checking OTA Mode"
      - if:
          condition:
            binary_sensor.is_off: otamode
          then:
            - logger.log: 'OTA Mode OFF, allowing deep sleep'
            # Only enter deep Sleep if wifi initialized
            - if:
                condition:
                  lambda: 'return id(is_initialized);'
                then:
                  - logger.log: 'Device initialized, allowing deep sleep'
                  - deep_sleep.allow: deep_sleep_handler
                  - deep_sleep.enter: deep_sleep_handler
                else:
                  - logger.log: 'Device not initilaized, postponing deep sleep'    
          else:
            - logger.log: 'OTA Mode ON'
            - deep_sleep.prevent: deep_sleep_handler
  
sensor:
  - platform: adc
    pin: A0
    id: moistaf
    name: "Moisture"
    update_interval: 1s
    unit_of_measurement: "%"
    filters:
    - median:
        window_size: 7
        send_every: 4
        send_first_at: 1
    - calibrate_linear:
        - 1.0 -> 0.00
        - 0.52 -> 100.00
    - lambda: if (x < 1) return 0; else return (x);
    accuracy_decimals: 0
    force_update: True
    on_value:
      then:
        - script.execute: test_ota
        - logger.log:
            format: ">>>>> Received deep sleep duration Debug vX2"

I don’t know much about improv_serial: but typically you’d have the below details populated.

# It is highly recommended to use secrets
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

I also tend to use static_ip:

1 Like

Thank you,

Setting the wifi ssid/password explicitly made it work.

I’m not sure why this is happening, as it does connect normally without explicit credentials (presumably through the captive AP?), when running a boilerplate yaml.

1 Like