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,419 @@
1
+ import sys
2
+ from typing import Any, Union
3
+
4
+ from esphome import codegen as cg, config_validation as cv
5
+ from esphome.config_validation import Invalid
6
+ from esphome.const import CONF_GROUP, CONF_ID, CONF_STATE, CONF_TYPE
7
+ from esphome.core import ID, TimePeriod
8
+ from esphome.coroutine import FakeAwaitable
9
+ from esphome.cpp_generator import CallExpression, MockObj
10
+
11
+ from ..defines import (
12
+ CONF_DEFAULT,
13
+ CONF_FLEX_ALIGN_CROSS,
14
+ CONF_FLEX_ALIGN_MAIN,
15
+ CONF_FLEX_ALIGN_TRACK,
16
+ CONF_FLEX_FLOW,
17
+ CONF_GRID_COLUMN_ALIGN,
18
+ CONF_GRID_COLUMNS,
19
+ CONF_GRID_ROW_ALIGN,
20
+ CONF_GRID_ROWS,
21
+ CONF_LAYOUT,
22
+ CONF_MAIN,
23
+ CONF_PAD_COLUMN,
24
+ CONF_PAD_ROW,
25
+ CONF_SCROLLBAR_MODE,
26
+ CONF_STYLES,
27
+ CONF_WIDGETS,
28
+ OBJ_FLAGS,
29
+ PARTS,
30
+ STATES,
31
+ TYPE_FLEX,
32
+ TYPE_GRID,
33
+ LValidator,
34
+ call_lambda,
35
+ join_enums,
36
+ literal,
37
+ )
38
+ from ..helpers import add_lv_use
39
+ from ..lvcode import (
40
+ LvConditional,
41
+ add_line_marks,
42
+ lv,
43
+ lv_add,
44
+ lv_assign,
45
+ lv_expr,
46
+ lv_obj,
47
+ lv_Pvariable,
48
+ )
49
+ from ..schemas import ALL_STYLES, STYLE_REMAP, WIDGET_TYPES
50
+ from ..types import LV_STATE, LvType, WidgetType, lv_coord_t, lv_obj_t, lv_obj_t_ptr
51
+
52
+ EVENT_LAMB = "event_lamb__"
53
+
54
+ theme_widget_map = {}
55
+
56
+
57
+ class LvScrActType(WidgetType):
58
+ """
59
+ A "widget" representing the active screen.
60
+ """
61
+
62
+ def __init__(self):
63
+ super().__init__("lv_scr_act()", lv_obj_t, ())
64
+
65
+ async def to_code(self, w, config: dict):
66
+ return []
67
+
68
+
69
+ class Widget:
70
+ """
71
+ Represents a Widget.
72
+ """
73
+
74
+ widgets_completed = False
75
+
76
+ @staticmethod
77
+ def set_completed():
78
+ Widget.widgets_completed = True
79
+
80
+ def __init__(self, var, wtype: WidgetType, config: dict = None):
81
+ self.var = var
82
+ self.type = wtype
83
+ self.config = config
84
+ self.scale = 1.0
85
+ self.step = 1.0
86
+ self.range_from = -sys.maxsize
87
+ self.range_to = sys.maxsize
88
+ if wtype.is_compound():
89
+ self.obj = MockObj(f"{self.var}->obj")
90
+ else:
91
+ self.obj = var
92
+
93
+ @staticmethod
94
+ def create(name, var, wtype: WidgetType, config: dict = None):
95
+ w = Widget(var, wtype, config)
96
+ if name is not None:
97
+ widget_map[name] = w
98
+ return w
99
+
100
+ def add_state(self, state):
101
+ return lv_obj.add_state(self.obj, literal(state))
102
+
103
+ def clear_state(self, state):
104
+ return lv_obj.clear_state(self.obj, literal(state))
105
+
106
+ def has_state(self, state):
107
+ return (lv_expr.obj_get_state(self.obj) & literal(state)) != 0
108
+
109
+ def is_pressed(self):
110
+ return self.has_state(LV_STATE.PRESSED)
111
+
112
+ def is_checked(self):
113
+ return self.has_state(LV_STATE.CHECKED)
114
+
115
+ def add_flag(self, flag):
116
+ return lv_obj.add_flag(self.obj, literal(flag))
117
+
118
+ def clear_flag(self, flag):
119
+ return lv_obj.clear_flag(self.obj, literal(flag))
120
+
121
+ async def set_property(self, prop, value, animated: bool = None):
122
+ if isinstance(value, dict):
123
+ value = value.get(prop)
124
+ if isinstance(ALL_STYLES.get(prop), LValidator):
125
+ value = await ALL_STYLES[prop].process(value)
126
+ else:
127
+ value = literal(value)
128
+ if value is None:
129
+ return
130
+ if isinstance(value, TimePeriod):
131
+ value = value.total_milliseconds
132
+ if isinstance(value, str):
133
+ value = literal(value)
134
+ if animated is None or self.type.animated is not True:
135
+ lv.call(f"{self.type.lv_name}_set_{prop}", self.obj, value)
136
+ else:
137
+ lv.call(
138
+ f"{self.type.lv_name}_set_{prop}",
139
+ self.obj,
140
+ value,
141
+ literal("LV_ANIM_ON" if animated else "LV_ANIM_OFF"),
142
+ )
143
+
144
+ def get_property(self, prop, ltype=None):
145
+ ltype = ltype or self.__type_base()
146
+ return cg.RawExpression(f"lv_{ltype}_get_{prop}({self.obj})")
147
+
148
+ def set_style(self, prop, value, state):
149
+ if value is None:
150
+ return
151
+ lv.call(f"obj_set_style_{prop}", self.obj, value, state)
152
+
153
+ def __type_base(self):
154
+ wtype = self.type.w_type
155
+ base = str(wtype)
156
+ if base.startswith("Lv"):
157
+ return f"{wtype}".removeprefix("Lv").removesuffix("Type").lower()
158
+ return f"{wtype}".removeprefix("lv_").removesuffix("_t")
159
+
160
+ def __str__(self):
161
+ return f"({self.var}, {self.type})"
162
+
163
+ def get_args(self):
164
+ if isinstance(self.type.w_type, LvType):
165
+ return self.type.w_type.args
166
+ return [(lv_obj_t_ptr, "obj")]
167
+
168
+ def get_value(self):
169
+ if isinstance(self.type.w_type, LvType):
170
+ return self.type.w_type.value(self)
171
+ return self.obj
172
+
173
+ def get_number_value(self):
174
+ value = self.type.mock_obj.get_value(self.obj)
175
+ if self.scale == 1.0:
176
+ return value
177
+ return value / float(self.scale)
178
+
179
+ def is_selected(self):
180
+ """
181
+ Overridable property to determine if the widget is selected. Will be None except
182
+ for matrix buttons
183
+ :return:
184
+ """
185
+ return None
186
+
187
+ def get_max(self):
188
+ return self.type.get_max(self.config)
189
+
190
+ def get_min(self):
191
+ return self.type.get_min(self.config)
192
+
193
+ def get_step(self):
194
+ return self.type.get_step(self.config)
195
+
196
+ def get_scale(self):
197
+ return self.type.get_scale(self.config)
198
+
199
+
200
+ # Map of widgets to their config, used for trigger generation
201
+ widget_map: dict[Any, Widget] = {}
202
+
203
+
204
+ def get_widget_generator(wid):
205
+ """
206
+ Used to wait for a widget during code generation.
207
+ :param wid:
208
+ :return:
209
+ """
210
+ while True:
211
+ if obj := widget_map.get(wid):
212
+ return obj
213
+ if Widget.widgets_completed:
214
+ raise Invalid(
215
+ f"Widget {wid} not found, yet all widgets should be defined by now"
216
+ )
217
+ yield
218
+
219
+
220
+ async def get_widget_(wid: Widget):
221
+ if obj := widget_map.get(wid):
222
+ return obj
223
+ return await FakeAwaitable(get_widget_generator(wid))
224
+
225
+
226
+ async def get_widgets(config: Union[dict, list], id: str = CONF_ID) -> list[Widget]:
227
+ if not config:
228
+ return []
229
+ if not isinstance(config, list):
230
+ config = [config]
231
+ return [await get_widget_(c[id]) for c in config if id in c]
232
+
233
+
234
+ def collect_props(config):
235
+ """
236
+ Collect all properties from a configuration
237
+ :param config:
238
+ :return:
239
+ """
240
+ props = {}
241
+ for prop in [*ALL_STYLES, *OBJ_FLAGS, CONF_STYLES, CONF_GROUP]:
242
+ if prop in config:
243
+ props[prop] = config[prop]
244
+ return props
245
+
246
+
247
+ def collect_states(config):
248
+ """
249
+ Collect prperties for each state of a widget
250
+ :param config:
251
+ :return:
252
+ """
253
+ states = {CONF_DEFAULT: collect_props(config)}
254
+ for state in STATES:
255
+ if state in config:
256
+ states[state] = collect_props(config[state])
257
+ return states
258
+
259
+
260
+ def collect_parts(config):
261
+ """
262
+ Collect properties and states for all widget parts
263
+ :param config:
264
+ :return:
265
+ """
266
+ parts = {CONF_MAIN: collect_states(config)}
267
+ for part in PARTS:
268
+ if part in config:
269
+ parts[part] = collect_states(config[part])
270
+ return parts
271
+
272
+
273
+ async def set_obj_properties(w: Widget, config):
274
+ """Generate a list of C++ statements to apply properties to an lv_obj_t"""
275
+ if layout := config.get(CONF_LAYOUT):
276
+ layout_type: str = layout[CONF_TYPE]
277
+ add_lv_use(layout_type)
278
+ lv_obj.set_layout(w.obj, literal(f"LV_LAYOUT_{layout_type.upper()}"))
279
+ if (pad_row := layout.get(CONF_PAD_ROW)) is not None:
280
+ w.set_style(CONF_PAD_ROW, pad_row, 0)
281
+ if (pad_column := layout.get(CONF_PAD_COLUMN)) is not None:
282
+ w.set_style(CONF_PAD_COLUMN, pad_column, 0)
283
+ if layout_type == TYPE_GRID:
284
+ wid = config[CONF_ID]
285
+ rows = [str(x) for x in layout[CONF_GRID_ROWS]]
286
+ rows = "{" + ",".join(rows) + ", LV_GRID_TEMPLATE_LAST}"
287
+ row_id = ID(f"{wid}_row_dsc", is_declaration=True, type=lv_coord_t)
288
+ row_array = cg.static_const_array(row_id, cg.RawExpression(rows))
289
+ w.set_style("grid_row_dsc_array", row_array, 0)
290
+ columns = [str(x) for x in layout[CONF_GRID_COLUMNS]]
291
+ columns = "{" + ",".join(columns) + ", LV_GRID_TEMPLATE_LAST}"
292
+ column_id = ID(f"{wid}_column_dsc", is_declaration=True, type=lv_coord_t)
293
+ column_array = cg.static_const_array(column_id, cg.RawExpression(columns))
294
+ w.set_style("grid_column_dsc_array", column_array, 0)
295
+ w.set_style(
296
+ CONF_GRID_COLUMN_ALIGN, literal(layout.get(CONF_GRID_COLUMN_ALIGN)), 0
297
+ )
298
+ w.set_style(
299
+ CONF_GRID_ROW_ALIGN, literal(layout.get(CONF_GRID_ROW_ALIGN)), 0
300
+ )
301
+ if layout_type == TYPE_FLEX:
302
+ lv_obj.set_flex_flow(w.obj, literal(layout[CONF_FLEX_FLOW]))
303
+ main = literal(layout[CONF_FLEX_ALIGN_MAIN])
304
+ cross = literal(layout[CONF_FLEX_ALIGN_CROSS])
305
+ track = literal(layout[CONF_FLEX_ALIGN_TRACK])
306
+ lv_obj.set_flex_align(w.obj, main, cross, track)
307
+ parts = collect_parts(config)
308
+ for part, states in parts.items():
309
+ for state, props in states.items():
310
+ lv_state = join_enums((f"LV_STATE_{state}", f"LV_PART_{part}"))
311
+ for style_id in props.get(CONF_STYLES, ()):
312
+ lv_obj.add_style(w.obj, MockObj(style_id), lv_state)
313
+ for prop, value in {
314
+ k: v for k, v in props.items() if k in ALL_STYLES
315
+ }.items():
316
+ if isinstance(ALL_STYLES[prop], LValidator):
317
+ value = await ALL_STYLES[prop].process(value)
318
+ prop_r = STYLE_REMAP.get(prop, prop)
319
+ w.set_style(prop_r, value, lv_state)
320
+ if group := config.get(CONF_GROUP):
321
+ group = await cg.get_variable(group)
322
+ lv.group_add_obj(group, w.obj)
323
+ flag_clr = set()
324
+ flag_set = set()
325
+ props = parts[CONF_MAIN][CONF_DEFAULT]
326
+ lambs = {}
327
+ flag_set = set()
328
+ flag_clr = set()
329
+ for prop, value in {k: v for k, v in props.items() if k in OBJ_FLAGS}.items():
330
+ if isinstance(value, cv.Lambda):
331
+ lambs[prop] = value
332
+ elif value:
333
+ flag_set.add(prop)
334
+ else:
335
+ flag_clr.add(prop)
336
+ if flag_set:
337
+ adds = join_enums(flag_set, "LV_OBJ_FLAG_")
338
+ w.add_flag(adds)
339
+ if flag_clr:
340
+ clrs = join_enums(flag_clr, "LV_OBJ_FLAG_")
341
+ w.clear_flag(clrs)
342
+ for key, value in lambs.items():
343
+ lamb = await cg.process_lambda(value, [], return_type=cg.bool_)
344
+ flag = f"LV_OBJ_FLAG_{key.upper()}"
345
+ with LvConditional(call_lambda(lamb)) as cond:
346
+ w.add_flag(flag)
347
+ cond.else_()
348
+ w.clear_flag(flag)
349
+
350
+ if states := config.get(CONF_STATE):
351
+ adds = set()
352
+ clears = set()
353
+ lambs = {}
354
+ for key, value in states.items():
355
+ if isinstance(value, cv.Lambda):
356
+ lambs[key] = value
357
+ elif value:
358
+ adds.add(key)
359
+ else:
360
+ clears.add(key)
361
+ if adds:
362
+ adds = join_enums(adds, "LV_STATE_")
363
+ w.add_state(adds)
364
+ if clears:
365
+ clears = join_enums(clears, "LV_STATE_")
366
+ w.clear_state(clears)
367
+ for key, value in lambs.items():
368
+ lamb = await cg.process_lambda(value, [], return_type=cg.bool_)
369
+ state = f"LV_STATE_{key.upper()}"
370
+ with LvConditional(call_lambda(lamb)) as cond:
371
+ w.add_state(state)
372
+ cond.else_()
373
+ w.clear_state(state)
374
+ await w.set_property(CONF_SCROLLBAR_MODE, config)
375
+
376
+
377
+ async def add_widgets(parent: Widget, config: dict):
378
+ """
379
+ Add all widgets to an object
380
+ :param parent: The enclosing obj
381
+ :param config: The configuration
382
+ :return:
383
+ """
384
+ for w in config.get(CONF_WIDGETS, ()):
385
+ w_type, w_cnfig = next(iter(w.items()))
386
+ await widget_to_code(w_cnfig, w_type, parent.obj)
387
+
388
+
389
+ async def widget_to_code(w_cnfig, w_type: WidgetType, parent):
390
+ """
391
+ Converts a Widget definition to C code.
392
+ :param w_cnfig: The widget configuration
393
+ :param w_type: The Widget type
394
+ :param parent: The parent to which the widget should be added
395
+ :return:
396
+ """
397
+ spec: WidgetType = WIDGET_TYPES[w_type]
398
+ creator = spec.obj_creator(parent, w_cnfig)
399
+ add_lv_use(spec.name)
400
+ add_lv_use(*spec.get_uses())
401
+ wid = w_cnfig[CONF_ID]
402
+ add_line_marks(wid)
403
+ if spec.is_compound():
404
+ var = cg.new_Pvariable(wid)
405
+ lv_add(var.set_obj(creator))
406
+ else:
407
+ var = lv_Pvariable(lv_obj_t, wid)
408
+ lv_assign(var, creator)
409
+
410
+ w = Widget.create(wid, var, spec, w_cnfig)
411
+ if theme := theme_widget_map.get(w_type):
412
+ lv_add(CallExpression(theme, w.obj))
413
+ await set_obj_properties(w, w_cnfig)
414
+ await add_widgets(w, w_cnfig)
415
+ await spec.to_code(w, w_cnfig)
416
+
417
+
418
+ lv_scr_act_spec = LvScrActType()
419
+ lv_scr_act = Widget.create(None, literal("lv_scr_act()"), lv_scr_act_spec, {})
@@ -0,0 +1,117 @@
1
+ from esphome import automation
2
+ import esphome.codegen as cg
3
+ import esphome.config_validation as cv
4
+ from esphome.const import CONF_DURATION, CONF_ID
5
+ from esphome.cpp_generator import MockObj
6
+
7
+ from ..automation import action_to_code
8
+ from ..defines import CONF_AUTO_START, CONF_MAIN, CONF_REPEAT_COUNT, CONF_SRC
9
+ from ..helpers import lvgl_components_required
10
+ from ..lv_validation import lv_image, lv_milliseconds
11
+ from ..lvcode import lv, lv_expr
12
+ from ..types import LvType, ObjUpdateAction, void_ptr
13
+ from . import Widget, WidgetType, get_widgets
14
+ from .img import CONF_IMAGE
15
+ from .label import CONF_LABEL
16
+
17
+ CONF_ANIMIMG = "animimg"
18
+ CONF_SRC_LIST_ID = "src_list_id"
19
+
20
+
21
+ def lv_repeat_count(value):
22
+ if isinstance(value, str) and value.lower() in ("forever", "infinite"):
23
+ value = 0xFFFF
24
+ return cv.int_range(min=0, max=0xFFFF)(value)
25
+
26
+
27
+ ANIMIMG_BASE_SCHEMA = cv.Schema(
28
+ {
29
+ cv.Optional(CONF_REPEAT_COUNT, default="forever"): lv_repeat_count,
30
+ cv.Optional(CONF_AUTO_START, default=True): cv.boolean,
31
+ }
32
+ )
33
+ ANIMIMG_SCHEMA = ANIMIMG_BASE_SCHEMA.extend(
34
+ {
35
+ cv.Required(CONF_DURATION): lv_milliseconds,
36
+ cv.Required(CONF_SRC): cv.ensure_list(lv_image),
37
+ cv.GenerateID(CONF_SRC_LIST_ID): cv.declare_id(void_ptr),
38
+ }
39
+ )
40
+
41
+ ANIMIMG_MODIFY_SCHEMA = ANIMIMG_BASE_SCHEMA.extend(
42
+ {
43
+ cv.Optional(CONF_DURATION): lv_milliseconds,
44
+ }
45
+ )
46
+
47
+ lv_animimg_t = LvType("lv_animimg_t")
48
+
49
+
50
+ class AnimimgType(WidgetType):
51
+ def __init__(self):
52
+ super().__init__(
53
+ CONF_ANIMIMG,
54
+ lv_animimg_t,
55
+ (CONF_MAIN,),
56
+ ANIMIMG_SCHEMA,
57
+ ANIMIMG_MODIFY_SCHEMA,
58
+ )
59
+
60
+ async def to_code(self, w: Widget, config):
61
+ lvgl_components_required.add(CONF_IMAGE)
62
+ lvgl_components_required.add(CONF_ANIMIMG)
63
+ if CONF_SRC in config:
64
+ for x in config[CONF_SRC]:
65
+ await cg.get_variable(x)
66
+ srcs = [lv_expr.img_from(MockObj(x)) for x in config[CONF_SRC]]
67
+ src_id = cg.static_const_array(config[CONF_SRC_LIST_ID], srcs)
68
+ count = len(config[CONF_SRC])
69
+ lv.animimg_set_src(w.obj, src_id, count)
70
+ lv.animimg_set_repeat_count(w.obj, config[CONF_REPEAT_COUNT])
71
+ lv.animimg_set_duration(w.obj, config[CONF_DURATION])
72
+ if config.get(CONF_AUTO_START):
73
+ lv.animimg_start(w.obj)
74
+
75
+ def get_uses(self):
76
+ return CONF_IMAGE, CONF_LABEL
77
+
78
+
79
+ animimg_spec = AnimimgType()
80
+
81
+
82
+ @automation.register_action(
83
+ "lvgl.animimg.start",
84
+ ObjUpdateAction,
85
+ cv.maybe_simple_value(
86
+ {
87
+ cv.Required(CONF_ID): cv.use_id(lv_animimg_t),
88
+ },
89
+ key=CONF_ID,
90
+ ),
91
+ )
92
+ async def animimg_start(config, action_id, template_arg, args):
93
+ widget = await get_widgets(config)
94
+
95
+ async def do_start(w: Widget):
96
+ lv.animimg_start(w.obj)
97
+
98
+ return await action_to_code(widget, do_start, action_id, template_arg, args)
99
+
100
+
101
+ @automation.register_action(
102
+ "lvgl.animimg.stop",
103
+ ObjUpdateAction,
104
+ cv.maybe_simple_value(
105
+ {
106
+ cv.Required(CONF_ID): cv.use_id(lv_animimg_t),
107
+ },
108
+ key=CONF_ID,
109
+ ),
110
+ )
111
+ async def animimg_stop(config, action_id, template_arg, args):
112
+ widget = await get_widgets(config)
113
+
114
+ async def do_stop(w: Widget):
115
+ lv.animimg_stop(w.obj)
116
+
117
+ return await action_to_code(widget, do_stop, action_id, template_arg, args)
@@ -0,0 +1,78 @@
1
+ import esphome.config_validation as cv
2
+ from esphome.const import (
3
+ CONF_MAX_VALUE,
4
+ CONF_MIN_VALUE,
5
+ CONF_MODE,
6
+ CONF_ROTATION,
7
+ CONF_VALUE,
8
+ )
9
+ from esphome.cpp_types import nullptr
10
+
11
+ from ..defines import (
12
+ ARC_MODES,
13
+ CONF_ADJUSTABLE,
14
+ CONF_CHANGE_RATE,
15
+ CONF_END_ANGLE,
16
+ CONF_INDICATOR,
17
+ CONF_KNOB,
18
+ CONF_MAIN,
19
+ CONF_START_ANGLE,
20
+ literal,
21
+ )
22
+ from ..lv_validation import angle, get_start_value, lv_float
23
+ from ..lvcode import lv, lv_obj
24
+ from ..types import LvNumber, NumberType
25
+ from . import Widget
26
+
27
+ CONF_ARC = "arc"
28
+ ARC_SCHEMA = cv.Schema(
29
+ {
30
+ cv.Optional(CONF_VALUE): lv_float,
31
+ cv.Optional(CONF_MIN_VALUE, default=0): cv.int_,
32
+ cv.Optional(CONF_MAX_VALUE, default=100): cv.int_,
33
+ cv.Optional(CONF_START_ANGLE, default=135): angle,
34
+ cv.Optional(CONF_END_ANGLE, default=45): angle,
35
+ cv.Optional(CONF_ROTATION, default=0.0): angle,
36
+ cv.Optional(CONF_ADJUSTABLE, default=False): bool,
37
+ cv.Optional(CONF_MODE, default="NORMAL"): ARC_MODES.one_of,
38
+ cv.Optional(CONF_CHANGE_RATE, default=720): cv.uint16_t,
39
+ }
40
+ )
41
+
42
+ ARC_MODIFY_SCHEMA = cv.Schema(
43
+ {
44
+ cv.Optional(CONF_VALUE): lv_float,
45
+ }
46
+ )
47
+
48
+
49
+ class ArcType(NumberType):
50
+ def __init__(self):
51
+ super().__init__(
52
+ CONF_ARC,
53
+ LvNumber("lv_arc_t"),
54
+ parts=(CONF_MAIN, CONF_INDICATOR, CONF_KNOB),
55
+ schema=ARC_SCHEMA,
56
+ modify_schema=ARC_MODIFY_SCHEMA,
57
+ )
58
+
59
+ async def to_code(self, w: Widget, config):
60
+ if CONF_MIN_VALUE in config:
61
+ lv.arc_set_range(w.obj, config[CONF_MIN_VALUE], config[CONF_MAX_VALUE])
62
+ lv.arc_set_bg_angles(
63
+ w.obj, config[CONF_START_ANGLE] // 10, config[CONF_END_ANGLE] // 10
64
+ )
65
+ lv.arc_set_rotation(w.obj, config[CONF_ROTATION] // 10)
66
+ lv.arc_set_mode(w.obj, literal(config[CONF_MODE]))
67
+ lv.arc_set_change_rate(w.obj, config[CONF_CHANGE_RATE])
68
+
69
+ if config.get(CONF_ADJUSTABLE) is False:
70
+ lv_obj.remove_style(w.obj, nullptr, literal("LV_PART_KNOB"))
71
+ w.clear_flag("LV_OBJ_FLAG_CLICKABLE")
72
+
73
+ value = await get_start_value(config)
74
+ if value is not None:
75
+ lv.arc_set_value(w.obj, value)
76
+
77
+
78
+ arc_spec = ArcType()
@@ -0,0 +1,20 @@
1
+ from esphome.const import CONF_BUTTON
2
+
3
+ from ..defines import CONF_MAIN
4
+ from ..types import LvBoolean, WidgetType
5
+
6
+ lv_button_t = LvBoolean("lv_btn_t")
7
+
8
+
9
+ class ButtonType(WidgetType):
10
+ def __init__(self):
11
+ super().__init__(CONF_BUTTON, lv_button_t, (CONF_MAIN,), lv_name="btn")
12
+
13
+ def get_uses(self):
14
+ return ("btn",)
15
+
16
+ async def to_code(self, w, config):
17
+ return []
18
+
19
+
20
+ button_spec = ButtonType()