esphome 2024.12.4__py3-none-any.whl → 2025.2.0__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 (366) hide show
  1. esphome/__main__.py +16 -3
  2. esphome/components/adc/__init__.py +17 -11
  3. esphome/components/adc/adc_sensor.h +17 -0
  4. esphome/components/adc/adc_sensor_common.cpp +55 -0
  5. esphome/components/adc/adc_sensor_esp32.cpp +8 -5
  6. esphome/components/adc/adc_sensor_esp8266.cpp +10 -6
  7. esphome/components/adc/adc_sensor_libretiny.cpp +11 -6
  8. esphome/components/adc/adc_sensor_rp2040.cpp +13 -10
  9. esphome/components/adc/sensor.py +9 -3
  10. esphome/components/ads1115/ads1115.cpp +56 -7
  11. esphome/components/ads1115/ads1115.h +13 -1
  12. esphome/components/ads1115/sensor/__init__.py +16 -0
  13. esphome/components/ads1115/sensor/ads1115_sensor.cpp +2 -1
  14. esphome/components/ads1115/sensor/ads1115_sensor.h +2 -0
  15. esphome/components/animation/__init__.py +23 -261
  16. esphome/components/animation/animation.cpp +2 -2
  17. esphome/components/animation/animation.h +2 -1
  18. esphome/components/api/api_pb2.cpp +14 -0
  19. esphome/components/api/api_pb2.h +1 -0
  20. esphome/components/api/client.py +8 -3
  21. esphome/components/audio/__init__.py +112 -0
  22. esphome/components/audio/audio.cpp +67 -0
  23. esphome/components/audio/audio.h +125 -7
  24. esphome/components/audio/audio_decoder.cpp +361 -0
  25. esphome/components/audio/audio_decoder.h +135 -0
  26. esphome/components/audio/audio_reader.cpp +308 -0
  27. esphome/components/audio/audio_reader.h +85 -0
  28. esphome/components/audio/audio_resampler.cpp +159 -0
  29. esphome/components/audio/audio_resampler.h +101 -0
  30. esphome/components/audio/audio_transfer_buffer.cpp +165 -0
  31. esphome/components/audio/audio_transfer_buffer.h +139 -0
  32. esphome/components/audio_adc/__init__.py +41 -0
  33. esphome/components/audio_adc/audio_adc.h +17 -0
  34. esphome/components/audio_adc/automation.h +23 -0
  35. esphome/components/bk72xx/__init__.py +1 -0
  36. esphome/components/ble_client/ble_client.cpp +1 -2
  37. esphome/components/ble_client/sensor/__init__.py +1 -1
  38. esphome/components/ble_client/text_sensor/__init__.py +1 -1
  39. esphome/components/bluetooth_proxy/bluetooth_connection.cpp +5 -0
  40. esphome/components/bluetooth_proxy/bluetooth_connection.h +1 -0
  41. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +5 -0
  42. esphome/components/ch422g/ch422g.h +2 -0
  43. esphome/components/climate/__init__.py +1 -1
  44. esphome/components/climate_ir/climate_ir.cpp +2 -1
  45. esphome/components/coolix/coolix.cpp +2 -1
  46. esphome/components/cse7766/cse7766.cpp +8 -16
  47. esphome/components/custom/__init__.py +0 -3
  48. esphome/components/custom/binary_sensor/__init__.py +2 -28
  49. esphome/components/custom/climate/__init__.py +2 -27
  50. esphome/components/custom/cover/__init__.py +2 -27
  51. esphome/components/custom/light/__init__.py +2 -27
  52. esphome/components/custom/output/__init__.py +2 -58
  53. esphome/components/custom/sensor/__init__.py +2 -24
  54. esphome/components/custom/switch/__init__.py +2 -24
  55. esphome/components/custom/text_sensor/__init__.py +2 -29
  56. esphome/components/custom_component/__init__.py +3 -27
  57. esphome/components/daly_bms/daly_bms.cpp +6 -0
  58. esphome/components/daly_bms/daly_bms.h +2 -0
  59. esphome/components/daly_bms/sensor.py +6 -0
  60. esphome/components/debug/debug_component.cpp +4 -0
  61. esphome/components/debug/debug_component.h +14 -0
  62. esphome/components/debug/debug_esp32.cpp +154 -74
  63. esphome/components/dfplayer/dfplayer.cpp +15 -2
  64. esphome/components/dfrobot_sen0395/dfrobot_sen0395.cpp +2 -1
  65. esphome/components/dht/dht.cpp +4 -2
  66. esphome/components/dht/sensor.py +1 -1
  67. esphome/components/display/__init__.py +18 -5
  68. esphome/components/display/display.cpp +16 -3
  69. esphome/components/display/rect.cpp +2 -1
  70. esphome/components/es7210/__init__.py +0 -0
  71. esphome/components/es7210/audio_adc.py +51 -0
  72. esphome/components/es7210/es7210.cpp +228 -0
  73. esphome/components/es7210/es7210.h +62 -0
  74. esphome/components/es7210/es7210_const.h +129 -0
  75. esphome/components/es7243e/__init__.py +0 -0
  76. esphome/components/es7243e/audio_adc.py +34 -0
  77. esphome/components/es7243e/es7243e.cpp +125 -0
  78. esphome/components/es7243e/es7243e.h +37 -0
  79. esphome/components/es7243e/es7243e_const.h +54 -0
  80. esphome/components/es8156/__init__.py +0 -0
  81. esphome/components/es8156/audio_dac.py +27 -0
  82. esphome/components/es8156/es8156.cpp +87 -0
  83. esphome/components/es8156/es8156.h +51 -0
  84. esphome/components/es8156/es8156_const.h +68 -0
  85. esphome/components/es8311/audio_dac.py +1 -2
  86. esphome/components/esp32/__init__.py +1 -0
  87. esphome/components/esp32/core.cpp +5 -1
  88. esphome/components/esp32/gpio.h +2 -0
  89. esphome/components/esp32_ble/__init__.py +39 -0
  90. esphome/components/esp32_ble/queue.h +4 -4
  91. esphome/components/esp32_ble_client/ble_client_base.cpp +46 -0
  92. esphome/components/esp32_ble_client/ble_client_base.h +2 -0
  93. esphome/components/esp32_ble_server/__init__.py +582 -12
  94. esphome/components/esp32_ble_server/ble_characteristic.cpp +48 -60
  95. esphome/components/esp32_ble_server/ble_characteristic.h +24 -17
  96. esphome/components/esp32_ble_server/ble_descriptor.cpp +21 -9
  97. esphome/components/esp32_ble_server/ble_descriptor.h +17 -6
  98. esphome/components/esp32_ble_server/ble_server.cpp +62 -67
  99. esphome/components/esp32_ble_server/ble_server.h +28 -32
  100. esphome/components/esp32_ble_server/ble_server_automations.cpp +77 -0
  101. esphome/components/esp32_ble_server/ble_server_automations.h +115 -0
  102. esphome/components/esp32_ble_server/ble_service.cpp +17 -15
  103. esphome/components/esp32_ble_server/ble_service.h +10 -14
  104. esphome/components/esp32_ble_tracker/__init__.py +6 -39
  105. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +33 -10
  106. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +8 -4
  107. esphome/components/esp32_dac/esp32_dac.cpp +16 -7
  108. esphome/components/esp32_dac/esp32_dac.h +8 -0
  109. esphome/components/esp32_dac/output.py +16 -4
  110. esphome/components/esp32_improv/__init__.py +2 -8
  111. esphome/components/esp32_improv/esp32_improv_component.cpp +21 -20
  112. esphome/components/esp32_improv/esp32_improv_component.h +3 -4
  113. esphome/components/esp32_rmt/__init__.py +28 -3
  114. esphome/components/esp32_rmt_led_strip/led_strip.cpp +73 -6
  115. esphome/components/esp32_rmt_led_strip/led_strip.h +21 -3
  116. esphome/components/esp32_rmt_led_strip/light.py +72 -7
  117. esphome/components/esp32_touch/esp32_touch.cpp +5 -0
  118. esphome/components/esp8266/__init__.py +1 -0
  119. esphome/components/esp8266/gpio.h +1 -0
  120. esphome/components/ethernet/__init__.py +10 -10
  121. esphome/components/event/event.cpp +4 -2
  122. esphome/components/event/event.h +2 -0
  123. esphome/components/event_emitter/__init__.py +5 -0
  124. esphome/components/event_emitter/event_emitter.cpp +14 -0
  125. esphome/components/event_emitter/event_emitter.h +63 -0
  126. esphome/components/font/__init__.py +1 -1
  127. esphome/components/gcja5/gcja5.cpp +2 -1
  128. esphome/components/graph/graph.cpp +4 -9
  129. esphome/components/haier/haier_base.cpp +2 -1
  130. esphome/components/haier/hon_climate.cpp +2 -1
  131. esphome/components/heatpumpir/heatpumpir.cpp +2 -1
  132. esphome/components/host/__init__.py +1 -0
  133. esphome/components/host/gpio.h +1 -0
  134. esphome/components/http_request/http_request.h +2 -2
  135. esphome/components/http_request/http_request_arduino.cpp +1 -1
  136. esphome/components/http_request/http_request_idf.cpp +1 -1
  137. esphome/components/i2c/i2c_bus_esp_idf.cpp +4 -0
  138. esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +7 -5
  139. esphome/components/i2s_audio/speaker/__init__.py +53 -6
  140. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +92 -46
  141. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +8 -0
  142. esphome/components/ili9xxx/display.py +29 -11
  143. esphome/components/ili9xxx/ili9xxx_display.cpp +2 -5
  144. esphome/components/ili9xxx/ili9xxx_display.h +2 -1
  145. esphome/components/image/__init__.py +443 -255
  146. esphome/components/image/image.cpp +115 -61
  147. esphome/components/image/image.h +15 -24
  148. esphome/components/json/json_util.cpp +8 -34
  149. esphome/components/libretiny/__init__.py +1 -0
  150. esphome/components/libretiny/gpio_arduino.h +1 -0
  151. esphome/components/light/light_color_values.h +1 -1
  152. esphome/components/logger/__init__.py +45 -9
  153. esphome/components/logger/logger.cpp +16 -14
  154. esphome/components/logger/logger.h +11 -7
  155. esphome/components/logger/select/__init__.py +29 -0
  156. esphome/components/logger/select/logger_level_select.cpp +27 -0
  157. esphome/components/logger/select/logger_level_select.h +15 -0
  158. esphome/components/lvgl/__init__.py +96 -73
  159. esphome/components/lvgl/automation.py +39 -7
  160. esphome/components/lvgl/defines.py +8 -2
  161. esphome/components/lvgl/lvgl_esphome.cpp +8 -15
  162. esphome/components/lvgl/lvgl_esphome.h +20 -5
  163. esphome/components/lvgl/schemas.py +25 -14
  164. esphome/components/lvgl/trigger.py +27 -3
  165. esphome/components/lvgl/widgets/dropdown.py +1 -1
  166. esphome/components/lvgl/widgets/keyboard.py +8 -1
  167. esphome/components/lvgl/widgets/meter.py +2 -1
  168. esphome/components/lvgl/widgets/msgbox.py +1 -1
  169. esphome/components/lvgl/widgets/obj.py +1 -12
  170. esphome/components/lvgl/widgets/page.py +37 -2
  171. esphome/components/lvgl/widgets/tabview.py +1 -1
  172. esphome/components/max6956/max6956.h +2 -0
  173. esphome/components/mcp23016/mcp23016.h +2 -0
  174. esphome/components/mcp23xxx_base/mcp23xxx_base.h +2 -0
  175. esphome/components/mdns/__init__.py +1 -1
  176. esphome/components/media_player/__init__.py +37 -8
  177. esphome/components/media_player/automation.h +11 -2
  178. esphome/components/media_player/media_player.cpp +8 -0
  179. esphome/components/media_player/media_player.h +8 -4
  180. esphome/components/micronova/switch/micronova_switch.cpp +4 -2
  181. esphome/components/midea/ac_automations.h +3 -1
  182. esphome/components/midea/air_conditioner.cpp +7 -5
  183. esphome/components/midea/air_conditioner.h +1 -1
  184. esphome/components/midea/climate.py +4 -2
  185. esphome/components/midea/ir_transmitter.h +36 -5
  186. esphome/components/mixer/__init__.py +0 -0
  187. esphome/components/mixer/speaker/__init__.py +172 -0
  188. esphome/components/mixer/speaker/automation.h +19 -0
  189. esphome/components/mixer/speaker/mixer_speaker.cpp +624 -0
  190. esphome/components/mixer/speaker/mixer_speaker.h +207 -0
  191. esphome/components/modbus_controller/text_sensor/modbus_textsensor.cpp +7 -13
  192. esphome/components/mpr121/mpr121.h +2 -0
  193. esphome/components/mqtt/__init__.py +1 -1
  194. esphome/components/mqtt/mqtt_client.cpp +7 -1
  195. esphome/components/mqtt/mqtt_client.h +1 -1
  196. esphome/components/mqtt/mqtt_climate.cpp +2 -2
  197. esphome/components/network/ip_address.h +2 -0
  198. esphome/components/nextion/automation.h +17 -0
  199. esphome/components/nextion/display.py +42 -17
  200. esphome/components/nextion/nextion.cpp +4 -10
  201. esphome/components/nextion/nextion.h +89 -82
  202. esphome/components/nextion/nextion_commands.cpp +10 -10
  203. esphome/components/ntc/sensor.py +2 -4
  204. esphome/components/online_image/__init__.py +98 -46
  205. esphome/components/online_image/bmp_image.cpp +101 -0
  206. esphome/components/online_image/bmp_image.h +40 -0
  207. esphome/components/online_image/image_decoder.cpp +31 -2
  208. esphome/components/online_image/image_decoder.h +24 -15
  209. esphome/components/online_image/jpeg_image.cpp +92 -0
  210. esphome/components/online_image/jpeg_image.h +34 -0
  211. esphome/components/online_image/online_image.cpp +118 -58
  212. esphome/components/online_image/online_image.h +39 -9
  213. esphome/components/online_image/png_image.cpp +7 -3
  214. esphome/components/online_image/png_image.h +2 -1
  215. esphome/components/opentherm/__init__.py +73 -7
  216. esphome/components/opentherm/automation.h +25 -0
  217. esphome/components/opentherm/const.py +1 -0
  218. esphome/components/opentherm/generate.py +39 -6
  219. esphome/components/opentherm/hub.cpp +117 -79
  220. esphome/components/opentherm/hub.h +31 -15
  221. esphome/components/opentherm/opentherm.cpp +47 -23
  222. esphome/components/opentherm/opentherm.h +27 -6
  223. esphome/components/opentherm/opentherm_macros.h +11 -0
  224. esphome/components/opentherm/schema.py +78 -1
  225. esphome/components/opentherm/validate.py +7 -2
  226. esphome/components/pca6416a/pca6416a.h +2 -0
  227. esphome/components/pca9554/pca9554.h +2 -0
  228. esphome/components/pcf8574/pcf8574.h +2 -0
  229. esphome/components/preferences/__init__.py +2 -4
  230. esphome/components/preferences/syncer.h +10 -3
  231. esphome/components/prometheus/prometheus_handler.cpp +313 -0
  232. esphome/components/prometheus/prometheus_handler.h +48 -7
  233. esphome/components/psram/psram.cpp +8 -1
  234. esphome/components/pulse_counter/pulse_counter_sensor.cpp +14 -9
  235. esphome/components/pulse_counter/pulse_counter_sensor.h +4 -4
  236. esphome/components/pulse_meter/pulse_meter_sensor.cpp +2 -0
  237. esphome/components/qspi_dbi/__init__.py +3 -0
  238. esphome/components/qspi_dbi/display.py +74 -47
  239. esphome/components/qspi_dbi/models.py +245 -2
  240. esphome/components/qspi_dbi/qspi_dbi.cpp +9 -16
  241. esphome/components/qspi_dbi/qspi_dbi.h +2 -2
  242. esphome/components/remote_base/__init__.py +77 -25
  243. esphome/components/remote_base/remote_base.cpp +1 -1
  244. esphome/components/remote_base/remote_base.h +20 -2
  245. esphome/components/remote_base/toto_protocol.cpp +100 -0
  246. esphome/components/remote_base/toto_protocol.h +45 -0
  247. esphome/components/remote_receiver/__init__.py +55 -10
  248. esphome/components/remote_receiver/remote_receiver.h +36 -3
  249. esphome/components/remote_receiver/remote_receiver_esp32.cpp +145 -6
  250. esphome/components/remote_transmitter/__init__.py +62 -4
  251. esphome/components/remote_transmitter/remote_transmitter.h +21 -2
  252. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +140 -4
  253. esphome/components/remote_transmitter/remote_transmitter_esp8266.cpp +3 -3
  254. esphome/components/remote_transmitter/remote_transmitter_libretiny.cpp +3 -3
  255. esphome/components/resampler/__init__.py +0 -0
  256. esphome/components/resampler/speaker/__init__.py +103 -0
  257. esphome/components/resampler/speaker/resampler_speaker.cpp +318 -0
  258. esphome/components/resampler/speaker/resampler_speaker.h +107 -0
  259. esphome/components/resistance/resistance_sensor.h +2 -3
  260. esphome/components/resistance/sensor.py +2 -9
  261. esphome/components/rotary_encoder/rotary_encoder.cpp +8 -4
  262. esphome/components/rp2040/__init__.py +1 -0
  263. esphome/components/rp2040/gpio.h +1 -0
  264. esphome/components/rtl87xx/__init__.py +2 -0
  265. esphome/components/scd30/sensor.py +1 -1
  266. esphome/components/sdl/binary_sensor.py +270 -0
  267. esphome/components/sdl/sdl_esphome.cpp +16 -0
  268. esphome/components/sdl/sdl_esphome.h +9 -0
  269. esphome/components/seeed_mr60bha2/binary_sensor.py +25 -0
  270. esphome/components/seeed_mr60bha2/seeed_mr60bha2.cpp +26 -2
  271. esphome/components/seeed_mr60bha2/seeed_mr60bha2.h +9 -20
  272. esphome/components/seeed_mr60bha2/sensor.py +9 -1
  273. esphome/components/sn74hc165/sn74hc165.h +3 -0
  274. esphome/components/sn74hc595/sn74hc595.h +3 -0
  275. esphome/components/speaker/__init__.py +5 -4
  276. esphome/components/speaker/media_player/__init__.py +458 -0
  277. esphome/components/speaker/media_player/audio_pipeline.cpp +568 -0
  278. esphome/components/speaker/media_player/audio_pipeline.h +159 -0
  279. esphome/components/speaker/media_player/automation.h +26 -0
  280. esphome/components/speaker/media_player/speaker_media_player.cpp +577 -0
  281. esphome/components/speaker/media_player/speaker_media_player.h +160 -0
  282. esphome/components/speaker/speaker.h +20 -0
  283. esphome/components/spi/__init__.py +1 -5
  284. esphome/components/spi/spi.cpp +7 -1
  285. esphome/components/spi/spi.h +21 -2
  286. esphome/components/spi_led_strip/light.py +3 -5
  287. esphome/components/spi_led_strip/spi_led_strip.cpp +67 -0
  288. esphome/components/spi_led_strip/spi_led_strip.h +8 -60
  289. esphome/components/sprinkler/sprinkler.cpp +3 -1
  290. esphome/components/sx1509/sx1509_gpio_pin.h +2 -0
  291. esphome/components/tca9555/tca9555.h +2 -0
  292. esphome/components/toshiba/toshiba.cpp +2 -1
  293. esphome/components/tuya/light/tuya_light.cpp +4 -2
  294. esphome/components/uart/uart_component_esp32_arduino.cpp +2 -2
  295. esphome/components/uart/uart_component_esp_idf.cpp +2 -2
  296. esphome/components/udp/__init__.py +8 -2
  297. esphome/components/udp/udp_component.cpp +25 -56
  298. esphome/components/udp/udp_component.h +3 -0
  299. esphome/components/uponor_smatrix/sensor/__init__.py +14 -4
  300. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.cpp +5 -0
  301. esphome/components/uponor_smatrix/sensor/uponor_smatrix_sensor.h +1 -0
  302. esphome/components/uptime/text_sensor/__init__.py +19 -0
  303. esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +63 -0
  304. esphome/components/uptime/text_sensor/uptime_text_sensor.h +25 -0
  305. esphome/components/voice_assistant/voice_assistant.cpp +24 -14
  306. esphome/components/voice_assistant/voice_assistant.h +8 -0
  307. esphome/components/waveshare_epaper/display.py +22 -1
  308. esphome/components/waveshare_epaper/waveshare_213v3.cpp +9 -3
  309. esphome/components/waveshare_epaper/waveshare_epaper.cpp +1155 -44
  310. esphome/components/waveshare_epaper/waveshare_epaper.h +208 -7
  311. esphome/components/web_server/web_server.cpp +28 -6
  312. esphome/components/weikai/weikai.h +2 -0
  313. esphome/components/wifi/__init__.py +6 -6
  314. esphome/components/wifi/wifi_component.cpp +1 -1
  315. esphome/components/wifi/wifi_component_esp32_arduino.cpp +30 -1
  316. esphome/components/wireguard/__init__.py +2 -2
  317. esphome/components/xl9535/xl9535.h +2 -0
  318. esphome/components/xxtea/__init__.py +3 -0
  319. esphome/components/xxtea/xxtea.cpp +46 -0
  320. esphome/components/xxtea/xxtea.h +26 -0
  321. esphome/components/yashima/yashima.cpp +2 -1
  322. esphome/config.py +9 -5
  323. esphome/config_validation.py +55 -17
  324. esphome/const.py +7 -10
  325. esphome/core/__init__.py +6 -13
  326. esphome/core/base_automation.h +1 -0
  327. esphome/core/config.py +59 -72
  328. esphome/core/defines.h +9 -1
  329. esphome/core/gpio.h +7 -0
  330. esphome/core/helpers.cpp +19 -15
  331. esphome/core/helpers.h +57 -8
  332. esphome/core/log.h +9 -7
  333. esphome/cpp_generator.py +2 -2
  334. esphome/dashboard/web_server.py +1 -1
  335. esphome/espota2.py +3 -2
  336. esphome/loader.py +12 -4
  337. esphome/log.py +5 -7
  338. esphome/yaml_util.py +2 -2
  339. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/METADATA +14 -9
  340. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/RECORD +349 -300
  341. esphome/components/custom/binary_sensor/custom_binary_sensor.cpp +0 -16
  342. esphome/components/custom/binary_sensor/custom_binary_sensor.h +0 -26
  343. esphome/components/custom/climate/custom_climate.h +0 -22
  344. esphome/components/custom/cover/custom_cover.h +0 -21
  345. esphome/components/custom/light/custom_light_output.h +0 -24
  346. esphome/components/custom/output/custom_output.h +0 -37
  347. esphome/components/custom/sensor/custom_sensor.cpp +0 -16
  348. esphome/components/custom/sensor/custom_sensor.h +0 -24
  349. esphome/components/custom/switch/custom_switch.cpp +0 -16
  350. esphome/components/custom/switch/custom_switch.h +0 -24
  351. esphome/components/custom/text_sensor/custom_text_sensor.cpp +0 -16
  352. esphome/components/custom/text_sensor/custom_text_sensor.h +0 -26
  353. esphome/components/custom_component/custom_component.h +0 -28
  354. esphome/components/esp32_ble_server/ble_2901.cpp +0 -18
  355. esphome/components/esp32_ble_server/ble_2901.h +0 -19
  356. esphome/components/resistance_sampler/__init__.py +0 -6
  357. esphome/components/resistance_sampler/resistance_sampler.h +0 -10
  358. esphome/components/uptime/{sensor.py → sensor/__init__.py} +3 -3
  359. /esphome/components/uptime/{uptime_seconds_sensor.cpp → sensor/uptime_seconds_sensor.cpp} +0 -0
  360. /esphome/components/uptime/{uptime_seconds_sensor.h → sensor/uptime_seconds_sensor.h} +0 -0
  361. /esphome/components/uptime/{uptime_timestamp_sensor.cpp → sensor/uptime_timestamp_sensor.cpp} +0 -0
  362. /esphome/components/uptime/{uptime_timestamp_sensor.h → sensor/uptime_timestamp_sensor.h} +0 -0
  363. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/LICENSE +0 -0
  364. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/WHEEL +0 -0
  365. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/entry_points.txt +0 -0
  366. {esphome-2024.12.4.dist-info → esphome-2025.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,29 @@
1
+ import esphome.codegen as cg
2
+ from esphome.components import select
3
+ import esphome.config_validation as cv
4
+ from esphome.const import CONF_LEVEL, CONF_LOGGER, ENTITY_CATEGORY_CONFIG, ICON_BUG
5
+ from esphome.core import CORE
6
+ from esphome.cpp_helpers import register_component, register_parented
7
+
8
+ from .. import CONF_LOGGER_ID, LOG_LEVEL_SEVERITY, Logger, logger_ns
9
+
10
+ CODEOWNERS = ["@clydebarrow"]
11
+
12
+ LoggerLevelSelect = logger_ns.class_("LoggerLevelSelect", select.Select, cg.Component)
13
+
14
+ CONFIG_SCHEMA = select.select_schema(
15
+ LoggerLevelSelect, icon=ICON_BUG, entity_category=ENTITY_CATEGORY_CONFIG
16
+ ).extend(
17
+ {
18
+ cv.GenerateID(CONF_LOGGER_ID): cv.use_id(Logger),
19
+ }
20
+ )
21
+
22
+
23
+ async def to_code(config):
24
+ levels = LOG_LEVEL_SEVERITY
25
+ index = levels.index(CORE.config[CONF_LOGGER][CONF_LEVEL])
26
+ levels = levels[: index + 1]
27
+ var = await select.new_select(config, options=levels)
28
+ await register_parented(var, config[CONF_LOGGER_ID])
29
+ await register_component(var, config)
@@ -0,0 +1,27 @@
1
+ #include "logger_level_select.h"
2
+
3
+ namespace esphome {
4
+ namespace logger {
5
+
6
+ void LoggerLevelSelect::publish_state(int level) {
7
+ auto value = this->at(level);
8
+ if (!value) {
9
+ return;
10
+ }
11
+ Select::publish_state(value.value());
12
+ }
13
+
14
+ void LoggerLevelSelect::setup() {
15
+ this->parent_->add_listener([this](int level) { this->publish_state(level); });
16
+ this->publish_state(this->parent_->get_log_level());
17
+ }
18
+
19
+ void LoggerLevelSelect::control(const std::string &value) {
20
+ auto level = this->index_of(value);
21
+ if (!level)
22
+ return;
23
+ this->parent_->set_log_level(level.value());
24
+ }
25
+
26
+ } // namespace logger
27
+ } // namespace esphome
@@ -0,0 +1,15 @@
1
+ #pragma once
2
+
3
+ #include "esphome/components/select/select.h"
4
+ #include "esphome/core/component.h"
5
+ #include "esphome/components/logger/logger.h"
6
+ namespace esphome {
7
+ namespace logger {
8
+ class LoggerLevelSelect : public Component, public select::Select, public Parented<Logger> {
9
+ public:
10
+ void publish_state(int level);
11
+ void setup() override;
12
+ void control(const std::string &value) override;
13
+ };
14
+ } // namespace logger
15
+ } // namespace esphome
@@ -23,7 +23,7 @@ from esphome.helpers import write_file_if_changed
23
23
 
24
24
  from . import defines as df, helpers, lv_validation as lvalid
25
25
  from .automation import disp_update, focused_widgets, update_to_code
26
- from .defines import add_define
26
+ from .defines import CONF_DRAW_ROUNDING, add_define
27
27
  from .encoders import (
28
28
  ENCODERS_CONFIG,
29
29
  encoders_to_code,
@@ -61,7 +61,14 @@ from .types import (
61
61
  lv_style_t,
62
62
  lvgl_ns,
63
63
  )
64
- from .widgets import Widget, add_widgets, get_scr_act, set_obj_properties, styles_used
64
+ from .widgets import (
65
+ LvScrActType,
66
+ Widget,
67
+ add_widgets,
68
+ get_scr_act,
69
+ set_obj_properties,
70
+ styles_used,
71
+ )
65
72
  from .widgets.animimg import animimg_spec
66
73
  from .widgets.arc import arc_spec
67
74
  from .widgets.button import button_spec
@@ -197,14 +204,18 @@ def final_validation(configs):
197
204
  for display_id in config[df.CONF_DISPLAYS]:
198
205
  path = global_config.get_path_for_id(display_id)[:-1]
199
206
  display = global_config.get_config_for_path(path)
200
- if CONF_LAMBDA in display:
207
+ if CONF_LAMBDA in display or CONF_PAGES in display:
201
208
  raise cv.Invalid(
202
- "Using lambda: in display config not compatible with LVGL"
209
+ "Using lambda: or pages: in display config is not compatible with LVGL"
203
210
  )
204
- if display[CONF_AUTO_CLEAR_ENABLED]:
211
+ if display.get(CONF_AUTO_CLEAR_ENABLED) is True:
205
212
  raise cv.Invalid(
206
213
  "Using auto_clear_enabled: true in display config not compatible with LVGL"
207
214
  )
215
+ if draw_rounding := display.get(CONF_DRAW_ROUNDING):
216
+ config[CONF_DRAW_ROUNDING] = max(
217
+ draw_rounding, config[CONF_DRAW_ROUNDING]
218
+ )
208
219
  buffer_frac = config[CONF_BUFFER_SIZE]
209
220
  if CORE.is_esp32 and buffer_frac > 0.5 and "psram" not in global_config:
210
221
  LOGGER.warning("buffer_size: may need to be reduced without PSRAM")
@@ -314,7 +325,7 @@ async def to_code(configs):
314
325
  config[df.CONF_RESUME_ON_INPUT],
315
326
  )
316
327
  await cg.register_component(lv_component, config)
317
- Widget.create(config[CONF_ID], lv_component, obj_spec, config)
328
+ Widget.create(config[CONF_ID], lv_component, LvScrActType(), config)
318
329
 
319
330
  lv_scr_act = get_scr_act(lv_component)
320
331
  async with LvContext():
@@ -385,75 +396,87 @@ def add_hello_world(config):
385
396
 
386
397
  FINAL_VALIDATE_SCHEMA = final_validation
387
398
 
388
- LVGL_SCHEMA = (
389
- cv.polling_component_schema("1s")
390
- .extend(obj_schema(obj_spec))
391
- .extend(
392
- {
393
- cv.GenerateID(CONF_ID): cv.declare_id(LvglComponent),
394
- cv.GenerateID(df.CONF_DISPLAYS): display_schema,
395
- cv.Optional(df.CONF_COLOR_DEPTH, default=16): cv.one_of(16),
396
- cv.Optional(df.CONF_DEFAULT_FONT, default="montserrat_14"): lvalid.lv_font,
397
- cv.Optional(df.CONF_FULL_REFRESH, default=False): cv.boolean,
398
- cv.Optional(df.CONF_DRAW_ROUNDING, default=2): cv.positive_int,
399
- cv.Optional(CONF_BUFFER_SIZE, default="100%"): cv.percentage,
400
- cv.Optional(df.CONF_LOG_LEVEL, default="WARN"): cv.one_of(
401
- *df.LV_LOG_LEVELS, upper=True
402
- ),
403
- cv.Optional(df.CONF_BYTE_ORDER, default="big_endian"): cv.one_of(
404
- "big_endian", "little_endian"
405
- ),
406
- cv.Optional(df.CONF_STYLE_DEFINITIONS): cv.ensure_list(
407
- cv.Schema({cv.Required(CONF_ID): cv.declare_id(lv_style_t)})
408
- .extend(STYLE_SCHEMA)
409
- .extend(
399
+ LVGL_SCHEMA = cv.All(
400
+ container_schema(
401
+ obj_spec,
402
+ cv.polling_component_schema("1s")
403
+ .extend(
404
+ {
405
+ cv.GenerateID(CONF_ID): cv.declare_id(LvglComponent),
406
+ cv.GenerateID(df.CONF_DISPLAYS): display_schema,
407
+ cv.Optional(df.CONF_COLOR_DEPTH, default=16): cv.one_of(16),
408
+ cv.Optional(
409
+ df.CONF_DEFAULT_FONT, default="montserrat_14"
410
+ ): lvalid.lv_font,
411
+ cv.Optional(df.CONF_FULL_REFRESH, default=False): cv.boolean,
412
+ cv.Optional(df.CONF_DRAW_ROUNDING, default=2): cv.positive_int,
413
+ cv.Optional(CONF_BUFFER_SIZE, default="100%"): cv.percentage,
414
+ cv.Optional(df.CONF_LOG_LEVEL, default="WARN"): cv.one_of(
415
+ *df.LV_LOG_LEVELS, upper=True
416
+ ),
417
+ cv.Optional(df.CONF_BYTE_ORDER, default="big_endian"): cv.one_of(
418
+ "big_endian", "little_endian"
419
+ ),
420
+ cv.Optional(df.CONF_STYLE_DEFINITIONS): cv.ensure_list(
421
+ cv.Schema({cv.Required(CONF_ID): cv.declare_id(lv_style_t)})
422
+ .extend(STYLE_SCHEMA)
423
+ .extend(
424
+ {
425
+ cv.Optional(df.CONF_GRID_CELL_X_ALIGN): grid_alignments,
426
+ cv.Optional(df.CONF_GRID_CELL_Y_ALIGN): grid_alignments,
427
+ cv.Optional(df.CONF_PAD_ROW): lvalid.pixels,
428
+ cv.Optional(df.CONF_PAD_COLUMN): lvalid.pixels,
429
+ }
430
+ )
431
+ ),
432
+ cv.Optional(CONF_ON_IDLE): validate_automation(
410
433
  {
411
- cv.Optional(df.CONF_GRID_CELL_X_ALIGN): grid_alignments,
412
- cv.Optional(df.CONF_GRID_CELL_Y_ALIGN): grid_alignments,
413
- cv.Optional(df.CONF_PAD_ROW): lvalid.pixels,
414
- cv.Optional(df.CONF_PAD_COLUMN): lvalid.pixels,
434
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(IdleTrigger),
435
+ cv.Required(CONF_TIMEOUT): cv.templatable(
436
+ cv.positive_time_period_milliseconds
437
+ ),
415
438
  }
416
- )
417
- ),
418
- cv.Optional(CONF_ON_IDLE): validate_automation(
419
- {
420
- cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(IdleTrigger),
421
- cv.Required(CONF_TIMEOUT): cv.templatable(
422
- cv.positive_time_period_milliseconds
423
- ),
424
- }
425
- ),
426
- cv.Optional(df.CONF_ON_PAUSE): validate_automation(
427
- {
428
- cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PauseTrigger),
429
- }
430
- ),
431
- cv.Optional(df.CONF_ON_RESUME): validate_automation(
432
- {
433
- cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PauseTrigger),
434
- }
435
- ),
436
- cv.Exclusive(df.CONF_WIDGETS, CONF_PAGES): cv.ensure_list(WIDGET_SCHEMA),
437
- cv.Exclusive(CONF_PAGES, CONF_PAGES): cv.ensure_list(
438
- container_schema(page_spec)
439
- ),
440
- cv.Optional(df.CONF_MSGBOXES): cv.ensure_list(MSGBOX_SCHEMA),
441
- cv.Optional(df.CONF_PAGE_WRAP, default=True): lv_bool,
442
- cv.Optional(df.CONF_TOP_LAYER): container_schema(obj_spec),
443
- cv.Optional(df.CONF_TRANSPARENCY_KEY, default=0x000400): lvalid.lv_color,
444
- cv.Optional(df.CONF_THEME): cv.Schema(
445
- {cv.Optional(name): obj_schema(w) for name, w in WIDGET_TYPES.items()}
446
- ),
447
- cv.Optional(df.CONF_GRADIENTS): GRADIENT_SCHEMA,
448
- cv.Optional(df.CONF_TOUCHSCREENS, default=None): touchscreen_schema,
449
- cv.Optional(df.CONF_ENCODERS, default=None): ENCODERS_CONFIG,
450
- cv.Optional(df.CONF_KEYPADS, default=None): KEYPADS_CONFIG,
451
- cv.GenerateID(df.CONF_DEFAULT_GROUP): cv.declare_id(lv_group_t),
452
- cv.Optional(df.CONF_RESUME_ON_INPUT, default=True): cv.boolean,
453
- }
454
- )
455
- .extend(DISP_BG_SCHEMA)
456
- .add_extra(add_hello_world)
439
+ ),
440
+ cv.Optional(df.CONF_ON_PAUSE): validate_automation(
441
+ {
442
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PauseTrigger),
443
+ }
444
+ ),
445
+ cv.Optional(df.CONF_ON_RESUME): validate_automation(
446
+ {
447
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PauseTrigger),
448
+ }
449
+ ),
450
+ cv.Exclusive(df.CONF_WIDGETS, CONF_PAGES): cv.ensure_list(
451
+ WIDGET_SCHEMA
452
+ ),
453
+ cv.Exclusive(CONF_PAGES, CONF_PAGES): cv.ensure_list(
454
+ container_schema(page_spec)
455
+ ),
456
+ cv.Optional(df.CONF_MSGBOXES): cv.ensure_list(MSGBOX_SCHEMA),
457
+ cv.Optional(df.CONF_PAGE_WRAP, default=True): lv_bool,
458
+ cv.Optional(df.CONF_TOP_LAYER): container_schema(obj_spec),
459
+ cv.Optional(
460
+ df.CONF_TRANSPARENCY_KEY, default=0x000400
461
+ ): lvalid.lv_color,
462
+ cv.Optional(df.CONF_THEME): cv.Schema(
463
+ {
464
+ cv.Optional(name): obj_schema(w)
465
+ for name, w in WIDGET_TYPES.items()
466
+ }
467
+ ),
468
+ cv.Optional(df.CONF_GRADIENTS): GRADIENT_SCHEMA,
469
+ cv.Optional(df.CONF_TOUCHSCREENS, default=None): touchscreen_schema,
470
+ cv.Optional(df.CONF_ENCODERS, default=None): ENCODERS_CONFIG,
471
+ cv.Optional(df.CONF_KEYPADS, default=None): KEYPADS_CONFIG,
472
+ cv.GenerateID(df.CONF_DEFAULT_GROUP): cv.declare_id(lv_group_t),
473
+ cv.Optional(df.CONF_RESUME_ON_INPUT, default=True): cv.boolean,
474
+ }
475
+ )
476
+ .extend(DISP_BG_SCHEMA),
477
+ ),
478
+ cv.has_at_most_one_key(CONF_PAGES, df.CONF_LAYOUT),
479
+ add_hello_world,
457
480
  )
458
481
 
459
482
 
@@ -4,24 +4,27 @@ from esphome import automation
4
4
  import esphome.codegen as cg
5
5
  import esphome.config_validation as cv
6
6
  from esphome.const import CONF_ACTION, CONF_GROUP, CONF_ID, CONF_TIMEOUT
7
- from esphome.cpp_generator import get_variable
7
+ from esphome.cpp_generator import TemplateArguments, get_variable
8
8
  from esphome.cpp_types import nullptr
9
9
 
10
10
  from .defines import (
11
11
  CONF_DISP_BG_COLOR,
12
12
  CONF_DISP_BG_IMAGE,
13
+ CONF_DISP_BG_OPA,
13
14
  CONF_EDITING,
14
15
  CONF_FREEZE,
15
16
  CONF_LVGL_ID,
16
17
  CONF_SHOW_SNOW,
18
+ PARTS,
17
19
  literal,
18
20
  )
19
- from .lv_validation import lv_bool, lv_color, lv_image
21
+ from .lv_validation import lv_bool, lv_color, lv_image, opacity
20
22
  from .lvcode import (
21
23
  LVGL_COMP_ARG,
22
24
  UPDATE_EVENT,
23
25
  LambdaContext,
24
26
  LocalVariable,
27
+ LvglComponent,
25
28
  ReturnStatement,
26
29
  add_line_marks,
27
30
  lv,
@@ -31,7 +34,7 @@ from .lvcode import (
31
34
  lvgl_comp,
32
35
  static_cast,
33
36
  )
34
- from .schemas import DISP_BG_SCHEMA, LIST_ACTION_SCHEMA, LVGL_SCHEMA
37
+ from .schemas import DISP_BG_SCHEMA, LIST_ACTION_SCHEMA, LVGL_SCHEMA, base_update_schema
35
38
  from .types import (
36
39
  LV_STATE,
37
40
  LvglAction,
@@ -39,6 +42,7 @@ from .types import (
39
42
  ObjUpdateAction,
40
43
  lv_disp_t,
41
44
  lv_group_t,
45
+ lv_obj_base_t,
42
46
  lv_obj_t,
43
47
  lv_pseudo_button_t,
44
48
  )
@@ -92,7 +96,11 @@ async def lvgl_is_paused(config, condition_id, template_arg, args):
92
96
  lvgl = config[CONF_LVGL_ID]
93
97
  async with LambdaContext(LVGL_COMP_ARG, return_type=cg.bool_) as context:
94
98
  lv_add(ReturnStatement(lvgl_comp.is_paused()))
95
- var = cg.new_Pvariable(condition_id, template_arg, await context.get_lambda())
99
+ var = cg.new_Pvariable(
100
+ condition_id,
101
+ TemplateArguments(LvglComponent, *template_arg),
102
+ await context.get_lambda(),
103
+ )
96
104
  await cg.register_parented(var, lvgl)
97
105
  return var
98
106
 
@@ -113,19 +121,32 @@ async def lvgl_is_idle(config, condition_id, template_arg, args):
113
121
  timeout = await cg.templatable(config[CONF_TIMEOUT], [], cg.uint32)
114
122
  async with LambdaContext(LVGL_COMP_ARG, return_type=cg.bool_) as context:
115
123
  lv_add(ReturnStatement(lvgl_comp.is_idle(timeout)))
116
- var = cg.new_Pvariable(condition_id, template_arg, await context.get_lambda())
124
+ var = cg.new_Pvariable(
125
+ condition_id,
126
+ TemplateArguments(LvglComponent, *template_arg),
127
+ await context.get_lambda(),
128
+ )
117
129
  await cg.register_parented(var, lvgl)
118
130
  return var
119
131
 
120
132
 
121
133
  async def disp_update(disp, config: dict):
122
- if CONF_DISP_BG_COLOR not in config and CONF_DISP_BG_IMAGE not in config:
134
+ if (
135
+ CONF_DISP_BG_COLOR not in config
136
+ and CONF_DISP_BG_IMAGE not in config
137
+ and CONF_DISP_BG_OPA not in config
138
+ ):
123
139
  return
124
140
  with LocalVariable("lv_disp_tmp", lv_disp_t, disp) as disp_temp:
125
141
  if (bg_color := config.get(CONF_DISP_BG_COLOR)) is not None:
126
142
  lv.disp_set_bg_color(disp_temp, await lv_color.process(bg_color))
127
143
  if bg_image := config.get(CONF_DISP_BG_IMAGE):
128
- lv.disp_set_bg_image(disp_temp, await lv_image.process(bg_image))
144
+ if bg_image == "none":
145
+ lv.disp_set_bg_image(disp_temp, static_cast("void *", "nullptr"))
146
+ else:
147
+ lv.disp_set_bg_image(disp_temp, await lv_image.process(bg_image))
148
+ if (bg_opa := config.get(CONF_DISP_BG_OPA)) is not None:
149
+ lv.disp_set_bg_opa(disp_temp, await opacity.process(bg_opa))
129
150
 
130
151
 
131
152
  @automation.register_action(
@@ -317,3 +338,14 @@ async def widget_focus(config, action_id, template_arg, args):
317
338
  lv.group_focus_freeze(group, True)
318
339
  var = cg.new_Pvariable(action_id, template_arg, await context.get_lambda())
319
340
  return var
341
+
342
+
343
+ @automation.register_action(
344
+ "lvgl.widget.update", ObjUpdateAction, base_update_schema(lv_obj_base_t, PARTS)
345
+ )
346
+ async def obj_update_to_code(config, action_id, template_arg, args):
347
+ async def do_update(widget: Widget):
348
+ await set_obj_properties(widget, config)
349
+
350
+ widgets = await get_widgets(config[CONF_ID])
351
+ return await action_to_code(widgets, do_update, action_id, template_arg, args)
@@ -146,6 +146,8 @@ TYPE_FLEX = "flex"
146
146
  TYPE_GRID = "grid"
147
147
  TYPE_NONE = "none"
148
148
 
149
+ DIRECTIONS = LvConstant("LV_DIR_", "LEFT", "RIGHT", "BOTTOM", "TOP")
150
+
149
151
  LV_FONTS = list(f"montserrat_{s}" for s in range(8, 50, 2)) + [
150
152
  "dejavu_16_persian_hebrew",
151
153
  "simsun_16_cjk",
@@ -169,9 +171,13 @@ LV_EVENT_MAP = {
169
171
  "CANCEL": "CANCEL",
170
172
  "ALL_EVENTS": "ALL",
171
173
  "CHANGE": "VALUE_CHANGED",
174
+ "GESTURE": "GESTURE",
172
175
  }
173
176
 
174
177
  LV_EVENT_TRIGGERS = tuple(f"on_{x.lower()}" for x in LV_EVENT_MAP)
178
+ SWIPE_TRIGGERS = tuple(
179
+ f"on_swipe_{x.lower()}" for x in DIRECTIONS.choices + ("up", "down")
180
+ )
175
181
 
176
182
 
177
183
  LV_ANIM = LvConstant(
@@ -215,7 +221,7 @@ LV_LONG_MODES = LvConstant(
215
221
  )
216
222
 
217
223
  STATES = (
218
- "default",
224
+ # default state not included here
219
225
  "checked",
220
226
  "focused",
221
227
  "focus_key",
@@ -250,7 +256,6 @@ KEYBOARD_MODES = LvConstant(
250
256
  "NUMBER",
251
257
  )
252
258
  ROLLER_MODES = LvConstant("LV_ROLLER_MODE_", "NORMAL", "INFINITE")
253
- DIRECTIONS = LvConstant("LV_DIR_", "LEFT", "RIGHT", "BOTTOM", "TOP")
254
259
  TILE_DIRECTIONS = DIRECTIONS.extend("HOR", "VER", "ALL")
255
260
  CHILD_ALIGNMENTS = LvConstant(
256
261
  "LV_ALIGN_",
@@ -403,6 +408,7 @@ CONF_COLUMN = "column"
403
408
  CONF_DIGITS = "digits"
404
409
  CONF_DISP_BG_COLOR = "disp_bg_color"
405
410
  CONF_DISP_BG_IMAGE = "disp_bg_image"
411
+ CONF_DISP_BG_OPA = "disp_bg_opa"
406
412
  CONF_BODY = "body"
407
413
  CONF_BUTTONS = "buttons"
408
414
  CONF_BYTE_ORDER = "byte_order"
@@ -119,6 +119,7 @@ void LvglComponent::add_event_cb(lv_obj_t *obj, event_callback_t callback, lv_ev
119
119
  }
120
120
  void LvglComponent::add_page(LvPageType *page) {
121
121
  this->pages_.push_back(page);
122
+ page->set_parent(this);
122
123
  page->setup(this->pages_.size() - 1);
123
124
  }
124
125
  void LvglComponent::show_page(size_t index, lv_scr_load_anim_t anim, uint32_t time) {
@@ -143,6 +144,8 @@ void LvglComponent::show_prev_page(lv_scr_load_anim_t anim, uint32_t time) {
143
144
  } while (this->pages_[this->current_page_]->skip); // skip empty pages()
144
145
  this->show_page(this->current_page_, anim, time);
145
146
  }
147
+ size_t LvglComponent::get_current_page() const { return this->current_page_; }
148
+ bool LvPageType::is_showing() const { return this->parent_->get_current_page() == this->index; }
146
149
  void LvglComponent::draw_buffer_(const lv_area_t *area, lv_color_t *ptr) {
147
150
  auto width = lv_area_get_width(area);
148
151
  auto height = lv_area_get_height(area);
@@ -498,9 +501,7 @@ size_t lv_millis(void) { return esphome::millis(); }
498
501
  void *lv_custom_mem_alloc(size_t size) {
499
502
  auto *ptr = malloc(size); // NOLINT
500
503
  if (ptr == nullptr) {
501
- #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_ERROR
502
- esphome::ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
503
- #endif
504
+ ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
504
505
  }
505
506
  return ptr;
506
507
  }
@@ -517,30 +518,22 @@ void *lv_custom_mem_alloc(size_t size) {
517
518
  ptr = heap_caps_malloc(size, cap_bits);
518
519
  }
519
520
  if (ptr == nullptr) {
520
- #if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_ERROR
521
- esphome::ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
522
- #endif
521
+ ESP_LOGE(esphome::lvgl::TAG, "Failed to allocate %zu bytes", size);
523
522
  return nullptr;
524
523
  }
525
- #ifdef ESPHOME_LOG_HAS_VERBOSE
526
- esphome::ESP_LOGV(esphome::lvgl::TAG, "allocate %zu - > %p", size, ptr);
527
- #endif
524
+ ESP_LOGV(esphome::lvgl::TAG, "allocate %zu - > %p", size, ptr);
528
525
  return ptr;
529
526
  }
530
527
 
531
528
  void lv_custom_mem_free(void *ptr) {
532
- #ifdef ESPHOME_LOG_HAS_VERBOSE
533
- esphome::ESP_LOGV(esphome::lvgl::TAG, "free %p", ptr);
534
- #endif
529
+ ESP_LOGV(esphome::lvgl::TAG, "free %p", ptr);
535
530
  if (ptr == nullptr)
536
531
  return;
537
532
  heap_caps_free(ptr);
538
533
  }
539
534
 
540
535
  void *lv_custom_mem_realloc(void *ptr, size_t size) {
541
- #ifdef ESPHOME_LOG_HAS_VERBOSE
542
- esphome::ESP_LOGV(esphome::lvgl::TAG, "realloc %p: %zu", ptr, size);
543
- #endif
536
+ ESP_LOGV(esphome::lvgl::TAG, "realloc %p: %zu", ptr, size);
544
537
  return heap_caps_realloc(ptr, size, cap_bits);
545
538
  }
546
539
  #endif
@@ -59,6 +59,16 @@ inline void lv_img_set_src(lv_obj_t *obj, esphome::image::Image *image) {
59
59
  inline void lv_disp_set_bg_image(lv_disp_t *disp, esphome::image::Image *image) {
60
60
  lv_disp_set_bg_image(disp, image->get_lv_img_dsc());
61
61
  }
62
+
63
+ inline void lv_obj_set_style_bg_img_src(lv_obj_t *obj, esphome::image::Image *image, lv_style_selector_t selector) {
64
+ lv_obj_set_style_bg_img_src(obj, image->get_lv_img_dsc(), selector);
65
+ }
66
+ #ifdef USE_LVGL_METER
67
+ inline lv_meter_indicator_t *lv_meter_add_needle_img(lv_obj_t *obj, lv_meter_scale_t *scale, esphome::image::Image *src,
68
+ lv_coord_t pivot_x, lv_coord_t pivot_y) {
69
+ return lv_meter_add_needle_img(obj, scale, src->get_lv_img_dsc(), pivot_x, pivot_y);
70
+ }
71
+ #endif // USE_LVGL_METER
62
72
  #endif // USE_LVGL_IMAGE
63
73
  #ifdef USE_LVGL_ANIMIMG
64
74
  inline void lv_animimg_set_src(lv_obj_t *img, std::vector<image::Image *> images) {
@@ -84,7 +94,9 @@ class LvCompound {
84
94
  lv_obj_t *obj{};
85
95
  };
86
96
 
87
- class LvPageType {
97
+ class LvglComponent;
98
+
99
+ class LvPageType : public Parented<LvglComponent> {
88
100
  public:
89
101
  LvPageType(bool skip) : skip(skip) {}
90
102
 
@@ -92,6 +104,9 @@ class LvPageType {
92
104
  this->index = index;
93
105
  this->obj = lv_obj_create(nullptr);
94
106
  }
107
+
108
+ bool is_showing() const;
109
+
95
110
  lv_obj_t *obj{};
96
111
  size_t index{};
97
112
  bool skip;
@@ -178,6 +193,7 @@ class LvglComponent : public PollingComponent {
178
193
  void show_next_page(lv_scr_load_anim_t anim, uint32_t time);
179
194
  void show_prev_page(lv_scr_load_anim_t anim, uint32_t time);
180
195
  void set_page_wrap(bool wrap) { this->page_wrap_ = wrap; }
196
+ size_t get_current_page() const;
181
197
  void set_focus_mark(lv_group_t *group) { this->focus_marks_[group] = lv_group_get_focused(group); }
182
198
  void restore_focus_mark(lv_group_t *group) {
183
199
  auto *mark = this->focus_marks_[group];
@@ -241,14 +257,13 @@ template<typename... Ts> class LvglAction : public Action<Ts...>, public Parente
241
257
  std::function<void(LvglComponent *)> action_{};
242
258
  };
243
259
 
244
- template<typename... Ts> class LvglCondition : public Condition<Ts...>, public Parented<LvglComponent> {
260
+ template<typename Tc, typename... Ts> class LvglCondition : public Condition<Ts...>, public Parented<Tc> {
245
261
  public:
246
- LvglCondition(std::function<bool(LvglComponent *)> &&condition_lambda)
247
- : condition_lambda_(std::move(condition_lambda)) {}
262
+ LvglCondition(std::function<bool(Tc *)> &&condition_lambda) : condition_lambda_(std::move(condition_lambda)) {}
248
263
  bool check(Ts... x) override { return this->condition_lambda_(this->parent_); }
249
264
 
250
265
  protected:
251
- std::function<bool(LvglComponent *)> condition_lambda_{};
266
+ std::function<bool(Tc *)> condition_lambda_{};
252
267
  };
253
268
 
254
269
  #ifdef USE_LVGL_TOUCHSCREEN
@@ -19,7 +19,7 @@ from esphome.schema_extractors import SCHEMA_EXTRACT
19
19
  from . import defines as df, lv_validation as lvalid
20
20
  from .defines import CONF_TIME_FORMAT, LV_GRAD_DIR
21
21
  from .helpers import add_lv_use, requires_component, validate_printf
22
- from .lv_validation import lv_color, lv_font, lv_gradient, lv_image
22
+ from .lv_validation import lv_color, lv_font, lv_gradient, lv_image, opacity
23
23
  from .lvcode import LvglComponent, lv_event_t_ptr
24
24
  from .types import (
25
25
  LVEncoderListener,
@@ -199,23 +199,21 @@ FLAG_SCHEMA = cv.Schema({cv.Optional(flag): lvalid.lv_bool for flag in df.OBJ_FL
199
199
  FLAG_LIST = cv.ensure_list(df.LvConstant("LV_OBJ_FLAG_", *df.OBJ_FLAGS).one_of)
200
200
 
201
201
 
202
- def part_schema(widget_type: WidgetType):
202
+ def part_schema(parts):
203
203
  """
204
204
  Generate a schema for the various parts (e.g. main:, indicator:) of a widget type
205
- :param widget_type: The type of widget to generate for
206
- :return:
205
+ :param parts: The parts to include in the schema
206
+ :return: The schema
207
207
  """
208
- parts = widget_type.parts
209
208
  return cv.Schema({cv.Optional(part): STATE_SCHEMA for part in parts}).extend(
210
209
  STATE_SCHEMA
211
210
  )
212
211
 
213
212
 
214
213
  def automation_schema(typ: LvType):
214
+ events = df.LV_EVENT_TRIGGERS + df.SWIPE_TRIGGERS
215
215
  if typ.has_on_value:
216
- events = df.LV_EVENT_TRIGGERS + (CONF_ON_VALUE,)
217
- else:
218
- events = df.LV_EVENT_TRIGGERS
216
+ events = events + (CONF_ON_VALUE,)
219
217
  args = typ.get_arg_type() if isinstance(typ, LvType) else []
220
218
  args.append(lv_event_t_ptr)
221
219
  return {
@@ -228,9 +226,15 @@ def automation_schema(typ: LvType):
228
226
  }
229
227
 
230
228
 
231
- def create_modify_schema(widget_type):
229
+ def base_update_schema(widget_type, parts):
230
+ """
231
+ Create a schema for updating a widgets style properties, states and flags
232
+ :param widget_type: The type of the ID
233
+ :param parts: The allowable parts to specify
234
+ :return:
235
+ """
232
236
  return (
233
- part_schema(widget_type)
237
+ part_schema(parts)
234
238
  .extend(
235
239
  {
236
240
  cv.Required(CONF_ID): cv.ensure_list(
@@ -245,7 +249,12 @@ def create_modify_schema(widget_type):
245
249
  }
246
250
  )
247
251
  .extend(FLAG_SCHEMA)
248
- .extend(widget_type.modify_schema)
252
+ )
253
+
254
+
255
+ def create_modify_schema(widget_type):
256
+ return base_update_schema(widget_type.w_type, widget_type.parts).extend(
257
+ widget_type.modify_schema
249
258
  )
250
259
 
251
260
 
@@ -256,7 +265,7 @@ def obj_schema(widget_type: WidgetType):
256
265
  :return:
257
266
  """
258
267
  return (
259
- part_schema(widget_type)
268
+ part_schema(widget_type.parts)
260
269
  .extend(FLAG_SCHEMA)
261
270
  .extend(LAYOUT_SCHEMA)
262
271
  .extend(ALIGN_TO_SCHEMA)
@@ -341,11 +350,13 @@ FLEX_OBJ_SCHEMA = {
341
350
  cv.Optional(df.CONF_FLEX_GROW): cv.int_,
342
351
  }
343
352
 
344
-
345
353
  DISP_BG_SCHEMA = cv.Schema(
346
354
  {
347
- cv.Optional(df.CONF_DISP_BG_IMAGE): lv_image,
355
+ cv.Optional(df.CONF_DISP_BG_IMAGE): cv.Any(
356
+ cv.one_of("none", lower=True), lv_image
357
+ ),
348
358
  cv.Optional(df.CONF_DISP_BG_COLOR): lv_color,
359
+ cv.Optional(df.CONF_DISP_BG_OPA): opacity,
349
360
  }
350
361
  )
351
362