Wait_until number.in_range condition

Hello All,
I need some help on how to get some code properly working.
Setup: Sonoff POWR controlling power to dehumidify. HA has generic_hygrostat in config.

Goal: When HA sends switch.turn_off to the Sonoff, make sure the compressor has been off for an x amount of time.

How I’m trying to do this: In ESPHome yaml file, keep track of number component int when power used is within a range with interval. When turn_off is sent, ESPHome will use wait_untill before turning off power to dehumidifier.

The Problem: I see the number component updating but it seems the wait_until isn’t waiting for the condition to be true.

The code:

esphome:
  name: $base_name
  friendly_name: $friendly_name
  on_boot:
    priority: 800.0
    then:
      - number.set:
          id: compressor_off_time
          value: 0

sensor:
  - platform: cse7766
    update_interval: 1s
    current:
      name: $friendly_name Current
      id: a_sensor
    voltage:
      name: $friendly_name Voltage
      id: v_sensor
    power:
      name: $friendly_name Power
      id: w_sensor
      on_value_range:
        - above: 80.0
          then:
            - light.turn_on: switch_led
        - below: 80.0
          then:
            - light.turn_off: switch_led
    energy:
      name: $friendly_name Energy
      id: wh_sensor

number:
  - platform: template
    name: compressor_off_time
    id: compressor_off_time
    #internal: True
    max_value: 1000
    min_value: 0
    step: 1
    optimistic: true

switch:
  - platform: gpio #turn off
    restore_mode: ALWAYS_OFF
    internal: true
    id: relay_off
    pin: GPIO04
    on_turn_on:
      - logger.log: "Waiting for compressor to turn off"
      - wait_until:
          number.in_range:
            id: compressor_off_time
            above: 180.0
      - logger.log: "Compressor has turned off"
      - delay: 100ms
      - switch.turn_off: relay_off # bi-stable relay so no need to keep on
      - light.turn_off: switch_led
      - number.set:
          id: compressor_off_time
          value: '0'
    interlock: [relay_on]

interval:
  - interval: 1s
    then:
      if:
        condition:
          sensor.in_range:
            id: w_sensor
            above: 10
            below: 100
        then:
          - number.increment:
              id: compressor_off_time
              cycle: false

I’ve tried to follow examples in the online docs but it seems to elude me with combining if, wait_until, and number.in_range I get errors since wait_until is an action. Any help would be greatly appreciated.

Thank you

number.in_range Condition

# in a trigger:
on_...:
  if:
    condition:
      number.in_range:
        id: my_number
        above: 50.0
    then:
      - script.execute: my_script

wait_until Action

# In a trigger:
on_...:
  - logger.log: "Waiting for binary sensor"
  - wait_until:
      binary_sensor.is_on: some_binary_sensor
  - logger.log: "Binary sensor is ready"

Edit: added platform: cse7766 for clearity of sensor source w_sensor

Not sure where you define this - obviously you need to ensure it’s value is valid.

Is there some reason a simple delay: action wouldn’t work?

    on_turn_on:
      - logger.log: "Waiting for compressor to turn off"
      - delay: 180s

Sorry about that, w_sensor is a valid source.

Edited the code to include platform: cse7766 of the source w_sensor to remove any future confusion.

A simple delay wouldn’t work since I don’t have any communications from the dehumidifier and how the dehumidifier works is it’ll turn on the compressor and if there is any build up of ice internally, it’ll run just the fan to defrost it as a fail safe.

To get any internal sensor feedback of the dehumidifier would require hacking the unit and would void warranty. By monitoring the power usage, it’s possible to determine which state the dehumidifier is in.

When HA sends the switch.turn_off signal, I’d want the controller to locally determine when it’s safe to cut the power to it.

Here is the entirety of the code, which is a bit different from the top since I’ve been working on trial and error so it doesn’t reflect the original post.

substitutions:
  friendly_name: POWR320D
  base_name: powr320d_1267

esphome:
  name: $base_name
  friendly_name: $friendly_name
  on_boot:
    priority: 800.0
    then:
      - number.set:
          id: compressor_off_time
          value: 0
      - number.set:
          id: compressor_on_time
          value: 0
 
esp32:
  board: nodemcu-32s

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  ap:
    ssid: $base_name
    password: !secret wifi_password
  manual_ip:
    static_ip: 192.168.8.219
    gateway: 192.168.8.1
    subnet: 255.255.255.0

captive_portal:

logger:

api:
  services:
    - service: turn_off
      then:
      - wait_until:
          sensor.in_range:
            id: w_sensor
            below: 80
      - delay: 180s
      - switch.turn_off: relay_1
    - service: turn_on
      then:
        - switch.turn_on: relay_1

ota:

web_server:
  port: 80
  ota: true
  js_url: http://192.168.8.123:8123/local/www.js

uart:
  rx_pin: GPIO16
  baud_rate: 4800

time:
  - platform: homeassistant
    id: homeassistant_time

number:
  - platform: template
    name: compressor_off_time
    id: compressor_off_time
    #internal: True
    max_value: 1000
    min_value: 0
    step: 1
    optimistic: true
  - platform: template
    name: compressor_on_time
    id: compressor_on_time
    #internal: True
    max_value: 10000
    min_value: 0
    step: 1
    optimistic: True


sensor:
  - platform: cse7766
    update_interval: 1s
    current:
      name: $friendly_name Current
      id: a_sensor
    voltage:
      name: $friendly_name Voltage
      id: v_sensor
    power:
      name: $friendly_name Power
      id: w_sensor
      on_value_range:
        - above: 80.0
          then:
            - light.turn_on: switch_led
        - below: 80.0
          then:
            - light.turn_off: switch_led
    energy:
      name: $friendly_name Energy
      id: wh_sensor

  - platform: total_daily_energy
    name: $friendly_name Total Daily Energy
    power_id: w_sensor

  - platform: wifi_signal
    name: $friendly_name Wifi RSSI
    update_interval: 60s

  - platform: uptime
    id: uptime_sensor
    internal: True
    on_raw_value:
      then:
        - text_sensor.template.publish:
            id: uptime_human
            state: !lambda |-
              int seconds = round(id(uptime_sensor).raw_state);
              int days = seconds / (24 * 3600);
              seconds = seconds % (24 * 3600);
              int hours = seconds / 3600;
              seconds = seconds % 3600;
              int minutes = seconds /  60;
              seconds = seconds % 60;
              return (
                (days ? to_string(days) + "d " : "") +
                (hours ? to_string(hours) + "h " : "") +
                (minutes ? to_string(minutes) + "m " : "") +
                (to_string(seconds) + "s")
              ).c_str();

  - platform: template
    name: $friendly_name Power Factor
    device_class: power_factor
    id: power_factor
    lambda: return id(w_sensor).state / id(v_sensor).state / id(a_sensor).state;

binary_sensor:
  - platform: gpio
    pin: GPIO00
    id: reset
    internal: true
    filters:
      - invert:
      - delayed_off: 10ms
    on_click:
      - max_length: 350ms # short press to toggle the relay
        then:
          switch.toggle: relay_1
      - min_length: 360ms # long press to cycle display info
        max_length: 3s
        then:
          - if:
              condition:
                binary_sensor.is_on: page
              then:
                binary_sensor.template.publish:
                  id: page
                  state: OFF
              else:
                binary_sensor.template.publish:
                  id: page
                  state: ON
  - platform: template # this is a fake sensor to tell the screen which info to show on display
    id: page
    publish_initial_state: true
    internal: true

display:
  platform: tm1621
  id: tm1621_display
  cs_pin: GPIO25
  data_pin: GPIO14
  read_pin: GPIO26
  write_pin: GPIO27
  lambda: |-
    if (id(page).state) {
      it.display_voltage(true);
      it.display_kwh(false);
      it.printf(0, "%.1f", id(v_sensor).state);
      it.printf(1, "%.1f", id(a_sensor).state);
    } else {  
      it.display_voltage(false);
      it.display_kwh(true);
      it.printf(0, "%.1f", id(wh_sensor).state);
      it.printf(1, "%.1f", id(w_sensor).state);
    }

output:
  - platform: ledc
    id: led
    pin:
      number: GPIO18
      inverted: True

switch:
  - platform: template
    name: $friendly_name
    optimistic: true
    id: relay_1
    turn_off_action:
      - switch.turn_on: relay_off
    turn_on_action:
      - switch.turn_on: relay_on

  - platform: gpio #turn off
    restore_mode: ALWAYS_OFF
    internal: true
    id: relay_off
    pin: GPIO04
    on_turn_on:
          if:
            condition:
              wait_until:
                number.in_range: #currently in error state while working on it
                  id: compressor_off_time
                  above: 180.0
            then:
              - logger.log: "Compressor has turned off"
              - delay: 100ms
              - switch.turn_off: relay_off # bi-stable relay so no need to keep on
              - light.turn_off: switch_led
              - number.set:
                  id: compressor_off_time
                  value: '0'
    interlock: [relay_on]

  - platform: gpio #turn on
    restore_mode: ALWAYS_OFF
    internal: true
    id: relay_on
    pin: GPIO02
    on_turn_on:
      - delay: 100ms
      - switch.turn_off: relay_on  # bi-stable relay so no need to keep on
      - light.turn_on: switch_led
    interlock: [relay_off]

  - platform: restart
    name: $friendly_name Restart

text_sensor:
  - platform: template
    name: $friendly_name Uptime
    id: uptime_human
    icon: mdi:clock-start
  - platform: wifi_info
    ip_address:
      name: $friendly_name IP
    ssid:
      name: $friendly_name SSID
    bssid:
      name: $friendly_name BSSID

light:
  - platform: monochromatic
    id: switch_led
    output: led
    internal: True
  - platform: status_led
    id: wifi_status_led
    internal: True
    pin:
      number: GPIO05
      inverted: True

interval:
  - interval: 1s
    then:
      if:
        condition:
          sensor.in_range:
            id: w_sensor
            above: 10
            below: 100
        then:
          - number.increment:
              id: compressor_off_time
              cycle: false


  - interval: 30s
    then:
      if:
        condition:
          wifi.connected:
        then:
          - light.turn_on: wifi_status_led
        else:
          - light.turn_off: wifi_status_led
  - interval: 100ms
    then:
      if:
        condition:
          sensor.in_range:
            id: a_sensor
            above: 20.0
        then:
        - switch.turn_on: relay_off