esphome 2024.7.2__py3-none-any.whl → 2024.8.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 (353) hide show
  1. esphome/__main__.py +15 -81
  2. esphome/automation.py +1 -1
  3. esphome/codegen.py +53 -53
  4. esphome/components/ade7953/sensor.py +1 -1
  5. esphome/components/ade7953_spi/ade7953_spi.cpp +1 -1
  6. esphome/components/airthings_wave_plus/airthings_wave_plus.cpp +5 -2
  7. esphome/components/airthings_wave_plus/airthings_wave_plus.h +2 -0
  8. esphome/components/airthings_wave_plus/sensor.py +12 -0
  9. esphome/components/alarm_control_panel/__init__.py +75 -66
  10. esphome/components/apds9306/__init__.py +4 -0
  11. esphome/components/apds9306/apds9306.cpp +151 -0
  12. esphome/components/apds9306/apds9306.h +66 -0
  13. esphome/components/apds9306/sensor.py +95 -0
  14. esphome/components/api/__init__.py +80 -52
  15. esphome/components/api/api_connection.cpp +14 -1
  16. esphome/components/api/api_pb2.cpp +33 -4
  17. esphome/components/api/api_pb2.h +8 -1
  18. esphome/components/api/api_server.cpp +10 -0
  19. esphome/components/api/api_server.h +3 -0
  20. esphome/components/atm90e32/__init__.py +7 -0
  21. esphome/components/atm90e32/atm90e32.cpp +68 -16
  22. esphome/components/atm90e32/atm90e32.h +20 -7
  23. esphome/components/atm90e32/atm90e32_reg.h +2 -0
  24. esphome/components/atm90e32/button/__init__.py +43 -0
  25. esphome/components/atm90e32/button/atm90e32_button.cpp +20 -0
  26. esphome/components/atm90e32/button/atm90e32_button.h +27 -0
  27. esphome/components/atm90e32/sensor.py +15 -11
  28. esphome/components/bedjet/bedjet_codec.h +1 -1
  29. esphome/components/binary/light/binary_light_output.h +3 -2
  30. esphome/components/binary_sensor/__init__.py +5 -5
  31. esphome/components/ble_client/__init__.py +3 -3
  32. esphome/components/ble_client/output/__init__.py +1 -1
  33. esphome/components/ble_client/sensor/__init__.py +4 -3
  34. esphome/components/ble_client/switch/__init__.py +2 -1
  35. esphome/components/ble_client/text_sensor/__init__.py +4 -3
  36. esphome/components/ble_presence/binary_sensor.py +3 -3
  37. esphome/components/ble_rssi/sensor.py +2 -2
  38. esphome/components/ble_scanner/text_sensor.py +1 -1
  39. esphome/components/bluetooth_proxy/__init__.py +3 -3
  40. esphome/components/bme68x_bsec2/__init__.py +196 -0
  41. esphome/components/bme68x_bsec2/bme68x_bsec2.cpp +523 -0
  42. esphome/components/bme68x_bsec2/bme68x_bsec2.h +163 -0
  43. esphome/components/bme68x_bsec2/sensor.py +130 -0
  44. esphome/components/bme68x_bsec2/text_sensor.py +33 -0
  45. esphome/components/bme68x_bsec2_i2c/__init__.py +28 -0
  46. esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.cpp +53 -0
  47. esphome/components/bme68x_bsec2_i2c/bme68x_bsec2_i2c.h +28 -0
  48. esphome/components/bmp3xx/sensor.py +1 -1
  49. esphome/components/button/__init__.py +4 -4
  50. esphome/components/climate/__init__.py +5 -5
  51. esphome/components/climate/climate.h +1 -1
  52. esphome/components/cover/__init__.py +8 -8
  53. esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +11 -7
  54. esphome/components/cst226/touchscreen/cst226_touchscreen.h +1 -1
  55. esphome/components/datetime/__init__.py +11 -13
  56. esphome/components/demo/demo_sensor.h +3 -2
  57. esphome/components/display/display.cpp +31 -0
  58. esphome/components/display/display.h +3 -0
  59. esphome/components/display_menu_base/__init__.py +14 -13
  60. esphome/components/ens160/sensor.py +1 -1
  61. esphome/components/esp32/__init__.py +22 -10
  62. esphome/components/esp32/boards.py +1 -1
  63. esphome/components/esp32/gpio.py +12 -13
  64. esphome/components/esp32/gpio_esp32.py +1 -2
  65. esphome/components/esp32/gpio_esp32_c2.py +1 -2
  66. esphome/components/esp32/gpio_esp32_c3.py +1 -5
  67. esphome/components/esp32/gpio_esp32_c6.py +1 -2
  68. esphome/components/esp32/gpio_esp32_h2.py +1 -2
  69. esphome/components/esp32/gpio_esp32_s2.py +1 -2
  70. esphome/components/esp32/gpio_esp32_s3.py +1 -6
  71. esphome/components/esp32_ble/__init__.py +20 -3
  72. esphome/components/esp32_ble/ble.cpp +9 -1
  73. esphome/components/esp32_ble/ble.h +9 -0
  74. esphome/components/esp32_ble/ble_advertising.cpp +42 -9
  75. esphome/components/esp32_ble/ble_advertising.h +21 -1
  76. esphome/components/esp32_ble_beacon/__init__.py +17 -7
  77. esphome/components/esp32_ble_beacon/esp32_ble_beacon.cpp +45 -113
  78. esphome/components/esp32_ble_beacon/esp32_ble_beacon.h +17 -19
  79. esphome/components/esp32_ble_client/__init__.py +0 -1
  80. esphome/components/esp32_ble_server/__init__.py +2 -3
  81. esphome/components/esp32_ble_tracker/__init__.py +2 -2
  82. esphome/components/esp32_improv/__init__.py +2 -4
  83. esphome/components/ethernet/__init__.py +17 -17
  84. esphome/components/ethernet_info/text_sensor.py +2 -2
  85. esphome/components/event/__init__.py +5 -5
  86. esphome/components/fan/__init__.py +14 -14
  87. esphome/components/fan/fan.cpp +2 -2
  88. esphome/components/fingerprint_grow/fingerprint_grow.cpp +1 -1
  89. esphome/components/fingerprint_grow/fingerprint_grow.h +1 -1
  90. esphome/components/graphical_display_menu/__init__.py +11 -8
  91. esphome/components/haier/haier_base.h +2 -2
  92. esphome/components/homeassistant/__init__.py +8 -1
  93. esphome/components/homeassistant/number/__init__.py +33 -0
  94. esphome/components/homeassistant/number/homeassistant_number.cpp +100 -0
  95. esphome/components/homeassistant/number/homeassistant_number.h +31 -0
  96. esphome/components/homeassistant/switch/__init__.py +30 -0
  97. esphome/components/homeassistant/switch/homeassistant_switch.cpp +59 -0
  98. esphome/components/homeassistant/switch/homeassistant_switch.h +22 -0
  99. esphome/components/host/__init__.py +3 -7
  100. esphome/components/http_request/__init__.py +12 -1
  101. esphome/components/http_request/http_request_arduino.cpp +2 -2
  102. esphome/components/http_request/http_request_idf.cpp +11 -2
  103. esphome/components/http_request/http_request_idf.h +10 -0
  104. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  105. esphome/components/http_request/update/http_request_update.cpp +2 -2
  106. esphome/components/http_request/update/http_request_update.h +2 -1
  107. esphome/components/hx711/hx711.cpp +10 -1
  108. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +1 -1
  109. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +11 -2
  110. esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +2 -0
  111. esphome/components/ili9xxx/ili9xxx_defines.h +3 -1
  112. esphome/components/ili9xxx/ili9xxx_display.cpp +9 -22
  113. esphome/components/ili9xxx/ili9xxx_display.h +5 -7
  114. esphome/components/ili9xxx/ili9xxx_init.h +4 -4
  115. esphome/components/improv_base/__init__.py +2 -3
  116. esphome/components/improv_serial/__init__.py +4 -10
  117. esphome/components/improv_serial/improv_serial_component.cpp +4 -0
  118. esphome/components/jsn_sr04t/jsn_sr04t.cpp +18 -1
  119. esphome/components/jsn_sr04t/jsn_sr04t.h +7 -1
  120. esphome/components/jsn_sr04t/sensor.py +13 -0
  121. esphome/components/kalman_combinator/sensor.py +1 -1
  122. esphome/components/light/__init__.py +16 -15
  123. esphome/components/light/addressable_light_effect.h +12 -8
  124. esphome/components/light/automation.h +16 -1
  125. esphome/components/light/automation.py +21 -0
  126. esphome/components/light/base_light_effects.h +5 -5
  127. esphome/components/light/esp_color_correction.h +8 -8
  128. esphome/components/light/types.py +7 -0
  129. esphome/components/lock/__init__.py +3 -3
  130. esphome/components/logger/__init__.py +15 -18
  131. esphome/components/lvgl/__init__.py +346 -0
  132. esphome/components/lvgl/automation.py +226 -0
  133. esphome/components/lvgl/binary_sensor/__init__.py +43 -0
  134. esphome/components/lvgl/defines.py +508 -0
  135. esphome/components/lvgl/encoders.py +77 -0
  136. esphome/components/lvgl/font.cpp +76 -0
  137. esphome/components/lvgl/helpers.py +49 -0
  138. esphome/components/lvgl/light/__init__.py +32 -0
  139. esphome/components/lvgl/light/lvgl_light.h +48 -0
  140. esphome/components/lvgl/lv_validation.py +303 -0
  141. esphome/components/lvgl/lvcode.py +349 -0
  142. esphome/components/lvgl/lvgl_esphome.cpp +407 -0
  143. esphome/components/lvgl/lvgl_esphome.h +274 -0
  144. esphome/components/lvgl/lvgl_hal.h +21 -0
  145. esphome/components/lvgl/number/__init__.py +66 -0
  146. esphome/components/lvgl/number/lvgl_number.h +34 -0
  147. esphome/components/lvgl/schemas.py +436 -0
  148. esphome/components/lvgl/select/__init__.py +55 -0
  149. esphome/components/lvgl/select/lvgl_select.h +62 -0
  150. esphome/components/lvgl/sensor/__init__.py +47 -0
  151. esphome/components/lvgl/styles.py +58 -0
  152. esphome/components/lvgl/switch/__init__.py +56 -0
  153. esphome/components/lvgl/switch/lvgl_switch.h +34 -0
  154. esphome/components/lvgl/text/__init__.py +50 -0
  155. esphome/components/lvgl/text/lvgl_text.h +34 -0
  156. esphome/components/lvgl/text_sensor/__init__.py +42 -0
  157. esphome/components/lvgl/touchscreens.py +45 -0
  158. esphome/components/lvgl/trigger.py +74 -0
  159. esphome/components/lvgl/types.py +191 -0
  160. esphome/components/lvgl/widgets/__init__.py +419 -0
  161. esphome/components/lvgl/widgets/animimg.py +117 -0
  162. esphome/components/lvgl/widgets/arc.py +78 -0
  163. esphome/components/lvgl/widgets/button.py +20 -0
  164. esphome/components/lvgl/widgets/buttonmatrix.py +275 -0
  165. esphome/components/lvgl/widgets/checkbox.py +27 -0
  166. esphome/components/lvgl/widgets/dropdown.py +76 -0
  167. esphome/components/lvgl/widgets/img.py +85 -0
  168. esphome/components/lvgl/widgets/keyboard.py +49 -0
  169. esphome/components/lvgl/widgets/label.py +42 -0
  170. esphome/components/lvgl/widgets/led.py +29 -0
  171. esphome/components/lvgl/widgets/line.py +50 -0
  172. esphome/components/lvgl/widgets/lv_bar.py +55 -0
  173. esphome/components/lvgl/widgets/meter.py +302 -0
  174. esphome/components/lvgl/widgets/msgbox.py +134 -0
  175. esphome/components/lvgl/widgets/obj.py +28 -0
  176. esphome/components/lvgl/widgets/page.py +113 -0
  177. esphome/components/lvgl/widgets/roller.py +77 -0
  178. esphome/components/lvgl/widgets/slider.py +63 -0
  179. esphome/components/lvgl/widgets/spinbox.py +178 -0
  180. esphome/components/lvgl/widgets/spinner.py +43 -0
  181. esphome/components/lvgl/widgets/switch.py +20 -0
  182. esphome/components/lvgl/widgets/tabview.py +114 -0
  183. esphome/components/lvgl/widgets/textarea.py +66 -0
  184. esphome/components/lvgl/widgets/tileview.py +128 -0
  185. esphome/components/m5stack_8angle/__init__.py +33 -0
  186. esphome/components/m5stack_8angle/binary_sensor/__init__.py +30 -0
  187. esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.cpp +17 -0
  188. esphome/components/m5stack_8angle/binary_sensor/m5stack_8angle_binary_sensor.h +19 -0
  189. esphome/components/m5stack_8angle/light/__init__.py +31 -0
  190. esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +45 -0
  191. esphome/components/m5stack_8angle/light/m5stack_8angle_light.h +37 -0
  192. esphome/components/m5stack_8angle/m5stack_8angle.cpp +74 -0
  193. esphome/components/m5stack_8angle/m5stack_8angle.h +34 -0
  194. esphome/components/m5stack_8angle/sensor/__init__.py +66 -0
  195. esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.cpp +24 -0
  196. esphome/components/m5stack_8angle/sensor/m5stack_8angle_sensor.h +27 -0
  197. esphome/components/matrix_keypad/matrix_keypad.cpp +2 -0
  198. esphome/components/max31856/sensor.py +5 -5
  199. esphome/components/media_player/__init__.py +3 -5
  200. esphome/components/media_player/automation.h +31 -27
  201. esphome/components/micro_wake_word/__init__.py +20 -25
  202. esphome/components/micro_wake_word/streaming_model.cpp +6 -4
  203. esphome/components/microphone/microphone.h +4 -1
  204. esphome/components/mitsubishi/mitsubishi.cpp +7 -1
  205. esphome/components/modbus_controller/__init__.py +26 -2
  206. esphome/components/modbus_controller/automation.h +19 -0
  207. esphome/components/modbus_controller/const.py +1 -0
  208. esphome/components/modbus_controller/modbus_controller.cpp +8 -0
  209. esphome/components/modbus_controller/modbus_controller.h +3 -0
  210. esphome/components/mqtt/__init__.py +20 -9
  211. esphome/components/mqtt/mqtt_alarm_control_panel.cpp +128 -0
  212. esphome/components/mqtt/mqtt_alarm_control_panel.h +39 -0
  213. esphome/components/mqtt/mqtt_backend.h +3 -1
  214. esphome/components/mqtt/mqtt_backend_esp32.cpp +4 -1
  215. esphome/components/mqtt/mqtt_backend_esp32.h +3 -1
  216. esphome/components/mqtt/mqtt_backend_esp8266.h +3 -1
  217. esphome/components/mqtt/mqtt_backend_libretiny.h +3 -1
  218. esphome/components/mqtt/mqtt_client.cpp +16 -3
  219. esphome/components/mqtt/mqtt_client.h +5 -1
  220. esphome/components/mqtt/mqtt_component.cpp +32 -4
  221. esphome/components/mqtt/mqtt_const.h +2 -0
  222. esphome/components/network/__init__.py +15 -12
  223. esphome/components/network/ip_address.h +3 -0
  224. esphome/components/network/util.cpp +2 -1
  225. esphome/components/network/util.h +3 -1
  226. esphome/components/nextion/base_component.py +5 -8
  227. esphome/components/number/__init__.py +7 -8
  228. esphome/components/online_image/__init__.py +167 -0
  229. esphome/components/online_image/image_decoder.cpp +44 -0
  230. esphome/components/online_image/image_decoder.h +112 -0
  231. esphome/components/online_image/online_image.cpp +283 -0
  232. esphome/components/online_image/online_image.h +195 -0
  233. esphome/components/online_image/png_image.cpp +68 -0
  234. esphome/components/online_image/png_image.h +33 -0
  235. esphome/components/ota/__init__.py +8 -4
  236. esphome/components/pid/pid_climate.h +2 -0
  237. esphome/components/pmwcs3/pmwcs3.cpp +31 -30
  238. esphome/components/remote_base/pronto_protocol.cpp +0 -3
  239. esphome/components/remote_transmitter/remote_transmitter.h +1 -1
  240. esphome/components/rgbct/rgbct_light_output.h +3 -2
  241. esphome/components/rgbw/rgbw_light_output.h +3 -2
  242. esphome/components/rgbww/rgbww_light_output.h +3 -2
  243. esphome/components/rp2040_pio_led_strip/led_strip.cpp +31 -5
  244. esphome/components/rp2040_pio_led_strip/led_strip.h +5 -0
  245. esphome/components/rtttl/rtttl.cpp +108 -21
  246. esphome/components/rtttl/rtttl.h +15 -6
  247. esphome/components/select/__init__.py +7 -7
  248. esphome/components/sensor/__init__.py +29 -10
  249. esphome/components/sensor/filter.cpp +8 -0
  250. esphome/components/sensor/filter.h +9 -0
  251. esphome/components/sml/sml_parser.cpp +48 -22
  252. esphome/components/socket/socket.cpp +11 -14
  253. esphome/components/speaker/__init__.py +14 -5
  254. esphome/components/speaker/automation.h +10 -0
  255. esphome/components/speaker/speaker.h +9 -0
  256. esphome/components/spi/spi.cpp +0 -6
  257. esphome/components/spi/spi.h +2 -19
  258. esphome/components/spi_led_strip/spi_led_strip.h +5 -4
  259. esphome/components/sprinkler/sprinkler.cpp +2 -2
  260. esphome/components/sprinkler/sprinkler.h +1 -1
  261. esphome/components/switch/__init__.py +3 -3
  262. esphome/components/text/__init__.py +5 -5
  263. esphome/components/text_sensor/__init__.py +7 -7
  264. esphome/components/time/__init__.py +8 -8
  265. esphome/components/touchscreen/binary_sensor/__init__.py +24 -10
  266. esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.cpp +3 -2
  267. esphome/components/touchscreen/binary_sensor/touchscreen_binary_sensor.h +4 -2
  268. esphome/components/uart/uart_component_host.cpp +6 -2
  269. esphome/components/update/__init__.py +33 -15
  270. esphome/components/update/automation.h +23 -0
  271. esphome/components/update/update_entity.h +3 -1
  272. esphome/components/valve/__init__.py +3 -3
  273. esphome/components/voice_assistant/__init__.py +7 -8
  274. esphome/components/wake_on_lan/wake_on_lan.cpp +2 -0
  275. esphome/components/wake_on_lan/wake_on_lan.h +3 -1
  276. esphome/components/watchdog/__init__.py +1 -0
  277. esphome/components/{http_request → watchdog}/watchdog.cpp +0 -2
  278. esphome/components/{http_request → watchdog}/watchdog.h +0 -2
  279. esphome/components/waveshare_epaper/waveshare_epaper.cpp +5 -5
  280. esphome/components/web_server/server_index_v3.h +3615 -3603
  281. esphome/components/web_server/web_server.cpp +0 -209
  282. esphome/components/web_server/web_server.h +1 -1
  283. esphome/components/web_server/web_server_v1.cpp +217 -0
  284. esphome/components/web_server_base/web_server_base.h +1 -0
  285. esphome/components/wifi/__init__.py +15 -14
  286. esphome/components/wifi/wifi_component.cpp +2 -0
  287. esphome/components/wifi/wifi_component.h +7 -1
  288. esphome/components/wifi/wifi_component_esp32_arduino.cpp +5 -2
  289. esphome/components/wifi/wifi_component_esp8266.cpp +2 -0
  290. esphome/components/wifi/wifi_component_esp_idf.cpp +43 -7
  291. esphome/components/wifi/wifi_component_libretiny.cpp +2 -0
  292. esphome/components/wifi/wifi_component_pico_w.cpp +2 -0
  293. esphome/components/wifi/wpa2_eap.py +6 -7
  294. esphome/components/wifi_info/text_sensor.py +3 -3
  295. esphome/components/wifi_info/wifi_info_text_sensor.cpp +2 -0
  296. esphome/components/wifi_info/wifi_info_text_sensor.h +2 -0
  297. esphome/components/wifi_signal/sensor.py +1 -1
  298. esphome/components/wifi_signal/wifi_signal_sensor.cpp +2 -0
  299. esphome/components/wifi_signal/wifi_signal_sensor.h +2 -1
  300. esphome/components/xiaomi_ble/xiaomi_ble.cpp +20 -3
  301. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  302. esphome/components/xiaomi_lywsd02mmc/__init__.py +0 -0
  303. esphome/components/xiaomi_lywsd02mmc/sensor.py +77 -0
  304. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.cpp +73 -0
  305. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +37 -0
  306. esphome/config.py +17 -19
  307. esphome/config_validation.py +55 -23
  308. esphome/const.py +25 -9
  309. esphome/core/__init__.py +17 -14
  310. esphome/core/application.h +42 -21
  311. esphome/core/automation.h +5 -3
  312. esphome/core/base_automation.h +3 -2
  313. esphome/core/bytebuffer.cpp +134 -0
  314. esphome/core/bytebuffer.h +96 -0
  315. esphome/core/color.h +24 -16
  316. esphome/core/config.py +3 -3
  317. esphome/core/defines.h +14 -1
  318. esphome/core/entity_base.h +2 -2
  319. esphome/core/entity_helpers.py +1 -2
  320. esphome/core/gpio.h +0 -18
  321. esphome/core/helpers.h +1 -1
  322. esphome/core/optional.h +15 -16
  323. esphome/coroutine.py +1 -1
  324. esphome/cpp_generator.py +1 -1
  325. esphome/cpp_helpers.py +3 -5
  326. esphome/dashboard/core.py +3 -3
  327. esphome/dashboard/dashboard.py +3 -3
  328. esphome/dashboard/entries.py +1 -1
  329. esphome/dashboard/util/file.py +1 -1
  330. esphome/dashboard/web_server.py +3 -3
  331. esphome/external_files.py +5 -3
  332. esphome/final_validate.py +2 -2
  333. esphome/git.py +4 -4
  334. esphome/helpers.py +5 -5
  335. esphome/loader.py +15 -10
  336. esphome/mqtt.py +4 -8
  337. esphome/pins.py +6 -6
  338. esphome/platformio_api.py +5 -5
  339. esphome/storage_json.py +2 -1
  340. esphome/types.py +1 -1
  341. esphome/util.py +2 -3
  342. esphome/voluptuous_schema.py +1 -0
  343. esphome/vscode.py +5 -4
  344. esphome/wizard.py +1 -1
  345. esphome/writer.py +7 -7
  346. esphome/yaml_util.py +3 -3
  347. esphome/zeroconf.py +1 -1
  348. {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/METADATA +3 -3
  349. {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/RECORD +353 -247
  350. {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/LICENSE +0 -0
  351. {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/WHEEL +0 -0
  352. {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/entry_points.txt +0 -0
  353. {esphome-2024.7.2.dist-info → esphome-2024.8.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,58 @@
1
+ import esphome.codegen as cg
2
+ from esphome.const import CONF_ID
3
+ from esphome.core import ID
4
+ from esphome.cpp_generator import MockObj
5
+
6
+ from .defines import (
7
+ CONF_STYLE_DEFINITIONS,
8
+ CONF_THEME,
9
+ CONF_TOP_LAYER,
10
+ LValidator,
11
+ literal,
12
+ )
13
+ from .helpers import add_lv_use
14
+ from .lvcode import LambdaContext, LocalVariable, lv, lv_assign, lv_variable
15
+ from .schemas import ALL_STYLES
16
+ from .types import lv_lambda_t, lv_obj_t, lv_obj_t_ptr
17
+ from .widgets import Widget, add_widgets, set_obj_properties, theme_widget_map
18
+ from .widgets.obj import obj_spec
19
+
20
+ TOP_LAYER = literal("lv_disp_get_layer_top(lv_component->get_disp())")
21
+
22
+
23
+ async def styles_to_code(config):
24
+ """Convert styles to C__ code."""
25
+ for style in config.get(CONF_STYLE_DEFINITIONS, ()):
26
+ svar = cg.new_Pvariable(style[CONF_ID])
27
+ lv.style_init(svar)
28
+ for prop, validator in ALL_STYLES.items():
29
+ if (value := style.get(prop)) is not None:
30
+ if isinstance(validator, LValidator):
31
+ value = await validator.process(value)
32
+ if isinstance(value, list):
33
+ value = "|".join(value)
34
+ lv.call(f"style_set_{prop}", svar, literal(value))
35
+
36
+
37
+ async def theme_to_code(config):
38
+ if theme := config.get(CONF_THEME):
39
+ add_lv_use(CONF_THEME)
40
+ for w_name, style in theme.items():
41
+ if not isinstance(style, dict):
42
+ continue
43
+
44
+ lname = "lv_theme_apply_" + w_name
45
+ apply = lv_variable(lv_lambda_t, lname)
46
+ theme_widget_map[w_name] = apply
47
+ ow = Widget.create("obj", MockObj(ID("obj")), obj_spec)
48
+ async with LambdaContext([(lv_obj_t_ptr, "obj")], where=w_name) as context:
49
+ await set_obj_properties(ow, style)
50
+ lv_assign(apply, await context.get_lambda())
51
+
52
+
53
+ async def add_top_layer(config):
54
+ if top_conf := config.get(CONF_TOP_LAYER):
55
+ with LocalVariable("top_layer", lv_obj_t, TOP_LAYER) as top_layer_obj:
56
+ top_w = Widget(top_layer_obj, obj_spec, top_conf)
57
+ await set_obj_properties(top_w, top_conf)
58
+ await add_widgets(top_w, top_conf)
@@ -0,0 +1,56 @@
1
+ import esphome.codegen as cg
2
+ from esphome.components.switch import Switch, new_switch, switch_schema
3
+ import esphome.config_validation as cv
4
+ from esphome.cpp_generator import MockObj
5
+
6
+ from ..defines import CONF_LVGL_ID, CONF_WIDGET
7
+ from ..lvcode import (
8
+ API_EVENT,
9
+ EVENT_ARG,
10
+ UPDATE_EVENT,
11
+ LambdaContext,
12
+ LvConditional,
13
+ LvContext,
14
+ lv,
15
+ lv_add,
16
+ )
17
+ from ..schemas import LVGL_SCHEMA
18
+ from ..types import LV_EVENT, LV_STATE, lv_pseudo_button_t, lvgl_ns
19
+ from ..widgets import get_widgets
20
+
21
+ LVGLSwitch = lvgl_ns.class_("LVGLSwitch", Switch)
22
+ CONFIG_SCHEMA = (
23
+ switch_schema(LVGLSwitch)
24
+ .extend(LVGL_SCHEMA)
25
+ .extend(
26
+ {
27
+ cv.Required(CONF_WIDGET): cv.use_id(lv_pseudo_button_t),
28
+ }
29
+ )
30
+ )
31
+
32
+
33
+ async def to_code(config):
34
+ switch = await new_switch(config)
35
+ paren = await cg.get_variable(config[CONF_LVGL_ID])
36
+ widget = await get_widgets(config, CONF_WIDGET)
37
+ widget = widget[0]
38
+ async with LambdaContext(EVENT_ARG) as checked_ctx:
39
+ checked_ctx.add(switch.publish_state(widget.get_value()))
40
+ async with LambdaContext([(cg.bool_, "v")]) as control:
41
+ with LvConditional(MockObj("v")) as cond:
42
+ widget.add_state(LV_STATE.CHECKED)
43
+ cond.else_()
44
+ widget.clear_state(LV_STATE.CHECKED)
45
+ lv.event_send(widget.obj, API_EVENT, cg.nullptr)
46
+ async with LvContext(paren) as ctx:
47
+ lv_add(switch.set_control_lambda(await control.get_lambda()))
48
+ ctx.add(
49
+ paren.add_event_cb(
50
+ widget.obj,
51
+ await checked_ctx.get_lambda(),
52
+ LV_EVENT.VALUE_CHANGED,
53
+ UPDATE_EVENT,
54
+ )
55
+ )
56
+ lv_add(switch.publish_state(widget.get_value()))
@@ -0,0 +1,34 @@
1
+ #pragma once
2
+
3
+ #include "esphome/components/switch/switch.h"
4
+ #include "esphome/core/automation.h"
5
+ #include "esphome/core/component.h"
6
+ #include "esphome/core/preferences.h"
7
+
8
+ namespace esphome {
9
+ namespace lvgl {
10
+
11
+ class LVGLSwitch : public switch_::Switch {
12
+ public:
13
+ void set_control_lambda(std::function<void(bool)> state_lambda) {
14
+ this->state_lambda_ = state_lambda;
15
+ if (this->initial_state_.has_value()) {
16
+ this->state_lambda_(this->initial_state_.value());
17
+ this->initial_state_.reset();
18
+ }
19
+ }
20
+
21
+ protected:
22
+ void write_state(bool value) override {
23
+ if (this->state_lambda_ != nullptr) {
24
+ this->state_lambda_(value);
25
+ } else {
26
+ this->initial_state_ = value;
27
+ }
28
+ }
29
+ std::function<void(bool)> state_lambda_{};
30
+ optional<bool> initial_state_{};
31
+ };
32
+
33
+ } // namespace lvgl
34
+ } // namespace esphome
@@ -0,0 +1,50 @@
1
+ import esphome.codegen as cg
2
+ from esphome.components import text
3
+ from esphome.components.text import new_text
4
+ import esphome.config_validation as cv
5
+
6
+ from ..defines import CONF_LVGL_ID, CONF_WIDGET
7
+ from ..lvcode import (
8
+ API_EVENT,
9
+ EVENT_ARG,
10
+ UPDATE_EVENT,
11
+ LambdaContext,
12
+ LvContext,
13
+ lv,
14
+ lv_add,
15
+ )
16
+ from ..schemas import LVGL_SCHEMA
17
+ from ..types import LV_EVENT, LvText, lvgl_ns
18
+ from ..widgets import get_widgets
19
+
20
+ LVGLText = lvgl_ns.class_("LVGLText", text.Text)
21
+
22
+ CONFIG_SCHEMA = text.TEXT_SCHEMA.extend(LVGL_SCHEMA).extend(
23
+ {
24
+ cv.GenerateID(): cv.declare_id(LVGLText),
25
+ cv.Required(CONF_WIDGET): cv.use_id(LvText),
26
+ }
27
+ )
28
+
29
+
30
+ async def to_code(config):
31
+ textvar = await new_text(config)
32
+ paren = await cg.get_variable(config[CONF_LVGL_ID])
33
+ widget = await get_widgets(config, CONF_WIDGET)
34
+ widget = widget[0]
35
+ async with LambdaContext([(cg.std_string, "text_value")]) as control:
36
+ await widget.set_property("text", "text_value.c_str())")
37
+ lv.event_send(widget.obj, API_EVENT, None)
38
+ async with LambdaContext(EVENT_ARG) as lamb:
39
+ lv_add(textvar.publish_state(widget.get_value()))
40
+ async with LvContext(paren):
41
+ widget.var.set_control_lambda(await control.get_lambda())
42
+ lv_add(
43
+ paren.add_event_cb(
44
+ widget.obj,
45
+ await lamb.get_lambda(),
46
+ LV_EVENT.VALUE_CHANGED,
47
+ UPDATE_EVENT,
48
+ )
49
+ )
50
+ lv_add(textvar.publish_state(widget.get_value()))
@@ -0,0 +1,34 @@
1
+ #pragma once
2
+
3
+ #include "esphome/components/text/text.h"
4
+ #include "esphome/core/automation.h"
5
+ #include "esphome/core/component.h"
6
+ #include "esphome/core/preferences.h"
7
+
8
+ namespace esphome {
9
+ namespace lvgl {
10
+
11
+ class LVGLText : public text::Text {
12
+ public:
13
+ void set_control_lambda(std::function<void(const std::string)> control_lambda) {
14
+ this->control_lambda_ = control_lambda;
15
+ if (this->initial_state_.has_value()) {
16
+ this->control_lambda_(this->initial_state_.value());
17
+ this->initial_state_.reset();
18
+ }
19
+ }
20
+
21
+ protected:
22
+ void control(const std::string &value) override {
23
+ if (this->control_lambda_ != nullptr) {
24
+ this->control_lambda_(value);
25
+ } else {
26
+ this->initial_state_ = value;
27
+ }
28
+ }
29
+ std::function<void(const std::string)> control_lambda_{};
30
+ optional<std::string> initial_state_{};
31
+ };
32
+
33
+ } // namespace lvgl
34
+ } // namespace esphome
@@ -0,0 +1,42 @@
1
+ import esphome.codegen as cg
2
+ from esphome.components.text_sensor import (
3
+ TextSensor,
4
+ new_text_sensor,
5
+ text_sensor_schema,
6
+ )
7
+ import esphome.config_validation as cv
8
+
9
+ from ..defines import CONF_LVGL_ID, CONF_WIDGET
10
+ from ..lvcode import API_EVENT, EVENT_ARG, UPDATE_EVENT, LambdaContext, LvContext
11
+ from ..schemas import LVGL_SCHEMA
12
+ from ..types import LV_EVENT, LvText
13
+ from ..widgets import get_widgets
14
+
15
+ CONFIG_SCHEMA = (
16
+ text_sensor_schema(TextSensor)
17
+ .extend(LVGL_SCHEMA)
18
+ .extend(
19
+ {
20
+ cv.Required(CONF_WIDGET): cv.use_id(LvText),
21
+ }
22
+ )
23
+ )
24
+
25
+
26
+ async def to_code(config):
27
+ sensor = await new_text_sensor(config)
28
+ paren = await cg.get_variable(config[CONF_LVGL_ID])
29
+ widget = await get_widgets(config, CONF_WIDGET)
30
+ widget = widget[0]
31
+ async with LambdaContext(EVENT_ARG) as pressed_ctx:
32
+ pressed_ctx.add(sensor.publish_state(widget.get_value()))
33
+ async with LvContext(paren) as ctx:
34
+ ctx.add(
35
+ paren.add_event_cb(
36
+ widget.obj,
37
+ await pressed_ctx.get_lambda(),
38
+ LV_EVENT.VALUE_CHANGED,
39
+ API_EVENT,
40
+ UPDATE_EVENT,
41
+ )
42
+ )
@@ -0,0 +1,45 @@
1
+ import esphome.codegen as cg
2
+ from esphome.components.touchscreen import CONF_TOUCHSCREEN_ID, Touchscreen
3
+ import esphome.config_validation as cv
4
+ from esphome.const import CONF_ID
5
+ from esphome.core import CORE
6
+
7
+ from .defines import (
8
+ CONF_LONG_PRESS_REPEAT_TIME,
9
+ CONF_LONG_PRESS_TIME,
10
+ CONF_TOUCHSCREENS,
11
+ )
12
+ from .helpers import lvgl_components_required
13
+ from .lvcode import lv
14
+ from .schemas import PRESS_TIME
15
+ from .types import LVTouchListener
16
+
17
+ CONF_TOUCHSCREEN = "touchscreen"
18
+ TOUCHSCREENS_CONFIG = cv.maybe_simple_value(
19
+ {
20
+ cv.Required(CONF_TOUCHSCREEN_ID): cv.use_id(Touchscreen),
21
+ cv.Optional(CONF_LONG_PRESS_TIME, default="400ms"): PRESS_TIME,
22
+ cv.Optional(CONF_LONG_PRESS_REPEAT_TIME, default="100ms"): PRESS_TIME,
23
+ cv.GenerateID(): cv.declare_id(LVTouchListener),
24
+ },
25
+ key=CONF_TOUCHSCREEN_ID,
26
+ )
27
+
28
+
29
+ def touchscreen_schema(config):
30
+ value = cv.ensure_list(TOUCHSCREENS_CONFIG)(config)
31
+ if value or CONF_TOUCHSCREEN not in CORE.loaded_integrations:
32
+ return value
33
+ return [TOUCHSCREENS_CONFIG(config)]
34
+
35
+
36
+ async def touchscreens_to_code(var, config):
37
+ for tconf in config[CONF_TOUCHSCREENS]:
38
+ lvgl_components_required.add(CONF_TOUCHSCREEN)
39
+ touchscreen = await cg.get_variable(tconf[CONF_TOUCHSCREEN_ID])
40
+ lpt = tconf[CONF_LONG_PRESS_TIME].total_milliseconds
41
+ lprt = tconf[CONF_LONG_PRESS_REPEAT_TIME].total_milliseconds
42
+ listener = cg.new_Pvariable(tconf[CONF_ID], lpt, lprt)
43
+ await cg.register_parented(listener, var)
44
+ lv.indev_drv_register(listener.get_drv())
45
+ cg.add(touchscreen.register_listener(listener))
@@ -0,0 +1,74 @@
1
+ from esphome import automation
2
+ import esphome.codegen as cg
3
+ from esphome.const import CONF_ID, CONF_ON_VALUE, CONF_TRIGGER_ID
4
+
5
+ from .defines import (
6
+ CONF_ALIGN,
7
+ CONF_ALIGN_TO,
8
+ CONF_X,
9
+ CONF_Y,
10
+ LV_EVENT_MAP,
11
+ LV_EVENT_TRIGGERS,
12
+ literal,
13
+ )
14
+ from .lvcode import (
15
+ API_EVENT,
16
+ EVENT_ARG,
17
+ UPDATE_EVENT,
18
+ LambdaContext,
19
+ LvConditional,
20
+ lv,
21
+ lv_add,
22
+ )
23
+ from .types import LV_EVENT
24
+ from .widgets import widget_map
25
+
26
+
27
+ async def generate_triggers(lv_component):
28
+ """
29
+ Generate LVGL triggers for all defined widgets
30
+ Must be done after all widgets completed
31
+ :param lv_component: The parent component
32
+ :return:
33
+ """
34
+
35
+ for w in widget_map.values():
36
+ if w.config:
37
+ for event, conf in {
38
+ event: conf
39
+ for event, conf in w.config.items()
40
+ if event in LV_EVENT_TRIGGERS
41
+ }.items():
42
+ conf = conf[0]
43
+ w.add_flag("LV_OBJ_FLAG_CLICKABLE")
44
+ event = literal("LV_EVENT_" + LV_EVENT_MAP[event[3:].upper()])
45
+ await add_trigger(conf, lv_component, w, event)
46
+ for conf in w.config.get(CONF_ON_VALUE, ()):
47
+ await add_trigger(
48
+ conf,
49
+ lv_component,
50
+ w,
51
+ LV_EVENT.VALUE_CHANGED,
52
+ API_EVENT,
53
+ UPDATE_EVENT,
54
+ )
55
+
56
+ # Generate align to directives while we're here
57
+ if align_to := w.config.get(CONF_ALIGN_TO):
58
+ target = widget_map[align_to[CONF_ID]].obj
59
+ align = literal(align_to[CONF_ALIGN])
60
+ x = align_to[CONF_X]
61
+ y = align_to[CONF_Y]
62
+ lv.obj_align_to(w.obj, target, align, x, y)
63
+
64
+
65
+ async def add_trigger(conf, lv_component, w, *events):
66
+ tid = conf[CONF_TRIGGER_ID]
67
+ trigger = cg.new_Pvariable(tid)
68
+ args = w.get_args()
69
+ value = w.get_value()
70
+ await automation.build_automation(trigger, args, conf)
71
+ async with LambdaContext(EVENT_ARG, where=tid) as context:
72
+ with LvConditional(w.is_selected()):
73
+ lv_add(trigger.trigger(value))
74
+ lv_add(lv_component.add_event_cb(w.obj, await context.get_lambda(), *events))
@@ -0,0 +1,191 @@
1
+ import sys
2
+
3
+ from esphome import automation, codegen as cg
4
+ from esphome.const import CONF_MAX_VALUE, CONF_MIN_VALUE, CONF_TEXT, CONF_VALUE
5
+ from esphome.cpp_generator import MockObj, MockObjClass
6
+
7
+ from .defines import lvgl_ns
8
+ from .lvcode import lv_expr
9
+
10
+
11
+ class LvType(cg.MockObjClass):
12
+ def __init__(self, *args, **kwargs):
13
+ parens = kwargs.pop("parents", ())
14
+ super().__init__(*args, parents=parens + (lv_obj_base_t,))
15
+ self.args = kwargs.pop("largs", [(lv_obj_t_ptr, "obj")])
16
+ self.value = kwargs.pop("lvalue", lambda w: w.obj)
17
+ self.has_on_value = kwargs.pop("has_on_value", False)
18
+ self.value_property = None
19
+
20
+ def get_arg_type(self):
21
+ return self.args[0][0] if len(self.args) else None
22
+
23
+
24
+ class LvNumber(LvType):
25
+ def __init__(self, *args):
26
+ super().__init__(
27
+ *args,
28
+ largs=[(cg.float_, "x")],
29
+ lvalue=lambda w: w.get_number_value(),
30
+ has_on_value=True,
31
+ )
32
+ self.value_property = CONF_VALUE
33
+
34
+
35
+ uint16_t_ptr = cg.uint16.operator("ptr")
36
+ char_ptr = cg.global_ns.namespace("char").operator("ptr")
37
+ void_ptr = cg.void.operator("ptr")
38
+ lv_coord_t = cg.global_ns.namespace("lv_coord_t")
39
+ lv_event_code_t = cg.global_ns.enum("lv_event_code_t")
40
+ lv_indev_type_t = cg.global_ns.enum("lv_indev_type_t")
41
+ FontEngine = lvgl_ns.class_("FontEngine")
42
+ IdleTrigger = lvgl_ns.class_("IdleTrigger", automation.Trigger.template())
43
+ ObjUpdateAction = lvgl_ns.class_("ObjUpdateAction", automation.Action)
44
+ LvglCondition = lvgl_ns.class_("LvglCondition", automation.Condition)
45
+ LvglAction = lvgl_ns.class_("LvglAction", automation.Action)
46
+ lv_lambda_t = lvgl_ns.class_("LvLambdaType")
47
+ LvCompound = lvgl_ns.class_("LvCompound")
48
+ lv_font_t = cg.global_ns.class_("lv_font_t")
49
+ lv_style_t = cg.global_ns.struct("lv_style_t")
50
+ # fake parent class for first class widgets and matrix buttons
51
+ lv_pseudo_button_t = lvgl_ns.class_("LvPseudoButton")
52
+ lv_obj_base_t = cg.global_ns.class_("lv_obj_t", lv_pseudo_button_t)
53
+ lv_obj_t_ptr = lv_obj_base_t.operator("ptr")
54
+ lv_disp_t = cg.global_ns.struct("lv_disp_t")
55
+ lv_color_t = cg.global_ns.struct("lv_color_t")
56
+ lv_group_t = cg.global_ns.struct("lv_group_t")
57
+ LVTouchListener = lvgl_ns.class_("LVTouchListener")
58
+ LVEncoderListener = lvgl_ns.class_("LVEncoderListener")
59
+ lv_obj_t = LvType("lv_obj_t")
60
+ lv_page_t = cg.global_ns.class_("LvPageType", LvCompound)
61
+ lv_img_t = LvType("lv_img_t")
62
+
63
+ LV_EVENT = MockObj(base="LV_EVENT_", op="")
64
+ LV_STATE = MockObj(base="LV_STATE_", op="")
65
+ LV_BTNMATRIX_CTRL = MockObj(base="LV_BTNMATRIX_CTRL_", op="")
66
+
67
+
68
+ class LvText(LvType):
69
+ def __init__(self, *args, **kwargs):
70
+ super().__init__(
71
+ *args,
72
+ largs=[(cg.std_string, "text")],
73
+ lvalue=lambda w: w.get_property("text"),
74
+ has_on_value=True,
75
+ **kwargs,
76
+ )
77
+ self.value_property = CONF_TEXT
78
+
79
+
80
+ class LvBoolean(LvType):
81
+ def __init__(self, *args, **kwargs):
82
+ super().__init__(
83
+ *args,
84
+ largs=[(cg.bool_, "x")],
85
+ lvalue=lambda w: w.is_checked(),
86
+ has_on_value=True,
87
+ **kwargs,
88
+ )
89
+
90
+
91
+ class LvSelect(LvType):
92
+ def __init__(self, *args, **kwargs):
93
+ super().__init__(
94
+ *args,
95
+ largs=[(cg.int_, "x")],
96
+ lvalue=lambda w: w.get_property("selected"),
97
+ has_on_value=True,
98
+ **kwargs,
99
+ )
100
+
101
+
102
+ class WidgetType:
103
+ """
104
+ Describes a type of Widget, e.g. "bar" or "line"
105
+ """
106
+
107
+ def __init__(
108
+ self,
109
+ name: str,
110
+ w_type: LvType,
111
+ parts: tuple,
112
+ schema=None,
113
+ modify_schema=None,
114
+ lv_name=None,
115
+ ):
116
+ """
117
+ :param name: The widget name, e.g. "bar"
118
+ :param w_type: The C type of the widget
119
+ :param parts: What parts this widget supports
120
+ :param schema: The config schema for defining a widget
121
+ :param modify_schema: A schema to update the widget
122
+ """
123
+ self.name = name
124
+ self.lv_name = lv_name or name
125
+ self.w_type = w_type
126
+ self.parts = parts
127
+ if schema is None:
128
+ self.schema = {}
129
+ else:
130
+ self.schema = schema
131
+ if modify_schema is None:
132
+ self.modify_schema = self.schema
133
+ else:
134
+ self.modify_schema = modify_schema
135
+ self.mock_obj = MockObj(f"lv_{self.lv_name}", "_")
136
+
137
+ @property
138
+ def animated(self):
139
+ return False
140
+
141
+ @property
142
+ def required_component(self):
143
+ return None
144
+
145
+ def is_compound(self):
146
+ return self.w_type.inherits_from(LvCompound)
147
+
148
+ async def to_code(self, w, config: dict):
149
+ """
150
+ Generate code for a given widget
151
+ :param w: The widget
152
+ :param config: Its configuration
153
+ :return: Generated code as a list of text lines
154
+ """
155
+ return []
156
+
157
+ def obj_creator(self, parent: MockObjClass, config: dict):
158
+ """
159
+ Create an instance of the widget type
160
+ :param parent: The parent to which it should be attached
161
+ :param config: Its configuration
162
+ :return: Generated code as a single text line
163
+ """
164
+ return lv_expr.call(f"{self.lv_name}_create", parent)
165
+
166
+ def get_uses(self):
167
+ """
168
+ Get a list of other widgets used by this one
169
+ :return:
170
+ """
171
+ return ()
172
+
173
+ def get_max(self, config: dict):
174
+ return sys.maxsize
175
+
176
+ def get_min(self, config: dict):
177
+ return -sys.maxsize
178
+
179
+ def get_step(self, config: dict):
180
+ return 1
181
+
182
+ def get_scale(self, config: dict):
183
+ return 1.0
184
+
185
+
186
+ class NumberType(WidgetType):
187
+ def get_max(self, config: dict):
188
+ return int(config[CONF_MAX_VALUE] or 100)
189
+
190
+ def get_min(self, config: dict):
191
+ return int(config[CONF_MIN_VALUE] or 0)