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,151 @@
1
+ // Based on this datasheet:
2
+ // https://www.mouser.ca/datasheet/2/678/AVGO_S_A0002854364_1-2574547.pdf
3
+
4
+ #include "apds9306.h"
5
+ #include "esphome/core/helpers.h"
6
+ #include "esphome/core/log.h"
7
+
8
+ namespace esphome {
9
+ namespace apds9306 {
10
+
11
+ static const char *const TAG = "apds9306";
12
+
13
+ enum { // APDS9306 registers
14
+ APDS9306_MAIN_CTRL = 0x00,
15
+ APDS9306_ALS_MEAS_RATE = 0x04,
16
+ APDS9306_ALS_GAIN = 0x05,
17
+ APDS9306_PART_ID = 0x06,
18
+ APDS9306_MAIN_STATUS = 0x07,
19
+ APDS9306_CLEAR_DATA_0 = 0x0A, // LSB
20
+ APDS9306_CLEAR_DATA_1 = 0x0B,
21
+ APDS9306_CLEAR_DATA_2 = 0x0C, // MSB
22
+ APDS9306_ALS_DATA_0 = 0x0D, // LSB
23
+ APDS9306_ALS_DATA_1 = 0x0E,
24
+ APDS9306_ALS_DATA_2 = 0x0F, // MSB
25
+ APDS9306_INT_CFG = 0x19,
26
+ APDS9306_INT_PERSISTENCE = 0x1A,
27
+ APDS9306_ALS_THRES_UP_0 = 0x21, // LSB
28
+ APDS9306_ALS_THRES_UP_1 = 0x22,
29
+ APDS9306_ALS_THRES_UP_2 = 0x23, // MSB
30
+ APDS9306_ALS_THRES_LOW_0 = 0x24, // LSB
31
+ APDS9306_ALS_THRES_LOW_1 = 0x25,
32
+ APDS9306_ALS_THRES_LOW_2 = 0x26, // MSB
33
+ APDS9306_ALS_THRES_VAR = 0x27
34
+ };
35
+
36
+ #define APDS9306_ERROR_CHECK(func, error) \
37
+ if (!(func)) { \
38
+ ESP_LOGE(TAG, error); \
39
+ this->mark_failed(); \
40
+ return; \
41
+ }
42
+ #define APDS9306_WARNING_CHECK(func, warning) \
43
+ if (!(func)) { \
44
+ ESP_LOGW(TAG, warning); \
45
+ this->status_set_warning(); \
46
+ return; \
47
+ }
48
+ #define APDS9306_WRITE_BYTE(reg, value) \
49
+ ESP_LOGV(TAG, "Writing 0x%02x to 0x%02x", value, reg); \
50
+ if (!this->write_byte(reg, value)) { \
51
+ ESP_LOGE(TAG, "Failed writing 0x%02x to 0x%02x", value, reg); \
52
+ this->mark_failed(); \
53
+ return; \
54
+ }
55
+
56
+ void APDS9306::setup() {
57
+ ESP_LOGCONFIG(TAG, "Setting up APDS9306...");
58
+
59
+ uint8_t id;
60
+ if (!this->read_byte(APDS9306_PART_ID, &id)) { // Part ID register
61
+ this->error_code_ = COMMUNICATION_FAILED;
62
+ this->mark_failed();
63
+ return;
64
+ }
65
+
66
+ if (id != 0xB1 && id != 0xB3) { // 0xB1 for APDS9306 0xB3 for APDS9306-065
67
+ this->error_code_ = WRONG_ID;
68
+ this->mark_failed();
69
+ return;
70
+ }
71
+
72
+ // ALS resolution and measurement, see datasheet or init.py for options
73
+ uint8_t als_meas_rate = ((this->bit_width_ & 0x07) << 4) | (this->measurement_rate_ & 0x07);
74
+ APDS9306_WRITE_BYTE(APDS9306_ALS_MEAS_RATE, als_meas_rate);
75
+
76
+ // ALS gain, see datasheet or init.py for options
77
+ uint8_t als_gain = (this->gain_ & 0x07);
78
+ APDS9306_WRITE_BYTE(APDS9306_ALS_GAIN, als_gain);
79
+
80
+ // Set to standby mode
81
+ APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x00);
82
+
83
+ // Check for data, clear main status
84
+ uint8_t status;
85
+ APDS9306_WARNING_CHECK(this->read_byte(APDS9306_MAIN_STATUS, &status), "Reading MAIN STATUS failed.");
86
+
87
+ // Set to active mode
88
+ APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x02);
89
+
90
+ ESP_LOGCONFIG(TAG, "APDS9306 setup complete");
91
+ }
92
+
93
+ void APDS9306::dump_config() {
94
+ LOG_SENSOR("", "APDS9306", this);
95
+ LOG_I2C_DEVICE(this);
96
+
97
+ if (this->is_failed()) {
98
+ switch (this->error_code_) {
99
+ case COMMUNICATION_FAILED:
100
+ ESP_LOGE(TAG, "Communication with APDS9306 failed!");
101
+ break;
102
+ case WRONG_ID:
103
+ ESP_LOGE(TAG, "APDS9306 has invalid id!");
104
+ break;
105
+ default:
106
+ ESP_LOGE(TAG, "Setting up APDS9306 registers failed!");
107
+ break;
108
+ }
109
+ }
110
+
111
+ ESP_LOGCONFIG(TAG, " Gain: %u", AMBIENT_LIGHT_GAIN_VALUES[this->gain_]);
112
+ ESP_LOGCONFIG(TAG, " Measurement rate: %u", MEASUREMENT_RATE_VALUES[this->measurement_rate_]);
113
+ ESP_LOGCONFIG(TAG, " Measurement Resolution/Bit width: %d", MEASUREMENT_BIT_WIDTH_VALUES[this->bit_width_]);
114
+
115
+ LOG_UPDATE_INTERVAL(this);
116
+ }
117
+
118
+ void APDS9306::update() {
119
+ // Check for new data
120
+ uint8_t status;
121
+ APDS9306_WARNING_CHECK(this->read_byte(APDS9306_MAIN_STATUS, &status), "Reading MAIN STATUS failed.");
122
+
123
+ this->status_clear_warning();
124
+
125
+ if (!(status &= 0b00001000)) { // No new data
126
+ return;
127
+ }
128
+
129
+ // Set to standby mode
130
+ APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x00);
131
+
132
+ // Clear MAIN STATUS
133
+ APDS9306_WARNING_CHECK(this->read_byte(APDS9306_MAIN_STATUS, &status), "Reading MAIN STATUS failed.");
134
+
135
+ uint8_t als_data[3];
136
+ APDS9306_WARNING_CHECK(this->read_bytes(APDS9306_ALS_DATA_0, als_data, 3), "Reading ALS data has failed.");
137
+
138
+ // Set to active mode
139
+ APDS9306_WRITE_BYTE(APDS9306_MAIN_CTRL, 0x02);
140
+
141
+ uint32_t light_level = 0x00 | encode_uint24(als_data[2], als_data[1], als_data[0]);
142
+
143
+ float lux = ((float) light_level / AMBIENT_LIGHT_GAIN_VALUES[this->gain_]) *
144
+ (100.0f / MEASUREMENT_RATE_VALUES[this->measurement_rate_]);
145
+
146
+ ESP_LOGD(TAG, "Got illuminance=%.1flx from", lux);
147
+ this->publish_state(lux);
148
+ }
149
+
150
+ } // namespace apds9306
151
+ } // namespace esphome
@@ -0,0 +1,66 @@
1
+ // Based on this datasheet:
2
+ // https://www.mouser.ca/datasheet/2/678/AVGO_S_A0002854364_1-2574547.pdf
3
+
4
+ #pragma once
5
+
6
+ #include "esphome/components/i2c/i2c.h"
7
+ #include "esphome/components/sensor/sensor.h"
8
+ #include "esphome/core/component.h"
9
+
10
+ namespace esphome {
11
+ namespace apds9306 {
12
+
13
+ enum MeasurementBitWidth : uint8_t {
14
+ MEASUREMENT_BIT_WIDTH_20 = 0,
15
+ MEASUREMENT_BIT_WIDTH_19 = 1,
16
+ MEASUREMENT_BIT_WIDTH_18 = 2,
17
+ MEASUREMENT_BIT_WIDTH_17 = 3,
18
+ MEASUREMENT_BIT_WIDTH_16 = 4,
19
+ MEASUREMENT_BIT_WIDTH_13 = 5,
20
+ };
21
+ static const uint8_t MEASUREMENT_BIT_WIDTH_VALUES[] = {20, 19, 18, 17, 16, 13};
22
+
23
+ enum MeasurementRate : uint8_t {
24
+ MEASUREMENT_RATE_25 = 0,
25
+ MEASUREMENT_RATE_50 = 1,
26
+ MEASUREMENT_RATE_100 = 2,
27
+ MEASUREMENT_RATE_200 = 3,
28
+ MEASUREMENT_RATE_500 = 4,
29
+ MEASUREMENT_RATE_1000 = 5,
30
+ MEASUREMENT_RATE_2000 = 6,
31
+ };
32
+ static const uint16_t MEASUREMENT_RATE_VALUES[] = {25, 50, 100, 200, 500, 1000, 2000};
33
+
34
+ enum AmbientLightGain : uint8_t {
35
+ AMBIENT_LIGHT_GAIN_1 = 0,
36
+ AMBIENT_LIGHT_GAIN_3 = 1,
37
+ AMBIENT_LIGHT_GAIN_6 = 2,
38
+ AMBIENT_LIGHT_GAIN_9 = 3,
39
+ AMBIENT_LIGHT_GAIN_18 = 4,
40
+ };
41
+ static const uint8_t AMBIENT_LIGHT_GAIN_VALUES[] = {1, 3, 6, 9, 18};
42
+
43
+ class APDS9306 : public sensor::Sensor, public PollingComponent, public i2c::I2CDevice {
44
+ public:
45
+ void setup() override;
46
+ float get_setup_priority() const override { return setup_priority::BUS; }
47
+ void dump_config() override;
48
+ void update() override;
49
+ void set_bit_width(MeasurementBitWidth bit_width) { this->bit_width_ = bit_width; }
50
+ void set_measurement_rate(MeasurementRate measurement_rate) { this->measurement_rate_ = measurement_rate; }
51
+ void set_ambient_light_gain(AmbientLightGain gain) { this->gain_ = gain; }
52
+
53
+ protected:
54
+ enum ErrorCode {
55
+ NONE = 0,
56
+ COMMUNICATION_FAILED,
57
+ WRONG_ID,
58
+ } error_code_{NONE};
59
+
60
+ MeasurementBitWidth bit_width_;
61
+ MeasurementRate measurement_rate_;
62
+ AmbientLightGain gain_;
63
+ };
64
+
65
+ } // namespace apds9306
66
+ } // namespace esphome
@@ -0,0 +1,95 @@
1
+ # Based on this datasheet:
2
+ # https://www.mouser.ca/datasheet/2/678/AVGO_S_A0002854364_1-2574547.pdf
3
+
4
+ import esphome.codegen as cg
5
+ import esphome.config_validation as cv
6
+ from esphome.components import i2c, sensor
7
+ from esphome.const import (
8
+ CONF_GAIN,
9
+ DEVICE_CLASS_ILLUMINANCE,
10
+ ICON_LIGHTBULB,
11
+ STATE_CLASS_MEASUREMENT,
12
+ UNIT_LUX,
13
+ )
14
+
15
+ DEPENDENCIES = ["i2c"]
16
+
17
+ CONF_APDS9306_ID = "apds9306_id"
18
+ CONF_BIT_WIDTH = "bit_width"
19
+ CONF_MEASUREMENT_RATE = "measurement_rate"
20
+
21
+ apds9306_ns = cg.esphome_ns.namespace("apds9306")
22
+ APDS9306 = apds9306_ns.class_(
23
+ "APDS9306", sensor.Sensor, cg.PollingComponent, i2c.I2CDevice
24
+ )
25
+
26
+ MeasurementBitWidth = apds9306_ns.enum("MeasurementBitWidth")
27
+ MeasurementRate = apds9306_ns.enum("MeasurementRate")
28
+ AmbientLightGain = apds9306_ns.enum("AmbientLightGain")
29
+
30
+ MEASUREMENT_BIT_WIDTHS = {
31
+ 20: MeasurementBitWidth.MEASUREMENT_BIT_WIDTH_20,
32
+ 19: MeasurementBitWidth.MEASUREMENT_BIT_WIDTH_19,
33
+ 18: MeasurementBitWidth.MEASUREMENT_BIT_WIDTH_18,
34
+ 17: MeasurementBitWidth.MEASUREMENT_BIT_WIDTH_17,
35
+ 16: MeasurementBitWidth.MEASUREMENT_BIT_WIDTH_16,
36
+ 13: MeasurementBitWidth.MEASUREMENT_BIT_WIDTH_13,
37
+ }
38
+
39
+ MEASUREMENT_RATES = {
40
+ 25: MeasurementRate.MEASUREMENT_RATE_25,
41
+ 50: MeasurementRate.MEASUREMENT_RATE_50,
42
+ 100: MeasurementRate.MEASUREMENT_RATE_100,
43
+ 200: MeasurementRate.MEASUREMENT_RATE_200,
44
+ 500: MeasurementRate.MEASUREMENT_RATE_500,
45
+ 1000: MeasurementRate.MEASUREMENT_RATE_1000,
46
+ 2000: MeasurementRate.MEASUREMENT_RATE_2000,
47
+ }
48
+
49
+ AMBIENT_LIGHT_GAINS = {
50
+ 1: AmbientLightGain.AMBIENT_LIGHT_GAIN_1,
51
+ 3: AmbientLightGain.AMBIENT_LIGHT_GAIN_3,
52
+ 6: AmbientLightGain.AMBIENT_LIGHT_GAIN_6,
53
+ 9: AmbientLightGain.AMBIENT_LIGHT_GAIN_9,
54
+ 18: AmbientLightGain.AMBIENT_LIGHT_GAIN_18,
55
+ }
56
+
57
+
58
+ def _validate_measurement_rate(value):
59
+ value = cv.positive_time_period_milliseconds(value)
60
+ return cv.enum(MEASUREMENT_RATES, int=True)(value.total_milliseconds)
61
+
62
+
63
+ CONFIG_SCHEMA = (
64
+ sensor.sensor_schema(
65
+ APDS9306,
66
+ unit_of_measurement=UNIT_LUX,
67
+ accuracy_decimals=1,
68
+ device_class=DEVICE_CLASS_ILLUMINANCE,
69
+ state_class=STATE_CLASS_MEASUREMENT,
70
+ icon=ICON_LIGHTBULB,
71
+ )
72
+ .extend(
73
+ {
74
+ cv.Optional(CONF_GAIN, default="1"): cv.enum(AMBIENT_LIGHT_GAINS, int=True),
75
+ cv.Optional(CONF_BIT_WIDTH, default="18"): cv.enum(
76
+ MEASUREMENT_BIT_WIDTHS, int=True
77
+ ),
78
+ cv.Optional(
79
+ CONF_MEASUREMENT_RATE, default="100ms"
80
+ ): _validate_measurement_rate,
81
+ }
82
+ )
83
+ .extend(cv.polling_component_schema("60s"))
84
+ .extend(i2c.i2c_device_schema(0x52))
85
+ )
86
+
87
+
88
+ async def to_code(config):
89
+ var = await sensor.new_sensor(config)
90
+ await cg.register_component(var, config)
91
+ await i2c.register_i2c_device(var, config)
92
+
93
+ cg.add(var.set_bit_width(config[CONF_BIT_WIDTH]))
94
+ cg.add(var.set_measurement_rate(config[CONF_MEASUREMENT_RATE]))
95
+ cg.add(var.set_ambient_light_gain(config[CONF_GAIN]))
@@ -1,25 +1,27 @@
1
1
  import base64
2
2
 
3
- import esphome.codegen as cg
4
- import esphome.config_validation as cv
5
3
  from esphome import automation
6
4
  from esphome.automation import Condition
5
+ import esphome.codegen as cg
6
+ import esphome.config_validation as cv
7
7
  from esphome.const import (
8
+ CONF_ACTION,
9
+ CONF_ACTIONS,
8
10
  CONF_DATA,
9
11
  CONF_DATA_TEMPLATE,
12
+ CONF_EVENT,
10
13
  CONF_ID,
11
14
  CONF_KEY,
15
+ CONF_ON_CLIENT_CONNECTED,
16
+ CONF_ON_CLIENT_DISCONNECTED,
12
17
  CONF_PASSWORD,
13
18
  CONF_PORT,
14
19
  CONF_REBOOT_TIMEOUT,
15
20
  CONF_SERVICE,
16
- CONF_VARIABLES,
17
21
  CONF_SERVICES,
18
- CONF_TRIGGER_ID,
19
- CONF_EVENT,
20
22
  CONF_TAG,
21
- CONF_ON_CLIENT_CONNECTED,
22
- CONF_ON_CLIENT_DISCONNECTED,
23
+ CONF_TRIGGER_ID,
24
+ CONF_VARIABLES,
23
25
  )
24
26
  from esphome.core import coroutine_with_priority
25
27
 
@@ -63,40 +65,51 @@ def validate_encryption_key(value):
63
65
  return value
64
66
 
65
67
 
66
- CONFIG_SCHEMA = cv.Schema(
68
+ ACTIONS_SCHEMA = automation.validate_automation(
67
69
  {
68
- cv.GenerateID(): cv.declare_id(APIServer),
69
- cv.Optional(CONF_PORT, default=6053): cv.port,
70
- cv.Optional(CONF_PASSWORD, default=""): cv.string_strict,
71
- cv.Optional(
72
- CONF_REBOOT_TIMEOUT, default="15min"
73
- ): cv.positive_time_period_milliseconds,
74
- cv.Optional(CONF_SERVICES): automation.validate_automation(
75
- {
76
- cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(UserServiceTrigger),
77
- cv.Required(CONF_SERVICE): cv.valid_name,
78
- cv.Optional(CONF_VARIABLES, default={}): cv.Schema(
79
- {
80
- cv.validate_id_name: cv.one_of(
81
- *SERVICE_ARG_NATIVE_TYPES, lower=True
82
- ),
83
- }
84
- ),
85
- }
86
- ),
87
- cv.Optional(CONF_ENCRYPTION): cv.Schema(
70
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(UserServiceTrigger),
71
+ cv.Exclusive(CONF_SERVICE, group_of_exclusion=CONF_ACTION): cv.valid_name,
72
+ cv.Exclusive(CONF_ACTION, group_of_exclusion=CONF_ACTION): cv.valid_name,
73
+ cv.Optional(CONF_VARIABLES, default={}): cv.Schema(
88
74
  {
89
- cv.Required(CONF_KEY): validate_encryption_key,
75
+ cv.validate_id_name: cv.one_of(*SERVICE_ARG_NATIVE_TYPES, lower=True),
90
76
  }
91
77
  ),
92
- cv.Optional(CONF_ON_CLIENT_CONNECTED): automation.validate_automation(
93
- single=True
94
- ),
95
- cv.Optional(CONF_ON_CLIENT_DISCONNECTED): automation.validate_automation(
96
- single=True
97
- ),
98
- }
99
- ).extend(cv.COMPONENT_SCHEMA)
78
+ },
79
+ cv.All(
80
+ cv.has_exactly_one_key(CONF_SERVICE, CONF_ACTION),
81
+ cv.rename_key(CONF_SERVICE, CONF_ACTION),
82
+ ),
83
+ )
84
+
85
+ CONFIG_SCHEMA = cv.All(
86
+ cv.Schema(
87
+ {
88
+ cv.GenerateID(): cv.declare_id(APIServer),
89
+ cv.Optional(CONF_PORT, default=6053): cv.port,
90
+ cv.Optional(CONF_PASSWORD, default=""): cv.string_strict,
91
+ cv.Optional(
92
+ CONF_REBOOT_TIMEOUT, default="15min"
93
+ ): cv.positive_time_period_milliseconds,
94
+ cv.Exclusive(
95
+ CONF_SERVICES, group_of_exclusion=CONF_ACTIONS
96
+ ): ACTIONS_SCHEMA,
97
+ cv.Exclusive(CONF_ACTIONS, group_of_exclusion=CONF_ACTIONS): ACTIONS_SCHEMA,
98
+ cv.Optional(CONF_ENCRYPTION): cv.Schema(
99
+ {
100
+ cv.Required(CONF_KEY): validate_encryption_key,
101
+ }
102
+ ),
103
+ cv.Optional(CONF_ON_CLIENT_CONNECTED): automation.validate_automation(
104
+ single=True
105
+ ),
106
+ cv.Optional(CONF_ON_CLIENT_DISCONNECTED): automation.validate_automation(
107
+ single=True
108
+ ),
109
+ }
110
+ ).extend(cv.COMPONENT_SCHEMA),
111
+ cv.rename_key(CONF_SERVICES, CONF_ACTIONS),
112
+ )
100
113
 
101
114
 
102
115
  @coroutine_with_priority(40.0)
@@ -108,7 +121,7 @@ async def to_code(config):
108
121
  cg.add(var.set_password(config[CONF_PASSWORD]))
109
122
  cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
110
123
 
111
- for conf in config.get(CONF_SERVICES, []):
124
+ for conf in config.get(CONF_ACTIONS, []):
112
125
  template_args = []
113
126
  func_args = []
114
127
  service_arg_names = []
@@ -119,7 +132,7 @@ async def to_code(config):
119
132
  service_arg_names.append(name)
120
133
  templ = cg.TemplateArguments(*template_args)
121
134
  trigger = cg.new_Pvariable(
122
- conf[CONF_TRIGGER_ID], templ, conf[CONF_SERVICE], service_arg_names
135
+ conf[CONF_TRIGGER_ID], templ, conf[CONF_ACTION], service_arg_names
123
136
  )
124
137
  cg.add(var.register_user_service(trigger))
125
138
  await automation.build_automation(trigger, func_args, conf)
@@ -142,7 +155,7 @@ async def to_code(config):
142
155
  decoded = base64.b64decode(encryption_config[CONF_KEY])
143
156
  cg.add(var.set_noise_psk(list(decoded)))
144
157
  cg.add_define("USE_API_NOISE")
145
- cg.add_library("esphome/noise-c", "0.1.4")
158
+ cg.add_library("esphome/noise-c", "0.1.6")
146
159
  else:
147
160
  cg.add_define("USE_API_PLAINTEXT")
148
161
 
@@ -152,28 +165,43 @@ async def to_code(config):
152
165
 
153
166
  KEY_VALUE_SCHEMA = cv.Schema({cv.string: cv.templatable(cv.string_strict)})
154
167
 
155
- HOMEASSISTANT_SERVICE_ACTION_SCHEMA = cv.Schema(
156
- {
157
- cv.GenerateID(): cv.use_id(APIServer),
158
- cv.Required(CONF_SERVICE): cv.templatable(cv.string),
159
- cv.Optional(CONF_DATA, default={}): KEY_VALUE_SCHEMA,
160
- cv.Optional(CONF_DATA_TEMPLATE, default={}): KEY_VALUE_SCHEMA,
161
- cv.Optional(CONF_VARIABLES, default={}): cv.Schema(
162
- {cv.string: cv.returning_lambda}
163
- ),
164
- }
168
+
169
+ HOMEASSISTANT_ACTION_ACTION_SCHEMA = cv.All(
170
+ cv.Schema(
171
+ {
172
+ cv.GenerateID(): cv.use_id(APIServer),
173
+ cv.Exclusive(CONF_SERVICE, group_of_exclusion=CONF_ACTION): cv.templatable(
174
+ cv.string
175
+ ),
176
+ cv.Exclusive(CONF_ACTION, group_of_exclusion=CONF_ACTION): cv.templatable(
177
+ cv.string
178
+ ),
179
+ cv.Optional(CONF_DATA, default={}): KEY_VALUE_SCHEMA,
180
+ cv.Optional(CONF_DATA_TEMPLATE, default={}): KEY_VALUE_SCHEMA,
181
+ cv.Optional(CONF_VARIABLES, default={}): cv.Schema(
182
+ {cv.string: cv.returning_lambda}
183
+ ),
184
+ }
185
+ ),
186
+ cv.has_exactly_one_key(CONF_SERVICE, CONF_ACTION),
187
+ cv.rename_key(CONF_SERVICE, CONF_ACTION),
165
188
  )
166
189
 
167
190
 
191
+ @automation.register_action(
192
+ "homeassistant.action",
193
+ HomeAssistantServiceCallAction,
194
+ HOMEASSISTANT_ACTION_ACTION_SCHEMA,
195
+ )
168
196
  @automation.register_action(
169
197
  "homeassistant.service",
170
198
  HomeAssistantServiceCallAction,
171
- HOMEASSISTANT_SERVICE_ACTION_SCHEMA,
199
+ HOMEASSISTANT_ACTION_ACTION_SCHEMA,
172
200
  )
173
201
  async def homeassistant_service_to_code(config, action_id, template_arg, args):
174
202
  serv = await cg.get_variable(config[CONF_ID])
175
203
  var = cg.new_Pvariable(action_id, template_arg, serv, False)
176
- templ = await cg.templatable(config[CONF_SERVICE], args, None)
204
+ templ = await cg.templatable(config[CONF_ACTION], args, None)
177
205
  cg.add(var.set_service(templ))
178
206
  for key, value in config[CONF_DATA].items():
179
207
  templ = await cg.templatable(value, args, None)
@@ -1328,7 +1328,20 @@ void APIConnection::update_command(const UpdateCommandRequest &msg) {
1328
1328
  if (update == nullptr)
1329
1329
  return;
1330
1330
 
1331
- update->perform();
1331
+ switch (msg.command) {
1332
+ case enums::UPDATE_COMMAND_UPDATE:
1333
+ update->perform();
1334
+ break;
1335
+ case enums::UPDATE_COMMAND_CHECK:
1336
+ update->check();
1337
+ break;
1338
+ case enums::UPDATE_COMMAND_NONE:
1339
+ ESP_LOGE(TAG, "UPDATE_COMMAND_NONE not handled. Check client is sending the correct command");
1340
+ break;
1341
+ default:
1342
+ ESP_LOGW(TAG, "Unknown update command: %" PRIu32, msg.command);
1343
+ break;
1344
+ }
1332
1345
  }
1333
1346
  #endif
1334
1347
 
@@ -567,6 +567,20 @@ template<> const char *proto_enum_to_string<enums::ValveOperation>(enums::ValveO
567
567
  }
568
568
  }
569
569
  #endif
570
+ #ifdef HAS_PROTO_MESSAGE_DUMP
571
+ template<> const char *proto_enum_to_string<enums::UpdateCommand>(enums::UpdateCommand value) {
572
+ switch (value) {
573
+ case enums::UPDATE_COMMAND_NONE:
574
+ return "UPDATE_COMMAND_NONE";
575
+ case enums::UPDATE_COMMAND_UPDATE:
576
+ return "UPDATE_COMMAND_UPDATE";
577
+ case enums::UPDATE_COMMAND_CHECK:
578
+ return "UPDATE_COMMAND_CHECK";
579
+ default:
580
+ return "UNKNOWN";
581
+ }
582
+ }
583
+ #endif
570
584
  bool HelloRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
571
585
  switch (field_id) {
572
586
  case 2: {
@@ -3095,6 +3109,16 @@ void SubscribeHomeAssistantStatesRequest::dump_to(std::string &out) const {
3095
3109
  out.append("SubscribeHomeAssistantStatesRequest {}");
3096
3110
  }
3097
3111
  #endif
3112
+ bool SubscribeHomeAssistantStateResponse::decode_varint(uint32_t field_id, ProtoVarInt value) {
3113
+ switch (field_id) {
3114
+ case 3: {
3115
+ this->once = value.as_bool();
3116
+ return true;
3117
+ }
3118
+ default:
3119
+ return false;
3120
+ }
3121
+ }
3098
3122
  bool SubscribeHomeAssistantStateResponse::decode_length(uint32_t field_id, ProtoLengthDelimited value) {
3099
3123
  switch (field_id) {
3100
3124
  case 1: {
@@ -3112,6 +3136,7 @@ bool SubscribeHomeAssistantStateResponse::decode_length(uint32_t field_id, Proto
3112
3136
  void SubscribeHomeAssistantStateResponse::encode(ProtoWriteBuffer buffer) const {
3113
3137
  buffer.encode_string(1, this->entity_id);
3114
3138
  buffer.encode_string(2, this->attribute);
3139
+ buffer.encode_bool(3, this->once);
3115
3140
  }
3116
3141
  #ifdef HAS_PROTO_MESSAGE_DUMP
3117
3142
  void SubscribeHomeAssistantStateResponse::dump_to(std::string &out) const {
@@ -3124,6 +3149,10 @@ void SubscribeHomeAssistantStateResponse::dump_to(std::string &out) const {
3124
3149
  out.append(" attribute: ");
3125
3150
  out.append("'").append(this->attribute).append("'");
3126
3151
  out.append("\n");
3152
+
3153
+ out.append(" once: ");
3154
+ out.append(YESNO(this->once));
3155
+ out.append("\n");
3127
3156
  out.append("}");
3128
3157
  }
3129
3158
  #endif
@@ -8596,7 +8625,7 @@ void UpdateStateResponse::dump_to(std::string &out) const {
8596
8625
  bool UpdateCommandRequest::decode_varint(uint32_t field_id, ProtoVarInt value) {
8597
8626
  switch (field_id) {
8598
8627
  case 2: {
8599
- this->install = value.as_bool();
8628
+ this->command = value.as_enum<enums::UpdateCommand>();
8600
8629
  return true;
8601
8630
  }
8602
8631
  default:
@@ -8615,7 +8644,7 @@ bool UpdateCommandRequest::decode_32bit(uint32_t field_id, Proto32Bit value) {
8615
8644
  }
8616
8645
  void UpdateCommandRequest::encode(ProtoWriteBuffer buffer) const {
8617
8646
  buffer.encode_fixed32(1, this->key);
8618
- buffer.encode_bool(2, this->install);
8647
+ buffer.encode_enum<enums::UpdateCommand>(2, this->command);
8619
8648
  }
8620
8649
  #ifdef HAS_PROTO_MESSAGE_DUMP
8621
8650
  void UpdateCommandRequest::dump_to(std::string &out) const {
@@ -8626,8 +8655,8 @@ void UpdateCommandRequest::dump_to(std::string &out) const {
8626
8655
  out.append(buffer);
8627
8656
  out.append("\n");
8628
8657
 
8629
- out.append(" install: ");
8630
- out.append(YESNO(this->install));
8658
+ out.append(" command: ");
8659
+ out.append(proto_enum_to_string<enums::UpdateCommand>(this->command));
8631
8660
  out.append("\n");
8632
8661
  out.append("}");
8633
8662
  }
@@ -227,6 +227,11 @@ enum ValveOperation : uint32_t {
227
227
  VALVE_OPERATION_IS_OPENING = 1,
228
228
  VALVE_OPERATION_IS_CLOSING = 2,
229
229
  };
230
+ enum UpdateCommand : uint32_t {
231
+ UPDATE_COMMAND_NONE = 0,
232
+ UPDATE_COMMAND_UPDATE = 1,
233
+ UPDATE_COMMAND_CHECK = 2,
234
+ };
230
235
 
231
236
  } // namespace enums
232
237
 
@@ -831,6 +836,7 @@ class SubscribeHomeAssistantStateResponse : public ProtoMessage {
831
836
  public:
832
837
  std::string entity_id{};
833
838
  std::string attribute{};
839
+ bool once{false};
834
840
  void encode(ProtoWriteBuffer buffer) const override;
835
841
  #ifdef HAS_PROTO_MESSAGE_DUMP
836
842
  void dump_to(std::string &out) const override;
@@ -838,6 +844,7 @@ class SubscribeHomeAssistantStateResponse : public ProtoMessage {
838
844
 
839
845
  protected:
840
846
  bool decode_length(uint32_t field_id, ProtoLengthDelimited value) override;
847
+ bool decode_varint(uint32_t field_id, ProtoVarInt value) override;
841
848
  };
842
849
  class HomeAssistantStateResponse : public ProtoMessage {
843
850
  public:
@@ -2175,7 +2182,7 @@ class UpdateStateResponse : public ProtoMessage {
2175
2182
  class UpdateCommandRequest : public ProtoMessage {
2176
2183
  public:
2177
2184
  uint32_t key{0};
2178
- bool install{false};
2185
+ enums::UpdateCommand command{};
2179
2186
  void encode(ProtoWriteBuffer buffer) const override;
2180
2187
  #ifdef HAS_PROTO_MESSAGE_DUMP
2181
2188
  void dump_to(std::string &out) const override;
@@ -359,8 +359,18 @@ void APIServer::subscribe_home_assistant_state(std::string entity_id, optional<s
359
359
  .entity_id = std::move(entity_id),
360
360
  .attribute = std::move(attribute),
361
361
  .callback = std::move(f),
362
+ .once = false,
362
363
  });
363
364
  }
365
+ void APIServer::get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
366
+ std::function<void(std::string)> f) {
367
+ this->state_subs_.push_back(HomeAssistantStateSubscription{
368
+ .entity_id = std::move(entity_id),
369
+ .attribute = std::move(attribute),
370
+ .callback = std::move(f),
371
+ .once = true,
372
+ });
373
+ };
364
374
  const std::vector<APIServer::HomeAssistantStateSubscription> &APIServer::get_state_subs() const {
365
375
  return this->state_subs_;
366
376
  }
@@ -112,10 +112,13 @@ class APIServer : public Component, public Controller {
112
112
  std::string entity_id;
113
113
  optional<std::string> attribute;
114
114
  std::function<void(std::string)> callback;
115
+ bool once;
115
116
  };
116
117
 
117
118
  void subscribe_home_assistant_state(std::string entity_id, optional<std::string> attribute,
118
119
  std::function<void(std::string)> f);
120
+ void get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
121
+ std::function<void(std::string)> f);
119
122
  const std::vector<HomeAssistantStateSubscription> &get_state_subs() const;
120
123
  const std::vector<UserServiceDescriptor *> &get_user_services() const { return this->user_services_; }
121
124