esphome 2025.6.2__py3-none-any.whl → 2025.7.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 (648) hide show
  1. esphome/__main__.py +1 -3
  2. esphome/codegen.py +2 -0
  3. esphome/components/ac_dimmer/ac_dimmer.cpp +6 -6
  4. esphome/components/adc/__init__.py +25 -1
  5. esphome/components/adc/adc_sensor.h +11 -11
  6. esphome/components/adc/adc_sensor_common.cpp +1 -1
  7. esphome/components/adc/adc_sensor_esp32.cpp +16 -8
  8. esphome/components/ade7880/ade7880.h +0 -2
  9. esphome/components/ads1115/ads1115.h +0 -1
  10. esphome/components/ads1118/ads1118.h +0 -1
  11. esphome/components/ags10/ags10.h +0 -2
  12. esphome/components/aic3204/aic3204.h +0 -1
  13. esphome/components/alarm_control_panel/__init__.py +5 -2
  14. esphome/components/alpha3/alpha3.h +0 -1
  15. esphome/components/am43/cover/am43_cover.h +0 -1
  16. esphome/components/am43/sensor/am43_sensor.h +0 -1
  17. esphome/components/analog_threshold/analog_threshold_binary_sensor.h +0 -2
  18. esphome/components/anova/anova.cpp +5 -1
  19. esphome/components/anova/anova.h +0 -1
  20. esphome/components/apds9960/apds9960.cpp +1 -1
  21. esphome/components/api/__init__.py +57 -21
  22. esphome/components/api/api_connection.cpp +344 -539
  23. esphome/components/api/api_connection.h +224 -141
  24. esphome/components/api/api_frame_helper.cpp +91 -127
  25. esphome/components/api/api_frame_helper.h +64 -54
  26. esphome/components/api/api_pb2.cpp +1837 -9044
  27. esphome/components/api/api_pb2.h +532 -685
  28. esphome/components/api/api_pb2_dump.cpp +4432 -0
  29. esphome/components/api/api_pb2_service.cpp +184 -425
  30. esphome/components/api/api_pb2_service.h +13 -6
  31. esphome/components/api/api_server.cpp +131 -167
  32. esphome/components/api/api_server.h +38 -10
  33. esphome/components/api/client.py +10 -4
  34. esphome/components/api/custom_api_device.h +8 -0
  35. esphome/components/api/list_entities.cpp +37 -104
  36. esphome/components/api/list_entities.h +33 -23
  37. esphome/components/api/proto.h +532 -26
  38. esphome/components/api/subscribe_state.cpp +23 -29
  39. esphome/components/api/subscribe_state.h +26 -19
  40. esphome/components/api/user_services.h +2 -0
  41. esphome/components/as3935_spi/as3935_spi.h +0 -2
  42. esphome/components/as5600/as5600.h +0 -1
  43. esphome/components/async_tcp/__init__.py +14 -5
  44. esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
  45. esphome/components/atm90e32/atm90e32.cpp +2 -1
  46. esphome/components/audio/audio_decoder.cpp +1 -1
  47. esphome/components/audio/audio_transfer_buffer.cpp +2 -2
  48. esphome/components/b_parasite/b_parasite.h +0 -1
  49. esphome/components/bedjet/bedjet_hub.cpp +5 -1
  50. esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
  51. esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
  52. esphome/components/bh1750/bh1750.cpp +5 -5
  53. esphome/components/binary_sensor/__init__.py +82 -5
  54. esphome/components/binary_sensor/automation.h +19 -1
  55. esphome/components/binary_sensor/binary_sensor.cpp +12 -30
  56. esphome/components/binary_sensor/binary_sensor.h +11 -25
  57. esphome/components/binary_sensor/filter.cpp +29 -24
  58. esphome/components/binary_sensor/filter.h +20 -10
  59. esphome/components/ble_client/output/ble_binary_output.h +0 -1
  60. esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
  61. esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
  62. esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
  63. esphome/components/ble_client/sensor/ble_sensor.h +0 -1
  64. esphome/components/ble_client/switch/ble_switch.h +0 -1
  65. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
  66. esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
  67. esphome/components/ble_presence/ble_presence_device.h +0 -1
  68. esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
  69. esphome/components/ble_scanner/ble_scanner.h +0 -1
  70. esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
  71. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
  72. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
  73. esphome/components/bme680/sensor.py +1 -1
  74. esphome/components/bmp581/bmp581.h +0 -2
  75. esphome/components/button/__init__.py +5 -2
  76. esphome/components/camera/__init__.py +1 -0
  77. esphome/components/camera/camera.cpp +22 -0
  78. esphome/components/camera/camera.h +80 -0
  79. esphome/components/canbus/__init__.py +1 -0
  80. esphome/components/cap1188/cap1188.h +0 -1
  81. esphome/components/captive_portal/__init__.py +12 -2
  82. esphome/components/captive_portal/captive_portal.cpp +12 -2
  83. esphome/components/captive_portal/captive_portal.h +5 -2
  84. esphome/components/ccs811/ccs811.h +0 -2
  85. esphome/components/climate/__init__.py +5 -2
  86. esphome/components/cm1106/sensor.py +2 -2
  87. esphome/components/const/__init__.py +2 -0
  88. esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
  89. esphome/components/copy/button/copy_button.h +0 -1
  90. esphome/components/copy/cover/copy_cover.h +0 -1
  91. esphome/components/copy/fan/copy_fan.h +0 -1
  92. esphome/components/copy/lock/copy_lock.h +0 -1
  93. esphome/components/copy/number/copy_number.h +0 -1
  94. esphome/components/copy/select/copy_select.h +0 -1
  95. esphome/components/copy/sensor/copy_sensor.h +0 -1
  96. esphome/components/copy/switch/copy_switch.h +0 -1
  97. esphome/components/copy/text/copy_text.h +0 -1
  98. esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
  99. esphome/components/cover/__init__.py +5 -2
  100. esphome/components/cs5460a/cs5460a.h +0 -1
  101. esphome/components/datetime/__init__.py +4 -2
  102. esphome/components/debug/__init__.py +20 -0
  103. esphome/components/debug/debug_esp32.cpp +2 -0
  104. esphome/components/deep_sleep/__init__.py +43 -9
  105. esphome/components/demo/__init__.py +2 -2
  106. esphome/components/display/display.cpp +4 -3
  107. esphome/components/display/display.h +0 -2
  108. esphome/components/display/display_buffer.cpp +1 -1
  109. esphome/components/ds2484/__init__.py +1 -0
  110. esphome/components/ds2484/ds2484.cpp +209 -0
  111. esphome/components/ds2484/ds2484.h +43 -0
  112. esphome/components/ds2484/one_wire.py +37 -0
  113. esphome/components/duty_time/duty_time_sensor.h +0 -1
  114. esphome/components/ens160_base/ens160_base.h +0 -1
  115. esphome/components/es7210/es7210.h +0 -1
  116. esphome/components/es7243e/es7243e.h +0 -1
  117. esphome/components/es8156/es8156.h +0 -1
  118. esphome/components/es8311/es8311.h +0 -1
  119. esphome/components/es8388/es8388.h +0 -1
  120. esphome/components/esp32/__init__.py +103 -135
  121. esphome/components/esp32/core.cpp +0 -4
  122. esphome/components/esp32/gpio.h +1 -1
  123. esphome/components/esp32/helpers.cpp +69 -0
  124. esphome/components/esp32_ble/ble.cpp +5 -6
  125. esphome/components/esp32_ble/ble.h +29 -14
  126. esphome/components/esp32_ble/ble_event.h +6 -6
  127. esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
  128. esphome/components/esp32_ble_client/ble_client_base.h +24 -9
  129. esphome/components/esp32_ble_tracker/__init__.py +2 -8
  130. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
  131. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
  132. esphome/components/esp32_camera/__init__.py +112 -98
  133. esphome/components/esp32_camera/esp32_camera.cpp +41 -31
  134. esphome/components/esp32_camera/esp32_camera.h +35 -30
  135. esphome/components/esp32_camera_web_server/__init__.py +2 -1
  136. esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
  137. esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
  138. esphome/components/esp32_hall/sensor.py +2 -21
  139. esphome/components/esp32_hosted/__init__.py +101 -0
  140. esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
  141. esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
  142. esphome/components/esp32_rmt/__init__.py +0 -58
  143. esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
  144. esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
  145. esphome/components/esp32_rmt_led_strip/light.py +14 -76
  146. esphome/components/esp32_touch/esp32_touch.h +174 -28
  147. esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
  148. esphome/components/esp32_touch/esp32_touch_v1.cpp +240 -0
  149. esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
  150. esphome/components/esp8266/__init__.py +2 -0
  151. esphome/components/esp8266/gpio.cpp +10 -10
  152. esphome/components/esp8266/helpers.cpp +31 -0
  153. esphome/components/esp_ldo/__init__.py +10 -8
  154. esphome/components/esp_ldo/esp_ldo.h +3 -0
  155. esphome/components/esphome/ota/__init__.py +1 -0
  156. esphome/components/esphome/ota/ota_esphome.cpp +24 -19
  157. esphome/components/ethernet/__init__.py +42 -23
  158. esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
  159. esphome/components/ethernet/ethernet_component.cpp +69 -29
  160. esphome/components/ethernet/ethernet_component.h +18 -10
  161. esphome/components/event/__init__.py +5 -2
  162. esphome/components/ezo/ezo.h +0 -1
  163. esphome/components/ezo_pmp/ezo_pmp.h +0 -1
  164. esphome/components/fan/__init__.py +5 -2
  165. esphome/components/fan/fan.cpp +4 -0
  166. esphome/components/feedback/feedback_cover.h +0 -1
  167. esphome/components/font/__init__.py +92 -82
  168. esphome/components/font/font.cpp +9 -2
  169. esphome/components/font/font.h +20 -5
  170. esphome/components/fs3000/fs3000.h +0 -1
  171. esphome/components/gcja5/gcja5.h +0 -1
  172. esphome/components/gl_r01_i2c/__init__.py +0 -0
  173. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
  174. esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
  175. esphome/components/gl_r01_i2c/sensor.py +36 -0
  176. esphome/components/gp8403/gp8403.h +0 -1
  177. esphome/components/gpio/binary_sensor/__init__.py +39 -1
  178. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
  179. esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
  180. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
  181. esphome/components/he60r/he60r.h +0 -1
  182. esphome/components/heatpumpir/climate.py +2 -1
  183. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  184. esphome/components/heatpumpir/heatpumpir.h +1 -0
  185. esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
  186. esphome/components/host/__init__.py +3 -1
  187. esphome/components/host/helpers.cpp +57 -0
  188. esphome/components/http_request/__init__.py +19 -1
  189. esphome/components/http_request/http_request.h +1 -1
  190. esphome/components/http_request/http_request_arduino.cpp +0 -1
  191. esphome/components/http_request/http_request_arduino.h +1 -0
  192. esphome/components/http_request/http_request_idf.cpp +0 -1
  193. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  194. esphome/components/http_request/update/http_request_update.cpp +35 -16
  195. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +3 -9
  196. esphome/components/hydreon_rgxx/sensor.py +1 -1
  197. esphome/components/i2c/__init__.py +23 -11
  198. esphome/components/i2c/i2c_bus.h +8 -1
  199. esphome/components/i2c/i2c_bus_arduino.cpp +4 -3
  200. esphome/components/i2c/i2c_bus_arduino.h +6 -3
  201. esphome/components/i2c/i2c_bus_esp_idf.h +5 -3
  202. esphome/components/i2c_device/i2c_device.h +0 -1
  203. esphome/components/i2s_audio/__init__.py +2 -10
  204. esphome/components/i2s_audio/i2s_audio.cpp +1 -5
  205. esphome/components/i2s_audio/media_player/__init__.py +2 -2
  206. esphome/components/i2s_audio/speaker/__init__.py +1 -1
  207. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +2 -2
  208. esphome/components/iaqcore/iaqcore.h +0 -2
  209. esphome/components/image/__init__.py +123 -24
  210. esphome/components/improv_serial/improv_serial_component.cpp +0 -4
  211. esphome/components/ina219/ina219.cpp +7 -0
  212. esphome/components/ina219/ina219.h +1 -0
  213. esphome/components/ina260/ina260.h +0 -2
  214. esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h +0 -1
  215. esphome/components/inkplate6/display.py +15 -0
  216. esphome/components/inkplate6/inkplate.cpp +2 -2
  217. esphome/components/integration/integration_sensor.h +0 -1
  218. esphome/components/internal_temperature/internal_temperature.cpp +8 -27
  219. esphome/components/internal_temperature/sensor.py +0 -26
  220. esphome/components/interval/interval.h +0 -2
  221. esphome/components/json/__init__.py +1 -1
  222. esphome/components/json/json_util.cpp +56 -63
  223. esphome/components/ld2410/button/__init__.py +3 -3
  224. esphome/components/ld2410/button/factory_reset_button.cpp +9 -0
  225. esphome/components/ld2410/button/{reset_button.h → factory_reset_button.h} +2 -2
  226. esphome/components/ld2410/ld2410.cpp +421 -268
  227. esphome/components/ld2410/ld2410.h +44 -146
  228. esphome/components/ld2410/number/__init__.py +2 -2
  229. esphome/components/ld2410/sensor.py +1 -1
  230. esphome/components/ld2410/switch/__init__.py +1 -1
  231. esphome/components/ld2420/binary_sensor/ld2420_binary_sensor.cpp +2 -2
  232. esphome/components/ld2420/button/reconfig_buttons.cpp +1 -1
  233. esphome/components/ld2420/ld2420.cpp +252 -147
  234. esphome/components/ld2420/ld2420.h +52 -126
  235. esphome/components/ld2420/number/__init__.py +2 -2
  236. esphome/components/ld2420/number/gate_config_number.cpp +1 -1
  237. esphome/components/ld2420/select/operating_mode_select.cpp +1 -1
  238. esphome/components/ld2420/sensor/__init__.py +6 -2
  239. esphome/components/ld2420/sensor/ld2420_sensor.cpp +2 -2
  240. esphome/components/ld2420/sensor/ld2420_sensor.h +1 -1
  241. esphome/components/ld2420/text_sensor/text_sensor.cpp +2 -2
  242. esphome/components/ld2450/button/__init__.py +3 -3
  243. esphome/components/ld2450/button/factory_reset_button.cpp +9 -0
  244. esphome/components/ld2450/button/{reset_button.h → factory_reset_button.h} +2 -2
  245. esphome/components/ld2450/ld2450.cpp +384 -232
  246. esphome/components/ld2450/ld2450.h +60 -69
  247. esphome/components/ld2450/switch/__init__.py +1 -1
  248. esphome/components/ledc/ledc_output.cpp +1 -63
  249. esphome/components/libretiny/__init__.py +5 -3
  250. esphome/components/libretiny/const.py +5 -0
  251. esphome/components/libretiny/generate_components.py +1 -0
  252. esphome/components/libretiny/helpers.cpp +35 -0
  253. esphome/components/libretiny/lt_component.cpp +5 -3
  254. esphome/components/light/__init__.py +4 -2
  255. esphome/components/light/addressable_light.h +3 -3
  256. esphome/components/light/light_call.cpp +180 -243
  257. esphome/components/light/light_call.h +72 -20
  258. esphome/components/light/light_color_values.h +14 -14
  259. esphome/components/light/light_json_schema.cpp +17 -16
  260. esphome/components/light/light_state.h +15 -13
  261. esphome/components/light/transformers.h +2 -2
  262. esphome/components/ln882x/__init__.py +52 -0
  263. esphome/components/ln882x/boards.py +285 -0
  264. esphome/components/lock/__init__.py +5 -2
  265. esphome/components/logger/__init__.py +40 -3
  266. esphome/components/logger/logger.cpp +47 -12
  267. esphome/components/logger/logger.h +80 -49
  268. esphome/components/logger/logger_esp32.cpp +3 -3
  269. esphome/components/lps22/__init__.py +0 -0
  270. esphome/components/lps22/lps22.cpp +75 -0
  271. esphome/components/lps22/lps22.h +27 -0
  272. esphome/components/lps22/sensor.py +58 -0
  273. esphome/components/ltr390/ltr390.h +0 -1
  274. esphome/components/ltr501/ltr501.h +0 -1
  275. esphome/components/ltr_als_ps/ltr_als_ps.h +0 -1
  276. esphome/components/lvgl/__init__.py +1 -1
  277. esphome/components/lvgl/schemas.py +66 -6
  278. esphome/components/lvgl/styles.py +24 -16
  279. esphome/components/lvgl/widgets/__init__.py +12 -2
  280. esphome/components/lvgl/widgets/lv_bar.py +40 -19
  281. esphome/components/lvgl/widgets/meter.py +20 -13
  282. esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +1 -1
  283. esphome/components/max9611/max9611.h +0 -1
  284. esphome/components/mcp23016/__init__.py +1 -1
  285. esphome/components/mcp23xxx_base/__init__.py +1 -1
  286. esphome/components/mcp4461/__init__.py +1 -1
  287. esphome/components/mcp4461/output/__init__.py +3 -2
  288. esphome/components/mcp9600/mcp9600.h +0 -2
  289. esphome/components/md5/md5.cpp +3 -3
  290. esphome/components/md5/md5.h +1 -6
  291. esphome/components/mdns/__init__.py +22 -11
  292. esphome/components/media_player/__init__.py +4 -3
  293. esphome/components/micro_wake_word/__init__.py +1 -5
  294. esphome/components/micro_wake_word/streaming_model.cpp +2 -2
  295. esphome/components/microphone/microphone.cpp +7 -9
  296. esphome/components/microphone/microphone.h +0 -2
  297. esphome/components/mipi_spi/display.py +1 -0
  298. esphome/components/mmc5603/mmc5603.cpp +1 -1
  299. esphome/components/modbus/modbus.cpp +33 -15
  300. esphome/components/modbus/modbus.h +9 -0
  301. esphome/components/modbus_controller/__init__.py +42 -10
  302. esphome/components/modbus_controller/modbus_controller.cpp +92 -11
  303. esphome/components/modbus_controller/modbus_controller.h +61 -7
  304. esphome/components/mopeka_pro_check/mopeka_pro_check.h +0 -1
  305. esphome/components/mopeka_std_check/mopeka_std_check.h +0 -1
  306. esphome/components/mpl3115a2/mpl3115a2.h +0 -2
  307. esphome/components/mqtt/__init__.py +16 -0
  308. esphome/components/mqtt/mqtt_alarm_control_panel.cpp +2 -1
  309. esphome/components/mqtt/mqtt_backend.h +2 -1
  310. esphome/components/mqtt/mqtt_backend_esp32.cpp +132 -47
  311. esphome/components/mqtt/mqtt_backend_esp32.h +106 -4
  312. esphome/components/mqtt/mqtt_binary_sensor.cpp +1 -0
  313. esphome/components/mqtt/mqtt_button.cpp +4 -1
  314. esphome/components/mqtt/mqtt_client.cpp +17 -9
  315. esphome/components/mqtt/mqtt_client.h +8 -3
  316. esphome/components/mqtt/mqtt_climate.cpp +6 -4
  317. esphome/components/mqtt/mqtt_component.cpp +3 -1
  318. esphome/components/mqtt/mqtt_cover.cpp +1 -0
  319. esphome/components/mqtt/mqtt_date.cpp +4 -3
  320. esphome/components/mqtt/mqtt_datetime.cpp +7 -6
  321. esphome/components/mqtt/mqtt_event.cpp +6 -3
  322. esphome/components/mqtt/mqtt_fan.cpp +1 -0
  323. esphome/components/mqtt/mqtt_light.cpp +8 -4
  324. esphome/components/mqtt/mqtt_lock.cpp +3 -1
  325. esphome/components/mqtt/mqtt_number.cpp +1 -0
  326. esphome/components/mqtt/mqtt_select.cpp +2 -1
  327. esphome/components/mqtt/mqtt_sensor.cpp +3 -1
  328. esphome/components/mqtt/mqtt_switch.cpp +3 -1
  329. esphome/components/mqtt/mqtt_text.cpp +1 -0
  330. esphome/components/mqtt/mqtt_text_sensor.cpp +3 -1
  331. esphome/components/mqtt/mqtt_time.cpp +4 -3
  332. esphome/components/mqtt/mqtt_update.cpp +1 -0
  333. esphome/components/mqtt/mqtt_valve.cpp +3 -1
  334. esphome/components/ms8607/ms8607.cpp +1 -1
  335. esphome/components/ms8607/ms8607.h +0 -1
  336. esphome/components/neopixelbus/light.py +4 -1
  337. esphome/components/neopixelbus/neopixelbus_light.h +1 -1
  338. esphome/components/network/__init__.py +4 -1
  339. esphome/components/network/ip_address.h +1 -0
  340. esphome/components/nextion/__init__.py +16 -0
  341. esphome/components/nextion/base_component.py +1 -0
  342. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
  343. esphome/components/nextion/display.py +14 -4
  344. esphome/components/nextion/nextion.cpp +166 -101
  345. esphome/components/nextion/nextion.h +84 -53
  346. esphome/components/nextion/nextion_commands.cpp +11 -10
  347. esphome/components/nextion/nextion_component.cpp +28 -28
  348. esphome/components/nextion/nextion_component.h +53 -18
  349. esphome/components/nextion/nextion_component_base.h +3 -0
  350. esphome/components/nextion/nextion_upload.cpp +36 -0
  351. esphome/components/nextion/nextion_upload_arduino.cpp +10 -35
  352. esphome/components/nextion/nextion_upload_idf.cpp +9 -33
  353. esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
  354. esphome/components/nextion/switch/nextion_switch.cpp +1 -1
  355. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
  356. esphome/components/nfc/nfc.cpp +3 -22
  357. esphome/components/nfc/nfc.h +3 -3
  358. esphome/components/number/__init__.py +5 -2
  359. esphome/components/online_image/__init__.py +9 -1
  360. esphome/components/online_image/online_image.cpp +17 -7
  361. esphome/components/online_image/online_image.h +10 -2
  362. esphome/components/opentherm/opentherm.cpp +7 -12
  363. esphome/components/opentherm/output/output.cpp +1 -1
  364. esphome/components/openthread/__init__.py +47 -40
  365. esphome/components/openthread/const.py +1 -0
  366. esphome/components/openthread/openthread_esp.cpp +27 -5
  367. esphome/components/opt3001/__init__.py +0 -0
  368. esphome/components/opt3001/opt3001.cpp +122 -0
  369. esphome/components/opt3001/opt3001.h +27 -0
  370. esphome/components/opt3001/sensor.py +35 -0
  371. esphome/components/ota/__init__.py +17 -0
  372. esphome/components/ota/ota_backend.h +27 -1
  373. esphome/components/ota/ota_backend_arduino_esp32.cpp +12 -2
  374. esphome/components/ota/ota_backend_arduino_esp32.h +3 -0
  375. esphome/components/ota/ota_backend_arduino_esp8266.cpp +18 -4
  376. esphome/components/ota/ota_backend_arduino_esp8266.h +3 -0
  377. esphome/components/ota/ota_backend_arduino_libretiny.cpp +12 -2
  378. esphome/components/ota/ota_backend_arduino_libretiny.h +3 -0
  379. esphome/components/ota/ota_backend_arduino_rp2040.cpp +9 -2
  380. esphome/components/ota/ota_backend_arduino_rp2040.h +3 -0
  381. esphome/components/ota/ota_backend_esp_idf.cpp +10 -16
  382. esphome/components/ota/ota_backend_esp_idf.h +1 -0
  383. esphome/components/packages/__init__.py +5 -2
  384. esphome/components/packet_transport/binary_sensor.py +61 -4
  385. esphome/components/packet_transport/packet_transport.cpp +34 -1
  386. esphome/components/packet_transport/packet_transport.h +11 -5
  387. esphome/components/pcf8574/__init__.py +1 -1
  388. esphome/components/pi4ioe5v6408/__init__.py +84 -0
  389. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +171 -0
  390. esphome/components/pi4ioe5v6408/pi4ioe5v6408.h +70 -0
  391. esphome/components/pmsa003i/pmsa003i.h +0 -1
  392. esphome/components/pmsx003/pmsx003.h +0 -1
  393. esphome/components/pn7150/pn7150.cpp +7 -7
  394. esphome/components/pn7150/pn7150.h +0 -1
  395. esphome/components/pn7160/pn7160.cpp +7 -7
  396. esphome/components/pn7160/pn7160.h +0 -1
  397. esphome/components/preferences/syncer.h +2 -0
  398. esphome/components/prometheus/prometheus_handler.h +1 -1
  399. esphome/components/psram/psram.cpp +0 -20
  400. esphome/components/pulse_counter/pulse_counter_sensor.h +0 -1
  401. esphome/components/pulse_meter/pulse_meter_sensor.cpp +8 -4
  402. esphome/components/pulse_width/pulse_width.h +0 -1
  403. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +0 -4
  404. esphome/components/pvvx_mithermometer/display/pvvx_display.h +0 -2
  405. esphome/components/pvvx_mithermometer/pvvx_mithermometer.h +0 -1
  406. esphome/components/qr_code/__init__.py +13 -10
  407. esphome/components/qwiic_pir/qwiic_pir.h +0 -1
  408. esphome/components/radon_eye_ble/radon_eye_listener.cpp +1 -1
  409. esphome/components/rc522/rc522.h +0 -1
  410. esphome/components/rdm6300/rdm6300.h +0 -2
  411. esphome/components/remote_base/__init__.py +7 -5
  412. esphome/components/remote_base/remote_base.cpp +24 -21
  413. esphome/components/remote_base/remote_base.h +3 -26
  414. esphome/components/remote_receiver/__init__.py +40 -46
  415. esphome/components/remote_receiver/remote_receiver.h +4 -18
  416. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -87
  417. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +1 -1
  418. esphome/components/remote_transmitter/__init__.py +42 -43
  419. esphome/components/remote_transmitter/remote_transmitter.h +2 -14
  420. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -77
  421. esphome/components/resistance/resistance_sensor.h +0 -1
  422. esphome/components/rp2040/__init__.py +2 -0
  423. esphome/components/rp2040/helpers.cpp +55 -0
  424. esphome/components/rp2040_pio_led_strip/led_strip.cpp +2 -2
  425. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -4
  426. esphome/components/rtttl/__init__.py +4 -4
  427. esphome/components/rtttl/rtttl.cpp +10 -1
  428. esphome/components/ruuvitag/ruuvitag.h +0 -1
  429. esphome/components/safe_mode/safe_mode.cpp +2 -0
  430. esphome/components/safe_mode/safe_mode.h +4 -1
  431. esphome/components/scd30/scd30.h +0 -1
  432. esphome/components/scd30/sensor.py +2 -2
  433. esphome/components/scd4x/scd4x.cpp +61 -54
  434. esphome/components/scd4x/scd4x.h +17 -15
  435. esphome/components/scd4x/sensor.py +4 -4
  436. esphome/components/script/script.h +0 -2
  437. esphome/components/sdp3x/sensor.py +1 -1
  438. esphome/components/select/__init__.py +5 -2
  439. esphome/components/sen5x/sen5x.h +0 -1
  440. esphome/components/senseair/senseair.h +0 -1
  441. esphome/components/sensor/__init__.py +4 -2
  442. esphome/components/sensor/filter.cpp +1 -1
  443. esphome/components/sensor/sensor.cpp +12 -6
  444. esphome/components/sensor/sensor.h +13 -5
  445. esphome/components/servo/servo.cpp +2 -2
  446. esphome/components/servo/servo.h +0 -1
  447. esphome/components/sfa30/sfa30.h +0 -1
  448. esphome/components/sgp30/sgp30.h +0 -1
  449. esphome/components/sgp4x/sgp4x.h +0 -1
  450. esphome/components/shelly_dimmer/stm32flash.cpp +1 -2
  451. esphome/components/sht4x/sht4x.h +0 -1
  452. esphome/components/sm300d2/sm300d2.h +0 -2
  453. esphome/components/smt100/sensor.py +8 -4
  454. esphome/components/smt100/smt100.cpp +5 -5
  455. esphome/components/smt100/smt100.h +3 -3
  456. esphome/components/sn74hc595/__init__.py +1 -1
  457. esphome/components/sn74hc595/sn74hc595.cpp +5 -4
  458. esphome/components/sntp/sntp_component.cpp +9 -3
  459. esphome/components/sntp/time.py +2 -0
  460. esphome/components/socket/__init__.py +17 -0
  461. esphome/components/spi/__init__.py +27 -6
  462. esphome/components/spi/spi.cpp +3 -2
  463. esphome/components/spi/spi.h +9 -3
  464. esphome/components/spi/spi_arduino.cpp +3 -5
  465. esphome/components/spi/spi_esp_idf.cpp +40 -21
  466. esphome/components/spi_led_strip/spi_led_strip.cpp +1 -1
  467. esphome/components/sps30/sps30.h +0 -1
  468. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  469. esphome/components/st7701s/st7701s.cpp +0 -4
  470. esphome/components/status/status_binary_sensor.h +0 -2
  471. esphome/components/substitutions/__init__.py +81 -21
  472. esphome/components/substitutions/jinja.py +99 -0
  473. esphome/components/sun/sun.cpp +3 -4
  474. esphome/components/switch/__init__.py +5 -2
  475. esphome/components/switch/binary_sensor/switch_binary_sensor.h +0 -1
  476. esphome/components/sx126x/__init__.py +317 -0
  477. esphome/components/sx126x/automation.h +62 -0
  478. esphome/components/sx126x/packet_transport/__init__.py +26 -0
  479. esphome/components/sx126x/packet_transport/sx126x_transport.cpp +26 -0
  480. esphome/components/sx126x/packet_transport/sx126x_transport.h +25 -0
  481. esphome/components/sx126x/sx126x.cpp +523 -0
  482. esphome/components/sx126x/sx126x.h +140 -0
  483. esphome/components/sx126x/sx126x_reg.h +163 -0
  484. esphome/components/sx127x/__init__.py +325 -0
  485. esphome/components/sx127x/automation.h +62 -0
  486. esphome/components/sx127x/packet_transport/__init__.py +26 -0
  487. esphome/components/sx127x/packet_transport/sx127x_transport.cpp +26 -0
  488. esphome/components/sx127x/packet_transport/sx127x_transport.h +25 -0
  489. esphome/components/sx127x/sx127x.cpp +498 -0
  490. esphome/components/sx127x/sx127x.h +128 -0
  491. esphome/components/sx127x/sx127x_reg.h +295 -0
  492. esphome/components/syslog/esphome_syslog.cpp +5 -3
  493. esphome/components/syslog/esphome_syslog.h +1 -1
  494. esphome/components/tca9555/__init__.py +1 -1
  495. esphome/components/template/binary_sensor/template_binary_sensor.cpp +1 -9
  496. esphome/components/text/__init__.py +5 -2
  497. esphome/components/text_sensor/__init__.py +5 -2
  498. esphome/components/thermostat/thermostat_climate.cpp +34 -31
  499. esphome/components/thermostat/thermostat_climate.h +43 -39
  500. esphome/components/time/__init__.py +16 -2
  501. esphome/components/time/real_time_clock.cpp +4 -0
  502. esphome/components/time/real_time_clock.h +5 -1
  503. esphome/components/tlc5971/tlc5971.cpp +4 -1
  504. esphome/components/tmp1075/tmp1075.h +0 -2
  505. esphome/components/tof10120/tof10120_sensor.h +0 -1
  506. esphome/components/tormatic/tormatic_cover.h +0 -1
  507. esphome/components/total_daily_energy/total_daily_energy.h +0 -1
  508. esphome/components/tsl2591/tsl2591.cpp +1 -1
  509. esphome/components/ttp229_bsf/ttp229_bsf.h +0 -1
  510. esphome/components/ttp229_lsf/ttp229_lsf.h +0 -1
  511. esphome/components/tx20/tx20.cpp +2 -2
  512. esphome/components/uart/__init__.py +18 -0
  513. esphome/components/uart/uart_component_esp_idf.cpp +1 -5
  514. esphome/components/update/__init__.py +5 -2
  515. esphome/components/update/update_entity.h +8 -0
  516. esphome/components/usb_host/__init__.py +5 -2
  517. esphome/components/usb_host/usb_host_client.cpp +10 -10
  518. esphome/components/usb_uart/cp210x.cpp +1 -1
  519. esphome/components/usb_uart/usb_uart.cpp +41 -44
  520. esphome/components/usb_uart/usb_uart.h +4 -3
  521. esphome/components/valve/__init__.py +5 -2
  522. esphome/components/vbus/vbus.h +0 -1
  523. esphome/components/veml3235/veml3235.h +0 -1
  524. esphome/components/veml7700/veml7700.h +0 -1
  525. esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
  526. esphome/components/voice_assistant/voice_assistant.cpp +4 -4
  527. esphome/components/watchdog/watchdog.cpp +0 -4
  528. esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
  529. esphome/components/web_server/__init__.py +34 -19
  530. esphome/components/web_server/ota/__init__.py +32 -0
  531. esphome/components/web_server/ota/ota_web_server.cpp +210 -0
  532. esphome/components/web_server/ota/ota_web_server.h +26 -0
  533. esphome/components/web_server/web_server.cpp +324 -439
  534. esphome/components/web_server/web_server.h +33 -23
  535. esphome/components/web_server/web_server_v1.cpp +4 -5
  536. esphome/components/web_server_base/__init__.py +5 -2
  537. esphome/components/web_server_base/web_server_base.cpp +2 -94
  538. esphome/components/web_server_base/web_server_base.h +5 -25
  539. esphome/components/web_server_idf/multipart.cpp +254 -0
  540. esphome/components/web_server_idf/multipart.h +86 -0
  541. esphome/components/web_server_idf/utils.cpp +32 -0
  542. esphome/components/web_server_idf/utils.h +10 -0
  543. esphome/components/web_server_idf/web_server_idf.cpp +164 -16
  544. esphome/components/web_server_idf/web_server_idf.h +11 -10
  545. esphome/components/wiegand/wiegand.cpp +2 -2
  546. esphome/components/wifi/__init__.py +18 -0
  547. esphome/components/wifi/wifi_component.cpp +17 -22
  548. esphome/components/wifi/wifi_component.h +27 -23
  549. esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
  550. esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
  551. esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
  552. esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
  553. esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
  554. esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
  555. esphome/components/wireguard/__init__.py +2 -11
  556. esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
  557. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  558. esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
  559. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
  560. esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
  561. esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
  562. esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
  563. esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
  564. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
  565. esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
  566. esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
  567. esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
  568. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
  569. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
  570. esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
  571. esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
  572. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
  573. esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
  574. esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
  575. esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
  576. esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
  577. esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
  578. esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
  579. esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
  580. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
  581. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
  582. esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
  583. esphome/components/zyaura/zyaura.h +0 -1
  584. esphome/config.py +88 -22
  585. esphome/config_helpers.py +74 -1
  586. esphome/config_validation.py +12 -1
  587. esphome/const.py +65 -10
  588. esphome/core/__init__.py +18 -2
  589. esphome/core/application.cpp +169 -10
  590. esphome/core/application.h +145 -165
  591. esphome/core/area.h +19 -0
  592. esphome/core/automation.h +58 -9
  593. esphome/core/color.cpp +3 -5
  594. esphome/core/color.h +16 -16
  595. esphome/core/component.cpp +156 -22
  596. esphome/core/component.h +98 -4
  597. esphome/core/component_iterator.cpp +11 -9
  598. esphome/core/component_iterator.h +12 -10
  599. esphome/core/config.py +155 -6
  600. esphome/core/controller.cpp +4 -2
  601. esphome/core/controller.h +1 -1
  602. esphome/core/datatypes.h +2 -2
  603. esphome/core/defines.h +17 -2
  604. esphome/core/device.h +20 -0
  605. esphome/core/entity_base.cpp +20 -15
  606. esphome/core/entity_base.h +76 -0
  607. esphome/core/entity_helpers.py +168 -1
  608. esphome/core/event_pool.h +81 -0
  609. esphome/core/helpers.cpp +75 -230
  610. esphome/core/helpers.h +165 -105
  611. esphome/core/lock_free_queue.h +151 -0
  612. esphome/core/log.cpp +2 -2
  613. esphome/core/log.h +2 -0
  614. esphome/core/optional.h +5 -0
  615. esphome/core/ring_buffer.cpp +2 -2
  616. esphome/core/scheduler.cpp +275 -103
  617. esphome/core/scheduler.h +154 -17
  618. esphome/core/time.cpp +5 -5
  619. esphome/core/time.h +5 -5
  620. esphome/cpp_generator.py +17 -0
  621. esphome/cpp_helpers.py +0 -22
  622. esphome/cpp_types.py +3 -1
  623. esphome/dashboard/entries.py +1 -1
  624. esphome/dashboard/util/text.py +5 -21
  625. esphome/dashboard/web_server.py +9 -1
  626. esphome/helpers.py +47 -0
  627. esphome/loader.py +15 -1
  628. esphome/pins.py +14 -8
  629. esphome/platformio_api.py +2 -0
  630. esphome/wizard.py +17 -4
  631. esphome/writer.py +44 -3
  632. esphome/yaml_util.py +0 -2
  633. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/METADATA +10 -9
  634. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/RECORD +639 -580
  635. esphome/components/api/api_pb2_size.h +0 -361
  636. esphome/components/esp32_ble/ble_event_pool.h +0 -72
  637. esphome/components/esp32_ble/queue.h +0 -85
  638. esphome/components/esp32_hall/esp32_hall.cpp +0 -25
  639. esphome/components/esp32_hall/esp32_hall.h +0 -23
  640. esphome/components/esp32_touch/esp32_touch.cpp +0 -355
  641. esphome/components/ld2410/button/reset_button.cpp +0 -9
  642. esphome/components/ld2450/button/reset_button.cpp +0 -9
  643. esphome/components/openthread/tlv.py +0 -65
  644. /esphome/{dashboard/enum.py → enum.py} +0 -0
  645. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/WHEEL +0 -0
  646. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/entry_points.txt +0 -0
  647. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/licenses/LICENSE +0 -0
  648. {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,122 @@
1
+ #include "opt3001.h"
2
+ #include "esphome/core/log.h"
3
+
4
+ namespace esphome {
5
+ namespace opt3001 {
6
+
7
+ static const char *const TAG = "opt3001.sensor";
8
+
9
+ static const uint8_t OPT3001_REG_RESULT = 0x00;
10
+ static const uint8_t OPT3001_REG_CONFIGURATION = 0x01;
11
+ // See datasheet for full description of each bit.
12
+ static const uint16_t OPT3001_CONFIGURATION_RANGE_FULL = 0b1100000000000000;
13
+ static const uint16_t OPT3001_CONFIGURATION_CONVERSION_TIME_800 = 0b100000000000;
14
+ static const uint16_t OPT3001_CONFIGURATION_CONVERSION_MODE_MASK = 0b11000000000;
15
+ static const uint16_t OPT3001_CONFIGURATION_CONVERSION_MODE_SINGLE_SHOT = 0b01000000000;
16
+ static const uint16_t OPT3001_CONFIGURATION_CONVERSION_MODE_SHUTDOWN = 0b00000000000;
17
+ // tl;dr: Configure an automatic-ranged, 800ms single shot reading,
18
+ // with INT processing disabled
19
+ static const uint16_t OPT3001_CONFIGURATION_FULL_RANGE_ONE_SHOT = OPT3001_CONFIGURATION_RANGE_FULL |
20
+ OPT3001_CONFIGURATION_CONVERSION_TIME_800 |
21
+ OPT3001_CONFIGURATION_CONVERSION_MODE_SINGLE_SHOT;
22
+ static const uint16_t OPT3001_CONVERSION_TIME_800 = 825; // give it 25 extra ms; it seems to not be ready quite often
23
+
24
+ /*
25
+ opt3001 properties:
26
+
27
+ - e (exponent) = high 4 bits of result register
28
+ - m (mantissa) = low 12 bits of result register
29
+ - formula: (0.01 * 2^e) * m lx
30
+
31
+ */
32
+
33
+ void OPT3001Sensor::read_result_(const std::function<void(float)> &f) {
34
+ // ensure the single shot flag is clear, indicating it's done
35
+ uint16_t raw_value;
36
+ if (this->read(reinterpret_cast<uint8_t *>(&raw_value), 2) != i2c::ERROR_OK) {
37
+ ESP_LOGW(TAG, "Reading configuration register failed");
38
+ f(NAN);
39
+ return;
40
+ }
41
+ raw_value = i2c::i2ctohs(raw_value);
42
+
43
+ if ((raw_value & OPT3001_CONFIGURATION_CONVERSION_MODE_MASK) != OPT3001_CONFIGURATION_CONVERSION_MODE_SHUTDOWN) {
44
+ // not ready; wait 10ms and try again
45
+ ESP_LOGW(TAG, "Data not ready; waiting 10ms");
46
+ this->set_timeout("opt3001_wait", 10, [this, f]() { read_result_(f); });
47
+ return;
48
+ }
49
+
50
+ if (this->read_register(OPT3001_REG_RESULT, reinterpret_cast<uint8_t *>(&raw_value), 2) != i2c::ERROR_OK) {
51
+ ESP_LOGW(TAG, "Reading result register failed");
52
+ f(NAN);
53
+ return;
54
+ }
55
+ raw_value = i2c::i2ctohs(raw_value);
56
+
57
+ uint8_t exponent = raw_value >> 12;
58
+ uint16_t mantissa = raw_value & 0b111111111111;
59
+
60
+ double lx = 0.01 * pow(2.0, double(exponent)) * double(mantissa);
61
+ f(float(lx));
62
+ }
63
+
64
+ void OPT3001Sensor::read_lx_(const std::function<void(float)> &f) {
65
+ // turn on (after one-shot sensor automatically powers down)
66
+ uint16_t start_measurement = i2c::htoi2cs(OPT3001_CONFIGURATION_FULL_RANGE_ONE_SHOT);
67
+ if (this->write_register(OPT3001_REG_CONFIGURATION, reinterpret_cast<uint8_t *>(&start_measurement), 2) !=
68
+ i2c::ERROR_OK) {
69
+ ESP_LOGW(TAG, "Triggering one shot measurement failed");
70
+ f(NAN);
71
+ return;
72
+ }
73
+
74
+ this->set_timeout("read", OPT3001_CONVERSION_TIME_800, [this, f]() {
75
+ if (this->write(&OPT3001_REG_CONFIGURATION, 1, true) != i2c::ERROR_OK) {
76
+ ESP_LOGW(TAG, "Starting configuration register read failed");
77
+ f(NAN);
78
+ return;
79
+ }
80
+
81
+ this->read_result_(f);
82
+ });
83
+ }
84
+
85
+ void OPT3001Sensor::dump_config() {
86
+ LOG_SENSOR("", "OPT3001", this);
87
+ LOG_I2C_DEVICE(this);
88
+ if (this->is_failed()) {
89
+ ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
90
+ }
91
+
92
+ LOG_UPDATE_INTERVAL(this);
93
+ }
94
+
95
+ void OPT3001Sensor::update() {
96
+ // Set a flag and skip just in case the sensor isn't responding,
97
+ // and we just keep waiting for it in read_result_.
98
+ // This way we don't end up with potentially boundless "threads"
99
+ // using up memory and eventually crashing the device
100
+ if (this->updating_) {
101
+ return;
102
+ }
103
+ this->updating_ = true;
104
+
105
+ this->read_lx_([this](float val) {
106
+ this->updating_ = false;
107
+
108
+ if (std::isnan(val)) {
109
+ this->status_set_warning();
110
+ this->publish_state(NAN);
111
+ return;
112
+ }
113
+ ESP_LOGD(TAG, "'%s': Illuminance=%.1flx", this->get_name().c_str(), val);
114
+ this->status_clear_warning();
115
+ this->publish_state(val);
116
+ });
117
+ }
118
+
119
+ float OPT3001Sensor::get_setup_priority() const { return setup_priority::DATA; }
120
+
121
+ } // namespace opt3001
122
+ } // namespace esphome
@@ -0,0 +1,27 @@
1
+ #pragma once
2
+
3
+ #include "esphome/core/component.h"
4
+ #include "esphome/components/sensor/sensor.h"
5
+ #include "esphome/components/i2c/i2c.h"
6
+
7
+ namespace esphome {
8
+ namespace opt3001 {
9
+
10
+ /// This class implements support for the i2c-based OPT3001 ambient light sensor.
11
+ class OPT3001Sensor : public sensor::Sensor, public PollingComponent, public i2c::I2CDevice {
12
+ public:
13
+ void dump_config() override;
14
+ void update() override;
15
+ float get_setup_priority() const override;
16
+
17
+ protected:
18
+ // checks if one-shot is complete before reading the result and returning it
19
+ void read_result_(const std::function<void(float)> &f);
20
+ // begins a one-shot measurement
21
+ void read_lx_(const std::function<void(float)> &f);
22
+
23
+ bool updating_{false};
24
+ };
25
+
26
+ } // namespace opt3001
27
+ } // namespace esphome
@@ -0,0 +1,35 @@
1
+ import esphome.codegen as cg
2
+ import esphome.config_validation as cv
3
+ from esphome.components import i2c, sensor
4
+ from esphome.const import (
5
+ DEVICE_CLASS_ILLUMINANCE,
6
+ STATE_CLASS_MEASUREMENT,
7
+ UNIT_LUX,
8
+ )
9
+
10
+ DEPENDENCIES = ["i2c"]
11
+ CODEOWNERS = ["@ccutrer"]
12
+
13
+ opt3001_ns = cg.esphome_ns.namespace("opt3001")
14
+
15
+ OPT3001Sensor = opt3001_ns.class_(
16
+ "OPT3001Sensor", sensor.Sensor, cg.PollingComponent, i2c.I2CDevice
17
+ )
18
+
19
+ CONFIG_SCHEMA = (
20
+ sensor.sensor_schema(
21
+ OPT3001Sensor,
22
+ unit_of_measurement=UNIT_LUX,
23
+ accuracy_decimals=1,
24
+ device_class=DEVICE_CLASS_ILLUMINANCE,
25
+ state_class=STATE_CLASS_MEASUREMENT,
26
+ )
27
+ .extend(cv.polling_component_schema("60s"))
28
+ .extend(i2c.i2c_device_schema(0x44))
29
+ )
30
+
31
+
32
+ async def to_code(config):
33
+ var = await sensor.new_sensor(config)
34
+ await cg.register_component(var, config)
35
+ await i2c.register_i2c_device(var, config)
@@ -1,5 +1,6 @@
1
1
  from esphome import automation
2
2
  import esphome.codegen as cg
3
+ from esphome.config_helpers import filter_source_files_from_platform
3
4
  import esphome.config_validation as cv
4
5
  from esphome.const import (
5
6
  CONF_ESPHOME,
@@ -7,6 +8,7 @@ from esphome.const import (
7
8
  CONF_OTA,
8
9
  CONF_PLATFORM,
9
10
  CONF_TRIGGER_ID,
11
+ PlatformFramework,
10
12
  )
11
13
  from esphome.core import CORE, coroutine_with_priority
12
14
 
@@ -120,3 +122,18 @@ async def ota_to_code(var, config):
120
122
  use_state_callback = True
121
123
  if use_state_callback:
122
124
  cg.add_define("USE_OTA_STATE_CALLBACK")
125
+
126
+
127
+ FILTER_SOURCE_FILES = filter_source_files_from_platform(
128
+ {
129
+ "ota_backend_arduino_esp32.cpp": {PlatformFramework.ESP32_ARDUINO},
130
+ "ota_backend_esp_idf.cpp": {PlatformFramework.ESP32_IDF},
131
+ "ota_backend_arduino_esp8266.cpp": {PlatformFramework.ESP8266_ARDUINO},
132
+ "ota_backend_arduino_rp2040.cpp": {PlatformFramework.RP2040_ARDUINO},
133
+ "ota_backend_arduino_libretiny.cpp": {
134
+ PlatformFramework.BK72XX_ARDUINO,
135
+ PlatformFramework.RTL87XX_ARDUINO,
136
+ PlatformFramework.LN882X_ARDUINO,
137
+ },
138
+ }
139
+ )
@@ -67,7 +67,28 @@ class OTAComponent : public Component {
67
67
  }
68
68
 
69
69
  protected:
70
- CallbackManager<void(ota::OTAState, float, uint8_t)> state_callback_{};
70
+ /** Extended callback manager with deferred call support.
71
+ *
72
+ * This adds a call_deferred() method for thread-safe execution from other tasks.
73
+ */
74
+ class StateCallbackManager : public CallbackManager<void(OTAState, float, uint8_t)> {
75
+ public:
76
+ StateCallbackManager(OTAComponent *component) : component_(component) {}
77
+
78
+ /** Call callbacks with deferral to main loop (for thread safety).
79
+ *
80
+ * This should be used by OTA implementations that run in separate tasks
81
+ * (like web_server OTA) to ensure callbacks execute in the main loop.
82
+ */
83
+ void call_deferred(ota::OTAState state, float progress, uint8_t error) {
84
+ component_->defer([this, state, progress, error]() { this->call(state, progress, error); });
85
+ }
86
+
87
+ private:
88
+ OTAComponent *component_;
89
+ };
90
+
91
+ StateCallbackManager state_callback_{this};
71
92
  #endif
72
93
  };
73
94
 
@@ -89,6 +110,11 @@ class OTAGlobalCallback {
89
110
 
90
111
  OTAGlobalCallback *get_global_ota_callback();
91
112
  void register_ota_platform(OTAComponent *ota_caller);
113
+
114
+ // OTA implementations should use:
115
+ // - state_callback_.call() when already in main loop (e.g., esphome OTA)
116
+ // - state_callback_.call_deferred() when in separate task (e.g., web_server OTA)
117
+ // This ensures proper callback execution in all contexts.
92
118
  #endif
93
119
  std::unique_ptr<ota::OTABackend> make_ota_backend();
94
120
 
@@ -15,6 +15,11 @@ static const char *const TAG = "ota.arduino_esp32";
15
15
  std::unique_ptr<ota::OTABackend> make_ota_backend() { return make_unique<ota::ArduinoESP32OTABackend>(); }
16
16
 
17
17
  OTAResponseTypes ArduinoESP32OTABackend::begin(size_t image_size) {
18
+ // Handle UPDATE_SIZE_UNKNOWN (0) which is used by web server OTA
19
+ // where the exact firmware size is unknown due to multipart encoding
20
+ if (image_size == 0) {
21
+ image_size = UPDATE_SIZE_UNKNOWN;
22
+ }
18
23
  bool ret = Update.begin(image_size, U_FLASH);
19
24
  if (ret) {
20
25
  return OTA_RESPONSE_OK;
@@ -29,7 +34,10 @@ OTAResponseTypes ArduinoESP32OTABackend::begin(size_t image_size) {
29
34
  return OTA_RESPONSE_ERROR_UNKNOWN;
30
35
  }
31
36
 
32
- void ArduinoESP32OTABackend::set_update_md5(const char *md5) { Update.setMD5(md5); }
37
+ void ArduinoESP32OTABackend::set_update_md5(const char *md5) {
38
+ Update.setMD5(md5);
39
+ this->md5_set_ = true;
40
+ }
33
41
 
34
42
  OTAResponseTypes ArduinoESP32OTABackend::write(uint8_t *data, size_t len) {
35
43
  size_t written = Update.write(data, len);
@@ -44,7 +52,9 @@ OTAResponseTypes ArduinoESP32OTABackend::write(uint8_t *data, size_t len) {
44
52
  }
45
53
 
46
54
  OTAResponseTypes ArduinoESP32OTABackend::end() {
47
- if (Update.end()) {
55
+ // Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
56
+ // This matches the behavior of the old web_server OTA implementation
57
+ if (Update.end(!this->md5_set_)) {
48
58
  return OTA_RESPONSE_OK;
49
59
  }
50
60
 
@@ -16,6 +16,9 @@ class ArduinoESP32OTABackend : public OTABackend {
16
16
  OTAResponseTypes end() override;
17
17
  void abort() override;
18
18
  bool supports_compression() override { return false; }
19
+
20
+ private:
21
+ bool md5_set_{false};
19
22
  };
20
23
 
21
24
  } // namespace ota
@@ -17,6 +17,11 @@ static const char *const TAG = "ota.arduino_esp8266";
17
17
  std::unique_ptr<ota::OTABackend> make_ota_backend() { return make_unique<ota::ArduinoESP8266OTABackend>(); }
18
18
 
19
19
  OTAResponseTypes ArduinoESP8266OTABackend::begin(size_t image_size) {
20
+ // Handle UPDATE_SIZE_UNKNOWN (0) by calculating available space
21
+ if (image_size == 0) {
22
+ // NOLINTNEXTLINE(readability-static-accessed-through-instance)
23
+ image_size = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
24
+ }
20
25
  bool ret = Update.begin(image_size, U_FLASH);
21
26
  if (ret) {
22
27
  esp8266::preferences_prevent_write(true);
@@ -38,7 +43,10 @@ OTAResponseTypes ArduinoESP8266OTABackend::begin(size_t image_size) {
38
43
  return OTA_RESPONSE_ERROR_UNKNOWN;
39
44
  }
40
45
 
41
- void ArduinoESP8266OTABackend::set_update_md5(const char *md5) { Update.setMD5(md5); }
46
+ void ArduinoESP8266OTABackend::set_update_md5(const char *md5) {
47
+ Update.setMD5(md5);
48
+ this->md5_set_ = true;
49
+ }
42
50
 
43
51
  OTAResponseTypes ArduinoESP8266OTABackend::write(uint8_t *data, size_t len) {
44
52
  size_t written = Update.write(data, len);
@@ -53,13 +61,19 @@ OTAResponseTypes ArduinoESP8266OTABackend::write(uint8_t *data, size_t len) {
53
61
  }
54
62
 
55
63
  OTAResponseTypes ArduinoESP8266OTABackend::end() {
56
- if (Update.end()) {
64
+ // Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
65
+ // This matches the behavior of the old web_server OTA implementation
66
+ bool success = Update.end(!this->md5_set_);
67
+
68
+ // On ESP8266, Update.end() might return false even with error code 0
69
+ // Check the actual error code to determine success
70
+ uint8_t error = Update.getError();
71
+
72
+ if (success || error == UPDATE_ERROR_OK) {
57
73
  return OTA_RESPONSE_OK;
58
74
  }
59
75
 
60
- uint8_t error = Update.getError();
61
76
  ESP_LOGE(TAG, "End error: %d", error);
62
-
63
77
  return OTA_RESPONSE_ERROR_UPDATE_END;
64
78
  }
65
79
 
@@ -21,6 +21,9 @@ class ArduinoESP8266OTABackend : public OTABackend {
21
21
  #else
22
22
  bool supports_compression() override { return false; }
23
23
  #endif
24
+
25
+ private:
26
+ bool md5_set_{false};
24
27
  };
25
28
 
26
29
  } // namespace ota
@@ -15,6 +15,11 @@ static const char *const TAG = "ota.arduino_libretiny";
15
15
  std::unique_ptr<ota::OTABackend> make_ota_backend() { return make_unique<ota::ArduinoLibreTinyOTABackend>(); }
16
16
 
17
17
  OTAResponseTypes ArduinoLibreTinyOTABackend::begin(size_t image_size) {
18
+ // Handle UPDATE_SIZE_UNKNOWN (0) which is used by web server OTA
19
+ // where the exact firmware size is unknown due to multipart encoding
20
+ if (image_size == 0) {
21
+ image_size = UPDATE_SIZE_UNKNOWN;
22
+ }
18
23
  bool ret = Update.begin(image_size, U_FLASH);
19
24
  if (ret) {
20
25
  return OTA_RESPONSE_OK;
@@ -29,7 +34,10 @@ OTAResponseTypes ArduinoLibreTinyOTABackend::begin(size_t image_size) {
29
34
  return OTA_RESPONSE_ERROR_UNKNOWN;
30
35
  }
31
36
 
32
- void ArduinoLibreTinyOTABackend::set_update_md5(const char *md5) { Update.setMD5(md5); }
37
+ void ArduinoLibreTinyOTABackend::set_update_md5(const char *md5) {
38
+ Update.setMD5(md5);
39
+ this->md5_set_ = true;
40
+ }
33
41
 
34
42
  OTAResponseTypes ArduinoLibreTinyOTABackend::write(uint8_t *data, size_t len) {
35
43
  size_t written = Update.write(data, len);
@@ -44,7 +52,9 @@ OTAResponseTypes ArduinoLibreTinyOTABackend::write(uint8_t *data, size_t len) {
44
52
  }
45
53
 
46
54
  OTAResponseTypes ArduinoLibreTinyOTABackend::end() {
47
- if (Update.end()) {
55
+ // Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
56
+ // This matches the behavior of the old web_server OTA implementation
57
+ if (Update.end(!this->md5_set_)) {
48
58
  return OTA_RESPONSE_OK;
49
59
  }
50
60
 
@@ -15,6 +15,9 @@ class ArduinoLibreTinyOTABackend : public OTABackend {
15
15
  OTAResponseTypes end() override;
16
16
  void abort() override;
17
17
  bool supports_compression() override { return false; }
18
+
19
+ private:
20
+ bool md5_set_{false};
18
21
  };
19
22
 
20
23
  } // namespace ota
@@ -17,6 +17,8 @@ static const char *const TAG = "ota.arduino_rp2040";
17
17
  std::unique_ptr<ota::OTABackend> make_ota_backend() { return make_unique<ota::ArduinoRP2040OTABackend>(); }
18
18
 
19
19
  OTAResponseTypes ArduinoRP2040OTABackend::begin(size_t image_size) {
20
+ // OTA size of 0 is not currently handled, but
21
+ // web_server is not supported for RP2040, so this is not an issue.
20
22
  bool ret = Update.begin(image_size, U_FLASH);
21
23
  if (ret) {
22
24
  rp2040::preferences_prevent_write(true);
@@ -38,7 +40,10 @@ OTAResponseTypes ArduinoRP2040OTABackend::begin(size_t image_size) {
38
40
  return OTA_RESPONSE_ERROR_UNKNOWN;
39
41
  }
40
42
 
41
- void ArduinoRP2040OTABackend::set_update_md5(const char *md5) { Update.setMD5(md5); }
43
+ void ArduinoRP2040OTABackend::set_update_md5(const char *md5) {
44
+ Update.setMD5(md5);
45
+ this->md5_set_ = true;
46
+ }
42
47
 
43
48
  OTAResponseTypes ArduinoRP2040OTABackend::write(uint8_t *data, size_t len) {
44
49
  size_t written = Update.write(data, len);
@@ -53,7 +58,9 @@ OTAResponseTypes ArduinoRP2040OTABackend::write(uint8_t *data, size_t len) {
53
58
  }
54
59
 
55
60
  OTAResponseTypes ArduinoRP2040OTABackend::end() {
56
- if (Update.end()) {
61
+ // Use strict validation (false) when MD5 is set, lenient validation (true) when no MD5
62
+ // This matches the behavior of the old web_server OTA implementation
63
+ if (Update.end(!this->md5_set_)) {
57
64
  return OTA_RESPONSE_OK;
58
65
  }
59
66
 
@@ -17,6 +17,9 @@ class ArduinoRP2040OTABackend : public OTABackend {
17
17
  OTAResponseTypes end() override;
18
18
  void abort() override;
19
19
  bool supports_compression() override { return false; }
20
+
21
+ private:
22
+ bool md5_set_{false};
20
23
  };
21
24
 
22
25
  } // namespace ota
@@ -6,10 +6,7 @@
6
6
 
7
7
  #include <esp_ota_ops.h>
8
8
  #include <esp_task_wdt.h>
9
-
10
- #if ESP_IDF_VERSION_MAJOR >= 5
11
9
  #include <spi_flash_mmap.h>
12
- #endif
13
10
 
14
11
  namespace esphome {
15
12
  namespace ota {
@@ -24,7 +21,6 @@ OTAResponseTypes IDFOTABackend::begin(size_t image_size) {
24
21
 
25
22
  #if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15
26
23
  // The following function takes longer than the 5 seconds timeout of WDT
27
- #if ESP_IDF_VERSION_MAJOR >= 5
28
24
  esp_task_wdt_config_t wdtc;
29
25
  wdtc.idle_core_mask = 0;
30
26
  #if CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0
@@ -36,21 +32,14 @@ OTAResponseTypes IDFOTABackend::begin(size_t image_size) {
36
32
  wdtc.timeout_ms = 15000;
37
33
  wdtc.trigger_panic = false;
38
34
  esp_task_wdt_reconfigure(&wdtc);
39
- #else
40
- esp_task_wdt_init(15, false);
41
- #endif
42
35
  #endif
43
36
 
44
37
  esp_err_t err = esp_ota_begin(this->partition_, image_size, &this->update_handle_);
45
38
 
46
39
  #if CONFIG_ESP_TASK_WDT_TIMEOUT_S < 15
47
40
  // Set the WDT back to the configured timeout
48
- #if ESP_IDF_VERSION_MAJOR >= 5
49
41
  wdtc.timeout_ms = CONFIG_ESP_TASK_WDT_TIMEOUT_S * 1000;
50
42
  esp_task_wdt_reconfigure(&wdtc);
51
- #else
52
- esp_task_wdt_init(CONFIG_ESP_TASK_WDT_TIMEOUT_S, false);
53
- #endif
54
43
  #endif
55
44
 
56
45
  if (err != ESP_OK) {
@@ -67,7 +56,10 @@ OTAResponseTypes IDFOTABackend::begin(size_t image_size) {
67
56
  return OTA_RESPONSE_OK;
68
57
  }
69
58
 
70
- void IDFOTABackend::set_update_md5(const char *expected_md5) { memcpy(this->expected_bin_md5_, expected_md5, 32); }
59
+ void IDFOTABackend::set_update_md5(const char *expected_md5) {
60
+ memcpy(this->expected_bin_md5_, expected_md5, 32);
61
+ this->md5_set_ = true;
62
+ }
71
63
 
72
64
  OTAResponseTypes IDFOTABackend::write(uint8_t *data, size_t len) {
73
65
  esp_err_t err = esp_ota_write(this->update_handle_, data, len);
@@ -84,10 +76,12 @@ OTAResponseTypes IDFOTABackend::write(uint8_t *data, size_t len) {
84
76
  }
85
77
 
86
78
  OTAResponseTypes IDFOTABackend::end() {
87
- this->md5_.calculate();
88
- if (!this->md5_.equals_hex(this->expected_bin_md5_)) {
89
- this->abort();
90
- return OTA_RESPONSE_ERROR_MD5_MISMATCH;
79
+ if (this->md5_set_) {
80
+ this->md5_.calculate();
81
+ if (!this->md5_.equals_hex(this->expected_bin_md5_)) {
82
+ this->abort();
83
+ return OTA_RESPONSE_ERROR_MD5_MISMATCH;
84
+ }
91
85
  }
92
86
  esp_err_t err = esp_ota_end(this->update_handle_);
93
87
  this->update_handle_ = 0;
@@ -24,6 +24,7 @@ class IDFOTABackend : public OTABackend {
24
24
  const esp_partition_t *partition_;
25
25
  md5::MD5Digest md5_{};
26
26
  char expected_bin_md5_[32];
27
+ bool md5_set_{false};
27
28
  };
28
29
 
29
30
  } // namespace ota
@@ -63,6 +63,7 @@ BASE_SCHEMA = cv.All(
63
63
  cv.Schema(
64
64
  {
65
65
  cv.Required(CONF_URL): cv.url,
66
+ cv.Optional(CONF_PATH): cv.string,
66
67
  cv.Optional(CONF_USERNAME): cv.string,
67
68
  cv.Optional(CONF_PASSWORD): cv.string,
68
69
  cv.Exclusive(CONF_FILE, CONF_FILES): validate_yaml_filename,
@@ -74,7 +75,7 @@ BASE_SCHEMA = cv.All(
74
75
  {
75
76
  cv.Required(CONF_PATH): validate_yaml_filename,
76
77
  cv.Optional(CONF_VARS, default={}): cv.Schema(
77
- {cv.string: cv.string}
78
+ {cv.string: object}
78
79
  ),
79
80
  }
80
81
  ),
@@ -116,6 +117,9 @@ def _process_base_package(config: dict) -> dict:
116
117
  )
117
118
  files = []
118
119
 
120
+ if base_path := config.get(CONF_PATH):
121
+ repo_dir = repo_dir / base_path
122
+
119
123
  for file in config[CONF_FILES]:
120
124
  if isinstance(file, str):
121
125
  files.append({CONF_PATH: file, CONF_VARS: {}})
@@ -148,7 +152,6 @@ def _process_base_package(config: dict) -> dict:
148
152
  raise cv.Invalid(
149
153
  f"Current ESPHome Version is too old to use this package: {ESPHOME_VERSION} < {min_version}"
150
154
  )
151
- vars = {k: str(v) for k, v in vars.items()}
152
155
  new_yaml = yaml_util.substitute_vars(new_yaml, vars)
153
156
  packages[f"{filename}{idx}"] = new_yaml
154
157
  except EsphomeError as e:
@@ -1,19 +1,76 @@
1
1
  import esphome.codegen as cg
2
2
  from esphome.components import binary_sensor
3
- from esphome.const import CONF_ID
3
+ import esphome.config_validation as cv
4
+ from esphome.const import (
5
+ CONF_DATA,
6
+ CONF_ID,
7
+ CONF_NAME,
8
+ CONF_STATUS,
9
+ CONF_TYPE,
10
+ DEVICE_CLASS_CONNECTIVITY,
11
+ ENTITY_CATEGORY_DIAGNOSTIC,
12
+ )
13
+ import esphome.final_validate as fv
4
14
 
5
15
  from . import (
16
+ CONF_ENCRYPTION,
17
+ CONF_PING_PONG_ENABLE,
6
18
  CONF_PROVIDER,
19
+ CONF_PROVIDERS,
7
20
  CONF_REMOTE_ID,
8
21
  CONF_TRANSPORT_ID,
22
+ PacketTransport,
9
23
  packet_transport_sensor_schema,
24
+ provider_name_validate,
25
+ )
26
+
27
+ STATUS_SENSOR_SCHEMA = binary_sensor.binary_sensor_schema(
28
+ device_class=DEVICE_CLASS_CONNECTIVITY,
29
+ entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
30
+ ).extend(
31
+ {
32
+ cv.GenerateID(CONF_TRANSPORT_ID): cv.use_id(PacketTransport),
33
+ cv.Required(CONF_PROVIDER): provider_name_validate,
34
+ }
35
+ )
36
+
37
+ CONFIG_SCHEMA = cv.typed_schema(
38
+ {
39
+ CONF_DATA: packet_transport_sensor_schema(binary_sensor.binary_sensor_schema()),
40
+ CONF_STATUS: STATUS_SENSOR_SCHEMA,
41
+ },
42
+ key=CONF_TYPE,
43
+ default_type=CONF_DATA,
10
44
  )
11
45
 
12
- CONFIG_SCHEMA = packet_transport_sensor_schema(binary_sensor.binary_sensor_schema())
46
+
47
+ def _final_validate(config):
48
+ if config[CONF_TYPE] != CONF_STATUS:
49
+ # Only run this validation if a status sensor is being configured
50
+ return config
51
+ full_config = fv.full_config.get()
52
+ transport_path = full_config.get_path_for_id(config[CONF_TRANSPORT_ID])[:-1]
53
+ transport_config = full_config.get_config_for_path(transport_path)
54
+ if transport_config[CONF_PING_PONG_ENABLE] and any(
55
+ CONF_ENCRYPTION in p
56
+ for p in transport_config[CONF_PROVIDERS]
57
+ if p[CONF_NAME] == config[CONF_PROVIDER]
58
+ ):
59
+ return config
60
+ raise cv.Invalid(
61
+ "Status sensor requires ping-pong to be enabled and the nominated provider to use encryption."
62
+ )
63
+
64
+
65
+ FINAL_VALIDATE_SCHEMA = _final_validate
13
66
 
14
67
 
15
68
  async def to_code(config):
16
69
  var = await binary_sensor.new_binary_sensor(config)
17
70
  comp = await cg.get_variable(config[CONF_TRANSPORT_ID])
18
- remote_id = str(config.get(CONF_REMOTE_ID) or config.get(CONF_ID))
19
- cg.add(comp.add_remote_binary_sensor(config[CONF_PROVIDER], remote_id, var))
71
+ if config[CONF_TYPE] == CONF_STATUS:
72
+ cg.add(comp.set_provider_status_sensor(config[CONF_PROVIDER], var))
73
+ cg.add_define("USE_STATUS_SENSOR")
74
+ else: # CONF_DATA is default
75
+ remote_id = str(config.get(CONF_REMOTE_ID) or config.get(CONF_ID))
76
+ cg.add(comp.add_remote_binary_sensor(config[CONF_PROVIDER], remote_id, var))