Enable access point mode on demand?

Is there a way at present to force an ESPHome device to switch to access point mode?

My setup is that I hard code wifi networks and IP addresses to all my devices to maximize reliability and minimize flash memory usage. This works fine.

However if I replace a device, then the old device - if it has the same IP - on power up will find it’s old wifi SSID and reconnect immediately with that IP.

What I’d like to be able to do is use one of the normal factory default/safe mode buttons to force the device to start AP mode even if the wifi is discovered.

Is there any way to request AP mode from a button press?

Why not power up the device connected to a computer. You can then update the IP/YAML straight away and update via the cable and not OTA. You could also use a different IP for the new device. Unless a device has failed my IP’s remain linked to that device.

I haven’t read anywhere that AP can be forced. You could power up outside your wifi range and then AP would start.

Not sure how adding AP to image helps to

Esphome documentation tells :
“ap_timeout (Optional, Time): The time after which to enable the configured fallback hotspot. Can be disabled by setting this to 0s, which requires manually starting the AP by other means (eg: from a button press). Defaults to 1min.”

But obviously doesn’t tell how…
I had a look a the wifi component library and in case of timeout it calls function:
void WiFiComponent::setup_ap_config_()
You could try to call that in labda.

Did anyone figure out or confirm how to do this? Frustrating that the documentation explicitly lists this example use-case but I can’t find anything explaining how to actually do this.

Because that wasn’t the question…

There are many devices that require advanced soldering skills to be flashed manually. Not a very friendly approach when recovering a bunch of devices with lost OTA keys. Hardcoding an easy wifi password is a nice solution if the AP would only start with manual intervention instead of every time the WiFi infrastructure is down.

I use this:

script:
  - id: wifi_temp_on
    mode: restart
    then:
      - lambda: WiFi.mode(WIFI_AP);
      - delay: 10min
      - lambda: WiFi.mode(WIFI_OFF);

This enables the AP mode and then switches off WiFi completely

Through trial and error, found that this only works with the Arduino framework, not ESP-IDF (it throws an error while compiling). Also found that this doesn’t use the AP settings I have in my YAML, but rather uses a generic SSID (ESP_XXXXX) with no password. Additionally, the AP it created was flaky (I couldn’t reliably connect to it and it seemed to disappear after a short time). I admittedly didn’t take the step to physically connect to the ESP to pull logs for troubleshooting since it wasn’t using my AP settings and wouldn’t work for my use-case. Thanks for the idea though!

I’ve just been testing with this, works quite nicely. The factory reset is needed to wipe a password stored with the captive portal. Then the shorter press is to delete the ‘factory’ settings temporarily, it can be cancelled by power cycling.

wifi:
  ssid: OpenWrt
  password: verysecret
  id: wificomp

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Test Fallback Hotspot"
    password: "00000000"
    ap_timeout: 0s

captive_portal:
    
binary_sensor:
  - platform: gpio
    pin: D4
    name: btntest
    filters: 
      - invert:
    on_click:
      - min_length: 2000ms
        max_length: 5000ms
        then:
          - lambda: |-
              id(wificomp).set_ap_timeout(1);
              id(wificomp).disable();
              id(wificomp).clear_sta();
              id(wificomp).enable(); 
      - min_length: 5000ms
        max_length: 10000ms
        then:
          - switch.turn_on: factrst

switch:
  - platform: factory_reset
    id: factrst

Thanks for working this out! This fits my use-case perfectly; just flashed and verified it works as I need it (and even works with the ESP-IDF framework).

You should update the ESPHome docs accordingly, to include your example. I think you’d help some other folks in the future.

Thanks again!

Hi, thanks. Feel free to add any of this to the docs. I’ve been testing some more and found a more elegant solution. It turns out you just need to not program wifi credentials and then you can even use the web_server component. It’ll only start the captive portal when in factory reset state, and not when it cannot connect.

wifi:
  ap:
    ssid: "Test Fallback Hotspot"
    password: "00000000"
    ap_timeout: 0s

captive_portal:

web_server:
  port: 80
    
binary_sensor:
  - platform: gpio
    pin: D4
    name: btntest
    filters: 
      - invert:
    on_click: 
      - min_length: 5000ms
        max_length: 10000ms
        then:
          - switch.turn_on: factrst

switch:
  - platform: factory_reset
    id: factrst