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
@@ -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 {
@@ -26,7 +26,7 @@ void DaikinArcClimate::transmit_query_() {
26
26
  uint8_t remote_header[8] = {0x11, 0xDA, 0x27, 0x00, 0x84, 0x87, 0x20, 0x00};
27
27
 
28
28
  // Calculate checksum
29
- for (int i = 0; i < sizeof(remote_header) - 1; i++) {
29
+ for (size_t i = 0; i < sizeof(remote_header) - 1; i++) {
30
30
  remote_header[sizeof(remote_header) - 1] += remote_header[i];
31
31
  }
32
32
 
@@ -102,7 +102,7 @@ void DaikinArcClimate::transmit_state() {
102
102
  remote_state[9] = fan_speed & 0xff;
103
103
 
104
104
  // Calculate checksum
105
- for (int i = 0; i < sizeof(remote_header) - 1; i++) {
105
+ for (size_t i = 0; i < sizeof(remote_header) - 1; i++) {
106
106
  remote_header[sizeof(remote_header) - 1] += remote_header[i];
107
107
  }
108
108
 
@@ -350,7 +350,7 @@ bool DaikinArcClimate::on_receive(remote_base::RemoteReceiveData data) {
350
350
  bool valid_daikin_frame = false;
351
351
  if (data.expect_item(DAIKIN_HEADER_MARK, DAIKIN_HEADER_SPACE)) {
352
352
  valid_daikin_frame = true;
353
- int bytes_count = data.size() / 2 / 8;
353
+ size_t bytes_count = data.size() / 2 / 8;
354
354
  std::unique_ptr<char[]> buf(new char[bytes_count * 3 + 1]);
355
355
  buf[0] = '\0';
356
356
  for (size_t i = 0; i < bytes_count; i++) {
@@ -370,7 +370,7 @@ bool DaikinArcClimate::on_receive(remote_base::RemoteReceiveData data) {
370
370
  if (!valid_daikin_frame) {
371
371
  char sbuf[16 * 10 + 1];
372
372
  sbuf[0] = '\0';
373
- for (size_t j = 0; j < data.size(); j++) {
373
+ for (size_t j = 0; j < static_cast<size_t>(data.size()); j++) {
374
374
  if ((j - 2) % 16 == 0) {
375
375
  if (j > 0) {
376
376
  ESP_LOGD(TAG, "DATA %04x: %s", (j - 16 > 0xffff ? 0 : j - 16), sbuf);
@@ -380,19 +380,26 @@ bool DaikinArcClimate::on_receive(remote_base::RemoteReceiveData data) {
380
380
  char type_ch = ' ';
381
381
  // debug_tolerance = 25%
382
382
 
383
- if (DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_MARK))
383
+ if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_MARK)) <= data[j] &&
384
+ data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_MARK)))
384
385
  type_ch = 'P';
385
- if (DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_SPACE))
386
+ if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ARC_PRE_SPACE)) <= -data[j] &&
387
+ -data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ARC_PRE_SPACE)))
386
388
  type_ch = 'a';
387
- if (DAIKIN_DBG_LOWER(DAIKIN_HEADER_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_HEADER_MARK))
389
+ if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_HEADER_MARK)) <= data[j] &&
390
+ data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_HEADER_MARK)))
388
391
  type_ch = 'H';
389
- if (DAIKIN_DBG_LOWER(DAIKIN_HEADER_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_HEADER_SPACE))
392
+ if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_HEADER_SPACE)) <= -data[j] &&
393
+ -data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_HEADER_SPACE)))
390
394
  type_ch = 'h';
391
- if (DAIKIN_DBG_LOWER(DAIKIN_BIT_MARK) <= data[j] && data[j] <= DAIKIN_DBG_UPPER(DAIKIN_BIT_MARK))
395
+ if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_BIT_MARK)) <= data[j] &&
396
+ data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_BIT_MARK)))
392
397
  type_ch = 'B';
393
- if (DAIKIN_DBG_LOWER(DAIKIN_ONE_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ONE_SPACE))
398
+ if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ONE_SPACE)) <= -data[j] &&
399
+ -data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ONE_SPACE)))
394
400
  type_ch = '1';
395
- if (DAIKIN_DBG_LOWER(DAIKIN_ZERO_SPACE) <= -data[j] && -data[j] <= DAIKIN_DBG_UPPER(DAIKIN_ZERO_SPACE))
401
+ if (static_cast<int32_t>(DAIKIN_DBG_LOWER(DAIKIN_ZERO_SPACE)) <= -data[j] &&
402
+ -data[j] <= static_cast<int32_t>(DAIKIN_DBG_UPPER(DAIKIN_ZERO_SPACE)))
396
403
  type_ch = '0';
397
404
 
398
405
  if (abs(data[j]) > 100000) {
@@ -400,7 +407,7 @@ bool DaikinArcClimate::on_receive(remote_base::RemoteReceiveData data) {
400
407
  } else {
401
408
  sprintf(sbuf, "%s%-5d[%c] ", sbuf, (int) (round(data[j] / 10.) * 10), type_ch);
402
409
  }
403
- if (j == data.size() - 1) {
410
+ if (j + 1 == static_cast<size_t>(data.size())) {
404
411
  ESP_LOGD(TAG, "DATA %04x: %s", (j - 8 > 0xffff ? 0 : j - 8), sbuf);
405
412
  }
406
413
  }
@@ -197,7 +197,8 @@ CONFIG_SCHEMA = cv.All(
197
197
  cv.Optional(CONF_ESP32_EXT1_WAKEUP): cv.All(
198
198
  cv.only_on_esp32,
199
199
  esp32.only_on_variant(
200
- unsupported=[VARIANT_ESP32C3], msg_prefix="Wakeup from ext1"
200
+ unsupported=[VARIANT_ESP32C2, VARIANT_ESP32C3],
201
+ msg_prefix="Wakeup from ext1",
201
202
  ),
202
203
  cv.Schema(
203
204
  {
@@ -214,7 +215,13 @@ CONFIG_SCHEMA = cv.All(
214
215
  cv.Optional(CONF_TOUCH_WAKEUP): cv.All(
215
216
  cv.only_on_esp32,
216
217
  esp32.only_on_variant(
217
- unsupported=[VARIANT_ESP32C3], msg_prefix="Wakeup from touch"
218
+ unsupported=[
219
+ VARIANT_ESP32C2,
220
+ VARIANT_ESP32C3,
221
+ VARIANT_ESP32C6,
222
+ VARIANT_ESP32H2,
223
+ ],
224
+ msg_prefix="Wakeup from touch",
218
225
  ),
219
226
  cv.boolean,
220
227
  ),
@@ -34,7 +34,7 @@ enum WakeupPinMode {
34
34
  WAKEUP_PIN_MODE_INVERT_WAKEUP,
35
35
  };
36
36
 
37
- #if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C3)
37
+ #if defined(USE_ESP32) && !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3)
38
38
  struct Ext1Wakeup {
39
39
  uint64_t mask;
40
40
  esp_sleep_ext1_wakeup_mode_t wakeup_mode;
@@ -50,7 +50,7 @@ struct WakeupCauseToRunDuration {
50
50
  uint32_t gpio_cause;
51
51
  };
52
52
 
53
- #endif
53
+ #endif // USE_ESP32
54
54
 
55
55
  template<typename... Ts> class EnterDeepSleepAction;
56
56
 
@@ -73,20 +73,22 @@ class DeepSleepComponent : public Component {
73
73
  void set_wakeup_pin(InternalGPIOPin *pin) { this->wakeup_pin_ = pin; }
74
74
 
75
75
  void set_wakeup_pin_mode(WakeupPinMode wakeup_pin_mode);
76
- #endif
76
+ #endif // USE_ESP32
77
77
 
78
78
  #if defined(USE_ESP32)
79
- #if !defined(USE_ESP32_VARIANT_ESP32C3)
80
-
79
+ #if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3)
81
80
  void set_ext1_wakeup(Ext1Wakeup ext1_wakeup);
81
+ #endif
82
82
 
83
+ #if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) && \
84
+ !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2)
83
85
  void set_touch_wakeup(bool touch_wakeup);
84
-
85
86
  #endif
87
+
86
88
  // Set the duration in ms for how long the code should run before entering
87
89
  // deep sleep mode, according to the cause the ESP32 has woken.
88
90
  void set_run_duration(WakeupCauseToRunDuration wakeup_cause_to_run_duration);
89
- #endif
91
+ #endif // USE_ESP32
90
92
 
91
93
  /// Set a duration in ms for how long the code should run before entering deep sleep mode.
92
94
  void set_run_duration(uint32_t time_ms);
@@ -117,13 +119,13 @@ class DeepSleepComponent : public Component {
117
119
  InternalGPIOPin *wakeup_pin_;
118
120
  WakeupPinMode wakeup_pin_mode_{WAKEUP_PIN_MODE_IGNORE};
119
121
 
120
- #if !defined(USE_ESP32_VARIANT_ESP32C3)
122
+ #if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3)
121
123
  optional<Ext1Wakeup> ext1_wakeup_;
122
124
  #endif
123
125
 
124
126
  optional<bool> touch_wakeup_;
125
127
  optional<WakeupCauseToRunDuration> wakeup_cause_to_run_duration_;
126
- #endif
128
+ #endif // USE_ESP32
127
129
  optional<uint32_t> run_duration_;
128
130
  bool next_enter_deep_sleep_{false};
129
131
  bool prevent_{false};
@@ -7,6 +7,26 @@
7
7
  namespace esphome {
8
8
  namespace deep_sleep {
9
9
 
10
+ // Deep Sleep feature support matrix for ESP32 variants:
11
+ //
12
+ // | Variant | ext0 | ext1 | Touch | GPIO wakeup |
13
+ // |-----------|------|------|-------|-------------|
14
+ // | ESP32 | ✓ | ✓ | ✓ | |
15
+ // | ESP32-S2 | ✓ | ✓ | ✓ | |
16
+ // | ESP32-S3 | ✓ | ✓ | ✓ | |
17
+ // | ESP32-C2 | | | | ✓ |
18
+ // | ESP32-C3 | | | | ✓ |
19
+ // | ESP32-C5 | | (✓) | | (✓) |
20
+ // | ESP32-C6 | | ✓ | | ✓ |
21
+ // | ESP32-H2 | | ✓ | | |
22
+ //
23
+ // Notes:
24
+ // - (✓) = Supported by hardware but not yet implemented in ESPHome
25
+ // - ext0: Single pin wakeup using RTC GPIO (esp_sleep_enable_ext0_wakeup)
26
+ // - ext1: Multiple pin wakeup (esp_sleep_enable_ext1_wakeup)
27
+ // - Touch: Touch pad wakeup (esp_sleep_enable_touchpad_wakeup)
28
+ // - GPIO wakeup: GPIO wakeup for non-RTC pins (esp_deep_sleep_enable_gpio_wakeup)
29
+
10
30
  static const char *const TAG = "deep_sleep";
11
31
 
12
32
  optional<uint32_t> DeepSleepComponent::get_run_duration_() const {
@@ -30,13 +50,13 @@ void DeepSleepComponent::set_wakeup_pin_mode(WakeupPinMode wakeup_pin_mode) {
30
50
  this->wakeup_pin_mode_ = wakeup_pin_mode;
31
51
  }
32
52
 
33
- #if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32C6)
53
+ #if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3)
34
54
  void DeepSleepComponent::set_ext1_wakeup(Ext1Wakeup ext1_wakeup) { this->ext1_wakeup_ = ext1_wakeup; }
35
-
36
- #if !defined(USE_ESP32_VARIANT_ESP32H2)
37
- void DeepSleepComponent::set_touch_wakeup(bool touch_wakeup) { this->touch_wakeup_ = touch_wakeup; }
38
55
  #endif
39
56
 
57
+ #if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) && \
58
+ !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2)
59
+ void DeepSleepComponent::set_touch_wakeup(bool touch_wakeup) { this->touch_wakeup_ = touch_wakeup; }
40
60
  #endif
41
61
 
42
62
  void DeepSleepComponent::set_run_duration(WakeupCauseToRunDuration wakeup_cause_to_run_duration) {
@@ -72,9 +92,13 @@ bool DeepSleepComponent::prepare_to_sleep_() {
72
92
  }
73
93
 
74
94
  void DeepSleepComponent::deep_sleep_() {
75
- #if !defined(USE_ESP32_VARIANT_ESP32C3) && !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2)
95
+ // Timer wakeup - all variants support this
76
96
  if (this->sleep_duration_.has_value())
77
97
  esp_sleep_enable_timer_wakeup(*this->sleep_duration_);
98
+
99
+ // Single pin wakeup (ext0) - ESP32, S2, S3 only
100
+ #if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) && \
101
+ !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2)
78
102
  if (this->wakeup_pin_ != nullptr) {
79
103
  const auto gpio_pin = gpio_num_t(this->wakeup_pin_->get_pin());
80
104
  if (this->wakeup_pin_->get_flags() & gpio::FLAG_PULLUP) {
@@ -95,32 +119,15 @@ void DeepSleepComponent::deep_sleep_() {
95
119
  }
96
120
  esp_sleep_enable_ext0_wakeup(gpio_pin, level);
97
121
  }
98
- if (this->ext1_wakeup_.has_value()) {
99
- esp_sleep_enable_ext1_wakeup(this->ext1_wakeup_->mask, this->ext1_wakeup_->wakeup_mode);
100
- }
101
-
102
- if (this->touch_wakeup_.has_value() && *(this->touch_wakeup_)) {
103
- esp_sleep_enable_touchpad_wakeup();
104
- esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
105
- }
106
122
  #endif
107
123
 
108
- #if defined(USE_ESP32_VARIANT_ESP32H2)
109
- if (this->sleep_duration_.has_value())
110
- esp_sleep_enable_timer_wakeup(*this->sleep_duration_);
111
- if (this->ext1_wakeup_.has_value()) {
112
- esp_sleep_enable_ext1_wakeup(this->ext1_wakeup_->mask, this->ext1_wakeup_->wakeup_mode);
113
- }
114
- #endif
115
-
116
- #if defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6)
117
- if (this->sleep_duration_.has_value())
118
- esp_sleep_enable_timer_wakeup(*this->sleep_duration_);
124
+ // GPIO wakeup - C2, C3, C6 only
125
+ #if defined(USE_ESP32_VARIANT_ESP32C2) || defined(USE_ESP32_VARIANT_ESP32C3) || defined(USE_ESP32_VARIANT_ESP32C6)
119
126
  if (this->wakeup_pin_ != nullptr) {
120
127
  const auto gpio_pin = gpio_num_t(this->wakeup_pin_->get_pin());
121
- if (this->wakeup_pin_->get_flags() && gpio::FLAG_PULLUP) {
128
+ if (this->wakeup_pin_->get_flags() & gpio::FLAG_PULLUP) {
122
129
  gpio_sleep_set_pull_mode(gpio_pin, GPIO_PULLUP_ONLY);
123
- } else if (this->wakeup_pin_->get_flags() && gpio::FLAG_PULLDOWN) {
130
+ } else if (this->wakeup_pin_->get_flags() & gpio::FLAG_PULLDOWN) {
124
131
  gpio_sleep_set_pull_mode(gpio_pin, GPIO_PULLDOWN_ONLY);
125
132
  }
126
133
  gpio_sleep_set_direction(gpio_pin, GPIO_MODE_INPUT);
@@ -138,9 +145,26 @@ void DeepSleepComponent::deep_sleep_() {
138
145
  static_cast<esp_deepsleep_gpio_wake_up_mode_t>(level));
139
146
  }
140
147
  #endif
148
+
149
+ // Multiple pin wakeup (ext1) - All except C2, C3
150
+ #if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3)
151
+ if (this->ext1_wakeup_.has_value()) {
152
+ esp_sleep_enable_ext1_wakeup(this->ext1_wakeup_->mask, this->ext1_wakeup_->wakeup_mode);
153
+ }
154
+ #endif
155
+
156
+ // Touch wakeup - ESP32, S2, S3 only
157
+ #if !defined(USE_ESP32_VARIANT_ESP32C2) && !defined(USE_ESP32_VARIANT_ESP32C3) && \
158
+ !defined(USE_ESP32_VARIANT_ESP32C6) && !defined(USE_ESP32_VARIANT_ESP32H2)
159
+ if (this->touch_wakeup_.has_value() && *(this->touch_wakeup_)) {
160
+ esp_sleep_enable_touchpad_wakeup();
161
+ esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
162
+ }
163
+ #endif
164
+
141
165
  esp_deep_sleep_start();
142
166
  }
143
167
 
144
168
  } // namespace deep_sleep
145
169
  } // namespace esphome
146
- #endif
170
+ #endif // USE_ESP32
@@ -2,7 +2,7 @@ from esphome import pins
2
2
  import esphome.codegen as cg
3
3
  from esphome.components import i2c, touchscreen
4
4
  import esphome.config_validation as cv
5
- from esphome.const import CONF_ID, CONF_INTERRUPT_PIN
5
+ from esphome.const import CONF_ID, CONF_INTERRUPT_PIN, CONF_RESET_PIN
6
6
 
7
7
  CODEOWNERS = ["@jesserockz"]
8
8
  DEPENDENCIES = ["i2c"]
@@ -15,7 +15,7 @@ EKTF2232Touchscreen = ektf2232_ns.class_(
15
15
  )
16
16
 
17
17
  CONF_EKTF2232_ID = "ektf2232_id"
18
- CONF_RTS_PIN = "rts_pin"
18
+ CONF_RTS_PIN = "rts_pin" # To be removed before 2026.4.0
19
19
 
20
20
  CONFIG_SCHEMA = touchscreen.TOUCHSCREEN_SCHEMA.extend(
21
21
  cv.Schema(
@@ -24,7 +24,10 @@ CONFIG_SCHEMA = touchscreen.TOUCHSCREEN_SCHEMA.extend(
24
24
  cv.Required(CONF_INTERRUPT_PIN): cv.All(
25
25
  pins.internal_gpio_input_pin_schema
26
26
  ),
27
- cv.Required(CONF_RTS_PIN): pins.gpio_output_pin_schema,
27
+ cv.Required(CONF_RESET_PIN): pins.gpio_output_pin_schema,
28
+ cv.Optional(CONF_RTS_PIN): cv.invalid(
29
+ f"{CONF_RTS_PIN} has been renamed to {CONF_RESET_PIN}"
30
+ ),
28
31
  }
29
32
  ).extend(i2c.i2c_device_schema(0x15))
30
33
  )
@@ -37,5 +40,5 @@ async def to_code(config):
37
40
 
38
41
  interrupt_pin = await cg.gpio_pin_expression(config[CONF_INTERRUPT_PIN])
39
42
  cg.add(var.set_interrupt_pin(interrupt_pin))
40
- rts_pin = await cg.gpio_pin_expression(config[CONF_RTS_PIN])
41
- cg.add(var.set_rts_pin(rts_pin))
43
+ reset_pin = await cg.gpio_pin_expression(config[CONF_RESET_PIN])
44
+ cg.add(var.set_reset_pin(reset_pin))
@@ -21,7 +21,7 @@ void EKTF2232Touchscreen::setup() {
21
21
 
22
22
  this->attach_interrupt_(this->interrupt_pin_, gpio::INTERRUPT_FALLING_EDGE);
23
23
 
24
- this->rts_pin_->setup();
24
+ this->reset_pin_->setup();
25
25
 
26
26
  this->hard_reset_();
27
27
  if (!this->soft_reset_()) {
@@ -98,9 +98,9 @@ bool EKTF2232Touchscreen::get_power_state() {
98
98
  }
99
99
 
100
100
  void EKTF2232Touchscreen::hard_reset_() {
101
- this->rts_pin_->digital_write(false);
101
+ this->reset_pin_->digital_write(false);
102
102
  delay(15);
103
- this->rts_pin_->digital_write(true);
103
+ this->reset_pin_->digital_write(true);
104
104
  delay(15);
105
105
  }
106
106
 
@@ -127,7 +127,7 @@ void EKTF2232Touchscreen::dump_config() {
127
127
  ESP_LOGCONFIG(TAG, "EKT2232 Touchscreen:");
128
128
  LOG_I2C_DEVICE(this);
129
129
  LOG_PIN(" Interrupt Pin: ", this->interrupt_pin_);
130
- LOG_PIN(" RTS Pin: ", this->rts_pin_);
130
+ LOG_PIN(" Reset Pin: ", this->reset_pin_);
131
131
  }
132
132
 
133
133
  } // namespace ektf2232