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
@@ -1504,6 +1504,10 @@ BOARDS = {
|
|
1504
1504
|
"name": "BPI-Bit",
|
1505
1505
|
"variant": VARIANT_ESP32,
|
1506
1506
|
},
|
1507
|
+
"bpi-centi-s3": {
|
1508
|
+
"name": "BPI-Centi-S3",
|
1509
|
+
"variant": VARIANT_ESP32S3,
|
1510
|
+
},
|
1507
1511
|
"bpi_leaf_s3": {
|
1508
1512
|
"name": "BPI-Leaf-S3",
|
1509
1513
|
"variant": VARIANT_ESP32S3,
|
@@ -1664,10 +1668,46 @@ BOARDS = {
|
|
1664
1668
|
"name": "Espressif ESP32-S3-DevKitC-1-N8 (8 MB QD, No PSRAM)",
|
1665
1669
|
"variant": VARIANT_ESP32S3,
|
1666
1670
|
},
|
1671
|
+
"esp32-s3-devkitc-1-n32r8v": {
|
1672
|
+
"name": "Espressif ESP32-S3-DevKitC-1-N32R8V (32 MB Flash Octal, 8 MB PSRAM Octal)",
|
1673
|
+
"variant": VARIANT_ESP32S3,
|
1674
|
+
},
|
1675
|
+
"esp32-s3-devkitc1-n16r16": {
|
1676
|
+
"name": "Espressif ESP32-S3-DevKitC-1-N16R16V (16 MB Flash Quad, 16 MB PSRAM Octal)",
|
1677
|
+
"variant": VARIANT_ESP32S3,
|
1678
|
+
},
|
1679
|
+
"esp32-s3-devkitc1-n16r2": {
|
1680
|
+
"name": "Espressif ESP32-S3-DevKitC-1-N16R2 (16 MB Flash Quad, 2 MB PSRAM Quad)",
|
1681
|
+
"variant": VARIANT_ESP32S3,
|
1682
|
+
},
|
1683
|
+
"esp32-s3-devkitc1-n16r8": {
|
1684
|
+
"name": "Espressif ESP32-S3-DevKitC-1-N16R8V (16 MB Flash Quad, 8 MB PSRAM Octal)",
|
1685
|
+
"variant": VARIANT_ESP32S3,
|
1686
|
+
},
|
1687
|
+
"esp32-s3-devkitc1-n4r2": {
|
1688
|
+
"name": "Espressif ESP32-S3-DevKitC-1-N4R2 (4 MB Flash Quad, 2 MB PSRAM Quad)",
|
1689
|
+
"variant": VARIANT_ESP32S3,
|
1690
|
+
},
|
1691
|
+
"esp32-s3-devkitc1-n4r8": {
|
1692
|
+
"name": "Espressif ESP32-S3-DevKitC-1-N4R8 (4 MB Flash Quad, 8 MB PSRAM Octal)",
|
1693
|
+
"variant": VARIANT_ESP32S3,
|
1694
|
+
},
|
1695
|
+
"esp32-s3-devkitc1-n8r2": {
|
1696
|
+
"name": "Espressif ESP32-S3-DevKitC-1-N8R2 (8 MB Flash Quad, 2 MB PSRAM quad)",
|
1697
|
+
"variant": VARIANT_ESP32S3,
|
1698
|
+
},
|
1699
|
+
"esp32-s3-devkitc1-n8r8": {
|
1700
|
+
"name": "Espressif ESP32-S3-DevKitC-1-N8R8 (8 MB Flash Quad, 8 MB PSRAM Octal)",
|
1701
|
+
"variant": VARIANT_ESP32S3,
|
1702
|
+
},
|
1667
1703
|
"esp32-s3-devkitm-1": {
|
1668
1704
|
"name": "Espressif ESP32-S3-DevKitM-1",
|
1669
1705
|
"variant": VARIANT_ESP32S3,
|
1670
1706
|
},
|
1707
|
+
"esp32-s3-fh4r2": {
|
1708
|
+
"name": "Espressif ESP32-S3-FH4R2 (4 MB QD, 2MB PSRAM)",
|
1709
|
+
"variant": VARIANT_ESP32S3,
|
1710
|
+
},
|
1671
1711
|
"esp32-solo1": {
|
1672
1712
|
"name": "Espressif Generic ESP32-solo1 4M Flash",
|
1673
1713
|
"variant": VARIANT_ESP32,
|
@@ -1764,6 +1804,10 @@ BOARDS = {
|
|
1764
1804
|
"name": "Franzininho WiFi MSC",
|
1765
1805
|
"variant": VARIANT_ESP32S2,
|
1766
1806
|
},
|
1807
|
+
"freenove-esp32-s3-n8r8": {
|
1808
|
+
"name": "Freenove ESP32-S3 WROOM N8R8 (8MB Flash / 8MB PSRAM)",
|
1809
|
+
"variant": VARIANT_ESP32S3,
|
1810
|
+
},
|
1767
1811
|
"freenove_esp32_s3_wroom": {
|
1768
1812
|
"name": "Freenove ESP32-S3 WROOM N8R8 (8MB Flash / 8MB PSRAM)",
|
1769
1813
|
"variant": VARIANT_ESP32S3,
|
@@ -1964,6 +2008,10 @@ BOARDS = {
|
|
1964
2008
|
"name": "M5Stack AtomS3",
|
1965
2009
|
"variant": VARIANT_ESP32S3,
|
1966
2010
|
},
|
2011
|
+
"m5stack-atoms3u": {
|
2012
|
+
"name": "M5Stack AtomS3U",
|
2013
|
+
"variant": VARIANT_ESP32S3,
|
2014
|
+
},
|
1967
2015
|
"m5stack-core-esp32": {
|
1968
2016
|
"name": "M5Stack Core ESP32",
|
1969
2017
|
"variant": VARIANT_ESP32,
|
@@ -2084,6 +2132,10 @@ BOARDS = {
|
|
2084
2132
|
"name": "Ai-Thinker NodeMCU-32S2 (ESP-12K)",
|
2085
2133
|
"variant": VARIANT_ESP32S2,
|
2086
2134
|
},
|
2135
|
+
"nologo_esp32c3_super_mini": {
|
2136
|
+
"name": "Nologo ESP32C3 SuperMini",
|
2137
|
+
"variant": VARIANT_ESP32C3,
|
2138
|
+
},
|
2087
2139
|
"nscreen-32": {
|
2088
2140
|
"name": "YeaCreate NSCREEN-32",
|
2089
2141
|
"variant": VARIANT_ESP32,
|
@@ -2192,6 +2244,10 @@ BOARDS = {
|
|
2192
2244
|
"name": "SparkFun LoRa Gateway 1-Channel",
|
2193
2245
|
"variant": VARIANT_ESP32,
|
2194
2246
|
},
|
2247
|
+
"sparkfun_pro_micro_esp32c3": {
|
2248
|
+
"name": "SparkFun Pro Micro ESP32-C3",
|
2249
|
+
"variant": VARIANT_ESP32C3,
|
2250
|
+
},
|
2195
2251
|
"sparkfun_qwiic_pocket_esp32c6": {
|
2196
2252
|
"name": "SparkFun ESP32-C6 Qwiic Pocket",
|
2197
2253
|
"variant": VARIANT_ESP32C6,
|
@@ -2256,6 +2312,14 @@ BOARDS = {
|
|
2256
2312
|
"name": "Turta IoT Node",
|
2257
2313
|
"variant": VARIANT_ESP32,
|
2258
2314
|
},
|
2315
|
+
"um_bling": {
|
2316
|
+
"name": "Unexpected Maker BLING!",
|
2317
|
+
"variant": VARIANT_ESP32S3,
|
2318
|
+
},
|
2319
|
+
"um_edges3_d": {
|
2320
|
+
"name": "Unexpected Maker EDGES3[D]",
|
2321
|
+
"variant": VARIANT_ESP32S3,
|
2322
|
+
},
|
2259
2323
|
"um_feathers2": {
|
2260
2324
|
"name": "Unexpected Maker FeatherS2",
|
2261
2325
|
"variant": VARIANT_ESP32S2,
|
@@ -2268,10 +2332,18 @@ BOARDS = {
|
|
2268
2332
|
"name": "Unexpected Maker FeatherS3",
|
2269
2333
|
"variant": VARIANT_ESP32S3,
|
2270
2334
|
},
|
2335
|
+
"um_feathers3_neo": {
|
2336
|
+
"name": "Unexpected Maker FeatherS3 Neo",
|
2337
|
+
"variant": VARIANT_ESP32S3,
|
2338
|
+
},
|
2271
2339
|
"um_nanos3": {
|
2272
2340
|
"name": "Unexpected Maker NanoS3",
|
2273
2341
|
"variant": VARIANT_ESP32S3,
|
2274
2342
|
},
|
2343
|
+
"um_omgs3": {
|
2344
|
+
"name": "Unexpected Maker OMGS3",
|
2345
|
+
"variant": VARIANT_ESP32S3,
|
2346
|
+
},
|
2275
2347
|
"um_pros3": {
|
2276
2348
|
"name": "Unexpected Maker PROS3",
|
2277
2349
|
"variant": VARIANT_ESP32S3,
|
@@ -2280,6 +2352,14 @@ BOARDS = {
|
|
2280
2352
|
"name": "Unexpected Maker RMP",
|
2281
2353
|
"variant": VARIANT_ESP32S2,
|
2282
2354
|
},
|
2355
|
+
"um_squixl": {
|
2356
|
+
"name": "Unexpected Maker SQUiXL",
|
2357
|
+
"variant": VARIANT_ESP32S3,
|
2358
|
+
},
|
2359
|
+
"um_tinyc6": {
|
2360
|
+
"name": "Unexpected Maker TinyC6",
|
2361
|
+
"variant": VARIANT_ESP32C6,
|
2362
|
+
},
|
2283
2363
|
"um_tinys2": {
|
2284
2364
|
"name": "Unexpected Maker TinyS2",
|
2285
2365
|
"variant": VARIANT_ESP32S2,
|
@@ -2401,3 +2481,4 @@ BOARDS = {
|
|
2401
2481
|
"variant": VARIANT_ESP32S3,
|
2402
2482
|
},
|
2403
2483
|
}
|
2484
|
+
# DO NOT ADD ANYTHING BELOW THIS LINE
|
@@ -17,7 +17,14 @@ static const char *const TAG = "esp32.preferences";
|
|
17
17
|
|
18
18
|
struct NVSData {
|
19
19
|
std::string key;
|
20
|
-
std::
|
20
|
+
std::unique_ptr<uint8_t[]> data;
|
21
|
+
size_t len;
|
22
|
+
|
23
|
+
void set_data(const uint8_t *src, size_t size) {
|
24
|
+
data = std::make_unique<uint8_t[]>(size);
|
25
|
+
memcpy(data.get(), src, size);
|
26
|
+
len = size;
|
27
|
+
}
|
21
28
|
};
|
22
29
|
|
23
30
|
static std::vector<NVSData> s_pending_save; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
@@ -30,26 +37,26 @@ class ESP32PreferenceBackend : public ESPPreferenceBackend {
|
|
30
37
|
// try find in pending saves and update that
|
31
38
|
for (auto &obj : s_pending_save) {
|
32
39
|
if (obj.key == key) {
|
33
|
-
obj.
|
40
|
+
obj.set_data(data, len);
|
34
41
|
return true;
|
35
42
|
}
|
36
43
|
}
|
37
44
|
NVSData save{};
|
38
45
|
save.key = key;
|
39
|
-
save.
|
40
|
-
s_pending_save.emplace_back(save);
|
41
|
-
ESP_LOGVV(TAG, "s_pending_save: key: %s, len: %
|
46
|
+
save.set_data(data, len);
|
47
|
+
s_pending_save.emplace_back(std::move(save));
|
48
|
+
ESP_LOGVV(TAG, "s_pending_save: key: %s, len: %zu", key.c_str(), len);
|
42
49
|
return true;
|
43
50
|
}
|
44
51
|
bool load(uint8_t *data, size_t len) override {
|
45
52
|
// try find in pending saves and load from that
|
46
53
|
for (auto &obj : s_pending_save) {
|
47
54
|
if (obj.key == key) {
|
48
|
-
if (obj.
|
55
|
+
if (obj.len != len) {
|
49
56
|
// size mismatch
|
50
57
|
return false;
|
51
58
|
}
|
52
|
-
memcpy(data, obj.data.
|
59
|
+
memcpy(data, obj.data.get(), len);
|
53
60
|
return true;
|
54
61
|
}
|
55
62
|
}
|
@@ -61,7 +68,7 @@ class ESP32PreferenceBackend : public ESPPreferenceBackend {
|
|
61
68
|
return false;
|
62
69
|
}
|
63
70
|
if (actual_len != len) {
|
64
|
-
ESP_LOGVV(TAG, "NVS length does not match (%
|
71
|
+
ESP_LOGVV(TAG, "NVS length does not match (%zu!=%zu)", actual_len, len);
|
65
72
|
return false;
|
66
73
|
}
|
67
74
|
err = nvs_get_blob(nvs_handle, key.c_str(), data, &len);
|
@@ -69,7 +76,7 @@ class ESP32PreferenceBackend : public ESPPreferenceBackend {
|
|
69
76
|
ESP_LOGV(TAG, "nvs_get_blob('%s') failed: %s", key.c_str(), esp_err_to_name(err));
|
70
77
|
return false;
|
71
78
|
} else {
|
72
|
-
ESP_LOGVV(TAG, "nvs_get_blob: key: %s, len: %
|
79
|
+
ESP_LOGVV(TAG, "nvs_get_blob: key: %s, len: %zu", key.c_str(), len);
|
73
80
|
}
|
74
81
|
return true;
|
75
82
|
}
|
@@ -112,7 +119,7 @@ class ESP32Preferences : public ESPPreferences {
|
|
112
119
|
if (s_pending_save.empty())
|
113
120
|
return true;
|
114
121
|
|
115
|
-
ESP_LOGV(TAG, "Saving %
|
122
|
+
ESP_LOGV(TAG, "Saving %zu items...", s_pending_save.size());
|
116
123
|
// goal try write all pending saves even if one fails
|
117
124
|
int cached = 0, written = 0, failed = 0;
|
118
125
|
esp_err_t last_err = ESP_OK;
|
@@ -123,11 +130,10 @@ class ESP32Preferences : public ESPPreferences {
|
|
123
130
|
const auto &save = s_pending_save[i];
|
124
131
|
ESP_LOGVV(TAG, "Checking if NVS data %s has changed", save.key.c_str());
|
125
132
|
if (is_changed(nvs_handle, save)) {
|
126
|
-
esp_err_t err = nvs_set_blob(nvs_handle, save.key.c_str(), save.data.
|
127
|
-
ESP_LOGV(TAG, "sync: key: %s, len: %
|
133
|
+
esp_err_t err = nvs_set_blob(nvs_handle, save.key.c_str(), save.data.get(), save.len);
|
134
|
+
ESP_LOGV(TAG, "sync: key: %s, len: %zu", save.key.c_str(), save.len);
|
128
135
|
if (err != 0) {
|
129
|
-
ESP_LOGV(TAG, "nvs_set_blob('%s', len=%
|
130
|
-
esp_err_to_name(err));
|
136
|
+
ESP_LOGV(TAG, "nvs_set_blob('%s', len=%zu) failed: %s", save.key.c_str(), save.len, esp_err_to_name(err));
|
131
137
|
failed++;
|
132
138
|
last_err = err;
|
133
139
|
last_key = save.key;
|
@@ -135,7 +141,7 @@ class ESP32Preferences : public ESPPreferences {
|
|
135
141
|
}
|
136
142
|
written++;
|
137
143
|
} else {
|
138
|
-
ESP_LOGV(TAG, "NVS data not changed skipping %s len=%
|
144
|
+
ESP_LOGV(TAG, "NVS data not changed skipping %s len=%zu", save.key.c_str(), save.len);
|
139
145
|
cached++;
|
140
146
|
}
|
141
147
|
s_pending_save.erase(s_pending_save.begin() + i);
|
@@ -164,7 +170,7 @@ class ESP32Preferences : public ESPPreferences {
|
|
164
170
|
return true;
|
165
171
|
}
|
166
172
|
// Check size first before allocating memory
|
167
|
-
if (actual_len != to_save.
|
173
|
+
if (actual_len != to_save.len) {
|
168
174
|
return true;
|
169
175
|
}
|
170
176
|
auto stored_data = std::make_unique<uint8_t[]>(actual_len);
|
@@ -173,7 +179,7 @@ class ESP32Preferences : public ESPPreferences {
|
|
173
179
|
ESP_LOGV(TAG, "nvs_get_blob('%s') failed: %s", to_save.key.c_str(), esp_err_to_name(err));
|
174
180
|
return true;
|
175
181
|
}
|
176
|
-
return memcmp(to_save.data.
|
182
|
+
return memcmp(to_save.data.get(), stored_data.get(), to_save.len) != 0;
|
177
183
|
}
|
178
184
|
|
179
185
|
bool reset() override {
|
@@ -1,5 +1,8 @@
|
|
1
|
+
from collections.abc import Callable, MutableMapping
|
1
2
|
from enum import Enum
|
3
|
+
import logging
|
2
4
|
import re
|
5
|
+
from typing import Any
|
3
6
|
|
4
7
|
from esphome import automation
|
5
8
|
import esphome.codegen as cg
|
@@ -9,6 +12,7 @@ from esphome.const import (
|
|
9
12
|
CONF_ENABLE_ON_BOOT,
|
10
13
|
CONF_ESPHOME,
|
11
14
|
CONF_ID,
|
15
|
+
CONF_MAX_CONNECTIONS,
|
12
16
|
CONF_NAME,
|
13
17
|
CONF_NAME_ADD_MAC_SUFFIX,
|
14
18
|
)
|
@@ -19,6 +23,8 @@ DEPENDENCIES = ["esp32"]
|
|
19
23
|
CODEOWNERS = ["@jesserockz", "@Rapsssito", "@bdraco"]
|
20
24
|
DOMAIN = "esp32_ble"
|
21
25
|
|
26
|
+
_LOGGER = logging.getLogger(__name__)
|
27
|
+
|
22
28
|
|
23
29
|
class BTLoggers(Enum):
|
24
30
|
"""Bluetooth logger categories available in ESP-IDF.
|
@@ -127,6 +133,28 @@ CONF_DISABLE_BT_LOGS = "disable_bt_logs"
|
|
127
133
|
CONF_CONNECTION_TIMEOUT = "connection_timeout"
|
128
134
|
CONF_MAX_NOTIFICATIONS = "max_notifications"
|
129
135
|
|
136
|
+
# BLE connection limits
|
137
|
+
# ESP-IDF CONFIG_BT_ACL_CONNECTIONS has range 1-9, default 4
|
138
|
+
# Total instances: 10 (ADV + SCAN + connections)
|
139
|
+
# - ADV only: up to 9 connections
|
140
|
+
# - SCAN only: up to 9 connections
|
141
|
+
# - ADV + SCAN: up to 8 connections
|
142
|
+
DEFAULT_MAX_CONNECTIONS = 3
|
143
|
+
IDF_MAX_CONNECTIONS = 9
|
144
|
+
|
145
|
+
# Connection slot tracking keys
|
146
|
+
KEY_ESP32_BLE = "esp32_ble"
|
147
|
+
KEY_USED_CONNECTION_SLOTS = "used_connection_slots"
|
148
|
+
|
149
|
+
# Export for use by other components (bluetooth_proxy, etc.)
|
150
|
+
__all__ = [
|
151
|
+
"DEFAULT_MAX_CONNECTIONS",
|
152
|
+
"IDF_MAX_CONNECTIONS",
|
153
|
+
"KEY_ESP32_BLE",
|
154
|
+
"KEY_USED_CONNECTION_SLOTS",
|
155
|
+
"consume_connection_slots",
|
156
|
+
]
|
157
|
+
|
130
158
|
NO_BLUETOOTH_VARIANTS = [const.VARIANT_ESP32S2]
|
131
159
|
|
132
160
|
esp32_ble_ns = cg.esphome_ns.namespace("esp32_ble")
|
@@ -174,19 +202,18 @@ CONFIG_SCHEMA = cv.Schema(
|
|
174
202
|
cv.Optional(
|
175
203
|
CONF_ADVERTISING_CYCLE_TIME, default="10s"
|
176
204
|
): cv.positive_time_period_milliseconds,
|
177
|
-
cv.
|
178
|
-
|
179
|
-
),
|
180
|
-
cv.SplitDefault(CONF_CONNECTION_TIMEOUT, esp32_idf="20s"): cv.All(
|
181
|
-
cv.only_with_esp_idf,
|
205
|
+
cv.Optional(CONF_DISABLE_BT_LOGS, default=True): cv.boolean,
|
206
|
+
cv.Optional(CONF_CONNECTION_TIMEOUT, default="20s"): cv.All(
|
182
207
|
cv.positive_time_period_seconds,
|
183
208
|
cv.Range(min=TimePeriod(seconds=10), max=TimePeriod(seconds=180)),
|
184
209
|
),
|
185
|
-
cv.
|
186
|
-
cv.only_with_esp_idf,
|
210
|
+
cv.Optional(CONF_MAX_NOTIFICATIONS, default=12): cv.All(
|
187
211
|
cv.positive_int,
|
188
212
|
cv.Range(min=1, max=64),
|
189
213
|
),
|
214
|
+
cv.Optional(CONF_MAX_CONNECTIONS, default=DEFAULT_MAX_CONNECTIONS): cv.All(
|
215
|
+
cv.positive_int, cv.Range(min=1, max=IDF_MAX_CONNECTIONS)
|
216
|
+
),
|
190
217
|
}
|
191
218
|
).extend(cv.COMPONENT_SCHEMA)
|
192
219
|
|
@@ -234,6 +261,60 @@ def validate_variant(_):
|
|
234
261
|
raise cv.Invalid(f"{variant} does not support Bluetooth")
|
235
262
|
|
236
263
|
|
264
|
+
def consume_connection_slots(
|
265
|
+
value: int, consumer: str
|
266
|
+
) -> Callable[[MutableMapping], MutableMapping]:
|
267
|
+
"""Reserve BLE connection slots for a component.
|
268
|
+
|
269
|
+
Args:
|
270
|
+
value: Number of connection slots to reserve
|
271
|
+
consumer: Name of the component consuming the slots
|
272
|
+
|
273
|
+
Returns:
|
274
|
+
A validator function that records the slot usage
|
275
|
+
"""
|
276
|
+
|
277
|
+
def _consume_connection_slots(config: MutableMapping) -> MutableMapping:
|
278
|
+
data: dict[str, Any] = CORE.data.setdefault(KEY_ESP32_BLE, {})
|
279
|
+
slots: list[str] = data.setdefault(KEY_USED_CONNECTION_SLOTS, [])
|
280
|
+
slots.extend([consumer] * value)
|
281
|
+
return config
|
282
|
+
|
283
|
+
return _consume_connection_slots
|
284
|
+
|
285
|
+
|
286
|
+
def validate_connection_slots(max_connections: int) -> None:
|
287
|
+
"""Validate that BLE connection slots don't exceed the configured maximum."""
|
288
|
+
# Skip validation in testing mode to allow component grouping
|
289
|
+
if CORE.testing_mode:
|
290
|
+
return
|
291
|
+
|
292
|
+
ble_data = CORE.data.get(KEY_ESP32_BLE, {})
|
293
|
+
used_slots = ble_data.get(KEY_USED_CONNECTION_SLOTS, [])
|
294
|
+
num_used = len(used_slots)
|
295
|
+
|
296
|
+
if num_used <= max_connections:
|
297
|
+
return
|
298
|
+
|
299
|
+
slot_users = ", ".join(used_slots)
|
300
|
+
|
301
|
+
if num_used > IDF_MAX_CONNECTIONS:
|
302
|
+
raise cv.Invalid(
|
303
|
+
f"BLE components require {num_used} connection slots but maximum is {IDF_MAX_CONNECTIONS}. "
|
304
|
+
f"Reduce the number of BLE clients. Components: {slot_users}"
|
305
|
+
)
|
306
|
+
|
307
|
+
_LOGGER.warning(
|
308
|
+
"BLE components require %d connection slot(s) but only %d configured. "
|
309
|
+
"Please set 'max_connections: %d' in the 'esp32_ble' component. "
|
310
|
+
"Components: %s",
|
311
|
+
num_used,
|
312
|
+
max_connections,
|
313
|
+
num_used,
|
314
|
+
slot_users,
|
315
|
+
)
|
316
|
+
|
317
|
+
|
237
318
|
def final_validation(config):
|
238
319
|
validate_variant(config)
|
239
320
|
if (name := config.get(CONF_NAME)) is not None:
|
@@ -246,6 +327,47 @@ def final_validation(config):
|
|
246
327
|
f"Name '{name}' is too long, maximum length is {max_length} characters"
|
247
328
|
)
|
248
329
|
|
330
|
+
# Set GATT Client/Server sdkconfig options based on which components are loaded
|
331
|
+
full_config = fv.full_config.get()
|
332
|
+
|
333
|
+
# Validate connection slots usage
|
334
|
+
max_connections = config.get(CONF_MAX_CONNECTIONS, DEFAULT_MAX_CONNECTIONS)
|
335
|
+
validate_connection_slots(max_connections)
|
336
|
+
|
337
|
+
# Check if BLE Server is needed
|
338
|
+
has_ble_server = "esp32_ble_server" in full_config
|
339
|
+
|
340
|
+
# Check if BLE Client is needed (via esp32_ble_tracker or esp32_ble_client)
|
341
|
+
has_ble_client = (
|
342
|
+
"esp32_ble_tracker" in full_config or "esp32_ble_client" in full_config
|
343
|
+
)
|
344
|
+
|
345
|
+
# ESP-IDF BLE stack requires GATT Server to be enabled when GATT Client is enabled
|
346
|
+
# This is an internal dependency in the Bluedroid stack (tested ESP-IDF 5.4.2-5.5.1)
|
347
|
+
# See: https://github.com/espressif/esp-idf/issues/17724
|
348
|
+
add_idf_sdkconfig_option("CONFIG_BT_GATTS_ENABLE", has_ble_server or has_ble_client)
|
349
|
+
add_idf_sdkconfig_option("CONFIG_BT_GATTC_ENABLE", has_ble_client)
|
350
|
+
|
351
|
+
# Handle max_connections: check for deprecated location in esp32_ble_tracker
|
352
|
+
max_connections = config.get(CONF_MAX_CONNECTIONS, DEFAULT_MAX_CONNECTIONS)
|
353
|
+
|
354
|
+
# Use value from tracker if esp32_ble doesn't have it explicitly set (backward compat)
|
355
|
+
if "esp32_ble_tracker" in full_config:
|
356
|
+
tracker_config = full_config["esp32_ble_tracker"]
|
357
|
+
if "max_connections" in tracker_config and CONF_MAX_CONNECTIONS not in config:
|
358
|
+
max_connections = tracker_config["max_connections"]
|
359
|
+
|
360
|
+
# Set CONFIG_BT_ACL_CONNECTIONS to the maximum connections needed + 1 for ADV/SCAN
|
361
|
+
# This is the Bluedroid host stack total instance limit (range 1-9, default 4)
|
362
|
+
# Total instances = ADV/SCAN (1) + connection slots (max_connections)
|
363
|
+
# Shared between client (tracker/ble_client) and server
|
364
|
+
add_idf_sdkconfig_option("CONFIG_BT_ACL_CONNECTIONS", max_connections + 1)
|
365
|
+
|
366
|
+
# Set controller-specific max connections for ESP32 (classic)
|
367
|
+
# CONFIG_BTDM_CTRL_BLE_MAX_CONN is ESP32-specific controller limit (just connections, not ADV/SCAN)
|
368
|
+
# For newer chips (C3/S3/etc), different configs are used automatically
|
369
|
+
add_idf_sdkconfig_option("CONFIG_BTDM_CTRL_BLE_MAX_CONN", max_connections)
|
370
|
+
|
249
371
|
return config
|
250
372
|
|
251
373
|
|
@@ -261,43 +383,44 @@ async def to_code(config):
|
|
261
383
|
cg.add(var.set_name(name))
|
262
384
|
await cg.register_component(var, config)
|
263
385
|
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
386
|
+
# Define max connections for use in C++ code (e.g., ble_server.h)
|
387
|
+
max_connections = config.get(CONF_MAX_CONNECTIONS, DEFAULT_MAX_CONNECTIONS)
|
388
|
+
cg.add_define("USE_ESP32_BLE_MAX_CONNECTIONS", max_connections)
|
389
|
+
|
390
|
+
add_idf_sdkconfig_option("CONFIG_BT_ENABLED", True)
|
391
|
+
add_idf_sdkconfig_option("CONFIG_BT_BLE_42_FEATURES_SUPPORTED", True)
|
392
|
+
|
393
|
+
# Register the core BLE loggers that are always needed
|
394
|
+
register_bt_logger(BTLoggers.GAP, BTLoggers.BTM, BTLoggers.HCI)
|
395
|
+
|
396
|
+
# Apply logger settings if log disabling is enabled
|
397
|
+
if config.get(CONF_DISABLE_BT_LOGS, False):
|
398
|
+
# Disable all Bluetooth loggers that are not required
|
399
|
+
for logger in BTLoggers:
|
400
|
+
if logger not in _required_loggers:
|
401
|
+
add_idf_sdkconfig_option(f"{logger.value}_NONE", True)
|
402
|
+
|
403
|
+
# Set BLE connection establishment timeout to match aioesphomeapi/bleak-retry-connector
|
404
|
+
# Default is 20 seconds instead of ESP-IDF's 30 seconds. Because there is no way to
|
405
|
+
# cancel a BLE connection in progress, when aioesphomeapi times out at 20 seconds,
|
406
|
+
# the connection slot remains occupied for the remaining time, preventing new connection
|
407
|
+
# attempts and wasting valuable connection slots.
|
408
|
+
if CONF_CONNECTION_TIMEOUT in config:
|
409
|
+
timeout_seconds = int(config[CONF_CONNECTION_TIMEOUT].total_seconds)
|
410
|
+
add_idf_sdkconfig_option("CONFIG_BT_BLE_ESTAB_LINK_CONN_TOUT", timeout_seconds)
|
411
|
+
# Increase GATT client connection retry count for problematic devices
|
412
|
+
# Default in ESP-IDF is 3, we increase to 10 for better reliability with
|
413
|
+
# low-power/timing-sensitive devices
|
414
|
+
add_idf_sdkconfig_option("CONFIG_BT_GATTC_CONNECT_RETRY_COUNT", 10)
|
415
|
+
|
416
|
+
# Set the maximum number of notification registrations
|
417
|
+
# This controls how many BLE characteristics can have notifications enabled
|
418
|
+
# across all connections for a single GATT client interface
|
419
|
+
# https://github.com/esphome/issues/issues/6808
|
420
|
+
if CONF_MAX_NOTIFICATIONS in config:
|
421
|
+
add_idf_sdkconfig_option(
|
422
|
+
"CONFIG_BT_GATTC_NOTIF_REG_MAX", config[CONF_MAX_NOTIFICATIONS]
|
423
|
+
)
|
301
424
|
|
302
425
|
cg.add_define("USE_ESP32_BLE")
|
303
426
|
|