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,275 @@
1
+ from esphome import automation
2
+ import esphome.codegen as cg
3
+ from esphome.components.key_provider import KeyProvider
4
+ import esphome.config_validation as cv
5
+ from esphome.const import CONF_ID, CONF_ITEMS, CONF_TEXT, CONF_WIDTH
6
+ from esphome.cpp_generator import MockObj
7
+
8
+ from ..automation import action_to_code
9
+ from ..defines import (
10
+ BUTTONMATRIX_CTRLS,
11
+ CONF_BUTTONS,
12
+ CONF_CONTROL,
13
+ CONF_KEY_CODE,
14
+ CONF_MAIN,
15
+ CONF_ONE_CHECKED,
16
+ CONF_ROWS,
17
+ CONF_SELECTED,
18
+ )
19
+ from ..helpers import lvgl_components_required
20
+ from ..lv_validation import key_code, lv_bool
21
+ from ..lvcode import lv, lv_add, lv_expr
22
+ from ..schemas import automation_schema
23
+ from ..types import (
24
+ LV_BTNMATRIX_CTRL,
25
+ LV_STATE,
26
+ LvBoolean,
27
+ LvCompound,
28
+ LvType,
29
+ ObjUpdateAction,
30
+ char_ptr,
31
+ lv_pseudo_button_t,
32
+ )
33
+ from . import Widget, WidgetType, get_widgets, widget_map
34
+ from .button import lv_button_t
35
+
36
+ CONF_BUTTONMATRIX = "buttonmatrix"
37
+ CONF_BUTTON_TEXT_LIST_ID = "button_text_list_id"
38
+
39
+ LvButtonMatrixButton = LvBoolean(
40
+ str(cg.uint16),
41
+ parents=(lv_pseudo_button_t,),
42
+ )
43
+ BUTTONMATRIX_BUTTON_SCHEMA = cv.Schema(
44
+ {
45
+ cv.Optional(CONF_TEXT): cv.string,
46
+ cv.Optional(CONF_KEY_CODE): key_code,
47
+ cv.GenerateID(): cv.declare_id(LvButtonMatrixButton),
48
+ cv.Optional(CONF_WIDTH, default=1): cv.positive_int,
49
+ cv.Optional(CONF_CONTROL): cv.ensure_list(
50
+ cv.Schema(
51
+ {cv.Optional(k.lower()): cv.boolean for k in BUTTONMATRIX_CTRLS.choices}
52
+ )
53
+ ),
54
+ }
55
+ ).extend(automation_schema(lv_button_t))
56
+
57
+ BUTTONMATRIX_SCHEMA = cv.Schema(
58
+ {
59
+ cv.Optional(CONF_ONE_CHECKED, default=False): lv_bool,
60
+ cv.GenerateID(CONF_BUTTON_TEXT_LIST_ID): cv.declare_id(char_ptr),
61
+ cv.Required(CONF_ROWS): cv.ensure_list(
62
+ cv.Schema(
63
+ {
64
+ cv.Required(CONF_BUTTONS): cv.ensure_list(
65
+ BUTTONMATRIX_BUTTON_SCHEMA
66
+ ),
67
+ }
68
+ )
69
+ ),
70
+ }
71
+ )
72
+
73
+
74
+ class ButtonmatrixButtonType(WidgetType):
75
+ """
76
+ A pseudo-widget for the matrix buttons
77
+ """
78
+
79
+ def __init__(self):
80
+ super().__init__("btnmatrix_btn", LvButtonMatrixButton, (), {}, {})
81
+
82
+ async def to_code(self, w, config: dict):
83
+ return []
84
+
85
+
86
+ btn_btn_spec = ButtonmatrixButtonType()
87
+
88
+
89
+ class MatrixButton(Widget):
90
+ """
91
+ Describes a button within a button matrix.
92
+ """
93
+
94
+ @staticmethod
95
+ def create_button(id, parent, config: dict, index):
96
+ w = MatrixButton(id, parent, config, index)
97
+ widget_map[id] = w
98
+ return w
99
+
100
+ def __init__(self, id, parent: Widget, config, index):
101
+ super().__init__(id, btn_btn_spec, config)
102
+ self.parent = parent
103
+ self.index = index
104
+ self.obj = parent.obj
105
+
106
+ def is_selected(self):
107
+ return self.parent.var.get_selected() == MockObj(self.var)
108
+
109
+ @staticmethod
110
+ def map_ctrls(state):
111
+ state = str(state).upper().removeprefix("LV_STATE_")
112
+ assert state in BUTTONMATRIX_CTRLS.choices
113
+ return getattr(LV_BTNMATRIX_CTRL, state)
114
+
115
+ def has_state(self, state):
116
+ state = self.map_ctrls(state)
117
+ return lv_expr.btnmatrix_has_btn_ctrl(self.obj, self.index, state)
118
+
119
+ def add_state(self, state):
120
+ state = self.map_ctrls(state)
121
+ return lv.btnmatrix_set_btn_ctrl(self.obj, self.index, state)
122
+
123
+ def clear_state(self, state):
124
+ state = self.map_ctrls(state)
125
+ return lv.btnmatrix_clear_btn_ctrl(self.obj, self.index, state)
126
+
127
+ def is_pressed(self):
128
+ return self.is_selected() & self.parent.has_state(LV_STATE.PRESSED)
129
+
130
+ def is_checked(self):
131
+ return self.has_state(LV_STATE.CHECKED)
132
+
133
+ def get_value(self):
134
+ return self.is_checked()
135
+
136
+ def check_null(self):
137
+ return None
138
+
139
+
140
+ async def get_button_data(config, buttonmatrix: Widget):
141
+ """
142
+ Process a button matrix button list
143
+ :param config: The row list
144
+ :param buttonmatrix: The parent variable
145
+ :return: text array id, control list, width list
146
+ """
147
+ text_list = []
148
+ ctrl_list = []
149
+ width_list = []
150
+ key_list = []
151
+ for row in config:
152
+ for button_conf in row.get(CONF_BUTTONS, ()):
153
+ bid = button_conf[CONF_ID]
154
+ index = len(width_list)
155
+ MatrixButton.create_button(bid, buttonmatrix, button_conf, index)
156
+ cg.new_variable(bid, index)
157
+ text_list.append(button_conf.get(CONF_TEXT) or "")
158
+ key_list.append(button_conf.get(CONF_KEY_CODE) or 0)
159
+ width_list.append(button_conf[CONF_WIDTH])
160
+ ctrl = ["LV_BTNMATRIX_CTRL_CLICK_TRIG"]
161
+ for item in button_conf.get(CONF_CONTROL, ()):
162
+ ctrl.extend([k for k, v in item.items() if v])
163
+ ctrl_list.append(await BUTTONMATRIX_CTRLS.process(ctrl))
164
+ text_list.append("\n")
165
+ text_list = text_list[:-1]
166
+ text_list.append(cg.nullptr)
167
+ return text_list, ctrl_list, width_list, key_list
168
+
169
+
170
+ lv_buttonmatrix_t = LvType(
171
+ "LvButtonMatrixType",
172
+ parents=(KeyProvider, LvCompound),
173
+ largs=[(cg.uint16, "x")],
174
+ lvalue=lambda w: w.var.get_selected(),
175
+ )
176
+
177
+
178
+ class ButtonMatrixType(WidgetType):
179
+ def __init__(self):
180
+ super().__init__(
181
+ CONF_BUTTONMATRIX,
182
+ lv_buttonmatrix_t,
183
+ (CONF_MAIN, CONF_ITEMS),
184
+ BUTTONMATRIX_SCHEMA,
185
+ {},
186
+ lv_name="btnmatrix",
187
+ )
188
+
189
+ async def to_code(self, w: Widget, config):
190
+ lvgl_components_required.add("BUTTONMATRIX")
191
+ if CONF_ROWS not in config:
192
+ return []
193
+ text_list, ctrl_list, width_list, key_list = await get_button_data(
194
+ config[CONF_ROWS], w
195
+ )
196
+ text_id = config[CONF_BUTTON_TEXT_LIST_ID]
197
+ text_id = cg.static_const_array(text_id, text_list)
198
+ lv.btnmatrix_set_map(w.obj, text_id)
199
+ set_btn_data(w.obj, ctrl_list, width_list)
200
+ lv.btnmatrix_set_one_checked(w.obj, config[CONF_ONE_CHECKED])
201
+ for index, key in enumerate(key_list):
202
+ if key != 0:
203
+ lv_add(w.var.set_key(index, key))
204
+
205
+ def get_uses(self):
206
+ return ("btnmatrix",)
207
+
208
+
209
+ def set_btn_data(obj, ctrl_list, width_list):
210
+ for index, ctrl in enumerate(ctrl_list):
211
+ lv.btnmatrix_set_btn_ctrl(obj, index, ctrl)
212
+ for index, width in enumerate(width_list):
213
+ lv.btnmatrix_set_btn_width(obj, index, width)
214
+
215
+
216
+ buttonmatrix_spec = ButtonMatrixType()
217
+
218
+
219
+ @automation.register_action(
220
+ "lvgl.matrix.button.update",
221
+ ObjUpdateAction,
222
+ cv.Schema(
223
+ {
224
+ cv.Optional(CONF_WIDTH): cv.positive_int,
225
+ cv.Optional(CONF_CONTROL): cv.ensure_list(
226
+ cv.Schema(
227
+ {
228
+ cv.Optional(k.lower()): cv.boolean
229
+ for k in BUTTONMATRIX_CTRLS.choices
230
+ }
231
+ ),
232
+ ),
233
+ cv.Required(CONF_ID): cv.ensure_list(
234
+ cv.maybe_simple_value(
235
+ {
236
+ cv.Required(CONF_ID): cv.use_id(LvButtonMatrixButton),
237
+ },
238
+ key=CONF_ID,
239
+ )
240
+ ),
241
+ cv.Optional(CONF_SELECTED): lv_bool,
242
+ }
243
+ ),
244
+ )
245
+ async def button_update_to_code(config, action_id, template_arg, args):
246
+ widgets = await get_widgets(config[CONF_ID])
247
+ assert all(isinstance(w, MatrixButton) for w in widgets)
248
+
249
+ async def do_button_update(w: MatrixButton):
250
+ if (width := config.get(CONF_WIDTH)) is not None:
251
+ lv.btnmatrix_set_btn_width(w.obj, w.index, width)
252
+ if config.get(CONF_SELECTED):
253
+ lv.btnmatrix_set_selected_btn(w.obj, w.index)
254
+ if controls := config.get(CONF_CONTROL):
255
+ adds = []
256
+ clrs = []
257
+ for item in controls:
258
+ adds.extend(
259
+ [f"LV_BTNMATRIX_CTRL_{k.upper()}" for k, v in item.items() if v]
260
+ )
261
+ clrs.extend(
262
+ [f"LV_BTNMATRIX_CTRL_{k.upper()}" for k, v in item.items() if not v]
263
+ )
264
+ if adds:
265
+ lv.btnmatrix_set_btn_ctrl(
266
+ w.obj, w.index, await BUTTONMATRIX_CTRLS.process(adds)
267
+ )
268
+ if clrs:
269
+ lv.btnmatrix_clear_btn_ctrl(
270
+ w.obj, w.index, await BUTTONMATRIX_CTRLS.process(clrs)
271
+ )
272
+
273
+ return await action_to_code(
274
+ widgets, do_button_update, action_id, template_arg, args
275
+ )
@@ -0,0 +1,27 @@
1
+ from esphome.const import CONF_TEXT
2
+
3
+ from ..defines import CONF_INDICATOR, CONF_MAIN
4
+ from ..lv_validation import lv_text
5
+ from ..lvcode import lv
6
+ from ..schemas import TEXT_SCHEMA
7
+ from ..types import LvBoolean
8
+ from . import Widget, WidgetType
9
+
10
+ CONF_CHECKBOX = "checkbox"
11
+
12
+
13
+ class CheckboxType(WidgetType):
14
+ def __init__(self):
15
+ super().__init__(
16
+ CONF_CHECKBOX,
17
+ LvBoolean("lv_checkbox_t"),
18
+ (CONF_MAIN, CONF_INDICATOR),
19
+ TEXT_SCHEMA,
20
+ )
21
+
22
+ async def to_code(self, w: Widget, config):
23
+ if (value := config.get(CONF_TEXT)) is not None:
24
+ lv.checkbox_set_text(w.obj, await lv_text.process(value))
25
+
26
+
27
+ checkbox_spec = CheckboxType()
@@ -0,0 +1,76 @@
1
+ import esphome.codegen as cg
2
+ import esphome.config_validation as cv
3
+ from esphome.const import CONF_OPTIONS
4
+
5
+ from ..defines import (
6
+ CONF_DIR,
7
+ CONF_INDICATOR,
8
+ CONF_MAIN,
9
+ CONF_SELECTED_INDEX,
10
+ CONF_SYMBOL,
11
+ DIRECTIONS,
12
+ literal,
13
+ )
14
+ from ..lv_validation import lv_int, lv_text, option_string
15
+ from ..lvcode import LocalVariable, lv, lv_expr
16
+ from ..schemas import part_schema
17
+ from ..types import LvSelect, LvType, lv_obj_t
18
+ from . import Widget, WidgetType, set_obj_properties
19
+ from .label import CONF_LABEL
20
+
21
+ CONF_DROPDOWN = "dropdown"
22
+ CONF_DROPDOWN_LIST = "dropdown_list"
23
+
24
+ lv_dropdown_t = LvSelect("lv_dropdown_t")
25
+ lv_dropdown_list_t = LvType("lv_dropdown_list_t")
26
+ dropdown_list_spec = WidgetType(CONF_DROPDOWN_LIST, lv_dropdown_list_t, (CONF_MAIN,))
27
+
28
+ DROPDOWN_BASE_SCHEMA = cv.Schema(
29
+ {
30
+ cv.Optional(CONF_SYMBOL): lv_text,
31
+ cv.Optional(CONF_SELECTED_INDEX): cv.templatable(cv.int_),
32
+ cv.Optional(CONF_DIR, default="BOTTOM"): DIRECTIONS.one_of,
33
+ cv.Optional(CONF_DROPDOWN_LIST): part_schema(dropdown_list_spec),
34
+ }
35
+ )
36
+
37
+ DROPDOWN_SCHEMA = DROPDOWN_BASE_SCHEMA.extend(
38
+ {
39
+ cv.Required(CONF_OPTIONS): cv.ensure_list(option_string),
40
+ }
41
+ )
42
+
43
+
44
+ class DropdownType(WidgetType):
45
+ def __init__(self):
46
+ super().__init__(
47
+ CONF_DROPDOWN,
48
+ lv_dropdown_t,
49
+ (CONF_MAIN, CONF_INDICATOR),
50
+ DROPDOWN_SCHEMA,
51
+ DROPDOWN_BASE_SCHEMA,
52
+ )
53
+
54
+ async def to_code(self, w: Widget, config):
55
+ if options := config.get(CONF_OPTIONS):
56
+ text = cg.safe_exp("\n".join(options))
57
+ lv.dropdown_set_options(w.obj, text)
58
+ if symbol := config.get(CONF_SYMBOL):
59
+ lv.dropdown_set_symbol(w.obj, await lv_text.process(symbol))
60
+ if (selected := config.get(CONF_SELECTED_INDEX)) is not None:
61
+ value = await lv_int.process(selected)
62
+ lv.dropdown_set_selected(w.obj, value)
63
+ if dirn := config.get(CONF_DIR):
64
+ lv.dropdown_set_dir(w.obj, literal(dirn))
65
+ if dlist := config.get(CONF_DROPDOWN_LIST):
66
+ with LocalVariable(
67
+ "dropdown_list", lv_obj_t, lv_expr.dropdown_get_list(w.obj)
68
+ ) as dlist_obj:
69
+ dwid = Widget(dlist_obj, dropdown_list_spec, dlist)
70
+ await set_obj_properties(dwid, dlist)
71
+
72
+ def get_uses(self):
73
+ return (CONF_LABEL,)
74
+
75
+
76
+ dropdown_spec = DropdownType()
@@ -0,0 +1,85 @@
1
+ import esphome.config_validation as cv
2
+ from esphome.const import CONF_ANGLE, CONF_MODE
3
+
4
+ from ..defines import (
5
+ CONF_ANTIALIAS,
6
+ CONF_MAIN,
7
+ CONF_OFFSET_X,
8
+ CONF_OFFSET_Y,
9
+ CONF_PIVOT_X,
10
+ CONF_PIVOT_Y,
11
+ CONF_SRC,
12
+ CONF_ZOOM,
13
+ LvConstant,
14
+ )
15
+ from ..lv_validation import angle, lv_bool, lv_image, size, zoom
16
+ from ..lvcode import lv
17
+ from ..types import lv_img_t
18
+ from . import Widget, WidgetType
19
+ from .label import CONF_LABEL
20
+
21
+ CONF_IMAGE = "image"
22
+
23
+ BASE_IMG_SCHEMA = cv.Schema(
24
+ {
25
+ cv.Optional(CONF_PIVOT_X, default="50%"): size,
26
+ cv.Optional(CONF_PIVOT_Y, default="50%"): size,
27
+ cv.Optional(CONF_ANGLE): angle,
28
+ cv.Optional(CONF_ZOOM): zoom,
29
+ cv.Optional(CONF_OFFSET_X): size,
30
+ cv.Optional(CONF_OFFSET_Y): size,
31
+ cv.Optional(CONF_ANTIALIAS): lv_bool,
32
+ cv.Optional(CONF_MODE): LvConstant(
33
+ "LV_IMG_SIZE_MODE_", "VIRTUAL", "REAL"
34
+ ).one_of,
35
+ }
36
+ )
37
+
38
+ IMG_SCHEMA = BASE_IMG_SCHEMA.extend(
39
+ {
40
+ cv.Required(CONF_SRC): lv_image,
41
+ }
42
+ )
43
+
44
+ IMG_MODIFY_SCHEMA = BASE_IMG_SCHEMA.extend(
45
+ {
46
+ cv.Optional(CONF_SRC): lv_image,
47
+ }
48
+ )
49
+
50
+
51
+ class ImgType(WidgetType):
52
+ def __init__(self):
53
+ super().__init__(
54
+ CONF_IMAGE,
55
+ lv_img_t,
56
+ (CONF_MAIN,),
57
+ IMG_SCHEMA,
58
+ IMG_MODIFY_SCHEMA,
59
+ lv_name="img",
60
+ )
61
+
62
+ def get_uses(self):
63
+ return "img", CONF_LABEL
64
+
65
+ async def to_code(self, w: Widget, config):
66
+ if src := config.get(CONF_SRC):
67
+ lv.img_set_src(w.obj, await lv_image.process(src))
68
+ if (cf_angle := config.get(CONF_ANGLE)) is not None:
69
+ pivot_x = config[CONF_PIVOT_X]
70
+ pivot_y = config[CONF_PIVOT_Y]
71
+ lv.img_set_pivot(w.obj, pivot_x, pivot_y)
72
+ lv.img_set_angle(w.obj, cf_angle)
73
+ if (img_zoom := config.get(CONF_ZOOM)) is not None:
74
+ lv.img_set_zoom(w.obj, img_zoom)
75
+ if (offset := config.get(CONF_OFFSET_X)) is not None:
76
+ lv.img_set_offset_x(w.obj, offset)
77
+ if (offset := config.get(CONF_OFFSET_Y)) is not None:
78
+ lv.img_set_offset_y(w.obj, offset)
79
+ if CONF_ANTIALIAS in config:
80
+ lv.img_set_antialias(w.obj, config[CONF_ANTIALIAS])
81
+ if mode := config.get(CONF_MODE):
82
+ lv.img_set_mode(w.obj, mode)
83
+
84
+
85
+ img_spec = ImgType()
@@ -0,0 +1,49 @@
1
+ from esphome.components.key_provider import KeyProvider
2
+ import esphome.config_validation as cv
3
+ from esphome.const import CONF_ITEMS, CONF_MODE
4
+ from esphome.cpp_types import std_string
5
+
6
+ from ..defines import CONF_MAIN, KEYBOARD_MODES, literal
7
+ from ..helpers import add_lv_use, lvgl_components_required
8
+ from ..types import LvCompound, LvType
9
+ from . import Widget, WidgetType, get_widgets
10
+ from .textarea import CONF_TEXTAREA, lv_textarea_t
11
+
12
+ CONF_KEYBOARD = "keyboard"
13
+
14
+ KEYBOARD_SCHEMA = {
15
+ cv.Optional(CONF_MODE, default="TEXT_UPPER"): KEYBOARD_MODES.one_of,
16
+ cv.Optional(CONF_TEXTAREA): cv.use_id(lv_textarea_t),
17
+ }
18
+
19
+ lv_keyboard_t = LvType(
20
+ "LvKeyboardType",
21
+ parents=(KeyProvider, LvCompound),
22
+ largs=[(std_string, "text")],
23
+ has_on_value=True,
24
+ lvalue=lambda w: literal(f"lv_textarea_get_text({w.obj})"),
25
+ )
26
+
27
+
28
+ class KeyboardType(WidgetType):
29
+ def __init__(self):
30
+ super().__init__(
31
+ CONF_KEYBOARD,
32
+ lv_keyboard_t,
33
+ (CONF_MAIN, CONF_ITEMS),
34
+ KEYBOARD_SCHEMA,
35
+ )
36
+
37
+ def get_uses(self):
38
+ return CONF_KEYBOARD, CONF_TEXTAREA
39
+
40
+ async def to_code(self, w: Widget, config: dict):
41
+ lvgl_components_required.add("KEY_LISTENER")
42
+ lvgl_components_required.add(CONF_KEYBOARD)
43
+ add_lv_use("btnmatrix")
44
+ await w.set_property(CONF_MODE, await KEYBOARD_MODES.process(config[CONF_MODE]))
45
+ if ta := await get_widgets(config, CONF_TEXTAREA):
46
+ await w.set_property(CONF_TEXTAREA, ta[0].obj)
47
+
48
+
49
+ keyboard_spec = KeyboardType()
@@ -0,0 +1,42 @@
1
+ import esphome.config_validation as cv
2
+ from esphome.const import CONF_TEXT
3
+
4
+ from ..defines import (
5
+ CONF_LONG_MODE,
6
+ CONF_MAIN,
7
+ CONF_RECOLOR,
8
+ CONF_SCROLLBAR,
9
+ CONF_SELECTED,
10
+ LV_LONG_MODES,
11
+ )
12
+ from ..lv_validation import lv_bool, lv_text
13
+ from ..schemas import TEXT_SCHEMA
14
+ from ..types import LvText, WidgetType
15
+ from . import Widget
16
+
17
+ CONF_LABEL = "label"
18
+
19
+
20
+ class LabelType(WidgetType):
21
+ def __init__(self):
22
+ super().__init__(
23
+ CONF_LABEL,
24
+ LvText("lv_label_t"),
25
+ (CONF_MAIN, CONF_SCROLLBAR, CONF_SELECTED),
26
+ TEXT_SCHEMA.extend(
27
+ {
28
+ cv.Optional(CONF_RECOLOR): lv_bool,
29
+ cv.Optional(CONF_LONG_MODE): LV_LONG_MODES.one_of,
30
+ }
31
+ ),
32
+ )
33
+
34
+ async def to_code(self, w: Widget, config):
35
+ """For a text object, create and set text"""
36
+ if value := config.get(CONF_TEXT):
37
+ await w.set_property(CONF_TEXT, await lv_text.process(value))
38
+ await w.set_property(CONF_LONG_MODE, config)
39
+ await w.set_property(CONF_RECOLOR, config)
40
+
41
+
42
+ label_spec = LabelType()
@@ -0,0 +1,29 @@
1
+ import esphome.config_validation as cv
2
+ from esphome.const import CONF_BRIGHTNESS, CONF_COLOR, CONF_LED
3
+
4
+ from ..defines import CONF_MAIN
5
+ from ..lv_validation import lv_brightness, lv_color
6
+ from ..lvcode import lv
7
+ from ..types import LvType
8
+ from . import Widget, WidgetType
9
+
10
+ LED_SCHEMA = cv.Schema(
11
+ {
12
+ cv.Optional(CONF_COLOR): lv_color,
13
+ cv.Optional(CONF_BRIGHTNESS): lv_brightness,
14
+ }
15
+ )
16
+
17
+
18
+ class LedType(WidgetType):
19
+ def __init__(self):
20
+ super().__init__(CONF_LED, LvType("lv_led_t"), (CONF_MAIN,), LED_SCHEMA)
21
+
22
+ async def to_code(self, w: Widget, config):
23
+ if (color := config.get(CONF_COLOR)) is not None:
24
+ lv.led_set_color(w.obj, await lv_color.process(color))
25
+ if (brightness := config.get(CONF_BRIGHTNESS)) is not None:
26
+ lv.led_set_brightness(w.obj, await lv_brightness.process(brightness))
27
+
28
+
29
+ led_spec = LedType()
@@ -0,0 +1,50 @@
1
+ import functools
2
+
3
+ import esphome.codegen as cg
4
+ import esphome.config_validation as cv
5
+
6
+ from ..defines import CONF_MAIN, literal
7
+ from ..lvcode import lv
8
+ from ..types import LvType
9
+ from . import Widget, WidgetType
10
+
11
+ CONF_LINE = "line"
12
+ CONF_POINTS = "points"
13
+ CONF_POINT_LIST_ID = "point_list_id"
14
+
15
+ lv_point_t = cg.global_ns.struct("lv_point_t")
16
+
17
+
18
+ def point_list(il):
19
+ il = cv.string(il)
20
+ nl = il.replace(" ", "").split(",")
21
+ return [int(n) for n in nl]
22
+
23
+
24
+ def cv_point_list(value):
25
+ if not isinstance(value, list):
26
+ raise cv.Invalid("List of points required")
27
+ values = [point_list(v) for v in value]
28
+ if not functools.reduce(lambda f, v: f and len(v) == 2, values, True):
29
+ raise cv.Invalid("Points must be a list of x,y integer pairs")
30
+ return values
31
+
32
+
33
+ LINE_SCHEMA = {
34
+ cv.Required(CONF_POINTS): cv_point_list,
35
+ cv.GenerateID(CONF_POINT_LIST_ID): cv.declare_id(lv_point_t),
36
+ }
37
+
38
+
39
+ class LineType(WidgetType):
40
+ def __init__(self):
41
+ super().__init__(CONF_LINE, LvType("lv_line_t"), (CONF_MAIN,), LINE_SCHEMA)
42
+
43
+ async def to_code(self, w: Widget, config):
44
+ """For a line object, create and add the points"""
45
+ data = literal(config[CONF_POINTS])
46
+ points = cg.static_const_array(config[CONF_POINT_LIST_ID], data)
47
+ lv.line_set_points(w.obj, points, len(data))
48
+
49
+
50
+ line_spec = LineType()
@@ -0,0 +1,55 @@
1
+ import esphome.config_validation as cv
2
+ from esphome.const import CONF_MAX_VALUE, CONF_MIN_VALUE, CONF_MODE, CONF_VALUE
3
+
4
+ from ..defines import BAR_MODES, CONF_ANIMATED, CONF_INDICATOR, CONF_MAIN, literal
5
+ from ..lv_validation import animated, get_start_value, lv_float
6
+ from ..lvcode import lv
7
+ from ..types import LvNumber, NumberType
8
+ from . import Widget
9
+
10
+ # Note this file cannot be called "bar.py" because that name is disallowed.
11
+
12
+ CONF_BAR = "bar"
13
+ BAR_MODIFY_SCHEMA = cv.Schema(
14
+ {
15
+ cv.Optional(CONF_VALUE): lv_float,
16
+ cv.Optional(CONF_ANIMATED, default=True): animated,
17
+ }
18
+ )
19
+
20
+ BAR_SCHEMA = cv.Schema(
21
+ {
22
+ cv.Optional(CONF_VALUE): lv_float,
23
+ cv.Optional(CONF_MIN_VALUE, default=0): cv.int_,
24
+ cv.Optional(CONF_MAX_VALUE, default=100): cv.int_,
25
+ cv.Optional(CONF_MODE, default="NORMAL"): BAR_MODES.one_of,
26
+ cv.Optional(CONF_ANIMATED, default=True): animated,
27
+ }
28
+ )
29
+
30
+
31
+ class BarType(NumberType):
32
+ def __init__(self):
33
+ super().__init__(
34
+ CONF_BAR,
35
+ LvNumber("lv_bar_t"),
36
+ parts=(CONF_MAIN, CONF_INDICATOR),
37
+ schema=BAR_SCHEMA,
38
+ modify_schema=BAR_MODIFY_SCHEMA,
39
+ )
40
+
41
+ async def to_code(self, w: Widget, config):
42
+ var = w.obj
43
+ if CONF_MIN_VALUE in config:
44
+ lv.bar_set_range(var, config[CONF_MIN_VALUE], config[CONF_MAX_VALUE])
45
+ lv.bar_set_mode(var, literal(config[CONF_MODE]))
46
+ value = await get_start_value(config)
47
+ if value is not None:
48
+ lv.bar_set_value(var, value, literal(config[CONF_ANIMATED]))
49
+
50
+ @property
51
+ def animated(self):
52
+ return True
53
+
54
+
55
+ bar_spec = BarType()