I had a (self induced) power outage in my wifi router yesterday, and subsequently all my ESPHOMEs apparently did not reconnect. I pushed the reset button on all, and we were back in business.
Will ESPHOME try to wifi connect, even when in AP mode?
Says:
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.
and:
reboot_timeout (Optional, Time): The amount of time to wait before rebooting when no WiFi connection exists. Can be disabled by setting this to 0s, but note that the low level IP stack currently seems to have issues with WiFi where a full reboot is required to get the interface back working. Defaults to 15min. Does not apply when in access point mode.
Is there any way to teach the ESP to do the best of the two worlds: Open an AP for emergency or PW change - but reconnect once the wifi is back?
Just curious: do you need AP? I don’t… i don’t have AP set up in any of my devices. I use fixed IP, fixed SSID and password (wrote down in yaml itself), so i see no need for AP. I also don’t have “captive_portal’” in any of my devices. If you remove AP then module will restart after “restart_timeout”:
when there”s no wifi connection,
when there’s no connection to HA via API (if you use api, not mqtt).
disabling the AP fall-back would require me to physically remove all ESPs and serial-flash those if at any point I need to reconfigure my wifi. E.g. I recently had to change the wifi password, that would lead to quite some some effort.
(If it is planned one could OTA all with new credentials, while the old config is still live, knowing they would not be connecting, as the new config is not yet active)
I was hoping to get free lunch with AP and retry at the same time.
I see you… although it’s questionable which is faster:
do OTA of all devices before changing password or
connect to each one of them and change password of each manually…
since it’s possible to have wifi credentials in one file only for all esphome devices (with include…file in yaml) i dare to say that first option is way faster, since you just change password in that file and click “update all” in esphome web interface…
I have wifi credentials and sensors, which are in all devices stored in that file (like wifi signal strength, uptime, connection led…)
Another case where this is extremely painful is when using bssids instead of ssids.
Cases when we need a wifi credentials change:
Change existing wifi credentials.
Changing to new equipment, when existing equipment is at hand.
Existing equipment goes bad and need to replace it with new equipment.
Case 1 and 2 is fairly simple (although we do have to wait for the new equipment to arrive in case 2). Case 3 is quite painful, if we don’t have AP mode backup.
Two possible solutions I’m exploring currently:
Setting up a hardcoded backup network to connect to (like a mobile hotspot). If this works properly, then AP may be disabled safely.
Setting ap_timeout to a large value and setting up physical actions on the device (like button presses) to change it to a low value, and once connected to wifi changing it back to a high value (possible?)
Solution 1 works. Solution 2 doesn’t, if AP is enabled setting “reboot_timeout” in wifi has no effect. But “reboot_timeout” in API should work, but I can’t figure out why it doesn’t for me.
Something which works for me below. Yeah, I have a crap ton of redundancies…
Wifi settings:
wifi:
use_address: ${device_use_address}
reboot_timeout: "8min" # This won't work anyway as ap is enabled
power_save_mode: ${wifi_power_save_mode}
networks:
- ssid: ${wifi_ssid}
bssid: ${wifi_bssid}
password: ${wifi_password}
priority: 10.0
manual_ip:
static_ip: ${device_static_ip}
gateway: ${wifi_gateway_ip}
subnet: ${wifi_subnet}
- ssid: ${bk_wifi_ssid}
password: ${wifi_password}
priority: 1.0
manual_ip:
static_ip: ${bk_device_static_ip}
gateway: ${bk_wifi_gateway_ip}
subnet: ${bk_wifi_subnet}
# Enable fallback hotspot (captive portal) in case wifi connection fails.
ap:
ap_timeout: "5min"
password: ${fallback_wifi_password}
manual_ip:
static_ip: ${ap_static_ip}
gateway: ${ap_gateway}
subnet: ${ap_subnet}
on_connect:
# Log to ESPHome
- logger.log: "Wifi Connected!"
# Log to HA
- homeassistant.action:
action: system_log.write
data:
level: info
message: "Wifi Connected!"
logger: custom.esphome
on_disconnect:
# Log to ESPHome
- logger.log: "Wifi Disconnected!"
# Log to HA
- homeassistant.action:
action: system_log.write
data:
level: info
message: "Device ${device_name}: Wifi Disconnected!"
logger: custom.esphome
- delay: 8 min
# Restart after 8 min if still no wifi
- if:
condition:
not:
wifi.connected:
then:
- logger.log: Still no wifi!
- button.press: restart_button
else:
- logger.log: Wifi reconnected within 8 min!
# Log to HA
- homeassistant.action:
action: system_log.write
data:
level: info
message: "Device ${device_name}: Wifi reconnected within 8 min!"
logger: custom.esphome
API settings:
# Enable Home Assistant API
api:
encryption:
key: ${esphome_api_encryption_key}
# This should work, but doesn't do a safe_reboot, only reboot
reboot_timeout: "8min"
# Scan wifi / Reset wifi actions
actions:
- action: scan_wifi
then:
- lambda: |-
wifi::global_wifi_component->start_scanning();
on_client_connected:
# This is executed only when connected and authenticated
# Log to ESPHome
- logger.log:
format: "Client %s connected to API with IP %s"
args: ["client_info.c_str()", "client_address.c_str()"]
# Log to HA
- homeassistant.action:
action: system_log.write
data:
level: info
logger: custom.esphome
data_template:
message: |-
Device ${device_name}: Api Connected - Client: {{client_info}} - Address: {{client_address}}
variables:
client_info: |-
return client_info;
client_address: |-
return client_address;
on_client_disconnected:
# This is executed even when connected but not authenticated
# Log to ESPHome
- logger.log:
format: "Client %s disconnected from API with IP %s"
args: ["client_info.c_str()", "client_address.c_str()"]
# Log to HA
- homeassistant.action:
action: system_log.write
data:
level: info
logger: custom.esphome
data_template:
message: |-
Device ${device_name}: Api Disconnected - Client: {{client_info}} - Address: {{client_address}}
variables:
client_info: |-
return client_info;
client_address: |-
return client_address;
# Restart after 8 min if still no API clients are connected
- if:
condition:
not:
api.connected:
then:
- delay: 8 min
- if:
condition:
not:
api.connected:
then:
- logger.log: Still no api clients connected!
- button.press: restart_button
else:
- logger.log: Some api clients are still connected!
# Log to HA
- homeassistant.action:
action: system_log.write
data:
level: info
message: "Device ${device_name}: Some api clients are still connected!"
logger: custom.esphome
else:
- logger.log: Some api clients are still connected!
# Log to HA
- homeassistant.action:
action: system_log.write
data:
level: info
message: "Device ${device_name}: Some api clients are still connected!"
logger: custom.esphome
On Boot settings:
on_boot:
- priority: -100
then:
- delay: 8 min
- if:
condition:
not:
wifi.connected:
then:
- logger.log: Still no wifi!
- button.press: restart_button
- if:
condition:
not:
api.connected:
then:
- logger.log: Still no API clients!
- button.press: restart_button
For my 2/4 gang touch switches i also enable manual reboot and safe reboot as follows:
platform: "tuya"
name: ${sensor_name}
sensor_datapoint: ${sensor_id}
on_multi_click:
- timing:
- ON for at most 1s
- OFF for at most 1s
- ON for at most 1s
- OFF for at most 1s
- ON for at most 1s
- OFF for at least 0.5s
then:
# Log to HA
- homeassistant.action:
action: system_log.write
data:
level: info
message: "Device ${device_name}: Button triple clicked, starting from OFF. Triggering ${sensor_name} in 10s."
logger: custom.esphome
- delay: 10s
- logger.log: "Button triple clicked, starting from OFF. Triggering ${sensor_name}."
- button.press: ${sensor_button}
- timing:
- OFF for at most 1s
- ON for at most 1s
- OFF for at most 1s
- ON for at most 1s
- OFF for at most 1s
- ON for at least 0.5s
then:
# Log to HA
- homeassistant.action:
action: system_log.write
data:
level: info
message: "Device ${device_name}: Button triple clicked, starting from ON. Triggering ${sensor_name} in 10s."
logger: custom.esphome
- delay: 10s
- logger.log: "Button triple clicked, starting from ON. Triggering ${sensor_name}."
- button.press: ${sensor_button}