esphome 2025.9.2__py3-none-any.whl → 2025.10.0b1__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.
Files changed (344) hide show
  1. esphome/__main__.py +87 -31
  2. esphome/address_cache.py +142 -0
  3. esphome/automation.py +130 -32
  4. esphome/build_gen/platformio.py +1 -3
  5. esphome/codegen.py +1 -0
  6. esphome/components/animation/animation.cpp +2 -2
  7. esphome/components/api/__init__.py +167 -3
  8. esphome/components/api/api_connection.cpp +84 -41
  9. esphome/components/api/api_connection.h +22 -16
  10. esphome/components/api/api_frame_helper.cpp +33 -19
  11. esphome/components/api/api_frame_helper.h +19 -4
  12. esphome/components/api/api_frame_helper_noise.cpp +41 -53
  13. esphome/components/api/api_frame_helper_noise.h +1 -1
  14. esphome/components/api/api_frame_helper_plaintext.cpp +22 -31
  15. esphome/components/api/api_frame_helper_plaintext.h +1 -1
  16. esphome/components/api/api_pb2.cpp +189 -15
  17. esphome/components/api/api_pb2.h +132 -20
  18. esphome/components/api/api_pb2_dump.cpp +97 -9
  19. esphome/components/api/api_pb2_service.cpp +118 -160
  20. esphome/components/api/api_pb2_service.h +31 -3
  21. esphome/components/api/api_server.cpp +78 -11
  22. esphome/components/api/api_server.h +32 -4
  23. esphome/components/api/custom_api_device.h +8 -8
  24. esphome/components/api/homeassistant_service.h +123 -6
  25. esphome/components/api/proto.h +6 -2
  26. esphome/components/api/user_services.h +2 -2
  27. esphome/components/as7341/sensor.py +1 -1
  28. esphome/components/audio/__init__.py +1 -1
  29. esphome/components/audio/audio.cpp +1 -1
  30. esphome/components/audio/audio_decoder.cpp +9 -9
  31. esphome/components/bl0906/bl0906.cpp +2 -2
  32. esphome/components/bl0942/bl0942.cpp +2 -2
  33. esphome/components/ble_client/__init__.py +1 -1
  34. esphome/components/bluetooth_proxy/__init__.py +4 -30
  35. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +11 -4
  36. esphome/components/bluetooth_proxy/bluetooth_connection.h +2 -2
  37. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +2 -2
  38. esphome/components/camera_encoder/__init__.py +2 -4
  39. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.cpp +4 -2
  40. esphome/components/camera_encoder/esp32_camera_jpeg_encoder.h +3 -1
  41. esphome/components/canbus/canbus.cpp +7 -5
  42. esphome/components/canbus/canbus.h +4 -4
  43. esphome/components/captive_portal/__init__.py +18 -1
  44. esphome/components/captive_portal/captive_portal.cpp +40 -46
  45. esphome/components/captive_portal/captive_portal.h +20 -22
  46. esphome/components/captive_portal/dns_server_esp32_idf.cpp +205 -0
  47. esphome/components/captive_portal/dns_server_esp32_idf.h +27 -0
  48. esphome/components/ccs811/ccs811.cpp +1 -1
  49. esphome/components/climate/climate.cpp +10 -7
  50. esphome/components/cm1106/cm1106.cpp +1 -1
  51. esphome/components/copy/lock/copy_lock.cpp +1 -1
  52. esphome/components/cover/cover.cpp +1 -0
  53. esphome/components/daikin_arc/daikin_arc.cpp +19 -12
  54. esphome/components/deep_sleep/__init__.py +9 -2
  55. esphome/components/deep_sleep/deep_sleep_component.h +11 -9
  56. esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
  57. esphome/components/ektf2232/touchscreen/__init__.py +8 -5
  58. esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
  59. esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
  60. esphome/components/epaper_spi/__init__.py +1 -0
  61. esphome/components/epaper_spi/display.py +80 -0
  62. esphome/components/epaper_spi/epaper_spi.cpp +227 -0
  63. esphome/components/epaper_spi/epaper_spi.h +93 -0
  64. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
  65. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
  66. esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
  67. esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
  68. esphome/components/es7210/es7210.cpp +3 -3
  69. esphome/components/esp32/__init__.py +254 -339
  70. esphome/components/esp32/boards.py +81 -0
  71. esphome/components/esp32/preferences.cpp +23 -17
  72. esphome/components/esp32_ble/__init__.py +159 -44
  73. esphome/components/esp32_ble/ble.cpp +47 -3
  74. esphome/components/esp32_ble/ble.h +18 -0
  75. esphome/components/esp32_ble/ble_advertising.cpp +7 -3
  76. esphome/components/esp32_ble/ble_advertising.h +4 -0
  77. esphome/components/esp32_ble/ble_uuid.cpp +16 -42
  78. esphome/components/esp32_ble_beacon/__init__.py +3 -4
  79. esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
  80. esphome/components/esp32_ble_server/__init__.py +28 -14
  81. esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
  82. esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
  83. esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
  84. esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
  85. esphome/components/esp32_ble_server/ble_server.cpp +59 -24
  86. esphome/components/esp32_ble_server/ble_server.h +38 -20
  87. esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
  88. esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
  89. esphome/components/esp32_ble_tracker/__init__.py +25 -80
  90. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -4
  91. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
  92. esphome/components/esp32_camera/__init__.py +1 -3
  93. esphome/components/esp32_can/esp32_can.cpp +22 -4
  94. esphome/components/esp32_can/esp32_can.h +3 -0
  95. esphome/components/esp32_hosted/__init__.py +2 -1
  96. esphome/components/esp32_improv/esp32_improv_component.cpp +102 -44
  97. esphome/components/esp32_improv/esp32_improv_component.h +6 -1
  98. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  99. esphome/components/esp8266/__init__.py +3 -3
  100. esphome/components/esphome/ota/__init__.py +21 -2
  101. esphome/components/esphome/ota/ota_esphome.cpp +455 -145
  102. esphome/components/esphome/ota/ota_esphome.h +49 -2
  103. esphome/components/ethernet/__init__.py +39 -22
  104. esphome/components/ethernet/ethernet_component.cpp +28 -5
  105. esphome/components/ethernet/ethernet_component.h +5 -1
  106. esphome/components/external_components/__init__.py +8 -6
  107. esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
  108. esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
  109. esphome/components/font/__init__.py +5 -5
  110. esphome/components/graph/graph.cpp +1 -1
  111. esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
  112. esphome/components/haier/hon_climate.cpp +2 -2
  113. esphome/components/haier/hon_climate.h +1 -1
  114. esphome/components/hdc1080/hdc1080.cpp +42 -34
  115. esphome/components/hdc1080/hdc1080.h +1 -3
  116. esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
  117. esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
  118. esphome/components/http_request/__init__.py +3 -3
  119. esphome/components/htu21d/htu21d.cpp +13 -18
  120. esphome/components/htu21d/htu21d.h +1 -1
  121. esphome/components/i2s_audio/__init__.py +1 -2
  122. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  123. esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
  124. esphome/components/improv_serial/improv_serial_component.cpp +12 -15
  125. esphome/components/improv_serial/improv_serial_component.h +6 -8
  126. esphome/components/json/json_util.cpp +35 -43
  127. esphome/components/json/json_util.h +57 -0
  128. esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
  129. esphome/components/key_collector/key_collector.h +4 -4
  130. esphome/components/libretiny/__init__.py +6 -6
  131. esphome/components/libretiny/preferences.cpp +23 -16
  132. esphome/components/light/light_call.cpp +98 -120
  133. esphome/components/light/light_call.h +17 -7
  134. esphome/components/lm75b/__init__.py +0 -0
  135. esphome/components/lm75b/lm75b.cpp +39 -0
  136. esphome/components/lm75b/lm75b.h +19 -0
  137. esphome/components/lm75b/sensor.py +34 -0
  138. esphome/components/lock/lock.h +12 -6
  139. esphome/components/logger/__init__.py +15 -27
  140. esphome/components/logger/logger.cpp +10 -20
  141. esphome/components/logger/logger.h +105 -62
  142. esphome/components/logger/logger_esp32.cpp +0 -48
  143. esphome/components/logger/logger_zephyr.cpp +2 -3
  144. esphome/components/logger/select/logger_level_select.cpp +6 -7
  145. esphome/components/logger/select/logger_level_select.h +7 -0
  146. esphome/components/ltr501/ltr501.cpp +7 -6
  147. esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
  148. esphome/components/matrix_keypad/matrix_keypad.h +4 -4
  149. esphome/components/max7219digit/max7219digit.cpp +1 -1
  150. esphome/components/mcp2515/mcp2515.cpp +31 -3
  151. esphome/components/mcp2515/mcp2515_defs.h +3 -1
  152. esphome/components/md5/md5.cpp +0 -26
  153. esphome/components/md5/md5.h +10 -20
  154. esphome/components/mdns/__init__.py +19 -6
  155. esphome/components/mdns/mdns_component.cpp +27 -59
  156. esphome/components/mdns/mdns_component.h +23 -10
  157. esphome/components/mdns/mdns_esp32.cpp +7 -7
  158. esphome/components/mdns/mdns_esp8266.cpp +6 -6
  159. esphome/components/mdns/mdns_libretiny.cpp +3 -3
  160. esphome/components/mdns/mdns_rp2040.cpp +3 -3
  161. esphome/components/mipi/__init__.py +1 -5
  162. esphome/components/mipi_spi/display.py +24 -8
  163. esphome/components/mipi_spi/mipi_spi.h +3 -3
  164. esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
  165. esphome/components/mmc5603/mmc5603.cpp +3 -3
  166. esphome/components/modbus/modbus.cpp +27 -13
  167. esphome/components/modbus/modbus.h +5 -3
  168. esphome/components/modbus/modbus_definitions.h +86 -0
  169. esphome/components/modbus_controller/__init__.py +29 -1
  170. esphome/components/modbus_controller/const.py +4 -0
  171. esphome/components/modbus_controller/modbus_controller.cpp +38 -13
  172. esphome/components/modbus_controller/modbus_controller.h +18 -29
  173. esphome/components/mpr121/mpr121.cpp +41 -42
  174. esphome/components/mpr121/mpr121.h +0 -1
  175. esphome/components/nau7802/nau7802.cpp +2 -2
  176. esphome/components/network/__init__.py +7 -3
  177. esphome/components/nextion/display.py +4 -4
  178. esphome/components/nextion/nextion.cpp +8 -8
  179. esphome/components/number/__init__.py +2 -0
  180. esphome/components/number/number_call.cpp +23 -12
  181. esphome/components/number/number_call.h +5 -0
  182. esphome/components/online_image/bmp_image.cpp +2 -1
  183. esphome/components/online_image/jpeg_image.cpp +4 -2
  184. esphome/components/openthread/openthread.cpp +6 -7
  185. esphome/components/openthread/openthread.h +0 -1
  186. esphome/components/ota/ota_backend.h +1 -0
  187. esphome/components/packages/__init__.py +10 -8
  188. esphome/components/packet_transport/packet_transport.cpp +2 -0
  189. esphome/components/pid/pid_controller.cpp +1 -1
  190. esphome/components/prometheus/prometheus_handler.cpp +239 -239
  191. esphome/components/psram/__init__.py +30 -28
  192. esphome/components/qmc5883l/qmc5883l.cpp +15 -0
  193. esphome/components/qmc5883l/qmc5883l.h +3 -0
  194. esphome/components/qmc5883l/sensor.py +31 -12
  195. esphome/components/remote_base/gobox_protocol.cpp +3 -3
  196. esphome/components/remote_receiver/__init__.py +14 -2
  197. esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
  198. esphome/components/remote_receiver/remote_receiver.h +4 -0
  199. esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
  200. esphome/components/remote_transmitter/__init__.py +2 -2
  201. esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
  202. esphome/components/rp2040/__init__.py +11 -11
  203. esphome/components/rtttl/rtttl.cpp +2 -2
  204. esphome/components/scd30/sensor.py +1 -1
  205. esphome/components/script/__init__.py +1 -1
  206. esphome/components/script/script.h +7 -7
  207. esphome/components/select/select.cpp +5 -4
  208. esphome/components/select/select_call.cpp +1 -1
  209. esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
  210. esphome/components/sensor/__init__.py +2 -0
  211. esphome/components/sha256/__init__.py +22 -0
  212. esphome/components/sha256/sha256.cpp +116 -0
  213. esphome/components/sha256/sha256.h +60 -0
  214. esphome/components/sim800l/sim800l.cpp +8 -4
  215. esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
  216. esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
  217. esphome/components/spi/__init__.py +0 -3
  218. esphome/components/split_buffer/__init__.py +5 -0
  219. esphome/components/split_buffer/split_buffer.cpp +133 -0
  220. esphome/components/split_buffer/split_buffer.h +40 -0
  221. esphome/components/sps30/sps30.cpp +14 -10
  222. esphome/components/sps30/sps30.h +2 -0
  223. esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
  224. esphome/components/st7789v/st7789v.cpp +3 -2
  225. esphome/components/statsd/statsd.cpp +1 -1
  226. esphome/components/substitutions/__init__.py +3 -1
  227. esphome/components/substitutions/jinja.py +13 -3
  228. esphome/components/sx126x/__init__.py +16 -0
  229. esphome/components/sx126x/sx126x.cpp +15 -1
  230. esphome/components/sx126x/sx126x.h +9 -1
  231. esphome/components/sx126x/sx126x_reg.h +2 -0
  232. esphome/components/text_sensor/text_sensor.cpp +16 -0
  233. esphome/components/text_sensor/text_sensor.h +3 -10
  234. esphome/components/tormatic/tormatic_cover.cpp +1 -1
  235. esphome/components/tuya/select/tuya_select.cpp +1 -1
  236. esphome/components/tuya/tuya.cpp +29 -4
  237. esphome/components/uart/__init__.py +36 -26
  238. esphome/components/uart/uart.h +6 -0
  239. esphome/components/uart/uart_component.cpp +8 -0
  240. esphome/components/uart/uart_component.h +28 -0
  241. esphome/components/uart/uart_component_esp_idf.cpp +64 -10
  242. esphome/components/uart/uart_component_esp_idf.h +5 -2
  243. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  244. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
  245. esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
  246. esphome/components/usb_host/__init__.py +2 -1
  247. esphome/components/usb_host/usb_host.h +82 -13
  248. esphome/components/usb_host/usb_host_client.cpp +180 -24
  249. esphome/components/usb_host/usb_host_component.cpp +1 -1
  250. esphome/components/usb_uart/__init__.py +0 -1
  251. esphome/components/usb_uart/ch34x.cpp +4 -4
  252. esphome/components/usb_uart/cp210x.cpp +3 -3
  253. esphome/components/usb_uart/usb_uart.cpp +88 -32
  254. esphome/components/usb_uart/usb_uart.h +30 -6
  255. esphome/components/valve/valve.cpp +1 -0
  256. esphome/components/veml7700/veml7700.cpp +7 -6
  257. esphome/components/version/version_text_sensor.cpp +2 -1
  258. esphome/components/voice_assistant/voice_assistant.cpp +3 -3
  259. esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
  260. esphome/components/web_server/list_entities.cpp +3 -4
  261. esphome/components/web_server/list_entities.h +8 -10
  262. esphome/components/web_server/ota/__init__.py +1 -1
  263. esphome/components/web_server/ota/ota_web_server.cpp +9 -3
  264. esphome/components/web_server/web_server.cpp +509 -404
  265. esphome/components/web_server/web_server.h +5 -6
  266. esphome/components/web_server/web_server_v1.cpp +21 -19
  267. esphome/components/web_server_base/__init__.py +5 -2
  268. esphome/components/web_server_base/web_server_base.h +27 -7
  269. esphome/components/web_server_idf/__init__.py +1 -1
  270. esphome/components/web_server_idf/multipart.cpp +2 -2
  271. esphome/components/web_server_idf/multipart.h +2 -2
  272. esphome/components/web_server_idf/utils.cpp +2 -2
  273. esphome/components/web_server_idf/utils.h +2 -2
  274. esphome/components/web_server_idf/web_server_idf.cpp +118 -26
  275. esphome/components/web_server_idf/web_server_idf.h +12 -10
  276. esphome/components/wifi/__init__.py +13 -11
  277. esphome/components/wifi/wifi_component.cpp +73 -56
  278. esphome/components/wifi/wifi_component.h +4 -4
  279. esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
  280. esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
  281. esphome/components/wireguard/__init__.py +1 -1
  282. esphome/components/wts01/__init__.py +0 -0
  283. esphome/components/wts01/sensor.py +41 -0
  284. esphome/components/wts01/wts01.cpp +91 -0
  285. esphome/components/wts01/wts01.h +27 -0
  286. esphome/components/zephyr/__init__.py +5 -5
  287. esphome/components/zwave_proxy/__init__.py +43 -0
  288. esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
  289. esphome/components/zwave_proxy/zwave_proxy.h +93 -0
  290. esphome/config.py +79 -24
  291. esphome/config_validation.py +13 -15
  292. esphome/const.py +9 -2
  293. esphome/core/__init__.py +31 -22
  294. esphome/core/component.cpp +28 -18
  295. esphome/core/component_iterator.h +2 -1
  296. esphome/core/config.py +15 -15
  297. esphome/core/defines.h +19 -0
  298. esphome/core/hash_base.h +56 -0
  299. esphome/core/helpers.cpp +19 -3
  300. esphome/core/helpers.h +26 -0
  301. esphome/core/scheduler.cpp +5 -21
  302. esphome/core/scheduler.h +19 -8
  303. esphome/core/string_ref.h +1 -1
  304. esphome/core/time.cpp +5 -5
  305. esphome/cpp_generator.py +4 -29
  306. esphome/dashboard/const.py +21 -4
  307. esphome/dashboard/core.py +10 -8
  308. esphome/dashboard/dns.py +15 -0
  309. esphome/dashboard/entries.py +15 -21
  310. esphome/dashboard/models.py +76 -0
  311. esphome/dashboard/settings.py +7 -7
  312. esphome/dashboard/status/mdns.py +46 -2
  313. esphome/dashboard/web_server.py +367 -93
  314. esphome/espota2.py +111 -31
  315. esphome/external_files.py +6 -7
  316. esphome/git.py +8 -0
  317. esphome/helpers.py +124 -77
  318. esphome/loader.py +8 -9
  319. esphome/platformio_api.py +25 -18
  320. esphome/storage_json.py +26 -21
  321. esphome/types.py +30 -2
  322. esphome/util.py +32 -16
  323. esphome/vscode.py +8 -8
  324. esphome/wizard.py +10 -10
  325. esphome/writer.py +50 -15
  326. esphome/yaml_util.py +37 -31
  327. esphome/zeroconf.py +12 -3
  328. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/METADATA +11 -11
  329. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/RECORD +333 -313
  330. esphome/components/event_emitter/__init__.py +0 -5
  331. esphome/components/event_emitter/event_emitter.cpp +0 -14
  332. esphome/components/event_emitter/event_emitter.h +0 -63
  333. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
  334. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
  335. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
  336. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
  337. esphome/components/uart/uart_component_esp32_arduino.h +0 -60
  338. esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
  339. esphome/core/string_ref.cpp +0 -12
  340. esphome/dashboard/util/file.py +0 -63
  341. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/WHEEL +0 -0
  342. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/entry_points.txt +0 -0
  343. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/licenses/LICENSE +0 -0
  344. {esphome-2025.9.2.dist-info → esphome-2025.10.0b1.dist-info}/top_level.txt +0 -0
@@ -36,9 +36,8 @@ from esphome.const import (
36
36
  __version__,
37
37
  )
38
38
  from esphome.core import CORE, HexInt, TimePeriod
39
- from esphome.cpp_generator import RawExpression
40
39
  import esphome.final_validate as fv
41
- from esphome.helpers import copy_file_if_changed, mkdir_p, write_file_if_changed
40
+ from esphome.helpers import copy_file_if_changed, write_file_if_changed
42
41
  from esphome.types import ConfigType
43
42
  from esphome.writer import clean_cmake_cache
44
43
 
@@ -157,8 +156,6 @@ def set_core_data(config):
157
156
  conf = config[CONF_FRAMEWORK]
158
157
  if conf[CONF_TYPE] == FRAMEWORK_ESP_IDF:
159
158
  CORE.data[KEY_CORE][KEY_TARGET_FRAMEWORK] = "esp-idf"
160
- CORE.data[KEY_ESP32][KEY_SDKCONFIG_OPTIONS] = {}
161
- CORE.data[KEY_ESP32][KEY_COMPONENTS] = {}
162
159
  elif conf[CONF_TYPE] == FRAMEWORK_ARDUINO:
163
160
  CORE.data[KEY_CORE][KEY_TARGET_FRAMEWORK] = "arduino"
164
161
  if variant not in ARDUINO_ALLOWED_VARIANTS:
@@ -166,6 +163,8 @@ def set_core_data(config):
166
163
  f"ESPHome does not support using the Arduino framework for the {variant}. Please use the ESP-IDF framework instead.",
167
164
  path=[CONF_FRAMEWORK, CONF_TYPE],
168
165
  )
166
+ CORE.data[KEY_ESP32][KEY_SDKCONFIG_OPTIONS] = {}
167
+ CORE.data[KEY_ESP32][KEY_COMPONENTS] = {}
169
168
  CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] = cv.Version.parse(
170
169
  config[CONF_FRAMEWORK][CONF_VERSION]
171
170
  )
@@ -236,8 +235,6 @@ SdkconfigValueType = bool | int | HexInt | str | RawSdkconfigValue
236
235
 
237
236
  def add_idf_sdkconfig_option(name: str, value: SdkconfigValueType):
238
237
  """Set an esp-idf sdkconfig value."""
239
- if not CORE.using_esp_idf:
240
- raise ValueError("Not an esp-idf project")
241
238
  CORE.data[KEY_ESP32][KEY_SDKCONFIG_OPTIONS][name] = value
242
239
 
243
240
 
@@ -252,8 +249,6 @@ def add_idf_component(
252
249
  submodules: list[str] | None = None,
253
250
  ):
254
251
  """Add an esp-idf component to the project."""
255
- if not CORE.using_esp_idf:
256
- raise ValueError("Not an esp-idf project")
257
252
  if not repo and not ref and not path:
258
253
  raise ValueError("Requires at least one of repo, ref or path")
259
254
  if refresh or submodules or components:
@@ -277,14 +272,14 @@ def add_idf_component(
277
272
  }
278
273
 
279
274
 
280
- def add_extra_script(stage: str, filename: str, path: str):
275
+ def add_extra_script(stage: str, filename: str, path: Path):
281
276
  """Add an extra script to the project."""
282
277
  key = f"{stage}:{filename}"
283
278
  if add_extra_build_file(filename, path):
284
279
  cg.add_platformio_option("extra_scripts", [key])
285
280
 
286
281
 
287
- def add_extra_build_file(filename: str, path: str) -> bool:
282
+ def add_extra_build_file(filename: str, path: Path) -> bool:
288
283
  """Add an extra build file to the project."""
289
284
  if filename not in CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES]:
290
285
  CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES][filename] = {
@@ -301,14 +296,9 @@ def _format_framework_arduino_version(ver: cv.Version) -> str:
301
296
  return f"pioarduino/framework-arduinoespressif32@https://github.com/espressif/arduino-esp32/releases/download/{str(ver)}/esp32-{str(ver)}.zip"
302
297
 
303
298
 
304
- def _format_framework_espidf_version(
305
- ver: cv.Version, release: str, for_platformio: bool
306
- ) -> str:
307
- # format the given arduino (https://github.com/espressif/esp-idf/releases) version to
299
+ def _format_framework_espidf_version(ver: cv.Version, release: str) -> str:
300
+ # format the given espidf (https://github.com/pioarduino/esp-idf/releases) version to
308
301
  # a PIO platformio/framework-espidf value
309
- # List of package versions: https://api.registry.platformio.org/v3/packages/platformio/tool/framework-espidf
310
- if for_platformio:
311
- return f"platformio/framework-espidf@~3.{ver.major}{ver.minor:02d}{ver.patch:02d}.0"
312
302
  if release:
313
303
  return f"pioarduino/framework-espidf@https://github.com/pioarduino/esp-idf/releases/download/v{str(ver)}.{release}/esp-idf-v{str(ver)}.zip"
314
304
  return f"pioarduino/framework-espidf@https://github.com/pioarduino/esp-idf/releases/download/v{str(ver)}/esp-idf-v{str(ver)}.zip"
@@ -322,154 +312,114 @@ def _format_framework_espidf_version(
322
312
 
323
313
  # The default/recommended arduino framework version
324
314
  # - https://github.com/espressif/arduino-esp32/releases
325
- RECOMMENDED_ARDUINO_FRAMEWORK_VERSION = cv.Version(3, 2, 1)
326
- # The platform-espressif32 version to use for arduino frameworks
327
- # - https://github.com/pioarduino/platform-espressif32/releases
328
- ARDUINO_PLATFORM_VERSION = cv.Version(54, 3, 21, "2")
315
+ ARDUINO_FRAMEWORK_VERSION_LOOKUP = {
316
+ "recommended": cv.Version(3, 2, 1),
317
+ "latest": cv.Version(3, 3, 1),
318
+ "dev": cv.Version(3, 3, 1),
319
+ }
320
+ ARDUINO_PLATFORM_VERSION_LOOKUP = {
321
+ cv.Version(3, 3, 1): cv.Version(55, 3, 31),
322
+ cv.Version(3, 3, 0): cv.Version(55, 3, 30, "2"),
323
+ cv.Version(3, 2, 1): cv.Version(54, 3, 21, "2"),
324
+ cv.Version(3, 2, 0): cv.Version(54, 3, 20),
325
+ cv.Version(3, 1, 3): cv.Version(53, 3, 13),
326
+ cv.Version(3, 1, 2): cv.Version(53, 3, 12),
327
+ cv.Version(3, 1, 1): cv.Version(53, 3, 11),
328
+ cv.Version(3, 1, 0): cv.Version(53, 3, 10),
329
+ }
329
330
 
330
331
  # The default/recommended esp-idf framework version
331
332
  # - https://github.com/espressif/esp-idf/releases
332
- # - https://api.registry.platformio.org/v3/packages/platformio/tool/framework-espidf
333
- RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION = cv.Version(5, 4, 2)
334
- # The platformio/espressif32 version to use for esp-idf frameworks
335
- # - https://github.com/platformio/platform-espressif32/releases
336
- # - https://api.registry.platformio.org/v3/packages/platformio/platform/espressif32
337
- ESP_IDF_PLATFORM_VERSION = cv.Version(54, 3, 21, "2")
338
-
339
- # List based on https://registry.platformio.org/tools/platformio/framework-espidf/versions
340
- SUPPORTED_PLATFORMIO_ESP_IDF_5X = [
341
- cv.Version(5, 3, 1),
342
- cv.Version(5, 3, 0),
343
- cv.Version(5, 2, 2),
344
- cv.Version(5, 2, 1),
345
- cv.Version(5, 1, 2),
346
- cv.Version(5, 1, 1),
347
- cv.Version(5, 1, 0),
348
- cv.Version(5, 0, 2),
349
- cv.Version(5, 0, 1),
350
- cv.Version(5, 0, 0),
351
- ]
333
+ ESP_IDF_FRAMEWORK_VERSION_LOOKUP = {
334
+ "recommended": cv.Version(5, 4, 2),
335
+ "latest": cv.Version(5, 5, 1),
336
+ "dev": cv.Version(5, 5, 1),
337
+ }
338
+ ESP_IDF_PLATFORM_VERSION_LOOKUP = {
339
+ cv.Version(5, 5, 1): cv.Version(55, 3, 31),
340
+ cv.Version(5, 5, 0): cv.Version(55, 3, 31),
341
+ cv.Version(5, 4, 2): cv.Version(54, 3, 21, "2"),
342
+ cv.Version(5, 4, 1): cv.Version(54, 3, 21, "2"),
343
+ cv.Version(5, 4, 0): cv.Version(54, 3, 21, "2"),
344
+ cv.Version(5, 3, 2): cv.Version(53, 3, 13),
345
+ cv.Version(5, 3, 1): cv.Version(53, 3, 13),
346
+ cv.Version(5, 3, 0): cv.Version(53, 3, 13),
347
+ cv.Version(5, 1, 6): cv.Version(51, 3, 7),
348
+ cv.Version(5, 1, 5): cv.Version(51, 3, 7),
349
+ }
352
350
 
353
- # pioarduino versions that don't require a release number
354
- # List based on https://github.com/pioarduino/esp-idf/releases
355
- SUPPORTED_PIOARDUINO_ESP_IDF_5X = [
356
- cv.Version(5, 5, 0),
357
- cv.Version(5, 4, 2),
358
- cv.Version(5, 4, 1),
359
- cv.Version(5, 4, 0),
360
- cv.Version(5, 3, 3),
361
- cv.Version(5, 3, 2),
362
- cv.Version(5, 3, 1),
363
- cv.Version(5, 3, 0),
364
- cv.Version(5, 1, 5),
365
- cv.Version(5, 1, 6),
366
- ]
351
+ # The platform-espressif32 version
352
+ # - https://github.com/pioarduino/platform-espressif32/releases
353
+ PLATFORM_VERSION_LOOKUP = {
354
+ "recommended": cv.Version(54, 3, 21, "2"),
355
+ "latest": cv.Version(55, 3, 31),
356
+ "dev": "https://github.com/pioarduino/platform-espressif32.git#develop",
357
+ }
367
358
 
368
359
 
369
- def _arduino_check_versions(value):
360
+ def _check_versions(value):
370
361
  value = value.copy()
371
- lookups = {
372
- "dev": (cv.Version(3, 2, 1), "https://github.com/espressif/arduino-esp32.git"),
373
- "latest": (cv.Version(3, 2, 1), None),
374
- "recommended": (RECOMMENDED_ARDUINO_FRAMEWORK_VERSION, None),
375
- }
376
-
377
- if value[CONF_VERSION] in lookups:
378
- if CONF_SOURCE in value:
362
+
363
+ if value[CONF_VERSION] in PLATFORM_VERSION_LOOKUP:
364
+ if CONF_SOURCE in value or CONF_PLATFORM_VERSION in value:
379
365
  raise cv.Invalid(
380
- "Framework version needs to be explicitly specified when custom source is used."
366
+ "Version needs to be explicitly set when a custom source or platform_version is used."
381
367
  )
382
368
 
383
- version, source = lookups[value[CONF_VERSION]]
369
+ platform_lookup = PLATFORM_VERSION_LOOKUP[value[CONF_VERSION]]
370
+ value[CONF_PLATFORM_VERSION] = _parse_platform_version(str(platform_lookup))
371
+
372
+ if value[CONF_TYPE] == FRAMEWORK_ARDUINO:
373
+ version = ARDUINO_FRAMEWORK_VERSION_LOOKUP[value[CONF_VERSION]]
374
+ else:
375
+ version = ESP_IDF_FRAMEWORK_VERSION_LOOKUP[value[CONF_VERSION]]
384
376
  else:
385
377
  version = cv.Version.parse(cv.version_number(value[CONF_VERSION]))
386
- source = value.get(CONF_SOURCE, None)
387
378
 
388
379
  value[CONF_VERSION] = str(version)
389
- value[CONF_SOURCE] = source or _format_framework_arduino_version(version)
390
-
391
- value[CONF_PLATFORM_VERSION] = value.get(
392
- CONF_PLATFORM_VERSION, _parse_platform_version(str(ARDUINO_PLATFORM_VERSION))
393
- )
394
-
395
- if value[CONF_SOURCE].startswith("http"):
396
- # prefix is necessary or platformio will complain with a cryptic error
397
- value[CONF_SOURCE] = f"framework-arduinoespressif32@{value[CONF_SOURCE]}"
398
380
 
399
- if version != RECOMMENDED_ARDUINO_FRAMEWORK_VERSION:
400
- _LOGGER.warning(
401
- "The selected Arduino framework version is not the recommended one. "
402
- "If there are connectivity or build issues please remove the manual version."
381
+ if value[CONF_TYPE] == FRAMEWORK_ARDUINO:
382
+ if version < cv.Version(3, 0, 0):
383
+ raise cv.Invalid("Only Arduino 3.0+ is supported.")
384
+ recommended_version = ARDUINO_FRAMEWORK_VERSION_LOOKUP["recommended"]
385
+ platform_lookup = ARDUINO_PLATFORM_VERSION_LOOKUP.get(version)
386
+ value[CONF_SOURCE] = value.get(
387
+ CONF_SOURCE, _format_framework_arduino_version(version)
403
388
  )
404
-
405
- return value
406
-
407
-
408
- def _esp_idf_check_versions(value):
409
- value = value.copy()
410
- lookups = {
411
- "dev": (cv.Version(5, 4, 2), "https://github.com/espressif/esp-idf.git"),
412
- "latest": (cv.Version(5, 2, 2), None),
413
- "recommended": (RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION, None),
414
- }
415
-
416
- if value[CONF_VERSION] in lookups:
417
- if CONF_SOURCE in value:
418
- raise cv.Invalid(
419
- "Framework version needs to be explicitly specified when custom source is used."
389
+ if value[CONF_SOURCE].startswith("http"):
390
+ value[CONF_SOURCE] = (
391
+ f"pioarduino/framework-arduinoespressif32@{value[CONF_SOURCE]}"
420
392
  )
421
-
422
- version, source = lookups[value[CONF_VERSION]]
423
393
  else:
424
- version = cv.Version.parse(cv.version_number(value[CONF_VERSION]))
425
- source = value.get(CONF_SOURCE, None)
426
-
427
- if version < cv.Version(5, 0, 0):
428
- raise cv.Invalid("Only ESP-IDF 5.0+ is supported.")
429
-
430
- # flag this for later *before* we set value[CONF_PLATFORM_VERSION] below
431
- has_platform_ver = CONF_PLATFORM_VERSION in value
432
-
433
- value[CONF_PLATFORM_VERSION] = value.get(
434
- CONF_PLATFORM_VERSION, _parse_platform_version(str(ESP_IDF_PLATFORM_VERSION))
435
- )
436
-
437
- if (
438
- is_platformio := _platform_is_platformio(value[CONF_PLATFORM_VERSION])
439
- ) and version not in SUPPORTED_PLATFORMIO_ESP_IDF_5X:
440
- raise cv.Invalid(
441
- f"ESP-IDF {str(version)} not supported by platformio/espressif32"
394
+ if version < cv.Version(5, 0, 0):
395
+ raise cv.Invalid("Only ESP-IDF 5.0+ is supported.")
396
+ recommended_version = ESP_IDF_FRAMEWORK_VERSION_LOOKUP["recommended"]
397
+ platform_lookup = ESP_IDF_PLATFORM_VERSION_LOOKUP.get(version)
398
+ value[CONF_SOURCE] = value.get(
399
+ CONF_SOURCE,
400
+ _format_framework_espidf_version(version, value.get(CONF_RELEASE, None)),
442
401
  )
402
+ if value[CONF_SOURCE].startswith("http"):
403
+ value[CONF_SOURCE] = f"pioarduino/framework-espidf@{value[CONF_SOURCE]}"
443
404
 
444
- if (
445
- version in SUPPORTED_PLATFORMIO_ESP_IDF_5X
446
- and version not in SUPPORTED_PIOARDUINO_ESP_IDF_5X
447
- ) and not has_platform_ver:
448
- raise cv.Invalid(
449
- f"ESP-IDF {value[CONF_VERSION]} may be supported by platformio/espressif32; please specify '{CONF_PLATFORM_VERSION}'"
450
- )
405
+ if CONF_PLATFORM_VERSION not in value:
406
+ if platform_lookup is None:
407
+ raise cv.Invalid(
408
+ "Framework version not recognized; please specify platform_version"
409
+ )
410
+ value[CONF_PLATFORM_VERSION] = _parse_platform_version(str(platform_lookup))
451
411
 
452
- if (
453
- not is_platformio
454
- and CONF_RELEASE not in value
455
- and version not in SUPPORTED_PIOARDUINO_ESP_IDF_5X
456
- ):
457
- raise cv.Invalid(
458
- f"ESP-IDF {value[CONF_VERSION]} is not available with pioarduino; you may need to specify '{CONF_RELEASE}'"
412
+ if version != recommended_version:
413
+ _LOGGER.warning(
414
+ "The selected framework version is not the recommended one. "
415
+ "If there are connectivity or build issues please remove the manual version."
459
416
  )
460
417
 
461
- value[CONF_VERSION] = str(version)
462
- value[CONF_SOURCE] = source or _format_framework_espidf_version(
463
- version, value.get(CONF_RELEASE, None), is_platformio
464
- )
465
-
466
- if value[CONF_SOURCE].startswith("http"):
467
- # prefix is necessary or platformio will complain with a cryptic error
468
- value[CONF_SOURCE] = f"framework-espidf@{value[CONF_SOURCE]}"
469
-
470
- if version != RECOMMENDED_ESP_IDF_FRAMEWORK_VERSION:
418
+ if value[CONF_PLATFORM_VERSION] != _parse_platform_version(
419
+ str(PLATFORM_VERSION_LOOKUP["recommended"])
420
+ ):
471
421
  _LOGGER.warning(
472
- "The selected ESP-IDF framework version is not the recommended one. "
422
+ "The selected platform version is not the recommended one. "
473
423
  "If there are connectivity or build issues please remove the manual version."
474
424
  )
475
425
 
@@ -479,26 +429,14 @@ def _esp_idf_check_versions(value):
479
429
  def _parse_platform_version(value):
480
430
  try:
481
431
  ver = cv.Version.parse(cv.version_number(value))
482
- if ver.major >= 50: # a pioarduino version
483
- release = f"{ver.major}.{ver.minor:02d}.{ver.patch:02d}"
484
- if ver.extra:
485
- release += f"-{ver.extra}"
486
- return f"https://github.com/pioarduino/platform-espressif32/releases/download/{release}/platform-espressif32.zip"
487
- # if platform version is a valid version constraint, prefix the default package
488
- cv.platformio_version_constraint(value)
489
- return f"platformio/espressif32@{value}"
432
+ release = f"{ver.major}.{ver.minor:02d}.{ver.patch:02d}"
433
+ if ver.extra:
434
+ release += f"-{ver.extra}"
435
+ return f"https://github.com/pioarduino/platform-espressif32/releases/download/{release}/platform-espressif32.zip"
490
436
  except cv.Invalid:
491
437
  return value
492
438
 
493
439
 
494
- def _platform_is_platformio(value):
495
- try:
496
- ver = cv.Version.parse(cv.version_number(value))
497
- return ver.major < 50
498
- except cv.Invalid:
499
- return "platformio" in value
500
-
501
-
502
440
  def _detect_variant(value):
503
441
  board = value.get(CONF_BOARD)
504
442
  variant = value.get(CONF_VARIANT)
@@ -588,24 +526,6 @@ def final_validate(config):
588
526
  return config
589
527
 
590
528
 
591
- ARDUINO_FRAMEWORK_SCHEMA = cv.All(
592
- cv.Schema(
593
- {
594
- cv.Optional(CONF_VERSION, default="recommended"): cv.string_strict,
595
- cv.Optional(CONF_SOURCE): cv.string_strict,
596
- cv.Optional(CONF_PLATFORM_VERSION): _parse_platform_version,
597
- cv.Optional(CONF_ADVANCED, default={}): cv.Schema(
598
- {
599
- cv.Optional(
600
- CONF_IGNORE_EFUSE_CUSTOM_MAC, default=False
601
- ): cv.boolean,
602
- }
603
- ),
604
- }
605
- ),
606
- _arduino_check_versions,
607
- )
608
-
609
529
  CONF_SDKCONFIG_OPTIONS = "sdkconfig_options"
610
530
  CONF_ENABLE_LWIP_DHCP_SERVER = "enable_lwip_dhcp_server"
611
531
  CONF_ENABLE_LWIP_MDNS_QUERIES = "enable_lwip_mdns_queries"
@@ -624,9 +544,14 @@ def _validate_idf_component(config: ConfigType) -> ConfigType:
624
544
  return config
625
545
 
626
546
 
627
- ESP_IDF_FRAMEWORK_SCHEMA = cv.All(
547
+ FRAMEWORK_ESP_IDF = "esp-idf"
548
+ FRAMEWORK_ARDUINO = "arduino"
549
+ FRAMEWORK_SCHEMA = cv.All(
628
550
  cv.Schema(
629
551
  {
552
+ cv.Optional(CONF_TYPE, default=FRAMEWORK_ARDUINO): cv.one_of(
553
+ FRAMEWORK_ESP_IDF, FRAMEWORK_ARDUINO
554
+ ),
630
555
  cv.Optional(CONF_VERSION, default="recommended"): cv.string_strict,
631
556
  cv.Optional(CONF_RELEASE): cv.string_strict,
632
557
  cv.Optional(CONF_SOURCE): cv.string_strict,
@@ -690,7 +615,7 @@ ESP_IDF_FRAMEWORK_SCHEMA = cv.All(
690
615
  ),
691
616
  }
692
617
  ),
693
- _esp_idf_check_versions,
618
+ _check_versions,
694
619
  )
695
620
 
696
621
 
@@ -757,32 +682,18 @@ def _set_default_framework(config):
757
682
  config = config.copy()
758
683
 
759
684
  variant = config[CONF_VARIANT]
685
+ config[CONF_FRAMEWORK] = FRAMEWORK_SCHEMA({})
760
686
  if variant in ARDUINO_ALLOWED_VARIANTS:
761
- config[CONF_FRAMEWORK] = ARDUINO_FRAMEWORK_SCHEMA({})
762
687
  config[CONF_FRAMEWORK][CONF_TYPE] = FRAMEWORK_ARDUINO
763
- # Show the migration message
764
688
  _show_framework_migration_message(
765
689
  config.get(CONF_NAME, "This device"), variant
766
690
  )
767
691
  else:
768
- config[CONF_FRAMEWORK] = ESP_IDF_FRAMEWORK_SCHEMA({})
769
692
  config[CONF_FRAMEWORK][CONF_TYPE] = FRAMEWORK_ESP_IDF
770
693
 
771
694
  return config
772
695
 
773
696
 
774
- FRAMEWORK_ESP_IDF = "esp-idf"
775
- FRAMEWORK_ARDUINO = "arduino"
776
- FRAMEWORK_SCHEMA = cv.typed_schema(
777
- {
778
- FRAMEWORK_ESP_IDF: ESP_IDF_FRAMEWORK_SCHEMA,
779
- FRAMEWORK_ARDUINO: ARDUINO_FRAMEWORK_SCHEMA,
780
- },
781
- lower=True,
782
- space="-",
783
- )
784
-
785
-
786
697
  FLASH_SIZES = [
787
698
  "2MB",
788
699
  "4MB",
@@ -837,6 +748,8 @@ async def to_code(config):
837
748
 
838
749
  conf = config[CONF_FRAMEWORK]
839
750
  cg.add_platformio_option("platform", conf[CONF_PLATFORM_VERSION])
751
+ if CONF_SOURCE in conf:
752
+ cg.add_platformio_option("platform_packages", [conf[CONF_SOURCE]])
840
753
 
841
754
  if conf[CONF_ADVANCED][CONF_IGNORE_EFUSE_CUSTOM_MAC]:
842
755
  cg.add_define("USE_ESP32_IGNORE_EFUSE_CUSTOM_MAC")
@@ -847,142 +760,146 @@ async def to_code(config):
847
760
  add_extra_script(
848
761
  "post",
849
762
  "post_build.py",
850
- os.path.join(os.path.dirname(__file__), "post_build.py.script"),
763
+ Path(__file__).parent / "post_build.py.script",
851
764
  )
852
765
 
853
- freq = config[CONF_CPU_FREQUENCY][:-3]
854
766
  if conf[CONF_TYPE] == FRAMEWORK_ESP_IDF:
855
767
  cg.add_platformio_option("framework", "espidf")
856
768
  cg.add_build_flag("-DUSE_ESP_IDF")
857
769
  cg.add_build_flag("-DUSE_ESP32_FRAMEWORK_ESP_IDF")
858
- cg.add_build_flag("-Wno-nonnull-compare")
859
-
860
- cg.add_platformio_option("platform_packages", [conf[CONF_SOURCE]])
861
-
862
- add_idf_sdkconfig_option(f"CONFIG_IDF_TARGET_{variant}", True)
863
- add_idf_sdkconfig_option(
864
- f"CONFIG_ESPTOOLPY_FLASHSIZE_{config[CONF_FLASH_SIZE]}", True
770
+ else:
771
+ cg.add_platformio_option("framework", "arduino, espidf")
772
+ cg.add_build_flag("-DUSE_ARDUINO")
773
+ cg.add_build_flag("-DUSE_ESP32_FRAMEWORK_ARDUINO")
774
+ cg.add_platformio_option(
775
+ "board_build.embed_txtfiles",
776
+ [
777
+ "managed_components/espressif__esp_insights/server_certs/https_server.crt",
778
+ "managed_components/espressif__esp_rainmaker/server_certs/rmaker_mqtt_server.crt",
779
+ "managed_components/espressif__esp_rainmaker/server_certs/rmaker_claim_service_server.crt",
780
+ "managed_components/espressif__esp_rainmaker/server_certs/rmaker_ota_server.crt",
781
+ ],
865
782
  )
866
- add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_SINGLE_APP", False)
867
- add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_CUSTOM", True)
868
- add_idf_sdkconfig_option(
869
- "CONFIG_PARTITION_TABLE_CUSTOM_FILENAME", "partitions.csv"
783
+ cg.add_define(
784
+ "USE_ARDUINO_VERSION_CODE",
785
+ cg.RawExpression(
786
+ f"VERSION_CODE({framework_ver.major}, {framework_ver.minor}, {framework_ver.patch})"
787
+ ),
870
788
  )
789
+ add_idf_sdkconfig_option("CONFIG_AUTOSTART_ARDUINO", True)
790
+ add_idf_sdkconfig_option("CONFIG_MBEDTLS_PSK_MODES", True)
791
+ add_idf_sdkconfig_option("CONFIG_MBEDTLS_CERTIFICATE_BUNDLE", True)
871
792
 
872
- # Increase freertos tick speed from 100Hz to 1kHz so that delay() resolution is 1ms
873
- add_idf_sdkconfig_option("CONFIG_FREERTOS_HZ", 1000)
874
-
875
- # Setup watchdog
876
- add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT", True)
877
- add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_PANIC", True)
878
- add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0", False)
879
- add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1", False)
880
-
881
- # Disable dynamic log level control to save memory
882
- add_idf_sdkconfig_option("CONFIG_LOG_DYNAMIC_LEVEL_CONTROL", False)
883
-
884
- # Set default CPU frequency
885
- add_idf_sdkconfig_option(f"CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_{freq}", True)
886
-
887
- # Apply LWIP optimization settings
888
- advanced = conf[CONF_ADVANCED]
889
- # DHCP server: only disable if explicitly set to false
890
- # WiFi component handles its own optimization when AP mode is not used
891
- if (
892
- CONF_ENABLE_LWIP_DHCP_SERVER in advanced
893
- and not advanced[CONF_ENABLE_LWIP_DHCP_SERVER]
894
- ):
895
- add_idf_sdkconfig_option("CONFIG_LWIP_DHCPS", False)
896
- if not advanced.get(CONF_ENABLE_LWIP_MDNS_QUERIES, True):
897
- add_idf_sdkconfig_option("CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES", False)
898
- if not advanced.get(CONF_ENABLE_LWIP_BRIDGE_INTERFACE, False):
899
- add_idf_sdkconfig_option("CONFIG_LWIP_BRIDGEIF_MAX_PORTS", 0)
900
- if advanced.get(CONF_EXECUTE_FROM_PSRAM, False):
901
- add_idf_sdkconfig_option("CONFIG_SPIRAM_FETCH_INSTRUCTIONS", True)
902
- add_idf_sdkconfig_option("CONFIG_SPIRAM_RODATA", True)
903
-
904
- # Apply LWIP core locking for better socket performance
905
- # This is already enabled by default in Arduino framework, where it provides
906
- # significant performance benefits. Our benchmarks show socket operations are
907
- # 24-200% faster with core locking enabled:
908
- # - select() on 4 sockets: ~190μs (Arduino/core locking) vs ~235μs (ESP-IDF default)
909
- # - Up to 200% slower under load when all operations queue through tcpip_thread
910
- # Enabling this makes ESP-IDF socket performance match Arduino framework.
911
- if advanced.get(CONF_ENABLE_LWIP_TCPIP_CORE_LOCKING, True):
912
- add_idf_sdkconfig_option("CONFIG_LWIP_TCPIP_CORE_LOCKING", True)
913
- if advanced.get(CONF_ENABLE_LWIP_CHECK_THREAD_SAFETY, True):
914
- add_idf_sdkconfig_option("CONFIG_LWIP_CHECK_THREAD_SAFETY", True)
915
-
916
- cg.add_platformio_option("board_build.partitions", "partitions.csv")
917
- if CONF_PARTITIONS in config:
918
- add_extra_build_file(
919
- "partitions.csv", CORE.relative_config_path(config[CONF_PARTITIONS])
920
- )
793
+ cg.add_build_flag("-Wno-nonnull-compare")
921
794
 
922
- if assertion_level := advanced.get(CONF_ASSERTION_LEVEL):
923
- for key, flag in ASSERTION_LEVELS.items():
924
- add_idf_sdkconfig_option(flag, assertion_level == key)
795
+ add_idf_sdkconfig_option(f"CONFIG_IDF_TARGET_{variant}", True)
796
+ add_idf_sdkconfig_option(
797
+ f"CONFIG_ESPTOOLPY_FLASHSIZE_{config[CONF_FLASH_SIZE]}", True
798
+ )
799
+ add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_SINGLE_APP", False)
800
+ add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_CUSTOM", True)
801
+ add_idf_sdkconfig_option("CONFIG_PARTITION_TABLE_CUSTOM_FILENAME", "partitions.csv")
925
802
 
926
- add_idf_sdkconfig_option("CONFIG_COMPILER_OPTIMIZATION_DEFAULT", False)
927
- compiler_optimization = advanced.get(CONF_COMPILER_OPTIMIZATION)
928
- for key, flag in COMPILER_OPTIMIZATIONS.items():
929
- add_idf_sdkconfig_option(flag, compiler_optimization == key)
803
+ # Increase freertos tick speed from 100Hz to 1kHz so that delay() resolution is 1ms
804
+ add_idf_sdkconfig_option("CONFIG_FREERTOS_HZ", 1000)
930
805
 
931
- add_idf_sdkconfig_option(
932
- "CONFIG_LWIP_ESP_LWIP_ASSERT",
933
- conf[CONF_ADVANCED][CONF_ENABLE_LWIP_ASSERT],
934
- )
806
+ # Setup watchdog
807
+ add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT", True)
808
+ add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_PANIC", True)
809
+ add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0", False)
810
+ add_idf_sdkconfig_option("CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1", False)
935
811
 
936
- if advanced.get(CONF_IGNORE_EFUSE_MAC_CRC):
937
- add_idf_sdkconfig_option("CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR", True)
938
- add_idf_sdkconfig_option(
939
- "CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE", False
940
- )
941
- if advanced.get(CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES):
942
- _LOGGER.warning(
943
- "Using experimental features in ESP-IDF may result in unexpected failures."
944
- )
945
- add_idf_sdkconfig_option("CONFIG_IDF_EXPERIMENTAL_FEATURES", True)
812
+ # Disable dynamic log level control to save memory
813
+ add_idf_sdkconfig_option("CONFIG_LOG_DYNAMIC_LEVEL_CONTROL", False)
946
814
 
947
- cg.add_define(
948
- "USE_ESP_IDF_VERSION_CODE",
949
- cg.RawExpression(
950
- f"VERSION_CODE({framework_ver.major}, {framework_ver.minor}, {framework_ver.patch})"
951
- ),
815
+ # Set default CPU frequency
816
+ add_idf_sdkconfig_option(
817
+ f"CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_{config[CONF_CPU_FREQUENCY][:-3]}", True
818
+ )
819
+
820
+ # Apply LWIP optimization settings
821
+ advanced = conf[CONF_ADVANCED]
822
+ # DHCP server: only disable if explicitly set to false
823
+ # WiFi component handles its own optimization when AP mode is not used
824
+ # When using Arduino with Ethernet, DHCP server functions must be available
825
+ # for the Network library to compile, even if not actively used
826
+ if (
827
+ CONF_ENABLE_LWIP_DHCP_SERVER in advanced
828
+ and not advanced[CONF_ENABLE_LWIP_DHCP_SERVER]
829
+ and not (
830
+ conf[CONF_TYPE] == FRAMEWORK_ARDUINO
831
+ and "ethernet" in CORE.loaded_integrations
952
832
  )
833
+ ):
834
+ add_idf_sdkconfig_option("CONFIG_LWIP_DHCPS", False)
835
+ if not advanced.get(CONF_ENABLE_LWIP_MDNS_QUERIES, True):
836
+ add_idf_sdkconfig_option("CONFIG_LWIP_DNS_SUPPORT_MDNS_QUERIES", False)
837
+ if not advanced.get(CONF_ENABLE_LWIP_BRIDGE_INTERFACE, False):
838
+ add_idf_sdkconfig_option("CONFIG_LWIP_BRIDGEIF_MAX_PORTS", 0)
839
+ if advanced.get(CONF_EXECUTE_FROM_PSRAM, False):
840
+ add_idf_sdkconfig_option("CONFIG_SPIRAM_FETCH_INSTRUCTIONS", True)
841
+ add_idf_sdkconfig_option("CONFIG_SPIRAM_RODATA", True)
842
+
843
+ # Apply LWIP core locking for better socket performance
844
+ # This is already enabled by default in Arduino framework, where it provides
845
+ # significant performance benefits. Our benchmarks show socket operations are
846
+ # 24-200% faster with core locking enabled:
847
+ # - select() on 4 sockets: ~190μs (Arduino/core locking) vs ~235μs (ESP-IDF default)
848
+ # - Up to 200% slower under load when all operations queue through tcpip_thread
849
+ # Enabling this makes ESP-IDF socket performance match Arduino framework.
850
+ if advanced.get(CONF_ENABLE_LWIP_TCPIP_CORE_LOCKING, True):
851
+ add_idf_sdkconfig_option("CONFIG_LWIP_TCPIP_CORE_LOCKING", True)
852
+ if advanced.get(CONF_ENABLE_LWIP_CHECK_THREAD_SAFETY, True):
853
+ add_idf_sdkconfig_option("CONFIG_LWIP_CHECK_THREAD_SAFETY", True)
854
+
855
+ cg.add_platformio_option("board_build.partitions", "partitions.csv")
856
+ if CONF_PARTITIONS in config:
857
+ add_extra_build_file(
858
+ "partitions.csv", CORE.relative_config_path(config[CONF_PARTITIONS])
859
+ )
860
+
861
+ if assertion_level := advanced.get(CONF_ASSERTION_LEVEL):
862
+ for key, flag in ASSERTION_LEVELS.items():
863
+ add_idf_sdkconfig_option(flag, assertion_level == key)
864
+
865
+ add_idf_sdkconfig_option("CONFIG_COMPILER_OPTIMIZATION_DEFAULT", False)
866
+ compiler_optimization = advanced.get(CONF_COMPILER_OPTIMIZATION)
867
+ for key, flag in COMPILER_OPTIMIZATIONS.items():
868
+ add_idf_sdkconfig_option(flag, compiler_optimization == key)
869
+
870
+ add_idf_sdkconfig_option(
871
+ "CONFIG_LWIP_ESP_LWIP_ASSERT",
872
+ conf[CONF_ADVANCED][CONF_ENABLE_LWIP_ASSERT],
873
+ )
953
874
 
954
- add_idf_sdkconfig_option(
955
- f"CONFIG_LOG_DEFAULT_LEVEL_{conf[CONF_LOG_LEVEL]}", True
875
+ if advanced.get(CONF_IGNORE_EFUSE_MAC_CRC):
876
+ add_idf_sdkconfig_option("CONFIG_ESP_MAC_IGNORE_MAC_CRC_ERROR", True)
877
+ add_idf_sdkconfig_option("CONFIG_ESP_PHY_CALIBRATION_AND_DATA_STORAGE", False)
878
+ if advanced.get(CONF_ENABLE_IDF_EXPERIMENTAL_FEATURES):
879
+ _LOGGER.warning(
880
+ "Using experimental features in ESP-IDF may result in unexpected failures."
956
881
  )
882
+ add_idf_sdkconfig_option("CONFIG_IDF_EXPERIMENTAL_FEATURES", True)
957
883
 
958
- for name, value in conf[CONF_SDKCONFIG_OPTIONS].items():
959
- add_idf_sdkconfig_option(name, RawSdkconfigValue(value))
884
+ cg.add_define(
885
+ "USE_ESP_IDF_VERSION_CODE",
886
+ cg.RawExpression(
887
+ f"VERSION_CODE({framework_ver.major}, {framework_ver.minor}, {framework_ver.patch})"
888
+ ),
889
+ )
960
890
 
961
- for component in conf[CONF_COMPONENTS]:
962
- add_idf_component(
963
- name=component[CONF_NAME],
964
- repo=component.get(CONF_SOURCE),
965
- ref=component.get(CONF_REF),
966
- path=component.get(CONF_PATH),
967
- )
968
- elif conf[CONF_TYPE] == FRAMEWORK_ARDUINO:
969
- cg.add_platformio_option("framework", "arduino")
970
- cg.add_build_flag("-DUSE_ARDUINO")
971
- cg.add_build_flag("-DUSE_ESP32_FRAMEWORK_ARDUINO")
972
- cg.add_platformio_option("platform_packages", [conf[CONF_SOURCE]])
891
+ add_idf_sdkconfig_option(f"CONFIG_LOG_DEFAULT_LEVEL_{conf[CONF_LOG_LEVEL]}", True)
973
892
 
974
- if CONF_PARTITIONS in config:
975
- cg.add_platformio_option("board_build.partitions", config[CONF_PARTITIONS])
976
- else:
977
- cg.add_platformio_option("board_build.partitions", "partitions.csv")
893
+ for name, value in conf[CONF_SDKCONFIG_OPTIONS].items():
894
+ add_idf_sdkconfig_option(name, RawSdkconfigValue(value))
978
895
 
979
- cg.add_define(
980
- "USE_ARDUINO_VERSION_CODE",
981
- cg.RawExpression(
982
- f"VERSION_CODE({framework_ver.major}, {framework_ver.minor}, {framework_ver.patch})"
983
- ),
896
+ for component in conf[CONF_COMPONENTS]:
897
+ add_idf_component(
898
+ name=component[CONF_NAME],
899
+ repo=component.get(CONF_SOURCE),
900
+ ref=component.get(CONF_REF),
901
+ path=component.get(CONF_PATH),
984
902
  )
985
- cg.add(RawExpression(f"setCpuFrequencyMhz({freq})"))
986
903
 
987
904
 
988
905
  APP_PARTITION_SIZES = {
@@ -1056,13 +973,14 @@ def _write_sdkconfig():
1056
973
  )
1057
974
  + "\n"
1058
975
  )
976
+
1059
977
  if write_file_if_changed(internal_path, contents):
1060
978
  # internal changed, update real one
1061
979
  write_file_if_changed(sdk_path, contents)
1062
980
 
1063
981
 
1064
982
  def _write_idf_component_yml():
1065
- yml_path = Path(CORE.relative_build_path("src/idf_component.yml"))
983
+ yml_path = CORE.relative_build_path("src/idf_component.yml")
1066
984
  if CORE.data[KEY_ESP32][KEY_COMPONENTS]:
1067
985
  components: dict = CORE.data[KEY_ESP32][KEY_COMPONENTS]
1068
986
  dependencies = {}
@@ -1080,51 +998,48 @@ def _write_idf_component_yml():
1080
998
  contents = ""
1081
999
  if write_file_if_changed(yml_path, contents):
1082
1000
  dependencies_lock = CORE.relative_build_path("dependencies.lock")
1083
- if os.path.isfile(dependencies_lock):
1084
- os.remove(dependencies_lock)
1001
+ if dependencies_lock.is_file():
1002
+ dependencies_lock.unlink()
1085
1003
  clean_cmake_cache()
1086
1004
 
1087
1005
 
1088
1006
  # Called by writer.py
1089
1007
  def copy_files():
1090
- if (
1091
- CORE.using_arduino
1092
- and "partitions.csv" not in CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES]
1093
- ):
1094
- write_file_if_changed(
1095
- CORE.relative_build_path("partitions.csv"),
1096
- get_arduino_partition_csv(
1097
- CORE.platformio_options.get("board_upload.flash_size")
1098
- ),
1099
- )
1100
- if CORE.using_esp_idf:
1101
- _write_sdkconfig()
1102
- _write_idf_component_yml()
1103
- if "partitions.csv" not in CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES]:
1008
+ _write_sdkconfig()
1009
+ _write_idf_component_yml()
1010
+
1011
+ if "partitions.csv" not in CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES]:
1012
+ if CORE.using_arduino:
1013
+ write_file_if_changed(
1014
+ CORE.relative_build_path("partitions.csv"),
1015
+ get_arduino_partition_csv(
1016
+ CORE.platformio_options.get("board_upload.flash_size")
1017
+ ),
1018
+ )
1019
+ else:
1104
1020
  write_file_if_changed(
1105
1021
  CORE.relative_build_path("partitions.csv"),
1106
1022
  get_idf_partition_csv(
1107
1023
  CORE.platformio_options.get("board_upload.flash_size")
1108
1024
  ),
1109
1025
  )
1110
- # IDF build scripts look for version string to put in the build.
1111
- # However, if the build path does not have an initialized git repo,
1112
- # and no version.txt file exists, the CMake script fails for some setups.
1113
- # Fix by manually pasting a version.txt file, containing the ESPHome version
1114
- write_file_if_changed(
1115
- CORE.relative_build_path("version.txt"),
1116
- __version__,
1117
- )
1026
+ # IDF build scripts look for version string to put in the build.
1027
+ # However, if the build path does not have an initialized git repo,
1028
+ # and no version.txt file exists, the CMake script fails for some setups.
1029
+ # Fix by manually pasting a version.txt file, containing the ESPHome version
1030
+ write_file_if_changed(
1031
+ CORE.relative_build_path("version.txt"),
1032
+ __version__,
1033
+ )
1118
1034
 
1119
1035
  for file in CORE.data[KEY_ESP32][KEY_EXTRA_BUILD_FILES].values():
1120
- if file[KEY_PATH].startswith("http"):
1036
+ name: str = file[KEY_NAME]
1037
+ path: Path = file[KEY_PATH]
1038
+ if str(path).startswith("http"):
1121
1039
  import requests
1122
1040
 
1123
- mkdir_p(CORE.relative_build_path(os.path.dirname(file[KEY_NAME])))
1124
- with open(CORE.relative_build_path(file[KEY_NAME]), "wb") as f:
1125
- f.write(requests.get(file[KEY_PATH], timeout=30).content)
1041
+ CORE.relative_build_path(name).parent.mkdir(parents=True, exist_ok=True)
1042
+ content = requests.get(path, timeout=30).content
1043
+ CORE.relative_build_path(name).write_bytes(content)
1126
1044
  else:
1127
- copy_file_if_changed(
1128
- file[KEY_PATH],
1129
- CORE.relative_build_path(file[KEY_NAME]),
1130
- )
1045
+ copy_file_if_changed(path, CORE.relative_build_path(name))