esphome 2025.9.3__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 (343) 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 +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 +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/socket/lwip_raw_tcp_impl.cpp +34 -6
  215. esphome/components/sonoff_d1/sonoff_d1.cpp +1 -1
  216. esphome/components/spi/__init__.py +0 -3
  217. esphome/components/split_buffer/__init__.py +5 -0
  218. esphome/components/split_buffer/split_buffer.cpp +133 -0
  219. esphome/components/split_buffer/split_buffer.h +40 -0
  220. esphome/components/sps30/sps30.cpp +14 -10
  221. esphome/components/sps30/sps30.h +2 -0
  222. esphome/components/st7567_i2c/st7567_i2c.cpp +3 -1
  223. esphome/components/st7789v/st7789v.cpp +3 -2
  224. esphome/components/statsd/statsd.cpp +1 -1
  225. esphome/components/substitutions/__init__.py +3 -1
  226. esphome/components/substitutions/jinja.py +13 -3
  227. esphome/components/sx126x/__init__.py +16 -0
  228. esphome/components/sx126x/sx126x.cpp +15 -1
  229. esphome/components/sx126x/sx126x.h +9 -1
  230. esphome/components/sx126x/sx126x_reg.h +2 -0
  231. esphome/components/text_sensor/text_sensor.cpp +16 -0
  232. esphome/components/text_sensor/text_sensor.h +3 -10
  233. esphome/components/tormatic/tormatic_cover.cpp +1 -1
  234. esphome/components/tuya/select/tuya_select.cpp +1 -1
  235. esphome/components/tuya/tuya.cpp +29 -4
  236. esphome/components/uart/__init__.py +36 -26
  237. esphome/components/uart/uart.h +6 -0
  238. esphome/components/uart/uart_component.cpp +8 -0
  239. esphome/components/uart/uart_component.h +28 -0
  240. esphome/components/uart/uart_component_esp_idf.cpp +64 -10
  241. esphome/components/uart/uart_component_esp_idf.h +5 -2
  242. esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +1 -1
  243. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +1 -1
  244. esphome/components/uponor_smatrix/uponor_smatrix.cpp +3 -3
  245. esphome/components/usb_host/__init__.py +2 -1
  246. esphome/components/usb_host/usb_host.h +82 -13
  247. esphome/components/usb_host/usb_host_client.cpp +180 -24
  248. esphome/components/usb_host/usb_host_component.cpp +1 -1
  249. esphome/components/usb_uart/__init__.py +0 -1
  250. esphome/components/usb_uart/ch34x.cpp +4 -4
  251. esphome/components/usb_uart/cp210x.cpp +3 -3
  252. esphome/components/usb_uart/usb_uart.cpp +88 -32
  253. esphome/components/usb_uart/usb_uart.h +30 -6
  254. esphome/components/valve/valve.cpp +1 -0
  255. esphome/components/veml7700/veml7700.cpp +7 -6
  256. esphome/components/version/version_text_sensor.cpp +2 -1
  257. esphome/components/voice_assistant/voice_assistant.cpp +3 -2
  258. esphome/components/waveshare_epaper/waveshare_epaper.cpp +4 -4
  259. esphome/components/web_server/list_entities.cpp +3 -4
  260. esphome/components/web_server/list_entities.h +8 -10
  261. esphome/components/web_server/ota/__init__.py +1 -1
  262. esphome/components/web_server/ota/ota_web_server.cpp +9 -3
  263. esphome/components/web_server/web_server.cpp +509 -404
  264. esphome/components/web_server/web_server.h +5 -6
  265. esphome/components/web_server/web_server_v1.cpp +21 -19
  266. esphome/components/web_server_base/__init__.py +5 -2
  267. esphome/components/web_server_base/web_server_base.h +27 -7
  268. esphome/components/web_server_idf/__init__.py +1 -1
  269. esphome/components/web_server_idf/multipart.cpp +2 -2
  270. esphome/components/web_server_idf/multipart.h +2 -2
  271. esphome/components/web_server_idf/utils.cpp +2 -2
  272. esphome/components/web_server_idf/utils.h +2 -2
  273. esphome/components/web_server_idf/web_server_idf.cpp +118 -26
  274. esphome/components/web_server_idf/web_server_idf.h +12 -10
  275. esphome/components/wifi/__init__.py +13 -11
  276. esphome/components/wifi/wifi_component.cpp +73 -56
  277. esphome/components/wifi/wifi_component.h +4 -4
  278. esphome/components/wifi/wifi_component_esp8266.cpp +1 -1
  279. esphome/components/wifi/wifi_component_esp_idf.cpp +24 -4
  280. esphome/components/wireguard/__init__.py +1 -1
  281. esphome/components/wts01/__init__.py +0 -0
  282. esphome/components/wts01/sensor.py +41 -0
  283. esphome/components/wts01/wts01.cpp +91 -0
  284. esphome/components/wts01/wts01.h +27 -0
  285. esphome/components/zephyr/__init__.py +5 -5
  286. esphome/components/zwave_proxy/__init__.py +43 -0
  287. esphome/components/zwave_proxy/zwave_proxy.cpp +346 -0
  288. esphome/components/zwave_proxy/zwave_proxy.h +93 -0
  289. esphome/config.py +79 -24
  290. esphome/config_validation.py +13 -15
  291. esphome/const.py +9 -2
  292. esphome/core/__init__.py +31 -22
  293. esphome/core/component.cpp +28 -18
  294. esphome/core/component_iterator.h +2 -1
  295. esphome/core/config.py +15 -15
  296. esphome/core/defines.h +19 -0
  297. esphome/core/hash_base.h +56 -0
  298. esphome/core/helpers.cpp +19 -3
  299. esphome/core/helpers.h +26 -0
  300. esphome/core/scheduler.cpp +5 -21
  301. esphome/core/scheduler.h +19 -8
  302. esphome/core/string_ref.h +1 -1
  303. esphome/core/time.cpp +5 -5
  304. esphome/cpp_generator.py +4 -29
  305. esphome/dashboard/const.py +21 -4
  306. esphome/dashboard/core.py +10 -8
  307. esphome/dashboard/dns.py +15 -0
  308. esphome/dashboard/entries.py +15 -21
  309. esphome/dashboard/models.py +76 -0
  310. esphome/dashboard/settings.py +7 -7
  311. esphome/dashboard/status/mdns.py +46 -2
  312. esphome/dashboard/web_server.py +367 -93
  313. esphome/espota2.py +111 -31
  314. esphome/external_files.py +6 -7
  315. esphome/git.py +8 -0
  316. esphome/helpers.py +124 -77
  317. esphome/loader.py +8 -9
  318. esphome/platformio_api.py +25 -18
  319. esphome/storage_json.py +26 -21
  320. esphome/types.py +30 -2
  321. esphome/util.py +32 -16
  322. esphome/vscode.py +8 -8
  323. esphome/wizard.py +10 -10
  324. esphome/writer.py +50 -15
  325. esphome/yaml_util.py +37 -31
  326. esphome/zeroconf.py +12 -3
  327. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/METADATA +11 -11
  328. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/RECORD +332 -312
  329. esphome/components/event_emitter/__init__.py +0 -5
  330. esphome/components/event_emitter/event_emitter.cpp +0 -14
  331. esphome/components/event_emitter/event_emitter.h +0 -63
  332. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -125
  333. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +0 -107
  334. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +0 -110
  335. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -214
  336. esphome/components/uart/uart_component_esp32_arduino.h +0 -60
  337. esphome/components/wifi/wifi_component_esp32_arduino.cpp +0 -860
  338. esphome/core/string_ref.cpp +0 -12
  339. esphome/dashboard/util/file.py +0 -63
  340. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/WHEEL +0 -0
  341. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/entry_points.txt +0 -0
  342. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/licenses/LICENSE +0 -0
  343. {esphome-2025.9.3.dist-info → esphome-2025.10.0b1.dist-info}/top_level.txt +0 -0
@@ -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
@@ -17,7 +17,7 @@ class EKTF2232Touchscreen : public Touchscreen, public i2c::I2CDevice {
17
17
  void dump_config() override;
18
18
 
19
19
  void set_interrupt_pin(InternalGPIOPin *pin) { this->interrupt_pin_ = pin; }
20
- void set_rts_pin(GPIOPin *pin) { this->rts_pin_ = pin; }
20
+ void set_reset_pin(GPIOPin *pin) { this->reset_pin_ = pin; }
21
21
 
22
22
  void set_power_state(bool enable);
23
23
  bool get_power_state();
@@ -28,7 +28,7 @@ class EKTF2232Touchscreen : public Touchscreen, public i2c::I2CDevice {
28
28
  void update_touches() override;
29
29
 
30
30
  InternalGPIOPin *interrupt_pin_;
31
- GPIOPin *rts_pin_;
31
+ GPIOPin *reset_pin_;
32
32
  };
33
33
 
34
34
  } // namespace ektf2232
@@ -0,0 +1 @@
1
+ CODEOWNERS = ["@esphome/core"]
@@ -0,0 +1,80 @@
1
+ from esphome import core, pins
2
+ import esphome.codegen as cg
3
+ from esphome.components import display, spi
4
+ import esphome.config_validation as cv
5
+ from esphome.const import (
6
+ CONF_BUSY_PIN,
7
+ CONF_DC_PIN,
8
+ CONF_ID,
9
+ CONF_LAMBDA,
10
+ CONF_MODEL,
11
+ CONF_PAGES,
12
+ CONF_RESET_DURATION,
13
+ CONF_RESET_PIN,
14
+ )
15
+
16
+ AUTO_LOAD = ["split_buffer"]
17
+ DEPENDENCIES = ["spi"]
18
+
19
+ epaper_spi_ns = cg.esphome_ns.namespace("epaper_spi")
20
+ EPaperBase = epaper_spi_ns.class_(
21
+ "EPaperBase", cg.PollingComponent, spi.SPIDevice, display.DisplayBuffer
22
+ )
23
+
24
+ EPaperSpectraE6 = epaper_spi_ns.class_("EPaperSpectraE6", EPaperBase)
25
+ EPaper7p3InSpectraE6 = epaper_spi_ns.class_("EPaper7p3InSpectraE6", EPaperSpectraE6)
26
+
27
+ MODELS = {
28
+ "7.3in-spectra-e6": EPaper7p3InSpectraE6,
29
+ }
30
+
31
+
32
+ CONFIG_SCHEMA = cv.All(
33
+ display.FULL_DISPLAY_SCHEMA.extend(
34
+ {
35
+ cv.GenerateID(): cv.declare_id(EPaperBase),
36
+ cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema,
37
+ cv.Required(CONF_MODEL): cv.one_of(*MODELS, lower=True, space="-"),
38
+ cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
39
+ cv.Optional(CONF_BUSY_PIN): pins.gpio_input_pin_schema,
40
+ cv.Optional(CONF_RESET_DURATION): cv.All(
41
+ cv.positive_time_period_milliseconds,
42
+ cv.Range(max=core.TimePeriod(milliseconds=500)),
43
+ ),
44
+ }
45
+ )
46
+ .extend(cv.polling_component_schema("60s"))
47
+ .extend(spi.spi_device_schema()),
48
+ cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA),
49
+ )
50
+
51
+ FINAL_VALIDATE_SCHEMA = spi.final_validate_device_schema(
52
+ "epaper_spi", require_miso=False, require_mosi=True
53
+ )
54
+
55
+
56
+ async def to_code(config):
57
+ model = MODELS[config[CONF_MODEL]]
58
+
59
+ rhs = model.new()
60
+ var = cg.Pvariable(config[CONF_ID], rhs, model)
61
+
62
+ await display.register_display(var, config)
63
+ await spi.register_spi_device(var, config)
64
+
65
+ dc = await cg.gpio_pin_expression(config[CONF_DC_PIN])
66
+ cg.add(var.set_dc_pin(dc))
67
+
68
+ if CONF_LAMBDA in config:
69
+ lambda_ = await cg.process_lambda(
70
+ config[CONF_LAMBDA], [(display.DisplayRef, "it")], return_type=cg.void
71
+ )
72
+ cg.add(var.set_writer(lambda_))
73
+ if CONF_RESET_PIN in config:
74
+ reset = await cg.gpio_pin_expression(config[CONF_RESET_PIN])
75
+ cg.add(var.set_reset_pin(reset))
76
+ if CONF_BUSY_PIN in config:
77
+ busy = await cg.gpio_pin_expression(config[CONF_BUSY_PIN])
78
+ cg.add(var.set_busy_pin(busy))
79
+ if CONF_RESET_DURATION in config:
80
+ cg.add(var.set_reset_duration(config[CONF_RESET_DURATION]))
@@ -0,0 +1,227 @@
1
+ #include "epaper_spi.h"
2
+ #include <cinttypes>
3
+ #include "esphome/core/application.h"
4
+ #include "esphome/core/helpers.h"
5
+ #include "esphome/core/log.h"
6
+
7
+ namespace esphome::epaper_spi {
8
+
9
+ static const char *const TAG = "epaper_spi";
10
+
11
+ static const LogString *epaper_state_to_string(EPaperState state) {
12
+ switch (state) {
13
+ case EPaperState::IDLE:
14
+ return LOG_STR("IDLE");
15
+ case EPaperState::UPDATE:
16
+ return LOG_STR("UPDATE");
17
+ case EPaperState::RESET:
18
+ return LOG_STR("RESET");
19
+ case EPaperState::INITIALISE:
20
+ return LOG_STR("INITIALISE");
21
+ case EPaperState::TRANSFER_DATA:
22
+ return LOG_STR("TRANSFER_DATA");
23
+ case EPaperState::POWER_ON:
24
+ return LOG_STR("POWER_ON");
25
+ case EPaperState::REFRESH_SCREEN:
26
+ return LOG_STR("REFRESH_SCREEN");
27
+ case EPaperState::POWER_OFF:
28
+ return LOG_STR("POWER_OFF");
29
+ case EPaperState::DEEP_SLEEP:
30
+ return LOG_STR("DEEP_SLEEP");
31
+ default:
32
+ return LOG_STR("UNKNOWN");
33
+ }
34
+ }
35
+
36
+ void EPaperBase::setup() {
37
+ if (!this->init_buffer_(this->get_buffer_length())) {
38
+ this->mark_failed("Failed to initialise buffer");
39
+ return;
40
+ }
41
+ this->setup_pins_();
42
+ this->spi_setup();
43
+ }
44
+
45
+ bool EPaperBase::init_buffer_(size_t buffer_length) {
46
+ if (!this->buffer_.init(buffer_length)) {
47
+ return false;
48
+ }
49
+ this->clear();
50
+ return true;
51
+ }
52
+
53
+ void EPaperBase::setup_pins_() {
54
+ this->dc_pin_->setup(); // OUTPUT
55
+ this->dc_pin_->digital_write(false);
56
+
57
+ if (this->reset_pin_ != nullptr) {
58
+ this->reset_pin_->setup(); // OUTPUT
59
+ this->reset_pin_->digital_write(true);
60
+ }
61
+
62
+ if (this->busy_pin_ != nullptr) {
63
+ this->busy_pin_->setup(); // INPUT
64
+ }
65
+ }
66
+
67
+ float EPaperBase::get_setup_priority() const { return setup_priority::PROCESSOR; }
68
+
69
+ void EPaperBase::command(uint8_t value) {
70
+ this->start_command_();
71
+ this->write_byte(value);
72
+ this->end_command_();
73
+ }
74
+
75
+ void EPaperBase::data(uint8_t value) {
76
+ this->start_data_();
77
+ this->write_byte(value);
78
+ this->end_data_();
79
+ }
80
+
81
+ // write a command followed by zero or more bytes of data.
82
+ // The command is the first byte, length is the length of data only in the second byte, followed by the data.
83
+ // [COMMAND, LENGTH, DATA...]
84
+ void EPaperBase::cmd_data(const uint8_t *data) {
85
+ const uint8_t command = data[0];
86
+ const uint8_t length = data[1];
87
+ const uint8_t *ptr = data + 2;
88
+
89
+ ESP_LOGVV(TAG, "Command: 0x%02X, Length: %d, Data: %s", command, length,
90
+ format_hex_pretty(ptr, length, '.', false).c_str());
91
+
92
+ this->dc_pin_->digital_write(false);
93
+ this->enable();
94
+ this->write_byte(command);
95
+ if (length > 0) {
96
+ this->dc_pin_->digital_write(true);
97
+ this->write_array(ptr, length);
98
+ }
99
+ this->disable();
100
+ }
101
+
102
+ bool EPaperBase::is_idle_() {
103
+ if (this->busy_pin_ == nullptr) {
104
+ return true;
105
+ }
106
+ return !this->busy_pin_->digital_read();
107
+ }
108
+
109
+ void EPaperBase::reset() {
110
+ if (this->reset_pin_ != nullptr) {
111
+ this->reset_pin_->digital_write(false);
112
+ this->disable_loop();
113
+ this->set_timeout(this->reset_duration_, [this] {
114
+ this->reset_pin_->digital_write(true);
115
+ this->set_timeout(20, [this] { this->enable_loop(); });
116
+ });
117
+ }
118
+ }
119
+
120
+ void EPaperBase::update() {
121
+ if (!this->state_queue_.empty()) {
122
+ ESP_LOGE(TAG, "Display update already in progress - %s",
123
+ LOG_STR_ARG(epaper_state_to_string(this->state_queue_.front())));
124
+ return;
125
+ }
126
+
127
+ this->state_queue_.push(EPaperState::UPDATE);
128
+ this->state_queue_.push(EPaperState::RESET);
129
+ this->state_queue_.push(EPaperState::INITIALISE);
130
+ this->state_queue_.push(EPaperState::TRANSFER_DATA);
131
+ this->state_queue_.push(EPaperState::POWER_ON);
132
+ this->state_queue_.push(EPaperState::REFRESH_SCREEN);
133
+ this->state_queue_.push(EPaperState::POWER_OFF);
134
+ this->state_queue_.push(EPaperState::DEEP_SLEEP);
135
+ this->state_queue_.push(EPaperState::IDLE);
136
+
137
+ this->enable_loop();
138
+ }
139
+
140
+ void EPaperBase::loop() {
141
+ if (this->waiting_for_idle_) {
142
+ if (this->is_idle_()) {
143
+ this->waiting_for_idle_ = false;
144
+ } else {
145
+ if (App.get_loop_component_start_time() - this->waiting_for_idle_last_print_ >= 1000) {
146
+ ESP_LOGV(TAG, "Waiting for idle");
147
+ this->waiting_for_idle_last_print_ = App.get_loop_component_start_time();
148
+ }
149
+ return;
150
+ }
151
+ }
152
+
153
+ auto state = this->state_queue_.front();
154
+
155
+ switch (state) {
156
+ case EPaperState::IDLE:
157
+ this->disable_loop();
158
+ break;
159
+ case EPaperState::UPDATE:
160
+ this->do_update_(); // Calls ESPHome (current page) lambda
161
+ break;
162
+ case EPaperState::RESET:
163
+ this->reset();
164
+ break;
165
+ case EPaperState::INITIALISE:
166
+ this->initialise_();
167
+ break;
168
+ case EPaperState::TRANSFER_DATA:
169
+ if (!this->transfer_data()) {
170
+ return; // Not done yet, come back next loop
171
+ }
172
+ break;
173
+ case EPaperState::POWER_ON:
174
+ this->power_on();
175
+ break;
176
+ case EPaperState::REFRESH_SCREEN:
177
+ this->refresh_screen();
178
+ break;
179
+ case EPaperState::POWER_OFF:
180
+ this->power_off();
181
+ break;
182
+ case EPaperState::DEEP_SLEEP:
183
+ this->deep_sleep();
184
+ break;
185
+ }
186
+ this->state_queue_.pop();
187
+ }
188
+
189
+ void EPaperBase::start_command_() {
190
+ this->dc_pin_->digital_write(false);
191
+ this->enable();
192
+ }
193
+
194
+ void EPaperBase::end_command_() { this->disable(); }
195
+
196
+ void EPaperBase::start_data_() {
197
+ this->dc_pin_->digital_write(true);
198
+ this->enable();
199
+ }
200
+ void EPaperBase::end_data_() { this->disable(); }
201
+
202
+ void EPaperBase::on_safe_shutdown() { this->deep_sleep(); }
203
+
204
+ void EPaperBase::initialise_() {
205
+ size_t index = 0;
206
+ const auto &sequence = this->init_sequence_;
207
+ const size_t sequence_size = this->init_sequence_length_;
208
+ while (index != sequence_size) {
209
+ if (sequence_size - index < 2) {
210
+ this->mark_failed("Malformed init sequence");
211
+ return;
212
+ }
213
+ const auto *ptr = sequence + index;
214
+ const uint8_t length = ptr[1];
215
+ if (sequence_size - index < length + 2) {
216
+ this->mark_failed("Malformed init sequence");
217
+ return;
218
+ }
219
+
220
+ this->cmd_data(ptr);
221
+ index += length + 2;
222
+ }
223
+
224
+ this->power_on();
225
+ }
226
+
227
+ } // namespace esphome::epaper_spi