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
@@ -1,8 +1,16 @@
1
1
  import binascii
2
2
  import esphome.codegen as cg
3
3
  import esphome.config_validation as cv
4
+ from esphome import automation
4
5
  from esphome.components import modbus
5
- from esphome.const import CONF_ADDRESS, CONF_ID, CONF_NAME, CONF_LAMBDA, CONF_OFFSET
6
+ from esphome.const import (
7
+ CONF_ADDRESS,
8
+ CONF_ID,
9
+ CONF_NAME,
10
+ CONF_LAMBDA,
11
+ CONF_OFFSET,
12
+ CONF_TRIGGER_ID,
13
+ )
6
14
  from esphome.cpp_helpers import logging
7
15
  from .const import (
8
16
  CONF_BITMASK,
@@ -12,6 +20,7 @@ from .const import (
12
20
  CONF_CUSTOM_COMMAND,
13
21
  CONF_FORCE_NEW_RANGE,
14
22
  CONF_MODBUS_CONTROLLER_ID,
23
+ CONF_ON_COMMAND_SENT,
15
24
  CONF_REGISTER_COUNT,
16
25
  CONF_REGISTER_TYPE,
17
26
  CONF_RESPONSE_SIZE,
@@ -97,6 +106,10 @@ TYPE_REGISTER_MAP = {
97
106
  "FP32_R": 2,
98
107
  }
99
108
 
109
+ ModbusCommandSentTrigger = modbus_controller_ns.class_(
110
+ "ModbusCommandSentTrigger", automation.Trigger.template(cg.int_, cg.int_)
111
+ )
112
+
100
113
  _LOGGER = logging.getLogger(__name__)
101
114
 
102
115
  ModbusServerRegisterSchema = cv.Schema(
@@ -120,13 +133,19 @@ CONFIG_SCHEMA = cv.All(
120
133
  cv.Optional(
121
134
  CONF_SERVER_REGISTERS,
122
135
  ): cv.ensure_list(ModbusServerRegisterSchema),
136
+ cv.Optional(CONF_ON_COMMAND_SENT): automation.validate_automation(
137
+ {
138
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
139
+ ModbusCommandSentTrigger
140
+ ),
141
+ }
142
+ ),
123
143
  }
124
144
  )
125
145
  .extend(cv.polling_component_schema("60s"))
126
146
  .extend(modbus.modbus_device_schema(0x01))
127
147
  )
128
148
 
129
-
130
149
  ModbusItemBaseSchema = cv.Schema(
131
150
  {
132
151
  cv.GenerateID(CONF_MODBUS_CONTROLLER_ID): cv.use_id(ModbusController),
@@ -254,6 +273,11 @@ async def to_code(config):
254
273
  )
255
274
  )
256
275
  await register_modbus_device(var, config)
276
+ for conf in config.get(CONF_ON_COMMAND_SENT, []):
277
+ trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
278
+ await automation.build_automation(
279
+ trigger, [(int, "function_code"), (int, "address")], conf
280
+ )
257
281
 
258
282
 
259
283
  async def register_modbus_device(var, config):
@@ -0,0 +1,19 @@
1
+ #pragma once
2
+
3
+ #include "esphome/core/component.h"
4
+ #include "esphome/core/automation.h"
5
+ #include "esphome/components/modbus_controller/modbus_controller.h"
6
+
7
+ namespace esphome {
8
+ namespace modbus_controller {
9
+
10
+ class ModbusCommandSentTrigger : public Trigger<int, int> {
11
+ public:
12
+ ModbusCommandSentTrigger(ModbusController *a_modbuscontroller) {
13
+ a_modbuscontroller->add_on_command_sent_callback(
14
+ [this](int function_code, int address) { this->trigger(function_code, address); });
15
+ }
16
+ };
17
+
18
+ } // namespace modbus_controller
19
+ } // namespace esphome
@@ -6,6 +6,7 @@ CONF_CUSTOM_COMMAND = "custom_command"
6
6
  CONF_FORCE_NEW_RANGE = "force_new_range"
7
7
  CONF_MODBUS_CONTROLLER_ID = "modbus_controller_id"
8
8
  CONF_MODBUS_FUNCTIONCODE = "modbus_functioncode"
9
+ CONF_ON_COMMAND_SENT = "on_command_sent"
9
10
  CONF_RAW_ENCODE = "raw_encode"
10
11
  CONF_REGISTER_COUNT = "register_count"
11
12
  CONF_REGISTER_TYPE = "register_type"
@@ -43,7 +43,11 @@ bool ModbusController::send_next_command_() {
43
43
  ESP_LOGV(TAG, "Sending next modbus command to device %d register 0x%02X count %d", this->address_,
44
44
  command->register_address, command->register_count);
45
45
  command->send();
46
+
46
47
  this->last_command_timestamp_ = millis();
48
+
49
+ this->command_sent_callback_.call((int) command->function_code, command->register_address);
50
+
47
51
  // remove from queue if no handler is defined
48
52
  if (!command->on_data_func) {
49
53
  command_queue_.pop_front();
@@ -659,5 +663,9 @@ int64_t payload_to_number(const std::vector<uint8_t> &data, SensorValueType sens
659
663
  return value;
660
664
  }
661
665
 
666
+ void ModbusController::add_on_command_sent_callback(std::function<void(int, int)> &&callback) {
667
+ this->command_sent_callback_.add(std::move(callback));
668
+ }
669
+
662
670
  } // namespace modbus_controller
663
671
  } // namespace esphome
@@ -456,6 +456,8 @@ class ModbusController : public PollingComponent, public modbus::ModbusDevice {
456
456
  size_t get_command_queue_length() { return command_queue_.size(); }
457
457
  /// get if the module is offline, didn't respond the last command
458
458
  bool get_module_offline() { return module_offline_; }
459
+ /// Set callback for commands
460
+ void add_on_command_sent_callback(std::function<void(int, int)> &&callback);
459
461
 
460
462
  protected:
461
463
  /// parse sensormap_ and create range of sequential addresses
@@ -488,6 +490,7 @@ class ModbusController : public PollingComponent, public modbus::ModbusDevice {
488
490
  bool module_offline_;
489
491
  /// how many updates to skip if module is offline
490
492
  uint16_t offline_skip_updates_;
493
+ CallbackManager<void(int, int)> command_sent_callback_{};
491
494
  };
492
495
 
493
496
  /** Convert vector<uint8_t> response payload to float.
@@ -1,10 +1,11 @@
1
1
  import re
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
7
6
  from esphome.components import logger
7
+ from esphome.components.esp32 import add_idf_sdkconfig_option
8
+ import esphome.config_validation as cv
8
9
  from esphome.const import (
9
10
  CONF_AVAILABILITY,
10
11
  CONF_BIRTH_MESSAGE,
@@ -13,21 +14,21 @@ from esphome.const import (
13
14
  CONF_CLIENT_CERTIFICATE,
14
15
  CONF_CLIENT_CERTIFICATE_KEY,
15
16
  CONF_CLIENT_ID,
16
- CONF_COMMAND_TOPIC,
17
17
  CONF_COMMAND_RETAIN,
18
+ CONF_COMMAND_TOPIC,
18
19
  CONF_DISCOVERY,
20
+ CONF_DISCOVERY_OBJECT_ID_GENERATOR,
19
21
  CONF_DISCOVERY_PREFIX,
20
22
  CONF_DISCOVERY_RETAIN,
21
23
  CONF_DISCOVERY_UNIQUE_ID_GENERATOR,
22
- CONF_DISCOVERY_OBJECT_ID_GENERATOR,
23
24
  CONF_ID,
24
25
  CONF_KEEPALIVE,
25
26
  CONF_LEVEL,
26
27
  CONF_LOG_TOPIC,
27
- CONF_ON_JSON_MESSAGE,
28
- CONF_ON_MESSAGE,
29
28
  CONF_ON_CONNECT,
30
29
  CONF_ON_DISCONNECT,
30
+ CONF_ON_JSON_MESSAGE,
31
+ CONF_ON_MESSAGE,
31
32
  CONF_PASSWORD,
32
33
  CONF_PAYLOAD,
33
34
  CONF_PAYLOAD_AVAILABLE,
@@ -45,12 +46,11 @@ from esphome.const import (
45
46
  CONF_USE_ABBREVIATIONS,
46
47
  CONF_USERNAME,
47
48
  CONF_WILL_MESSAGE,
49
+ PLATFORM_BK72XX,
48
50
  PLATFORM_ESP32,
49
51
  PLATFORM_ESP8266,
50
- PLATFORM_BK72XX,
51
52
  )
52
- from esphome.core import coroutine_with_priority, CORE
53
- from esphome.components.esp32 import add_idf_sdkconfig_option
53
+ from esphome.core import CORE, coroutine_with_priority
54
54
 
55
55
  DEPENDENCIES = ["network"]
56
56
 
@@ -61,6 +61,7 @@ def AUTO_LOAD():
61
61
  return ["json"]
62
62
 
63
63
 
64
+ CONF_DISCOVER_IP = "discover_ip"
64
65
  CONF_IDF_SEND_ASYNC = "idf_send_async"
65
66
  CONF_SKIP_CERT_CN_CHECK = "skip_cert_cn_check"
66
67
 
@@ -109,6 +110,9 @@ MQTTDisconnectTrigger = mqtt_ns.class_(
109
110
  MQTTComponent = mqtt_ns.class_("MQTTComponent", cg.Component)
110
111
  MQTTConnectedCondition = mqtt_ns.class_("MQTTConnectedCondition", Condition)
111
112
 
113
+ MQTTAlarmControlPanelComponent = mqtt_ns.class_(
114
+ "MQTTAlarmControlPanelComponent", MQTTComponent
115
+ )
112
116
  MQTTBinarySensorComponent = mqtt_ns.class_("MQTTBinarySensorComponent", MQTTComponent)
113
117
  MQTTClimateComponent = mqtt_ns.class_("MQTTClimateComponent", MQTTComponent)
114
118
  MQTTCoverComponent = mqtt_ns.class_("MQTTCoverComponent", MQTTComponent)
@@ -225,6 +229,7 @@ CONFIG_SCHEMA = cv.All(
225
229
  cv.boolean, cv.one_of("CLEAN", upper=True)
226
230
  ),
227
231
  cv.Optional(CONF_DISCOVERY_RETAIN, default=True): cv.boolean,
232
+ cv.Optional(CONF_DISCOVER_IP, default=True): cv.boolean,
228
233
  cv.Optional(
229
234
  CONF_DISCOVERY_PREFIX, default="homeassistant"
230
235
  ): cv.publish_topic,
@@ -328,8 +333,12 @@ async def to_code(config):
328
333
  discovery_prefix = config[CONF_DISCOVERY_PREFIX]
329
334
  discovery_unique_id_generator = config[CONF_DISCOVERY_UNIQUE_ID_GENERATOR]
330
335
  discovery_object_id_generator = config[CONF_DISCOVERY_OBJECT_ID_GENERATOR]
336
+ discover_ip = config[CONF_DISCOVER_IP]
331
337
 
332
338
  if not discovery:
339
+ discovery_prefix = ""
340
+
341
+ if not discovery and not discover_ip:
333
342
  cg.add(var.disable_discovery())
334
343
  elif discovery == "CLEAN":
335
344
  cg.add(
@@ -338,6 +347,7 @@ async def to_code(config):
338
347
  discovery_unique_id_generator,
339
348
  discovery_object_id_generator,
340
349
  discovery_retain,
350
+ discover_ip,
341
351
  True,
342
352
  )
343
353
  )
@@ -348,6 +358,7 @@ async def to_code(config):
348
358
  discovery_unique_id_generator,
349
359
  discovery_object_id_generator,
350
360
  discovery_retain,
361
+ discover_ip,
351
362
  )
352
363
  )
353
364
 
@@ -0,0 +1,128 @@
1
+ #include "mqtt_alarm_control_panel.h"
2
+ #include "esphome/core/log.h"
3
+
4
+ #include "mqtt_const.h"
5
+
6
+ #ifdef USE_MQTT
7
+ #ifdef USE_ALARM_CONTROL_PANEL
8
+
9
+ namespace esphome {
10
+ namespace mqtt {
11
+
12
+ static const char *const TAG = "mqtt.alarm_control_panel";
13
+
14
+ using namespace esphome::alarm_control_panel;
15
+
16
+ MQTTAlarmControlPanelComponent::MQTTAlarmControlPanelComponent(AlarmControlPanel *alarm_control_panel)
17
+ : alarm_control_panel_(alarm_control_panel) {}
18
+ void MQTTAlarmControlPanelComponent::setup() {
19
+ this->alarm_control_panel_->add_on_state_callback([this]() { this->publish_state(); });
20
+ this->subscribe(this->get_command_topic_(), [this](const std::string &topic, const std::string &payload) {
21
+ auto call = this->alarm_control_panel_->make_call();
22
+ if (strcasecmp(payload.c_str(), "ARM_AWAY") == 0) {
23
+ call.arm_away();
24
+ } else if (strcasecmp(payload.c_str(), "ARM_HOME") == 0) {
25
+ call.arm_home();
26
+ } else if (strcasecmp(payload.c_str(), "ARM_NIGHT") == 0) {
27
+ call.arm_night();
28
+ } else if (strcasecmp(payload.c_str(), "ARM_VACATION") == 0) {
29
+ call.arm_vacation();
30
+ } else if (strcasecmp(payload.c_str(), "ARM_CUSTOM_BYPASS") == 0) {
31
+ call.arm_custom_bypass();
32
+ } else if (strcasecmp(payload.c_str(), "DISARM") == 0) {
33
+ call.disarm();
34
+ } else if (strcasecmp(payload.c_str(), "PENDING") == 0) {
35
+ call.pending();
36
+ } else if (strcasecmp(payload.c_str(), "TRIGGERED") == 0) {
37
+ call.triggered();
38
+ } else {
39
+ ESP_LOGW(TAG, "'%s': Received unknown command payload %s", this->friendly_name().c_str(), payload.c_str());
40
+ }
41
+ call.perform();
42
+ });
43
+ }
44
+
45
+ void MQTTAlarmControlPanelComponent::dump_config() {
46
+ ESP_LOGCONFIG(TAG, "MQTT alarm_control_panel '%s':", this->alarm_control_panel_->get_name().c_str());
47
+ LOG_MQTT_COMPONENT(true, true)
48
+ ESP_LOGCONFIG(TAG, " Supported Features: %" PRIu32, this->alarm_control_panel_->get_supported_features());
49
+ ESP_LOGCONFIG(TAG, " Requires Code to Disarm: %s", YESNO(this->alarm_control_panel_->get_requires_code()));
50
+ ESP_LOGCONFIG(TAG, " Requires Code To Arm: %s", YESNO(this->alarm_control_panel_->get_requires_code_to_arm()));
51
+ }
52
+
53
+ void MQTTAlarmControlPanelComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) {
54
+ JsonArray supported_features = root.createNestedArray(MQTT_SUPPORTED_FEATURES);
55
+ const uint32_t acp_supported_features = this->alarm_control_panel_->get_supported_features();
56
+ if (acp_supported_features & ACP_FEAT_ARM_AWAY) {
57
+ supported_features.add("arm_away");
58
+ }
59
+ if (acp_supported_features & ACP_FEAT_ARM_HOME) {
60
+ supported_features.add("arm_home");
61
+ }
62
+ if (acp_supported_features & ACP_FEAT_ARM_NIGHT) {
63
+ supported_features.add("arm_night");
64
+ }
65
+ if (acp_supported_features & ACP_FEAT_ARM_VACATION) {
66
+ supported_features.add("arm_vacation");
67
+ }
68
+ if (acp_supported_features & ACP_FEAT_ARM_CUSTOM_BYPASS) {
69
+ supported_features.add("arm_custom_bypass");
70
+ }
71
+ if (acp_supported_features & ACP_FEAT_TRIGGER) {
72
+ supported_features.add("trigger");
73
+ }
74
+ root[MQTT_CODE_DISARM_REQUIRED] = this->alarm_control_panel_->get_requires_code();
75
+ root[MQTT_CODE_ARM_REQUIRED] = this->alarm_control_panel_->get_requires_code_to_arm();
76
+ }
77
+
78
+ std::string MQTTAlarmControlPanelComponent::component_type() const { return "alarm_control_panel"; }
79
+ const EntityBase *MQTTAlarmControlPanelComponent::get_entity() const { return this->alarm_control_panel_; }
80
+
81
+ bool MQTTAlarmControlPanelComponent::send_initial_state() { return this->publish_state(); }
82
+ bool MQTTAlarmControlPanelComponent::publish_state() {
83
+ bool success = true;
84
+ const char *state_s = "";
85
+ switch (this->alarm_control_panel_->get_state()) {
86
+ case ACP_STATE_DISARMED:
87
+ state_s = "disarmed";
88
+ break;
89
+ case ACP_STATE_ARMED_HOME:
90
+ state_s = "armed_home";
91
+ break;
92
+ case ACP_STATE_ARMED_AWAY:
93
+ state_s = "armed_away";
94
+ break;
95
+ case ACP_STATE_ARMED_NIGHT:
96
+ state_s = "armed_night";
97
+ break;
98
+ case ACP_STATE_ARMED_VACATION:
99
+ state_s = "armed_vacation";
100
+ break;
101
+ case ACP_STATE_ARMED_CUSTOM_BYPASS:
102
+ state_s = "armed_custom_bypass";
103
+ break;
104
+ case ACP_STATE_PENDING:
105
+ state_s = "pending";
106
+ break;
107
+ case ACP_STATE_ARMING:
108
+ state_s = "arming";
109
+ break;
110
+ case ACP_STATE_DISARMING:
111
+ state_s = "disarming";
112
+ break;
113
+ case ACP_STATE_TRIGGERED:
114
+ state_s = "triggered";
115
+ break;
116
+ default:
117
+ state_s = "unknown";
118
+ }
119
+ if (!this->publish(this->get_state_topic_(), state_s))
120
+ success = false;
121
+ return success;
122
+ }
123
+
124
+ } // namespace mqtt
125
+ } // namespace esphome
126
+
127
+ #endif
128
+ #endif // USE_MQTT
@@ -0,0 +1,39 @@
1
+ #pragma once
2
+
3
+ #include "esphome/core/defines.h"
4
+
5
+ #ifdef USE_MQTT
6
+ #ifdef USE_ALARM_CONTROL_PANEL
7
+
8
+ #include "mqtt_component.h"
9
+ #include "esphome/components/alarm_control_panel/alarm_control_panel.h"
10
+
11
+ namespace esphome {
12
+ namespace mqtt {
13
+
14
+ class MQTTAlarmControlPanelComponent : public mqtt::MQTTComponent {
15
+ public:
16
+ explicit MQTTAlarmControlPanelComponent(alarm_control_panel::AlarmControlPanel *alarm_control_panel);
17
+
18
+ void setup() override;
19
+
20
+ void send_discovery(JsonObject root, mqtt::SendDiscoveryConfig &config) override;
21
+
22
+ bool send_initial_state() override;
23
+
24
+ bool publish_state();
25
+
26
+ void dump_config() override;
27
+
28
+ protected:
29
+ std::string component_type() const override;
30
+ const EntityBase *get_entity() const override;
31
+
32
+ alarm_control_panel::AlarmControlPanel *alarm_control_panel_;
33
+ };
34
+
35
+ } // namespace mqtt
36
+ } // namespace esphome
37
+
38
+ #endif
39
+ #endif // USE_MQTT
@@ -1,5 +1,6 @@
1
1
  #pragma once
2
-
2
+ #include "esphome/core/defines.h"
3
+ #ifdef USE_MQTT
3
4
  #include <string>
4
5
  #include <map>
5
6
  #include "esphome/components/network/ip_address.h"
@@ -67,3 +68,4 @@ class MQTTBackend {
67
68
 
68
69
  } // namespace mqtt
69
70
  } // namespace esphome
71
+ #endif
@@ -1,7 +1,9 @@
1
+ #include "mqtt_backend_esp32.h"
2
+
3
+ #ifdef USE_MQTT
1
4
  #ifdef USE_ESP32
2
5
 
3
6
  #include <string>
4
- #include "mqtt_backend_esp32.h"
5
7
  #include "esphome/core/log.h"
6
8
  #include "esphome/core/helpers.h"
7
9
 
@@ -189,3 +191,4 @@ void MQTTBackendESP32::mqtt_event_handler(void *handler_args, esp_event_base_t b
189
191
  } // namespace mqtt
190
192
  } // namespace esphome
191
193
  #endif // USE_ESP32
194
+ #endif
@@ -1,5 +1,7 @@
1
1
  #pragma once
2
2
 
3
+ #include "mqtt_backend.h"
4
+ #ifdef USE_MQTT
3
5
  #ifdef USE_ESP32
4
6
 
5
7
  #include <string>
@@ -7,7 +9,6 @@
7
9
  #include <mqtt_client.h>
8
10
  #include "esphome/components/network/ip_address.h"
9
11
  #include "esphome/core/helpers.h"
10
- #include "mqtt_backend.h"
11
12
 
12
13
  namespace esphome {
13
14
  namespace mqtt {
@@ -174,3 +175,4 @@ class MQTTBackendESP32 final : public MQTTBackend {
174
175
  } // namespace esphome
175
176
 
176
177
  #endif
178
+ #endif
@@ -1,8 +1,9 @@
1
1
  #pragma once
2
+ #include "mqtt_backend.h"
2
3
 
4
+ #ifdef USE_MQTT
3
5
  #ifdef USE_ESP8266
4
6
 
5
- #include "mqtt_backend.h"
6
7
  #include <AsyncMqttClient.h>
7
8
 
8
9
  namespace esphome {
@@ -70,3 +71,4 @@ class MQTTBackendESP8266 final : public MQTTBackend {
70
71
  } // namespace esphome
71
72
 
72
73
  #endif // defined(USE_ESP8266)
74
+ #endif
@@ -1,8 +1,9 @@
1
1
  #pragma once
2
+ #include "mqtt_backend.h"
2
3
 
4
+ #ifdef USE_MQTT
3
5
  #ifdef USE_LIBRETINY
4
6
 
5
- #include "mqtt_backend.h"
6
7
  #include <AsyncMqttClient.h>
7
8
 
8
9
  namespace esphome {
@@ -70,3 +71,4 @@ class MQTTBackendLibreTiny final : public MQTTBackend {
70
71
  } // namespace esphome
71
72
 
72
73
  #endif // defined(USE_LIBRETINY)
74
+ #endif
@@ -66,7 +66,7 @@ void MQTTClientComponent::setup() {
66
66
  }
67
67
  #endif
68
68
 
69
- if (this->is_discovery_enabled()) {
69
+ if (this->is_discovery_ip_enabled()) {
70
70
  this->subscribe(
71
71
  "esphome/discover", [this](const std::string &topic, const std::string &payload) { this->send_device_info_(); },
72
72
  2);
@@ -82,7 +82,7 @@ void MQTTClientComponent::setup() {
82
82
  }
83
83
 
84
84
  void MQTTClientComponent::send_device_info_() {
85
- if (!this->is_connected() or !this->is_discovery_enabled()) {
85
+ if (!this->is_connected() or !this->is_discovery_ip_enabled()) {
86
86
  return;
87
87
  }
88
88
  std::string topic = "esphome/discover/";
@@ -99,6 +99,9 @@ void MQTTClientComponent::send_device_info_() {
99
99
  }
100
100
  }
101
101
  root["name"] = App.get_name();
102
+ if (!App.get_friendly_name().empty()) {
103
+ root["friendly_name"] = App.get_friendly_name();
104
+ }
102
105
  #ifdef USE_API
103
106
  root["port"] = api::global_api_server->get_port();
104
107
  #endif
@@ -130,6 +133,10 @@ void MQTTClientComponent::send_device_info_() {
130
133
  #ifdef USE_DASHBOARD_IMPORT
131
134
  root["package_import_url"] = dashboard_import::get_package_import_url();
132
135
  #endif
136
+
137
+ #ifdef USE_API_NOISE
138
+ root["api_encryption"] = "Noise_NNpsk0_25519_ChaChaPoly_SHA256";
139
+ #endif
133
140
  },
134
141
  2, this->discovery_info_.retain);
135
142
  }
@@ -140,6 +147,9 @@ void MQTTClientComponent::dump_config() {
140
147
  this->ip_.str().c_str());
141
148
  ESP_LOGCONFIG(TAG, " Username: " LOG_SECRET("'%s'"), this->credentials_.username.c_str());
142
149
  ESP_LOGCONFIG(TAG, " Client ID: " LOG_SECRET("'%s'"), this->credentials_.client_id.c_str());
150
+ if (this->is_discovery_ip_enabled()) {
151
+ ESP_LOGCONFIG(TAG, " Discovery IP enabled");
152
+ }
143
153
  if (!this->discovery_info_.prefix.empty()) {
144
154
  ESP_LOGCONFIG(TAG, " Discovery prefix: '%s'", this->discovery_info_.prefix.c_str());
145
155
  ESP_LOGCONFIG(TAG, " Discovery retain: %s", YESNO(this->discovery_info_.retain));
@@ -581,6 +591,7 @@ void MQTTClientComponent::disable_shutdown_message() {
581
591
  this->recalculate_availability_();
582
592
  }
583
593
  bool MQTTClientComponent::is_discovery_enabled() const { return !this->discovery_info_.prefix.empty(); }
594
+ bool MQTTClientComponent::is_discovery_ip_enabled() const { return this->discovery_info_.discover_ip; }
584
595
  const Availability &MQTTClientComponent::get_availability() { return this->availability_; }
585
596
  void MQTTClientComponent::recalculate_availability_() {
586
597
  if (this->birth_message_.topic.empty() || this->birth_message_.topic != this->last_will_.topic) {
@@ -606,8 +617,9 @@ void MQTTClientComponent::set_shutdown_message(MQTTMessage &&message) { this->sh
606
617
 
607
618
  void MQTTClientComponent::set_discovery_info(std::string &&prefix, MQTTDiscoveryUniqueIdGenerator unique_id_generator,
608
619
  MQTTDiscoveryObjectIdGenerator object_id_generator, bool retain,
609
- bool clean) {
620
+ bool discover_ip, bool clean) {
610
621
  this->discovery_info_.prefix = std::move(prefix);
622
+ this->discovery_info_.discover_ip = discover_ip;
611
623
  this->discovery_info_.unique_id_generator = unique_id_generator;
612
624
  this->discovery_info_.object_id_generator = object_id_generator;
613
625
  this->discovery_info_.retain = retain;
@@ -620,6 +632,7 @@ void MQTTClientComponent::disable_discovery() {
620
632
  this->discovery_info_ = MQTTDiscoveryInfo{
621
633
  .prefix = "",
622
634
  .retain = false,
635
+ .discover_ip = false,
623
636
  .clean = false,
624
637
  .unique_id_generator = MQTT_LEGACY_UNIQUE_ID_GENERATOR,
625
638
  .object_id_generator = MQTT_NONE_OBJECT_ID_GENERATOR,
@@ -79,6 +79,7 @@ enum MQTTDiscoveryObjectIdGenerator {
79
79
  struct MQTTDiscoveryInfo {
80
80
  std::string prefix; ///< The Home Assistant discovery prefix. Empty means disabled.
81
81
  bool retain; ///< Whether to retain discovery messages.
82
+ bool discover_ip; ///< Enable the Home Assistant device discovery.
82
83
  bool clean;
83
84
  MQTTDiscoveryUniqueIdGenerator unique_id_generator;
84
85
  MQTTDiscoveryObjectIdGenerator object_id_generator;
@@ -122,12 +123,14 @@ class MQTTClientComponent : public Component {
122
123
  * @param retain Whether to retain discovery messages.
123
124
  */
124
125
  void set_discovery_info(std::string &&prefix, MQTTDiscoveryUniqueIdGenerator unique_id_generator,
125
- MQTTDiscoveryObjectIdGenerator object_id_generator, bool retain, bool clean = false);
126
+ MQTTDiscoveryObjectIdGenerator object_id_generator, bool retain, bool discover_ip,
127
+ bool clean = false);
126
128
  /// Get Home Assistant discovery info.
127
129
  const MQTTDiscoveryInfo &get_discovery_info() const;
128
130
  /// Globally disable Home Assistant discovery.
129
131
  void disable_discovery();
130
132
  bool is_discovery_enabled() const;
133
+ bool is_discovery_ip_enabled() const;
131
134
 
132
135
  #if ASYNC_TCP_SSL_ENABLED
133
136
  /** Add a SSL fingerprint to use for TCP SSL connections to the MQTT broker.
@@ -290,6 +293,7 @@ class MQTTClientComponent : public Component {
290
293
  MQTTDiscoveryInfo discovery_info_{
291
294
  .prefix = "homeassistant",
292
295
  .retain = true,
296
+ .discover_ip = true,
293
297
  .clean = false,
294
298
  .unique_id_generator = MQTT_LEGACY_UNIQUE_ID_GENERATOR,
295
299
  .object_id_generator = MQTT_NONE_OBJECT_ID_GENERATOR,
@@ -150,12 +150,40 @@ bool MQTTComponent::send_discovery_() {
150
150
  const std::string &node_area = App.get_area();
151
151
 
152
152
  JsonObject device_info = root.createNestedObject(MQTT_DEVICE);
153
- device_info[MQTT_DEVICE_IDENTIFIERS] = get_mac_address();
153
+ const auto mac = get_mac_address();
154
+ device_info[MQTT_DEVICE_IDENTIFIERS] = mac;
154
155
  device_info[MQTT_DEVICE_NAME] = node_friendly_name;
155
- device_info[MQTT_DEVICE_SW_VERSION] = "esphome v" ESPHOME_VERSION " " + App.get_compilation_time();
156
+ #ifdef ESPHOME_PROJECT_NAME
157
+ device_info[MQTT_DEVICE_SW_VERSION] = ESPHOME_PROJECT_VERSION " (ESPHome " ESPHOME_VERSION ")";
158
+ const char *model = std::strchr(ESPHOME_PROJECT_NAME, '.');
159
+ if (model == nullptr) { // must never happen but check anyway
160
+ device_info[MQTT_DEVICE_MODEL] = ESPHOME_BOARD;
161
+ device_info[MQTT_DEVICE_MANUFACTURER] = ESPHOME_PROJECT_NAME;
162
+ } else {
163
+ device_info[MQTT_DEVICE_MODEL] = model + 1;
164
+ device_info[MQTT_DEVICE_MANUFACTURER] = std::string(ESPHOME_PROJECT_NAME, model - ESPHOME_PROJECT_NAME);
165
+ }
166
+ #else
167
+ device_info[MQTT_DEVICE_SW_VERSION] = ESPHOME_VERSION " (" + App.get_compilation_time() + ")";
156
168
  device_info[MQTT_DEVICE_MODEL] = ESPHOME_BOARD;
157
- device_info[MQTT_DEVICE_MANUFACTURER] = "espressif";
158
- device_info[MQTT_DEVICE_SUGGESTED_AREA] = node_area;
169
+ #if defined(USE_ESP8266) || defined(USE_ESP32)
170
+ device_info[MQTT_DEVICE_MANUFACTURER] = "Espressif";
171
+ #elif defined(USE_RP2040)
172
+ device_info[MQTT_DEVICE_MANUFACTURER] = "Raspberry Pi";
173
+ #elif defined(USE_BK72XX)
174
+ device_info[MQTT_DEVICE_MANUFACTURER] = "Beken";
175
+ #elif defined(USE_RTL87XX)
176
+ device_info[MQTT_DEVICE_MANUFACTURER] = "Realtek";
177
+ #elif defined(USE_HOST)
178
+ device_info[MQTT_DEVICE_MANUFACTURER] = "Host";
179
+ #endif
180
+ #endif
181
+ if (!node_area.empty()) {
182
+ device_info[MQTT_DEVICE_SUGGESTED_AREA] = node_area;
183
+ }
184
+
185
+ device_info[MQTT_DEVICE_CONNECTIONS][0][0] = "mac";
186
+ device_info[MQTT_DEVICE_CONNECTIONS][0][1] = mac;
159
187
  },
160
188
  this->qos_, discovery_info.retain);
161
189
  }
@@ -62,6 +62,7 @@ constexpr const char *const MQTT_DEVICE_MODEL = "mdl";
62
62
  constexpr const char *const MQTT_DEVICE_NAME = "name";
63
63
  constexpr const char *const MQTT_DEVICE_SUGGESTED_AREA = "sa";
64
64
  constexpr const char *const MQTT_DEVICE_SW_VERSION = "sw";
65
+ constexpr const char *const MQTT_DEVICE_HW_VERSION = "hw";
65
66
  constexpr const char *const MQTT_DOCKED_TEMPLATE = "dock_tpl";
66
67
  constexpr const char *const MQTT_DOCKED_TOPIC = "dock_t";
67
68
  constexpr const char *const MQTT_EFFECT_COMMAND_TOPIC = "fx_cmd_t";
@@ -322,6 +323,7 @@ constexpr const char *const MQTT_DEVICE_MODEL = "model";
322
323
  constexpr const char *const MQTT_DEVICE_NAME = "name";
323
324
  constexpr const char *const MQTT_DEVICE_SUGGESTED_AREA = "suggested_area";
324
325
  constexpr const char *const MQTT_DEVICE_SW_VERSION = "sw_version";
326
+ constexpr const char *const MQTT_DEVICE_HW_VERSION = "hw_version";
325
327
  constexpr const char *const MQTT_DOCKED_TEMPLATE = "docked_template";
326
328
  constexpr const char *const MQTT_DOCKED_TOPIC = "docked_topic";
327
329
  constexpr const char *const MQTT_EFFECT_COMMAND_TOPIC = "effect_command_topic";