esphome 2025.7.5__py3-none-any.whl → 2025.8.0b2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (752) 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 +102 -52
  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/fs3000/fs3000.cpp +0 -2
  209. esphome/components/ft5x06/touchscreen/ft5x06_touchscreen.cpp +0 -2
  210. esphome/components/ft63x6/ft63x6.cpp +0 -1
  211. esphome/components/gdk101/gdk101.cpp +0 -1
  212. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +0 -1
  213. esphome/components/gl_r01_i2c/sensor.py +1 -1
  214. esphome/components/gpio/one_wire/gpio_one_wire.cpp +0 -1
  215. esphome/components/gpio/switch/gpio_switch.cpp +0 -2
  216. esphome/components/gpio_expander/cached_gpio.h +24 -15
  217. esphome/components/gps/__init__.py +6 -2
  218. esphome/components/gps/gps.cpp +50 -49
  219. esphome/components/gps/gps.h +4 -8
  220. esphome/components/gps/time/gps_time.cpp +3 -9
  221. esphome/components/gps/time/gps_time.h +4 -7
  222. esphome/components/graph/__init__.py +1 -1
  223. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.cpp +0 -1
  224. esphome/components/grove_tb6612fng/grove_tb6612fng.cpp +0 -1
  225. esphome/components/gt911/touchscreen/gt911_touchscreen.cpp +21 -12
  226. esphome/components/gt911/touchscreen/gt911_touchscreen.h +26 -2
  227. esphome/components/haier/climate.py +5 -10
  228. esphome/components/haier/haier_base.cpp +0 -1
  229. esphome/components/hbridge/switch/hbridge_switch.cpp +0 -2
  230. esphome/components/hdc1080/hdc1080.cpp +0 -2
  231. esphome/components/heatpumpir/climate.py +2 -2
  232. esphome/components/hlw8012/hlw8012.cpp +0 -1
  233. esphome/components/hm3301/hm3301.cpp +0 -1
  234. esphome/components/hmc5883l/hmc5883l.cpp +0 -1
  235. esphome/components/homeassistant/__init__.py +1 -0
  236. esphome/components/homeassistant/number/__init__.py +1 -0
  237. esphome/components/homeassistant/number/homeassistant_number.cpp +11 -7
  238. esphome/components/homeassistant/switch/__init__.py +1 -0
  239. esphome/components/homeassistant/switch/homeassistant_switch.cpp +9 -5
  240. esphome/components/honeywellabp/honeywellabp.cpp +1 -4
  241. esphome/components/host/__init__.py +2 -0
  242. esphome/components/hte501/hte501.cpp +0 -1
  243. esphome/components/http_request/__init__.py +2 -3
  244. esphome/components/http_request/http_request_idf.cpp +2 -2
  245. esphome/components/htu21d/htu21d.cpp +0 -2
  246. esphome/components/htu31d/htu31d.cpp +0 -2
  247. esphome/components/hx711/hx711.cpp +0 -1
  248. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +0 -1
  249. esphome/components/hydreon_rgxx/sensor.py +4 -5
  250. esphome/components/i2c/i2c_bus.h +1 -1
  251. esphome/components/i2c/i2c_bus_arduino.cpp +1 -2
  252. esphome/components/i2c/i2c_bus_esp_idf.cpp +192 -17
  253. esphome/components/i2c/i2c_bus_esp_idf.h +11 -1
  254. esphome/components/i2s_audio/__init__.py +6 -5
  255. esphome/components/i2s_audio/i2s_audio.cpp +0 -2
  256. esphome/components/i2s_audio/media_player/i2s_audio_media_player.cpp +1 -4
  257. esphome/components/i2s_audio/microphone/__init__.py +4 -6
  258. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +0 -1
  259. esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +2 -2
  260. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +273 -269
  261. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +19 -34
  262. esphome/components/ili9xxx/display.py +4 -3
  263. esphome/components/ili9xxx/ili9xxx_display.cpp +0 -2
  264. esphome/components/image/__init__.py +123 -92
  265. esphome/components/improv_serial/__init__.py +7 -8
  266. esphome/components/ina219/ina219.cpp +0 -1
  267. esphome/components/ina226/ina226.cpp +0 -2
  268. esphome/components/ina260/ina260.cpp +0 -2
  269. esphome/components/ina2xx_base/__init__.py +2 -5
  270. esphome/components/ina2xx_base/ina2xx_base.cpp +0 -2
  271. esphome/components/ina3221/ina3221.cpp +0 -1
  272. esphome/components/internal_temperature/internal_temperature.cpp +0 -2
  273. esphome/components/interval/interval.h +5 -9
  274. esphome/components/json/__init__.py +1 -1
  275. esphome/components/kmeteriso/kmeteriso.cpp +0 -2
  276. esphome/components/lc709203f/lc709203f.cpp +0 -2
  277. esphome/components/lcd_gpio/display.py +1 -3
  278. esphome/components/lcd_gpio/gpio_lcd_display.cpp +0 -1
  279. esphome/components/lcd_pcf8574/pcf8574_display.cpp +0 -1
  280. esphome/components/ld2410/__init__.py +4 -6
  281. esphome/components/ld2410/binary_sensor.py +4 -0
  282. esphome/components/ld2410/ld2410.cpp +56 -100
  283. esphome/components/ld2410/ld2410.h +17 -15
  284. esphome/components/ld2410/sensor.py +24 -10
  285. esphome/components/ld2412/__init__.py +46 -0
  286. esphome/components/ld2412/binary_sensor.py +70 -0
  287. esphome/components/ld2412/button/__init__.py +74 -0
  288. esphome/components/ld2412/button/factory_reset_button.cpp +9 -0
  289. esphome/components/ld2412/button/factory_reset_button.h +18 -0
  290. esphome/components/ld2412/button/query_button.cpp +9 -0
  291. esphome/components/ld2412/button/query_button.h +18 -0
  292. esphome/components/ld2412/button/restart_button.cpp +9 -0
  293. esphome/components/ld2412/button/restart_button.h +18 -0
  294. esphome/components/ld2412/button/start_dynamic_background_correction_button.cpp +11 -0
  295. esphome/components/ld2412/button/start_dynamic_background_correction_button.h +18 -0
  296. esphome/components/ld2412/ld2412.cpp +861 -0
  297. esphome/components/ld2412/ld2412.h +141 -0
  298. esphome/components/ld2412/number/__init__.py +126 -0
  299. esphome/components/ld2412/number/gate_threshold_number.cpp +14 -0
  300. esphome/components/ld2412/number/gate_threshold_number.h +19 -0
  301. esphome/components/ld2412/number/light_threshold_number.cpp +12 -0
  302. esphome/components/ld2412/number/light_threshold_number.h +18 -0
  303. esphome/components/ld2412/number/max_distance_timeout_number.cpp +12 -0
  304. esphome/components/ld2412/number/max_distance_timeout_number.h +18 -0
  305. esphome/components/ld2412/select/__init__.py +82 -0
  306. esphome/components/ld2412/select/baud_rate_select.cpp +12 -0
  307. esphome/components/ld2412/select/baud_rate_select.h +18 -0
  308. esphome/components/ld2412/select/distance_resolution_select.cpp +12 -0
  309. esphome/components/ld2412/select/distance_resolution_select.h +18 -0
  310. esphome/components/ld2412/select/light_out_control_select.cpp +12 -0
  311. esphome/components/ld2412/select/light_out_control_select.h +18 -0
  312. esphome/components/ld2412/sensor.py +124 -0
  313. esphome/components/ld2412/switch/__init__.py +45 -0
  314. esphome/components/ld2412/switch/bluetooth_switch.cpp +12 -0
  315. esphome/components/ld2412/switch/bluetooth_switch.h +18 -0
  316. esphome/components/ld2412/switch/engineering_mode_switch.cpp +12 -0
  317. esphome/components/ld2412/switch/engineering_mode_switch.h +18 -0
  318. esphome/components/ld2412/text_sensor.py +34 -0
  319. esphome/components/ld2420/ld2420.cpp +0 -1
  320. esphome/components/ld2450/__init__.py +3 -4
  321. esphome/components/ld2450/binary_sensor.py +3 -0
  322. esphome/components/ld2450/ld2450.cpp +77 -165
  323. esphome/components/ld2450/ld2450.h +26 -54
  324. esphome/components/ld2450/sensor.py +120 -6
  325. esphome/components/ld2450/text_sensor.py +5 -4
  326. esphome/components/ld24xx/__init__.py +1 -0
  327. esphome/components/ld24xx/ld24xx.h +65 -0
  328. esphome/components/ledc/ledc_output.cpp +0 -1
  329. esphome/components/libretiny/__init__.py +2 -0
  330. esphome/components/light/__init__.py +0 -1
  331. esphome/components/light/effects.py +70 -45
  332. esphome/components/light/light_call.cpp +101 -66
  333. esphome/components/light/light_color_values.h +16 -11
  334. esphome/components/light/light_json_schema.cpp +46 -44
  335. esphome/components/light/light_state.cpp +8 -11
  336. esphome/components/light/light_traits.h +17 -0
  337. esphome/components/lightwaverf/lightwaverf.cpp +0 -2
  338. esphome/components/lilygo_t5_47/touchscreen/lilygo_t5_47_touchscreen.cpp +0 -1
  339. esphome/components/lock/__init__.py +0 -1
  340. esphome/components/logger/__init__.py +31 -9
  341. esphome/components/logger/logger.cpp +12 -7
  342. esphome/components/logger/logger.h +25 -14
  343. esphome/components/logger/logger_esp32.cpp +2 -7
  344. esphome/components/logger/logger_esp8266.cpp +2 -4
  345. esphome/components/logger/logger_host.cpp +2 -4
  346. esphome/components/logger/logger_libretiny.cpp +2 -4
  347. esphome/components/logger/logger_rp2040.cpp +2 -4
  348. esphome/components/logger/logger_zephyr.cpp +86 -0
  349. esphome/components/logger/select/logger_level_select.cpp +2 -4
  350. esphome/components/logger/select/logger_level_select.h +2 -4
  351. esphome/components/logger/task_log_buffer.cpp +2 -4
  352. esphome/components/logger/task_log_buffer.h +2 -4
  353. esphome/components/lps22/sensor.py +5 -5
  354. esphome/components/ltr390/ltr390.cpp +0 -2
  355. esphome/components/ltr501/ltr501.cpp +0 -1
  356. esphome/components/ltr_als_ps/ltr_als_ps.cpp +0 -1
  357. esphome/components/lvgl/__init__.py +14 -13
  358. esphome/components/lvgl/automation.py +2 -4
  359. esphome/components/lvgl/defines.py +0 -2
  360. esphome/components/lvgl/helpers.py +1 -1
  361. esphome/components/lvgl/lv_validation.py +7 -4
  362. esphome/components/lvgl/lvgl_esphome.cpp +2 -3
  363. esphome/components/lvgl/styles.py +2 -2
  364. esphome/components/lvgl/types.py +1 -1
  365. esphome/components/lvgl/widgets/__init__.py +2 -2
  366. esphome/components/lvgl/widgets/arc.py +14 -11
  367. esphome/components/lvgl/widgets/buttonmatrix.py +1 -1
  368. esphome/components/lvgl/widgets/qrcode.py +7 -7
  369. esphome/components/lvgl/widgets/spinner.py +6 -6
  370. esphome/components/lvgl/widgets/switch.py +2 -2
  371. esphome/components/lvgl/widgets/tabview.py +3 -3
  372. esphome/components/m5stack_8angle/m5stack_8angle.cpp +0 -1
  373. esphome/components/matrix_keypad/__init__.py +4 -3
  374. esphome/components/max17043/max17043.cpp +0 -2
  375. esphome/components/max31855/max31855.cpp +1 -4
  376. esphome/components/max31856/max31856.cpp +0 -4
  377. esphome/components/max31865/max31865.cpp +0 -1
  378. esphome/components/max44009/max44009.cpp +0 -1
  379. esphome/components/max6675/max6675.cpp +1 -4
  380. esphome/components/max6956/max6956.cpp +0 -1
  381. esphome/components/max7219/max7219.cpp +0 -1
  382. esphome/components/max7219digit/display.py +1 -1
  383. esphome/components/max7219digit/max7219digit.cpp +0 -1
  384. esphome/components/max9611/max9611.cpp +0 -1
  385. esphome/components/mcp23008/__init__.py +1 -1
  386. esphome/components/mcp23008/mcp23008.cpp +0 -1
  387. esphome/components/mcp23016/mcp23016.cpp +0 -1
  388. esphome/components/mcp23017/__init__.py +1 -1
  389. esphome/components/mcp23017/mcp23017.cpp +0 -1
  390. esphome/components/mcp23s08/__init__.py +1 -1
  391. esphome/components/mcp23s08/mcp23s08.cpp +0 -1
  392. esphome/components/mcp23s17/__init__.py +1 -1
  393. esphome/components/mcp23s17/mcp23s17.cpp +0 -1
  394. esphome/components/mcp23x08_base/__init__.py +2 -0
  395. esphome/components/mcp23x08_base/mcp23x08_base.cpp +9 -7
  396. esphome/components/mcp23x08_base/mcp23x08_base.h +9 -4
  397. esphome/components/mcp23x17_base/__init__.py +2 -0
  398. esphome/components/mcp23x17_base/mcp23x17_base.cpp +20 -7
  399. esphome/components/mcp23x17_base/mcp23x17_base.h +9 -4
  400. esphome/components/mcp23xxx_base/__init__.py +11 -5
  401. esphome/components/mcp23xxx_base/mcp23xxx_base.cpp +15 -12
  402. esphome/components/mcp23xxx_base/mcp23xxx_base.h +8 -7
  403. esphome/components/mcp3008/mcp3008.cpp +1 -4
  404. esphome/components/mcp3204/mcp3204.cpp +1 -4
  405. esphome/components/mcp4461/mcp4461.cpp +0 -1
  406. esphome/components/mcp4725/mcp4725.cpp +0 -1
  407. esphome/components/mcp4728/mcp4728.cpp +0 -1
  408. esphome/components/mcp9600/mcp9600.cpp +0 -2
  409. esphome/components/mcp9808/mcp9808.cpp +0 -2
  410. esphome/components/mdns/__init__.py +3 -0
  411. esphome/components/mdns/mdns_component.cpp +2 -0
  412. esphome/components/mdns/mdns_component.h +4 -0
  413. esphome/components/media_player/__init__.py +40 -0
  414. esphome/components/media_player/automation.h +16 -0
  415. esphome/components/media_player/media_player.cpp +13 -0
  416. esphome/components/media_player/media_player.h +50 -3
  417. esphome/components/micro_wake_word/micro_wake_word.cpp +0 -3
  418. esphome/components/mics_4514/mics_4514.cpp +1 -6
  419. esphome/components/midea/ir_transmitter.h +4 -4
  420. esphome/components/mipi/__init__.py +416 -0
  421. esphome/components/mipi_dsi/__init__.py +5 -0
  422. esphome/components/mipi_dsi/display.py +233 -0
  423. esphome/components/mipi_dsi/mipi_dsi.cpp +379 -0
  424. esphome/components/mipi_dsi/mipi_dsi.h +123 -0
  425. esphome/components/mipi_dsi/models/__init__.py +0 -0
  426. esphome/components/mipi_dsi/models/guition.py +38 -0
  427. esphome/components/mipi_dsi/models/m5stack.py +57 -0
  428. esphome/components/mipi_dsi/models/waveshare.py +105 -0
  429. esphome/components/mipi_rgb/models/lilygo.py +0 -0
  430. esphome/components/mipi_spi/__init__.py +0 -9
  431. esphome/components/mipi_spi/display.py +220 -256
  432. esphome/components/mipi_spi/mipi_spi.cpp +1 -485
  433. esphome/components/mipi_spi/mipi_spi.h +556 -108
  434. esphome/components/mipi_spi/models/__init__.py +0 -65
  435. esphome/components/mipi_spi/models/adafruit.py +30 -0
  436. esphome/components/mipi_spi/models/amoled.py +41 -5
  437. esphome/components/mipi_spi/models/ili.py +5 -5
  438. esphome/components/mipi_spi/models/jc.py +1 -3
  439. esphome/components/mipi_spi/models/lilygo.py +1 -1
  440. esphome/components/mipi_spi/models/waveshare.py +16 -1
  441. esphome/components/mixer/speaker/__init__.py +4 -5
  442. esphome/components/mlx90393/sensor.py +7 -5
  443. esphome/components/mlx90393/sensor_mlx90393.cpp +0 -1
  444. esphome/components/mlx90614/mlx90614.cpp +0 -1
  445. esphome/components/mmc5603/mmc5603.cpp +0 -1
  446. esphome/components/mmc5983/mmc5983.cpp +0 -2
  447. esphome/components/mpl3115a2/mpl3115a2.cpp +0 -2
  448. esphome/components/mpr121/__init__.py +7 -6
  449. esphome/components/mpr121/mpr121.cpp +0 -1
  450. esphome/components/mpu6050/mpu6050.cpp +0 -1
  451. esphome/components/mpu6886/mpu6886.cpp +0 -1
  452. esphome/components/mqtt/__init__.py +1 -2
  453. esphome/components/mqtt/mqtt_button.cpp +1 -1
  454. esphome/components/mqtt/mqtt_client.cpp +0 -1
  455. esphome/components/mqtt/mqtt_component.cpp +8 -14
  456. esphome/components/mqtt/mqtt_component.h +0 -7
  457. esphome/components/mqtt/mqtt_sensor.cpp +0 -1
  458. esphome/components/mqtt/mqtt_sensor.h +0 -1
  459. esphome/components/mqtt/mqtt_text_sensor.cpp +0 -1
  460. esphome/components/mqtt/mqtt_text_sensor.h +0 -1
  461. esphome/components/ms5611/ms5611.cpp +0 -1
  462. esphome/components/ms8607/ms8607.cpp +0 -1
  463. esphome/components/msa3xx/msa3xx.cpp +0 -2
  464. esphome/components/my9231/my9231.cpp +0 -2
  465. esphome/components/nau7802/nau7802.cpp +0 -1
  466. esphome/components/neopixelbus/light.py +3 -0
  467. esphome/components/network/util.cpp +29 -0
  468. esphome/components/nextion/nextion.cpp +0 -1
  469. esphome/components/nfc/binary_sensor/{binary_sensor.cpp → nfc_binary_sensor.cpp} +1 -1
  470. esphome/components/npi19/npi19.cpp +0 -2
  471. esphome/components/nrf52/__init__.py +223 -0
  472. esphome/components/nrf52/boards.py +34 -0
  473. esphome/components/nrf52/const.py +18 -0
  474. esphome/components/nrf52/gpio.py +79 -0
  475. esphome/components/number/__init__.py +2 -1
  476. esphome/components/one_wire/__init__.py +1 -2
  477. esphome/components/one_wire/one_wire.cpp +0 -2
  478. esphome/components/one_wire/one_wire.h +0 -2
  479. esphome/components/opentherm/hub.cpp +0 -1
  480. esphome/components/opentherm/number/__init__.py +2 -2
  481. esphome/components/openthread/__init__.py +2 -3
  482. esphome/components/openthread/openthread.cpp +30 -13
  483. esphome/components/openthread/openthread.h +3 -0
  484. esphome/components/openthread/openthread_esp.cpp +3 -1
  485. esphome/components/opt3001/sensor.py +2 -6
  486. esphome/components/output/__init__.py +38 -0
  487. esphome/components/output/automation.h +24 -0
  488. esphome/components/output/switch/output_switch.cpp +0 -2
  489. esphome/components/packages/__init__.py +1 -2
  490. esphome/components/packet_transport/__init__.py +4 -3
  491. esphome/components/pca6416a/pca6416a.cpp +0 -1
  492. esphome/components/pca9554/pca9554.cpp +0 -1
  493. esphome/components/pca9685/pca9685_output.cpp +0 -2
  494. esphome/components/pcf85063/pcf85063.cpp +0 -1
  495. esphome/components/pcf8563/pcf8563.cpp +0 -1
  496. esphome/components/pcf8574/pcf8574.cpp +0 -1
  497. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +0 -1
  498. esphome/components/pipsolar/sensor/__init__.py +1 -1
  499. esphome/components/pm2005/pm2005.cpp +0 -1
  500. esphome/components/pmsa003i/pmsa003i.cpp +0 -2
  501. esphome/components/pmwcs3/sensor.py +1 -2
  502. esphome/components/pn532/pn532.cpp +0 -2
  503. esphome/components/pn532_spi/pn532_spi.cpp +0 -2
  504. esphome/components/power_supply/power_supply.cpp +7 -10
  505. esphome/components/power_supply/power_supply.h +1 -1
  506. esphome/components/psram/__init__.py +6 -1
  507. esphome/components/pulse_counter/pulse_counter_sensor.cpp +0 -1
  508. esphome/components/pulse_counter/sensor.py +9 -6
  509. esphome/components/pylontech/pylontech.cpp +0 -1
  510. esphome/components/qmc5883l/qmc5883l.cpp +0 -1
  511. esphome/components/qmp6988/qmp6988.cpp +0 -2
  512. esphome/components/qspi_dbi/display.py +2 -3
  513. esphome/components/qspi_dbi/qspi_dbi.cpp +0 -2
  514. esphome/components/qwiic_pir/binary_sensor.py +2 -3
  515. esphome/components/qwiic_pir/qwiic_pir.cpp +0 -2
  516. esphome/components/rc522/rc522.cpp +9 -31
  517. esphome/components/rc522_spi/rc522_spi.cpp +0 -1
  518. esphome/components/remote_base/__init__.py +5 -6
  519. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -1
  520. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +0 -1
  521. esphome/components/remote_receiver/remote_receiver_libretiny.cpp +0 -1
  522. esphome/components/remote_transmitter/__init__.py +26 -0
  523. esphome/components/remote_transmitter/automation.h +18 -0
  524. esphome/components/remote_transmitter/remote_transmitter.h +2 -1
  525. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -1
  526. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +2 -0
  527. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +2 -0
  528. esphome/components/resampler/speaker/__init__.py +4 -5
  529. esphome/components/rf_bridge/__init__.py +4 -8
  530. esphome/components/rotary_encoder/rotary_encoder.cpp +0 -2
  531. esphome/components/rp2040/__init__.py +3 -1
  532. esphome/components/rp2040_pio_led_strip/led_strip.cpp +0 -2
  533. esphome/components/rp2040_pio_led_strip/light.py +1 -2
  534. esphome/components/rp2040_pwm/rp2040_pwm.cpp +1 -5
  535. esphome/components/rpi_dpi_rgb/display.py +13 -15
  536. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -3
  537. esphome/components/runtime_stats/__init__.py +34 -0
  538. esphome/components/runtime_stats/runtime_stats.cpp +102 -0
  539. esphome/components/runtime_stats/runtime_stats.h +132 -0
  540. esphome/components/scd30/scd30.cpp +0 -2
  541. esphome/components/scd30/sensor.py +1 -2
  542. esphome/components/scd4x/scd4x.cpp +0 -1
  543. esphome/components/scd4x/sensor.py +1 -3
  544. esphome/components/sdl/display.py +3 -1
  545. esphome/components/sdl/sdl_esphome.cpp +0 -2
  546. esphome/components/sdp3x/sdp3x.cpp +0 -2
  547. esphome/components/seeed_mr24hpc1/seeed_mr24hpc1.cpp +0 -2
  548. esphome/components/seeed_mr60fda2/seeed_mr60fda2.cpp +0 -3
  549. esphome/components/select/__init__.py +2 -3
  550. esphome/components/select/select_traits.cpp +1 -1
  551. esphome/components/select/select_traits.h +1 -1
  552. esphome/components/sen0321/sen0321.cpp +0 -1
  553. esphome/components/sen5x/sen5x.cpp +0 -2
  554. esphome/components/sensor/__init__.py +36 -4
  555. esphome/components/sensor/filter.cpp +49 -10
  556. esphome/components/sensor/filter.h +22 -7
  557. esphome/components/sensor/sensor.cpp +0 -1
  558. esphome/components/sensor/sensor.h +0 -9
  559. esphome/components/sfa30/sfa30.cpp +0 -4
  560. esphome/components/sgp30/sgp30.cpp +0 -2
  561. esphome/components/sgp4x/sensor.py +1 -1
  562. esphome/components/sgp4x/sgp4x.cpp +0 -2
  563. esphome/components/shelly_dimmer/shelly_dimmer.cpp +0 -2
  564. esphome/components/sht3xd/sht3xd.cpp +0 -2
  565. esphome/components/sht4x/sht4x.cpp +0 -2
  566. esphome/components/shtcx/shtcx.cpp +0 -1
  567. esphome/components/sim800l/__init__.py +2 -4
  568. esphome/components/sm16716/sm16716.cpp +0 -1
  569. esphome/components/sm2135/sm2135.cpp +0 -1
  570. esphome/components/sm2235/sm2235.cpp +0 -1
  571. esphome/components/sm2335/sm2335.cpp +0 -1
  572. esphome/components/sn74hc165/sn74hc165.cpp +0 -1
  573. esphome/components/sn74hc595/sn74hc595.cpp +0 -1
  574. esphome/components/sntp/sntp_component.cpp +0 -1
  575. esphome/components/sound_level/sensor.py +1 -1
  576. esphome/components/speaker/media_player/__init__.py +21 -33
  577. esphome/components/speaker/media_player/audio_pipeline.cpp +4 -7
  578. esphome/components/spi/__init__.py +29 -13
  579. esphome/components/spi/spi.cpp +0 -2
  580. esphome/components/spi_device/spi_device.cpp +1 -4
  581. esphome/components/sprinkler/__init__.py +4 -4
  582. esphome/components/sps30/sps30.cpp +0 -1
  583. esphome/components/ssd1306_base/__init__.py +11 -11
  584. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  585. esphome/components/ssd1306_i2c/ssd1306_i2c.cpp +0 -1
  586. esphome/components/ssd1306_spi/ssd1306_spi.cpp +0 -1
  587. esphome/components/ssd1322_spi/ssd1322_spi.cpp +0 -1
  588. esphome/components/ssd1325_spi/ssd1325_spi.cpp +0 -1
  589. esphome/components/ssd1327_i2c/ssd1327_i2c.cpp +0 -1
  590. esphome/components/ssd1327_spi/ssd1327_spi.cpp +0 -1
  591. esphome/components/ssd1331_spi/ssd1331_spi.cpp +0 -1
  592. esphome/components/ssd1351_spi/ssd1351_spi.cpp +0 -1
  593. esphome/components/st7567_i2c/st7567_i2c.cpp +0 -1
  594. esphome/components/st7567_spi/st7567_spi.cpp +0 -1
  595. esphome/components/st7701s/display.py +10 -14
  596. esphome/components/st7701s/st7701s.cpp +0 -3
  597. esphome/components/st7735/st7735.cpp +0 -1
  598. esphome/components/st7789v/st7789v.cpp +0 -1
  599. esphome/components/st7920/st7920.cpp +0 -1
  600. esphome/components/status_led/light/status_led_light.cpp +0 -2
  601. esphome/components/status_led/status_led.cpp +0 -1
  602. esphome/components/stepper/__init__.py +2 -4
  603. esphome/components/sts3x/sts3x.cpp +0 -1
  604. esphome/components/substitutions/__init__.py +10 -16
  605. esphome/components/substitutions/jinja.py +24 -1
  606. esphome/components/sun/__init__.py +2 -3
  607. esphome/components/switch/__init__.py +31 -1
  608. esphome/components/switch/automation.h +24 -0
  609. esphome/components/switch/switch.cpp +8 -0
  610. esphome/components/switch/switch.h +8 -0
  611. esphome/components/sx126x/sx126x.cpp +0 -2
  612. esphome/components/sx127x/sx127x.cpp +0 -2
  613. esphome/components/sx1509/__init__.py +7 -5
  614. esphome/components/sx1509/output/sx1509_float_output.cpp +1 -1
  615. esphome/components/sx1509/sx1509.cpp +0 -2
  616. esphome/components/syslog/esphome_syslog.cpp +1 -1
  617. esphome/components/tc74/tc74.cpp +0 -1
  618. esphome/components/tca9548a/tca9548a.cpp +0 -1
  619. esphome/components/tca9555/tca9555.cpp +0 -1
  620. esphome/components/tcs34725/tcs34725.cpp +0 -1
  621. esphome/components/tee501/tee501.cpp +0 -1
  622. esphome/components/tem3200/tem3200.cpp +0 -2
  623. esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +0 -1
  624. esphome/components/template/cover/template_cover.cpp +0 -1
  625. esphome/components/template/select/template_select.cpp +0 -1
  626. esphome/components/template/text/template_text.cpp +0 -2
  627. esphome/components/template/valve/template_valve.cpp +0 -1
  628. esphome/components/text/__init__.py +0 -1
  629. esphome/components/text/text_traits.h +2 -0
  630. esphome/components/text_sensor/__init__.py +2 -1
  631. esphome/components/text_sensor/text_sensor.cpp +0 -2
  632. esphome/components/text_sensor/text_sensor.h +0 -8
  633. esphome/components/thermostat/climate.py +4 -4
  634. esphome/components/time/__init__.py +7 -4
  635. esphome/components/time/real_time_clock.cpp +16 -3
  636. esphome/components/tlc59208f/tlc59208f_output.cpp +0 -2
  637. esphome/components/tlc5947/tlc5947.cpp +0 -2
  638. esphome/components/tlc5971/tlc5971.cpp +0 -2
  639. esphome/components/tm1621/tm1621.cpp +0 -2
  640. esphome/components/tm1637/tm1637.cpp +0 -2
  641. esphome/components/tm1638/tm1638.cpp +0 -2
  642. esphome/components/tm1651/__init__.py +45 -48
  643. esphome/components/tm1651/tm1651.cpp +213 -47
  644. esphome/components/tm1651/tm1651.h +37 -32
  645. esphome/components/tmp117/tmp117.cpp +0 -2
  646. esphome/components/tsl2561/tsl2561.cpp +0 -1
  647. esphome/components/tsl2591/tsl2591.cpp +0 -1
  648. esphome/components/tt21100/touchscreen/tt21100.cpp +0 -2
  649. esphome/components/ttp229_bsf/ttp229_bsf.cpp +0 -1
  650. esphome/components/ttp229_lsf/ttp229_lsf.cpp +0 -1
  651. esphome/components/tuya/climate/__init__.py +9 -10
  652. esphome/components/tuya/number/__init__.py +8 -6
  653. esphome/components/tx20/tx20.cpp +0 -1
  654. esphome/components/uart/uart_component_esp32_arduino.cpp +0 -1
  655. esphome/components/uart/uart_component_esp8266.cpp +0 -1
  656. esphome/components/uart/uart_component_esp_idf.cpp +0 -2
  657. esphome/components/uart/uart_component_libretiny.cpp +0 -2
  658. esphome/components/uart/uart_component_rp2040.cpp +0 -2
  659. esphome/components/udp/__init__.py +1 -1
  660. esphome/components/ufire_ec/sensor.py +1 -2
  661. esphome/components/ufire_ec/ufire_ec.cpp +0 -2
  662. esphome/components/ufire_ise/sensor.py +1 -2
  663. esphome/components/ufire_ise/ufire_ise.cpp +0 -2
  664. esphome/components/ultrasonic/ultrasonic_sensor.cpp +0 -1
  665. esphome/components/update/__init__.py +0 -1
  666. esphome/components/uptime/sensor/uptime_seconds_sensor.cpp +0 -1
  667. esphome/components/uptime/sensor/uptime_seconds_sensor.h +0 -2
  668. esphome/components/usb_host/usb_host_client.cpp +0 -1
  669. esphome/components/usb_host/usb_host_component.cpp +0 -1
  670. esphome/components/valve/__init__.py +0 -1
  671. esphome/components/veml3235/veml3235.cpp +0 -3
  672. esphome/components/veml7700/veml7700.cpp +0 -2
  673. esphome/components/version/version_text_sensor.cpp +0 -1
  674. esphome/components/version/version_text_sensor.h +0 -1
  675. esphome/components/vl53l0x/vl53l0x_sensor.cpp +0 -4
  676. esphome/components/voice_assistant/voice_assistant.cpp +9 -8
  677. esphome/components/web_server/__init__.py +13 -0
  678. esphome/components/web_server/web_server.cpp +187 -352
  679. esphome/components/web_server/web_server.h +61 -1
  680. esphome/components/web_server_base/__init__.py +1 -1
  681. esphome/components/web_server_base/web_server_base.cpp +2 -0
  682. esphome/components/web_server_base/web_server_base.h +6 -0
  683. esphome/components/web_server_idf/web_server_idf.cpp +10 -8
  684. esphome/components/web_server_idf/web_server_idf.h +2 -0
  685. esphome/components/weikai_i2c/weikai_i2c.cpp +1 -2
  686. esphome/components/weikai_spi/weikai_spi.cpp +1 -1
  687. esphome/components/wifi/__init__.py +8 -43
  688. esphome/components/wifi/wifi_component.cpp +100 -36
  689. esphome/components/wifi/wifi_component.h +5 -1
  690. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -0
  691. esphome/components/wifi/wifi_component_esp_idf.cpp +30 -0
  692. esphome/components/wifi_info/wifi_info_text_sensor.h +0 -6
  693. esphome/components/wifi_signal/wifi_signal_sensor.h +0 -1
  694. esphome/components/wireguard/wireguard.cpp +0 -2
  695. esphome/components/x9c/x9c.cpp +0 -2
  696. esphome/components/xgzp68xx/xgzp68xx.cpp +0 -1
  697. esphome/components/xl9535/xl9535.cpp +0 -2
  698. esphome/components/zephyr/__init__.py +252 -0
  699. esphome/components/zephyr/const.py +16 -0
  700. esphome/components/zephyr/core.cpp +90 -0
  701. esphome/components/zephyr/gpio.cpp +120 -0
  702. esphome/components/zephyr/gpio.h +38 -0
  703. esphome/components/zephyr/pre_build.py.script +4 -0
  704. esphome/components/zephyr/preferences.cpp +156 -0
  705. esphome/components/zephyr/preferences.h +13 -0
  706. esphome/config.py +38 -16
  707. esphome/config_helpers.py +1 -2
  708. esphome/config_validation.py +12 -16
  709. esphome/const.py +26 -1
  710. esphome/core/__init__.py +88 -51
  711. esphome/core/application.cpp +75 -21
  712. esphome/core/application.h +106 -171
  713. esphome/core/color.h +10 -0
  714. esphome/core/component.cpp +41 -25
  715. esphome/core/component.h +9 -6
  716. esphome/core/component_iterator.cpp +61 -261
  717. esphome/core/component_iterator.h +15 -0
  718. esphome/core/config.py +26 -11
  719. esphome/core/defines.h +40 -2
  720. esphome/core/entity_base.h +18 -0
  721. esphome/core/entity_helpers.py +45 -10
  722. esphome/core/helpers.cpp +8 -15
  723. esphome/core/helpers.h +60 -6
  724. esphome/core/lock_free_queue.h +1 -1
  725. esphome/core/scheduler.cpp +277 -74
  726. esphome/core/scheduler.h +89 -27
  727. esphome/cpp_generator.py +2 -6
  728. esphome/cpp_helpers.py +1 -1
  729. esphome/dashboard/dashboard.py +2 -3
  730. esphome/dashboard/dns.py +2 -8
  731. esphome/dashboard/web_server.py +34 -19
  732. esphome/espota2.py +1 -4
  733. esphome/git.py +3 -1
  734. esphome/helpers.py +23 -4
  735. esphome/log.py +3 -1
  736. esphome/mqtt.py +3 -5
  737. esphome/platformio_api.py +7 -4
  738. esphome/types.py +12 -0
  739. esphome/util.py +20 -8
  740. esphome/voluptuous_schema.py +4 -3
  741. esphome/vscode.py +1 -2
  742. esphome/wizard.py +1 -4
  743. esphome/writer.py +5 -107
  744. esphome/yaml_util.py +7 -5
  745. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/METADATA +13 -14
  746. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/RECORD +751 -671
  747. esphome/components/mipi_spi/models/commands.py +0 -82
  748. /esphome/components/nfc/binary_sensor/{binary_sensor.h → nfc_binary_sensor.h} +0 -0
  749. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/WHEEL +0 -0
  750. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/entry_points.txt +0 -0
  751. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/licenses/LICENSE +0 -0
  752. {esphome-2025.7.5.dist-info → esphome-2025.8.0b2.dist-info}/top_level.txt +0 -0
@@ -1,20 +1,43 @@
1
+ import importlib
1
2
  import logging
3
+ import pkgutil
2
4
 
3
5
  from esphome import pins
4
6
  import esphome.codegen as cg
5
7
  from esphome.components import display, spi
8
+ from esphome.components.const import (
9
+ CONF_BYTE_ORDER,
10
+ CONF_COLOR_DEPTH,
11
+ CONF_DRAW_ROUNDING,
12
+ )
13
+ from esphome.components.display import CONF_SHOW_TEST_CARD, DISPLAY_ROTATIONS
14
+ from esphome.components.mipi import (
15
+ CONF_PIXEL_MODE,
16
+ CONF_USE_AXIS_FLIPS,
17
+ MADCTL,
18
+ MODE_BGR,
19
+ MODE_RGB,
20
+ PIXFMT,
21
+ DriverChip,
22
+ dimension_schema,
23
+ get_color_depth,
24
+ map_sequence,
25
+ power_of_two,
26
+ requires_buffer,
27
+ )
28
+ from esphome.components.psram import DOMAIN as PSRAM_DOMAIN
6
29
  from esphome.components.spi import TYPE_OCTAL, TYPE_QUAD, TYPE_SINGLE
7
30
  import esphome.config_validation as cv
8
31
  from esphome.config_validation import ALLOW_EXTRA
9
32
  from esphome.const import (
10
33
  CONF_BRIGHTNESS,
34
+ CONF_BUFFER_SIZE,
11
35
  CONF_COLOR_ORDER,
12
36
  CONF_CS_PIN,
13
37
  CONF_DATA_RATE,
14
38
  CONF_DC_PIN,
15
39
  CONF_DIMENSIONS,
16
40
  CONF_ENABLE_PIN,
17
- CONF_HEIGHT,
18
41
  CONF_ID,
19
42
  CONF_INIT_SEQUENCE,
20
43
  CONF_INVERT_COLORS,
@@ -22,177 +45,135 @@ from esphome.const import (
22
45
  CONF_MIRROR_X,
23
46
  CONF_MIRROR_Y,
24
47
  CONF_MODEL,
25
- CONF_OFFSET_HEIGHT,
26
- CONF_OFFSET_WIDTH,
27
48
  CONF_RESET_PIN,
28
49
  CONF_ROTATION,
29
50
  CONF_SWAP_XY,
30
51
  CONF_TRANSFORM,
31
52
  CONF_WIDTH,
32
53
  )
33
- from esphome.core import TimePeriod
34
-
35
- from ..const import CONF_DRAW_ROUNDING
36
- from ..lvgl.defines import CONF_COLOR_DEPTH
37
- from . import (
38
- CONF_BUS_MODE,
39
- CONF_DRAW_FROM_ORIGIN,
40
- CONF_NATIVE_HEIGHT,
41
- CONF_NATIVE_WIDTH,
42
- CONF_PIXEL_MODE,
43
- CONF_SPI_16,
44
- CONF_USE_AXIS_FLIPS,
45
- DOMAIN,
46
- MODE_BGR,
47
- MODE_RGB,
48
- )
49
- from .models import (
50
- DELAY_FLAG,
51
- MADCTL_BGR,
52
- MADCTL_MV,
53
- MADCTL_MX,
54
- MADCTL_MY,
55
- MADCTL_XFLIP,
56
- MADCTL_YFLIP,
57
- DriverChip,
58
- amoled,
59
- cyd,
60
- ili,
61
- jc,
62
- lanbon,
63
- lilygo,
64
- waveshare,
65
- )
66
- from .models.commands import BRIGHTNESS, DISPON, INVOFF, INVON, MADCTL, PIXFMT, SLPOUT
54
+ from esphome.core import CORE
55
+ from esphome.cpp_generator import TemplateArguments
56
+ from esphome.final_validate import full_config
57
+
58
+ from . import CONF_BUS_MODE, CONF_SPI_16, DOMAIN, models
67
59
 
68
60
  DEPENDENCIES = ["spi"]
69
61
 
70
62
  LOGGER = logging.getLogger(DOMAIN)
71
63
  mipi_spi_ns = cg.esphome_ns.namespace("mipi_spi")
72
- MipiSpi = mipi_spi_ns.class_(
73
- "MipiSpi", display.Display, display.DisplayBuffer, cg.Component, spi.SPIDevice
64
+ MipiSpi = mipi_spi_ns.class_("MipiSpi", display.Display, cg.Component, spi.SPIDevice)
65
+ MipiSpiBuffer = mipi_spi_ns.class_(
66
+ "MipiSpiBuffer", MipiSpi, display.Display, cg.Component, spi.SPIDevice
74
67
  )
75
68
  ColorOrder = display.display_ns.enum("ColorMode")
76
69
  ColorBitness = display.display_ns.enum("ColorBitness")
77
70
  Model = mipi_spi_ns.enum("Model")
78
71
 
72
+ PixelMode = mipi_spi_ns.enum("PixelMode")
73
+ BusType = mipi_spi_ns.enum("BusType")
74
+
79
75
  COLOR_ORDERS = {
80
76
  MODE_RGB: ColorOrder.COLOR_ORDER_RGB,
81
77
  MODE_BGR: ColorOrder.COLOR_ORDER_BGR,
82
78
  }
83
79
 
84
80
  COLOR_DEPTHS = {
85
- 8: ColorBitness.COLOR_BITNESS_332,
86
- 16: ColorBitness.COLOR_BITNESS_565,
81
+ 8: PixelMode.PIXEL_MODE_8,
82
+ 16: PixelMode.PIXEL_MODE_16,
83
+ 18: PixelMode.PIXEL_MODE_18,
87
84
  }
85
+
88
86
  DATA_PIN_SCHEMA = pins.internal_gpio_output_pin_schema
89
87
 
88
+ BusTypes = {
89
+ TYPE_SINGLE: BusType.BUS_TYPE_SINGLE,
90
+ TYPE_QUAD: BusType.BUS_TYPE_QUAD,
91
+ TYPE_OCTAL: BusType.BUS_TYPE_OCTAL,
92
+ }
93
+
94
+ DriverChip("CUSTOM")
90
95
 
91
- DriverChip("CUSTOM", initsequence={})
96
+ # Import all models dynamically from the models package
97
+ for module_info in pkgutil.iter_modules(models.__path__):
98
+ importlib.import_module(f".models.{module_info.name}", package=__package__)
92
99
 
93
- MODELS = DriverChip.models
94
- # These statements are noops, but serve to suppress linting of side-effect-only imports
95
- for _ in (ili, jc, amoled, lilygo, lanbon, cyd, waveshare):
96
- pass
100
+ MODELS = DriverChip.get_models()
97
101
 
98
- PixelMode = mipi_spi_ns.enum("PixelMode")
99
102
 
100
- PIXEL_MODE_18BIT = "18bit"
101
- PIXEL_MODE_16BIT = "16bit"
103
+ DISPLAY_18BIT = "18bit"
104
+ DISPLAY_16BIT = "16bit"
102
105
 
103
- PIXEL_MODES = {
104
- PIXEL_MODE_16BIT: 0x55,
105
- PIXEL_MODE_18BIT: 0x66,
106
+ DISPLAY_PIXEL_MODES = {
107
+ DISPLAY_16BIT: (0x55, PixelMode.PIXEL_MODE_16),
108
+ DISPLAY_18BIT: (0x66, PixelMode.PIXEL_MODE_18),
106
109
  }
107
110
 
108
111
 
109
- def validate_dimension(rounding):
110
- def validator(value):
111
- value = cv.positive_int(value)
112
- if value % rounding != 0:
113
- raise cv.Invalid(f"Dimensions and offsets must be divisible by {rounding}")
114
- return value
112
+ def denominator(config):
113
+ """
114
+ Calculate the best denominator for a buffer size fraction.
115
+ The denominator must be a number between 2 and 16 that divides the display height evenly,
116
+ and the fraction represented by the denominator must be less than or equal to the given fraction.
117
+ :config: The configuration dictionary containing the buffer size fraction and display dimensions
118
+ :return: The denominator to use for the buffer size fraction
119
+ """
120
+ model = MODELS[config[CONF_MODEL]]
121
+ frac = config.get(CONF_BUFFER_SIZE)
122
+ if frac is None or frac > 0.75:
123
+ return 1
124
+ height, _width, _offset_width, _offset_height = model.get_dimensions(config)
125
+ try:
126
+ return next(x for x in range(2, 17) if frac >= 1 / x and height % x == 0)
127
+ except StopIteration:
128
+ raise cv.Invalid(
129
+ f"Buffer size fraction {frac} is not compatible with display height {height}"
130
+ ) from StopIteration
115
131
 
116
- return validator
117
132
 
133
+ def swap_xy_schema(model):
134
+ uses_swap = model.get_default(CONF_SWAP_XY, None) != cv.UNDEFINED
118
135
 
119
- def map_sequence(value):
120
- """
121
- The format is a repeated sequence of [CMD, <data>] where <data> is s a sequence of bytes. The length is inferred
122
- from the length of the sequence and should not be explicit.
123
- A delay can be inserted by specifying "- delay N" where N is in ms
124
- """
125
- if isinstance(value, str) and value.lower().startswith("delay "):
126
- value = value.lower()[6:]
127
- delay = cv.All(
128
- cv.positive_time_period_milliseconds,
129
- cv.Range(TimePeriod(milliseconds=1), TimePeriod(milliseconds=255)),
130
- )(value)
131
- return DELAY_FLAG, delay.total_milliseconds
132
- if isinstance(value, int):
133
- return (value,)
134
- value = cv.All(cv.ensure_list(cv.int_range(0, 255)), cv.Length(1, 254))(value)
135
- return tuple(value)
136
-
137
-
138
- def power_of_two(value):
139
- value = cv.int_range(1, 128)(value)
140
- if value & (value - 1) != 0:
141
- raise cv.Invalid("value must be a power of two")
142
- return value
143
-
144
-
145
- def dimension_schema(rounding):
146
- return cv.Any(
147
- cv.dimensions,
148
- cv.Schema(
149
- {
150
- cv.Required(CONF_WIDTH): validate_dimension(rounding),
151
- cv.Required(CONF_HEIGHT): validate_dimension(rounding),
152
- cv.Optional(CONF_OFFSET_HEIGHT, default=0): validate_dimension(
153
- rounding
154
- ),
155
- cv.Optional(CONF_OFFSET_WIDTH, default=0): validate_dimension(rounding),
156
- }
157
- ),
158
- )
136
+ def validator(value):
137
+ if value:
138
+ raise cv.Invalid("Axis swapping not supported by this model")
139
+ return cv.boolean(value)
159
140
 
141
+ if uses_swap:
142
+ return {cv.Required(CONF_SWAP_XY): cv.boolean}
143
+ return {cv.Optional(CONF_SWAP_XY, default=False): validator}
160
144
 
161
- def model_schema(bus_mode, model: DriverChip, swapsies: bool):
145
+
146
+ def model_schema(config):
147
+ model = MODELS[config[CONF_MODEL]]
148
+ bus_mode = config[CONF_BUS_MODE]
162
149
  transform = cv.Schema(
163
150
  {
164
151
  cv.Required(CONF_MIRROR_X): cv.boolean,
165
152
  cv.Required(CONF_MIRROR_Y): cv.boolean,
153
+ **swap_xy_schema(model),
166
154
  }
167
155
  )
168
- if model.get_default(CONF_SWAP_XY, False) == cv.UNDEFINED:
169
- transform = transform.extend(
170
- {
171
- cv.Optional(CONF_SWAP_XY): cv.invalid(
172
- "Axis swapping not supported by this model"
173
- )
174
- }
175
- )
176
- else:
177
- transform = transform.extend(
178
- {
179
- cv.Required(CONF_SWAP_XY): cv.boolean,
180
- }
181
- )
182
156
  # CUSTOM model will need to provide a custom init sequence
183
157
  iseqconf = (
184
158
  cv.Required(CONF_INIT_SEQUENCE)
185
159
  if model.initsequence is None
186
160
  else cv.Optional(CONF_INIT_SEQUENCE)
187
161
  )
188
- # Dimensions are optional if the model has a default width and the transform is not overridden
162
+ # Dimensions are optional if the model has a default width and the x-y transform is not overridden
163
+ is_swapped = config.get(CONF_TRANSFORM, {}).get(CONF_SWAP_XY) is True
189
164
  cv_dimensions = (
190
- cv.Optional if model.get_default(CONF_WIDTH) and not swapsies else cv.Required
165
+ cv.Optional if model.get_default(CONF_WIDTH) and not is_swapped else cv.Required
191
166
  )
192
- pixel_modes = PIXEL_MODES if bus_mode == TYPE_SINGLE else (PIXEL_MODE_16BIT,)
167
+ pixel_modes = DISPLAY_PIXEL_MODES if bus_mode == TYPE_SINGLE else (DISPLAY_16BIT,)
193
168
  color_depth = (
194
169
  ("16", "8", "16bit", "8bit") if bus_mode == TYPE_SINGLE else ("16", "16bit")
195
170
  )
171
+ other_options = [
172
+ CONF_INVERT_COLORS,
173
+ CONF_USE_AXIS_FLIPS,
174
+ ]
175
+ if bus_mode == TYPE_SINGLE:
176
+ other_options.append(CONF_SPI_16)
196
177
  schema = (
197
178
  display.FULL_DISPLAY_SCHEMA.extend(
198
179
  spi.spi_device_schema(
@@ -220,11 +201,13 @@ def model_schema(bus_mode, model: DriverChip, swapsies: bool):
220
201
  model.option(CONF_COLOR_ORDER, MODE_BGR): cv.enum(
221
202
  COLOR_ORDERS, upper=True
222
203
  ),
204
+ model.option(CONF_BYTE_ORDER, "big_endian"): cv.one_of(
205
+ "big_endian", "little_endian", lower=True
206
+ ),
223
207
  model.option(CONF_COLOR_DEPTH, 16): cv.one_of(*color_depth, lower=True),
224
208
  model.option(CONF_DRAW_ROUNDING, 2): power_of_two,
225
- model.option(CONF_PIXEL_MODE, PIXEL_MODE_16BIT): cv.Any(
226
- cv.one_of(*pixel_modes, lower=True),
227
- cv.int_range(0, 255, min_included=True, max_included=True),
209
+ model.option(CONF_PIXEL_MODE, DISPLAY_16BIT): cv.one_of(
210
+ *pixel_modes, lower=True
228
211
  ),
229
212
  cv.Optional(CONF_TRANSFORM): transform,
230
213
  cv.Optional(CONF_BUS_MODE, default=bus_mode): cv.one_of(
@@ -232,19 +215,12 @@ def model_schema(bus_mode, model: DriverChip, swapsies: bool):
232
215
  ),
233
216
  cv.Required(CONF_MODEL): cv.one_of(model.name, upper=True),
234
217
  iseqconf: cv.ensure_list(map_sequence),
218
+ cv.Optional(CONF_BUFFER_SIZE): cv.All(
219
+ cv.percentage, cv.Range(0.12, 1.0)
220
+ ),
235
221
  }
236
222
  )
237
- .extend(
238
- {
239
- model.option(x): cv.boolean
240
- for x in [
241
- CONF_DRAW_FROM_ORIGIN,
242
- CONF_SPI_16,
243
- CONF_INVERT_COLORS,
244
- CONF_USE_AXIS_FLIPS,
245
- ]
246
- }
247
- )
223
+ .extend({model.option(x): cv.boolean for x in other_options})
248
224
  )
249
225
  if brightness := model.get_default(CONF_BRIGHTNESS):
250
226
  schema = schema.extend(
@@ -259,18 +235,13 @@ def model_schema(bus_mode, model: DriverChip, swapsies: bool):
259
235
  return schema
260
236
 
261
237
 
262
- def rotation_as_transform(model, config):
238
+ def customise_schema(config):
263
239
  """
264
- Check if a rotation can be implemented in hardware using the MADCTL register.
265
- A rotation of 180 is always possible, 90 and 270 are possible if the model supports swapping X and Y.
240
+ Create a customised config schema for a specific model and validate the configuration.
241
+ :param config: The configuration dictionary to validate
242
+ :return: The validated configuration dictionary
243
+ :raises cv.Invalid: If the configuration is invalid
266
244
  """
267
- rotation = config.get(CONF_ROTATION, 0)
268
- return rotation and (
269
- model.get_default(CONF_SWAP_XY) != cv.UNDEFINED or rotation == 180
270
- )
271
-
272
-
273
- def config_schema(config):
274
245
  # First get the model and bus mode
275
246
  config = cv.Schema(
276
247
  {
@@ -279,7 +250,7 @@ def config_schema(config):
279
250
  extra=ALLOW_EXTRA,
280
251
  )(config)
281
252
  model = MODELS[config[CONF_MODEL]]
282
- bus_modes = model.modes
253
+ bus_modes = (TYPE_SINGLE, TYPE_QUAD, TYPE_OCTAL)
283
254
  config = cv.Schema(
284
255
  {
285
256
  model.option(CONF_BUS_MODE, TYPE_SINGLE): cv.one_of(*bus_modes, lower=True),
@@ -287,30 +258,81 @@ def config_schema(config):
287
258
  },
288
259
  extra=ALLOW_EXTRA,
289
260
  )(config)
290
- bus_mode = config.get(CONF_BUS_MODE, model.modes[0])
291
- swapsies = config.get(CONF_TRANSFORM, {}).get(CONF_SWAP_XY) is True
292
- config = model_schema(bus_mode, model, swapsies)(config)
261
+ bus_mode = config[CONF_BUS_MODE]
262
+ config = model_schema(config)(config)
293
263
  # Check for invalid combinations of MADCTL config
294
264
  if init_sequence := config.get(CONF_INIT_SEQUENCE):
295
- if MADCTL in [x[0] for x in init_sequence] and CONF_TRANSFORM in config:
265
+ commands = [x[0] for x in init_sequence]
266
+ if MADCTL in commands and CONF_TRANSFORM in config:
296
267
  raise cv.Invalid(
297
268
  f"transform is not supported when MADCTL ({MADCTL:#X}) is in the init sequence"
298
269
  )
270
+ if PIXFMT in commands:
271
+ raise cv.Invalid(
272
+ f"PIXFMT ({PIXFMT:#X}) should not be in the init sequence, it will be set automatically"
273
+ )
299
274
 
300
275
  if bus_mode == TYPE_QUAD and CONF_DC_PIN in config:
301
276
  raise cv.Invalid("DC pin is not supported in quad mode")
302
- if config[CONF_PIXEL_MODE] == PIXEL_MODE_18BIT and bus_mode != TYPE_SINGLE:
303
- raise cv.Invalid("18-bit pixel mode is not supported on a quad or octal bus")
304
277
  if bus_mode != TYPE_QUAD and CONF_DC_PIN not in config:
305
278
  raise cv.Invalid(f"DC pin is required in {bus_mode} mode")
279
+ denominator(config)
306
280
  return config
307
281
 
308
282
 
309
- CONFIG_SCHEMA = config_schema
283
+ CONFIG_SCHEMA = customise_schema
310
284
 
311
285
 
312
- def get_transform(model, config):
313
- can_transform = rotation_as_transform(model, config)
286
+ def _final_validate(config):
287
+ global_config = full_config.get()
288
+ model = MODELS[config[CONF_MODEL]]
289
+
290
+ from esphome.components.lvgl import DOMAIN as LVGL_DOMAIN
291
+
292
+ if not requires_buffer(config) and LVGL_DOMAIN not in global_config:
293
+ # If no drawing methods are configured, and LVGL is not enabled, show a test card
294
+ config[CONF_SHOW_TEST_CARD] = True
295
+
296
+ if PSRAM_DOMAIN not in global_config and CONF_BUFFER_SIZE not in config:
297
+ if not requires_buffer(config):
298
+ return config # No buffer needed, so no need to set a buffer size
299
+ # If PSRAM is not enabled, choose a small buffer size by default
300
+ if not requires_buffer(config):
301
+ # not our problem.
302
+ return config
303
+ color_depth = get_color_depth(config)
304
+ frac = denominator(config)
305
+ height, width, _offset_width, _offset_height = model.get_dimensions(config)
306
+
307
+ buffer_size = color_depth // 8 * width * height // frac
308
+ # Target a buffer size of 20kB
309
+ fraction = 20000.0 / buffer_size
310
+ try:
311
+ config[CONF_BUFFER_SIZE] = 1.0 / next(
312
+ x for x in range(2, 17) if fraction >= 1 / x and height % x == 0
313
+ )
314
+ except StopIteration:
315
+ # Either the screen is too big, or the height is not divisible by any of the fractions, so use 1.0
316
+ # PSRAM will be needed.
317
+ if CORE.is_esp32:
318
+ raise cv.Invalid(
319
+ "PSRAM is required for this display"
320
+ ) from StopIteration
321
+
322
+ return config
323
+
324
+
325
+ FINAL_VALIDATE_SCHEMA = _final_validate
326
+
327
+
328
+ def get_transform(config):
329
+ """
330
+ Get the transformation configuration for the display.
331
+ :param config:
332
+ :return:
333
+ """
334
+ model = MODELS[config[CONF_MODEL]]
335
+ can_transform = model.rotation_as_transform(config)
314
336
  transform = config.get(
315
337
  CONF_TRANSFORM,
316
338
  {
@@ -336,123 +358,64 @@ def get_transform(model, config):
336
358
  return transform
337
359
 
338
360
 
339
- def get_sequence(model, config):
361
+ def get_instance(config):
340
362
  """
341
- Create the init sequence for the display.
342
- Use the default sequence from the model, if any, and append any custom sequence provided in the config.
343
- Append SLPOUT (if not already in the sequence) and DISPON to the end of the sequence
344
- Pixel format, color order, and orientation will be set.
363
+ Get the type of MipiSpi instance to create based on the configuration,
364
+ and the template arguments.
365
+ :param config:
366
+ :return: type, template arguments
345
367
  """
346
- sequence = list(model.initsequence)
347
- custom_sequence = config.get(CONF_INIT_SEQUENCE, [])
348
- sequence.extend(custom_sequence)
349
- # Ensure each command is a tuple
350
- sequence = [x if isinstance(x, tuple) else (x,) for x in sequence]
351
- commands = [x[0] for x in sequence]
352
- # Set pixel format if not already in the custom sequence
353
- if PIXFMT not in commands:
354
- pixel_mode = config[CONF_PIXEL_MODE]
355
- if not isinstance(pixel_mode, int):
356
- pixel_mode = PIXEL_MODES[pixel_mode]
357
- sequence.append((PIXFMT, pixel_mode))
358
- # Does the chip use the flipping bits for mirroring rather than the reverse order bits?
359
- use_flip = config[CONF_USE_AXIS_FLIPS]
360
- if MADCTL not in commands:
361
- madctl = 0
362
- transform = get_transform(model, config)
363
- if transform.get(CONF_TRANSFORM):
364
- LOGGER.info("Using hardware transform to implement rotation")
365
- if transform.get(CONF_MIRROR_X):
366
- madctl |= MADCTL_XFLIP if use_flip else MADCTL_MX
367
- if transform.get(CONF_MIRROR_Y):
368
- madctl |= MADCTL_YFLIP if use_flip else MADCTL_MY
369
- if transform.get(CONF_SWAP_XY) is True: # Exclude Undefined
370
- madctl |= MADCTL_MV
371
- if config[CONF_COLOR_ORDER] == MODE_BGR:
372
- madctl |= MADCTL_BGR
373
- sequence.append((MADCTL, madctl))
374
- if INVON not in commands and INVOFF not in commands:
375
- if config[CONF_INVERT_COLORS]:
376
- sequence.append((INVON,))
377
- else:
378
- sequence.append((INVOFF,))
379
- if BRIGHTNESS not in commands:
380
- if brightness := config.get(
381
- CONF_BRIGHTNESS, model.get_default(CONF_BRIGHTNESS)
382
- ):
383
- sequence.append((BRIGHTNESS, brightness))
384
- if SLPOUT not in commands:
385
- sequence.append((SLPOUT,))
386
- sequence.append((DISPON,))
387
-
388
- # Flatten the sequence into a list of bytes, with the length of each command
389
- # or the delay flag inserted where needed
390
- return sum(
391
- tuple(
392
- (x[1], 0xFF) if x[0] == DELAY_FLAG else (x[0], len(x) - 1) + x[1:]
393
- for x in sequence
394
- ),
395
- (),
396
- )
368
+ model = MODELS[config[CONF_MODEL]]
369
+ width, height, offset_width, offset_height = model.get_dimensions(config)
370
+
371
+ color_depth = int(config[CONF_COLOR_DEPTH].removesuffix("bit"))
372
+ bufferpixels = COLOR_DEPTHS[color_depth]
373
+
374
+ display_pixel_mode = DISPLAY_PIXEL_MODES[config[CONF_PIXEL_MODE]][1]
375
+ bus_type = config[CONF_BUS_MODE]
376
+ if bus_type == TYPE_SINGLE and config.get(CONF_SPI_16, False):
377
+ # If the bus mode is single and spi_16 is set, use single 16-bit mode
378
+ bus_type = BusType.BUS_TYPE_SINGLE_16
379
+ else:
380
+ bus_type = BusTypes[bus_type]
381
+ buffer_type = cg.uint8 if color_depth == 8 else cg.uint16
382
+ frac = denominator(config)
383
+ rotation = DISPLAY_ROTATIONS[
384
+ 0 if model.rotation_as_transform(config) else config.get(CONF_ROTATION, 0)
385
+ ]
386
+ templateargs = [
387
+ buffer_type,
388
+ bufferpixels,
389
+ config[CONF_BYTE_ORDER] == "big_endian",
390
+ display_pixel_mode,
391
+ bus_type,
392
+ width,
393
+ height,
394
+ offset_width,
395
+ offset_height,
396
+ ]
397
+ # If a buffer is required, use MipiSpiBuffer, otherwise use MipiSpi
398
+ if requires_buffer(config):
399
+ templateargs.append(rotation)
400
+ templateargs.append(frac)
401
+ return MipiSpiBuffer, templateargs
402
+ return MipiSpi, templateargs
397
403
 
398
404
 
399
405
  async def to_code(config):
400
406
  model = MODELS[config[CONF_MODEL]]
401
- transform = get_transform(model, config)
402
- if CONF_DIMENSIONS in config:
403
- # Explicit dimensions, just use as is
404
- dimensions = config[CONF_DIMENSIONS]
405
- if isinstance(dimensions, dict):
406
- width = dimensions[CONF_WIDTH]
407
- height = dimensions[CONF_HEIGHT]
408
- offset_width = dimensions[CONF_OFFSET_WIDTH]
409
- offset_height = dimensions[CONF_OFFSET_HEIGHT]
410
- else:
411
- (width, height) = dimensions
412
- offset_width = 0
413
- offset_height = 0
414
- else:
415
- # Default dimensions, use model defaults and transform if needed
416
- width = model.get_default(CONF_WIDTH)
417
- height = model.get_default(CONF_HEIGHT)
418
- offset_width = model.get_default(CONF_OFFSET_WIDTH, 0)
419
- offset_height = model.get_default(CONF_OFFSET_HEIGHT, 0)
420
-
421
- # if mirroring axes and there are offsets, also mirror the offsets to cater for situations where
422
- # the offset is asymmetric
423
- if transform[CONF_MIRROR_X]:
424
- native_width = model.get_default(
425
- CONF_NATIVE_WIDTH, width + offset_width * 2
426
- )
427
- offset_width = native_width - width - offset_width
428
- if transform[CONF_MIRROR_Y]:
429
- native_height = model.get_default(
430
- CONF_NATIVE_HEIGHT, height + offset_height * 2
431
- )
432
- offset_height = native_height - height - offset_height
433
- # Swap default dimensions if swap_xy is set
434
- if transform[CONF_SWAP_XY] is True:
435
- width, height = height, width
436
- offset_height, offset_width = offset_width, offset_height
437
-
438
- color_depth = config[CONF_COLOR_DEPTH]
439
- if color_depth.endswith("bit"):
440
- color_depth = color_depth[:-3]
441
- color_depth = COLOR_DEPTHS[int(color_depth)]
442
-
443
- var = cg.new_Pvariable(
444
- config[CONF_ID], width, height, offset_width, offset_height, color_depth
445
- )
446
- cg.add(var.set_init_sequence(get_sequence(model, config)))
447
- if rotation_as_transform(model, config):
407
+ var_id = config[CONF_ID]
408
+ var_id.type, templateargs = get_instance(config)
409
+ var = cg.new_Pvariable(var_id, TemplateArguments(*templateargs))
410
+ init_sequence, _madctl = model.get_sequence(config)
411
+ cg.add(var.set_init_sequence(init_sequence))
412
+ if model.rotation_as_transform(config):
448
413
  if CONF_TRANSFORM in config:
449
414
  LOGGER.warning("Use of 'transform' with 'rotation' is not recommended")
450
415
  else:
451
416
  config[CONF_ROTATION] = 0
452
417
  cg.add(var.set_model(config[CONF_MODEL]))
453
- cg.add(var.set_draw_from_origin(config[CONF_DRAW_FROM_ORIGIN]))
454
418
  cg.add(var.set_draw_rounding(config[CONF_DRAW_ROUNDING]))
455
- cg.add(var.set_spi_16(config[CONF_SPI_16]))
456
419
  if enable_pin := config.get(CONF_ENABLE_PIN):
457
420
  enable = [await cg.gpio_pin_expression(pin) for pin in enable_pin]
458
421
  cg.add(var.set_enable_pins(enable))
@@ -472,4 +435,5 @@ async def to_code(config):
472
435
  cg.add(var.set_writer(lambda_))
473
436
  await display.register_display(var, config)
474
437
  await spi.register_spi_device(var, config)
438
+ # Displays are write-only, set the SPI device to write-only as well
475
439
  cg.add(var.set_write_only(True))