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
@@ -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
@@ -0,0 +1,93 @@
1
+ #pragma once
2
+
3
+ #include "esphome/components/display/display_buffer.h"
4
+ #include "esphome/components/spi/spi.h"
5
+ #include "esphome/components/split_buffer/split_buffer.h"
6
+ #include "esphome/core/component.h"
7
+
8
+ #include <queue>
9
+
10
+ namespace esphome::epaper_spi {
11
+
12
+ enum class EPaperState : uint8_t {
13
+ IDLE,
14
+ UPDATE,
15
+ RESET,
16
+ INITIALISE,
17
+ TRANSFER_DATA,
18
+ POWER_ON,
19
+ REFRESH_SCREEN,
20
+ POWER_OFF,
21
+ DEEP_SLEEP,
22
+ };
23
+
24
+ static const uint8_t MAX_TRANSFER_TIME = 10; // Transfer in 10ms blocks to allow the loop to run
25
+
26
+ class EPaperBase : public display::DisplayBuffer,
27
+ public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_LEADING,
28
+ spi::DATA_RATE_2MHZ> {
29
+ public:
30
+ EPaperBase(const uint8_t *init_sequence, const size_t init_sequence_length)
31
+ : init_sequence_length_(init_sequence_length), init_sequence_(init_sequence) {}
32
+ void set_dc_pin(GPIOPin *dc_pin) { dc_pin_ = dc_pin; }
33
+ float get_setup_priority() const override;
34
+ void set_reset_pin(GPIOPin *reset) { this->reset_pin_ = reset; }
35
+ void set_busy_pin(GPIOPin *busy) { this->busy_pin_ = busy; }
36
+ void set_reset_duration(uint32_t reset_duration) { this->reset_duration_ = reset_duration; }
37
+
38
+ void command(uint8_t value);
39
+ void data(uint8_t value);
40
+ void cmd_data(const uint8_t *data);
41
+
42
+ void update() override;
43
+ void loop() override;
44
+
45
+ void setup() override;
46
+
47
+ void on_safe_shutdown() override;
48
+
49
+ protected:
50
+ bool is_idle_();
51
+ void setup_pins_();
52
+ virtual void reset();
53
+ void initialise_();
54
+ bool init_buffer_(size_t buffer_length);
55
+
56
+ virtual int get_width_controller() { return this->get_width_internal(); };
57
+ virtual void deep_sleep() = 0;
58
+ /**
59
+ * Send data to the device via SPI
60
+ * @return true if done, false if should be called next loop
61
+ */
62
+ virtual bool transfer_data() = 0;
63
+ virtual void refresh_screen() = 0;
64
+
65
+ virtual void power_on() = 0;
66
+ virtual void power_off() = 0;
67
+ virtual uint32_t get_buffer_length() = 0;
68
+
69
+ void start_command_();
70
+ void end_command_();
71
+ void start_data_();
72
+ void end_data_();
73
+
74
+ const size_t init_sequence_length_{0};
75
+
76
+ size_t current_data_index_{0};
77
+ uint32_t reset_duration_{200};
78
+ uint32_t waiting_for_idle_last_print_{0};
79
+
80
+ GPIOPin *dc_pin_;
81
+ GPIOPin *busy_pin_{nullptr};
82
+ GPIOPin *reset_pin_{nullptr};
83
+
84
+ const uint8_t *init_sequence_{nullptr};
85
+
86
+ bool waiting_for_idle_{false};
87
+
88
+ split_buffer::SplitBuffer buffer_;
89
+
90
+ std::queue<EPaperState> state_queue_{{EPaperState::IDLE}};
91
+ };
92
+
93
+ } // namespace esphome::epaper_spi
@@ -0,0 +1,42 @@
1
+ #include "epaper_spi_model_7p3in_spectra_e6.h"
2
+
3
+ namespace esphome::epaper_spi {
4
+
5
+ static constexpr const char *const TAG = "epaper_spi.7.3in-spectra-e6";
6
+
7
+ void EPaper7p3InSpectraE6::power_on() {
8
+ ESP_LOGI(TAG, "Power on");
9
+ this->command(0x04);
10
+ this->waiting_for_idle_ = true;
11
+ }
12
+
13
+ void EPaper7p3InSpectraE6::power_off() {
14
+ ESP_LOGI(TAG, "Power off");
15
+ this->command(0x02);
16
+ this->data(0x00);
17
+ this->waiting_for_idle_ = true;
18
+ }
19
+
20
+ void EPaper7p3InSpectraE6::refresh_screen() {
21
+ ESP_LOGI(TAG, "Refresh");
22
+ this->command(0x12);
23
+ this->data(0x00);
24
+ this->waiting_for_idle_ = true;
25
+ }
26
+
27
+ void EPaper7p3InSpectraE6::deep_sleep() {
28
+ ESP_LOGI(TAG, "Deep sleep");
29
+ this->command(0x07);
30
+ this->data(0xA5);
31
+ }
32
+
33
+ void EPaper7p3InSpectraE6::dump_config() {
34
+ LOG_DISPLAY("", "E-Paper SPI", this);
35
+ ESP_LOGCONFIG(TAG, " Model: 7.3in Spectra E6");
36
+ LOG_PIN(" Reset Pin: ", this->reset_pin_);
37
+ LOG_PIN(" DC Pin: ", this->dc_pin_);
38
+ LOG_PIN(" Busy Pin: ", this->busy_pin_);
39
+ LOG_UPDATE_INTERVAL(this);
40
+ }
41
+
42
+ } // namespace esphome::epaper_spi
@@ -0,0 +1,45 @@
1
+ #pragma once
2
+
3
+ #include "epaper_spi_spectra_e6.h"
4
+
5
+ namespace esphome::epaper_spi {
6
+
7
+ class EPaper7p3InSpectraE6 : public EPaperSpectraE6 {
8
+ static constexpr const uint16_t WIDTH = 800;
9
+ static constexpr const uint16_t HEIGHT = 480;
10
+ // clang-format off
11
+
12
+ // Command, data length, data
13
+ static constexpr uint8_t INIT_SEQUENCE[] = {
14
+ 0xAA, 6, 0x49, 0x55, 0x20, 0x08, 0x09, 0x18,
15
+ 0x01, 1, 0x3F,
16
+ 0x00, 2, 0x5F, 0x69,
17
+ 0x03, 4, 0x00, 0x54, 0x00, 0x44,
18
+ 0x05, 4, 0x40, 0x1F, 0x1F, 0x2C,
19
+ 0x06, 4, 0x6F, 0x1F, 0x17, 0x49,
20
+ 0x08, 4, 0x6F, 0x1F, 0x1F, 0x22,
21
+ 0x30, 1, 0x03,
22
+ 0x50, 1, 0x3F,
23
+ 0x60, 2, 0x02, 0x00,
24
+ 0x61, 4, WIDTH / 256, WIDTH % 256, HEIGHT / 256, HEIGHT % 256,
25
+ 0x84, 1, 0x01,
26
+ 0xE3, 1, 0x2F,
27
+ };
28
+ // clang-format on
29
+
30
+ public:
31
+ EPaper7p3InSpectraE6() : EPaperSpectraE6(INIT_SEQUENCE, sizeof(INIT_SEQUENCE)) {}
32
+
33
+ void dump_config() override;
34
+
35
+ protected:
36
+ int get_width_internal() override { return WIDTH; };
37
+ int get_height_internal() override { return HEIGHT; };
38
+
39
+ void refresh_screen() override;
40
+ void power_on() override;
41
+ void power_off() override;
42
+ void deep_sleep() override;
43
+ };
44
+
45
+ } // namespace esphome::epaper_spi
@@ -0,0 +1,135 @@
1
+ #include "epaper_spi_spectra_e6.h"
2
+
3
+ #include "esphome/core/log.h"
4
+
5
+ namespace esphome::epaper_spi {
6
+
7
+ static constexpr const char *const TAG = "epaper_spi.6c";
8
+
9
+ static inline uint8_t color_to_hex(Color color) {
10
+ if (color.red > 127) {
11
+ if (color.green > 170) {
12
+ if (color.blue > 127) {
13
+ return 0x1; // White
14
+ } else {
15
+ return 0x2; // Yellow
16
+ }
17
+ } else {
18
+ return 0x3; // Red (or Magenta)
19
+ }
20
+ } else {
21
+ if (color.green > 127) {
22
+ if (color.blue > 127) {
23
+ return 0x5; // Cyan -> Blue
24
+ } else {
25
+ return 0x6; // Green
26
+ }
27
+ } else {
28
+ if (color.blue > 127) {
29
+ return 0x5; // Blue
30
+ } else {
31
+ return 0x0; // Black
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ void EPaperSpectraE6::fill(Color color) {
38
+ uint8_t pixel_color;
39
+ if (color.is_on()) {
40
+ pixel_color = color_to_hex(color);
41
+ } else {
42
+ pixel_color = 0x1;
43
+ }
44
+
45
+ // We store 8 bitset<3> in 3 bytes
46
+ // | byte 1 | byte 2 | byte 3 |
47
+ // |aaabbbaa|abbbaaab|bbaaabbb|
48
+ uint8_t byte_1 = pixel_color << 5 | pixel_color << 2 | pixel_color >> 1;
49
+ uint8_t byte_2 = pixel_color << 7 | pixel_color << 4 | pixel_color << 1 | pixel_color >> 2;
50
+ uint8_t byte_3 = pixel_color << 6 | pixel_color << 3 | pixel_color << 0;
51
+
52
+ const size_t buffer_length = this->get_buffer_length();
53
+ for (size_t i = 0; i < buffer_length; i += 3) {
54
+ this->buffer_[i + 0] = byte_1;
55
+ this->buffer_[i + 1] = byte_2;
56
+ this->buffer_[i + 2] = byte_3;
57
+ }
58
+ }
59
+
60
+ uint32_t EPaperSpectraE6::get_buffer_length() {
61
+ // 6 colors buffer, 1 pixel = 3 bits, we will store 8 pixels in 24 bits = 3 bytes
62
+ return this->get_width_controller() * this->get_height_internal() / 8u * 3u;
63
+ }
64
+
65
+ void HOT EPaperSpectraE6::draw_absolute_pixel_internal(int x, int y, Color color) {
66
+ if (x >= this->get_width_internal() || y >= this->get_height_internal() || x < 0 || y < 0)
67
+ return;
68
+
69
+ uint8_t pixel_bits = color_to_hex(color);
70
+ uint32_t pixel_position = x + y * this->get_width_controller();
71
+ uint32_t first_bit_position = pixel_position * 3;
72
+ uint32_t byte_position = first_bit_position / 8u;
73
+ uint32_t byte_subposition = first_bit_position % 8u;
74
+
75
+ if (byte_subposition <= 5) {
76
+ this->buffer_[byte_position] = (this->buffer_[byte_position] & (0xFF ^ (0b111 << (5 - byte_subposition)))) |
77
+ (pixel_bits << (5 - byte_subposition));
78
+ } else {
79
+ this->buffer_[byte_position] = (this->buffer_[byte_position] & (0xFF ^ (0b111 >> (byte_subposition - 5)))) |
80
+ (pixel_bits >> (byte_subposition - 5));
81
+
82
+ this->buffer_[byte_position + 1] =
83
+ (this->buffer_[byte_position + 1] & (0xFF ^ (0xFF & (0b111 << (13 - byte_subposition))))) |
84
+ (pixel_bits << (13 - byte_subposition));
85
+ }
86
+ }
87
+
88
+ bool HOT EPaperSpectraE6::transfer_data() {
89
+ const uint32_t start_time = App.get_loop_component_start_time();
90
+ if (this->current_data_index_ == 0) {
91
+ ESP_LOGV(TAG, "Sending data");
92
+ this->command(0x10);
93
+ }
94
+
95
+ uint8_t bytes_to_send[4]{0};
96
+ const size_t buffer_length = this->get_buffer_length();
97
+ for (size_t i = this->current_data_index_; i < buffer_length; i += 3) {
98
+ const uint32_t triplet = encode_uint24(this->buffer_[i + 0], this->buffer_[i + 1], this->buffer_[i + 2]);
99
+ // 8 pixels are stored in 3 bytes
100
+ // |aaabbbaa|abbbaaab|bbaaabbb|
101
+ // | byte 1 | byte 2 | byte 3 |
102
+ bytes_to_send[0] = ((triplet >> 17) & 0b01110000) | ((triplet >> 18) & 0b00000111);
103
+ bytes_to_send[1] = ((triplet >> 11) & 0b01110000) | ((triplet >> 12) & 0b00000111);
104
+ bytes_to_send[2] = ((triplet >> 5) & 0b01110000) | ((triplet >> 6) & 0b00000111);
105
+ bytes_to_send[3] = ((triplet << 1) & 0b01110000) | ((triplet << 0) & 0b00000111);
106
+
107
+ this->start_data_();
108
+ this->write_array(bytes_to_send, sizeof(bytes_to_send));
109
+ this->end_data_();
110
+
111
+ if (millis() - start_time > MAX_TRANSFER_TIME) {
112
+ // Let the main loop run and come back next loop
113
+ this->current_data_index_ = i + 3;
114
+ return false;
115
+ }
116
+ }
117
+ // Finished the entire dataset
118
+ this->current_data_index_ = 0;
119
+ return true;
120
+ }
121
+
122
+ void EPaperSpectraE6::reset() {
123
+ if (this->reset_pin_ != nullptr) {
124
+ this->disable_loop();
125
+ this->reset_pin_->digital_write(true);
126
+ this->set_timeout(20, [this] {
127
+ this->reset_pin_->digital_write(false);
128
+ delay(2);
129
+ this->reset_pin_->digital_write(true);
130
+ this->set_timeout(20, [this] { this->enable_loop(); });
131
+ });
132
+ }
133
+ }
134
+
135
+ } // namespace esphome::epaper_spi
@@ -0,0 +1,23 @@
1
+ #pragma once
2
+
3
+ #include "epaper_spi.h"
4
+
5
+ namespace esphome::epaper_spi {
6
+
7
+ class EPaperSpectraE6 : public EPaperBase {
8
+ public:
9
+ EPaperSpectraE6(const uint8_t *init_sequence, const size_t init_sequence_length)
10
+ : EPaperBase(init_sequence, init_sequence_length) {}
11
+
12
+ display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }
13
+ void fill(Color color) override;
14
+
15
+ protected:
16
+ void draw_absolute_pixel_internal(int x, int y, Color color) override;
17
+ uint32_t get_buffer_length() override;
18
+
19
+ bool transfer_data() override;
20
+ void reset() override;
21
+ };
22
+
23
+ } // namespace esphome::epaper_spi
@@ -97,12 +97,12 @@ bool ES7210::set_mic_gain(float mic_gain) {
97
97
  }
98
98
 
99
99
  bool ES7210::configure_sample_rate_() {
100
- int mclk_fre = this->sample_rate_ * MCLK_DIV_FRE;
100
+ uint32_t mclk_fre = this->sample_rate_ * MCLK_DIV_FRE;
101
101
  int coeff = -1;
102
102
 
103
- for (int i = 0; i < (sizeof(ES7210_COEFFICIENTS) / sizeof(ES7210_COEFFICIENTS[0])); ++i) {
103
+ for (size_t i = 0; i < (sizeof(ES7210_COEFFICIENTS) / sizeof(ES7210_COEFFICIENTS[0])); ++i) {
104
104
  if (ES7210_COEFFICIENTS[i].lrclk == this->sample_rate_ && ES7210_COEFFICIENTS[i].mclk == mclk_fre)
105
- coeff = i;
105
+ coeff = static_cast<int>(i);
106
106
  }
107
107
 
108
108
  if (coeff >= 0) {