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.
Files changed (351) hide show
  1. esphome/__main__.py +94 -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 +166 -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 +68 -10
  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 +7 -7
  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/dashboard_import/dashboard_import.cpp +1 -1
  55. esphome/components/dashboard_import/dashboard_import.h +1 -1
  56. esphome/components/deep_sleep/__init__.py +9 -2
  57. esphome/components/deep_sleep/deep_sleep_component.h +11 -9
  58. esphome/components/deep_sleep/deep_sleep_esp32.cpp +51 -27
  59. esphome/components/ektf2232/touchscreen/__init__.py +8 -5
  60. esphome/components/ektf2232/touchscreen/ektf2232.cpp +4 -4
  61. esphome/components/ektf2232/touchscreen/ektf2232.h +2 -2
  62. esphome/components/epaper_spi/__init__.py +1 -0
  63. esphome/components/epaper_spi/display.py +80 -0
  64. esphome/components/epaper_spi/epaper_spi.cpp +227 -0
  65. esphome/components/epaper_spi/epaper_spi.h +93 -0
  66. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.cpp +42 -0
  67. esphome/components/epaper_spi/epaper_spi_model_7p3in_spectra_e6.h +45 -0
  68. esphome/components/epaper_spi/epaper_spi_spectra_e6.cpp +135 -0
  69. esphome/components/epaper_spi/epaper_spi_spectra_e6.h +23 -0
  70. esphome/components/es7210/es7210.cpp +3 -3
  71. esphome/components/esp32/__init__.py +256 -340
  72. esphome/components/esp32/boards.py +81 -0
  73. esphome/components/esp32/preferences.cpp +23 -17
  74. esphome/components/esp32_ble/__init__.py +167 -44
  75. esphome/components/esp32_ble/ble.cpp +47 -3
  76. esphome/components/esp32_ble/ble.h +18 -0
  77. esphome/components/esp32_ble/ble_advertising.cpp +7 -3
  78. esphome/components/esp32_ble/ble_advertising.h +4 -0
  79. esphome/components/esp32_ble/ble_uuid.cpp +16 -42
  80. esphome/components/esp32_ble_beacon/__init__.py +3 -4
  81. esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +0 -4
  82. esphome/components/esp32_ble_client/ble_client_base.cpp +14 -12
  83. esphome/components/esp32_ble_server/__init__.py +28 -14
  84. esphome/components/esp32_ble_server/ble_characteristic.cpp +67 -57
  85. esphome/components/esp32_ble_server/ble_characteristic.h +27 -16
  86. esphome/components/esp32_ble_server/ble_descriptor.cpp +4 -3
  87. esphome/components/esp32_ble_server/ble_descriptor.h +13 -9
  88. esphome/components/esp32_ble_server/ble_server.cpp +59 -24
  89. esphome/components/esp32_ble_server/ble_server.h +38 -20
  90. esphome/components/esp32_ble_server/ble_server_automations.cpp +49 -33
  91. esphome/components/esp32_ble_server/ble_server_automations.h +39 -24
  92. esphome/components/esp32_ble_tracker/__init__.py +25 -80
  93. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +2 -8
  94. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +0 -3
  95. esphome/components/esp32_camera/__init__.py +1 -3
  96. esphome/components/esp32_can/esp32_can.cpp +22 -4
  97. esphome/components/esp32_can/esp32_can.h +3 -0
  98. esphome/components/esp32_hosted/__init__.py +2 -1
  99. esphome/components/esp32_improv/esp32_improv_component.cpp +135 -65
  100. esphome/components/esp32_improv/esp32_improv_component.h +7 -1
  101. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
  102. esphome/components/esp8266/__init__.py +3 -3
  103. esphome/components/esphome/ota/__init__.py +21 -2
  104. esphome/components/esphome/ota/ota_esphome.cpp +456 -146
  105. esphome/components/esphome/ota/ota_esphome.h +49 -2
  106. esphome/components/ethernet/__init__.py +39 -22
  107. esphome/components/ethernet/ethernet_component.cpp +28 -5
  108. esphome/components/ethernet/ethernet_component.h +5 -1
  109. esphome/components/external_components/__init__.py +8 -6
  110. esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
  111. esphome/components/fingerprint_grow/fingerprint_grow.h +2 -1
  112. esphome/components/font/__init__.py +5 -5
  113. esphome/components/graph/graph.cpp +1 -1
  114. esphome/components/graphical_display_menu/graphical_display_menu.cpp +3 -2
  115. esphome/components/haier/hon_climate.cpp +2 -2
  116. esphome/components/haier/hon_climate.h +1 -1
  117. esphome/components/hdc1080/hdc1080.cpp +42 -34
  118. esphome/components/hdc1080/hdc1080.h +1 -3
  119. esphome/components/homeassistant/number/homeassistant_number.cpp +2 -2
  120. esphome/components/homeassistant/switch/homeassistant_switch.cpp +2 -2
  121. esphome/components/http_request/__init__.py +3 -3
  122. esphome/components/htu21d/htu21d.cpp +13 -18
  123. esphome/components/htu21d/htu21d.h +1 -1
  124. esphome/components/i2s_audio/__init__.py +1 -2
  125. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +1 -1
  126. esphome/components/ili9xxx/ili9xxx_display.cpp +2 -2
  127. esphome/components/improv_serial/improv_serial_component.cpp +12 -15
  128. esphome/components/improv_serial/improv_serial_component.h +6 -8
  129. esphome/components/json/json_util.cpp +42 -44
  130. esphome/components/json/json_util.h +57 -0
  131. esphome/components/kamstrup_kmp/kamstrup_kmp.cpp +2 -2
  132. esphome/components/key_collector/key_collector.h +4 -4
  133. esphome/components/libretiny/__init__.py +6 -6
  134. esphome/components/libretiny/preferences.cpp +23 -16
  135. esphome/components/light/light_call.cpp +98 -120
  136. esphome/components/light/light_call.h +17 -7
  137. esphome/components/lm75b/__init__.py +0 -0
  138. esphome/components/lm75b/lm75b.cpp +39 -0
  139. esphome/components/lm75b/lm75b.h +19 -0
  140. esphome/components/lm75b/sensor.py +34 -0
  141. esphome/components/lock/lock.h +12 -6
  142. esphome/components/logger/__init__.py +15 -27
  143. esphome/components/logger/logger.cpp +10 -20
  144. esphome/components/logger/logger.h +105 -62
  145. esphome/components/logger/logger_esp32.cpp +0 -48
  146. esphome/components/logger/logger_zephyr.cpp +2 -3
  147. esphome/components/logger/select/logger_level_select.cpp +6 -7
  148. esphome/components/logger/select/logger_level_select.h +7 -0
  149. esphome/components/ltr501/ltr501.cpp +7 -6
  150. esphome/components/ltr_als_ps/ltr_als_ps.cpp +7 -6
  151. esphome/components/matrix_keypad/matrix_keypad.h +4 -4
  152. esphome/components/max7219digit/max7219digit.cpp +1 -1
  153. esphome/components/mcp23xxx_base/mcp23xxx_base.h +3 -3
  154. esphome/components/mcp2515/mcp2515.cpp +31 -3
  155. esphome/components/mcp2515/mcp2515_defs.h +3 -1
  156. esphome/components/md5/md5.cpp +0 -26
  157. esphome/components/md5/md5.h +10 -20
  158. esphome/components/mdns/__init__.py +93 -19
  159. esphome/components/mdns/mdns_component.cpp +57 -94
  160. esphome/components/mdns/mdns_component.h +35 -11
  161. esphome/components/mdns/mdns_esp32.cpp +7 -13
  162. esphome/components/mdns/mdns_esp8266.cpp +7 -7
  163. esphome/components/mdns/mdns_libretiny.cpp +3 -4
  164. esphome/components/mdns/mdns_rp2040.cpp +3 -4
  165. esphome/components/mipi/__init__.py +1 -5
  166. esphome/components/mipi_spi/display.py +24 -8
  167. esphome/components/mipi_spi/mipi_spi.h +3 -3
  168. esphome/components/mixer/speaker/mixer_speaker.cpp +3 -3
  169. esphome/components/mmc5603/mmc5603.cpp +3 -3
  170. esphome/components/modbus/modbus.cpp +27 -13
  171. esphome/components/modbus/modbus.h +5 -3
  172. esphome/components/modbus/modbus_definitions.h +86 -0
  173. esphome/components/modbus_controller/__init__.py +29 -1
  174. esphome/components/modbus_controller/const.py +4 -0
  175. esphome/components/modbus_controller/modbus_controller.cpp +38 -13
  176. esphome/components/modbus_controller/modbus_controller.h +18 -29
  177. esphome/components/mpr121/mpr121.cpp +41 -42
  178. esphome/components/mpr121/mpr121.h +0 -1
  179. esphome/components/nau7802/nau7802.cpp +2 -2
  180. esphome/components/network/__init__.py +7 -3
  181. esphome/components/nextion/display.py +4 -4
  182. esphome/components/nextion/nextion.cpp +8 -8
  183. esphome/components/number/__init__.py +2 -0
  184. esphome/components/number/number_call.cpp +23 -12
  185. esphome/components/number/number_call.h +5 -0
  186. esphome/components/online_image/bmp_image.cpp +2 -1
  187. esphome/components/online_image/jpeg_image.cpp +4 -2
  188. esphome/components/opentherm/opentherm.cpp +5 -5
  189. esphome/components/opentherm/opentherm.h +3 -3
  190. esphome/components/openthread/openthread.cpp +11 -10
  191. esphome/components/openthread/openthread.h +0 -1
  192. esphome/components/ota/ota_backend.h +1 -0
  193. esphome/components/packages/__init__.py +10 -8
  194. esphome/components/packet_transport/packet_transport.cpp +2 -0
  195. esphome/components/pid/pid_controller.cpp +1 -1
  196. esphome/components/prometheus/prometheus_handler.cpp +239 -239
  197. esphome/components/psram/__init__.py +30 -28
  198. esphome/components/qmc5883l/qmc5883l.cpp +15 -0
  199. esphome/components/qmc5883l/qmc5883l.h +3 -0
  200. esphome/components/qmc5883l/sensor.py +31 -12
  201. esphome/components/remote_base/gobox_protocol.cpp +3 -3
  202. esphome/components/remote_receiver/__init__.py +14 -2
  203. esphome/components/remote_receiver/{remote_receiver_esp8266.cpp → remote_receiver.cpp} +2 -2
  204. esphome/components/remote_receiver/remote_receiver.h +4 -0
  205. esphome/components/remote_receiver/remote_receiver_esp32.cpp +18 -1
  206. esphome/components/remote_transmitter/__init__.py +2 -2
  207. esphome/components/remote_transmitter/remote_transmitter.cpp +103 -0
  208. esphome/components/rp2040/__init__.py +11 -11
  209. esphome/components/rtttl/rtttl.cpp +2 -2
  210. esphome/components/scd30/sensor.py +1 -1
  211. esphome/components/script/__init__.py +1 -1
  212. esphome/components/script/script.h +7 -7
  213. esphome/components/select/select.cpp +5 -4
  214. esphome/components/select/select_call.cpp +1 -1
  215. esphome/components/sensirion_common/i2c_sensirion.cpp +2 -1
  216. esphome/components/sensor/__init__.py +2 -0
  217. esphome/components/sha256/__init__.py +22 -0
  218. esphome/components/sha256/sha256.cpp +116 -0
  219. esphome/components/sha256/sha256.h +60 -0
  220. esphome/components/socket/lwip_raw_tcp_impl.cpp +34 -6
  221. esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
  222. esphome/components/spi/__init__.py +0 -3
  223. esphome/components/split_buffer/__init__.py +5 -0
  224. esphome/components/split_buffer/split_buffer.cpp +133 -0
  225. esphome/components/split_buffer/split_buffer.h +40 -0
  226. esphome/components/sps30/sps30.cpp +14 -10
  227. esphome/components/sps30/sps30.h +2 -0
  228. esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
  229. esphome/components/st7789v/st7789v.cpp +3 -2
  230. esphome/components/statsd/statsd.cpp +1 -1
  231. esphome/components/substitutions/__init__.py +3 -1
  232. esphome/components/substitutions/jinja.py +13 -3
  233. esphome/components/sx126x/__init__.py +16 -0
  234. esphome/components/sx126x/sx126x.cpp +15 -1
  235. esphome/components/sx126x/sx126x.h +9 -1
  236. esphome/components/sx126x/sx126x_reg.h +2 -0
  237. esphome/components/text_sensor/text_sensor.cpp +16 -0
  238. esphome/components/text_sensor/text_sensor.h +3 -10
  239. esphome/components/tormatic/tormatic_cover.cpp +1 -1
  240. esphome/components/tuya/select/tuya_select.cpp +1 -1
  241. esphome/components/tuya/tuya.cpp +29 -4
  242. esphome/components/uart/__init__.py +37 -27
  243. esphome/components/uart/uart.h +6 -0
  244. esphome/components/uart/uart_component.cpp +8 -0
  245. esphome/components/uart/uart_component.h +28 -0
  246. esphome/components/uart/uart_component_esp_idf.cpp +64 -10
  247. esphome/components/uart/uart_component_esp_idf.h +5 -2
  248. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  249. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
  250. esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
  251. esphome/components/usb_host/__init__.py +12 -2
  252. esphome/components/usb_host/usb_host.h +89 -14
  253. esphome/components/usb_host/usb_host_client.cpp +157 -22
  254. esphome/components/usb_host/usb_host_component.cpp +1 -1
  255. esphome/components/usb_uart/__init__.py +0 -1
  256. esphome/components/usb_uart/ch34x.cpp +4 -4
  257. esphome/components/usb_uart/cp210x.cpp +3 -3
  258. esphome/components/usb_uart/usb_uart.cpp +88 -32
  259. esphome/components/usb_uart/usb_uart.h +30 -6
  260. esphome/components/valve/valve.cpp +1 -0
  261. esphome/components/veml7700/veml7700.cpp +7 -6
  262. esphome/components/version/version_text_sensor.cpp +2 -1
  263. esphome/components/voice_assistant/voice_assistant.cpp +3 -2
  264. esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
  265. esphome/components/web_server/list_entities.cpp +3 -4
  266. esphome/components/web_server/list_entities.h +8 -10
  267. esphome/components/web_server/ota/__init__.py +1 -1
  268. esphome/components/web_server/ota/ota_web_server.cpp +9 -3
  269. esphome/components/web_server/web_server.cpp +509 -404
  270. esphome/components/web_server/web_server.h +5 -6
  271. esphome/components/web_server/web_server_v1.cpp +21 -19
  272. esphome/components/web_server_base/__init__.py +5 -2
  273. esphome/components/web_server_base/web_server_base.h +27 -7
  274. esphome/components/web_server_idf/__init__.py +1 -1
  275. esphome/components/web_server_idf/multipart.cpp +2 -2
  276. esphome/components/web_server_idf/multipart.h +2 -2
  277. esphome/components/web_server_idf/utils.cpp +2 -2
  278. esphome/components/web_server_idf/utils.h +2 -2
  279. esphome/components/web_server_idf/web_server_idf.cpp +118 -26
  280. esphome/components/web_server_idf/web_server_idf.h +12 -10
  281. esphome/components/wifi/__init__.py +13 -11
  282. esphome/components/wifi/wifi_component.cpp +74 -56
  283. esphome/components/wifi/wifi_component.h +4 -4
  284. esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
  285. esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
  286. esphome/components/wireguard/__init__.py +1 -1
  287. esphome/components/wts01/__init__.py +0 -0
  288. esphome/components/wts01/sensor.py +41 -0
  289. esphome/components/wts01/wts01.cpp +91 -0
  290. esphome/components/wts01/wts01.h +27 -0
  291. esphome/components/zephyr/__init__.py +5 -5
  292. esphome/components/zwave_proxy/__init__.py +43 -0
  293. esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
  294. esphome/components/zwave_proxy/zwave_proxy.h +93 -0
  295. esphome/config.py +79 -24
  296. esphome/config_validation.py +13 -15
  297. esphome/const.py +9 -2
  298. esphome/core/__init__.py +33 -22
  299. esphome/core/component.cpp +28 -18
  300. esphome/core/component_iterator.h +2 -1
  301. esphome/core/config.py +15 -15
  302. esphome/core/defines.h +21 -0
  303. esphome/core/entity_helpers.py +9 -6
  304. esphome/core/hash_base.h +56 -0
  305. esphome/core/helpers.cpp +19 -3
  306. esphome/core/helpers.h +26 -0
  307. esphome/core/scheduler.cpp +5 -21
  308. esphome/core/scheduler.h +19 -8
  309. esphome/core/string_ref.h +1 -1
  310. esphome/core/time.cpp +5 -5
  311. esphome/cpp_generator.py +4 -29
  312. esphome/dashboard/const.py +21 -4
  313. esphome/dashboard/core.py +10 -8
  314. esphome/dashboard/dns.py +15 -0
  315. esphome/dashboard/entries.py +15 -21
  316. esphome/dashboard/models.py +76 -0
  317. esphome/dashboard/settings.py +7 -7
  318. esphome/dashboard/status/mdns.py +46 -2
  319. esphome/dashboard/web_server.py +367 -93
  320. esphome/espota2.py +112 -32
  321. esphome/external_files.py +6 -7
  322. esphome/git.py +8 -0
  323. esphome/helpers.py +124 -77
  324. esphome/loader.py +8 -9
  325. esphome/pins.py +2 -2
  326. esphome/platformio_api.py +56 -18
  327. esphome/storage_json.py +26 -21
  328. esphome/types.py +30 -2
  329. esphome/util.py +32 -16
  330. esphome/vscode.py +8 -8
  331. esphome/wizard.py +10 -10
  332. esphome/writer.py +50 -15
  333. esphome/yaml_util.py +37 -31
  334. esphome/zeroconf.py +12 -3
  335. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/METADATA +12 -12
  336. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/RECORD +340 -320
  337. esphome/components/event_emitter/__init__.py +0 -5
  338. esphome/components/event_emitter/event_emitter.cpp +0 -14
  339. esphome/components/event_emitter/event_emitter.h +0 -63
  340. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
  341. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
  342. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
  343. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
  344. esphome/components/uart/uart_component_esp32_arduino.h +0 -60
  345. esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
  346. esphome/core/string_ref.cpp +0 -12
  347. esphome/dashboard/util/file.py +0 -63
  348. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/WHEEL +0 -0
  349. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/entry_points.txt +0 -0
  350. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/licenses/LICENSE +0 -0
  351. {esphome-2025.9.3.dist-info → esphome-2025.10.0b2.dist-info}/top_level.txt +0 -0
@@ -1,5 +1,7 @@
1
1
  #pragma once
2
2
 
3
+ #include "esphome/core/defines.h"
4
+
3
5
  #ifdef USE_ESP32_CAMERA_JPEG_ENCODER
4
6
 
5
7
  #include <esp_camera.h>
@@ -24,7 +26,7 @@ class ESP32CameraJPEGEncoder : public camera::Encoder {
24
26
  void dump_config() override;
25
27
  // -------------------------
26
28
  protected:
27
- static size_t callback_(void *arg, size_t index, const void *data, size_t len);
29
+ static size_t callback(void *arg, size_t index, const void *data, size_t len);
28
30
  pixformat_t to_internal_(camera::PixelFormat format);
29
31
 
30
32
  camera::EncoderBuffer *output_{};
@@ -21,8 +21,8 @@ void Canbus::dump_config() {
21
21
  }
22
22
  }
23
23
 
24
- void Canbus::send_data(uint32_t can_id, bool use_extended_id, bool remote_transmission_request,
25
- const std::vector<uint8_t> &data) {
24
+ canbus::Error Canbus::send_data(uint32_t can_id, bool use_extended_id, bool remote_transmission_request,
25
+ const std::vector<uint8_t> &data) {
26
26
  struct CanFrame can_message;
27
27
 
28
28
  uint8_t size = static_cast<uint8_t>(data.size());
@@ -45,13 +45,15 @@ void Canbus::send_data(uint32_t can_id, bool use_extended_id, bool remote_transm
45
45
  ESP_LOGVV(TAG, " data[%d]=%02x", i, can_message.data[i]);
46
46
  }
47
47
 
48
- if (this->send_message(&can_message) != canbus::ERROR_OK) {
48
+ canbus::Error error = this->send_message(&can_message);
49
+ if (error != canbus::ERROR_OK) {
49
50
  if (use_extended_id) {
50
- ESP_LOGW(TAG, "send to extended id=0x%08" PRIx32 " failed!", can_id);
51
+ ESP_LOGW(TAG, "send to extended id=0x%08" PRIx32 " failed with error %d!", can_id, error);
51
52
  } else {
52
- ESP_LOGW(TAG, "send to standard id=0x%03" PRIx32 " failed!", can_id);
53
+ ESP_LOGW(TAG, "send to standard id=0x%03" PRIx32 " failed with error %d!", can_id, error);
53
54
  }
54
55
  }
56
+ return error;
55
57
  }
56
58
 
57
59
  void Canbus::add_trigger(CanbusTrigger *trigger) {
@@ -70,11 +70,11 @@ class Canbus : public Component {
70
70
  float get_setup_priority() const override { return setup_priority::HARDWARE; }
71
71
  void loop() override;
72
72
 
73
- void send_data(uint32_t can_id, bool use_extended_id, bool remote_transmission_request,
74
- const std::vector<uint8_t> &data);
75
- void send_data(uint32_t can_id, bool use_extended_id, const std::vector<uint8_t> &data) {
73
+ canbus::Error send_data(uint32_t can_id, bool use_extended_id, bool remote_transmission_request,
74
+ const std::vector<uint8_t> &data);
75
+ canbus::Error send_data(uint32_t can_id, bool use_extended_id, const std::vector<uint8_t> &data) {
76
76
  // for backwards compatibility only
77
- this->send_data(can_id, use_extended_id, false, data);
77
+ return this->send_data(can_id, use_extended_id, false, data);
78
78
  }
79
79
  void set_can_id(uint32_t can_id) { this->can_id_ = can_id; }
80
80
  void set_use_extended_id(bool use_extended_id) { this->use_extended_id_ = use_extended_id; }
@@ -105,9 +105,9 @@ class Canbus : public Component {
105
105
  CallbackManager<void(uint32_t can_id, bool extended_id, bool rtr, const std::vector<uint8_t> &data)>
106
106
  callback_manager_{};
107
107
 
108
- virtual bool setup_internal();
109
- virtual Error send_message(struct CanFrame *frame);
110
- virtual Error read_message(struct CanFrame *frame);
108
+ virtual bool setup_internal() = 0;
109
+ virtual Error send_message(struct CanFrame *frame) = 0;
110
+ virtual Error read_message(struct CanFrame *frame) = 0;
111
111
  };
112
112
 
113
113
  template<typename... Ts> class CanbusSendAction : public Action<Ts...>, public Parented<Canbus> {
@@ -1,6 +1,7 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import web_server_base
3
3
  from esphome.components.web_server_base import CONF_WEB_SERVER_BASE_ID
4
+ from esphome.config_helpers import filter_source_files_from_platform
4
5
  import esphome.config_validation as cv
5
6
  from esphome.const import (
6
7
  CONF_ID,
@@ -9,11 +10,19 @@ from esphome.const import (
9
10
  PLATFORM_ESP8266,
10
11
  PLATFORM_LN882X,
11
12
  PLATFORM_RTL87XX,
13
+ PlatformFramework,
12
14
  )
13
15
  from esphome.core import CORE, coroutine_with_priority
14
16
  from esphome.coroutine import CoroPriority
15
17
 
16
- AUTO_LOAD = ["web_server_base", "ota.web_server"]
18
+
19
+ def AUTO_LOAD() -> list[str]:
20
+ auto_load = ["web_server_base", "ota.web_server"]
21
+ if CORE.using_esp_idf:
22
+ auto_load.append("socket")
23
+ return auto_load
24
+
25
+
17
26
  DEPENDENCIES = ["wifi"]
18
27
  CODEOWNERS = ["@esphome/core"]
19
28
 
@@ -58,3 +67,11 @@ async def to_code(config):
58
67
  cg.add_library("DNSServer", None)
59
68
  if CORE.is_libretiny:
60
69
  cg.add_library("DNSServer", None)
70
+
71
+
72
+ # Only compile the ESP-IDF DNS server when using ESP-IDF framework
73
+ FILTER_SOURCE_FILES = filter_source_files_from_platform(
74
+ {
75
+ "dns_server_esp32_idf.cpp": {PlatformFramework.ESP32_IDF},
76
+ }
77
+ )
@@ -11,14 +11,14 @@ namespace captive_portal {
11
11
  static const char *const TAG = "captive_portal";
12
12
 
13
13
  void CaptivePortal::handle_config(AsyncWebServerRequest *request) {
14
- AsyncResponseStream *stream = request->beginResponseStream(F("application/json"));
15
- stream->addHeader(F("cache-control"), F("public, max-age=0, must-revalidate"));
14
+ AsyncResponseStream *stream = request->beginResponseStream(ESPHOME_F("application/json"));
15
+ stream->addHeader(ESPHOME_F("cache-control"), ESPHOME_F("public, max-age=0, must-revalidate"));
16
16
  #ifdef USE_ESP8266
17
- stream->print(F("{\"mac\":\""));
17
+ stream->print(ESPHOME_F("{\"mac\":\""));
18
18
  stream->print(get_mac_address_pretty().c_str());
19
- stream->print(F("\",\"name\":\""));
19
+ stream->print(ESPHOME_F("\",\"name\":\""));
20
20
  stream->print(App.get_name().c_str());
21
- stream->print(F("\",\"aps\":[{}"));
21
+ stream->print(ESPHOME_F("\",\"aps\":[{}"));
22
22
  #else
23
23
  stream->printf(R"({"mac":"%s","name":"%s","aps":[{})", get_mac_address_pretty().c_str(), App.get_name().c_str());
24
24
  #endif
@@ -29,37 +29,35 @@ void CaptivePortal::handle_config(AsyncWebServerRequest *request) {
29
29
 
30
30
  // Assumes no " in ssid, possible unicode isses?
31
31
  #ifdef USE_ESP8266
32
- stream->print(F(",{\"ssid\":\""));
32
+ stream->print(ESPHOME_F(",{\"ssid\":\""));
33
33
  stream->print(scan.get_ssid().c_str());
34
- stream->print(F("\",\"rssi\":"));
34
+ stream->print(ESPHOME_F("\",\"rssi\":"));
35
35
  stream->print(scan.get_rssi());
36
- stream->print(F(",\"lock\":"));
36
+ stream->print(ESPHOME_F(",\"lock\":"));
37
37
  stream->print(scan.get_with_auth());
38
- stream->print(F("}"));
38
+ stream->print(ESPHOME_F("}"));
39
39
  #else
40
40
  stream->printf(R"(,{"ssid":"%s","rssi":%d,"lock":%d})", scan.get_ssid().c_str(), scan.get_rssi(),
41
41
  scan.get_with_auth());
42
42
  #endif
43
43
  }
44
- stream->print(F("]}"));
44
+ stream->print(ESPHOME_F("]}"));
45
45
  request->send(stream);
46
46
  }
47
47
  void CaptivePortal::handle_wifisave(AsyncWebServerRequest *request) {
48
- std::string ssid = request->arg("ssid").c_str();
49
- std::string psk = request->arg("psk").c_str();
48
+ std::string ssid = request->arg("ssid").c_str(); // NOLINT(readability-redundant-string-cstr)
49
+ std::string psk = request->arg("psk").c_str(); // NOLINT(readability-redundant-string-cstr)
50
50
  ESP_LOGI(TAG, "Requested WiFi Settings Change:");
51
51
  ESP_LOGI(TAG, " SSID='%s'", ssid.c_str());
52
52
  ESP_LOGI(TAG, " Password=" LOG_SECRET("'%s'"), psk.c_str());
53
53
  wifi::global_wifi_component->save_wifi_sta(ssid, psk);
54
54
  wifi::global_wifi_component->start_scanning();
55
- request->redirect(F("/?save"));
55
+ request->redirect(ESPHOME_F("/?save"));
56
56
  }
57
57
 
58
58
  void CaptivePortal::setup() {
59
- #ifndef USE_ARDUINO
60
- // No DNS server needed for non-Arduino frameworks
59
+ // Disable loop by default - will be enabled when captive portal starts
61
60
  this->disable_loop();
62
- #endif
63
61
  }
64
62
  void CaptivePortal::start() {
65
63
  this->base_->init();
@@ -67,51 +65,47 @@ void CaptivePortal::start() {
67
65
  this->base_->add_handler(this);
68
66
  }
69
67
 
68
+ network::IPAddress ip = wifi::global_wifi_component->wifi_soft_ap_ip();
69
+
70
+ #ifdef USE_ESP_IDF
71
+ // Create DNS server instance for ESP-IDF
72
+ this->dns_server_ = make_unique<DNSServer>();
73
+ this->dns_server_->start(ip);
74
+ #endif
70
75
  #ifdef USE_ARDUINO
71
76
  this->dns_server_ = make_unique<DNSServer>();
72
77
  this->dns_server_->setErrorReplyCode(DNSReplyCode::NoError);
73
- network::IPAddress ip = wifi::global_wifi_component->wifi_soft_ap_ip();
74
- this->dns_server_->start(53, F("*"), ip);
75
- // Re-enable loop() when DNS server is started
76
- this->enable_loop();
77
- #endif
78
-
79
- this->base_->get_server()->onNotFound([this](AsyncWebServerRequest *req) {
80
- if (!this->active_ || req->host().c_str() == wifi::global_wifi_component->wifi_soft_ap_ip().str()) {
81
- req->send(404, F("text/html"), F("File not found"));
82
- return;
83
- }
84
-
85
- #ifdef USE_ESP8266
86
- String url = F("http://");
87
- url += wifi::global_wifi_component->wifi_soft_ap_ip().str().c_str();
88
- #else
89
- auto url = "http://" + wifi::global_wifi_component->wifi_soft_ap_ip().str();
78
+ this->dns_server_->start(53, ESPHOME_F("*"), ip);
90
79
  #endif
91
- req->redirect(url.c_str());
92
- });
93
80
 
94
81
  this->initialized_ = true;
95
82
  this->active_ = true;
83
+
84
+ // Enable loop() now that captive portal is active
85
+ this->enable_loop();
86
+
87
+ ESP_LOGV(TAG, "Captive portal started");
96
88
  }
97
89
 
98
90
  void CaptivePortal::handleRequest(AsyncWebServerRequest *req) {
99
- if (req->url() == F("/")) {
100
- #ifndef USE_ESP8266
101
- auto *response = req->beginResponse(200, F("text/html"), INDEX_GZ, sizeof(INDEX_GZ));
102
- #else
103
- auto *response = req->beginResponse_P(200, F("text/html"), INDEX_GZ, sizeof(INDEX_GZ));
104
- #endif
105
- response->addHeader(F("Content-Encoding"), F("gzip"));
106
- req->send(response);
107
- return;
108
- } else if (req->url() == F("/config.json")) {
91
+ if (req->url() == ESPHOME_F("/config.json")) {
109
92
  this->handle_config(req);
110
93
  return;
111
- } else if (req->url() == F("/wifisave")) {
94
+ } else if (req->url() == ESPHOME_F("/wifisave")) {
112
95
  this->handle_wifisave(req);
113
96
  return;
114
97
  }
98
+
99
+ // All other requests get the captive portal page
100
+ // This includes OS captive portal detection endpoints which will trigger
101
+ // the captive portal when they don't receive their expected responses
102
+ #ifndef USE_ESP8266
103
+ auto *response = req->beginResponse(200, ESPHOME_F("text/html"), INDEX_GZ, sizeof(INDEX_GZ));
104
+ #else
105
+ auto *response = req->beginResponse_P(200, ESPHOME_F("text/html"), INDEX_GZ, sizeof(INDEX_GZ));
106
+ #endif
107
+ response->addHeader(ESPHOME_F("Content-Encoding"), ESPHOME_F("gzip"));
108
+ req->send(response);
115
109
  }
116
110
 
117
111
  CaptivePortal::CaptivePortal(web_server_base::WebServerBase *base) : base_(base) { global_captive_portal = this; }
@@ -5,6 +5,9 @@
5
5
  #ifdef USE_ARDUINO
6
6
  #include <DNSServer.h>
7
7
  #endif
8
+ #ifdef USE_ESP_IDF
9
+ #include "dns_server_esp32_idf.h"
10
+ #endif
8
11
  #include "esphome/core/component.h"
9
12
  #include "esphome/core/helpers.h"
10
13
  #include "esphome/core/preferences.h"
@@ -19,41 +22,36 @@ class CaptivePortal : public AsyncWebHandler, public Component {
19
22
  CaptivePortal(web_server_base::WebServerBase *base);
20
23
  void setup() override;
21
24
  void dump_config() override;
22
- #ifdef USE_ARDUINO
23
25
  void loop() override {
26
+ #ifdef USE_ARDUINO
24
27
  if (this->dns_server_ != nullptr) {
25
28
  this->dns_server_->processNextRequest();
26
- } else {
27
- this->disable_loop();
28
29
  }
29
- }
30
30
  #endif
31
+ #ifdef USE_ESP_IDF
32
+ if (this->dns_server_ != nullptr) {
33
+ this->dns_server_->process_next_request();
34
+ }
35
+ #endif
36
+ }
31
37
  float get_setup_priority() const override;
32
38
  void start();
33
39
  bool is_active() const { return this->active_; }
34
40
  void end() {
35
41
  this->active_ = false;
42
+ this->disable_loop(); // Stop processing DNS requests
36
43
  this->base_->deinit();
37
- #ifdef USE_ARDUINO
38
- this->dns_server_->stop();
39
- this->dns_server_ = nullptr;
40
- #endif
44
+ if (this->dns_server_ != nullptr) {
45
+ this->dns_server_->stop();
46
+ this->dns_server_ = nullptr;
47
+ }
41
48
  }
42
49
 
43
50
  bool canHandle(AsyncWebServerRequest *request) const override {
44
- if (!this->active_)
45
- return false;
46
-
47
- if (request->method() == HTTP_GET) {
48
- if (request->url() == F("/"))
49
- return true;
50
- if (request->url() == F("/config.json"))
51
- return true;
52
- if (request->url() == F("/wifisave"))
53
- return true;
54
- }
55
-
56
- return false;
51
+ // Handle all GET requests when captive portal is active
52
+ // This allows us to respond with the portal page for any URL,
53
+ // triggering OS captive portal detection
54
+ return this->active_ && request->method() == HTTP_GET;
57
55
  }
58
56
 
59
57
  void handle_config(AsyncWebServerRequest *request);
@@ -66,7 +64,7 @@ class CaptivePortal : public AsyncWebHandler, public Component {
66
64
  web_server_base::WebServerBase *base_;
67
65
  bool initialized_{false};
68
66
  bool active_{false};
69
- #ifdef USE_ARDUINO
67
+ #if defined(USE_ARDUINO) || defined(USE_ESP_IDF)
70
68
  std::unique_ptr<DNSServer> dns_server_{nullptr};
71
69
  #endif
72
70
  };
@@ -0,0 +1,205 @@
1
+ #include "dns_server_esp32_idf.h"
2
+ #ifdef USE_ESP_IDF
3
+
4
+ #include "esphome/core/log.h"
5
+ #include "esphome/core/hal.h"
6
+ #include "esphome/components/socket/socket.h"
7
+ #include <lwip/sockets.h>
8
+ #include <lwip/inet.h>
9
+
10
+ namespace esphome::captive_portal {
11
+
12
+ static const char *const TAG = "captive_portal.dns";
13
+
14
+ // DNS constants
15
+ static constexpr uint16_t DNS_PORT = 53;
16
+ static constexpr uint16_t DNS_QR_FLAG = 1 << 15;
17
+ static constexpr uint16_t DNS_OPCODE_MASK = 0x7800;
18
+ static constexpr uint16_t DNS_QTYPE_A = 0x0001;
19
+ static constexpr uint16_t DNS_QCLASS_IN = 0x0001;
20
+ static constexpr uint16_t DNS_ANSWER_TTL = 300;
21
+
22
+ // DNS Header structure
23
+ struct DNSHeader {
24
+ uint16_t id;
25
+ uint16_t flags;
26
+ uint16_t qd_count;
27
+ uint16_t an_count;
28
+ uint16_t ns_count;
29
+ uint16_t ar_count;
30
+ } __attribute__((packed));
31
+
32
+ // DNS Question structure
33
+ struct DNSQuestion {
34
+ uint16_t type;
35
+ uint16_t dns_class;
36
+ } __attribute__((packed));
37
+
38
+ // DNS Answer structure
39
+ struct DNSAnswer {
40
+ uint16_t ptr_offset;
41
+ uint16_t type;
42
+ uint16_t dns_class;
43
+ uint32_t ttl;
44
+ uint16_t addr_len;
45
+ uint32_t ip_addr;
46
+ } __attribute__((packed));
47
+
48
+ void DNSServer::start(const network::IPAddress &ip) {
49
+ this->server_ip_ = ip;
50
+ ESP_LOGV(TAG, "Starting DNS server on %s", ip.str().c_str());
51
+
52
+ // Create loop-monitored UDP socket
53
+ this->socket_ = socket::socket_ip_loop_monitored(SOCK_DGRAM, IPPROTO_UDP);
54
+ if (this->socket_ == nullptr) {
55
+ ESP_LOGE(TAG, "Socket create failed");
56
+ return;
57
+ }
58
+
59
+ // Set socket options
60
+ int enable = 1;
61
+ this->socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable));
62
+
63
+ // Bind to port 53
64
+ struct sockaddr_storage server_addr = {};
65
+ socklen_t addr_len = socket::set_sockaddr_any((struct sockaddr *) &server_addr, sizeof(server_addr), DNS_PORT);
66
+
67
+ int err = this->socket_->bind((struct sockaddr *) &server_addr, addr_len);
68
+ if (err != 0) {
69
+ ESP_LOGE(TAG, "Bind failed: %d", errno);
70
+ this->socket_ = nullptr;
71
+ return;
72
+ }
73
+ ESP_LOGV(TAG, "Bound to port %d", DNS_PORT);
74
+ }
75
+
76
+ void DNSServer::stop() {
77
+ if (this->socket_ != nullptr) {
78
+ this->socket_->close();
79
+ this->socket_ = nullptr;
80
+ }
81
+ ESP_LOGV(TAG, "Stopped");
82
+ }
83
+
84
+ void DNSServer::process_next_request() {
85
+ // Process one request if socket is valid and data is available
86
+ if (this->socket_ == nullptr || !this->socket_->ready()) {
87
+ return;
88
+ }
89
+ struct sockaddr_in client_addr;
90
+ socklen_t client_addr_len = sizeof(client_addr);
91
+
92
+ // Receive DNS request using raw fd for recvfrom
93
+ int fd = this->socket_->get_fd();
94
+ if (fd < 0) {
95
+ return;
96
+ }
97
+
98
+ ssize_t len = recvfrom(fd, this->buffer_, sizeof(this->buffer_), MSG_DONTWAIT, (struct sockaddr *) &client_addr,
99
+ &client_addr_len);
100
+
101
+ if (len < 0) {
102
+ if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) {
103
+ ESP_LOGE(TAG, "recvfrom failed: %d", errno);
104
+ }
105
+ return;
106
+ }
107
+
108
+ ESP_LOGVV(TAG, "Received %d bytes from %s:%d", len, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
109
+
110
+ if (len < static_cast<ssize_t>(sizeof(DNSHeader) + 1)) {
111
+ ESP_LOGV(TAG, "Request too short: %d", len);
112
+ return;
113
+ }
114
+
115
+ // Parse DNS header
116
+ DNSHeader *header = (DNSHeader *) this->buffer_;
117
+ uint16_t flags = ntohs(header->flags);
118
+ uint16_t qd_count = ntohs(header->qd_count);
119
+
120
+ // Check if it's a standard query
121
+ if ((flags & DNS_QR_FLAG) || (flags & DNS_OPCODE_MASK) || qd_count != 1) {
122
+ ESP_LOGV(TAG, "Not a standard query: flags=0x%04X, qd_count=%d", flags, qd_count);
123
+ return; // Not a standard query
124
+ }
125
+
126
+ // Parse domain name (we don't actually care about it - redirect everything)
127
+ uint8_t *ptr = this->buffer_ + sizeof(DNSHeader);
128
+ uint8_t *end = this->buffer_ + len;
129
+
130
+ while (ptr < end && *ptr != 0) {
131
+ uint8_t label_len = *ptr;
132
+ if (label_len > 63) { // Check for invalid label length
133
+ return;
134
+ }
135
+ // Check if we have room for this label plus the length byte
136
+ if (ptr + label_len + 1 > end) {
137
+ return; // Would overflow
138
+ }
139
+ ptr += label_len + 1;
140
+ }
141
+
142
+ // Check if we reached a proper null terminator
143
+ if (ptr >= end || *ptr != 0) {
144
+ return; // Name not terminated or truncated
145
+ }
146
+ ptr++; // Skip the null terminator
147
+
148
+ // Check we have room for the question
149
+ if (ptr + sizeof(DNSQuestion) > end) {
150
+ return; // Request truncated
151
+ }
152
+
153
+ // Parse DNS question
154
+ DNSQuestion *question = (DNSQuestion *) ptr;
155
+ uint16_t qtype = ntohs(question->type);
156
+ uint16_t qclass = ntohs(question->dns_class);
157
+
158
+ // We only handle A queries
159
+ if (qtype != DNS_QTYPE_A || qclass != DNS_QCLASS_IN) {
160
+ ESP_LOGV(TAG, "Not an A query: type=0x%04X, class=0x%04X", qtype, qclass);
161
+ return; // Not an A query
162
+ }
163
+
164
+ // Build DNS response by modifying the request in-place
165
+ header->flags = htons(DNS_QR_FLAG | 0x8000); // Response + Authoritative
166
+ header->an_count = htons(1); // One answer
167
+
168
+ // Add answer section after the question
169
+ size_t question_len = (ptr + sizeof(DNSQuestion)) - this->buffer_ - sizeof(DNSHeader);
170
+ size_t answer_offset = sizeof(DNSHeader) + question_len;
171
+
172
+ // Check if we have room for the answer
173
+ if (answer_offset + sizeof(DNSAnswer) > sizeof(this->buffer_)) {
174
+ ESP_LOGW(TAG, "Response too large");
175
+ return;
176
+ }
177
+
178
+ DNSAnswer *answer = (DNSAnswer *) (this->buffer_ + answer_offset);
179
+
180
+ // Pointer to name in question (offset from start of packet)
181
+ answer->ptr_offset = htons(0xC000 | sizeof(DNSHeader));
182
+ answer->type = htons(DNS_QTYPE_A);
183
+ answer->dns_class = htons(DNS_QCLASS_IN);
184
+ answer->ttl = htonl(DNS_ANSWER_TTL);
185
+ answer->addr_len = htons(4);
186
+
187
+ // Get the raw IP address
188
+ ip4_addr_t addr = this->server_ip_;
189
+ answer->ip_addr = addr.addr;
190
+
191
+ size_t response_len = answer_offset + sizeof(DNSAnswer);
192
+
193
+ // Send response
194
+ ssize_t sent =
195
+ this->socket_->sendto(this->buffer_, response_len, 0, (struct sockaddr *) &client_addr, client_addr_len);
196
+ if (sent < 0) {
197
+ ESP_LOGV(TAG, "Send failed: %d", errno);
198
+ } else {
199
+ ESP_LOGV(TAG, "Sent %d bytes", sent);
200
+ }
201
+ }
202
+
203
+ } // namespace esphome::captive_portal
204
+
205
+ #endif // USE_ESP_IDF
@@ -0,0 +1,27 @@
1
+ #pragma once
2
+ #ifdef USE_ESP_IDF
3
+
4
+ #include <memory>
5
+ #include "esphome/core/helpers.h"
6
+ #include "esphome/components/network/ip_address.h"
7
+ #include "esphome/components/socket/socket.h"
8
+
9
+ namespace esphome::captive_portal {
10
+
11
+ class DNSServer {
12
+ public:
13
+ void start(const network::IPAddress &ip);
14
+ void stop();
15
+ void process_next_request();
16
+
17
+ protected:
18
+ static constexpr size_t DNS_BUFFER_SIZE = 192;
19
+
20
+ std::unique_ptr<socket::Socket> socket_{nullptr};
21
+ network::IPAddress server_ip_;
22
+ uint8_t buffer_[DNS_BUFFER_SIZE];
23
+ };
24
+
25
+ } // namespace esphome::captive_portal
26
+
27
+ #endif // USE_ESP_IDF
@@ -155,7 +155,7 @@ void CCS811Component::dump_config() {
155
155
  LOG_UPDATE_INTERVAL(this);
156
156
  LOG_SENSOR(" ", "CO2 Sensor", this->co2_);
157
157
  LOG_SENSOR(" ", "TVOC Sensor", this->tvoc_);
158
- LOG_TEXT_SENSOR(" ", "Firmware Version Sensor", this->version_)
158
+ LOG_TEXT_SENSOR(" ", "Firmware Version Sensor", this->version_);
159
159
  if (this->baseline_) {
160
160
  ESP_LOGCONFIG(TAG, " Baseline: %04X", *this->baseline_);
161
161
  } else {
@@ -367,9 +367,11 @@ void Climate::save_state_() {
367
367
  state.uses_custom_fan_mode = true;
368
368
  const auto &supported = traits.get_supported_custom_fan_modes();
369
369
  std::vector<std::string> vec{supported.begin(), supported.end()};
370
- auto it = std::find(vec.begin(), vec.end(), custom_fan_mode);
371
- if (it != vec.end()) {
372
- state.custom_fan_mode = std::distance(vec.begin(), it);
370
+ for (size_t i = 0; i < vec.size(); i++) {
371
+ if (vec[i] == custom_fan_mode) {
372
+ state.custom_fan_mode = i;
373
+ break;
374
+ }
373
375
  }
374
376
  }
375
377
  if (traits.get_supports_presets() && preset.has_value()) {
@@ -380,10 +382,11 @@ void Climate::save_state_() {
380
382
  state.uses_custom_preset = true;
381
383
  const auto &supported = traits.get_supported_custom_presets();
382
384
  std::vector<std::string> vec{supported.begin(), supported.end()};
383
- auto it = std::find(vec.begin(), vec.end(), custom_preset);
384
- // only set custom preset if value exists, otherwise leave it as is
385
- if (it != vec.cend()) {
386
- state.custom_preset = std::distance(vec.begin(), it);
385
+ for (size_t i = 0; i < vec.size(); i++) {
386
+ if (vec[i] == custom_preset) {
387
+ state.custom_preset = i;
388
+ break;
389
+ }
387
390
  }
388
391
  }
389
392
  if (traits.get_supports_swing_modes()) {
@@ -13,7 +13,7 @@ static const uint8_t C_M1106_CMD_SET_CO2_CALIB_RESPONSE[4] = {0x16, 0x01, 0x03,
13
13
 
14
14
  uint8_t cm1106_checksum(const uint8_t *response, size_t len) {
15
15
  uint8_t crc = 0;
16
- for (int i = 0; i < len - 1; i++) {
16
+ for (size_t i = 0; i < len - 1; i++) {
17
17
  crc -= response[i];
18
18
  }
19
19
  return crc;
@@ -11,7 +11,7 @@ void CopyLock::setup() {
11
11
 
12
12
  traits.set_assumed_state(source_->traits.get_assumed_state());
13
13
  traits.set_requires_code(source_->traits.get_requires_code());
14
- traits.set_supported_states(source_->traits.get_supported_states());
14
+ traits.set_supported_states_mask(source_->traits.get_supported_states_mask());
15
15
  traits.set_supports_open(source_->traits.get_supports_open());
16
16
 
17
17
  this->publish_state(source_->state);
@@ -1,5 +1,6 @@
1
1
  #include "cover.h"
2
2
  #include "esphome/core/log.h"
3
+ #include <strings.h>
3
4
 
4
5
  namespace esphome {
5
6
  namespace cover {