How to quickly detect when an ESPhome becomes available?

I have an ESPhome device which (according to logs) connects to the wifi in 0.2 seconds (static IP, BSSID provided without scanning needed). However, it takes 15 seconds or so to show up in HA and as result an HA automation triggered by the online presence takes as much.

trigger: state
entity_id:
  - switch.led_attic_q1_quinled_deca_light
from: unavailable
id: became-available

See the logbook:

LED-attic Restart changed to May 20, 2025 at 14:23

14:24:00 - Now

LED-attic Restart became unavailable triggered by action Button: Press

14:23:39 - 21 seconds ago

That’s 21 seconds for a restart, even if the bare connection to the wifi is well under a second. Other times maybe it takes “as little as” 11 seconds, but usually 15 s.
In the terminal, upon uploading the firmware, I also see:

INFO Successfully connected to led-attic @ 192.168.xxx in 15.528s
INFO Successful handshake with led-attic @ 192.168.x in 0.082s

Since I use ESPhome to control lights upon power-up, I would like to speed up the starting of automation.

What can I do?

This is the config:

esphome:
  name: led-attic
  friendly_name: LED-attic
  on_boot:
    - priority: 600
      then:
      - light.turn_on:
          id: central
          brightness: 33%

esp32:
  board: mhetesp32devkit
  framework:
    type: arduino

logger:
  baud_rate: 0

api:
  encryption:
    key: xxx

ota:
  - platform: esphome
    password: xxx

wifi:
  manual_ip:
    static_ip: 192.168.xxx
    gateway: 192.168.xxx
    subnet: 255.255.255.0
    dns1: 192.168.xxx

  networks:
  - ssid: !secret wifi_ssid
    password: !secret wifi_password
    bssid: xxx
    priority: 2
  - ssid: !secret wifi_ssid
    password: !secret wifi_password
    bssid: xxx
    priority: 1

  ap:
    ssid: "Led-Attic Fallback Hotspot"
    password: xxx

captive_portal:
    
web_server:

one_wire:
  - platform: gpio
    pin: 32

sensor:
  - platform: dallas_temp
    name: "q1_quinled_deca temp"

switch:
  - platform: gpio
    name: "q1_quinled_deca light"
    pin: 2
    inverted: True

output:
  - platform: ledc
    pin: 16
    frequency: 19531Hz
    id: LED_gpio_16

  - platform: ledc
    pin: 17
    frequency: 19531Hz
    id: LED_gpio_17

  - platform: ledc
    pin: 18
    frequency: 19531Hz
    id: LED_gpio_18

light:
  - platform: monochromatic
    id: rear
    name: "q1_quinled_deca-6"
    default_transition_length: 2s
    output: LED_gpio_16
    initial_state: 
      state: ON
      color_mode: brightness
      brightness: 55%

  - platform: monochromatic
    id: office
    name: "q1_quinled_deca-7"
    default_transition_length: 2s
    output: LED_gpio_17
    initial_state: 
      state: ON
      color_mode: brightness
      brightness: 55%

  - platform: monochromatic
    id: central
    name: "q1_quinled_deca-8"
    default_transition_length: 2s
    output: LED_gpio_18
    initial_state: 
      state: ON
      color_mode: brightness
      brightness: 33%
  
button:
  - platform: restart
    name: "Restart"

Can you substitute that automation with esphome automation?

I can try, but the fact that ESPhome logs show

INFO Successfully connected to led-attic @ 192.168.xxx in 15.528s

is not very promising.

I used:

api:
  encryption:
    key: xxx
  on_client_connected:
    - logger.log:
        format: "Client %s connected to API with IP %s"
        args: ["client_info.c_str()", "client_address.c_str()"]
    - lambda: |-
        if (id(ha_motion_rear).state) {
          id(central).turn_off();
          id(rear).turn_on();
        }
        if (id(ha_motion_office).state) {
          id(central).turn_off();
          id(office).turn_on();
        }

binary_sensor:
  - platform: homeassistant
    internal: True
    entity_id: binary_sensor.xxx
    id: ha_motion_office
  - platform: homeassistant
    internal: True
    entity_id: binary_sensor.xxx
    id: ha_motion_rear

but it doesn’t seem to work at all.

Not what I meant, but doesn’t matter, I see now that automation is about other devices not connected to Esphome.
Many people use MQTT, but I wonder if HTTP request could be an option as well?

I’m trying MQTT and it’s visibly faster. Still not clear why the native API are so slow.

I don’t know, but it depends on home assistant which makes the connection.

I was optimistic, it was only variability. It can be as slow as the API.

Have a look how HA can receive HTTP requests. Esphome can make them very quickly as soon as wifi is working.

Another option coud be to send HTTP request to another “always on” esphome device which then updates HA.

If you connect the node to a pc and flash it through usb, setting logging at VERY_VERBOSE you could see what is going on in the esp during those 15 seconds. May give you some insight.

If you disable encryption, is it the same? If it is the same and the logs are of no use, you can use wireshark to see what is going back and forth to HA during those 15sec.

You have tried ESP-IDF Framework?

I didn’t think about it, but I read it’s slower.

This did it!
Now I know the cause is the wifi, it’s performing a full scan even if I provided specific networks and BSSIDs specifically hoping to get the fastest connection speed.

[10:35:35][C][wifi:048]: Setting up WiFi...
[10:35:35][C][wifi:061]: Starting WiFi...
[10:35:35][C][wifi:062]:   Local MAC: 58:BF:25:8B:C8:D4
[10:35:35][V][esp32.preferences:059]: nvs_get_blob('1325887575'): ESP_ERR_NVS_NOT_FOUND - the key might not be set yet
[10:35:35][V][wifi_esp32:081]: Enabling STA.
[10:35:35][   423][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 0 - WIFI_READY
[10:35:35][V][wifi_esp32:523][arduino_events]: Event: WiFi ready
[10:35:35][   520][V][WiFiGeneric.cpp:338] _arduino_event_cb(): STA Started
[10:35:35][   520][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 2 - STA_START
[10:35:35][V][wifi_esp32:534][arduino_events]: Event: WiFi STA start
[10:35:35][W][component:157]: Component wifi set Warning flag: scanning for networks
[10:35:41][  6646][V][WiFiGeneric.cpp:381] _arduino_event_cb(): SCAN Done: ID: 128, Status: 0, Results: 13
[10:35:41][  6646][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 1 - SCAN_DONE
[10:35:41][V][wifi_esp32:528][arduino_events]: Event: WiFi Scan Done status=0 number=13 scan_id=128
[10:35:41][D][wifi:497]: Found networks:
[10:35:41][I][wifi:541]: - '_ssid_' (xxx) [redacted]▂▄▆█
[10:35:41][D][wifi:542]:     Channel: 1
[10:35:41][D][wifi:543]:     RSSI: -53 dB
[10:35:41][I][wifi:541]: - '_ssid_' (yyy) [redacted]▂▄▆█
[10:35:41][D][wifi:542]:     Channel: 6
[10:35:41][D][wifi:543]:     RSSI: -77 dB
...
[10:35:41][D][wifi:546]: - '_ssid_'[redacted] (zzz) [redacted]▂▄▆█
...
[10:35:41][I][wifi:313]: WiFi Connecting to '_ssid_'...
[10:35:41][V][wifi:315]: Connection Params:
[10:35:41][V][wifi:316]:   SSID: '_ssid_'
[10:35:41][V][wifi:319]:   BSSID: xxx
[10:35:41][V][wifi:349]:   Password: '...'[redacted]
[10:35:41][V][wifi:354]:   Channel: 1
[10:35:41][V][wifi:361]:   Manual IP: Static IP=192.168.... Gateway=192.168.... Subnet=255.255.255.0 DNS1=192.168.... DNS2=0.0.0.0
[10:35:41][V][wifi:365]:   Hidden: NO
[10:35:44][  9700][V][WiFiGeneric.cpp:353] _arduino_event_cb(): STA Connected: SSID: _ssid_, BSSID: xxx, Channel: 1, Auth: WPA2_PSK
[10:35:44][  9702][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 4 - STA_CONNECTED
[10:35:44][  9706][V][WiFiGeneric.cpp:367] _arduino_event_cb(): STA Got New IP:192.168....
[10:35:44][V][wifi_esp32:553][arduino_events]: Event: Connected ssid='_ssid_' bssid=xxx[redacted] channel=1, authmode=WPA2 PSK
[10:35:44][  9739][D][WiFiGeneric.cpp:929] _eventCallback(): Arduino Event: 7 - STA_GOT_IP
[10:35:44][  9739][D][WiFiGeneric.cpp:991] _eventCallback(): STA IP: 192.168...., MASK: 255.255.255.0, GW: 192.168....
[10:35:44][V][wifi_esp32:607][arduino_events]: Event: Got IP static_ip=192.168.... gateway=192.168....
[10:35:44][I][wifi:617]: WiFi Connected!
[10:35:44][C][wifi:428]:   Local MAC: ...
[10:35:44][C][wifi:433]:   SSID: '_ssid_'[redacted]
[10:35:44][C][wifi:436]:   IP Address: 192.168....
[10:35:44][C][wifi:440]:   BSSID: xxx[redacted]
[10:35:44][C][wifi:441]:   Hostname: 'led-attic'
[10:35:44][C][wifi:443]:   Signal strength: -52 dB ▂▄▆█
[10:35:44][V][wifi:445]:   Priority: 2.0
[10:35:44][C][wifi:447]:   Channel: 1
[10:35:44][C][wifi:448]:   Subnet: 255.255.255.0
[10:35:44][C][wifi:449]:   Gateway: 192.168....
[10:35:44][C][wifi:450]:   DNS1: 192.168....
[10:35:44][C][wifi:451]:   DNS2: 0.0.0.0
[10:35:44][D][wifi:626]: Disabling AP...

In the config I have:

wifi:
# fast connect not compatible with "networks"
#  fast_connect: True
  manual_ip:
    static_ip: 192.168....
    gateway: 192.168....
    subnet: 255.255.255.0
    dns1: 192.168....

  networks:
  - ssid: !secret wifi_ssid
    password: !secret wifi_password
    bssid: xxx
    priority: 2
  - ssid: !secret wifi_ssid
    password: !secret wifi_password
    bssid: yyy
    priority: 1

It connects to the first network I specify, but after doing a full scan.

Now I’ll use a normal configuration, with only SSID and password, which allows me to use fast_connect, letting ESPhome pick the network. It does what I expect and it pops up in HA within 3 seconds from boot!

However, the fast_connect does not guarantee the best network. Unfortunately ESPhome is not optimal in this regard:

Can someone please upvote the feature request, which would allow a fast connection and also the choice of the best network?

Just to note it.
You redacted the wrong thing in your post.
Your 192.168 IP is the local IP in your house.
I also have a 192 IP. Most do.
However the SSID is what most people redact since that can be reverse searched to get the location.
But it requires someone who actually cares to do it.

Thanks. Corrected.