esphome 2025.6.3__py3-none-any.whl → 2025.7.0b2__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 (606) 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 +8 -2
  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/as5600/as5600.h +0 -1
  42. esphome/components/async_tcp/__init__.py +14 -5
  43. esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
  44. esphome/components/atm90e32/atm90e32.cpp +2 -1
  45. esphome/components/audio/audio_decoder.cpp +1 -1
  46. esphome/components/audio/audio_transfer_buffer.cpp +2 -2
  47. esphome/components/b_parasite/b_parasite.h +0 -1
  48. esphome/components/bedjet/bedjet_hub.cpp +5 -1
  49. esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
  50. esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
  51. esphome/components/bh1750/bh1750.cpp +5 -5
  52. esphome/components/binary_sensor/__init__.py +82 -5
  53. esphome/components/binary_sensor/automation.h +19 -1
  54. esphome/components/binary_sensor/binary_sensor.cpp +12 -30
  55. esphome/components/binary_sensor/binary_sensor.h +11 -25
  56. esphome/components/binary_sensor/filter.cpp +29 -24
  57. esphome/components/binary_sensor/filter.h +20 -10
  58. esphome/components/ble_client/output/ble_binary_output.h +0 -1
  59. esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
  60. esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
  61. esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
  62. esphome/components/ble_client/sensor/ble_sensor.h +0 -1
  63. esphome/components/ble_client/switch/ble_switch.h +0 -1
  64. esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
  65. esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
  66. esphome/components/ble_presence/ble_presence_device.h +0 -1
  67. esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
  68. esphome/components/ble_scanner/ble_scanner.h +0 -1
  69. esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
  70. esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
  71. esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
  72. esphome/components/bme680/sensor.py +1 -1
  73. esphome/components/bmp581/bmp581.h +0 -2
  74. esphome/components/button/__init__.py +5 -2
  75. esphome/components/camera/__init__.py +1 -0
  76. esphome/components/camera/camera.cpp +22 -0
  77. esphome/components/camera/camera.h +80 -0
  78. esphome/components/canbus/__init__.py +1 -0
  79. esphome/components/cap1188/cap1188.h +0 -1
  80. esphome/components/captive_portal/__init__.py +12 -2
  81. esphome/components/captive_portal/captive_portal.cpp +12 -2
  82. esphome/components/captive_portal/captive_portal.h +5 -2
  83. esphome/components/ccs811/ccs811.h +0 -2
  84. esphome/components/climate/__init__.py +5 -2
  85. esphome/components/cm1106/sensor.py +2 -2
  86. esphome/components/const/__init__.py +2 -0
  87. esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
  88. esphome/components/copy/button/copy_button.h +0 -1
  89. esphome/components/copy/cover/copy_cover.h +0 -1
  90. esphome/components/copy/fan/copy_fan.h +0 -1
  91. esphome/components/copy/lock/copy_lock.h +0 -1
  92. esphome/components/copy/number/copy_number.h +0 -1
  93. esphome/components/copy/select/copy_select.h +0 -1
  94. esphome/components/copy/sensor/copy_sensor.h +0 -1
  95. esphome/components/copy/switch/copy_switch.h +0 -1
  96. esphome/components/copy/text/copy_text.h +0 -1
  97. esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
  98. esphome/components/cover/__init__.py +5 -2
  99. esphome/components/cs5460a/cs5460a.h +0 -1
  100. esphome/components/datetime/__init__.py +4 -2
  101. esphome/components/debug/__init__.py +20 -0
  102. esphome/components/debug/debug_esp32.cpp +2 -0
  103. esphome/components/deep_sleep/__init__.py +43 -9
  104. esphome/components/demo/__init__.py +2 -2
  105. esphome/components/display/display.cpp +4 -3
  106. esphome/components/display/display.h +0 -2
  107. esphome/components/display/display_buffer.cpp +1 -1
  108. esphome/components/ds2484/__init__.py +1 -0
  109. esphome/components/ds2484/ds2484.cpp +209 -0
  110. esphome/components/ds2484/ds2484.h +43 -0
  111. esphome/components/ds2484/one_wire.py +37 -0
  112. esphome/components/duty_time/duty_time_sensor.h +0 -1
  113. esphome/components/ens160_base/ens160_base.h +0 -1
  114. esphome/components/es7210/es7210.h +0 -1
  115. esphome/components/es7243e/es7243e.h +0 -1
  116. esphome/components/es8156/es8156.h +0 -1
  117. esphome/components/es8311/es8311.h +0 -1
  118. esphome/components/es8388/es8388.h +0 -1
  119. esphome/components/esp32/__init__.py +103 -135
  120. esphome/components/esp32/core.cpp +0 -4
  121. esphome/components/esp32/gpio.h +1 -1
  122. esphome/components/esp32/helpers.cpp +69 -0
  123. esphome/components/esp32_ble/ble.cpp +5 -6
  124. esphome/components/esp32_ble/ble.h +29 -14
  125. esphome/components/esp32_ble/ble_event.h +6 -6
  126. esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
  127. esphome/components/esp32_ble_client/ble_client_base.h +24 -9
  128. esphome/components/esp32_ble_tracker/__init__.py +2 -8
  129. esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
  130. esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
  131. esphome/components/esp32_camera/__init__.py +112 -98
  132. esphome/components/esp32_camera/esp32_camera.cpp +41 -31
  133. esphome/components/esp32_camera/esp32_camera.h +35 -30
  134. esphome/components/esp32_camera_web_server/__init__.py +2 -1
  135. esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
  136. esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
  137. esphome/components/esp32_hall/sensor.py +2 -21
  138. esphome/components/esp32_hosted/__init__.py +101 -0
  139. esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
  140. esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
  141. esphome/components/esp32_rmt/__init__.py +0 -58
  142. esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
  143. esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
  144. esphome/components/esp32_rmt_led_strip/light.py +14 -76
  145. esphome/components/esp32_touch/esp32_touch.h +174 -28
  146. esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
  147. esphome/components/esp32_touch/esp32_touch_v1.cpp +240 -0
  148. esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
  149. esphome/components/esp8266/__init__.py +2 -0
  150. esphome/components/esp8266/gpio.cpp +10 -10
  151. esphome/components/esp8266/helpers.cpp +31 -0
  152. esphome/components/esphome/ota/__init__.py +1 -0
  153. esphome/components/esphome/ota/ota_esphome.cpp +24 -19
  154. esphome/components/ethernet/__init__.py +42 -23
  155. esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
  156. esphome/components/ethernet/ethernet_component.cpp +69 -29
  157. esphome/components/ethernet/ethernet_component.h +18 -10
  158. esphome/components/event/__init__.py +5 -2
  159. esphome/components/ezo/ezo.h +0 -1
  160. esphome/components/ezo_pmp/ezo_pmp.h +0 -1
  161. esphome/components/fan/__init__.py +5 -2
  162. esphome/components/feedback/feedback_cover.h +0 -1
  163. esphome/components/font/__init__.py +92 -82
  164. esphome/components/font/font.cpp +9 -2
  165. esphome/components/font/font.h +20 -5
  166. esphome/components/fs3000/fs3000.h +0 -1
  167. esphome/components/gcja5/gcja5.h +0 -1
  168. esphome/components/gl_r01_i2c/__init__.py +0 -0
  169. esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
  170. esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
  171. esphome/components/gl_r01_i2c/sensor.py +36 -0
  172. esphome/components/gp8403/gp8403.h +0 -1
  173. esphome/components/gpio/binary_sensor/__init__.py +17 -0
  174. esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
  175. esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
  176. esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
  177. esphome/components/he60r/he60r.h +0 -1
  178. esphome/components/heatpumpir/climate.py +2 -1
  179. esphome/components/heatpumpir/heatpumpir.cpp +1 -0
  180. esphome/components/heatpumpir/heatpumpir.h +1 -0
  181. esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
  182. esphome/components/host/__init__.py +3 -1
  183. esphome/components/host/helpers.cpp +57 -0
  184. esphome/components/http_request/__init__.py +19 -1
  185. esphome/components/http_request/http_request.h +1 -1
  186. esphome/components/http_request/http_request_arduino.h +1 -0
  187. esphome/components/http_request/ota/ota_http_request.cpp +1 -1
  188. esphome/components/http_request/update/http_request_update.cpp +28 -9
  189. esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +3 -9
  190. esphome/components/hydreon_rgxx/sensor.py +1 -1
  191. esphome/components/i2c/__init__.py +23 -11
  192. esphome/components/i2c/i2c_bus.h +8 -1
  193. esphome/components/i2c/i2c_bus_arduino.cpp +4 -3
  194. esphome/components/i2c/i2c_bus_arduino.h +6 -3
  195. esphome/components/i2c/i2c_bus_esp_idf.h +5 -3
  196. esphome/components/i2c_device/i2c_device.h +0 -1
  197. esphome/components/i2s_audio/__init__.py +2 -10
  198. esphome/components/i2s_audio/i2s_audio.cpp +1 -5
  199. esphome/components/i2s_audio/media_player/__init__.py +2 -2
  200. esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +2 -2
  201. esphome/components/iaqcore/iaqcore.h +0 -2
  202. esphome/components/image/__init__.py +123 -24
  203. esphome/components/improv_serial/improv_serial_component.cpp +0 -4
  204. esphome/components/ina219/ina219.cpp +7 -0
  205. esphome/components/ina219/ina219.h +1 -0
  206. esphome/components/ina260/ina260.h +0 -2
  207. esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h +0 -1
  208. esphome/components/inkplate6/display.py +15 -0
  209. esphome/components/inkplate6/inkplate.cpp +2 -2
  210. esphome/components/integration/integration_sensor.h +0 -1
  211. esphome/components/internal_temperature/internal_temperature.cpp +8 -27
  212. esphome/components/internal_temperature/sensor.py +0 -26
  213. esphome/components/interval/interval.h +0 -2
  214. esphome/components/ld2410/button/__init__.py +3 -3
  215. esphome/components/ld2410/button/factory_reset_button.cpp +9 -0
  216. esphome/components/ld2410/button/{reset_button.h → factory_reset_button.h} +2 -2
  217. esphome/components/ld2410/ld2410.cpp +421 -268
  218. esphome/components/ld2410/ld2410.h +44 -146
  219. esphome/components/ld2410/number/__init__.py +2 -2
  220. esphome/components/ld2410/sensor.py +1 -1
  221. esphome/components/ld2410/switch/__init__.py +1 -1
  222. esphome/components/ld2420/ld2420.cpp +196 -100
  223. esphome/components/ld2420/ld2420.h +46 -118
  224. esphome/components/ld2420/number/__init__.py +2 -2
  225. esphome/components/ld2420/sensor/__init__.py +6 -2
  226. esphome/components/ld2420/sensor/ld2420_sensor.h +1 -1
  227. esphome/components/ld2450/button/__init__.py +3 -3
  228. esphome/components/ld2450/button/factory_reset_button.cpp +9 -0
  229. esphome/components/ld2450/button/{reset_button.h → factory_reset_button.h} +2 -2
  230. esphome/components/ld2450/ld2450.cpp +384 -232
  231. esphome/components/ld2450/ld2450.h +60 -69
  232. esphome/components/ld2450/switch/__init__.py +1 -1
  233. esphome/components/ledc/ledc_output.cpp +1 -63
  234. esphome/components/libretiny/__init__.py +5 -3
  235. esphome/components/libretiny/const.py +5 -0
  236. esphome/components/libretiny/generate_components.py +1 -0
  237. esphome/components/libretiny/helpers.cpp +35 -0
  238. esphome/components/libretiny/lt_component.cpp +5 -3
  239. esphome/components/light/__init__.py +4 -2
  240. esphome/components/light/addressable_light.h +3 -3
  241. esphome/components/light/light_call.cpp +180 -243
  242. esphome/components/light/light_call.h +72 -20
  243. esphome/components/light/light_color_values.h +14 -14
  244. esphome/components/light/light_state.h +15 -13
  245. esphome/components/light/transformers.h +2 -2
  246. esphome/components/ln882x/__init__.py +52 -0
  247. esphome/components/ln882x/boards.py +285 -0
  248. esphome/components/lock/__init__.py +5 -2
  249. esphome/components/logger/__init__.py +40 -3
  250. esphome/components/logger/logger.cpp +47 -12
  251. esphome/components/logger/logger.h +80 -49
  252. esphome/components/logger/logger_esp32.cpp +3 -3
  253. esphome/components/lps22/__init__.py +0 -0
  254. esphome/components/lps22/lps22.cpp +75 -0
  255. esphome/components/lps22/lps22.h +27 -0
  256. esphome/components/lps22/sensor.py +58 -0
  257. esphome/components/ltr390/ltr390.h +0 -1
  258. esphome/components/ltr501/ltr501.h +0 -1
  259. esphome/components/ltr_als_ps/ltr_als_ps.h +0 -1
  260. esphome/components/lvgl/__init__.py +1 -1
  261. esphome/components/lvgl/schemas.py +66 -6
  262. esphome/components/lvgl/styles.py +24 -16
  263. esphome/components/lvgl/widgets/__init__.py +12 -2
  264. esphome/components/lvgl/widgets/lv_bar.py +40 -19
  265. esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +1 -1
  266. esphome/components/max9611/max9611.h +0 -1
  267. esphome/components/mcp23016/__init__.py +1 -1
  268. esphome/components/mcp23xxx_base/__init__.py +1 -1
  269. esphome/components/mcp4461/__init__.py +1 -1
  270. esphome/components/mcp4461/output/__init__.py +3 -2
  271. esphome/components/mcp9600/mcp9600.h +0 -2
  272. esphome/components/md5/md5.cpp +3 -3
  273. esphome/components/md5/md5.h +1 -6
  274. esphome/components/mdns/__init__.py +22 -11
  275. esphome/components/media_player/__init__.py +4 -3
  276. esphome/components/micro_wake_word/__init__.py +1 -5
  277. esphome/components/micro_wake_word/streaming_model.cpp +2 -2
  278. esphome/components/microphone/microphone.cpp +7 -9
  279. esphome/components/microphone/microphone.h +0 -2
  280. esphome/components/mipi_spi/display.py +1 -0
  281. esphome/components/mmc5603/mmc5603.cpp +1 -1
  282. esphome/components/modbus/modbus.cpp +33 -15
  283. esphome/components/modbus/modbus.h +9 -0
  284. esphome/components/modbus_controller/__init__.py +42 -10
  285. esphome/components/modbus_controller/modbus_controller.cpp +92 -11
  286. esphome/components/modbus_controller/modbus_controller.h +61 -7
  287. esphome/components/mopeka_pro_check/mopeka_pro_check.h +0 -1
  288. esphome/components/mopeka_std_check/mopeka_std_check.h +0 -1
  289. esphome/components/mpl3115a2/mpl3115a2.h +0 -2
  290. esphome/components/mqtt/__init__.py +16 -0
  291. esphome/components/mqtt/mqtt_backend.h +2 -1
  292. esphome/components/mqtt/mqtt_backend_esp32.cpp +132 -47
  293. esphome/components/mqtt/mqtt_backend_esp32.h +106 -4
  294. esphome/components/mqtt/mqtt_client.cpp +15 -9
  295. esphome/components/mqtt/mqtt_client.h +8 -3
  296. esphome/components/ms8607/ms8607.h +0 -1
  297. esphome/components/neopixelbus/light.py +4 -1
  298. esphome/components/neopixelbus/neopixelbus_light.h +1 -1
  299. esphome/components/network/__init__.py +4 -1
  300. esphome/components/network/ip_address.h +1 -0
  301. esphome/components/nextion/__init__.py +16 -0
  302. esphome/components/nextion/base_component.py +1 -0
  303. esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
  304. esphome/components/nextion/display.py +14 -4
  305. esphome/components/nextion/nextion.cpp +166 -101
  306. esphome/components/nextion/nextion.h +84 -53
  307. esphome/components/nextion/nextion_commands.cpp +11 -10
  308. esphome/components/nextion/nextion_component.cpp +28 -28
  309. esphome/components/nextion/nextion_component.h +53 -18
  310. esphome/components/nextion/nextion_component_base.h +3 -0
  311. esphome/components/nextion/nextion_upload.cpp +36 -0
  312. esphome/components/nextion/nextion_upload_arduino.cpp +10 -35
  313. esphome/components/nextion/nextion_upload_idf.cpp +9 -33
  314. esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
  315. esphome/components/nextion/switch/nextion_switch.cpp +1 -1
  316. esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
  317. esphome/components/nfc/nfc.cpp +3 -22
  318. esphome/components/nfc/nfc.h +3 -3
  319. esphome/components/number/__init__.py +5 -2
  320. esphome/components/online_image/__init__.py +5 -0
  321. esphome/components/online_image/online_image.cpp +6 -2
  322. esphome/components/online_image/online_image.h +4 -1
  323. esphome/components/opentherm/opentherm.cpp +7 -12
  324. esphome/components/openthread/__init__.py +47 -40
  325. esphome/components/openthread/const.py +1 -0
  326. esphome/components/openthread/openthread_esp.cpp +27 -5
  327. esphome/components/opt3001/__init__.py +0 -0
  328. esphome/components/opt3001/opt3001.cpp +122 -0
  329. esphome/components/opt3001/opt3001.h +27 -0
  330. esphome/components/opt3001/sensor.py +35 -0
  331. esphome/components/ota/__init__.py +17 -0
  332. esphome/components/ota/ota_backend.h +27 -1
  333. esphome/components/ota/ota_backend_arduino_esp32.cpp +12 -2
  334. esphome/components/ota/ota_backend_arduino_esp32.h +3 -0
  335. esphome/components/ota/ota_backend_arduino_esp8266.cpp +18 -4
  336. esphome/components/ota/ota_backend_arduino_esp8266.h +3 -0
  337. esphome/components/ota/ota_backend_arduino_libretiny.cpp +12 -2
  338. esphome/components/ota/ota_backend_arduino_libretiny.h +3 -0
  339. esphome/components/ota/ota_backend_arduino_rp2040.cpp +9 -2
  340. esphome/components/ota/ota_backend_arduino_rp2040.h +3 -0
  341. esphome/components/ota/ota_backend_esp_idf.cpp +10 -16
  342. esphome/components/ota/ota_backend_esp_idf.h +1 -0
  343. esphome/components/packages/__init__.py +5 -2
  344. esphome/components/packet_transport/binary_sensor.py +61 -4
  345. esphome/components/packet_transport/packet_transport.cpp +34 -1
  346. esphome/components/packet_transport/packet_transport.h +11 -5
  347. esphome/components/pcf8574/__init__.py +1 -1
  348. esphome/components/pi4ioe5v6408/__init__.py +84 -0
  349. esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +171 -0
  350. esphome/components/pi4ioe5v6408/pi4ioe5v6408.h +70 -0
  351. esphome/components/pmsa003i/pmsa003i.h +0 -1
  352. esphome/components/pmsx003/pmsx003.h +0 -1
  353. esphome/components/pn7150/pn7150.cpp +7 -7
  354. esphome/components/pn7150/pn7150.h +0 -1
  355. esphome/components/pn7160/pn7160.cpp +7 -7
  356. esphome/components/pn7160/pn7160.h +0 -1
  357. esphome/components/preferences/syncer.h +2 -0
  358. esphome/components/prometheus/prometheus_handler.h +1 -1
  359. esphome/components/psram/psram.cpp +0 -20
  360. esphome/components/pulse_counter/pulse_counter_sensor.h +0 -1
  361. esphome/components/pulse_meter/pulse_meter_sensor.cpp +8 -4
  362. esphome/components/pulse_width/pulse_width.h +0 -1
  363. esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +0 -4
  364. esphome/components/pvvx_mithermometer/display/pvvx_display.h +0 -2
  365. esphome/components/pvvx_mithermometer/pvvx_mithermometer.h +0 -1
  366. esphome/components/qr_code/__init__.py +13 -10
  367. esphome/components/qwiic_pir/qwiic_pir.h +0 -1
  368. esphome/components/radon_eye_ble/radon_eye_listener.cpp +1 -1
  369. esphome/components/rc522/rc522.h +0 -1
  370. esphome/components/rdm6300/rdm6300.h +0 -2
  371. esphome/components/remote_base/__init__.py +7 -5
  372. esphome/components/remote_base/remote_base.cpp +24 -21
  373. esphome/components/remote_base/remote_base.h +3 -26
  374. esphome/components/remote_receiver/__init__.py +40 -46
  375. esphome/components/remote_receiver/remote_receiver.h +4 -18
  376. esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -87
  377. esphome/components/remote_receiver/remote_receiver_esp8266.cpp +1 -1
  378. esphome/components/remote_transmitter/__init__.py +42 -43
  379. esphome/components/remote_transmitter/remote_transmitter.h +2 -14
  380. esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -77
  381. esphome/components/resistance/resistance_sensor.h +0 -1
  382. esphome/components/rp2040/__init__.py +2 -0
  383. esphome/components/rp2040/helpers.cpp +55 -0
  384. esphome/components/rp2040_pio_led_strip/led_strip.cpp +2 -2
  385. esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -4
  386. esphome/components/rtttl/__init__.py +4 -4
  387. esphome/components/rtttl/rtttl.cpp +10 -1
  388. esphome/components/ruuvitag/ruuvitag.h +0 -1
  389. esphome/components/safe_mode/safe_mode.cpp +2 -0
  390. esphome/components/safe_mode/safe_mode.h +4 -1
  391. esphome/components/scd30/scd30.h +0 -1
  392. esphome/components/scd30/sensor.py +2 -2
  393. esphome/components/scd4x/scd4x.cpp +61 -54
  394. esphome/components/scd4x/scd4x.h +17 -15
  395. esphome/components/scd4x/sensor.py +4 -4
  396. esphome/components/script/script.h +0 -2
  397. esphome/components/sdp3x/sensor.py +1 -1
  398. esphome/components/select/__init__.py +5 -2
  399. esphome/components/sen5x/sen5x.h +0 -1
  400. esphome/components/senseair/senseair.h +0 -1
  401. esphome/components/sensor/__init__.py +4 -2
  402. esphome/components/sensor/filter.cpp +1 -1
  403. esphome/components/sensor/sensor.cpp +12 -6
  404. esphome/components/sensor/sensor.h +13 -5
  405. esphome/components/servo/servo.h +0 -1
  406. esphome/components/sfa30/sfa30.h +0 -1
  407. esphome/components/sgp30/sgp30.h +0 -1
  408. esphome/components/sgp4x/sgp4x.h +0 -1
  409. esphome/components/shelly_dimmer/stm32flash.cpp +1 -2
  410. esphome/components/sht4x/sht4x.h +0 -1
  411. esphome/components/sm300d2/sm300d2.h +0 -2
  412. esphome/components/smt100/sensor.py +8 -4
  413. esphome/components/smt100/smt100.cpp +5 -5
  414. esphome/components/smt100/smt100.h +3 -3
  415. esphome/components/sn74hc595/__init__.py +1 -1
  416. esphome/components/sn74hc595/sn74hc595.cpp +5 -4
  417. esphome/components/sntp/sntp_component.cpp +9 -3
  418. esphome/components/sntp/time.py +2 -0
  419. esphome/components/socket/__init__.py +17 -0
  420. esphome/components/spi/__init__.py +27 -6
  421. esphome/components/spi/spi.cpp +3 -2
  422. esphome/components/spi/spi.h +9 -3
  423. esphome/components/spi/spi_arduino.cpp +3 -5
  424. esphome/components/spi/spi_esp_idf.cpp +40 -21
  425. esphome/components/spi_led_strip/spi_led_strip.cpp +1 -1
  426. esphome/components/sps30/sps30.h +0 -1
  427. esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
  428. esphome/components/st7701s/st7701s.cpp +0 -4
  429. esphome/components/status/status_binary_sensor.h +0 -2
  430. esphome/components/substitutions/__init__.py +76 -19
  431. esphome/components/substitutions/jinja.py +99 -0
  432. esphome/components/sun/sun.cpp +3 -4
  433. esphome/components/switch/__init__.py +5 -2
  434. esphome/components/switch/binary_sensor/switch_binary_sensor.h +0 -1
  435. esphome/components/sx126x/__init__.py +317 -0
  436. esphome/components/sx126x/automation.h +62 -0
  437. esphome/components/sx126x/packet_transport/__init__.py +26 -0
  438. esphome/components/sx126x/packet_transport/sx126x_transport.cpp +26 -0
  439. esphome/components/sx126x/packet_transport/sx126x_transport.h +25 -0
  440. esphome/components/sx126x/sx126x.cpp +523 -0
  441. esphome/components/sx126x/sx126x.h +140 -0
  442. esphome/components/sx126x/sx126x_reg.h +163 -0
  443. esphome/components/sx127x/__init__.py +325 -0
  444. esphome/components/sx127x/automation.h +62 -0
  445. esphome/components/sx127x/packet_transport/__init__.py +26 -0
  446. esphome/components/sx127x/packet_transport/sx127x_transport.cpp +26 -0
  447. esphome/components/sx127x/packet_transport/sx127x_transport.h +25 -0
  448. esphome/components/sx127x/sx127x.cpp +498 -0
  449. esphome/components/sx127x/sx127x.h +128 -0
  450. esphome/components/sx127x/sx127x_reg.h +295 -0
  451. esphome/components/syslog/esphome_syslog.cpp +5 -3
  452. esphome/components/syslog/esphome_syslog.h +1 -1
  453. esphome/components/tca9555/__init__.py +1 -1
  454. esphome/components/template/binary_sensor/template_binary_sensor.cpp +1 -9
  455. esphome/components/text/__init__.py +5 -2
  456. esphome/components/text_sensor/__init__.py +5 -2
  457. esphome/components/thermostat/thermostat_climate.cpp +34 -31
  458. esphome/components/thermostat/thermostat_climate.h +43 -39
  459. esphome/components/time/__init__.py +16 -2
  460. esphome/components/time/real_time_clock.cpp +4 -0
  461. esphome/components/time/real_time_clock.h +5 -1
  462. esphome/components/tlc5971/tlc5971.cpp +4 -1
  463. esphome/components/tmp1075/tmp1075.h +0 -2
  464. esphome/components/tof10120/tof10120_sensor.h +0 -1
  465. esphome/components/tormatic/tormatic_cover.h +0 -1
  466. esphome/components/total_daily_energy/total_daily_energy.h +0 -1
  467. esphome/components/tsl2591/tsl2591.cpp +1 -1
  468. esphome/components/ttp229_bsf/ttp229_bsf.h +0 -1
  469. esphome/components/ttp229_lsf/ttp229_lsf.h +0 -1
  470. esphome/components/tx20/tx20.cpp +2 -2
  471. esphome/components/uart/__init__.py +18 -0
  472. esphome/components/uart/uart_component_esp_idf.cpp +0 -4
  473. esphome/components/update/__init__.py +5 -2
  474. esphome/components/update/update_entity.h +8 -0
  475. esphome/components/usb_host/__init__.py +5 -2
  476. esphome/components/usb_host/usb_host_client.cpp +10 -10
  477. esphome/components/usb_uart/cp210x.cpp +1 -1
  478. esphome/components/usb_uart/usb_uart.cpp +41 -44
  479. esphome/components/usb_uart/usb_uart.h +4 -3
  480. esphome/components/valve/__init__.py +5 -2
  481. esphome/components/vbus/vbus.h +0 -1
  482. esphome/components/veml3235/veml3235.h +0 -1
  483. esphome/components/veml7700/veml7700.h +0 -1
  484. esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
  485. esphome/components/voice_assistant/voice_assistant.cpp +4 -4
  486. esphome/components/watchdog/watchdog.cpp +0 -4
  487. esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
  488. esphome/components/web_server/__init__.py +34 -19
  489. esphome/components/web_server/ota/__init__.py +32 -0
  490. esphome/components/web_server/ota/ota_web_server.cpp +210 -0
  491. esphome/components/web_server/ota/ota_web_server.h +26 -0
  492. esphome/components/web_server/web_server.cpp +305 -427
  493. esphome/components/web_server/web_server.h +33 -23
  494. esphome/components/web_server/web_server_v1.cpp +4 -5
  495. esphome/components/web_server_base/__init__.py +5 -2
  496. esphome/components/web_server_base/web_server_base.cpp +2 -94
  497. esphome/components/web_server_base/web_server_base.h +5 -25
  498. esphome/components/web_server_idf/multipart.cpp +254 -0
  499. esphome/components/web_server_idf/multipart.h +86 -0
  500. esphome/components/web_server_idf/utils.cpp +32 -0
  501. esphome/components/web_server_idf/utils.h +10 -0
  502. esphome/components/web_server_idf/web_server_idf.cpp +162 -16
  503. esphome/components/web_server_idf/web_server_idf.h +11 -10
  504. esphome/components/wiegand/wiegand.cpp +2 -2
  505. esphome/components/wifi/__init__.py +18 -0
  506. esphome/components/wifi/wifi_component.cpp +17 -22
  507. esphome/components/wifi/wifi_component.h +27 -23
  508. esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
  509. esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
  510. esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
  511. esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
  512. esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
  513. esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
  514. esphome/components/wireguard/__init__.py +2 -11
  515. esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
  516. esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
  517. esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
  518. esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
  519. esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
  520. esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
  521. esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
  522. esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
  523. esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
  524. esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
  525. esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
  526. esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
  527. esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
  528. esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
  529. esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
  530. esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
  531. esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
  532. esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
  533. esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
  534. esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
  535. esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
  536. esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
  537. esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
  538. esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
  539. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
  540. esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
  541. esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
  542. esphome/components/zyaura/zyaura.h +0 -1
  543. esphome/config.py +88 -22
  544. esphome/config_helpers.py +74 -1
  545. esphome/config_validation.py +12 -1
  546. esphome/const.py +65 -10
  547. esphome/core/__init__.py +18 -2
  548. esphome/core/application.cpp +163 -10
  549. esphome/core/application.h +145 -165
  550. esphome/core/area.h +19 -0
  551. esphome/core/automation.h +58 -9
  552. esphome/core/color.cpp +3 -5
  553. esphome/core/color.h +16 -16
  554. esphome/core/component.cpp +151 -18
  555. esphome/core/component.h +98 -4
  556. esphome/core/component_iterator.cpp +11 -9
  557. esphome/core/component_iterator.h +12 -10
  558. esphome/core/config.py +155 -6
  559. esphome/core/controller.cpp +4 -2
  560. esphome/core/controller.h +1 -1
  561. esphome/core/datatypes.h +2 -2
  562. esphome/core/defines.h +17 -2
  563. esphome/core/device.h +20 -0
  564. esphome/core/entity_base.cpp +20 -15
  565. esphome/core/entity_base.h +76 -0
  566. esphome/core/entity_helpers.py +168 -1
  567. esphome/core/event_pool.h +81 -0
  568. esphome/core/helpers.cpp +75 -230
  569. esphome/core/helpers.h +164 -104
  570. esphome/core/lock_free_queue.h +151 -0
  571. esphome/core/log.cpp +2 -2
  572. esphome/core/log.h +2 -0
  573. esphome/core/optional.h +5 -0
  574. esphome/core/ring_buffer.cpp +2 -2
  575. esphome/core/scheduler.cpp +275 -103
  576. esphome/core/scheduler.h +154 -17
  577. esphome/core/time.cpp +5 -5
  578. esphome/core/time.h +5 -5
  579. esphome/cpp_generator.py +17 -0
  580. esphome/cpp_helpers.py +0 -22
  581. esphome/cpp_types.py +3 -1
  582. esphome/dashboard/entries.py +1 -1
  583. esphome/dashboard/util/text.py +5 -21
  584. esphome/dashboard/web_server.py +9 -1
  585. esphome/helpers.py +47 -0
  586. esphome/loader.py +15 -1
  587. esphome/pins.py +14 -8
  588. esphome/wizard.py +17 -4
  589. esphome/writer.py +21 -3
  590. esphome/yaml_util.py +0 -2
  591. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/METADATA +10 -9
  592. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/RECORD +597 -538
  593. esphome/components/api/api_pb2_size.h +0 -361
  594. esphome/components/esp32_ble/ble_event_pool.h +0 -72
  595. esphome/components/esp32_ble/queue.h +0 -85
  596. esphome/components/esp32_hall/esp32_hall.cpp +0 -25
  597. esphome/components/esp32_hall/esp32_hall.h +0 -23
  598. esphome/components/esp32_touch/esp32_touch.cpp +0 -355
  599. esphome/components/ld2410/button/reset_button.cpp +0 -9
  600. esphome/components/ld2450/button/reset_button.cpp +0 -9
  601. esphome/components/openthread/tlv.py +0 -65
  602. /esphome/{dashboard/enum.py → enum.py} +0 -0
  603. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/WHEEL +0 -0
  604. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/entry_points.txt +0 -0
  605. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/licenses/LICENSE +0 -0
  606. {esphome-2025.6.3.dist-info → esphome-2025.7.0b2.dist-info}/top_level.txt +0 -0
@@ -6,73 +6,67 @@
6
6
  namespace esphome {
7
7
  namespace api {
8
8
 
9
+ // Generate entity handler implementations using macros
9
10
  #ifdef USE_BINARY_SENSOR
10
- bool InitialStateIterator::on_binary_sensor(binary_sensor::BinarySensor *binary_sensor) {
11
- return this->client_->send_binary_sensor_state(binary_sensor);
12
- }
11
+ INITIAL_STATE_HANDLER(binary_sensor, binary_sensor::BinarySensor)
13
12
  #endif
14
13
  #ifdef USE_COVER
15
- bool InitialStateIterator::on_cover(cover::Cover *cover) { return this->client_->send_cover_state(cover); }
14
+ INITIAL_STATE_HANDLER(cover, cover::Cover)
16
15
  #endif
17
16
  #ifdef USE_FAN
18
- bool InitialStateIterator::on_fan(fan::Fan *fan) { return this->client_->send_fan_state(fan); }
17
+ INITIAL_STATE_HANDLER(fan, fan::Fan)
19
18
  #endif
20
19
  #ifdef USE_LIGHT
21
- bool InitialStateIterator::on_light(light::LightState *light) { return this->client_->send_light_state(light); }
20
+ INITIAL_STATE_HANDLER(light, light::LightState)
22
21
  #endif
23
22
  #ifdef USE_SENSOR
24
- bool InitialStateIterator::on_sensor(sensor::Sensor *sensor) { return this->client_->send_sensor_state(sensor); }
23
+ INITIAL_STATE_HANDLER(sensor, sensor::Sensor)
25
24
  #endif
26
25
  #ifdef USE_SWITCH
27
- bool InitialStateIterator::on_switch(switch_::Switch *a_switch) { return this->client_->send_switch_state(a_switch); }
26
+ INITIAL_STATE_HANDLER(switch, switch_::Switch)
28
27
  #endif
29
28
  #ifdef USE_TEXT_SENSOR
30
- bool InitialStateIterator::on_text_sensor(text_sensor::TextSensor *text_sensor) {
31
- return this->client_->send_text_sensor_state(text_sensor);
32
- }
29
+ INITIAL_STATE_HANDLER(text_sensor, text_sensor::TextSensor)
33
30
  #endif
34
31
  #ifdef USE_CLIMATE
35
- bool InitialStateIterator::on_climate(climate::Climate *climate) { return this->client_->send_climate_state(climate); }
32
+ INITIAL_STATE_HANDLER(climate, climate::Climate)
36
33
  #endif
37
34
  #ifdef USE_NUMBER
38
- bool InitialStateIterator::on_number(number::Number *number) { return this->client_->send_number_state(number); }
35
+ INITIAL_STATE_HANDLER(number, number::Number)
39
36
  #endif
40
37
  #ifdef USE_DATETIME_DATE
41
- bool InitialStateIterator::on_date(datetime::DateEntity *date) { return this->client_->send_date_state(date); }
38
+ INITIAL_STATE_HANDLER(date, datetime::DateEntity)
42
39
  #endif
43
40
  #ifdef USE_DATETIME_TIME
44
- bool InitialStateIterator::on_time(datetime::TimeEntity *time) { return this->client_->send_time_state(time); }
41
+ INITIAL_STATE_HANDLER(time, datetime::TimeEntity)
45
42
  #endif
46
43
  #ifdef USE_DATETIME_DATETIME
47
- bool InitialStateIterator::on_datetime(datetime::DateTimeEntity *datetime) {
48
- return this->client_->send_datetime_state(datetime);
49
- }
44
+ INITIAL_STATE_HANDLER(datetime, datetime::DateTimeEntity)
50
45
  #endif
51
46
  #ifdef USE_TEXT
52
- bool InitialStateIterator::on_text(text::Text *text) { return this->client_->send_text_state(text); }
47
+ INITIAL_STATE_HANDLER(text, text::Text)
53
48
  #endif
54
49
  #ifdef USE_SELECT
55
- bool InitialStateIterator::on_select(select::Select *select) { return this->client_->send_select_state(select); }
50
+ INITIAL_STATE_HANDLER(select, select::Select)
56
51
  #endif
57
52
  #ifdef USE_LOCK
58
- bool InitialStateIterator::on_lock(lock::Lock *a_lock) { return this->client_->send_lock_state(a_lock); }
53
+ INITIAL_STATE_HANDLER(lock, lock::Lock)
59
54
  #endif
60
55
  #ifdef USE_VALVE
61
- bool InitialStateIterator::on_valve(valve::Valve *valve) { return this->client_->send_valve_state(valve); }
56
+ INITIAL_STATE_HANDLER(valve, valve::Valve)
62
57
  #endif
63
58
  #ifdef USE_MEDIA_PLAYER
64
- bool InitialStateIterator::on_media_player(media_player::MediaPlayer *media_player) {
65
- return this->client_->send_media_player_state(media_player);
66
- }
59
+ INITIAL_STATE_HANDLER(media_player, media_player::MediaPlayer)
67
60
  #endif
68
61
  #ifdef USE_ALARM_CONTROL_PANEL
69
- bool InitialStateIterator::on_alarm_control_panel(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
70
- return this->client_->send_alarm_control_panel_state(a_alarm_control_panel);
71
- }
62
+ INITIAL_STATE_HANDLER(alarm_control_panel, alarm_control_panel::AlarmControlPanel)
72
63
  #endif
73
64
  #ifdef USE_UPDATE
74
- bool InitialStateIterator::on_update(update::UpdateEntity *update) { return this->client_->send_update_state(update); }
65
+ INITIAL_STATE_HANDLER(update, update::UpdateEntity)
75
66
  #endif
67
+
68
+ // Special cases (button and event) are already defined inline in subscribe_state.h
69
+
76
70
  InitialStateIterator::InitialStateIterator(APIConnection *client) : client_(client) {}
77
71
 
78
72
  } // namespace api
@@ -10,71 +10,78 @@ namespace api {
10
10
 
11
11
  class APIConnection;
12
12
 
13
+ // Macro for generating InitialStateIterator handlers
14
+ // Calls send_*_state
15
+ #define INITIAL_STATE_HANDLER(entity_type, EntityClass) \
16
+ bool InitialStateIterator::on_##entity_type(EntityClass *entity) { /* NOLINT(bugprone-macro-parentheses) */ \
17
+ return this->client_->send_##entity_type##_state(entity); \
18
+ }
19
+
13
20
  class InitialStateIterator : public ComponentIterator {
14
21
  public:
15
22
  InitialStateIterator(APIConnection *client);
16
23
  #ifdef USE_BINARY_SENSOR
17
- bool on_binary_sensor(binary_sensor::BinarySensor *binary_sensor) override;
24
+ bool on_binary_sensor(binary_sensor::BinarySensor *entity) override;
18
25
  #endif
19
26
  #ifdef USE_COVER
20
- bool on_cover(cover::Cover *cover) override;
27
+ bool on_cover(cover::Cover *entity) override;
21
28
  #endif
22
29
  #ifdef USE_FAN
23
- bool on_fan(fan::Fan *fan) override;
30
+ bool on_fan(fan::Fan *entity) override;
24
31
  #endif
25
32
  #ifdef USE_LIGHT
26
- bool on_light(light::LightState *light) override;
33
+ bool on_light(light::LightState *entity) override;
27
34
  #endif
28
35
  #ifdef USE_SENSOR
29
- bool on_sensor(sensor::Sensor *sensor) override;
36
+ bool on_sensor(sensor::Sensor *entity) override;
30
37
  #endif
31
38
  #ifdef USE_SWITCH
32
- bool on_switch(switch_::Switch *a_switch) override;
39
+ bool on_switch(switch_::Switch *entity) override;
33
40
  #endif
34
41
  #ifdef USE_BUTTON
35
42
  bool on_button(button::Button *button) override { return true; };
36
43
  #endif
37
44
  #ifdef USE_TEXT_SENSOR
38
- bool on_text_sensor(text_sensor::TextSensor *text_sensor) override;
45
+ bool on_text_sensor(text_sensor::TextSensor *entity) override;
39
46
  #endif
40
47
  #ifdef USE_CLIMATE
41
- bool on_climate(climate::Climate *climate) override;
48
+ bool on_climate(climate::Climate *entity) override;
42
49
  #endif
43
50
  #ifdef USE_NUMBER
44
- bool on_number(number::Number *number) override;
51
+ bool on_number(number::Number *entity) override;
45
52
  #endif
46
53
  #ifdef USE_DATETIME_DATE
47
- bool on_date(datetime::DateEntity *date) override;
54
+ bool on_date(datetime::DateEntity *entity) override;
48
55
  #endif
49
56
  #ifdef USE_DATETIME_TIME
50
- bool on_time(datetime::TimeEntity *time) override;
57
+ bool on_time(datetime::TimeEntity *entity) override;
51
58
  #endif
52
59
  #ifdef USE_DATETIME_DATETIME
53
- bool on_datetime(datetime::DateTimeEntity *datetime) override;
60
+ bool on_datetime(datetime::DateTimeEntity *entity) override;
54
61
  #endif
55
62
  #ifdef USE_TEXT
56
- bool on_text(text::Text *text) override;
63
+ bool on_text(text::Text *entity) override;
57
64
  #endif
58
65
  #ifdef USE_SELECT
59
- bool on_select(select::Select *select) override;
66
+ bool on_select(select::Select *entity) override;
60
67
  #endif
61
68
  #ifdef USE_LOCK
62
- bool on_lock(lock::Lock *a_lock) override;
69
+ bool on_lock(lock::Lock *entity) override;
63
70
  #endif
64
71
  #ifdef USE_VALVE
65
- bool on_valve(valve::Valve *valve) override;
72
+ bool on_valve(valve::Valve *entity) override;
66
73
  #endif
67
74
  #ifdef USE_MEDIA_PLAYER
68
- bool on_media_player(media_player::MediaPlayer *media_player) override;
75
+ bool on_media_player(media_player::MediaPlayer *entity) override;
69
76
  #endif
70
77
  #ifdef USE_ALARM_CONTROL_PANEL
71
- bool on_alarm_control_panel(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) override;
78
+ bool on_alarm_control_panel(alarm_control_panel::AlarmControlPanel *entity) override;
72
79
  #endif
73
80
  #ifdef USE_EVENT
74
81
  bool on_event(event::Event *event) override { return true; };
75
82
  #endif
76
83
  #ifdef USE_UPDATE
77
- bool on_update(update::UpdateEntity *update) override;
84
+ bool on_update(update::UpdateEntity *entity) override;
78
85
  #endif
79
86
  bool completed() { return this->state_ == IteratorState::NONE; }
80
87
 
@@ -7,6 +7,7 @@
7
7
  #include "esphome/core/automation.h"
8
8
  #include "api_pb2.h"
9
9
 
10
+ #ifdef USE_API_SERVICES
10
11
  namespace esphome {
11
12
  namespace api {
12
13
 
@@ -73,3 +74,4 @@ template<typename... Ts> class UserServiceTrigger : public UserServiceBase<Ts...
73
74
 
74
75
  } // namespace api
75
76
  } // namespace esphome
77
+ #endif // USE_API_SERVICES
@@ -50,7 +50,6 @@ class AS5600Component : public Component, public i2c::I2CDevice {
50
50
  void setup() override;
51
51
  void dump_config() override;
52
52
  /// HARDWARE_LATE setup priority
53
- float get_setup_priority() const override { return setup_priority::DATA; }
54
53
 
55
54
  // configuration setters
56
55
  void set_dir_pin(InternalGPIOPin *pin) { this->dir_pin_ = pin; }
@@ -5,6 +5,7 @@ from esphome.const import (
5
5
  PLATFORM_BK72XX,
6
6
  PLATFORM_ESP32,
7
7
  PLATFORM_ESP8266,
8
+ PLATFORM_LN882X,
8
9
  PLATFORM_RTL87XX,
9
10
  )
10
11
  from esphome.core import CORE, coroutine_with_priority
@@ -14,15 +15,23 @@ CODEOWNERS = ["@OttoWinter"]
14
15
  CONFIG_SCHEMA = cv.All(
15
16
  cv.Schema({}),
16
17
  cv.only_with_arduino,
17
- cv.only_on([PLATFORM_ESP32, PLATFORM_ESP8266, PLATFORM_BK72XX, PLATFORM_RTL87XX]),
18
+ cv.only_on(
19
+ [
20
+ PLATFORM_ESP32,
21
+ PLATFORM_ESP8266,
22
+ PLATFORM_BK72XX,
23
+ PLATFORM_LN882X,
24
+ PLATFORM_RTL87XX,
25
+ ]
26
+ ),
18
27
  )
19
28
 
20
29
 
21
30
  @coroutine_with_priority(200.0)
22
31
  async def to_code(config):
23
32
  if CORE.is_esp32 or CORE.is_libretiny:
24
- # https://github.com/esphome/AsyncTCP/blob/master/library.json
25
- cg.add_library("esphome/AsyncTCP-esphome", "2.1.4")
33
+ # https://github.com/ESP32Async/AsyncTCP
34
+ cg.add_library("ESP32Async/AsyncTCP", "3.4.4")
26
35
  elif CORE.is_esp8266:
27
- # https://github.com/esphome/ESPAsyncTCP
28
- cg.add_library("esphome/ESPAsyncTCP-esphome", "2.0.0")
36
+ # https://github.com/ESP32Async/ESPAsyncTCP
37
+ cg.add_library("ESP32Async/ESPAsyncTCP", "2.0.0")
@@ -25,7 +25,6 @@ class ATCMiThermometer : public Component, public esp32_ble_tracker::ESPBTDevice
25
25
 
26
26
  bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override;
27
27
  void dump_config() override;
28
- float get_setup_priority() const override { return setup_priority::DATA; }
29
28
  void set_temperature(sensor::Sensor *temperature) { temperature_ = temperature; }
30
29
  void set_humidity(sensor::Sensor *humidity) { humidity_ = humidity; }
31
30
  void set_battery_level(sensor::Sensor *battery_level) { battery_level_ = battery_level; }
@@ -1,6 +1,7 @@
1
1
  #include "atm90e32.h"
2
2
  #include <cinttypes>
3
3
  #include <cmath>
4
+ #include <numbers>
4
5
  #include "esphome/core/log.h"
5
6
 
6
7
  namespace esphome {
@@ -848,7 +849,7 @@ uint16_t ATM90E32Component::calculate_voltage_threshold(int line_freq, uint16_t
848
849
  float nominal_voltage = (line_freq == 60) ? 120.0f : 220.0f;
849
850
  float target_voltage = nominal_voltage * multiplier;
850
851
 
851
- float peak_01v = target_voltage * 100.0f * std::sqrt(2.0f); // convert RMS → peak, scale to 0.01V
852
+ float peak_01v = target_voltage * 100.0f * std::numbers::sqrt2_v<float>; // convert RMS → peak, scale to 0.01V
852
853
  float divider = (2.0f * ugain) / 32768.0f;
853
854
 
854
855
  float threshold = peak_01v / divider;
@@ -312,7 +312,7 @@ FileDecoderState AudioDecoder::decode_mp3_() {
312
312
  if (err) {
313
313
  switch (err) {
314
314
  case esp_audio_libs::helix_decoder::ERR_MP3_OUT_OF_MEMORY:
315
- // Intentional fallthrough
315
+ [[fallthrough]];
316
316
  case esp_audio_libs::helix_decoder::ERR_MP3_NULL_POINTER:
317
317
  return FileDecoderState::FAILED;
318
318
  break;
@@ -86,7 +86,7 @@ bool AudioTransferBuffer::reallocate(size_t new_buffer_size) {
86
86
  bool AudioTransferBuffer::allocate_buffer_(size_t buffer_size) {
87
87
  this->buffer_size_ = buffer_size;
88
88
 
89
- RAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
89
+ RAMAllocator<uint8_t> allocator;
90
90
 
91
91
  this->buffer_ = allocator.allocate(this->buffer_size_);
92
92
  if (this->buffer_ == nullptr) {
@@ -101,7 +101,7 @@ bool AudioTransferBuffer::allocate_buffer_(size_t buffer_size) {
101
101
 
102
102
  void AudioTransferBuffer::deallocate_buffer_() {
103
103
  if (this->buffer_ != nullptr) {
104
- RAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
104
+ RAMAllocator<uint8_t> allocator;
105
105
  allocator.deallocate(this->buffer_, this->buffer_size_);
106
106
  this->buffer_ = nullptr;
107
107
  this->data_start_ = nullptr;
@@ -16,7 +16,6 @@ class BParasite : public Component, public esp32_ble_tracker::ESPBTDeviceListene
16
16
 
17
17
  bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override;
18
18
  void dump_config() override;
19
- float get_setup_priority() const override { return setup_priority::DATA; }
20
19
 
21
20
  void set_battery_voltage(sensor::Sensor *battery_voltage) { battery_voltage_ = battery_voltage; }
22
21
  void set_temperature(sensor::Sensor *temperature) { temperature_ = temperature; }
@@ -480,7 +480,11 @@ void BedJetHub::set_clock(uint8_t hour, uint8_t minute) {
480
480
 
481
481
  /* Internal */
482
482
 
483
- void BedJetHub::loop() {}
483
+ void BedJetHub::loop() {
484
+ // Parent BLEClientNode has a loop() method, but this component uses
485
+ // polling via update() and BLE callbacks so loop isn't needed
486
+ this->disable_loop();
487
+ }
484
488
  void BedJetHub::update() { this->dispatch_status_(); }
485
489
 
486
490
  void BedJetHub::dump_config() {
@@ -83,7 +83,11 @@ void BedJetClimate::reset_state_() {
83
83
  this->publish_state();
84
84
  }
85
85
 
86
- void BedJetClimate::loop() {}
86
+ void BedJetClimate::loop() {
87
+ // This component is controlled via the parent BedJetHub
88
+ // Empty loop not needed, disable to save CPU cycles
89
+ this->disable_loop();
90
+ }
87
91
 
88
92
  void BedJetClimate::control(const ClimateCall &call) {
89
93
  ESP_LOGD(TAG, "Received BedJetClimate::control");
@@ -7,11 +7,13 @@
7
7
 
8
8
  extern "C" {
9
9
  #include "rtos_pub.h"
10
- #include "spi.h"
10
+ // rtos_pub.h must be included before the rest of the includes
11
+
11
12
  #include "arm_arch.h"
12
13
  #include "general_dma_pub.h"
13
14
  #include "gpio_pub.h"
14
15
  #include "icu_pub.h"
16
+ #include "spi.h"
15
17
  #undef SPI_DAT
16
18
  #undef SPI_BASE
17
19
  };
@@ -124,7 +126,7 @@ void BekenSPILEDStripLightOutput::setup() {
124
126
  size_t buffer_size = this->get_buffer_size_();
125
127
  size_t dma_buffer_size = (buffer_size * 8) + (2 * 64);
126
128
 
127
- ExternalRAMAllocator<uint8_t> allocator(ExternalRAMAllocator<uint8_t>::ALLOW_FAILURE);
129
+ RAMAllocator<uint8_t> allocator;
128
130
  this->buf_ = allocator.allocate(buffer_size);
129
131
  if (this->buf_ == nullptr) {
130
132
  ESP_LOGE(TAG, "Cannot allocate LED buffer!");
@@ -50,7 +50,7 @@ void BH1750Sensor::read_lx_(BH1750Mode mode, uint8_t mtreg, const std::function<
50
50
  // turn on (after one-shot sensor automatically powers down)
51
51
  uint8_t turn_on = BH1750_COMMAND_POWER_ON;
52
52
  if (this->write(&turn_on, 1) != i2c::ERROR_OK) {
53
- ESP_LOGW(TAG, "Turning on BH1750 failed");
53
+ ESP_LOGW(TAG, "Power on failed");
54
54
  f(NAN);
55
55
  return;
56
56
  }
@@ -60,7 +60,7 @@ void BH1750Sensor::read_lx_(BH1750Mode mode, uint8_t mtreg, const std::function<
60
60
  uint8_t mtreg_hi = BH1750_COMMAND_MT_REG_HI | ((mtreg >> 5) & 0b111);
61
61
  uint8_t mtreg_lo = BH1750_COMMAND_MT_REG_LO | ((mtreg >> 0) & 0b11111);
62
62
  if (this->write(&mtreg_hi, 1) != i2c::ERROR_OK || this->write(&mtreg_lo, 1) != i2c::ERROR_OK) {
63
- ESP_LOGW(TAG, "Setting measurement time for BH1750 failed");
63
+ ESP_LOGW(TAG, "Set measurement time failed");
64
64
  active_mtreg_ = 0;
65
65
  f(NAN);
66
66
  return;
@@ -88,7 +88,7 @@ void BH1750Sensor::read_lx_(BH1750Mode mode, uint8_t mtreg, const std::function<
88
88
  return;
89
89
  }
90
90
  if (this->write(&cmd, 1) != i2c::ERROR_OK) {
91
- ESP_LOGW(TAG, "Starting measurement for BH1750 failed");
91
+ ESP_LOGW(TAG, "Start measurement failed");
92
92
  f(NAN);
93
93
  return;
94
94
  }
@@ -99,7 +99,7 @@ void BH1750Sensor::read_lx_(BH1750Mode mode, uint8_t mtreg, const std::function<
99
99
  this->set_timeout("read", meas_time, [this, mode, mtreg, f]() {
100
100
  uint16_t raw_value;
101
101
  if (this->read(reinterpret_cast<uint8_t *>(&raw_value), 2) != i2c::ERROR_OK) {
102
- ESP_LOGW(TAG, "Reading BH1750 data failed");
102
+ ESP_LOGW(TAG, "Read data failed");
103
103
  f(NAN);
104
104
  return;
105
105
  }
@@ -156,7 +156,7 @@ void BH1750Sensor::update() {
156
156
  this->publish_state(NAN);
157
157
  return;
158
158
  }
159
- ESP_LOGD(TAG, "'%s': Got illuminance=%.1flx", this->get_name().c_str(), val);
159
+ ESP_LOGD(TAG, "'%s': Illuminance=%.1flx", this->get_name().c_str(), val);
160
160
  this->status_clear_warning();
161
161
  this->publish_state(val);
162
162
  });
@@ -1,7 +1,10 @@
1
+ from logging import getLogger
2
+
1
3
  from esphome import automation, core
2
4
  from esphome.automation import Condition, maybe_simple_id
3
5
  import esphome.codegen as cg
4
6
  from esphome.components import mqtt, web_server
7
+ from esphome.components.const import CONF_ON_STATE_CHANGE
5
8
  import esphome.config_validation as cv
6
9
  from esphome.const import (
7
10
  CONF_DELAY,
@@ -57,8 +60,8 @@ from esphome.const import (
57
60
  DEVICE_CLASS_WINDOW,
58
61
  )
59
62
  from esphome.core import CORE, coroutine_with_priority
63
+ from esphome.core.entity_helpers import entity_duplicate_validator, setup_entity
60
64
  from esphome.cpp_generator import MockObjClass
61
- from esphome.cpp_helpers import setup_entity
62
65
  from esphome.util import Registry
63
66
 
64
67
  CODEOWNERS = ["@esphome/core"]
@@ -98,6 +101,7 @@ IS_PLATFORM_COMPONENT = True
98
101
 
99
102
  CONF_TIME_OFF = "time_off"
100
103
  CONF_TIME_ON = "time_on"
104
+ CONF_TRIGGER_ON_INITIAL_STATE = "trigger_on_initial_state"
101
105
 
102
106
  DEFAULT_DELAY = "1s"
103
107
  DEFAULT_TIME_OFF = "100ms"
@@ -127,15 +131,24 @@ MultiClickTriggerEvent = binary_sensor_ns.struct("MultiClickTriggerEvent")
127
131
  StateTrigger = binary_sensor_ns.class_(
128
132
  "StateTrigger", automation.Trigger.template(bool)
129
133
  )
134
+ StateChangeTrigger = binary_sensor_ns.class_(
135
+ "StateChangeTrigger",
136
+ automation.Trigger.template(cg.optional.template(bool), cg.optional.template(bool)),
137
+ )
138
+
130
139
  BinarySensorPublishAction = binary_sensor_ns.class_(
131
140
  "BinarySensorPublishAction", automation.Action
132
141
  )
142
+ BinarySensorInvalidateAction = binary_sensor_ns.class_(
143
+ "BinarySensorInvalidateAction", automation.Action
144
+ )
133
145
 
134
146
  # Condition
135
147
  BinarySensorCondition = binary_sensor_ns.class_("BinarySensorCondition", Condition)
136
148
 
137
149
  # Filters
138
150
  Filter = binary_sensor_ns.class_("Filter")
151
+ TimeoutFilter = binary_sensor_ns.class_("TimeoutFilter", Filter, cg.Component)
139
152
  DelayedOnOffFilter = binary_sensor_ns.class_("DelayedOnOffFilter", Filter, cg.Component)
140
153
  DelayedOnFilter = binary_sensor_ns.class_("DelayedOnFilter", Filter, cg.Component)
141
154
  DelayedOffFilter = binary_sensor_ns.class_("DelayedOffFilter", Filter, cg.Component)
@@ -144,6 +157,8 @@ AutorepeatFilter = binary_sensor_ns.class_("AutorepeatFilter", Filter, cg.Compon
144
157
  LambdaFilter = binary_sensor_ns.class_("LambdaFilter", Filter)
145
158
  SettleFilter = binary_sensor_ns.class_("SettleFilter", Filter, cg.Component)
146
159
 
160
+ _LOGGER = getLogger(__name__)
161
+
147
162
  FILTER_REGISTRY = Registry()
148
163
  validate_filters = cv.validate_registry("filter", FILTER_REGISTRY)
149
164
 
@@ -157,6 +172,19 @@ async def invert_filter_to_code(config, filter_id):
157
172
  return cg.new_Pvariable(filter_id)
158
173
 
159
174
 
175
+ @register_filter(
176
+ "timeout",
177
+ TimeoutFilter,
178
+ cv.templatable(cv.positive_time_period_milliseconds),
179
+ )
180
+ async def timeout_filter_to_code(config, filter_id):
181
+ var = cg.new_Pvariable(filter_id)
182
+ await cg.register_component(var, {})
183
+ template_ = await cg.templatable(config, [], cg.uint32)
184
+ cg.add(var.set_timeout_value(template_))
185
+ return var
186
+
187
+
160
188
  @register_filter(
161
189
  "delayed_on_off",
162
190
  DelayedOnOffFilter,
@@ -386,6 +414,14 @@ def validate_click_timing(value):
386
414
  return value
387
415
 
388
416
 
417
+ def validate_publish_initial_state(value):
418
+ value = cv.boolean(value)
419
+ _LOGGER.warning(
420
+ "The 'publish_initial_state' option has been replaced by 'trigger_on_initial_state' and will be removed in a future release"
421
+ )
422
+ return value
423
+
424
+
389
425
  _BINARY_SENSOR_SCHEMA = (
390
426
  cv.ENTITY_BASE_SCHEMA.extend(web_server.WEBSERVER_SORTING_SCHEMA)
391
427
  .extend(cv.MQTT_COMPONENT_SCHEMA)
@@ -395,7 +431,12 @@ _BINARY_SENSOR_SCHEMA = (
395
431
  cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(
396
432
  mqtt.MQTTBinarySensorComponent
397
433
  ),
398
- cv.Optional(CONF_PUBLISH_INITIAL_STATE): cv.boolean,
434
+ cv.Exclusive(
435
+ CONF_PUBLISH_INITIAL_STATE, CONF_TRIGGER_ON_INITIAL_STATE
436
+ ): validate_publish_initial_state,
437
+ cv.Exclusive(
438
+ CONF_TRIGGER_ON_INITIAL_STATE, CONF_TRIGGER_ON_INITIAL_STATE
439
+ ): cv.boolean,
399
440
  cv.Optional(CONF_DEVICE_CLASS): validate_device_class,
400
441
  cv.Optional(CONF_FILTERS): validate_filters,
401
442
  cv.Optional(CONF_ON_PRESS): automation.validate_automation(
@@ -454,11 +495,19 @@ _BINARY_SENSOR_SCHEMA = (
454
495
  cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StateTrigger),
455
496
  }
456
497
  ),
498
+ cv.Optional(CONF_ON_STATE_CHANGE): automation.validate_automation(
499
+ {
500
+ cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StateChangeTrigger),
501
+ }
502
+ ),
457
503
  }
458
504
  )
459
505
  )
460
506
 
461
507
 
508
+ _BINARY_SENSOR_SCHEMA.add_extra(entity_duplicate_validator("binary_sensor"))
509
+
510
+
462
511
  def binary_sensor_schema(
463
512
  class_: MockObjClass = cv.UNDEFINED,
464
513
  *,
@@ -489,12 +538,14 @@ BINARY_SENSOR_SCHEMA.add_extra(cv.deprecated_schema_constant("binary_sensor"))
489
538
 
490
539
 
491
540
  async def setup_binary_sensor_core_(var, config):
492
- await setup_entity(var, config)
541
+ await setup_entity(var, config, "binary_sensor")
493
542
 
494
543
  if (device_class := config.get(CONF_DEVICE_CLASS)) is not None:
495
544
  cg.add(var.set_device_class(device_class))
496
- if publish_initial_state := config.get(CONF_PUBLISH_INITIAL_STATE):
497
- cg.add(var.set_publish_initial_state(publish_initial_state))
545
+ trigger = config.get(CONF_TRIGGER_ON_INITIAL_STATE, False) or config.get(
546
+ CONF_PUBLISH_INITIAL_STATE, False
547
+ )
548
+ cg.add(var.set_trigger_on_initial_state(trigger))
498
549
  if inverted := config.get(CONF_INVERTED):
499
550
  cg.add(var.set_inverted(inverted))
500
551
  if filters_config := config.get(CONF_FILTERS):
@@ -542,6 +593,17 @@ async def setup_binary_sensor_core_(var, config):
542
593
  trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
543
594
  await automation.build_automation(trigger, [(bool, "x")], conf)
544
595
 
596
+ for conf in config.get(CONF_ON_STATE_CHANGE, []):
597
+ trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
598
+ await automation.build_automation(
599
+ trigger,
600
+ [
601
+ (cg.optional.template(bool), "x_previous"),
602
+ (cg.optional.template(bool), "x"),
603
+ ],
604
+ conf,
605
+ )
606
+
545
607
  if mqtt_id := config.get(CONF_MQTT_ID):
546
608
  mqtt_ = cg.new_Pvariable(mqtt_id, var)
547
609
  await mqtt.register_mqtt_component(mqtt_, config)
@@ -591,3 +653,18 @@ async def binary_sensor_is_off_to_code(config, condition_id, template_arg, args)
591
653
  async def to_code(config):
592
654
  cg.add_define("USE_BINARY_SENSOR")
593
655
  cg.add_global(binary_sensor_ns.using)
656
+
657
+
658
+ @automation.register_action(
659
+ "binary_sensor.invalidate_state",
660
+ BinarySensorInvalidateAction,
661
+ cv.maybe_simple_value(
662
+ {
663
+ cv.Required(CONF_ID): cv.use_id(BinarySensor),
664
+ },
665
+ key=CONF_ID,
666
+ ),
667
+ )
668
+ async def binary_sensor_invalidate_state_to_code(config, action_id, template_arg, args):
669
+ paren = await cg.get_variable(config[CONF_ID])
670
+ return cg.new_Pvariable(action_id, template_arg, paren)
@@ -96,7 +96,7 @@ class MultiClickTrigger : public Trigger<>, public Component {
96
96
  : parent_(parent), timing_(std::move(timing)) {}
97
97
 
98
98
  void setup() override {
99
- this->last_state_ = this->parent_->state;
99
+ this->last_state_ = this->parent_->get_state_default(false);
100
100
  auto f = std::bind(&MultiClickTrigger::on_state_, this, std::placeholders::_1);
101
101
  this->parent_->add_on_state_callback(f);
102
102
  }
@@ -130,6 +130,14 @@ class StateTrigger : public Trigger<bool> {
130
130
  }
131
131
  };
132
132
 
133
+ class StateChangeTrigger : public Trigger<optional<bool>, optional<bool> > {
134
+ public:
135
+ explicit StateChangeTrigger(BinarySensor *parent) {
136
+ parent->add_full_state_callback(
137
+ [this](optional<bool> old_state, optional<bool> state) { this->trigger(old_state, state); });
138
+ }
139
+ };
140
+
133
141
  template<typename... Ts> class BinarySensorCondition : public Condition<Ts...> {
134
142
  public:
135
143
  BinarySensorCondition(BinarySensor *parent, bool state) : parent_(parent), state_(state) {}
@@ -154,5 +162,15 @@ template<typename... Ts> class BinarySensorPublishAction : public Action<Ts...>
154
162
  BinarySensor *sensor_;
155
163
  };
156
164
 
165
+ template<typename... Ts> class BinarySensorInvalidateAction : public Action<Ts...> {
166
+ public:
167
+ explicit BinarySensorInvalidateAction(BinarySensor *sensor) : sensor_(sensor) {}
168
+
169
+ void play(Ts... x) override { this->sensor_->invalidate_state(); }
170
+
171
+ protected:
172
+ BinarySensor *sensor_;
173
+ };
174
+
157
175
  } // namespace binary_sensor
158
176
  } // namespace esphome