esphome 2025.7.4__py3-none-any.whl → 2025.8.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.

Potentially problematic release.


This version of esphome might be problematic. Click here for more details.

Files changed (754) hide show
  1. esphome/__main__.py +189 -82
  2. esphome/automation.py +2 -4
  3. esphome/build_gen/__init__.py +0 -0
  4. esphome/build_gen/platformio.py +102 -0
  5. esphome/components/a4988/a4988.cpp +0 -1
  6. esphome/components/absolute_humidity/absolute_humidity.cpp +0 -2
  7. esphome/components/absolute_humidity/sensor.py +2 -2
  8. esphome/components/adc/__init__.py +123 -85
  9. esphome/components/adc/adc_sensor.h +98 -35
  10. esphome/components/adc/adc_sensor_common.cpp +10 -4
  11. esphome/components/adc/adc_sensor_esp32.cpp +291 -123
  12. esphome/components/adc/adc_sensor_esp8266.cpp +1 -4
  13. esphome/components/adc/adc_sensor_libretiny.cpp +1 -2
  14. esphome/components/adc/adc_sensor_rp2040.cpp +1 -2
  15. esphome/components/adc/adc_sensor_zephyr.cpp +207 -0
  16. esphome/components/adc/sensor.py +61 -27
  17. esphome/components/adc128s102/adc128s102.cpp +1 -4
  18. esphome/components/ade7880/sensor.py +75 -49
  19. esphome/components/ads1115/ads1115.cpp +0 -1
  20. esphome/components/ads1118/ads1118.cpp +0 -1
  21. esphome/components/ags10/ags10.cpp +0 -4
  22. esphome/components/aht10/aht10.cpp +0 -4
  23. esphome/components/aic3204/aic3204.cpp +0 -2
  24. esphome/components/airthings_wave_plus/__init__.py +1 -1
  25. esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +22 -4
  26. esphome/components/airthings_wave_plus/airthings_wave_plus.h +10 -1
  27. esphome/components/airthings_wave_plus/sensor.py +55 -28
  28. esphome/components/alarm_control_panel/__init__.py +4 -9
  29. esphome/components/am2315c/am2315c.cpp +0 -2
  30. esphome/components/am2320/am2320.cpp +0 -1
  31. esphome/components/animation/__init__.py +14 -11
  32. esphome/components/apds9306/apds9306.cpp +0 -4
  33. esphome/components/apds9960/apds9960.cpp +0 -1
  34. esphome/components/api/__init__.py +29 -4
  35. esphome/components/api/api_connection.cpp +378 -401
  36. esphome/components/api/api_connection.h +112 -56
  37. esphome/components/api/api_frame_helper.cpp +69 -896
  38. esphome/components/api/api_frame_helper.h +31 -126
  39. esphome/components/api/api_frame_helper_noise.cpp +583 -0
  40. esphome/components/api/api_frame_helper_noise.h +68 -0
  41. esphome/components/api/api_frame_helper_plaintext.cpp +290 -0
  42. esphome/components/api/api_frame_helper_plaintext.h +53 -0
  43. esphome/components/api/api_noise_context.h +2 -4
  44. esphome/components/api/api_pb2.cpp +1601 -1808
  45. esphome/components/api/api_pb2.h +367 -323
  46. esphome/components/api/api_pb2_dump.cpp +1137 -3466
  47. esphome/components/api/api_pb2_includes.h +34 -0
  48. esphome/components/api/api_pb2_service.cpp +94 -105
  49. esphome/components/api/api_pb2_service.h +27 -16
  50. esphome/components/api/api_server.cpp +18 -17
  51. esphome/components/api/api_server.h +8 -5
  52. esphome/components/api/client.py +16 -8
  53. esphome/components/api/custom_api_device.h +68 -14
  54. esphome/components/api/homeassistant_service.h +24 -19
  55. esphome/components/api/list_entities.cpp +3 -5
  56. esphome/components/api/list_entities.h +2 -4
  57. esphome/components/api/proto.cpp +3 -5
  58. esphome/components/api/proto.h +239 -274
  59. esphome/components/api/subscribe_state.cpp +2 -4
  60. esphome/components/api/subscribe_state.h +2 -4
  61. esphome/components/api/user_services.cpp +2 -4
  62. esphome/components/api/user_services.h +8 -8
  63. esphome/components/as3935/as3935.cpp +0 -2
  64. esphome/components/as3935_spi/as3935_spi.cpp +0 -2
  65. esphome/components/as5600/__init__.py +1 -1
  66. esphome/components/as5600/as5600.cpp +0 -2
  67. esphome/components/as5600/sensor/__init__.py +0 -1
  68. esphome/components/as7341/as7341.cpp +0 -1
  69. esphome/components/async_tcp/__init__.py +1 -1
  70. esphome/components/at581x/at581x.cpp +1 -1
  71. esphome/components/atm90e26/atm90e26.cpp +0 -1
  72. esphome/components/atm90e32/atm90e32.cpp +488 -118
  73. esphome/components/atm90e32/atm90e32.h +44 -5
  74. esphome/components/audio/audio.h +2 -2
  75. esphome/components/axs15231/touchscreen/axs15231_touchscreen.cpp +0 -2
  76. esphome/components/beken_spi_led_strip/led_strip.cpp +0 -2
  77. esphome/components/bh1750/bh1750.cpp +0 -1
  78. esphome/components/binary_sensor/__init__.py +14 -12
  79. esphome/components/ble_client/__init__.py +4 -7
  80. esphome/components/bluetooth_proxy/__init__.py +40 -3
  81. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +387 -82
  82. esphome/components/bluetooth_proxy/bluetooth_connection.h +16 -5
  83. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +102 -311
  84. esphome/components/bluetooth_proxy/bluetooth_proxy.h +30 -14
  85. esphome/components/bme280_base/bme280_base.cpp +15 -16
  86. esphome/components/bme680/bme680.cpp +2 -3
  87. esphome/components/bme680_bsec/bme680_bsec.cpp +0 -2
  88. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +0 -2
  89. esphome/components/bmi160/bmi160.cpp +0 -1
  90. esphome/components/bmp085/bmp085.cpp +0 -1
  91. esphome/components/bmp280_base/bmp280_base.cpp +13 -14
  92. esphome/components/bmp3xx_base/bmp3xx_base.cpp +0 -1
  93. esphome/components/bmp581/bmp581.cpp +0 -2
  94. esphome/components/bp1658cj/bp1658cj.cpp +0 -1
  95. esphome/components/bp5758d/bp5758d.cpp +0 -1
  96. esphome/components/button/__init__.py +0 -1
  97. esphome/components/canbus/__init__.py +2 -3
  98. esphome/components/canbus/canbus.cpp +0 -1
  99. esphome/components/cap1188/cap1188.cpp +0 -2
  100. esphome/components/captive_portal/__init__.py +1 -1
  101. esphome/components/cd74hc4067/cd74hc4067.cpp +0 -2
  102. esphome/components/ch422g/ch422g.cpp +0 -1
  103. esphome/components/chsc6x/chsc6x_touchscreen.cpp +0 -3
  104. esphome/components/climate/__init__.py +0 -1
  105. esphome/components/climate/climate_traits.h +24 -0
  106. esphome/components/cm1106/cm1106.cpp +0 -1
  107. esphome/components/const/__init__.py +6 -0
  108. esphome/components/cover/__init__.py +0 -1
  109. esphome/components/cover/cover.cpp +9 -13
  110. esphome/components/cs5460a/cs5460a.cpp +0 -2
  111. esphome/components/cse7761/cse7761.cpp +0 -1
  112. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +0 -2
  113. esphome/components/cst816/touchscreen/cst816_touchscreen.cpp +0 -2
  114. esphome/components/dac7678/dac7678_output.cpp +0 -2
  115. esphome/components/dallas_temp/dallas_temp.cpp +0 -1
  116. esphome/components/datetime/__init__.py +0 -2
  117. esphome/components/debug/__init__.py +15 -1
  118. esphome/components/debug/debug_zephyr.cpp +281 -0
  119. esphome/components/debug/sensor.py +2 -1
  120. esphome/components/deep_sleep/deep_sleep_component.cpp +0 -1
  121. esphome/components/deep_sleep/deep_sleep_esp32.cpp +20 -1
  122. esphome/components/dfrobot_sen0395/__init__.py +1 -2
  123. esphome/components/dht/dht.cpp +0 -1
  124. esphome/components/dht12/dht12.cpp +0 -1
  125. esphome/components/display/__init__.py +16 -3
  126. esphome/components/display_menu_base/__init__.py +1 -1
  127. esphome/components/dps310/dps310.cpp +0 -2
  128. esphome/components/ds1307/ds1307.cpp +0 -1
  129. esphome/components/ds2484/ds2484.cpp +0 -1
  130. esphome/components/duty_cycle/duty_cycle_sensor.cpp +0 -1
  131. esphome/components/ee895/ee895.cpp +0 -1
  132. esphome/components/ektf2232/touchscreen/ektf2232.cpp +0 -1
  133. esphome/components/emc2101/emc2101.cpp +0 -2
  134. esphome/components/ens160_base/ens160_base.cpp +0 -2
  135. esphome/components/ens210/ens210.cpp +0 -1
  136. esphome/components/es7210/es7210.cpp +0 -2
  137. esphome/components/es7243e/es7243e.cpp +0 -2
  138. esphome/components/es8156/es8156.cpp +0 -2
  139. esphome/components/es8311/es8311.cpp +0 -2
  140. esphome/components/es8388/es8388.cpp +0 -2
  141. esphome/components/esp32/__init__.py +199 -58
  142. esphome/components/esp32/boards.py +17 -0
  143. esphome/components/esp32/gpio.cpp +0 -1
  144. esphome/components/esp32/gpio.py +1 -2
  145. esphome/components/esp32/gpio_esp32_h2.py +2 -7
  146. esphome/components/esp32/gpio_esp32_p4.py +2 -7
  147. esphome/components/esp32/post_build.py.script +112 -61
  148. esphome/components/esp32_ble/__init__.py +40 -2
  149. esphome/components/esp32_ble/ble.cpp +12 -8
  150. esphome/components/esp32_ble/ble.h +18 -18
  151. esphome/components/esp32_ble/ble_advertising.cpp +5 -5
  152. esphome/components/esp32_ble/ble_advertising.h +7 -5
  153. esphome/components/esp32_ble/ble_event.h +2 -4
  154. esphome/components/esp32_ble/ble_scan_result.h +2 -4
  155. esphome/components/esp32_ble/ble_uuid.cpp +5 -5
  156. esphome/components/esp32_ble/ble_uuid.h +6 -5
  157. esphome/components/esp32_ble_beacon/__init__.py +4 -0
  158. esphome/components/esp32_ble_client/__init__.py +1 -1
  159. esphome/components/esp32_ble_client/ble_characteristic.cpp +4 -4
  160. esphome/components/esp32_ble_client/ble_characteristic.h +6 -4
  161. esphome/components/esp32_ble_client/ble_client_base.cpp +155 -104
  162. esphome/components/esp32_ble_client/ble_client_base.h +17 -6
  163. esphome/components/esp32_ble_client/ble_descriptor.h +6 -4
  164. esphome/components/esp32_ble_client/ble_service.cpp +4 -4
  165. esphome/components/esp32_ble_client/ble_service.h +6 -4
  166. esphome/components/esp32_ble_server/__init__.py +15 -12
  167. esphome/components/esp32_ble_tracker/__init__.py +79 -11
  168. esphome/components/esp32_ble_tracker/automation.h +4 -4
  169. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +264 -261
  170. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +103 -37
  171. esphome/components/esp32_camera/__init__.py +13 -1
  172. esphome/components/esp32_camera/esp32_camera.cpp +7 -2
  173. esphome/components/esp32_camera/esp32_camera.h +1 -0
  174. esphome/components/esp32_dac/esp32_dac.cpp +3 -19
  175. esphome/components/esp32_dac/esp32_dac.h +4 -8
  176. esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -6
  177. esphome/components/esp32_rmt_led_strip/light.py +1 -1
  178. esphome/components/esp32_touch/__init__.py +2 -3
  179. esphome/components/esp32_touch/esp32_touch.h +9 -6
  180. esphome/components/esp32_touch/esp32_touch_common.cpp +2 -0
  181. esphome/components/esp32_touch/esp32_touch_v1.cpp +7 -9
  182. esphome/components/esp32_touch/esp32_touch_v2.cpp +10 -6
  183. esphome/components/esp8266/__init__.py +3 -1
  184. esphome/components/esp8266_pwm/esp8266_pwm.cpp +0 -1
  185. esphome/components/esphome/ota/__init__.py +1 -2
  186. esphome/components/esphome/ota/ota_esphome.cpp +150 -77
  187. esphome/components/esphome/ota/ota_esphome.h +8 -1
  188. esphome/components/espnow/__init__.py +309 -0
  189. esphome/components/espnow/automation.h +175 -0
  190. esphome/components/espnow/espnow_component.cpp +468 -0
  191. esphome/components/espnow/espnow_component.h +183 -0
  192. esphome/components/espnow/espnow_err.h +19 -0
  193. esphome/components/espnow/espnow_packet.h +166 -0
  194. esphome/components/ethernet/__init__.py +7 -1
  195. esphome/components/ethernet/esp_eth_phy_jl1101.c +5 -0
  196. esphome/components/ethernet/ethernet_component.cpp +0 -1
  197. esphome/components/ethernet/ethernet_component.h +4 -0
  198. esphome/components/ethernet_info/ethernet_info_text_sensor.h +0 -3
  199. esphome/components/event/__init__.py +0 -1
  200. esphome/components/factory_reset/__init__.py +92 -0
  201. esphome/components/factory_reset/factory_reset.cpp +76 -0
  202. esphome/components/factory_reset/factory_reset.h +43 -0
  203. esphome/components/fan/__init__.py +0 -1
  204. esphome/components/fan/fan_traits.h +16 -0
  205. esphome/components/fastled_base/fastled_light.cpp +0 -1
  206. esphome/components/fastled_spi/light.py +1 -3
  207. esphome/components/fingerprint_grow/fingerprint_grow.cpp +0 -2
  208. esphome/components/font/__init__.py +9 -1
  209. esphome/components/fs3000/fs3000.cpp +0 -2
  210. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
  211. esphome/components/ft63x6/ft63x6.cpp +0 -1
  212. esphome/components/gdk101/gdk101.cpp +0 -1
  213. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
  214. esphome/components/gl_r01_i2c/sensor.py +1 -1
  215. esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
  216. esphome/components/gpio/switch/gpio_switch.cpp +0 -2
  217. esphome/components/gpio_expander/cached_gpio.h +24 -15
  218. esphome/components/gps/__init__.py +6 -2
  219. esphome/components/gps/gps.cpp +50 -49
  220. esphome/components/gps/gps.h +4 -8
  221. esphome/components/gps/time/gps_time.cpp +3 -9
  222. esphome/components/gps/time/gps_time.h +4 -7
  223. esphome/components/graph/__init__.py +1 -1
  224. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
  225. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
  226. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
  227. esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
  228. esphome/components/haier/climate.py +5 -10
  229. esphome/components/haier/haier_base.cpp +0 -1
  230. esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
  231. esphome/components/hdc1080/hdc1080.cpp +0 -2
  232. esphome/components/heatpumpir/climate.py +2 -2
  233. esphome/components/hlw8012/hlw8012.cpp +0 -1
  234. esphome/components/hm3301/hm3301.cpp +0 -1
  235. esphome/components/hmc5883l/hmc5883l.cpp +0 -1
  236. esphome/components/homeassistant/__init__.py +1 -0
  237. esphome/components/homeassistant/number/__init__.py +1 -0
  238. esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
  239. esphome/components/homeassistant/switch/__init__.py +1 -0
  240. esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
  241. esphome/components/honeywellabp/honeywellabp.cpp +1 -4
  242. esphome/components/host/__init__.py +2 -0
  243. esphome/components/hte501/hte501.cpp +0 -1
  244. esphome/components/http_request/__init__.py +2 -3
  245. esphome/components/http_request/http_request_idf.cpp +2 -2
  246. esphome/components/htu21d/htu21d.cpp +0 -2
  247. esphome/components/htu31d/htu31d.cpp +0 -2
  248. esphome/components/hx711/hx711.cpp +0 -1
  249. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
  250. esphome/components/hydreon_rgxx/sensor.py +4 -5
  251. esphome/components/i2c/i2c_bus.h +1 -1
  252. esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
  253. esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
  254. esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
  255. esphome/components/i2s_audio/__init__.py +6 -5
  256. esphome/components/i2s_audio/i2s_audio.cpp +0 -2
  257. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
  258. esphome/components/i2s_audio/microphone/__init__.py +4 -6
  259. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +46 -19
  260. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +4 -3
  261. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
  262. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
  263. esphome/components/ili9xxx/display.py +4 -3
  264. esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
  265. esphome/components/image/__init__.py +123 -92
  266. esphome/components/improv_serial/__init__.py +7 -8
  267. esphome/components/ina219/ina219.cpp +0 -1
  268. esphome/components/ina226/ina226.cpp +0 -2
  269. esphome/components/ina260/ina260.cpp +0 -2
  270. esphome/components/ina2xx_base/__init__.py +2 -5
  271. esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
  272. esphome/components/ina3221/ina3221.cpp +0 -1
  273. esphome/components/internal_temperature/internal_temperature.cpp +0 -2
  274. esphome/components/interval/interval.h +5 -9
  275. esphome/components/json/__init__.py +1 -1
  276. esphome/components/kmeteriso/kmeteriso.cpp +0 -2
  277. esphome/components/lc709203f/lc709203f.cpp +0 -2
  278. esphome/components/lcd_gpio/display.py +1 -3
  279. esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
  280. esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
  281. esphome/components/ld2410/__init__.py +4 -6
  282. esphome/components/ld2410/binary_sensor.py +4 -0
  283. esphome/components/ld2410/ld2410.cpp +56 -100
  284. esphome/components/ld2410/ld2410.h +17 -15
  285. esphome/components/ld2410/sensor.py +24 -10
  286. esphome/components/ld2412/__init__.py +46 -0
  287. esphome/components/ld2412/binary_sensor.py +70 -0
  288. esphome/components/ld2412/button/__init__.py +74 -0
  289. esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
  290. esphome/components/ld2412/button/factory_reset_button.h +18 -0
  291. esphome/components/ld2412/button/query_button.cpp +9 -0
  292. esphome/components/ld2412/button/query_button.h +18 -0
  293. esphome/components/ld2412/button/restart_button.cpp +9 -0
  294. esphome/components/ld2412/button/restart_button.h +18 -0
  295. esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
  296. esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
  297. esphome/components/ld2412/ld2412.cpp +861 -0
  298. esphome/components/ld2412/ld2412.h +141 -0
  299. esphome/components/ld2412/number/__init__.py +126 -0
  300. esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
  301. esphome/components/ld2412/number/gate_threshold_number.h +19 -0
  302. esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
  303. esphome/components/ld2412/number/light_threshold_number.h +18 -0
  304. esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
  305. esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
  306. esphome/components/ld2412/select/__init__.py +82 -0
  307. esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
  308. esphome/components/ld2412/select/baud_rate_select.h +18 -0
  309. esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
  310. esphome/components/ld2412/select/distance_resolution_select.h +18 -0
  311. esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
  312. esphome/components/ld2412/select/light_out_control_select.h +18 -0
  313. esphome/components/ld2412/sensor.py +124 -0
  314. esphome/components/ld2412/switch/__init__.py +45 -0
  315. esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
  316. esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
  317. esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
  318. esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
  319. esphome/components/ld2412/text_sensor.py +34 -0
  320. esphome/components/ld2420/ld2420.cpp +0 -1
  321. esphome/components/ld2450/__init__.py +3 -4
  322. esphome/components/ld2450/binary_sensor.py +3 -0
  323. esphome/components/ld2450/ld2450.cpp +77 -165
  324. esphome/components/ld2450/ld2450.h +26 -54
  325. esphome/components/ld2450/sensor.py +120 -6
  326. esphome/components/ld2450/text_sensor.py +5 -4
  327. esphome/components/ld24xx/__init__.py +1 -0
  328. esphome/components/ld24xx/ld24xx.h +65 -0
  329. esphome/components/ledc/ledc_output.cpp +0 -1
  330. esphome/components/libretiny/__init__.py +2 -0
  331. esphome/components/light/__init__.py +0 -1
  332. esphome/components/light/effects.py +70 -45
  333. esphome/components/light/light_call.cpp +101 -66
  334. esphome/components/light/light_color_values.h +16 -11
  335. esphome/components/light/light_json_schema.cpp +46 -44
  336. esphome/components/light/light_state.cpp +8 -11
  337. esphome/components/light/light_traits.h +17 -0
  338. esphome/components/lightwaverf/lightwaverf.cpp +0 -2
  339. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
  340. esphome/components/lock/__init__.py +0 -1
  341. esphome/components/logger/__init__.py +31 -9
  342. esphome/components/logger/logger.cpp +12 -7
  343. esphome/components/logger/logger.h +25 -14
  344. esphome/components/logger/logger_esp32.cpp +2 -7
  345. esphome/components/logger/logger_esp8266.cpp +2 -4
  346. esphome/components/logger/logger_host.cpp +2 -4
  347. esphome/components/logger/logger_libretiny.cpp +2 -4
  348. esphome/components/logger/logger_rp2040.cpp +2 -4
  349. esphome/components/logger/logger_zephyr.cpp +86 -0
  350. esphome/components/logger/select/logger_level_select.cpp +2 -4
  351. esphome/components/logger/select/logger_level_select.h +2 -4
  352. esphome/components/logger/task_log_buffer.cpp +2 -4
  353. esphome/components/logger/task_log_buffer.h +2 -4
  354. esphome/components/lps22/sensor.py +5 -5
  355. esphome/components/ltr390/ltr390.cpp +0 -2
  356. esphome/components/ltr501/ltr501.cpp +0 -1
  357. esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
  358. esphome/components/lvgl/__init__.py +14 -13
  359. esphome/components/lvgl/automation.py +2 -4
  360. esphome/components/lvgl/defines.py +0 -2
  361. esphome/components/lvgl/helpers.py +1 -1
  362. esphome/components/lvgl/lv_validation.py +7 -4
  363. esphome/components/lvgl/lvgl_esphome.cpp +2 -3
  364. esphome/components/lvgl/styles.py +2 -2
  365. esphome/components/lvgl/types.py +1 -1
  366. esphome/components/lvgl/widgets/__init__.py +2 -2
  367. esphome/components/lvgl/widgets/arc.py +14 -11
  368. esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
  369. esphome/components/lvgl/widgets/qrcode.py +7 -7
  370. esphome/components/lvgl/widgets/spinner.py +6 -6
  371. esphome/components/lvgl/widgets/switch.py +2 -2
  372. esphome/components/lvgl/widgets/tabview.py +3 -3
  373. esphome/components/lvgl/widgets/tileview.py +15 -7
  374. esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
  375. esphome/components/matrix_keypad/__init__.py +4 -3
  376. esphome/components/max17043/max17043.cpp +0 -2
  377. esphome/components/max31855/max31855.cpp +1 -4
  378. esphome/components/max31856/max31856.cpp +0 -4
  379. esphome/components/max31865/max31865.cpp +0 -1
  380. esphome/components/max44009/max44009.cpp +0 -1
  381. esphome/components/max6675/max6675.cpp +1 -4
  382. esphome/components/max6956/max6956.cpp +0 -1
  383. esphome/components/max7219/max7219.cpp +0 -1
  384. esphome/components/max7219digit/display.py +1 -1
  385. esphome/components/max7219digit/max7219digit.cpp +0 -1
  386. esphome/components/max9611/max9611.cpp +0 -1
  387. esphome/components/mcp23008/__init__.py +1 -1
  388. esphome/components/mcp23008/mcp23008.cpp +0 -1
  389. esphome/components/mcp23016/mcp23016.cpp +0 -1
  390. esphome/components/mcp23017/__init__.py +1 -1
  391. esphome/components/mcp23017/mcp23017.cpp +0 -1
  392. esphome/components/mcp23s08/__init__.py +1 -1
  393. esphome/components/mcp23s08/mcp23s08.cpp +0 -1
  394. esphome/components/mcp23s17/__init__.py +1 -1
  395. esphome/components/mcp23s17/mcp23s17.cpp +0 -1
  396. esphome/components/mcp23x08_base/__init__.py +2 -0
  397. esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
  398. esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
  399. esphome/components/mcp23x17_base/__init__.py +2 -0
  400. esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
  401. esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
  402. esphome/components/mcp23xxx_base/__init__.py +11 -5
  403. esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
  404. esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
  405. esphome/components/mcp3008/mcp3008.cpp +1 -4
  406. esphome/components/mcp3204/mcp3204.cpp +1 -4
  407. esphome/components/mcp4461/mcp4461.cpp +0 -1
  408. esphome/components/mcp4725/mcp4725.cpp +0 -1
  409. esphome/components/mcp4728/mcp4728.cpp +0 -1
  410. esphome/components/mcp9600/mcp9600.cpp +0 -2
  411. esphome/components/mcp9808/mcp9808.cpp +0 -2
  412. esphome/components/mdns/__init__.py +3 -0
  413. esphome/components/mdns/mdns_component.cpp +2 -0
  414. esphome/components/mdns/mdns_component.h +4 -0
  415. esphome/components/media_player/__init__.py +40 -0
  416. esphome/components/media_player/automation.h +16 -0
  417. esphome/components/media_player/media_player.cpp +13 -0
  418. esphome/components/media_player/media_player.h +50 -3
  419. esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
  420. esphome/components/mics_4514/mics_4514.cpp +1 -6
  421. esphome/components/midea/ir_transmitter.h +4 -4
  422. esphome/components/mipi/__init__.py +416 -0
  423. esphome/components/mipi_dsi/__init__.py +5 -0
  424. esphome/components/mipi_dsi/display.py +233 -0
  425. esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
  426. esphome/components/mipi_dsi/mipi_dsi.h +123 -0
  427. esphome/components/mipi_dsi/models/__init__.py +0 -0
  428. esphome/components/mipi_dsi/models/guition.py +38 -0
  429. esphome/components/mipi_dsi/models/m5stack.py +57 -0
  430. esphome/components/mipi_dsi/models/waveshare.py +105 -0
  431. esphome/components/mipi_rgb/models/lilygo.py +0 -0
  432. esphome/components/mipi_spi/__init__.py +0 -9
  433. esphome/components/mipi_spi/display.py +220 -256
  434. esphome/components/mipi_spi/mipi_spi.cpp +1 -485
  435. esphome/components/mipi_spi/mipi_spi.h +556 -108
  436. esphome/components/mipi_spi/models/__init__.py +0 -65
  437. esphome/components/mipi_spi/models/adafruit.py +30 -0
  438. esphome/components/mipi_spi/models/amoled.py +41 -5
  439. esphome/components/mipi_spi/models/ili.py +5 -5
  440. esphome/components/mipi_spi/models/jc.py +1 -3
  441. esphome/components/mipi_spi/models/lilygo.py +1 -1
  442. esphome/components/mipi_spi/models/waveshare.py +16 -1
  443. esphome/components/mixer/speaker/__init__.py +4 -5
  444. esphome/components/mlx90393/sensor.py +7 -5
  445. esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
  446. esphome/components/mlx90614/mlx90614.cpp +0 -1
  447. esphome/components/mmc5603/mmc5603.cpp +0 -1
  448. esphome/components/mmc5983/mmc5983.cpp +0 -2
  449. esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
  450. esphome/components/mpr121/__init__.py +7 -6
  451. esphome/components/mpr121/mpr121.cpp +0 -1
  452. esphome/components/mpu6050/mpu6050.cpp +0 -1
  453. esphome/components/mpu6886/mpu6886.cpp +0 -1
  454. esphome/components/mqtt/__init__.py +1 -2
  455. esphome/components/mqtt/mqtt_button.cpp +1 -1
  456. esphome/components/mqtt/mqtt_client.cpp +0 -1
  457. esphome/components/mqtt/mqtt_component.cpp +8 -14
  458. esphome/components/mqtt/mqtt_component.h +0 -7
  459. esphome/components/mqtt/mqtt_sensor.cpp +0 -1
  460. esphome/components/mqtt/mqtt_sensor.h +0 -1
  461. esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
  462. esphome/components/mqtt/mqtt_text_sensor.h +0 -1
  463. esphome/components/ms5611/ms5611.cpp +0 -1
  464. esphome/components/ms8607/ms8607.cpp +0 -1
  465. esphome/components/msa3xx/msa3xx.cpp +0 -2
  466. esphome/components/my9231/my9231.cpp +0 -2
  467. esphome/components/nau7802/nau7802.cpp +0 -1
  468. esphome/components/neopixelbus/light.py +3 -0
  469. esphome/components/network/util.cpp +29 -0
  470. esphome/components/nextion/nextion.cpp +0 -1
  471. esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
  472. esphome/components/npi19/npi19.cpp +0 -2
  473. esphome/components/nrf52/__init__.py +223 -0
  474. esphome/components/nrf52/boards.py +34 -0
  475. esphome/components/nrf52/const.py +18 -0
  476. esphome/components/nrf52/gpio.py +79 -0
  477. esphome/components/number/__init__.py +2 -1
  478. esphome/components/one_wire/__init__.py +1 -2
  479. esphome/components/one_wire/one_wire.cpp +0 -2
  480. esphome/components/one_wire/one_wire.h +0 -2
  481. esphome/components/opentherm/hub.cpp +0 -1
  482. esphome/components/opentherm/number/__init__.py +2 -2
  483. esphome/components/openthread/__init__.py +2 -3
  484. esphome/components/openthread/openthread.cpp +30 -13
  485. esphome/components/openthread/openthread.h +3 -0
  486. esphome/components/openthread/openthread_esp.cpp +3 -1
  487. esphome/components/opt3001/sensor.py +2 -6
  488. esphome/components/output/__init__.py +38 -0
  489. esphome/components/output/automation.h +24 -0
  490. esphome/components/output/switch/output_switch.cpp +0 -2
  491. esphome/components/packages/__init__.py +1 -2
  492. esphome/components/packet_transport/__init__.py +4 -3
  493. esphome/components/pca6416a/pca6416a.cpp +0 -1
  494. esphome/components/pca9554/pca9554.cpp +0 -1
  495. esphome/components/pca9685/pca9685_output.cpp +0 -2
  496. esphome/components/pcf85063/pcf85063.cpp +0 -1
  497. esphome/components/pcf8563/pcf8563.cpp +0 -1
  498. esphome/components/pcf8574/pcf8574.cpp +0 -1
  499. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
  500. esphome/components/pipsolar/sensor/__init__.py +1 -1
  501. esphome/components/pm2005/pm2005.cpp +0 -1
  502. esphome/components/pmsa003i/pmsa003i.cpp +0 -2
  503. esphome/components/pmwcs3/sensor.py +1 -2
  504. esphome/components/pn532/pn532.cpp +0 -2
  505. esphome/components/pn532_spi/pn532_spi.cpp +0 -2
  506. esphome/components/power_supply/power_supply.cpp +7 -10
  507. esphome/components/power_supply/power_supply.h +1 -1
  508. esphome/components/psram/__init__.py +2 -1
  509. esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
  510. esphome/components/pulse_counter/sensor.py +9 -6
  511. esphome/components/pylontech/pylontech.cpp +0 -1
  512. esphome/components/qmc5883l/qmc5883l.cpp +0 -1
  513. esphome/components/qmp6988/qmp6988.cpp +0 -2
  514. esphome/components/qspi_dbi/display.py +2 -3
  515. esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
  516. esphome/components/qwiic_pir/binary_sensor.py +2 -3
  517. esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
  518. esphome/components/rc522/rc522.cpp +9 -31
  519. esphome/components/rc522_spi/rc522_spi.cpp +0 -1
  520. esphome/components/remote_base/__init__.py +5 -6
  521. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
  522. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
  523. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
  524. esphome/components/remote_transmitter/__init__.py +26 -0
  525. esphome/components/remote_transmitter/automation.h +18 -0
  526. esphome/components/remote_transmitter/remote_transmitter.h +2 -1
  527. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
  528. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
  529. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
  530. esphome/components/resampler/speaker/__init__.py +4 -5
  531. esphome/components/rf_bridge/__init__.py +4 -8
  532. esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
  533. esphome/components/rp2040/__init__.py +3 -1
  534. esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
  535. esphome/components/rp2040_pio_led_strip/light.py +1 -2
  536. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
  537. esphome/components/rpi_dpi_rgb/display.py +13 -15
  538. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
  539. esphome/components/runtime_stats/__init__.py +34 -0
  540. esphome/components/runtime_stats/runtime_stats.cpp +102 -0
  541. esphome/components/runtime_stats/runtime_stats.h +132 -0
  542. esphome/components/scd30/scd30.cpp +0 -2
  543. esphome/components/scd30/sensor.py +1 -2
  544. esphome/components/scd4x/scd4x.cpp +0 -1
  545. esphome/components/scd4x/sensor.py +1 -3
  546. esphome/components/sdl/display.py +3 -1
  547. esphome/components/sdl/sdl_esphome.cpp +0 -2
  548. esphome/components/sdp3x/sdp3x.cpp +0 -2
  549. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
  550. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
  551. esphome/components/select/__init__.py +2 -3
  552. esphome/components/select/select_traits.cpp +1 -1
  553. esphome/components/select/select_traits.h +1 -1
  554. esphome/components/sen0321/sen0321.cpp +0 -1
  555. esphome/components/sen5x/sen5x.cpp +0 -2
  556. esphome/components/sensor/__init__.py +36 -4
  557. esphome/components/sensor/filter.cpp +49 -10
  558. esphome/components/sensor/filter.h +22 -7
  559. esphome/components/sensor/sensor.cpp +0 -1
  560. esphome/components/sensor/sensor.h +0 -9
  561. esphome/components/sfa30/sfa30.cpp +0 -4
  562. esphome/components/sgp30/sgp30.cpp +0 -2
  563. esphome/components/sgp4x/sensor.py +1 -1
  564. esphome/components/sgp4x/sgp4x.cpp +0 -2
  565. esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
  566. esphome/components/sht3xd/sht3xd.cpp +0 -2
  567. esphome/components/sht4x/sht4x.cpp +0 -2
  568. esphome/components/shtcx/shtcx.cpp +0 -1
  569. esphome/components/sim800l/__init__.py +2 -4
  570. esphome/components/sm16716/sm16716.cpp +0 -1
  571. esphome/components/sm2135/sm2135.cpp +0 -1
  572. esphome/components/sm2235/sm2235.cpp +0 -1
  573. esphome/components/sm2335/sm2335.cpp +0 -1
  574. esphome/components/sn74hc165/sn74hc165.cpp +0 -1
  575. esphome/components/sn74hc595/sn74hc595.cpp +0 -1
  576. esphome/components/sntp/sntp_component.cpp +0 -1
  577. esphome/components/sound_level/sensor.py +1 -1
  578. esphome/components/speaker/media_player/__init__.py +21 -33
  579. esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
  580. esphome/components/spi/__init__.py +29 -13
  581. esphome/components/spi/spi.cpp +0 -2
  582. esphome/components/spi_device/spi_device.cpp +1 -4
  583. esphome/components/sprinkler/__init__.py +4 -4
  584. esphome/components/sps30/sps30.cpp +0 -1
  585. esphome/components/ssd1306_base/__init__.py +11 -11
  586. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  587. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
  588. esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
  589. esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
  590. esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
  591. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
  592. esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
  593. esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
  594. esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
  595. esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
  596. esphome/components/st7567_spi/st7567_spi.cpp +0 -1
  597. esphome/components/st7701s/display.py +10 -14
  598. esphome/components/st7701s/st7701s.cpp +0 -3
  599. esphome/components/st7735/st7735.cpp +0 -1
  600. esphome/components/st7789v/st7789v.cpp +0 -1
  601. esphome/components/st7920/st7920.cpp +0 -1
  602. esphome/components/status_led/light/status_led_light.cpp +0 -2
  603. esphome/components/status_led/status_led.cpp +0 -1
  604. esphome/components/stepper/__init__.py +2 -4
  605. esphome/components/sts3x/sts3x.cpp +0 -1
  606. esphome/components/substitutions/__init__.py +10 -16
  607. esphome/components/substitutions/jinja.py +24 -1
  608. esphome/components/sun/__init__.py +2 -3
  609. esphome/components/switch/__init__.py +31 -1
  610. esphome/components/switch/automation.h +24 -0
  611. esphome/components/switch/switch.cpp +8 -0
  612. esphome/components/switch/switch.h +8 -0
  613. esphome/components/sx126x/sx126x.cpp +0 -2
  614. esphome/components/sx127x/sx127x.cpp +0 -2
  615. esphome/components/sx1509/__init__.py +7 -5
  616. esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
  617. esphome/components/sx1509/sx1509.cpp +0 -2
  618. esphome/components/syslog/esphome_syslog.cpp +1 -1
  619. esphome/components/tc74/tc74.cpp +0 -1
  620. esphome/components/tca9548a/tca9548a.cpp +0 -1
  621. esphome/components/tca9555/tca9555.cpp +0 -1
  622. esphome/components/tcs34725/tcs34725.cpp +0 -1
  623. esphome/components/tee501/tee501.cpp +0 -1
  624. esphome/components/tem3200/tem3200.cpp +0 -2
  625. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
  626. esphome/components/template/cover/template_cover.cpp +0 -1
  627. esphome/components/template/select/template_select.cpp +0 -1
  628. esphome/components/template/text/template_text.cpp +0 -2
  629. esphome/components/template/valve/template_valve.cpp +0 -1
  630. esphome/components/text/__init__.py +0 -1
  631. esphome/components/text/text_traits.h +2 -0
  632. esphome/components/text_sensor/__init__.py +2 -1
  633. esphome/components/text_sensor/text_sensor.cpp +0 -2
  634. esphome/components/text_sensor/text_sensor.h +0 -8
  635. esphome/components/thermostat/climate.py +4 -4
  636. esphome/components/time/__init__.py +7 -4
  637. esphome/components/time/real_time_clock.cpp +16 -3
  638. esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
  639. esphome/components/tlc5947/tlc5947.cpp +0 -2
  640. esphome/components/tlc5971/tlc5971.cpp +0 -2
  641. esphome/components/tm1621/tm1621.cpp +0 -2
  642. esphome/components/tm1637/tm1637.cpp +0 -2
  643. esphome/components/tm1638/tm1638.cpp +0 -2
  644. esphome/components/tm1651/__init__.py +45 -48
  645. esphome/components/tm1651/tm1651.cpp +213 -47
  646. esphome/components/tm1651/tm1651.h +37 -32
  647. esphome/components/tmp117/tmp117.cpp +0 -2
  648. esphome/components/tsl2561/tsl2561.cpp +0 -1
  649. esphome/components/tsl2591/tsl2591.cpp +0 -1
  650. esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
  651. esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
  652. esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
  653. esphome/components/tuya/climate/__init__.py +9 -10
  654. esphome/components/tuya/number/__init__.py +8 -6
  655. esphome/components/tx20/tx20.cpp +0 -1
  656. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
  657. esphome/components/uart/uart_component_esp8266.cpp +0 -1
  658. esphome/components/uart/uart_component_esp_idf.cpp +0 -2
  659. esphome/components/uart/uart_component_libretiny.cpp +0 -2
  660. esphome/components/uart/uart_component_rp2040.cpp +0 -2
  661. esphome/components/udp/__init__.py +1 -1
  662. esphome/components/ufire_ec/sensor.py +1 -2
  663. esphome/components/ufire_ec/ufire_ec.cpp +0 -2
  664. esphome/components/ufire_ise/sensor.py +1 -2
  665. esphome/components/ufire_ise/ufire_ise.cpp +0 -2
  666. esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
  667. esphome/components/update/__init__.py +0 -1
  668. esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
  669. esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
  670. esphome/components/usb_host/usb_host_client.cpp +0 -1
  671. esphome/components/usb_host/usb_host_component.cpp +0 -1
  672. esphome/components/valve/__init__.py +0 -1
  673. esphome/components/veml3235/veml3235.cpp +0 -3
  674. esphome/components/veml7700/veml7700.cpp +0 -2
  675. esphome/components/version/version_text_sensor.cpp +0 -1
  676. esphome/components/version/version_text_sensor.h +0 -1
  677. esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
  678. esphome/components/voice_assistant/voice_assistant.cpp +9 -8
  679. esphome/components/web_server/__init__.py +13 -0
  680. esphome/components/web_server/web_server.cpp +187 -352
  681. esphome/components/web_server/web_server.h +61 -1
  682. esphome/components/web_server_base/__init__.py +1 -1
  683. esphome/components/web_server_base/web_server_base.cpp +2 -0
  684. esphome/components/web_server_base/web_server_base.h +6 -0
  685. esphome/components/web_server_idf/web_server_idf.cpp +10 -8
  686. esphome/components/web_server_idf/web_server_idf.h +2 -0
  687. esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
  688. esphome/components/weikai_spi/weikai_spi.cpp +1 -1
  689. esphome/components/wifi/__init__.py +8 -43
  690. esphome/components/wifi/wifi_component.cpp +100 -36
  691. esphome/components/wifi/wifi_component.h +5 -1
  692. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
  693. esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
  694. esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
  695. esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
  696. esphome/components/wireguard/wireguard.cpp +0 -2
  697. esphome/components/x9c/x9c.cpp +0 -2
  698. esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
  699. esphome/components/xl9535/xl9535.cpp +0 -2
  700. esphome/components/zephyr/__init__.py +252 -0
  701. esphome/components/zephyr/const.py +16 -0
  702. esphome/components/zephyr/core.cpp +90 -0
  703. esphome/components/zephyr/gpio.cpp +120 -0
  704. esphome/components/zephyr/gpio.h +38 -0
  705. esphome/components/zephyr/pre_build.py.script +4 -0
  706. esphome/components/zephyr/preferences.cpp +156 -0
  707. esphome/components/zephyr/preferences.h +13 -0
  708. esphome/config.py +38 -16
  709. esphome/config_helpers.py +1 -2
  710. esphome/config_validation.py +8 -15
  711. esphome/const.py +26 -1
  712. esphome/core/__init__.py +88 -51
  713. esphome/core/application.cpp +75 -21
  714. esphome/core/application.h +106 -171
  715. esphome/core/color.h +10 -0
  716. esphome/core/component.cpp +41 -25
  717. esphome/core/component.h +9 -6
  718. esphome/core/component_iterator.cpp +61 -261
  719. esphome/core/component_iterator.h +15 -0
  720. esphome/core/config.py +26 -11
  721. esphome/core/defines.h +40 -2
  722. esphome/core/entity_base.h +18 -0
  723. esphome/core/entity_helpers.py +41 -6
  724. esphome/core/helpers.cpp +8 -15
  725. esphome/core/helpers.h +60 -6
  726. esphome/core/lock_free_queue.h +1 -1
  727. esphome/core/scheduler.cpp +277 -74
  728. esphome/core/scheduler.h +89 -27
  729. esphome/cpp_generator.py +2 -6
  730. esphome/cpp_helpers.py +1 -1
  731. esphome/dashboard/dashboard.py +2 -3
  732. esphome/dashboard/dns.py +2 -8
  733. esphome/dashboard/web_server.py +34 -19
  734. esphome/espota2.py +1 -4
  735. esphome/git.py +3 -1
  736. esphome/helpers.py +23 -4
  737. esphome/log.py +3 -1
  738. esphome/mqtt.py +3 -5
  739. esphome/platformio_api.py +7 -4
  740. esphome/types.py +12 -0
  741. esphome/util.py +20 -8
  742. esphome/voluptuous_schema.py +4 -3
  743. esphome/vscode.py +1 -2
  744. esphome/wizard.py +1 -4
  745. esphome/writer.py +5 -107
  746. esphome/yaml_util.py +7 -5
  747. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/METADATA +12 -13
  748. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/RECORD +753 -673
  749. esphome/components/mipi_spi/models/commands.py +0 -82
  750. /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
  751. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/WHEEL +0 -0
  752. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/entry_points.txt +0 -0
  753. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/licenses/LICENSE +0 -0
  754. {esphome-2025.7.4.dist-info → esphome-2025.8.0b1.dist-info}/top_level.txt +0 -0
@@ -4,40 +4,39 @@
4
4
 
5
5
  #include "esphome/components/spi/spi.h"
6
6
  #include "esphome/components/display/display.h"
7
- #include "esphome/components/display/display_buffer.h"
8
7
  #include "esphome/components/display/display_color_utils.h"
9
8
 
10
9
  namespace esphome {
11
10
  namespace mipi_spi {
12
11
 
13
12
  constexpr static const char *const TAG = "display.mipi_spi";
14
- static const uint8_t SW_RESET_CMD = 0x01;
15
- static const uint8_t SLEEP_OUT = 0x11;
16
- static const uint8_t NORON = 0x13;
17
- static const uint8_t INVERT_OFF = 0x20;
18
- static const uint8_t INVERT_ON = 0x21;
19
- static const uint8_t ALL_ON = 0x23;
20
- static const uint8_t WRAM = 0x24;
21
- static const uint8_t MIPI = 0x26;
22
- static const uint8_t DISPLAY_ON = 0x29;
23
- static const uint8_t RASET = 0x2B;
24
- static const uint8_t CASET = 0x2A;
25
- static const uint8_t WDATA = 0x2C;
26
- static const uint8_t TEON = 0x35;
27
- static const uint8_t MADCTL_CMD = 0x36;
28
- static const uint8_t PIXFMT = 0x3A;
29
- static const uint8_t BRIGHTNESS = 0x51;
30
- static const uint8_t SWIRE1 = 0x5A;
31
- static const uint8_t SWIRE2 = 0x5B;
32
- static const uint8_t PAGESEL = 0xFE;
33
-
34
- static const uint8_t MADCTL_MY = 0x80; // Bit 7 Bottom to top
35
- static const uint8_t MADCTL_MX = 0x40; // Bit 6 Right to left
36
- static const uint8_t MADCTL_MV = 0x20; // Bit 5 Swap axes
37
- static const uint8_t MADCTL_RGB = 0x00; // Bit 3 Red-Green-Blue pixel order
38
- static const uint8_t MADCTL_BGR = 0x08; // Bit 3 Blue-Green-Red pixel order
39
- static const uint8_t MADCTL_XFLIP = 0x02; // Mirror the display horizontally
40
- static const uint8_t MADCTL_YFLIP = 0x01; // Mirror the display vertically
13
+ static constexpr uint8_t SW_RESET_CMD = 0x01;
14
+ static constexpr uint8_t SLEEP_OUT = 0x11;
15
+ static constexpr uint8_t NORON = 0x13;
16
+ static constexpr uint8_t INVERT_OFF = 0x20;
17
+ static constexpr uint8_t INVERT_ON = 0x21;
18
+ static constexpr uint8_t ALL_ON = 0x23;
19
+ static constexpr uint8_t WRAM = 0x24;
20
+ static constexpr uint8_t MIPI = 0x26;
21
+ static constexpr uint8_t DISPLAY_ON = 0x29;
22
+ static constexpr uint8_t RASET = 0x2B;
23
+ static constexpr uint8_t CASET = 0x2A;
24
+ static constexpr uint8_t WDATA = 0x2C;
25
+ static constexpr uint8_t TEON = 0x35;
26
+ static constexpr uint8_t MADCTL_CMD = 0x36;
27
+ static constexpr uint8_t PIXFMT = 0x3A;
28
+ static constexpr uint8_t BRIGHTNESS = 0x51;
29
+ static constexpr uint8_t SWIRE1 = 0x5A;
30
+ static constexpr uint8_t SWIRE2 = 0x5B;
31
+ static constexpr uint8_t PAGESEL = 0xFE;
32
+
33
+ static constexpr uint8_t MADCTL_MY = 0x80; // Bit 7 Bottom to top
34
+ static constexpr uint8_t MADCTL_MX = 0x40; // Bit 6 Right to left
35
+ static constexpr uint8_t MADCTL_MV = 0x20; // Bit 5 Swap axes
36
+ static constexpr uint8_t MADCTL_RGB = 0x00; // Bit 3 Red-Green-Blue pixel order
37
+ static constexpr uint8_t MADCTL_BGR = 0x08; // Bit 3 Blue-Green-Red pixel order
38
+ static constexpr uint8_t MADCTL_XFLIP = 0x02; // Mirror the display horizontally
39
+ static constexpr uint8_t MADCTL_YFLIP = 0x01; // Mirror the display vertically
41
40
 
42
41
  static const uint8_t DELAY_FLAG = 0xFF;
43
42
  // store a 16 bit value in a buffer, big endian.
@@ -46,28 +45,44 @@ static inline void put16_be(uint8_t *buf, uint16_t value) {
46
45
  buf[1] = value;
47
46
  }
48
47
 
48
+ // Buffer mode, conveniently also the number of bytes in a pixel
49
49
  enum PixelMode {
50
- PIXEL_MODE_16,
51
- PIXEL_MODE_18,
50
+ PIXEL_MODE_8 = 1,
51
+ PIXEL_MODE_16 = 2,
52
+ PIXEL_MODE_18 = 3,
53
+ };
54
+
55
+ enum BusType {
56
+ BUS_TYPE_SINGLE = 1,
57
+ BUS_TYPE_QUAD = 4,
58
+ BUS_TYPE_OCTAL = 8,
59
+ BUS_TYPE_SINGLE_16 = 16, // Single bit bus, but 16 bits per transfer
52
60
  };
53
61
 
54
- class MipiSpi : public display::DisplayBuffer,
62
+ /**
63
+ * Base class for MIPI SPI displays.
64
+ * All the methods are defined here in the header file, as it is not possible to define templated methods in a cpp file.
65
+ *
66
+ * @tparam BUFFERTYPE The type of the buffer pixels, e.g. uint8_t or uint16_t
67
+ * @tparam BUFFERPIXEL Color depth of the buffer
68
+ * @tparam DISPLAYPIXEL Color depth of the display
69
+ * @tparam BUS_TYPE The type of the interface bus (single, quad, octal)
70
+ * @tparam WIDTH Width of the display in pixels
71
+ * @tparam HEIGHT Height of the display in pixels
72
+ * @tparam OFFSET_WIDTH The x-offset of the display in pixels
73
+ * @tparam OFFSET_HEIGHT The y-offset of the display in pixels
74
+ * buffer
75
+ */
76
+ template<typename BUFFERTYPE, PixelMode BUFFERPIXEL, bool IS_BIG_ENDIAN, PixelMode DISPLAYPIXEL, BusType BUS_TYPE,
77
+ int WIDTH, int HEIGHT, int OFFSET_WIDTH, int OFFSET_HEIGHT>
78
+ class MipiSpi : public display::Display,
55
79
  public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_LEADING,
56
80
  spi::DATA_RATE_1MHZ> {
57
81
  public:
58
- MipiSpi(size_t width, size_t height, int16_t offset_width, int16_t offset_height, display::ColorBitness color_depth)
59
- : width_(width),
60
- height_(height),
61
- offset_width_(offset_width),
62
- offset_height_(offset_height),
63
- color_depth_(color_depth) {}
82
+ MipiSpi() {}
83
+ void update() override { this->stop_poller(); }
84
+ void draw_pixel_at(int x, int y, Color color) override {}
64
85
  void set_model(const char *model) { this->model_ = model; }
65
- void update() override;
66
- void setup() override;
67
- display::ColorOrder get_color_mode() {
68
- return this->madctl_ & MADCTL_BGR ? display::COLOR_ORDER_BGR : display::COLOR_ORDER_RGB;
69
- }
70
-
71
86
  void set_reset_pin(GPIOPin *reset_pin) { this->reset_pin_ = reset_pin; }
72
87
  void set_enable_pins(std::vector<GPIOPin *> enable_pins) { this->enable_pins_ = std::move(enable_pins); }
73
88
  void set_dc_pin(GPIOPin *dc_pin) { this->dc_pin_ = dc_pin; }
@@ -79,93 +94,526 @@ class MipiSpi : public display::DisplayBuffer,
79
94
  this->brightness_ = brightness;
80
95
  this->reset_params_();
81
96
  }
82
-
83
- void set_draw_from_origin(bool draw_from_origin) { this->draw_from_origin_ = draw_from_origin; }
84
97
  display::DisplayType get_display_type() override { return display::DisplayType::DISPLAY_TYPE_COLOR; }
85
- void dump_config() override;
86
98
 
87
- int get_width_internal() override { return this->width_; }
88
- int get_height_internal() override { return this->height_; }
89
- bool can_proceed() override { return this->setup_complete_; }
99
+ int get_width_internal() override { return WIDTH; }
100
+ int get_height_internal() override { return HEIGHT; }
90
101
  void set_init_sequence(const std::vector<uint8_t> &sequence) { this->init_sequence_ = sequence; }
91
102
  void set_draw_rounding(unsigned rounding) { this->draw_rounding_ = rounding; }
92
- void set_spi_16(bool spi_16) { this->spi_16_ = spi_16; }
93
103
 
94
- protected:
95
- bool check_buffer_() {
96
- if (this->is_failed())
97
- return false;
98
- if (this->buffer_ != nullptr)
99
- return true;
100
- auto bytes_per_pixel = this->color_depth_ == display::COLOR_BITNESS_565 ? 2 : 1;
101
- this->init_internal_(this->width_ * this->height_ * bytes_per_pixel);
102
- if (this->buffer_ == nullptr) {
103
- this->mark_failed();
104
- return false;
104
+ // reset the display, and write the init sequence
105
+ void setup() override {
106
+ this->spi_setup();
107
+ if (this->dc_pin_ != nullptr) {
108
+ this->dc_pin_->setup();
109
+ this->dc_pin_->digital_write(false);
105
110
  }
106
- this->buffer_bytes_ = this->width_ * this->height_ * bytes_per_pixel;
107
- return true;
111
+ for (auto *pin : this->enable_pins_) {
112
+ pin->setup();
113
+ pin->digital_write(true);
114
+ }
115
+ if (this->reset_pin_ != nullptr) {
116
+ this->reset_pin_->setup();
117
+ this->reset_pin_->digital_write(true);
118
+ delay(5);
119
+ this->reset_pin_->digital_write(false);
120
+ delay(5);
121
+ this->reset_pin_->digital_write(true);
122
+ }
123
+
124
+ // need to know when the display is ready for SLPOUT command - will be 120ms after reset
125
+ auto when = millis() + 120;
126
+ delay(10);
127
+ size_t index = 0;
128
+ auto &vec = this->init_sequence_;
129
+ while (index != vec.size()) {
130
+ if (vec.size() - index < 2) {
131
+ esph_log_e(TAG, "Malformed init sequence");
132
+ this->mark_failed();
133
+ return;
134
+ }
135
+ uint8_t cmd = vec[index++];
136
+ uint8_t x = vec[index++];
137
+ if (x == DELAY_FLAG) {
138
+ esph_log_d(TAG, "Delay %dms", cmd);
139
+ delay(cmd);
140
+ } else {
141
+ uint8_t num_args = x & 0x7F;
142
+ if (vec.size() - index < num_args) {
143
+ esph_log_e(TAG, "Malformed init sequence");
144
+ this->mark_failed();
145
+ return;
146
+ }
147
+ auto arg_byte = vec[index];
148
+ switch (cmd) {
149
+ case SLEEP_OUT: {
150
+ // are we ready, boots?
151
+ int duration = when - millis();
152
+ if (duration > 0) {
153
+ esph_log_d(TAG, "Sleep %dms", duration);
154
+ delay(duration);
155
+ }
156
+ } break;
157
+
158
+ case INVERT_ON:
159
+ this->invert_colors_ = true;
160
+ break;
161
+ case MADCTL_CMD:
162
+ this->madctl_ = arg_byte;
163
+ break;
164
+ case BRIGHTNESS:
165
+ this->brightness_ = arg_byte;
166
+ break;
167
+
168
+ default:
169
+ break;
170
+ }
171
+ const auto *ptr = vec.data() + index;
172
+ esph_log_d(TAG, "Command %02X, length %d, byte %02X", cmd, num_args, arg_byte);
173
+ this->write_command_(cmd, ptr, num_args);
174
+ index += num_args;
175
+ if (cmd == SLEEP_OUT)
176
+ delay(10);
177
+ }
178
+ }
179
+ // init sequence no longer needed
180
+ this->init_sequence_.clear();
108
181
  }
109
- void fill(Color color) override;
110
- void draw_absolute_pixel_internal(int x, int y, Color color) override;
182
+
183
+ // Drawing operations
184
+
111
185
  void draw_pixels_at(int x_start, int y_start, int w, int h, const uint8_t *ptr, display::ColorOrder order,
112
- display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) override;
113
- void write_18_from_16_bit_(const uint16_t *ptr, size_t w, size_t h, size_t stride);
114
- void write_18_from_8_bit_(const uint8_t *ptr, size_t w, size_t h, size_t stride);
115
- void write_16_from_8_bit_(const uint8_t *ptr, size_t w, size_t h, size_t stride);
116
- void write_to_display_(int x_start, int y_start, int w, int h, const uint8_t *ptr, int x_offset, int y_offset,
117
- int x_pad);
186
+ display::ColorBitness bitness, bool big_endian, int x_offset, int y_offset, int x_pad) override {
187
+ if (this->is_failed())
188
+ return;
189
+ if (w <= 0 || h <= 0)
190
+ return;
191
+ if (get_pixel_mode(bitness) != BUFFERPIXEL || big_endian != IS_BIG_ENDIAN) {
192
+ // note that the usual logging macros are banned in header files, so use their replacement
193
+ esph_log_e(TAG, "Unsupported color depth or bit order");
194
+ return;
195
+ }
196
+ this->write_to_display_(x_start, y_start, w, h, reinterpret_cast<const BUFFERTYPE *>(ptr), x_offset, y_offset,
197
+ x_pad);
198
+ }
199
+
200
+ void dump_config() override {
201
+ esph_log_config(TAG,
202
+ "MIPI_SPI Display\n"
203
+ " Model: %s\n"
204
+ " Width: %u\n"
205
+ " Height: %u",
206
+ this->model_, WIDTH, HEIGHT);
207
+ if constexpr (OFFSET_WIDTH != 0)
208
+ esph_log_config(TAG, " Offset width: %u", OFFSET_WIDTH);
209
+ if constexpr (OFFSET_HEIGHT != 0)
210
+ esph_log_config(TAG, " Offset height: %u", OFFSET_HEIGHT);
211
+ esph_log_config(TAG,
212
+ " Swap X/Y: %s\n"
213
+ " Mirror X: %s\n"
214
+ " Mirror Y: %s\n"
215
+ " Invert colors: %s\n"
216
+ " Color order: %s\n"
217
+ " Display pixels: %d bits\n"
218
+ " Endianness: %s\n",
219
+ YESNO(this->madctl_ & MADCTL_MV), YESNO(this->madctl_ & (MADCTL_MX | MADCTL_XFLIP)),
220
+ YESNO(this->madctl_ & (MADCTL_MY | MADCTL_YFLIP)), YESNO(this->invert_colors_),
221
+ this->madctl_ & MADCTL_BGR ? "BGR" : "RGB", DISPLAYPIXEL * 8, IS_BIG_ENDIAN ? "Big" : "Little");
222
+ if (this->brightness_.has_value())
223
+ esph_log_config(TAG, " Brightness: %u", this->brightness_.value());
224
+ if (this->cs_ != nullptr)
225
+ esph_log_config(TAG, " CS Pin: %s", this->cs_->dump_summary().c_str());
226
+ if (this->reset_pin_ != nullptr)
227
+ esph_log_config(TAG, " Reset Pin: %s", this->reset_pin_->dump_summary().c_str());
228
+ if (this->dc_pin_ != nullptr)
229
+ esph_log_config(TAG, " DC Pin: %s", this->dc_pin_->dump_summary().c_str());
230
+ esph_log_config(TAG,
231
+ " SPI Mode: %d\n"
232
+ " SPI Data rate: %dMHz\n"
233
+ " SPI Bus width: %d",
234
+ this->mode_, static_cast<unsigned>(this->data_rate_ / 1000000), BUS_TYPE);
235
+ }
236
+
237
+ protected:
238
+ /* METHODS */
239
+ // convenience functions to write commands with or without data
240
+ void write_command_(uint8_t cmd, uint8_t data) { this->write_command_(cmd, &data, 1); }
241
+ void write_command_(uint8_t cmd) { this->write_command_(cmd, &cmd, 0); }
242
+
243
+ // Writes a command to the display, with the given bytes.
244
+ void write_command_(uint8_t cmd, const uint8_t *bytes, size_t len) {
245
+ esph_log_v(TAG, "Command %02X, length %d, bytes %s", cmd, len, format_hex_pretty(bytes, len).c_str());
246
+ if constexpr (BUS_TYPE == BUS_TYPE_QUAD) {
247
+ this->enable();
248
+ this->write_cmd_addr_data(8, 0x02, 24, cmd << 8, bytes, len);
249
+ this->disable();
250
+ } else if constexpr (BUS_TYPE == BUS_TYPE_OCTAL) {
251
+ this->dc_pin_->digital_write(false);
252
+ this->enable();
253
+ this->write_cmd_addr_data(0, 0, 0, 0, &cmd, 1, 8);
254
+ this->disable();
255
+ this->dc_pin_->digital_write(true);
256
+ if (len != 0) {
257
+ this->enable();
258
+ this->write_cmd_addr_data(0, 0, 0, 0, bytes, len, 8);
259
+ this->disable();
260
+ }
261
+ } else if constexpr (BUS_TYPE == BUS_TYPE_SINGLE) {
262
+ this->dc_pin_->digital_write(false);
263
+ this->enable();
264
+ this->write_byte(cmd);
265
+ this->disable();
266
+ this->dc_pin_->digital_write(true);
267
+ if (len != 0) {
268
+ this->enable();
269
+ this->write_array(bytes, len);
270
+ this->disable();
271
+ }
272
+ } else if constexpr (BUS_TYPE == BUS_TYPE_SINGLE_16) {
273
+ this->dc_pin_->digital_write(false);
274
+ this->enable();
275
+ this->write_byte(cmd);
276
+ this->disable();
277
+ this->dc_pin_->digital_write(true);
278
+ for (size_t i = 0; i != len; i++) {
279
+ this->enable();
280
+ this->write_byte(0);
281
+ this->write_byte(bytes[i]);
282
+ this->disable();
283
+ }
284
+ }
285
+ }
286
+
287
+ // write changed parameters to the display
288
+ void reset_params_() {
289
+ if (!this->is_ready())
290
+ return;
291
+ this->write_command_(this->invert_colors_ ? INVERT_ON : INVERT_OFF);
292
+ if (this->brightness_.has_value())
293
+ this->write_command_(BRIGHTNESS, this->brightness_.value());
294
+ }
295
+
296
+ // set the address window for the next data write
297
+ void set_addr_window_(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
298
+ esph_log_v(TAG, "Set addr %d/%d, %d/%d", x1, y1, x2, y2);
299
+ uint8_t buf[4];
300
+ x1 += OFFSET_WIDTH;
301
+ x2 += OFFSET_WIDTH;
302
+ y1 += OFFSET_HEIGHT;
303
+ y2 += OFFSET_HEIGHT;
304
+ put16_be(buf, y1);
305
+ put16_be(buf + 2, y2);
306
+ this->write_command_(RASET, buf, sizeof buf);
307
+ put16_be(buf, x1);
308
+ put16_be(buf + 2, x2);
309
+ this->write_command_(CASET, buf, sizeof buf);
310
+ if constexpr (BUS_TYPE != BUS_TYPE_QUAD) {
311
+ this->write_command_(WDATA);
312
+ }
313
+ }
314
+
315
+ // map the display color bitness to the pixel mode
316
+ static PixelMode get_pixel_mode(display::ColorBitness bitness) {
317
+ switch (bitness) {
318
+ case display::COLOR_BITNESS_888:
319
+ return PIXEL_MODE_18; // 18 bits per pixel
320
+ case display::COLOR_BITNESS_565:
321
+ return PIXEL_MODE_16; // 16 bits per pixel
322
+ default:
323
+ return PIXEL_MODE_8; // Default to 8 bits per pixel
324
+ }
325
+ }
326
+
118
327
  /**
119
- * the RM67162 in quad SPI mode seems to work like this (not in the datasheet, this is deduced from the
120
- * sample code.)
121
- *
122
- * Immediately after enabling /CS send 4 bytes in single-dataline SPI mode:
123
- * 0: either 0x2 or 0x32. The first indicates that any subsequent data bytes after the initial 4 will be
124
- * sent in 1-dataline SPI. The second indicates quad mode.
125
- * 1: 0x00
126
- * 2: The command (register address) byte.
127
- * 3: 0x00
128
- *
129
- * This is followed by zero or more data bytes in either 1-wire or 4-wire mode, depending on the first byte.
130
- * At the conclusion of the write, de-assert /CS.
328
+ * Writes a buffer to the display.
329
+ * @param w Width of each line in bytes
330
+ * @param h Height of the buffer in rows
331
+ * @param pad Padding in bytes after each line
332
+ */
333
+ void write_display_data_(const uint8_t *ptr, size_t w, size_t h, size_t pad) {
334
+ if (pad == 0) {
335
+ if constexpr (BUS_TYPE == BUS_TYPE_SINGLE || BUS_TYPE == BUS_TYPE_SINGLE_16) {
336
+ this->write_array(ptr, w * h);
337
+ } else if constexpr (BUS_TYPE == BUS_TYPE_QUAD) {
338
+ this->write_cmd_addr_data(8, 0x32, 24, WDATA << 8, ptr, w * h, 4);
339
+ } else if constexpr (BUS_TYPE == BUS_TYPE_OCTAL) {
340
+ this->write_cmd_addr_data(0, 0, 0, 0, ptr, w * h, 8);
341
+ }
342
+ } else {
343
+ for (size_t y = 0; y != h; y++) {
344
+ if constexpr (BUS_TYPE == BUS_TYPE_SINGLE || BUS_TYPE == BUS_TYPE_SINGLE_16) {
345
+ this->write_array(ptr, w);
346
+ } else if constexpr (BUS_TYPE == BUS_TYPE_QUAD) {
347
+ this->write_cmd_addr_data(8, 0x32, 24, WDATA << 8, ptr, w, 4);
348
+ } else if constexpr (BUS_TYPE == BUS_TYPE_OCTAL) {
349
+ this->write_cmd_addr_data(0, 0, 0, 0, ptr, w, 8);
350
+ }
351
+ ptr += w + pad;
352
+ }
353
+ }
354
+ }
355
+
356
+ /**
357
+ * Writes a buffer to the display.
131
358
  *
132
- * @param cmd
133
- * @param bytes
134
- * @param len
359
+ * The ptr is a pointer to the pixel data
360
+ * The other parameters are all in pixel units.
135
361
  */
136
- void write_command_(uint8_t cmd, const uint8_t *bytes, size_t len);
362
+ void write_to_display_(int x_start, int y_start, int w, int h, const BUFFERTYPE *ptr, int x_offset, int y_offset,
363
+ int x_pad) {
364
+ this->set_addr_window_(x_start, y_start, x_start + w - 1, y_start + h - 1);
365
+ this->enable();
366
+ ptr += y_offset * (x_offset + w + x_pad) + x_offset;
367
+ if constexpr (BUFFERPIXEL == DISPLAYPIXEL) {
368
+ this->write_display_data_(reinterpret_cast<const uint8_t *>(ptr), w * sizeof(BUFFERTYPE), h,
369
+ x_pad * sizeof(BUFFERTYPE));
370
+ } else {
371
+ // type conversion required, do it in chunks
372
+ uint8_t dbuffer[DISPLAYPIXEL * 48];
373
+ uint8_t *dptr = dbuffer;
374
+ auto stride = x_offset + w + x_pad; // stride in pixels
375
+ for (size_t y = 0; y != h; y++) {
376
+ for (size_t x = 0; x != w; x++) {
377
+ auto color_val = ptr[y * stride + x];
378
+ if constexpr (DISPLAYPIXEL == PIXEL_MODE_18 && BUFFERPIXEL == PIXEL_MODE_16) {
379
+ // 16 to 18 bit conversion
380
+ if constexpr (IS_BIG_ENDIAN) {
381
+ *dptr++ = color_val & 0xF8;
382
+ *dptr++ = ((color_val & 0x7) << 5) | (color_val & 0xE000) >> 11;
383
+ *dptr++ = (color_val >> 5) & 0xF8;
384
+ } else {
385
+ *dptr++ = (color_val >> 8) & 0xF8; // Blue
386
+ *dptr++ = (color_val & 0x7E0) >> 3;
387
+ *dptr++ = color_val << 3;
388
+ }
389
+ } else if constexpr (DISPLAYPIXEL == PIXEL_MODE_18 && BUFFERPIXEL == PIXEL_MODE_8) {
390
+ // 8 bit to 18 bit conversion
391
+ *dptr++ = color_val << 6; // Blue
392
+ *dptr++ = (color_val & 0x1C) << 3; // Green
393
+ *dptr++ = (color_val & 0xE0); // Red
394
+ } else if constexpr (DISPLAYPIXEL == PIXEL_MODE_16 && BUFFERPIXEL == PIXEL_MODE_8) {
395
+ if constexpr (IS_BIG_ENDIAN) {
396
+ *dptr++ = (color_val & 0xE0) | ((color_val & 0x1C) >> 2);
397
+ *dptr++ = (color_val & 3) << 3;
398
+ } else {
399
+ *dptr++ = (color_val & 3) << 3;
400
+ *dptr++ = (color_val & 0xE0) | ((color_val & 0x1C) >> 2);
401
+ }
402
+ }
403
+ // buffer full? Flush.
404
+ if (dptr == dbuffer + sizeof(dbuffer)) {
405
+ this->write_display_data_(dbuffer, sizeof(dbuffer), 1, 0);
406
+ dptr = dbuffer;
407
+ }
408
+ }
409
+ }
410
+ // flush any remaining data
411
+ if (dptr != dbuffer) {
412
+ this->write_display_data_(dbuffer, dptr - dbuffer, 1, 0);
413
+ }
414
+ }
415
+ this->disable();
416
+ }
137
417
 
138
- void write_command_(uint8_t cmd, uint8_t data) { this->write_command_(cmd, &data, 1); }
139
- void write_command_(uint8_t cmd) { this->write_command_(cmd, &cmd, 0); }
140
- void reset_params_();
141
- void write_init_sequence_();
142
- void set_addr_window_(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
418
+ /* PROPERTIES */
143
419
 
420
+ // GPIO pins
144
421
  GPIOPin *reset_pin_{nullptr};
145
422
  std::vector<GPIOPin *> enable_pins_{};
146
423
  GPIOPin *dc_pin_{nullptr};
147
- uint16_t x_low_{1};
148
- uint16_t y_low_{1};
149
- uint16_t x_high_{0};
150
- uint16_t y_high_{0};
151
- bool setup_complete_{};
152
424
 
425
+ // other properties set by configuration
153
426
  bool invert_colors_{};
154
- size_t width_;
155
- size_t height_;
156
- int16_t offset_width_;
157
- int16_t offset_height_;
158
- size_t buffer_bytes_{0};
159
- display::ColorBitness color_depth_;
160
- PixelMode pixel_mode_{PIXEL_MODE_16};
161
- uint8_t bus_width_{};
162
- bool spi_16_{};
163
- uint8_t madctl_{};
164
- bool draw_from_origin_{false};
165
427
  unsigned draw_rounding_{2};
166
428
  optional<uint8_t> brightness_{};
167
429
  const char *model_{"Unknown"};
168
430
  std::vector<uint8_t> init_sequence_{};
431
+ uint8_t madctl_{};
432
+ };
433
+
434
+ /**
435
+ * Class for MIPI SPI displays with a buffer.
436
+ *
437
+ * @tparam BUFFERTYPE The type of the buffer pixels, e.g. uint8_t or uint16_t
438
+ * @tparam BUFFERPIXEL Color depth of the buffer
439
+ * @tparam DISPLAYPIXEL Color depth of the display
440
+ * @tparam BUS_TYPE The type of the interface bus (single, quad, octal)
441
+ * @tparam ROTATION The rotation of the display
442
+ * @tparam WIDTH Width of the display in pixels
443
+ * @tparam HEIGHT Height of the display in pixels
444
+ * @tparam OFFSET_WIDTH The x-offset of the display in pixels
445
+ * @tparam OFFSET_HEIGHT The y-offset of the display in pixels
446
+ * @tparam FRACTION The fraction of the display size to use for the buffer (e.g. 4 means a 1/4 buffer).
447
+ */
448
+ template<typename BUFFERTYPE, PixelMode BUFFERPIXEL, bool IS_BIG_ENDIAN, PixelMode DISPLAYPIXEL, BusType BUS_TYPE,
449
+ int WIDTH, int HEIGHT, int OFFSET_WIDTH, int OFFSET_HEIGHT, display::DisplayRotation ROTATION, int FRACTION>
450
+ class MipiSpiBuffer : public MipiSpi<BUFFERTYPE, BUFFERPIXEL, IS_BIG_ENDIAN, DISPLAYPIXEL, BUS_TYPE, WIDTH, HEIGHT,
451
+ OFFSET_WIDTH, OFFSET_HEIGHT> {
452
+ public:
453
+ MipiSpiBuffer() { this->rotation_ = ROTATION; }
454
+
455
+ void dump_config() override {
456
+ MipiSpi<BUFFERTYPE, BUFFERPIXEL, IS_BIG_ENDIAN, DISPLAYPIXEL, BUS_TYPE, WIDTH, HEIGHT, OFFSET_WIDTH,
457
+ OFFSET_HEIGHT>::dump_config();
458
+ esph_log_config(TAG,
459
+ " Rotation: %d°\n"
460
+ " Buffer pixels: %d bits\n"
461
+ " Buffer fraction: 1/%d\n"
462
+ " Buffer bytes: %zu\n"
463
+ " Draw rounding: %u",
464
+ this->rotation_, BUFFERPIXEL * 8, FRACTION, sizeof(BUFFERTYPE) * WIDTH * HEIGHT / FRACTION,
465
+ this->draw_rounding_);
466
+ }
467
+
468
+ void setup() override {
469
+ MipiSpi<BUFFERTYPE, BUFFERPIXEL, IS_BIG_ENDIAN, DISPLAYPIXEL, BUS_TYPE, WIDTH, HEIGHT, OFFSET_WIDTH,
470
+ OFFSET_HEIGHT>::setup();
471
+ RAMAllocator<BUFFERTYPE> allocator{};
472
+ this->buffer_ = allocator.allocate(WIDTH * HEIGHT / FRACTION);
473
+ if (this->buffer_ == nullptr) {
474
+ this->mark_failed("Buffer allocation failed");
475
+ }
476
+ }
477
+
478
+ void update() override {
479
+ #if ESPHOME_LOG_LEVEL == ESPHOME_LOG_LEVEL_VERBOSE
480
+ auto now = millis();
481
+ #endif
482
+ if (this->is_failed()) {
483
+ return;
484
+ }
485
+ // for updates with a small buffer, we repeatedly call the writer_ function, clipping the height to a fraction of
486
+ // the display height,
487
+ for (this->start_line_ = 0; this->start_line_ < HEIGHT; this->start_line_ += HEIGHT / FRACTION) {
488
+ #if ESPHOME_LOG_LEVEL == ESPHOME_LOG_LEVEL_VERBOSE
489
+ auto lap = millis();
490
+ #endif
491
+ this->end_line_ = this->start_line_ + HEIGHT / FRACTION;
492
+ if (this->auto_clear_enabled_) {
493
+ this->clear();
494
+ }
495
+ if (this->page_ != nullptr) {
496
+ this->page_->get_writer()(*this);
497
+ } else if (this->writer_.has_value()) {
498
+ (*this->writer_)(*this);
499
+ } else {
500
+ this->test_card();
501
+ }
502
+ #if ESPHOME_LOG_LEVEL == ESPHOME_LOG_LEVEL_VERBOSE
503
+ esph_log_v(TAG, "Drawing from line %d took %dms", this->start_line_, millis() - lap);
504
+ lap = millis();
505
+ #endif
506
+ if (this->x_low_ > this->x_high_ || this->y_low_ > this->y_high_)
507
+ return;
508
+ esph_log_v(TAG, "x_low %d, y_low %d, x_high %d, y_high %d", this->x_low_, this->y_low_, this->x_high_,
509
+ this->y_high_);
510
+ // Some chips require that the drawing window be aligned on certain boundaries
511
+ auto dr = this->draw_rounding_;
512
+ this->x_low_ = this->x_low_ / dr * dr;
513
+ this->y_low_ = this->y_low_ / dr * dr;
514
+ this->x_high_ = (this->x_high_ + dr) / dr * dr - 1;
515
+ this->y_high_ = (this->y_high_ + dr) / dr * dr - 1;
516
+ int w = this->x_high_ - this->x_low_ + 1;
517
+ int h = this->y_high_ - this->y_low_ + 1;
518
+ this->write_to_display_(this->x_low_, this->y_low_, w, h, this->buffer_, this->x_low_,
519
+ this->y_low_ - this->start_line_, WIDTH - w);
520
+ // invalidate watermarks
521
+ this->x_low_ = WIDTH;
522
+ this->y_low_ = HEIGHT;
523
+ this->x_high_ = 0;
524
+ this->y_high_ = 0;
525
+ #if ESPHOME_LOG_LEVEL == ESPHOME_LOG_LEVEL_VERBOSE
526
+ esph_log_v(TAG, "Write to display took %dms", millis() - lap);
527
+ lap = millis();
528
+ #endif
529
+ }
530
+ #if ESPHOME_LOG_LEVEL == ESPHOME_LOG_LEVEL_VERBOSE
531
+ esph_log_v(TAG, "Total update took %dms", millis() - now);
532
+ #endif
533
+ }
534
+
535
+ // Draw a pixel at the given coordinates.
536
+ void draw_pixel_at(int x, int y, Color color) override {
537
+ if (!this->get_clipping().inside(x, y))
538
+ return;
539
+ rotate_coordinates_(x, y);
540
+ if (x < 0 || x >= WIDTH || y < this->start_line_ || y >= this->end_line_)
541
+ return;
542
+ this->buffer_[(y - this->start_line_) * WIDTH + x] = convert_color_(color);
543
+ if (x < this->x_low_) {
544
+ this->x_low_ = x;
545
+ }
546
+ if (x > this->x_high_) {
547
+ this->x_high_ = x;
548
+ }
549
+ if (y < this->y_low_) {
550
+ this->y_low_ = y;
551
+ }
552
+ if (y > this->y_high_) {
553
+ this->y_high_ = y;
554
+ }
555
+ }
556
+
557
+ // Fills the display with a color.
558
+ void fill(Color color) override {
559
+ this->x_low_ = 0;
560
+ this->y_low_ = this->start_line_;
561
+ this->x_high_ = WIDTH - 1;
562
+ this->y_high_ = this->end_line_ - 1;
563
+ std::fill_n(this->buffer_, HEIGHT * WIDTH / FRACTION, convert_color_(color));
564
+ }
565
+
566
+ int get_width() override {
567
+ if constexpr (ROTATION == display::DISPLAY_ROTATION_90_DEGREES || ROTATION == display::DISPLAY_ROTATION_270_DEGREES)
568
+ return HEIGHT;
569
+ return WIDTH;
570
+ }
571
+
572
+ int get_height() override {
573
+ if constexpr (ROTATION == display::DISPLAY_ROTATION_90_DEGREES || ROTATION == display::DISPLAY_ROTATION_270_DEGREES)
574
+ return WIDTH;
575
+ return HEIGHT;
576
+ }
577
+
578
+ protected:
579
+ // Rotate the coordinates to match the display orientation.
580
+ void rotate_coordinates_(int &x, int &y) const {
581
+ if constexpr (ROTATION == display::DISPLAY_ROTATION_180_DEGREES) {
582
+ x = WIDTH - x - 1;
583
+ y = HEIGHT - y - 1;
584
+ } else if constexpr (ROTATION == display::DISPLAY_ROTATION_90_DEGREES) {
585
+ auto tmp = x;
586
+ x = WIDTH - y - 1;
587
+ y = tmp;
588
+ } else if constexpr (ROTATION == display::DISPLAY_ROTATION_270_DEGREES) {
589
+ auto tmp = y;
590
+ y = HEIGHT - x - 1;
591
+ x = tmp;
592
+ }
593
+ }
594
+
595
+ // Convert a color to the buffer pixel format.
596
+ BUFFERTYPE convert_color_(Color &color) const {
597
+ if constexpr (BUFFERPIXEL == PIXEL_MODE_8) {
598
+ return (color.red & 0xE0) | (color.g & 0xE0) >> 3 | color.b >> 6;
599
+ } else if constexpr (BUFFERPIXEL == PIXEL_MODE_16) {
600
+ if constexpr (IS_BIG_ENDIAN) {
601
+ return (color.r & 0xF8) | color.g >> 5 | (color.g & 0x1C) << 11 | (color.b & 0xF8) << 5;
602
+ } else {
603
+ return (color.r & 0xF8) << 8 | (color.g & 0xFC) << 3 | color.b >> 3;
604
+ }
605
+ }
606
+ return static_cast<BUFFERTYPE>(0);
607
+ }
608
+
609
+ BUFFERTYPE *buffer_{};
610
+ uint16_t x_low_{WIDTH};
611
+ uint16_t y_low_{HEIGHT};
612
+ uint16_t x_high_{0};
613
+ uint16_t y_high_{0};
614
+ uint16_t start_line_{0};
615
+ uint16_t end_line_{1};
169
616
  };
617
+
170
618
  } // namespace mipi_spi
171
619
  } // namespace esphome