esphome 2025.9.3__py3-none-any.whl → 2025.10.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/__main__.py +94 -31
- esphome/address_cache.py +142 -0
- esphome/automation.py +130 -32
- esphome/build_gen/platformio.py +1 -3
- esphome/codegen.py +1 -0
- esphome/components/animation/animation.cpp +2 -2
- esphome/components/api/__init__.py +166 -3
- esphome/components/api/api_connection.cpp +84 -41
- esphome/components/api/api_connection.h +22 -16
- esphome/components/api/api_frame_helper.cpp +33 -19
- esphome/components/api/api_frame_helper.h +19 -4
- esphome/components/api/api_frame_helper_noise.cpp +41 -53
- esphome/components/api/api_frame_helper_noise.h +1 -1
- esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
- esphome/components/api/api_frame_helper_plaintext.h +1 -1
- esphome/components/api/api_pb2.cpp +189 -15
- esphome/components/api/api_pb2.h +132 -20
- esphome/components/api/api_pb2_dump.cpp +97 -9
- esphome/components/api/api_pb2_service.cpp +118 -160
- esphome/components/api/api_pb2_service.h +31 -3
- esphome/components/api/api_server.cpp +68 -10
- esphome/components/api/api_server.h +32 -4
- esphome/components/api/custom_api_device.h +8 -8
- esphome/components/api/homeassistant_service.h +123 -6
- esphome/components/api/proto.h +6 -2
- esphome/components/api/user_services.h +2 -2
- esphome/components/as7341/sensor.py +1 -1
- esphome/components/audio/__init__.py +1 -1
- esphome/components/audio/audio.cpp +1 -1
- esphome/components/audio/audio_decoder.cpp +9 -9
- esphome/components/bl0906/bl0906.cpp +2 -2
- esphome/components/bl0942/bl0942.cpp +2 -2
- esphome/components/ble_client/__init__.py +1 -1
- esphome/components/bluetooth_proxy/__init__.py +4 -30
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
- esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
- esphome/components/camera_encoder/__init__.py +2 -4
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
- esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
- esphome/components/canbus/canbus.cpp +7 -5
- esphome/components/canbus/canbus.h +7 -7
- esphome/components/captive_portal/__init__.py +18 -1
- esphome/components/captive_portal/captive_portal.cpp +40 -46
- esphome/components/captive_portal/captive_portal.h +20 -22
- esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
- esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
- esphome/components/ccs811/ccs811.cpp +1 -1
- esphome/components/climate/climate.cpp +10 -7
- esphome/components/cm1106/cm1106.cpp +1 -1
- esphome/components/copy/lock/copy_lock.cpp +1 -1
- esphome/components/cover/cover.cpp +1 -0
- esphome/components/daikin_arc/daikin_arc.cpp +19 -12
- esphome/components/dashboard_import/dashboard_import.cpp +1 -1
- esphome/components/dashboard_import/dashboard_import.h +1 -1
- esphome/components/deep_sleep/__init__.py +9 -2
- esphome/components/deep_sleep/deep_sleep_component.h +11 -9
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
- esphome/components/ektf2232/touchscreen/__init__.py +8 -5
- esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
- esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
- esphome/components/epaper_spi/__init__.py +1 -0
- esphome/components/epaper_spi/display.py +80 -0
- esphome/components/epaper_spi/epaper_spi.cpp +227 -0
- esphome/components/epaper_spi/epaper_spi.h +93 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
- esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
- esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
- esphome/components/es7210/es7210.cpp +3 -3
- esphome/components/esp32/__init__.py +256 -340
- esphome/components/esp32/boards.py +81 -0
- esphome/components/esp32/preferences.cpp +23 -17
- esphome/components/esp32_ble/__init__.py +167 -44
- esphome/components/esp32_ble/ble.cpp +47 -3
- esphome/components/esp32_ble/ble.h +18 -0
- esphome/components/esp32_ble/ble_advertising.cpp +7 -3
- esphome/components/esp32_ble/ble_advertising.h +4 -0
- esphome/components/esp32_ble/ble_uuid.cpp +16 -42
- esphome/components/esp32_ble_beacon/__init__.py +3 -4
- esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +0 -4
- esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
- esphome/components/esp32_ble_server/__init__.py +28 -14
- esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
- esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
- esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
- esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
- esphome/components/esp32_ble_server/ble_server.cpp +59 -24
- esphome/components/esp32_ble_server/ble_server.h +38 -20
- esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
- esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
- esphome/components/esp32_ble_tracker/__init__.py +25 -80
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -8
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
- esphome/components/esp32_camera/__init__.py +1 -3
- esphome/components/esp32_can/esp32_can.cpp +22 -4
- esphome/components/esp32_can/esp32_can.h +3 -0
- esphome/components/esp32_hosted/__init__.py +2 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +135 -65
- esphome/components/esp32_improv/esp32_improv_component.h +7 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp8266/__init__.py +3 -3
- esphome/components/esphome/ota/__init__.py +21 -2
- esphome/components/esphome/ota/ota_esphome.cpp +456 -146
- esphome/components/esphome/ota/ota_esphome.h +49 -2
- esphome/components/ethernet/__init__.py +39 -22
- esphome/components/ethernet/ethernet_component.cpp +28 -5
- esphome/components/ethernet/ethernet_component.h +5 -1
- esphome/components/external_components/__init__.py +8 -6
- esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
- esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
- esphome/components/font/__init__.py +5 -5
- esphome/components/graph/graph.cpp +1 -1
- esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
- esphome/components/haier/hon_climate.cpp +2 -2
- esphome/components/haier/hon_climate.h +1 -1
- esphome/components/hdc1080/hdc1080.cpp +42 -34
- esphome/components/hdc1080/hdc1080.h +1 -3
- esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
- esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
- esphome/components/http_request/__init__.py +3 -3
- esphome/components/htu21d/htu21d.cpp +13 -18
- esphome/components/htu21d/htu21d.h +1 -1
- esphome/components/i2s_audio/__init__.py +1 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
- esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
- esphome/components/improv_serial/improv_serial_component.cpp +12 -15
- esphome/components/improv_serial/improv_serial_component.h +6 -8
- esphome/components/json/json_util.cpp +42 -44
- esphome/components/json/json_util.h +57 -0
- esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
- esphome/components/key_collector/key_collector.h +4 -4
- esphome/components/libretiny/__init__.py +6 -6
- esphome/components/libretiny/preferences.cpp +23 -16
- esphome/components/light/light_call.cpp +98 -120
- esphome/components/light/light_call.h +17 -7
- esphome/components/lm75b/__init__.py +0 -0
- esphome/components/lm75b/lm75b.cpp +39 -0
- esphome/components/lm75b/lm75b.h +19 -0
- esphome/components/lm75b/sensor.py +34 -0
- esphome/components/lock/lock.h +12 -6
- esphome/components/logger/__init__.py +15 -27
- esphome/components/logger/logger.cpp +10 -20
- esphome/components/logger/logger.h +105 -62
- esphome/components/logger/logger_esp32.cpp +0 -48
- esphome/components/logger/logger_zephyr.cpp +2 -3
- esphome/components/logger/select/logger_level_select.cpp +6 -7
- esphome/components/logger/select/logger_level_select.h +7 -0
- esphome/components/ltr501/ltr501.cpp +7 -6
- esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
- esphome/components/matrix_keypad/matrix_keypad.h +4 -4
- esphome/components/max7219digit/max7219digit.cpp +1 -1
- esphome/components/mcp23xxx_base/mcp23xxx_base.h +3 -3
- esphome/components/mcp2515/mcp2515.cpp +31 -3
- esphome/components/mcp2515/mcp2515_defs.h +3 -1
- esphome/components/md5/md5.cpp +0 -26
- esphome/components/md5/md5.h +10 -20
- esphome/components/mdns/__init__.py +93 -19
- esphome/components/mdns/mdns_component.cpp +57 -94
- esphome/components/mdns/mdns_component.h +35 -11
- esphome/components/mdns/mdns_esp32.cpp +7 -13
- esphome/components/mdns/mdns_esp8266.cpp +7 -7
- esphome/components/mdns/mdns_libretiny.cpp +3 -4
- esphome/components/mdns/mdns_rp2040.cpp +3 -4
- esphome/components/mipi/__init__.py +1 -5
- esphome/components/mipi_spi/display.py +24 -8
- esphome/components/mipi_spi/mipi_spi.h +3 -3
- esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
- esphome/components/mmc5603/mmc5603.cpp +3 -3
- esphome/components/modbus/modbus.cpp +27 -13
- esphome/components/modbus/modbus.h +5 -3
- esphome/components/modbus/modbus_definitions.h +86 -0
- esphome/components/modbus_controller/__init__.py +29 -1
- esphome/components/modbus_controller/const.py +4 -0
- esphome/components/modbus_controller/modbus_controller.cpp +38 -13
- esphome/components/modbus_controller/modbus_controller.h +18 -29
- esphome/components/mpr121/mpr121.cpp +41 -42
- esphome/components/mpr121/mpr121.h +0 -1
- esphome/components/nau7802/nau7802.cpp +2 -2
- esphome/components/network/__init__.py +7 -3
- esphome/components/nextion/display.py +4 -4
- esphome/components/nextion/nextion.cpp +8 -8
- esphome/components/number/__init__.py +2 -0
- esphome/components/number/number_call.cpp +23 -12
- esphome/components/number/number_call.h +5 -0
- esphome/components/online_image/bmp_image.cpp +2 -1
- esphome/components/online_image/jpeg_image.cpp +4 -2
- esphome/components/opentherm/opentherm.cpp +5 -5
- esphome/components/opentherm/opentherm.h +3 -3
- esphome/components/openthread/openthread.cpp +11 -10
- esphome/components/openthread/openthread.h +0 -1
- esphome/components/ota/ota_backend.h +1 -0
- esphome/components/packages/__init__.py +10 -8
- esphome/components/packet_transport/packet_transport.cpp +2 -0
- esphome/components/pid/pid_controller.cpp +1 -1
- esphome/components/prometheus/prometheus_handler.cpp +239 -239
- esphome/components/psram/__init__.py +30 -28
- esphome/components/qmc5883l/qmc5883l.cpp +15 -0
- esphome/components/qmc5883l/qmc5883l.h +3 -0
- esphome/components/qmc5883l/sensor.py +31 -12
- esphome/components/remote_base/gobox_protocol.cpp +3 -3
- esphome/components/remote_receiver/__init__.py +14 -2
- esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
- esphome/components/remote_receiver/remote_receiver.h +4 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
- esphome/components/remote_transmitter/__init__.py +2 -2
- esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
- esphome/components/rp2040/__init__.py +11 -11
- esphome/components/rtttl/rtttl.cpp +2 -2
- esphome/components/scd30/sensor.py +1 -1
- esphome/components/script/__init__.py +1 -1
- esphome/components/script/script.h +7 -7
- esphome/components/select/select.cpp +5 -4
- esphome/components/select/select_call.cpp +1 -1
- esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
- esphome/components/sensor/__init__.py +2 -0
- esphome/components/sha256/__init__.py +22 -0
- esphome/components/sha256/sha256.cpp +116 -0
- esphome/components/sha256/sha256.h +60 -0
- esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
- esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
- esphome/components/spi/__init__.py +0 -3
- esphome/components/split_buffer/__init__.py +5 -0
- esphome/components/split_buffer/split_buffer.cpp +133 -0
- esphome/components/split_buffer/split_buffer.h +40 -0
- esphome/components/sps30/sps30.cpp +14 -10
- esphome/components/sps30/sps30.h +2 -0
- esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
- esphome/components/st7789v/st7789v.cpp +3 -2
- esphome/components/statsd/statsd.cpp +1 -1
- esphome/components/substitutions/__init__.py +3 -1
- esphome/components/substitutions/jinja.py +13 -3
- esphome/components/sx126x/__init__.py +16 -0
- esphome/components/sx126x/sx126x.cpp +15 -1
- esphome/components/sx126x/sx126x.h +9 -1
- esphome/components/sx126x/sx126x_reg.h +2 -0
- esphome/components/text_sensor/text_sensor.cpp +16 -0
- esphome/components/text_sensor/text_sensor.h +3 -10
- esphome/components/tormatic/tormatic_cover.cpp +1 -1
- esphome/components/tuya/select/tuya_select.cpp +1 -1
- esphome/components/tuya/tuya.cpp +29 -4
- esphome/components/uart/__init__.py +37 -27
- esphome/components/uart/uart.h +6 -0
- esphome/components/uart/uart_component.cpp +8 -0
- esphome/components/uart/uart_component.h +28 -0
- esphome/components/uart/uart_component_esp_idf.cpp +64 -10
- esphome/components/uart/uart_component_esp_idf.h +5 -2
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
- esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
- esphome/components/usb_host/__init__.py +12 -2
- esphome/components/usb_host/usb_host.h +89 -14
- esphome/components/usb_host/usb_host_client.cpp +157 -22
- esphome/components/usb_host/usb_host_component.cpp +1 -1
- esphome/components/usb_uart/__init__.py +0 -1
- esphome/components/usb_uart/ch34x.cpp +4 -4
- esphome/components/usb_uart/cp210x.cpp +3 -3
- esphome/components/usb_uart/usb_uart.cpp +88 -32
- esphome/components/usb_uart/usb_uart.h +30 -6
- esphome/components/valve/valve.cpp +1 -0
- esphome/components/veml7700/veml7700.cpp +7 -6
- esphome/components/version/version_text_sensor.cpp +2 -1
- esphome/components/voice_assistant/voice_assistant.cpp +3 -2
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
- esphome/components/web_server/list_entities.cpp +3 -4
- esphome/components/web_server/list_entities.h +8 -10
- esphome/components/web_server/ota/__init__.py +1 -1
- esphome/components/web_server/ota/ota_web_server.cpp +9 -3
- esphome/components/web_server/web_server.cpp +509 -404
- esphome/components/web_server/web_server.h +5 -6
- esphome/components/web_server/web_server_v1.cpp +21 -19
- esphome/components/web_server_base/__init__.py +5 -2
- esphome/components/web_server_base/web_server_base.h +27 -7
- esphome/components/web_server_idf/__init__.py +1 -1
- esphome/components/web_server_idf/multipart.cpp +2 -2
- esphome/components/web_server_idf/multipart.h +2 -2
- esphome/components/web_server_idf/utils.cpp +2 -2
- esphome/components/web_server_idf/utils.h +2 -2
- esphome/components/web_server_idf/web_server_idf.cpp +118 -26
- esphome/components/web_server_idf/web_server_idf.h +12 -10
- esphome/components/wifi/__init__.py +13 -11
- esphome/components/wifi/wifi_component.cpp +74 -56
- esphome/components/wifi/wifi_component.h +4 -4
- esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
- esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
- esphome/components/wireguard/__init__.py +1 -1
- esphome/components/wts01/__init__.py +0 -0
- esphome/components/wts01/sensor.py +41 -0
- esphome/components/wts01/wts01.cpp +91 -0
- esphome/components/wts01/wts01.h +27 -0
- esphome/components/zephyr/__init__.py +5 -5
- esphome/components/zwave_proxy/__init__.py +43 -0
- esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
- esphome/components/zwave_proxy/zwave_proxy.h +93 -0
- esphome/config.py +79 -24
- esphome/config_validation.py +13 -15
- esphome/const.py +9 -2
- esphome/core/__init__.py +33 -22
- esphome/core/component.cpp +28 -18
- esphome/core/component_iterator.h +2 -1
- esphome/core/config.py +15 -15
- esphome/core/defines.h +21 -0
- esphome/core/entity_helpers.py +9 -6
- esphome/core/hash_base.h +56 -0
- esphome/core/helpers.cpp +19 -3
- esphome/core/helpers.h +26 -0
- esphome/core/scheduler.cpp +5 -21
- esphome/core/scheduler.h +19 -8
- esphome/core/string_ref.h +1 -1
- esphome/core/time.cpp +5 -5
- esphome/cpp_generator.py +4 -29
- esphome/dashboard/const.py +21 -4
- esphome/dashboard/core.py +10 -8
- esphome/dashboard/dns.py +15 -0
- esphome/dashboard/entries.py +15 -21
- esphome/dashboard/models.py +76 -0
- esphome/dashboard/settings.py +7 -7
- esphome/dashboard/status/mdns.py +46 -2
- esphome/dashboard/web_server.py +367 -93
- esphome/espota2.py +112 -32
- esphome/external_files.py +6 -7
- esphome/git.py +8 -0
- esphome/helpers.py +124 -77
- esphome/loader.py +8 -9
- esphome/pins.py +2 -2
- esphome/platformio_api.py +56 -18
- esphome/storage_json.py +26 -21
- esphome/types.py +30 -2
- esphome/util.py +32 -16
- esphome/vscode.py +8 -8
- esphome/wizard.py +10 -10
- esphome/writer.py +50 -15
- esphome/yaml_util.py +37 -31
- esphome/zeroconf.py +12 -3
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/METADATA +12 -12
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/RECORD +340 -320
- esphome/components/event_emitter/__init__.py +0 -5
- esphome/components/event_emitter/event_emitter.cpp +0 -14
- esphome/components/event_emitter/event_emitter.h +0 -63
- esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
- esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
- esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
- esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
- esphome/components/uart/uart_component_esp32_arduino.h +0 -60
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
- esphome/core/string_ref.cpp +0 -12
- esphome/dashboard/util/file.py +0 -63
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/WHEEL +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/top_level.txt +0 -0
@@ -1,860 +0,0 @@
|
|
1
|
-
#include "wifi_component.h"
|
2
|
-
|
3
|
-
#ifdef USE_WIFI
|
4
|
-
#ifdef USE_ESP32_FRAMEWORK_ARDUINO
|
5
|
-
|
6
|
-
#include <esp_netif.h>
|
7
|
-
#include <esp_wifi.h>
|
8
|
-
|
9
|
-
#include <algorithm>
|
10
|
-
#include <utility>
|
11
|
-
#ifdef USE_WIFI_WPA2_EAP
|
12
|
-
#include <esp_eap_client.h>
|
13
|
-
#endif
|
14
|
-
|
15
|
-
#ifdef USE_WIFI_AP
|
16
|
-
#include "dhcpserver/dhcpserver.h"
|
17
|
-
#endif // USE_WIFI_AP
|
18
|
-
|
19
|
-
#include "lwip/apps/sntp.h"
|
20
|
-
#include "lwip/dns.h"
|
21
|
-
#include "lwip/err.h"
|
22
|
-
|
23
|
-
#include "esphome/core/application.h"
|
24
|
-
#include "esphome/core/hal.h"
|
25
|
-
#include "esphome/core/helpers.h"
|
26
|
-
#include "esphome/core/log.h"
|
27
|
-
#include "esphome/core/util.h"
|
28
|
-
|
29
|
-
namespace esphome {
|
30
|
-
namespace wifi {
|
31
|
-
|
32
|
-
static const char *const TAG = "wifi_esp32";
|
33
|
-
|
34
|
-
static esp_netif_t *s_sta_netif = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
35
|
-
#ifdef USE_WIFI_AP
|
36
|
-
static esp_netif_t *s_ap_netif = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
37
|
-
#endif // USE_WIFI_AP
|
38
|
-
|
39
|
-
static bool s_sta_connecting = false; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
40
|
-
|
41
|
-
void WiFiComponent::wifi_pre_setup_() {
|
42
|
-
uint8_t mac[6];
|
43
|
-
if (has_custom_mac_address()) {
|
44
|
-
get_mac_address_raw(mac);
|
45
|
-
set_mac_address(mac);
|
46
|
-
}
|
47
|
-
auto f = std::bind(&WiFiComponent::wifi_event_callback_, this, std::placeholders::_1, std::placeholders::_2);
|
48
|
-
WiFi.onEvent(f);
|
49
|
-
WiFi.persistent(false);
|
50
|
-
// Make sure WiFi is in clean state before anything starts
|
51
|
-
this->wifi_mode_(false, false);
|
52
|
-
}
|
53
|
-
|
54
|
-
bool WiFiComponent::wifi_mode_(optional<bool> sta, optional<bool> ap) {
|
55
|
-
wifi_mode_t current_mode = WiFiClass::getMode();
|
56
|
-
bool current_sta = current_mode == WIFI_MODE_STA || current_mode == WIFI_MODE_APSTA;
|
57
|
-
bool current_ap = current_mode == WIFI_MODE_AP || current_mode == WIFI_MODE_APSTA;
|
58
|
-
|
59
|
-
bool set_sta = sta.value_or(current_sta);
|
60
|
-
bool set_ap = ap.value_or(current_ap);
|
61
|
-
|
62
|
-
wifi_mode_t set_mode;
|
63
|
-
if (set_sta && set_ap) {
|
64
|
-
set_mode = WIFI_MODE_APSTA;
|
65
|
-
} else if (set_sta && !set_ap) {
|
66
|
-
set_mode = WIFI_MODE_STA;
|
67
|
-
} else if (!set_sta && set_ap) {
|
68
|
-
set_mode = WIFI_MODE_AP;
|
69
|
-
} else {
|
70
|
-
set_mode = WIFI_MODE_NULL;
|
71
|
-
}
|
72
|
-
|
73
|
-
if (current_mode == set_mode)
|
74
|
-
return true;
|
75
|
-
|
76
|
-
if (set_sta && !current_sta) {
|
77
|
-
ESP_LOGV(TAG, "Enabling STA");
|
78
|
-
} else if (!set_sta && current_sta) {
|
79
|
-
ESP_LOGV(TAG, "Disabling STA");
|
80
|
-
}
|
81
|
-
if (set_ap && !current_ap) {
|
82
|
-
ESP_LOGV(TAG, "Enabling AP");
|
83
|
-
} else if (!set_ap && current_ap) {
|
84
|
-
ESP_LOGV(TAG, "Disabling AP");
|
85
|
-
}
|
86
|
-
|
87
|
-
bool ret = WiFiClass::mode(set_mode);
|
88
|
-
|
89
|
-
if (!ret) {
|
90
|
-
ESP_LOGW(TAG, "Setting mode failed");
|
91
|
-
return false;
|
92
|
-
}
|
93
|
-
|
94
|
-
// WiFiClass::mode above calls esp_netif_create_default_wifi_sta() and
|
95
|
-
// esp_netif_create_default_wifi_ap(), which creates the interfaces.
|
96
|
-
// s_sta_netif handle is set during ESPHOME_EVENT_ID_WIFI_STA_START event
|
97
|
-
|
98
|
-
#ifdef USE_WIFI_AP
|
99
|
-
if (set_ap)
|
100
|
-
s_ap_netif = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF");
|
101
|
-
#endif
|
102
|
-
|
103
|
-
return ret;
|
104
|
-
}
|
105
|
-
|
106
|
-
bool WiFiComponent::wifi_sta_pre_setup_() {
|
107
|
-
if (!this->wifi_mode_(true, {}))
|
108
|
-
return false;
|
109
|
-
|
110
|
-
WiFi.setAutoReconnect(false);
|
111
|
-
delay(10);
|
112
|
-
return true;
|
113
|
-
}
|
114
|
-
|
115
|
-
bool WiFiComponent::wifi_apply_output_power_(float output_power) {
|
116
|
-
int8_t val = static_cast<int8_t>(output_power * 4);
|
117
|
-
return esp_wifi_set_max_tx_power(val) == ESP_OK;
|
118
|
-
}
|
119
|
-
|
120
|
-
bool WiFiComponent::wifi_apply_power_save_() {
|
121
|
-
wifi_ps_type_t power_save;
|
122
|
-
switch (this->power_save_) {
|
123
|
-
case WIFI_POWER_SAVE_LIGHT:
|
124
|
-
power_save = WIFI_PS_MIN_MODEM;
|
125
|
-
break;
|
126
|
-
case WIFI_POWER_SAVE_HIGH:
|
127
|
-
power_save = WIFI_PS_MAX_MODEM;
|
128
|
-
break;
|
129
|
-
case WIFI_POWER_SAVE_NONE:
|
130
|
-
default:
|
131
|
-
power_save = WIFI_PS_NONE;
|
132
|
-
break;
|
133
|
-
}
|
134
|
-
return esp_wifi_set_ps(power_save) == ESP_OK;
|
135
|
-
}
|
136
|
-
|
137
|
-
bool WiFiComponent::wifi_sta_connect_(const WiFiAP &ap) {
|
138
|
-
// enable STA
|
139
|
-
if (!this->wifi_mode_(true, {}))
|
140
|
-
return false;
|
141
|
-
|
142
|
-
// https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html#_CPPv417wifi_sta_config_t
|
143
|
-
wifi_config_t conf;
|
144
|
-
memset(&conf, 0, sizeof(conf));
|
145
|
-
if (ap.get_ssid().size() > sizeof(conf.sta.ssid)) {
|
146
|
-
ESP_LOGE(TAG, "SSID too long");
|
147
|
-
return false;
|
148
|
-
}
|
149
|
-
if (ap.get_password().size() > sizeof(conf.sta.password)) {
|
150
|
-
ESP_LOGE(TAG, "Password too long");
|
151
|
-
return false;
|
152
|
-
}
|
153
|
-
memcpy(reinterpret_cast<char *>(conf.sta.ssid), ap.get_ssid().c_str(), ap.get_ssid().size());
|
154
|
-
memcpy(reinterpret_cast<char *>(conf.sta.password), ap.get_password().c_str(), ap.get_password().size());
|
155
|
-
|
156
|
-
// The weakest authmode to accept in the fast scan mode
|
157
|
-
if (ap.get_password().empty()) {
|
158
|
-
conf.sta.threshold.authmode = WIFI_AUTH_OPEN;
|
159
|
-
} else {
|
160
|
-
conf.sta.threshold.authmode = WIFI_AUTH_WPA_WPA2_PSK;
|
161
|
-
}
|
162
|
-
|
163
|
-
#ifdef USE_WIFI_WPA2_EAP
|
164
|
-
if (ap.get_eap().has_value()) {
|
165
|
-
conf.sta.threshold.authmode = WIFI_AUTH_WPA2_ENTERPRISE;
|
166
|
-
}
|
167
|
-
#endif
|
168
|
-
|
169
|
-
if (ap.get_bssid().has_value()) {
|
170
|
-
conf.sta.bssid_set = true;
|
171
|
-
memcpy(conf.sta.bssid, ap.get_bssid()->data(), 6);
|
172
|
-
} else {
|
173
|
-
conf.sta.bssid_set = false;
|
174
|
-
}
|
175
|
-
if (ap.get_channel().has_value()) {
|
176
|
-
conf.sta.channel = *ap.get_channel();
|
177
|
-
conf.sta.scan_method = WIFI_FAST_SCAN;
|
178
|
-
} else {
|
179
|
-
conf.sta.scan_method = WIFI_ALL_CHANNEL_SCAN;
|
180
|
-
}
|
181
|
-
// Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set.
|
182
|
-
// Units: AP beacon intervals. Defaults to 3 if set to 0.
|
183
|
-
conf.sta.listen_interval = 0;
|
184
|
-
|
185
|
-
// Protected Management Frame
|
186
|
-
// Device will prefer to connect in PMF mode if other device also advertises PMF capability.
|
187
|
-
conf.sta.pmf_cfg.capable = true;
|
188
|
-
conf.sta.pmf_cfg.required = false;
|
189
|
-
|
190
|
-
// note, we do our own filtering
|
191
|
-
// The minimum rssi to accept in the fast scan mode
|
192
|
-
conf.sta.threshold.rssi = -127;
|
193
|
-
|
194
|
-
conf.sta.threshold.authmode = WIFI_AUTH_OPEN;
|
195
|
-
|
196
|
-
wifi_config_t current_conf;
|
197
|
-
esp_err_t err;
|
198
|
-
err = esp_wifi_get_config(WIFI_IF_STA, ¤t_conf);
|
199
|
-
if (err != ERR_OK) {
|
200
|
-
ESP_LOGW(TAG, "esp_wifi_get_config failed: %s", esp_err_to_name(err));
|
201
|
-
// can continue
|
202
|
-
}
|
203
|
-
|
204
|
-
if (memcmp(¤t_conf, &conf, sizeof(wifi_config_t)) != 0) { // NOLINT
|
205
|
-
err = esp_wifi_disconnect();
|
206
|
-
if (err != ESP_OK) {
|
207
|
-
ESP_LOGV(TAG, "esp_wifi_disconnect failed: %s", esp_err_to_name(err));
|
208
|
-
return false;
|
209
|
-
}
|
210
|
-
}
|
211
|
-
|
212
|
-
err = esp_wifi_set_config(WIFI_IF_STA, &conf);
|
213
|
-
if (err != ESP_OK) {
|
214
|
-
ESP_LOGV(TAG, "esp_wifi_set_config failed: %s", esp_err_to_name(err));
|
215
|
-
return false;
|
216
|
-
}
|
217
|
-
|
218
|
-
if (!this->wifi_sta_ip_config_(ap.get_manual_ip())) {
|
219
|
-
return false;
|
220
|
-
}
|
221
|
-
|
222
|
-
// setup enterprise authentication if required
|
223
|
-
#ifdef USE_WIFI_WPA2_EAP
|
224
|
-
if (ap.get_eap().has_value()) {
|
225
|
-
// note: all certificates and keys have to be null terminated. Lengths are appended by +1 to include \0.
|
226
|
-
EAPAuth eap = ap.get_eap().value();
|
227
|
-
err = esp_eap_client_set_identity((uint8_t *) eap.identity.c_str(), eap.identity.length());
|
228
|
-
if (err != ESP_OK) {
|
229
|
-
ESP_LOGV(TAG, "esp_eap_client_set_identity failed: %d", err);
|
230
|
-
}
|
231
|
-
int ca_cert_len = strlen(eap.ca_cert);
|
232
|
-
int client_cert_len = strlen(eap.client_cert);
|
233
|
-
int client_key_len = strlen(eap.client_key);
|
234
|
-
if (ca_cert_len) {
|
235
|
-
err = esp_eap_client_set_ca_cert((uint8_t *) eap.ca_cert, ca_cert_len + 1);
|
236
|
-
if (err != ESP_OK) {
|
237
|
-
ESP_LOGV(TAG, "esp_eap_client_set_ca_cert failed: %d", err);
|
238
|
-
}
|
239
|
-
}
|
240
|
-
// workout what type of EAP this is
|
241
|
-
// validation is not required as the config tool has already validated it
|
242
|
-
if (client_cert_len && client_key_len) {
|
243
|
-
// if we have certs, this must be EAP-TLS
|
244
|
-
err = esp_eap_client_set_certificate_and_key((uint8_t *) eap.client_cert, client_cert_len + 1,
|
245
|
-
(uint8_t *) eap.client_key, client_key_len + 1,
|
246
|
-
(uint8_t *) eap.password.c_str(), strlen(eap.password.c_str()));
|
247
|
-
if (err != ESP_OK) {
|
248
|
-
ESP_LOGV(TAG, "esp_eap_client_set_certificate_and_key failed: %d", err);
|
249
|
-
}
|
250
|
-
} else {
|
251
|
-
// in the absence of certs, assume this is username/password based
|
252
|
-
err = esp_eap_client_set_username((uint8_t *) eap.username.c_str(), eap.username.length());
|
253
|
-
if (err != ESP_OK) {
|
254
|
-
ESP_LOGV(TAG, "esp_eap_client_set_username failed: %d", err);
|
255
|
-
}
|
256
|
-
err = esp_eap_client_set_password((uint8_t *) eap.password.c_str(), eap.password.length());
|
257
|
-
if (err != ESP_OK) {
|
258
|
-
ESP_LOGV(TAG, "esp_eap_client_set_password failed: %d", err);
|
259
|
-
}
|
260
|
-
}
|
261
|
-
err = esp_wifi_sta_enterprise_enable();
|
262
|
-
if (err != ESP_OK) {
|
263
|
-
ESP_LOGV(TAG, "esp_wifi_sta_enterprise_enable failed: %d", err);
|
264
|
-
}
|
265
|
-
}
|
266
|
-
#endif // USE_WIFI_WPA2_EAP
|
267
|
-
|
268
|
-
this->wifi_apply_hostname_();
|
269
|
-
|
270
|
-
s_sta_connecting = true;
|
271
|
-
|
272
|
-
err = esp_wifi_connect();
|
273
|
-
if (err != ESP_OK) {
|
274
|
-
ESP_LOGW(TAG, "esp_wifi_connect failed: %s", esp_err_to_name(err));
|
275
|
-
return false;
|
276
|
-
}
|
277
|
-
|
278
|
-
return true;
|
279
|
-
}
|
280
|
-
|
281
|
-
bool WiFiComponent::wifi_sta_ip_config_(optional<ManualIP> manual_ip) {
|
282
|
-
// enable STA
|
283
|
-
if (!this->wifi_mode_(true, {}))
|
284
|
-
return false;
|
285
|
-
|
286
|
-
// Check if the STA interface is initialized before using it
|
287
|
-
if (s_sta_netif == nullptr) {
|
288
|
-
ESP_LOGW(TAG, "STA interface not initialized");
|
289
|
-
return false;
|
290
|
-
}
|
291
|
-
|
292
|
-
esp_netif_dhcp_status_t dhcp_status;
|
293
|
-
esp_err_t err = esp_netif_dhcpc_get_status(s_sta_netif, &dhcp_status);
|
294
|
-
if (err != ESP_OK) {
|
295
|
-
ESP_LOGV(TAG, "esp_netif_dhcpc_get_status failed: %s", esp_err_to_name(err));
|
296
|
-
return false;
|
297
|
-
}
|
298
|
-
|
299
|
-
if (!manual_ip.has_value()) {
|
300
|
-
// sntp_servermode_dhcp lwip/sntp.c (Required to lock TCPIP core functionality!)
|
301
|
-
// https://github.com/esphome/issues/issues/6591
|
302
|
-
// https://github.com/espressif/arduino-esp32/issues/10526
|
303
|
-
{
|
304
|
-
LwIPLock lock;
|
305
|
-
// lwIP starts the SNTP client if it gets an SNTP server from DHCP. We don't need the time, and more importantly,
|
306
|
-
// the built-in SNTP client has a memory leak in certain situations. Disable this feature.
|
307
|
-
// https://github.com/esphome/issues/issues/2299
|
308
|
-
sntp_servermode_dhcp(false);
|
309
|
-
}
|
310
|
-
|
311
|
-
// No manual IP is set; use DHCP client
|
312
|
-
if (dhcp_status != ESP_NETIF_DHCP_STARTED) {
|
313
|
-
err = esp_netif_dhcpc_start(s_sta_netif);
|
314
|
-
if (err != ESP_OK) {
|
315
|
-
ESP_LOGV(TAG, "Starting DHCP client failed: %d", err);
|
316
|
-
}
|
317
|
-
return err == ESP_OK;
|
318
|
-
}
|
319
|
-
return true;
|
320
|
-
}
|
321
|
-
|
322
|
-
esp_netif_ip_info_t info; // struct of ip4_addr_t with ip, netmask, gw
|
323
|
-
info.ip = manual_ip->static_ip;
|
324
|
-
info.gw = manual_ip->gateway;
|
325
|
-
info.netmask = manual_ip->subnet;
|
326
|
-
err = esp_netif_dhcpc_stop(s_sta_netif);
|
327
|
-
if (err != ESP_OK && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED) {
|
328
|
-
ESP_LOGV(TAG, "Stopping DHCP client failed: %s", esp_err_to_name(err));
|
329
|
-
}
|
330
|
-
|
331
|
-
err = esp_netif_set_ip_info(s_sta_netif, &info);
|
332
|
-
if (err != ESP_OK) {
|
333
|
-
ESP_LOGV(TAG, "Setting manual IP info failed: %s", esp_err_to_name(err));
|
334
|
-
}
|
335
|
-
|
336
|
-
esp_netif_dns_info_t dns;
|
337
|
-
if (manual_ip->dns1.is_set()) {
|
338
|
-
dns.ip = manual_ip->dns1;
|
339
|
-
esp_netif_set_dns_info(s_sta_netif, ESP_NETIF_DNS_MAIN, &dns);
|
340
|
-
}
|
341
|
-
if (manual_ip->dns2.is_set()) {
|
342
|
-
dns.ip = manual_ip->dns2;
|
343
|
-
esp_netif_set_dns_info(s_sta_netif, ESP_NETIF_DNS_BACKUP, &dns);
|
344
|
-
}
|
345
|
-
|
346
|
-
return true;
|
347
|
-
}
|
348
|
-
|
349
|
-
network::IPAddresses WiFiComponent::wifi_sta_ip_addresses() {
|
350
|
-
if (!this->has_sta())
|
351
|
-
return {};
|
352
|
-
network::IPAddresses addresses;
|
353
|
-
esp_netif_ip_info_t ip;
|
354
|
-
esp_err_t err = esp_netif_get_ip_info(s_sta_netif, &ip);
|
355
|
-
if (err != ESP_OK) {
|
356
|
-
ESP_LOGV(TAG, "esp_netif_get_ip_info failed: %s", esp_err_to_name(err));
|
357
|
-
// TODO: do something smarter
|
358
|
-
// return false;
|
359
|
-
} else {
|
360
|
-
addresses[0] = network::IPAddress(&ip.ip);
|
361
|
-
}
|
362
|
-
#if USE_NETWORK_IPV6
|
363
|
-
struct esp_ip6_addr if_ip6s[CONFIG_LWIP_IPV6_NUM_ADDRESSES];
|
364
|
-
uint8_t count = 0;
|
365
|
-
count = esp_netif_get_all_ip6(s_sta_netif, if_ip6s);
|
366
|
-
assert(count <= CONFIG_LWIP_IPV6_NUM_ADDRESSES);
|
367
|
-
for (int i = 0; i < count; i++) {
|
368
|
-
addresses[i + 1] = network::IPAddress(&if_ip6s[i]);
|
369
|
-
}
|
370
|
-
#endif /* USE_NETWORK_IPV6 */
|
371
|
-
return addresses;
|
372
|
-
}
|
373
|
-
|
374
|
-
bool WiFiComponent::wifi_apply_hostname_() {
|
375
|
-
// setting is done in SYSTEM_EVENT_STA_START callback
|
376
|
-
return true;
|
377
|
-
}
|
378
|
-
const char *get_auth_mode_str(uint8_t mode) {
|
379
|
-
switch (mode) {
|
380
|
-
case WIFI_AUTH_OPEN:
|
381
|
-
return "OPEN";
|
382
|
-
case WIFI_AUTH_WEP:
|
383
|
-
return "WEP";
|
384
|
-
case WIFI_AUTH_WPA_PSK:
|
385
|
-
return "WPA PSK";
|
386
|
-
case WIFI_AUTH_WPA2_PSK:
|
387
|
-
return "WPA2 PSK";
|
388
|
-
case WIFI_AUTH_WPA_WPA2_PSK:
|
389
|
-
return "WPA/WPA2 PSK";
|
390
|
-
case WIFI_AUTH_WPA2_ENTERPRISE:
|
391
|
-
return "WPA2 Enterprise";
|
392
|
-
case WIFI_AUTH_WPA3_PSK:
|
393
|
-
return "WPA3 PSK";
|
394
|
-
case WIFI_AUTH_WPA2_WPA3_PSK:
|
395
|
-
return "WPA2/WPA3 PSK";
|
396
|
-
case WIFI_AUTH_WAPI_PSK:
|
397
|
-
return "WAPI PSK";
|
398
|
-
default:
|
399
|
-
return "UNKNOWN";
|
400
|
-
}
|
401
|
-
}
|
402
|
-
|
403
|
-
using esphome_ip4_addr_t = esp_ip4_addr_t;
|
404
|
-
|
405
|
-
std::string format_ip4_addr(const esphome_ip4_addr_t &ip) {
|
406
|
-
char buf[20];
|
407
|
-
sprintf(buf, "%u.%u.%u.%u", uint8_t(ip.addr >> 0), uint8_t(ip.addr >> 8), uint8_t(ip.addr >> 16),
|
408
|
-
uint8_t(ip.addr >> 24));
|
409
|
-
return buf;
|
410
|
-
}
|
411
|
-
const char *get_op_mode_str(uint8_t mode) {
|
412
|
-
switch (mode) {
|
413
|
-
case WIFI_OFF:
|
414
|
-
return "OFF";
|
415
|
-
case WIFI_STA:
|
416
|
-
return "STA";
|
417
|
-
case WIFI_AP:
|
418
|
-
return "AP";
|
419
|
-
case WIFI_AP_STA:
|
420
|
-
return "AP+STA";
|
421
|
-
default:
|
422
|
-
return "UNKNOWN";
|
423
|
-
}
|
424
|
-
}
|
425
|
-
const char *get_disconnect_reason_str(uint8_t reason) {
|
426
|
-
switch (reason) {
|
427
|
-
case WIFI_REASON_AUTH_EXPIRE:
|
428
|
-
return "Auth Expired";
|
429
|
-
case WIFI_REASON_AUTH_LEAVE:
|
430
|
-
return "Auth Leave";
|
431
|
-
case WIFI_REASON_ASSOC_EXPIRE:
|
432
|
-
return "Association Expired";
|
433
|
-
case WIFI_REASON_ASSOC_TOOMANY:
|
434
|
-
return "Too Many Associations";
|
435
|
-
case WIFI_REASON_NOT_AUTHED:
|
436
|
-
return "Not Authenticated";
|
437
|
-
case WIFI_REASON_NOT_ASSOCED:
|
438
|
-
return "Not Associated";
|
439
|
-
case WIFI_REASON_ASSOC_LEAVE:
|
440
|
-
return "Association Leave";
|
441
|
-
case WIFI_REASON_ASSOC_NOT_AUTHED:
|
442
|
-
return "Association not Authenticated";
|
443
|
-
case WIFI_REASON_DISASSOC_PWRCAP_BAD:
|
444
|
-
return "Disassociate Power Cap Bad";
|
445
|
-
case WIFI_REASON_DISASSOC_SUPCHAN_BAD:
|
446
|
-
return "Disassociate Supported Channel Bad";
|
447
|
-
case WIFI_REASON_IE_INVALID:
|
448
|
-
return "IE Invalid";
|
449
|
-
case WIFI_REASON_MIC_FAILURE:
|
450
|
-
return "Mic Failure";
|
451
|
-
case WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT:
|
452
|
-
return "4-Way Handshake Timeout";
|
453
|
-
case WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT:
|
454
|
-
return "Group Key Update Timeout";
|
455
|
-
case WIFI_REASON_IE_IN_4WAY_DIFFERS:
|
456
|
-
return "IE In 4-Way Handshake Differs";
|
457
|
-
case WIFI_REASON_GROUP_CIPHER_INVALID:
|
458
|
-
return "Group Cipher Invalid";
|
459
|
-
case WIFI_REASON_PAIRWISE_CIPHER_INVALID:
|
460
|
-
return "Pairwise Cipher Invalid";
|
461
|
-
case WIFI_REASON_AKMP_INVALID:
|
462
|
-
return "AKMP Invalid";
|
463
|
-
case WIFI_REASON_UNSUPP_RSN_IE_VERSION:
|
464
|
-
return "Unsupported RSN IE version";
|
465
|
-
case WIFI_REASON_INVALID_RSN_IE_CAP:
|
466
|
-
return "Invalid RSN IE Cap";
|
467
|
-
case WIFI_REASON_802_1X_AUTH_FAILED:
|
468
|
-
return "802.1x Authentication Failed";
|
469
|
-
case WIFI_REASON_CIPHER_SUITE_REJECTED:
|
470
|
-
return "Cipher Suite Rejected";
|
471
|
-
case WIFI_REASON_BEACON_TIMEOUT:
|
472
|
-
return "Beacon Timeout";
|
473
|
-
case WIFI_REASON_NO_AP_FOUND:
|
474
|
-
return "AP Not Found";
|
475
|
-
case WIFI_REASON_AUTH_FAIL:
|
476
|
-
return "Authentication Failed";
|
477
|
-
case WIFI_REASON_ASSOC_FAIL:
|
478
|
-
return "Association Failed";
|
479
|
-
case WIFI_REASON_HANDSHAKE_TIMEOUT:
|
480
|
-
return "Handshake Failed";
|
481
|
-
case WIFI_REASON_CONNECTION_FAIL:
|
482
|
-
return "Connection Failed";
|
483
|
-
case WIFI_REASON_AP_TSF_RESET:
|
484
|
-
return "AP TSF reset";
|
485
|
-
case WIFI_REASON_ROAMING:
|
486
|
-
return "Station Roaming";
|
487
|
-
case WIFI_REASON_ASSOC_COMEBACK_TIME_TOO_LONG:
|
488
|
-
return "Association comeback time too long";
|
489
|
-
case WIFI_REASON_SA_QUERY_TIMEOUT:
|
490
|
-
return "SA query timeout";
|
491
|
-
case WIFI_REASON_NO_AP_FOUND_W_COMPATIBLE_SECURITY:
|
492
|
-
return "No AP found with compatible security";
|
493
|
-
case WIFI_REASON_NO_AP_FOUND_IN_AUTHMODE_THRESHOLD:
|
494
|
-
return "No AP found in auth mode threshold";
|
495
|
-
case WIFI_REASON_NO_AP_FOUND_IN_RSSI_THRESHOLD:
|
496
|
-
return "No AP found in RSSI threshold";
|
497
|
-
case WIFI_REASON_UNSPECIFIED:
|
498
|
-
default:
|
499
|
-
return "Unspecified";
|
500
|
-
}
|
501
|
-
}
|
502
|
-
|
503
|
-
void WiFiComponent::wifi_loop_() {}
|
504
|
-
|
505
|
-
#define ESPHOME_EVENT_ID_WIFI_READY ARDUINO_EVENT_WIFI_READY
|
506
|
-
#define ESPHOME_EVENT_ID_WIFI_SCAN_DONE ARDUINO_EVENT_WIFI_SCAN_DONE
|
507
|
-
#define ESPHOME_EVENT_ID_WIFI_STA_START ARDUINO_EVENT_WIFI_STA_START
|
508
|
-
#define ESPHOME_EVENT_ID_WIFI_STA_STOP ARDUINO_EVENT_WIFI_STA_STOP
|
509
|
-
#define ESPHOME_EVENT_ID_WIFI_STA_CONNECTED ARDUINO_EVENT_WIFI_STA_CONNECTED
|
510
|
-
#define ESPHOME_EVENT_ID_WIFI_STA_DISCONNECTED ARDUINO_EVENT_WIFI_STA_DISCONNECTED
|
511
|
-
#define ESPHOME_EVENT_ID_WIFI_STA_AUTHMODE_CHANGE ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE
|
512
|
-
#define ESPHOME_EVENT_ID_WIFI_STA_GOT_IP ARDUINO_EVENT_WIFI_STA_GOT_IP
|
513
|
-
#define ESPHOME_EVENT_ID_WIFI_STA_GOT_IP6 ARDUINO_EVENT_WIFI_STA_GOT_IP6
|
514
|
-
#define ESPHOME_EVENT_ID_WIFI_STA_LOST_IP ARDUINO_EVENT_WIFI_STA_LOST_IP
|
515
|
-
#define ESPHOME_EVENT_ID_WIFI_AP_START ARDUINO_EVENT_WIFI_AP_START
|
516
|
-
#define ESPHOME_EVENT_ID_WIFI_AP_STOP ARDUINO_EVENT_WIFI_AP_STOP
|
517
|
-
#define ESPHOME_EVENT_ID_WIFI_AP_STACONNECTED ARDUINO_EVENT_WIFI_AP_STACONNECTED
|
518
|
-
#define ESPHOME_EVENT_ID_WIFI_AP_STADISCONNECTED ARDUINO_EVENT_WIFI_AP_STADISCONNECTED
|
519
|
-
#define ESPHOME_EVENT_ID_WIFI_AP_STAIPASSIGNED ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED
|
520
|
-
#define ESPHOME_EVENT_ID_WIFI_AP_PROBEREQRECVED ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED
|
521
|
-
#define ESPHOME_EVENT_ID_WIFI_AP_GOT_IP6 ARDUINO_EVENT_WIFI_AP_GOT_IP6
|
522
|
-
using esphome_wifi_event_id_t = arduino_event_id_t;
|
523
|
-
using esphome_wifi_event_info_t = arduino_event_info_t;
|
524
|
-
|
525
|
-
void WiFiComponent::wifi_event_callback_(esphome_wifi_event_id_t event, esphome_wifi_event_info_t info) {
|
526
|
-
switch (event) {
|
527
|
-
case ESPHOME_EVENT_ID_WIFI_READY: {
|
528
|
-
ESP_LOGV(TAG, "Ready");
|
529
|
-
break;
|
530
|
-
}
|
531
|
-
case ESPHOME_EVENT_ID_WIFI_SCAN_DONE: {
|
532
|
-
auto it = info.wifi_scan_done;
|
533
|
-
ESP_LOGV(TAG, "Scan done: status=%u number=%u scan_id=%u", it.status, it.number, it.scan_id);
|
534
|
-
|
535
|
-
this->wifi_scan_done_callback_();
|
536
|
-
break;
|
537
|
-
}
|
538
|
-
case ESPHOME_EVENT_ID_WIFI_STA_START: {
|
539
|
-
ESP_LOGV(TAG, "STA start");
|
540
|
-
// apply hostname
|
541
|
-
s_sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
|
542
|
-
esp_err_t err = esp_netif_set_hostname(s_sta_netif, App.get_name().c_str());
|
543
|
-
if (err != ERR_OK) {
|
544
|
-
ESP_LOGW(TAG, "esp_netif_set_hostname failed: %s", esp_err_to_name(err));
|
545
|
-
}
|
546
|
-
break;
|
547
|
-
}
|
548
|
-
case ESPHOME_EVENT_ID_WIFI_STA_STOP: {
|
549
|
-
ESP_LOGV(TAG, "STA stop");
|
550
|
-
break;
|
551
|
-
}
|
552
|
-
case ESPHOME_EVENT_ID_WIFI_STA_CONNECTED: {
|
553
|
-
auto it = info.wifi_sta_connected;
|
554
|
-
char buf[33];
|
555
|
-
memcpy(buf, it.ssid, it.ssid_len);
|
556
|
-
buf[it.ssid_len] = '\0';
|
557
|
-
ESP_LOGV(TAG, "Connected ssid='%s' bssid=" LOG_SECRET("%s") " channel=%u, authmode=%s", buf,
|
558
|
-
format_mac_address_pretty(it.bssid).c_str(), it.channel, get_auth_mode_str(it.authmode));
|
559
|
-
#if USE_NETWORK_IPV6
|
560
|
-
this->set_timeout(100, [] { WiFi.enableIPv6(); });
|
561
|
-
#endif /* USE_NETWORK_IPV6 */
|
562
|
-
|
563
|
-
break;
|
564
|
-
}
|
565
|
-
case ESPHOME_EVENT_ID_WIFI_STA_DISCONNECTED: {
|
566
|
-
auto it = info.wifi_sta_disconnected;
|
567
|
-
char buf[33];
|
568
|
-
memcpy(buf, it.ssid, it.ssid_len);
|
569
|
-
buf[it.ssid_len] = '\0';
|
570
|
-
if (it.reason == WIFI_REASON_NO_AP_FOUND) {
|
571
|
-
ESP_LOGW(TAG, "Disconnected ssid='%s' reason='Probe Request Unsuccessful'", buf);
|
572
|
-
} else {
|
573
|
-
ESP_LOGW(TAG, "Disconnected ssid='%s' bssid=" LOG_SECRET("%s") " reason='%s'", buf,
|
574
|
-
format_mac_address_pretty(it.bssid).c_str(), get_disconnect_reason_str(it.reason));
|
575
|
-
}
|
576
|
-
|
577
|
-
uint8_t reason = it.reason;
|
578
|
-
if (reason == WIFI_REASON_AUTH_EXPIRE || reason == WIFI_REASON_BEACON_TIMEOUT ||
|
579
|
-
reason == WIFI_REASON_NO_AP_FOUND || reason == WIFI_REASON_ASSOC_FAIL ||
|
580
|
-
reason == WIFI_REASON_HANDSHAKE_TIMEOUT) {
|
581
|
-
err_t err = esp_wifi_disconnect();
|
582
|
-
if (err != ESP_OK) {
|
583
|
-
ESP_LOGV(TAG, "Disconnect failed: %s", esp_err_to_name(err));
|
584
|
-
}
|
585
|
-
this->error_from_callback_ = true;
|
586
|
-
}
|
587
|
-
|
588
|
-
s_sta_connecting = false;
|
589
|
-
break;
|
590
|
-
}
|
591
|
-
case ESPHOME_EVENT_ID_WIFI_STA_AUTHMODE_CHANGE: {
|
592
|
-
auto it = info.wifi_sta_authmode_change;
|
593
|
-
ESP_LOGV(TAG, "Authmode Change old=%s new=%s", get_auth_mode_str(it.old_mode), get_auth_mode_str(it.new_mode));
|
594
|
-
// Mitigate CVE-2020-12638
|
595
|
-
// https://lbsfilm.at/blog/wpa2-authenticationmode-downgrade-in-espressif-microprocessors
|
596
|
-
if (it.old_mode != WIFI_AUTH_OPEN && it.new_mode == WIFI_AUTH_OPEN) {
|
597
|
-
ESP_LOGW(TAG, "Potential Authmode downgrade detected, disconnecting");
|
598
|
-
// we can't call retry_connect() from this context, so disconnect immediately
|
599
|
-
// and notify main thread with error_from_callback_
|
600
|
-
err_t err = esp_wifi_disconnect();
|
601
|
-
if (err != ESP_OK) {
|
602
|
-
ESP_LOGW(TAG, "Disconnect failed: %s", esp_err_to_name(err));
|
603
|
-
}
|
604
|
-
this->error_from_callback_ = true;
|
605
|
-
}
|
606
|
-
break;
|
607
|
-
}
|
608
|
-
case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP: {
|
609
|
-
auto it = info.got_ip.ip_info;
|
610
|
-
ESP_LOGV(TAG, "static_ip=%s gateway=%s", format_ip4_addr(it.ip).c_str(), format_ip4_addr(it.gw).c_str());
|
611
|
-
this->got_ipv4_address_ = true;
|
612
|
-
#if USE_NETWORK_IPV6
|
613
|
-
s_sta_connecting = this->num_ipv6_addresses_ < USE_NETWORK_MIN_IPV6_ADDR_COUNT;
|
614
|
-
#else
|
615
|
-
s_sta_connecting = false;
|
616
|
-
#endif /* USE_NETWORK_IPV6 */
|
617
|
-
break;
|
618
|
-
}
|
619
|
-
#if USE_NETWORK_IPV6
|
620
|
-
case ESPHOME_EVENT_ID_WIFI_STA_GOT_IP6: {
|
621
|
-
auto it = info.got_ip6.ip6_info;
|
622
|
-
ESP_LOGV(TAG, "IPv6 address=" IPV6STR, IPV62STR(it.ip));
|
623
|
-
this->num_ipv6_addresses_++;
|
624
|
-
s_sta_connecting = !(this->got_ipv4_address_ & (this->num_ipv6_addresses_ >= USE_NETWORK_MIN_IPV6_ADDR_COUNT));
|
625
|
-
break;
|
626
|
-
}
|
627
|
-
#endif /* USE_NETWORK_IPV6 */
|
628
|
-
case ESPHOME_EVENT_ID_WIFI_STA_LOST_IP: {
|
629
|
-
ESP_LOGV(TAG, "Lost IP");
|
630
|
-
this->got_ipv4_address_ = false;
|
631
|
-
break;
|
632
|
-
}
|
633
|
-
case ESPHOME_EVENT_ID_WIFI_AP_START: {
|
634
|
-
ESP_LOGV(TAG, "AP start");
|
635
|
-
break;
|
636
|
-
}
|
637
|
-
case ESPHOME_EVENT_ID_WIFI_AP_STOP: {
|
638
|
-
ESP_LOGV(TAG, "AP stop");
|
639
|
-
break;
|
640
|
-
}
|
641
|
-
case ESPHOME_EVENT_ID_WIFI_AP_STACONNECTED: {
|
642
|
-
auto it = info.wifi_sta_connected;
|
643
|
-
auto &mac = it.bssid;
|
644
|
-
ESP_LOGV(TAG, "AP client connected MAC=%s", format_mac_address_pretty(mac).c_str());
|
645
|
-
break;
|
646
|
-
}
|
647
|
-
case ESPHOME_EVENT_ID_WIFI_AP_STADISCONNECTED: {
|
648
|
-
auto it = info.wifi_sta_disconnected;
|
649
|
-
auto &mac = it.bssid;
|
650
|
-
ESP_LOGV(TAG, "AP client disconnected MAC=%s", format_mac_address_pretty(mac).c_str());
|
651
|
-
break;
|
652
|
-
}
|
653
|
-
case ESPHOME_EVENT_ID_WIFI_AP_STAIPASSIGNED: {
|
654
|
-
ESP_LOGV(TAG, "AP client assigned IP");
|
655
|
-
break;
|
656
|
-
}
|
657
|
-
case ESPHOME_EVENT_ID_WIFI_AP_PROBEREQRECVED: {
|
658
|
-
auto it = info.wifi_ap_probereqrecved;
|
659
|
-
ESP_LOGVV(TAG, "AP receive Probe Request MAC=%s RSSI=%d", format_mac_address_pretty(it.mac).c_str(), it.rssi);
|
660
|
-
break;
|
661
|
-
}
|
662
|
-
default:
|
663
|
-
break;
|
664
|
-
}
|
665
|
-
}
|
666
|
-
|
667
|
-
WiFiSTAConnectStatus WiFiComponent::wifi_sta_connect_status_() {
|
668
|
-
const auto status = WiFi.status();
|
669
|
-
if (status == WL_CONNECT_FAILED || status == WL_CONNECTION_LOST) {
|
670
|
-
return WiFiSTAConnectStatus::ERROR_CONNECT_FAILED;
|
671
|
-
}
|
672
|
-
if (status == WL_NO_SSID_AVAIL) {
|
673
|
-
return WiFiSTAConnectStatus::ERROR_NETWORK_NOT_FOUND;
|
674
|
-
}
|
675
|
-
if (s_sta_connecting) {
|
676
|
-
return WiFiSTAConnectStatus::CONNECTING;
|
677
|
-
}
|
678
|
-
if (status == WL_CONNECTED) {
|
679
|
-
return WiFiSTAConnectStatus::CONNECTED;
|
680
|
-
}
|
681
|
-
return WiFiSTAConnectStatus::IDLE;
|
682
|
-
}
|
683
|
-
bool WiFiComponent::wifi_scan_start_(bool passive) {
|
684
|
-
// enable STA
|
685
|
-
if (!this->wifi_mode_(true, {}))
|
686
|
-
return false;
|
687
|
-
|
688
|
-
// need to use WiFi because of WiFiScanClass allocations :(
|
689
|
-
int16_t err = WiFi.scanNetworks(true, true, passive, 200);
|
690
|
-
if (err != WIFI_SCAN_RUNNING) {
|
691
|
-
ESP_LOGV(TAG, "WiFi.scanNetworks failed: %d", err);
|
692
|
-
return false;
|
693
|
-
}
|
694
|
-
|
695
|
-
return true;
|
696
|
-
}
|
697
|
-
void WiFiComponent::wifi_scan_done_callback_() {
|
698
|
-
this->scan_result_.clear();
|
699
|
-
|
700
|
-
int16_t num = WiFi.scanComplete();
|
701
|
-
if (num < 0)
|
702
|
-
return;
|
703
|
-
|
704
|
-
this->scan_result_.reserve(static_cast<unsigned int>(num));
|
705
|
-
for (int i = 0; i < num; i++) {
|
706
|
-
String ssid = WiFi.SSID(i);
|
707
|
-
wifi_auth_mode_t authmode = WiFi.encryptionType(i);
|
708
|
-
int32_t rssi = WiFi.RSSI(i);
|
709
|
-
uint8_t *bssid = WiFi.BSSID(i);
|
710
|
-
int32_t channel = WiFi.channel(i);
|
711
|
-
|
712
|
-
WiFiScanResult scan({bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]}, std::string(ssid.c_str()),
|
713
|
-
channel, rssi, authmode != WIFI_AUTH_OPEN, ssid.length() == 0);
|
714
|
-
this->scan_result_.push_back(scan);
|
715
|
-
}
|
716
|
-
WiFi.scanDelete();
|
717
|
-
this->scan_done_ = true;
|
718
|
-
}
|
719
|
-
|
720
|
-
#ifdef USE_WIFI_AP
|
721
|
-
bool WiFiComponent::wifi_ap_ip_config_(optional<ManualIP> manual_ip) {
|
722
|
-
esp_err_t err;
|
723
|
-
|
724
|
-
// enable AP
|
725
|
-
if (!this->wifi_mode_({}, true))
|
726
|
-
return false;
|
727
|
-
|
728
|
-
// Check if the AP interface is initialized before using it
|
729
|
-
if (s_ap_netif == nullptr) {
|
730
|
-
ESP_LOGW(TAG, "AP interface not initialized");
|
731
|
-
return false;
|
732
|
-
}
|
733
|
-
|
734
|
-
esp_netif_ip_info_t info;
|
735
|
-
if (manual_ip.has_value()) {
|
736
|
-
info.ip = manual_ip->static_ip;
|
737
|
-
info.gw = manual_ip->gateway;
|
738
|
-
info.netmask = manual_ip->subnet;
|
739
|
-
} else {
|
740
|
-
info.ip = network::IPAddress(192, 168, 4, 1);
|
741
|
-
info.gw = network::IPAddress(192, 168, 4, 1);
|
742
|
-
info.netmask = network::IPAddress(255, 255, 255, 0);
|
743
|
-
}
|
744
|
-
|
745
|
-
err = esp_netif_dhcps_stop(s_ap_netif);
|
746
|
-
if (err != ESP_OK && err != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED) {
|
747
|
-
ESP_LOGE(TAG, "esp_netif_dhcps_stop failed: %s", esp_err_to_name(err));
|
748
|
-
return false;
|
749
|
-
}
|
750
|
-
|
751
|
-
err = esp_netif_set_ip_info(s_ap_netif, &info);
|
752
|
-
if (err != ESP_OK) {
|
753
|
-
ESP_LOGE(TAG, "esp_netif_set_ip_info failed: %d", err);
|
754
|
-
return false;
|
755
|
-
}
|
756
|
-
|
757
|
-
dhcps_lease_t lease;
|
758
|
-
lease.enable = true;
|
759
|
-
network::IPAddress start_address = network::IPAddress(&info.ip);
|
760
|
-
start_address += 99;
|
761
|
-
lease.start_ip = start_address;
|
762
|
-
ESP_LOGV(TAG, "DHCP server IP lease start: %s", start_address.str().c_str());
|
763
|
-
start_address += 10;
|
764
|
-
lease.end_ip = start_address;
|
765
|
-
ESP_LOGV(TAG, "DHCP server IP lease end: %s", start_address.str().c_str());
|
766
|
-
err = esp_netif_dhcps_option(s_ap_netif, ESP_NETIF_OP_SET, ESP_NETIF_REQUESTED_IP_ADDRESS, &lease, sizeof(lease));
|
767
|
-
|
768
|
-
if (err != ESP_OK) {
|
769
|
-
ESP_LOGE(TAG, "esp_netif_dhcps_option failed: %d", err);
|
770
|
-
return false;
|
771
|
-
}
|
772
|
-
|
773
|
-
err = esp_netif_dhcps_start(s_ap_netif);
|
774
|
-
|
775
|
-
if (err != ESP_OK) {
|
776
|
-
ESP_LOGE(TAG, "esp_netif_dhcps_start failed: %d", err);
|
777
|
-
return false;
|
778
|
-
}
|
779
|
-
|
780
|
-
return true;
|
781
|
-
}
|
782
|
-
|
783
|
-
bool WiFiComponent::wifi_start_ap_(const WiFiAP &ap) {
|
784
|
-
// enable AP
|
785
|
-
if (!this->wifi_mode_({}, true))
|
786
|
-
return false;
|
787
|
-
|
788
|
-
wifi_config_t conf;
|
789
|
-
memset(&conf, 0, sizeof(conf));
|
790
|
-
if (ap.get_ssid().size() > sizeof(conf.ap.ssid)) {
|
791
|
-
ESP_LOGE(TAG, "AP SSID too long");
|
792
|
-
return false;
|
793
|
-
}
|
794
|
-
memcpy(reinterpret_cast<char *>(conf.ap.ssid), ap.get_ssid().c_str(), ap.get_ssid().size());
|
795
|
-
conf.ap.channel = ap.get_channel().value_or(1);
|
796
|
-
conf.ap.ssid_hidden = ap.get_ssid().size();
|
797
|
-
conf.ap.max_connection = 5;
|
798
|
-
conf.ap.beacon_interval = 100;
|
799
|
-
|
800
|
-
if (ap.get_password().empty()) {
|
801
|
-
conf.ap.authmode = WIFI_AUTH_OPEN;
|
802
|
-
*conf.ap.password = 0;
|
803
|
-
} else {
|
804
|
-
conf.ap.authmode = WIFI_AUTH_WPA2_PSK;
|
805
|
-
if (ap.get_password().size() > sizeof(conf.ap.password)) {
|
806
|
-
ESP_LOGE(TAG, "AP password too long");
|
807
|
-
return false;
|
808
|
-
}
|
809
|
-
memcpy(reinterpret_cast<char *>(conf.ap.password), ap.get_password().c_str(), ap.get_password().size());
|
810
|
-
}
|
811
|
-
|
812
|
-
// pairwise cipher of SoftAP, group cipher will be derived using this.
|
813
|
-
conf.ap.pairwise_cipher = WIFI_CIPHER_TYPE_CCMP;
|
814
|
-
|
815
|
-
esp_err_t err = esp_wifi_set_config(WIFI_IF_AP, &conf);
|
816
|
-
if (err != ESP_OK) {
|
817
|
-
ESP_LOGV(TAG, "esp_wifi_set_config failed: %d", err);
|
818
|
-
return false;
|
819
|
-
}
|
820
|
-
|
821
|
-
yield();
|
822
|
-
|
823
|
-
if (!this->wifi_ap_ip_config_(ap.get_manual_ip())) {
|
824
|
-
ESP_LOGV(TAG, "wifi_ap_ip_config_ failed");
|
825
|
-
return false;
|
826
|
-
}
|
827
|
-
|
828
|
-
return true;
|
829
|
-
}
|
830
|
-
|
831
|
-
network::IPAddress WiFiComponent::wifi_soft_ap_ip() {
|
832
|
-
esp_netif_ip_info_t ip;
|
833
|
-
esp_netif_get_ip_info(s_ap_netif, &ip);
|
834
|
-
return network::IPAddress(&ip.ip);
|
835
|
-
}
|
836
|
-
#endif // USE_WIFI_AP
|
837
|
-
|
838
|
-
bool WiFiComponent::wifi_disconnect_() { return esp_wifi_disconnect(); }
|
839
|
-
|
840
|
-
bssid_t WiFiComponent::wifi_bssid() {
|
841
|
-
bssid_t bssid{};
|
842
|
-
uint8_t *raw_bssid = WiFi.BSSID();
|
843
|
-
if (raw_bssid != nullptr) {
|
844
|
-
for (size_t i = 0; i < bssid.size(); i++)
|
845
|
-
bssid[i] = raw_bssid[i];
|
846
|
-
}
|
847
|
-
return bssid;
|
848
|
-
}
|
849
|
-
std::string WiFiComponent::wifi_ssid() { return WiFi.SSID().c_str(); }
|
850
|
-
int8_t WiFiComponent::wifi_rssi() { return WiFi.RSSI(); }
|
851
|
-
int32_t WiFiComponent::get_wifi_channel() { return WiFi.channel(); }
|
852
|
-
network::IPAddress WiFiComponent::wifi_subnet_mask_() { return network::IPAddress(WiFi.subnetMask()); }
|
853
|
-
network::IPAddress WiFiComponent::wifi_gateway_ip_() { return network::IPAddress(WiFi.gatewayIP()); }
|
854
|
-
network::IPAddress WiFiComponent::wifi_dns_ip_(int num) { return network::IPAddress(WiFi.dnsIP(num)); }
|
855
|
-
|
856
|
-
} // namespace wifi
|
857
|
-
} // namespace esphome
|
858
|
-
|
859
|
-
#endif // USE_ESP32_FRAMEWORK_ARDUINO
|
860
|
-
#endif
|