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,349 @@
1
+ import abc
2
+ from typing import Union
3
+
4
+ from esphome import codegen as cg
5
+ from esphome.config import Config
6
+ from esphome.core import CORE, ID, Lambda
7
+ from esphome.cpp_generator import (
8
+ AssignmentExpression,
9
+ CallExpression,
10
+ Expression,
11
+ ExpressionStatement,
12
+ LambdaExpression,
13
+ MockObj,
14
+ RawExpression,
15
+ RawStatement,
16
+ SafeExpType,
17
+ Statement,
18
+ VariableDeclarationExpression,
19
+ statement,
20
+ )
21
+ from esphome.yaml_util import ESPHomeDataBase
22
+
23
+ from .defines import literal, lvgl_ns
24
+
25
+ LVGL_COMP = "lv_component" # used as a lambda argument in lvgl_comp()
26
+
27
+ # Argument tuple for use in lambdas
28
+ LvglComponent = lvgl_ns.class_("LvglComponent", cg.PollingComponent)
29
+ LVGL_COMP_ARG = [(LvglComponent.operator("ptr"), LVGL_COMP)]
30
+ lv_event_t_ptr = cg.global_ns.namespace("lv_event_t").operator("ptr")
31
+ EVENT_ARG = [(lv_event_t_ptr, "ev")]
32
+ # Two custom events; API_EVENT is fired when an entity is updated remotely by an API interaction;
33
+ # UPDATE_EVENT is fired when an entity is programmatically updated locally.
34
+ # VALUE_CHANGED is the event generated by LVGL when an entity's value changes through user interaction.
35
+ API_EVENT = literal("lvgl::lv_api_event")
36
+ UPDATE_EVENT = literal("lvgl::lv_update_event")
37
+
38
+
39
+ def get_line_marks(value) -> list:
40
+ """
41
+ If possible, return a preprocessor directive to identify the line number where the given id was defined.
42
+ :param value: The id or other token to get the line number for
43
+ :return: A list containing zero or more line directives
44
+ """
45
+ path = None
46
+ if isinstance(value, ESPHomeDataBase):
47
+ path = value.esp_range
48
+ elif isinstance(value, ID) and isinstance(CORE.config, Config):
49
+ path = CORE.config.get_path_for_id(value)[:-1]
50
+ path = CORE.config.get_deepest_document_range_for_path(path)
51
+ if path is None:
52
+ return []
53
+ return [path.start_mark.as_line_directive]
54
+
55
+
56
+ class IndentedStatement(Statement):
57
+ def __init__(self, stmt: Statement, indent: int):
58
+ self.statement = stmt
59
+ self.indent = indent
60
+
61
+ def __str__(self):
62
+ result = " " * self.indent * 4 + str(self.statement).strip()
63
+ if not isinstance(self.statement, RawStatement):
64
+ result += ";"
65
+ return result
66
+
67
+
68
+ class CodeContext(abc.ABC):
69
+ """
70
+ A class providing a context for code generation. Generated code will be added to the
71
+ current context. A new context will stack on the current context, and restore it
72
+ when done. Used with the `with` statement.
73
+ """
74
+
75
+ code_context = None
76
+
77
+ @abc.abstractmethod
78
+ def add(self, expression: Union[Expression, Statement]):
79
+ pass
80
+
81
+ @staticmethod
82
+ def start_block():
83
+ CodeContext.append(RawStatement("{"))
84
+ CodeContext.code_context.indent()
85
+
86
+ @staticmethod
87
+ def end_block():
88
+ CodeContext.code_context.detent()
89
+ CodeContext.append(RawStatement("}"))
90
+
91
+ @staticmethod
92
+ def append(expression: Union[Expression, Statement]):
93
+ if CodeContext.code_context is not None:
94
+ CodeContext.code_context.add(expression)
95
+ return expression
96
+
97
+ def __init__(self):
98
+ self.previous: Union[CodeContext | None] = None
99
+ self.indent_level = 0
100
+
101
+ async def __aenter__(self):
102
+ self.previous = CodeContext.code_context
103
+ CodeContext.code_context = self
104
+ return self
105
+
106
+ async def __aexit__(self, *args):
107
+ CodeContext.code_context = self.previous
108
+
109
+ def indent(self):
110
+ self.indent_level += 1
111
+
112
+ def detent(self):
113
+ self.indent_level -= 1
114
+
115
+ def indented_statement(self, stmt):
116
+ return IndentedStatement(stmt, self.indent_level)
117
+
118
+
119
+ class MainContext(CodeContext):
120
+ """
121
+ Code generation into the main() function
122
+ """
123
+
124
+ def add(self, expression: Union[Expression, Statement]):
125
+ return cg.add(self.indented_statement(expression))
126
+
127
+
128
+ class LambdaContext(CodeContext):
129
+ """
130
+ A context that will accumlate code for use in a lambda.
131
+ """
132
+
133
+ def __init__(
134
+ self,
135
+ parameters: list[tuple[SafeExpType, str]] = None,
136
+ return_type: SafeExpType = cg.void,
137
+ capture: str = "",
138
+ where=None,
139
+ ):
140
+ super().__init__()
141
+ self.code_list: list[Statement] = []
142
+ self.parameters = parameters or []
143
+ self.return_type = return_type
144
+ self.capture = capture
145
+ self.where = where
146
+
147
+ def add(self, expression: Union[Expression, Statement]):
148
+ self.code_list.append(self.indented_statement(expression))
149
+ return expression
150
+
151
+ async def get_lambda(self) -> LambdaExpression:
152
+ code_text = self.get_code()
153
+ return await cg.process_lambda(
154
+ Lambda("\n".join(code_text) + "\n"),
155
+ self.parameters,
156
+ capture=self.capture,
157
+ return_type=self.return_type,
158
+ )
159
+
160
+ def get_code(self):
161
+ code_text = []
162
+ for exp in self.code_list:
163
+ text = str(statement(exp))
164
+ text = text.rstrip()
165
+ code_text.append(text)
166
+ return code_text
167
+
168
+ async def __aenter__(self):
169
+ await super().__aenter__()
170
+ add_line_marks(self.where)
171
+ return self
172
+
173
+
174
+ class LvContext(LambdaContext):
175
+ """
176
+ Code generation into the LVGL initialisation code (called in `setup()`)
177
+ """
178
+
179
+ def __init__(self, lv_component, args=None):
180
+ self.args = args or LVGL_COMP_ARG
181
+ super().__init__(parameters=self.args)
182
+ self.lv_component = lv_component
183
+
184
+ async def add_init_lambda(self):
185
+ cg.add(self.lv_component.add_init_lambda(await self.get_lambda()))
186
+
187
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
188
+ await super().__aexit__(exc_type, exc_val, exc_tb)
189
+ await self.add_init_lambda()
190
+
191
+ def add(self, expression: Union[Expression, Statement]):
192
+ self.code_list.append(self.indented_statement(expression))
193
+ return expression
194
+
195
+ def __call__(self, *args):
196
+ return self.add(*args)
197
+
198
+
199
+ class LocalVariable(MockObj):
200
+ """
201
+ Create a local variable and enclose the code using it within a block.
202
+ """
203
+
204
+ def __init__(self, name, type, rhs=None, modifier="*"):
205
+ base = ID(name + "_VAR_", True, type)
206
+ super().__init__(base, "")
207
+ self.modifier = modifier
208
+ self.rhs = rhs
209
+
210
+ def __enter__(self):
211
+ CodeContext.start_block()
212
+ CodeContext.append(
213
+ VariableDeclarationExpression(self.base.type, self.modifier, self.base.id)
214
+ )
215
+ if self.rhs is not None:
216
+ CodeContext.append(AssignmentExpression(None, "", self.base, self.rhs))
217
+ return MockObj(self.base)
218
+
219
+ def __exit__(self, *args):
220
+ CodeContext.end_block()
221
+
222
+
223
+ class MockLv:
224
+ """
225
+ A mock object that can be used to generate LVGL calls.
226
+ """
227
+
228
+ def __init__(self, base):
229
+ self.base = base
230
+
231
+ def __getattr__(self, attr: str) -> "MockLv":
232
+ return MockLv(f"{self.base}{attr}")
233
+
234
+ def append(self, expression):
235
+ CodeContext.append(expression)
236
+
237
+ def __call__(self, *args: SafeExpType) -> "MockObj":
238
+ call = CallExpression(self.base, *args)
239
+ result = MockObj(call, "")
240
+ self.append(result)
241
+ return result
242
+
243
+ def __str__(self):
244
+ return str(self.base)
245
+
246
+ def __repr__(self):
247
+ return f"MockLv<{str(self.base)}>"
248
+
249
+ def call(self, prop, *args):
250
+ call = CallExpression(RawExpression(f"{self.base}{prop}"), *args)
251
+ result = MockObj(call, "")
252
+ self.append(result)
253
+ return result
254
+
255
+
256
+ class LvConditional:
257
+ def __init__(self, condition):
258
+ self.condition = condition
259
+
260
+ def __enter__(self):
261
+ if self.condition is not None:
262
+ CodeContext.append(RawStatement(f"if ({self.condition}) {{"))
263
+ CodeContext.code_context.indent()
264
+ return self
265
+
266
+ def __exit__(self, *args):
267
+ if self.condition is not None:
268
+ CodeContext.code_context.detent()
269
+ CodeContext.append(RawStatement("}"))
270
+
271
+ def else_(self):
272
+ assert self.condition is not None
273
+ CodeContext.code_context.detent()
274
+ CodeContext.append(RawStatement("} else {"))
275
+ CodeContext.code_context.indent()
276
+
277
+
278
+ class ReturnStatement(ExpressionStatement):
279
+ def __str__(self):
280
+ return f"return {self.expression};"
281
+
282
+
283
+ class LvExpr(MockLv):
284
+ def __getattr__(self, attr: str) -> "MockLv":
285
+ return LvExpr(f"{self.base}{attr}")
286
+
287
+ def append(self, expression):
288
+ pass
289
+
290
+
291
+ # Top level mock for generic lv_ calls to be recorded
292
+ lv = MockLv("lv_")
293
+ # Just generate an expression
294
+ lv_expr = LvExpr("lv_")
295
+ # Mock for lv_obj_ calls
296
+ lv_obj = MockLv("lv_obj_")
297
+ # Operations on the LVGL component
298
+ lvgl_comp = MockObj(LVGL_COMP, "->")
299
+
300
+
301
+ # equivalent to cg.add() for the current code context
302
+ def lv_add(expression: Union[Expression, Statement]):
303
+ return CodeContext.append(expression)
304
+
305
+
306
+ def add_line_marks(where):
307
+ """
308
+ Add line marks for the current code context
309
+ :param where: An object to identify the source of the line marks
310
+ :return:
311
+ """
312
+ for mark in get_line_marks(where):
313
+ lv_add(cg.RawStatement(mark))
314
+
315
+
316
+ def lv_assign(target, expression):
317
+ lv_add(AssignmentExpression("", "", target, expression))
318
+
319
+
320
+ def lv_Pvariable(type, name):
321
+ """
322
+ Create but do not initialise a pointer variable
323
+ :param type: Type of the variable target
324
+ :param name: name of the variable, or an ID
325
+ :return: A MockObj of the variable
326
+ """
327
+ if isinstance(name, str):
328
+ name = ID(name, True, type)
329
+ decl = VariableDeclarationExpression(type, "*", name)
330
+ CORE.add_global(decl)
331
+ var = MockObj(name, "->")
332
+ CORE.register_variable(name, var)
333
+ return var
334
+
335
+
336
+ def lv_variable(type, name):
337
+ """
338
+ Create but do not initialise a variable
339
+ :param type: Type of the variable target
340
+ :param name: name of the variable, or an ID
341
+ :return: A MockObj of the variable
342
+ """
343
+ if isinstance(name, str):
344
+ name = ID(name, True, type)
345
+ decl = VariableDeclarationExpression(type, "", name)
346
+ CORE.add_global(decl)
347
+ var = MockObj(name, ".")
348
+ CORE.register_variable(name, var)
349
+ return var