Use Home Assistant number as delay in ESPHome

Have been struggling with this problem for days and no matter what I try I am unable to get there. I have a home assistant input number that I’d like to use in delay functions. But it requires a either a float or a string where I’d like to use an integer.

I want to use it to set the delay time in minutes.

I obtain the value from home assistant as follows:

sensor:
  - platform: homeassistant
    id: max_run_time_minutes
    name: "Max Run Time - All Zones"
    entity_id: input_number.irrigation_max_duration

I want to use it with the delay function of this block:

switch:
  - platform: template
    name: $friendly_name $zone_4
    icon: $sprinkler_icon
    id: zone_4
    lambda: return id(relay_4).state;
    optimistic: true
    turn_on_action:
      - switch.turn_on: relay_4
      - delay:
          minutes: max_run_time_minutes
#      - delay:
#          minutes: float_max_run_time_minutes
#      - delay: $max_run_time
#      - delay: !lambda "return id(max_run_time_minutes) & 'min';"
      - switch.turn_off: relay_4
    turn_off_action:
      - switch.turn_off: relay_4

ESP Home complains that minutes expects a float. I tried to set up a global float but that doesn’t work either.

I have managed to use a substitution to set the delay time:

substitutions:
  # Set Max Run Time Here: =============================#
  max_run_time: "10min"
  # Sets delay between switch turn on and switch turn off
  #======================================================#

But I can’t figure out how to get that back to home assistant.

Tried this without success:

text_sensor:
  - platform: template
    name: "Irrigation Max Run"
    id: str_delay_setting
    lambda: |-
      return $max_run_time

I would like to set an initial value within ESPHome and update it with a home assistant value, or at least return that setting to home assistant.

Can anyone point me in the right direction. Just can’t seem to figure it out. Any help would be appreciated. Thanks for reading.

1 Like

Don’t you want minutes: id(max_run_time_minutes).state ?

Edit: What Nick said may be your problem - I missed that…

Try converting to float in lambda. All platform: homeassistant sensors are strings.

    turn_on_action:
      - switch.turn_on: relay_4
      - delay: !lambda "return  atof(id(max_run_time_minutes).state.c_str()) & 'min';"

Or something like that :slight_smile:

Although you may be better off converting into a variable, I can’t tell if the above format will work. I had to do a lot of this for the display component.

Thanks… I tried:

switch:
  - platform: template
    name: $friendly_name $zone_4
    icon: $sprinkler_icon
    id: zone_4
    lambda: return id(relay_4).state;
    optimistic: true
    turn_on_action:
      - switch.turn_on: relay_4
      - delay:
          minutes: id(float_max_run_time_minutes).state
#      - delay:
#          minutes: float_max_run_time_minutes
#      - delay: $max_run_time
#      - delay: !lambda "return id(max_run_time_minutes) & 'min';"
      - switch.turn_off: relay_4
    turn_off_action:
      - switch.turn_off: relay_4

Still says it wants a float, but it is a float:

globals:
  - id: float_max_run_time_minutes
    type: float
    initial_value: '10'

'10' is not a float, it is a string.

Thanks, I sure would like to assign it to a variable if I can figure out how. My understanding is that delay requires a string. I have used a substitution to set the delay…

substitutions:
  max_run_time: 10min
switch:
  - platform: template
    name: $friendly_name $zone_4
    icon: $sprinkler_icon
    id: zone_4
    lambda: return id(relay_4).state;
    optimistic: true
    turn_on_action:
      - switch.turn_on: relay_4
      - delay: $max_run_time
      - switch.turn_off: relay_4
    turn_off_action:
      - switch.turn_off: relay_4

Now that I know that all home assistant values are strings, perhaps a lambda function to append “min” to the value would work.

Thought this would work:

      - switch.turn_on: relay_4
      - delay: !lambda "return id(max_run_time_minutes).state & 'min';"

Alas…

/config/esphome/switch_back_4ch.yaml:115:44: warning: multi-character character constant [-Wmultichar]
  115 |       - delay: !lambda "return id(max_run_time_minutes).state & 'min';"
      |                                            ^~~~~
/config/esphome/switch_back_4ch.yaml: In lambda function:
/config/esphome/switch_back_4ch.yaml:115:42: error: invalid operands of types 'float' and 'int' to binary 'operator&'
  115 |       - delay: !lambda "return id(max_run_time_minutes).state & 'min';"
      |              ~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~
      |                                    |       |
      |                                    float   int
*** [/data/switch-irrigation-4ch/.pioenvs/switch-irrigation-4ch/src/main.cpp.o] Error 1
========================= [FAILED] Took 144.63 seconds =========================

Not sure why it thinks it’s a float (or an int) if “All platform: homeassistant sensors are strings.”

OK, so it is not possible to define an initial value as a number only as a string? Even though, as per the example on the ESP Home site, it has been defined as an integer.

 # Example configuration entry
 globals:
   - id: my_global_int
     type: int
     restore_value: no
     initial_value: '0'

I convert delays to milliseconds, input number is used as min in the frontend

## time pump is on
  - platform: homeassistant
    id: pump_start
    internal: true
    accuracy_decimals: 2
    entity_id: input_number.pump_start
    on_value:
      - globals.set:
          id: start
          value: !lambda 'return id(pump_start).state * 1000;'

Then save it in a global, you can set a default here

## time pump is on start
  - id: start
    type: int
    restore_value: no
    initial_value: '1200'

Drop state to use global in lambda

 !lambda 'return id(start);'
3 Likes

This looks promising. Thanks a lot.

Just use delay and not the extended config

- delay: !lambda 'return id(start);'
2 Likes

You said earlier that the system seemed to want a float?

I thought the quotes '' made it a string. But hey, I was wrong once before :slight_smile:

2 Likes

Yeah, I was trying two different methods…

- delay: $max_run_time # expects a string .. like "10min"

…and…

- delay:
    minutes: float_max_run_time_minutes #expects a float

No worries, thanks for your help.

Thanks, this works very well.

1 Like

Hmm, it did not work 4 me :frowning:

number:
  - platform: template
    name: "Czas pracy"
    icon: "mdi:timer"
    id: ontime
    optimistic: true
    min_value: 1
    max_value: 100
    initial_value: 5
    step: 1

switch:
  - platform: gpio
    name: Relay
    id: przekaznik
    pin: GPIO12
    restore_mode: RESTORE_DEFAULT_OFF
    icon: "mdi:toggle-switch-variant-off"
  
    on_turn_on:
    
    - logger.log: "Załączenie"

    - delay: !lambda 'return id(ontime);'
        
    - switch.turn_off: przekaznik


INFO ESPHome 2024.11.1
INFO Reading configuration /config/pompa-mauser.yaml...
INFO Detected timezone 'Europe/Warsaw'
INFO Generating C++ source...
INFO Compiling app...
Processing pompa-mauser (board: esp01_1m; framework: arduino; platform: platformio/[email protected])
--------------------------------------------------------------------------------
HARDWARE: ESP8266 80MHz, 80KB RAM, 1MB Flash
Dependency Graph
|-- ESPAsyncTCP-esphome @ 2.0.0
|-- ESPAsyncWebServer-esphome @ 3.2.2
|-- DNSServer @ 1.1.1
|-- ESP8266WiFi @ 1.0
|-- ESP8266mDNS @ 1.2
|-- noise-c @ 0.1.6
|-- ArduinoJson @ 6.18.5
Compiling .pioenvs/pompa-mauser/src/main.cpp.o
/config/pompa-mauser.yaml: In lambda function:
/config/pompa-mauser.yaml:127:14: error: invalid conversion from 'esphome::template_::TemplateNumber*' to 'uint32_t' {aka 'unsigned int'} [-fpermissive]
  127 |     - delay: !lambda 'return id(ontime);'
      |              ^~~~~~
      |              |
      |              esphome::template_::TemplateNumber*
*** [.pioenvs/pompa-mauser/src/main.cpp.o] Error 1

Any hint ?

You need to include state.

!lambda 'return id(ontime).state';
1 Like

thx 4 a hint !