esphome 2025.6.2__py3-none-any.whl → 2025.7.0b1__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.
- esphome/__main__.py +1 -3
- esphome/codegen.py +2 -0
- esphome/components/ac_dimmer/ac_dimmer.cpp +6 -6
- esphome/components/adc/__init__.py +25 -1
- esphome/components/adc/adc_sensor.h +11 -11
- esphome/components/adc/adc_sensor_common.cpp +1 -1
- esphome/components/adc/adc_sensor_esp32.cpp +16 -8
- esphome/components/ade7880/ade7880.h +0 -2
- esphome/components/ads1115/ads1115.h +0 -1
- esphome/components/ads1118/ads1118.h +0 -1
- esphome/components/ags10/ags10.h +0 -2
- esphome/components/aic3204/aic3204.h +0 -1
- esphome/components/alarm_control_panel/__init__.py +5 -2
- esphome/components/alpha3/alpha3.h +0 -1
- esphome/components/am43/cover/am43_cover.h +0 -1
- esphome/components/am43/sensor/am43_sensor.h +0 -1
- esphome/components/analog_threshold/analog_threshold_binary_sensor.h +0 -2
- esphome/components/anova/anova.cpp +5 -1
- esphome/components/anova/anova.h +0 -1
- esphome/components/apds9960/apds9960.cpp +1 -1
- esphome/components/api/__init__.py +42 -20
- esphome/components/api/api_connection.cpp +318 -391
- esphome/components/api/api_connection.h +206 -126
- esphome/components/api/api_frame_helper.cpp +89 -124
- esphome/components/api/api_frame_helper.h +57 -45
- esphome/components/api/api_pb2.cpp +414 -4350
- esphome/components/api/api_pb2.h +287 -198
- esphome/components/api/api_pb2_dump.cpp +4333 -0
- esphome/components/api/api_pb2_service.cpp +180 -425
- esphome/components/api/api_pb2_service.h +7 -6
- esphome/components/api/api_pb2_size.h +2 -4
- esphome/components/api/api_server.cpp +138 -167
- esphome/components/api/api_server.h +66 -12
- esphome/components/api/client.py +10 -4
- esphome/components/api/list_entities.cpp +36 -105
- esphome/components/api/list_entities.h +31 -23
- esphome/components/api/proto.h +26 -3
- esphome/components/api/subscribe_state.cpp +23 -29
- esphome/components/api/subscribe_state.h +26 -19
- esphome/components/as5600/as5600.h +0 -1
- esphome/components/async_tcp/__init__.py +14 -5
- esphome/components/atc_mithermometer/atc_mithermometer.h +0 -1
- esphome/components/atm90e32/atm90e32.cpp +2 -1
- esphome/components/audio/audio_decoder.cpp +1 -1
- esphome/components/audio/audio_transfer_buffer.cpp +2 -2
- esphome/components/b_parasite/b_parasite.h +0 -1
- esphome/components/bedjet/bedjet_hub.cpp +5 -1
- esphome/components/bedjet/climate/bedjet_climate.cpp +5 -1
- esphome/components/beken_spi_led_strip/led_strip.cpp +4 -2
- esphome/components/bh1750/bh1750.cpp +5 -5
- esphome/components/binary_sensor/__init__.py +82 -5
- esphome/components/binary_sensor/automation.h +19 -1
- esphome/components/binary_sensor/binary_sensor.cpp +12 -30
- esphome/components/binary_sensor/binary_sensor.h +11 -25
- esphome/components/binary_sensor/filter.cpp +29 -24
- esphome/components/binary_sensor/filter.h +20 -10
- esphome/components/ble_client/output/ble_binary_output.h +0 -1
- esphome/components/ble_client/sensor/ble_rssi_sensor.cpp +5 -1
- esphome/components/ble_client/sensor/ble_rssi_sensor.h +0 -1
- esphome/components/ble_client/sensor/ble_sensor.cpp +5 -1
- esphome/components/ble_client/sensor/ble_sensor.h +0 -1
- esphome/components/ble_client/switch/ble_switch.h +0 -1
- esphome/components/ble_client/text_sensor/ble_text_sensor.cpp +5 -1
- esphome/components/ble_client/text_sensor/ble_text_sensor.h +0 -1
- esphome/components/ble_presence/ble_presence_device.h +0 -1
- esphome/components/ble_rssi/ble_rssi_sensor.h +0 -1
- esphome/components/ble_scanner/ble_scanner.h +0 -1
- esphome/components/bluetooth_proxy/bluetooth_connection.h +9 -2
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +16 -6
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +8 -2
- esphome/components/bme680/sensor.py +1 -1
- esphome/components/bmp581/bmp581.h +0 -2
- esphome/components/button/__init__.py +5 -2
- esphome/components/camera/__init__.py +1 -0
- esphome/components/camera/camera.cpp +22 -0
- esphome/components/camera/camera.h +80 -0
- esphome/components/canbus/__init__.py +1 -0
- esphome/components/cap1188/cap1188.h +0 -1
- esphome/components/captive_portal/__init__.py +12 -2
- esphome/components/captive_portal/captive_portal.cpp +12 -2
- esphome/components/captive_portal/captive_portal.h +5 -2
- esphome/components/ccs811/ccs811.h +0 -2
- esphome/components/climate/__init__.py +5 -2
- esphome/components/cm1106/sensor.py +2 -2
- esphome/components/const/__init__.py +2 -0
- esphome/components/copy/binary_sensor/copy_binary_sensor.h +0 -1
- esphome/components/copy/button/copy_button.h +0 -1
- esphome/components/copy/cover/copy_cover.h +0 -1
- esphome/components/copy/fan/copy_fan.h +0 -1
- esphome/components/copy/lock/copy_lock.h +0 -1
- esphome/components/copy/number/copy_number.h +0 -1
- esphome/components/copy/select/copy_select.h +0 -1
- esphome/components/copy/sensor/copy_sensor.h +0 -1
- esphome/components/copy/switch/copy_switch.h +0 -1
- esphome/components/copy/text/copy_text.h +0 -1
- esphome/components/copy/text_sensor/copy_text_sensor.h +0 -1
- esphome/components/cover/__init__.py +5 -2
- esphome/components/cs5460a/cs5460a.h +0 -1
- esphome/components/datetime/__init__.py +4 -2
- esphome/components/debug/__init__.py +20 -0
- esphome/components/deep_sleep/__init__.py +43 -9
- esphome/components/demo/__init__.py +2 -2
- esphome/components/display/display.cpp +4 -3
- esphome/components/display/display.h +0 -2
- esphome/components/display/display_buffer.cpp +1 -1
- esphome/components/ds2484/__init__.py +1 -0
- esphome/components/ds2484/ds2484.cpp +209 -0
- esphome/components/ds2484/ds2484.h +43 -0
- esphome/components/ds2484/one_wire.py +37 -0
- esphome/components/duty_time/duty_time_sensor.h +0 -1
- esphome/components/ens160_base/ens160_base.h +0 -1
- esphome/components/es7210/es7210.h +0 -1
- esphome/components/es7243e/es7243e.h +0 -1
- esphome/components/es8156/es8156.h +0 -1
- esphome/components/es8311/es8311.h +0 -1
- esphome/components/es8388/es8388.h +0 -1
- esphome/components/esp32/__init__.py +102 -135
- esphome/components/esp32/core.cpp +0 -4
- esphome/components/esp32/gpio.h +1 -1
- esphome/components/esp32/helpers.cpp +69 -0
- esphome/components/esp32_ble/ble.cpp +5 -6
- esphome/components/esp32_ble/ble.h +29 -14
- esphome/components/esp32_ble/ble_event.h +6 -6
- esphome/components/esp32_ble_client/ble_client_base.cpp +21 -6
- esphome/components/esp32_ble_client/ble_client_base.h +24 -9
- esphome/components/esp32_ble_tracker/__init__.py +2 -8
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +5 -5
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +11 -7
- esphome/components/esp32_camera/__init__.py +111 -97
- esphome/components/esp32_camera/esp32_camera.cpp +41 -31
- esphome/components/esp32_camera/esp32_camera.h +35 -30
- esphome/components/esp32_camera_web_server/__init__.py +2 -1
- esphome/components/esp32_camera_web_server/camera_web_server.cpp +8 -8
- esphome/components/esp32_camera_web_server/camera_web_server.h +3 -3
- esphome/components/esp32_hall/sensor.py +2 -21
- esphome/components/esp32_hosted/__init__.py +101 -0
- esphome/components/esp32_hosted/esp32_hosted.py.script +12 -0
- esphome/components/esp32_improv/esp32_improv_component.cpp +3 -0
- esphome/components/esp32_rmt/__init__.py +0 -58
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +77 -63
- esphome/components/esp32_rmt_led_strip/led_strip.h +11 -17
- esphome/components/esp32_rmt_led_strip/light.py +14 -76
- esphome/components/esp32_touch/esp32_touch.h +174 -28
- esphome/components/esp32_touch/esp32_touch_common.cpp +162 -0
- esphome/components/esp32_touch/esp32_touch_v1.cpp +238 -0
- esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
- esphome/components/esp8266/__init__.py +1 -0
- esphome/components/esp8266/gpio.cpp +10 -10
- esphome/components/esp8266/helpers.cpp +31 -0
- esphome/components/esphome/ota/__init__.py +1 -0
- esphome/components/esphome/ota/ota_esphome.cpp +24 -19
- esphome/components/ethernet/__init__.py +42 -23
- esphome/components/ethernet/esp_eth_phy_jl1101.c +0 -16
- esphome/components/ethernet/ethernet_component.cpp +69 -29
- esphome/components/ethernet/ethernet_component.h +18 -10
- esphome/components/event/__init__.py +5 -2
- esphome/components/ezo/ezo.h +0 -1
- esphome/components/ezo_pmp/ezo_pmp.h +0 -1
- esphome/components/fan/__init__.py +5 -2
- esphome/components/feedback/feedback_cover.h +0 -1
- esphome/components/font/__init__.py +92 -82
- esphome/components/font/font.cpp +9 -2
- esphome/components/font/font.h +20 -5
- esphome/components/fs3000/fs3000.h +0 -1
- esphome/components/gcja5/gcja5.h +0 -1
- esphome/components/gl_r01_i2c/__init__.py +0 -0
- esphome/components/gl_r01_i2c/gl_r01_i2c.cpp +68 -0
- esphome/components/gl_r01_i2c/gl_r01_i2c.h +22 -0
- esphome/components/gl_r01_i2c/sensor.py +36 -0
- esphome/components/gp8403/gp8403.h +0 -1
- esphome/components/gpio/binary_sensor/__init__.py +17 -0
- esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +77 -3
- esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +40 -0
- esphome/components/grove_gas_mc_v2/grove_gas_mc_v2.h +0 -2
- esphome/components/he60r/he60r.h +0 -1
- esphome/components/heatpumpir/climate.py +2 -1
- esphome/components/heatpumpir/heatpumpir.cpp +1 -0
- esphome/components/heatpumpir/heatpumpir.h +1 -0
- esphome/components/honeywellabp2_i2c/honeywellabp2.h +0 -1
- esphome/components/host/__init__.py +2 -1
- esphome/components/host/helpers.cpp +57 -0
- esphome/components/http_request/__init__.py +19 -1
- esphome/components/http_request/http_request.h +1 -1
- esphome/components/http_request/http_request_arduino.cpp +0 -1
- esphome/components/http_request/http_request_arduino.h +1 -0
- esphome/components/http_request/http_request_idf.cpp +0 -1
- esphome/components/http_request/ota/ota_http_request.cpp +1 -1
- esphome/components/http_request/update/http_request_update.cpp +28 -9
- esphome/components/hydreon_rgxx/hydreon_rgxx.cpp +3 -9
- esphome/components/hydreon_rgxx/sensor.py +1 -1
- esphome/components/i2c/__init__.py +23 -11
- esphome/components/i2c/i2c_bus.h +8 -1
- esphome/components/i2c/i2c_bus_arduino.cpp +4 -3
- esphome/components/i2c/i2c_bus_arduino.h +6 -3
- esphome/components/i2c/i2c_bus_esp_idf.h +5 -3
- esphome/components/i2c_device/i2c_device.h +0 -1
- esphome/components/i2s_audio/__init__.py +2 -10
- esphome/components/i2s_audio/i2s_audio.cpp +1 -5
- esphome/components/i2s_audio/media_player/__init__.py +2 -2
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +2 -2
- esphome/components/iaqcore/iaqcore.h +0 -2
- esphome/components/image/__init__.py +123 -24
- esphome/components/improv_serial/improv_serial_component.cpp +0 -4
- esphome/components/ina219/ina219.cpp +7 -0
- esphome/components/ina219/ina219.h +1 -0
- esphome/components/ina260/ina260.h +0 -2
- esphome/components/inkbird_ibsth1_mini/inkbird_ibsth1_mini.h +0 -1
- esphome/components/inkplate6/display.py +15 -0
- esphome/components/inkplate6/inkplate.cpp +2 -2
- esphome/components/integration/integration_sensor.h +0 -1
- esphome/components/internal_temperature/internal_temperature.cpp +8 -27
- esphome/components/internal_temperature/sensor.py +0 -26
- esphome/components/interval/interval.h +0 -2
- esphome/components/ld2410/button/__init__.py +3 -3
- esphome/components/ld2410/button/factory_reset_button.cpp +9 -0
- esphome/components/ld2410/button/{reset_button.h → factory_reset_button.h} +2 -2
- esphome/components/ld2410/ld2410.cpp +430 -261
- esphome/components/ld2410/ld2410.h +44 -146
- esphome/components/ld2410/number/__init__.py +2 -2
- esphome/components/ld2410/sensor.py +1 -1
- esphome/components/ld2410/switch/__init__.py +1 -1
- esphome/components/ld2420/ld2420.cpp +196 -100
- esphome/components/ld2420/ld2420.h +46 -118
- esphome/components/ld2420/number/__init__.py +2 -2
- esphome/components/ld2420/sensor/__init__.py +6 -2
- esphome/components/ld2420/sensor/ld2420_sensor.h +1 -1
- esphome/components/ld2450/button/__init__.py +3 -3
- esphome/components/ld2450/button/factory_reset_button.cpp +9 -0
- esphome/components/ld2450/button/{reset_button.h → factory_reset_button.h} +2 -2
- esphome/components/ld2450/ld2450.cpp +384 -232
- esphome/components/ld2450/ld2450.h +60 -69
- esphome/components/ld2450/switch/__init__.py +1 -1
- esphome/components/ledc/ledc_output.cpp +1 -63
- esphome/components/libretiny/__init__.py +4 -3
- esphome/components/libretiny/const.py +5 -0
- esphome/components/libretiny/generate_components.py +1 -0
- esphome/components/libretiny/helpers.cpp +35 -0
- esphome/components/libretiny/lt_component.cpp +5 -3
- esphome/components/light/__init__.py +4 -2
- esphome/components/light/addressable_light.h +3 -3
- esphome/components/light/light_call.cpp +180 -243
- esphome/components/light/light_call.h +72 -20
- esphome/components/light/light_color_values.h +14 -14
- esphome/components/light/light_state.h +15 -13
- esphome/components/light/transformers.h +2 -2
- esphome/components/ln882x/__init__.py +52 -0
- esphome/components/ln882x/boards.py +285 -0
- esphome/components/lock/__init__.py +5 -2
- esphome/components/logger/__init__.py +40 -3
- esphome/components/logger/logger.cpp +47 -12
- esphome/components/logger/logger.h +80 -49
- esphome/components/logger/logger_esp32.cpp +3 -3
- esphome/components/lps22/__init__.py +0 -0
- esphome/components/lps22/lps22.cpp +75 -0
- esphome/components/lps22/lps22.h +27 -0
- esphome/components/lps22/sensor.py +58 -0
- esphome/components/ltr390/ltr390.h +0 -1
- esphome/components/ltr501/ltr501.h +0 -1
- esphome/components/ltr_als_ps/ltr_als_ps.h +0 -1
- esphome/components/lvgl/__init__.py +1 -1
- esphome/components/lvgl/schemas.py +66 -6
- esphome/components/lvgl/styles.py +24 -16
- esphome/components/lvgl/widgets/__init__.py +12 -2
- esphome/components/lvgl/widgets/lv_bar.py +40 -19
- esphome/components/m5stack_8angle/light/m5stack_8angle_light.cpp +1 -1
- esphome/components/max9611/max9611.h +0 -1
- esphome/components/mcp23016/__init__.py +1 -1
- esphome/components/mcp23xxx_base/__init__.py +1 -1
- esphome/components/mcp4461/__init__.py +1 -1
- esphome/components/mcp4461/output/__init__.py +3 -2
- esphome/components/mcp9600/mcp9600.h +0 -2
- esphome/components/md5/md5.cpp +3 -3
- esphome/components/md5/md5.h +1 -6
- esphome/components/mdns/__init__.py +22 -11
- esphome/components/media_player/__init__.py +4 -3
- esphome/components/micro_wake_word/__init__.py +1 -5
- esphome/components/micro_wake_word/streaming_model.cpp +2 -2
- esphome/components/microphone/microphone.cpp +7 -9
- esphome/components/microphone/microphone.h +0 -2
- esphome/components/mipi_spi/display.py +1 -0
- esphome/components/mmc5603/mmc5603.cpp +1 -1
- esphome/components/modbus/modbus.cpp +33 -15
- esphome/components/modbus/modbus.h +9 -0
- esphome/components/modbus_controller/__init__.py +42 -10
- esphome/components/modbus_controller/modbus_controller.cpp +92 -11
- esphome/components/modbus_controller/modbus_controller.h +61 -7
- esphome/components/mopeka_pro_check/mopeka_pro_check.h +0 -1
- esphome/components/mopeka_std_check/mopeka_std_check.h +0 -1
- esphome/components/mpl3115a2/mpl3115a2.h +0 -2
- esphome/components/mqtt/__init__.py +16 -0
- esphome/components/mqtt/mqtt_backend.h +2 -1
- esphome/components/mqtt/mqtt_backend_esp32.cpp +126 -45
- esphome/components/mqtt/mqtt_backend_esp32.h +106 -4
- esphome/components/mqtt/mqtt_client.cpp +15 -9
- esphome/components/mqtt/mqtt_client.h +8 -3
- esphome/components/ms8607/ms8607.h +0 -1
- esphome/components/neopixelbus/light.py +4 -1
- esphome/components/neopixelbus/neopixelbus_light.h +1 -1
- esphome/components/network/__init__.py +4 -1
- esphome/components/network/ip_address.h +1 -0
- esphome/components/nextion/__init__.py +16 -0
- esphome/components/nextion/base_component.py +1 -0
- esphome/components/nextion/binary_sensor/nextion_binarysensor.cpp +1 -1
- esphome/components/nextion/display.py +14 -4
- esphome/components/nextion/nextion.cpp +166 -101
- esphome/components/nextion/nextion.h +84 -53
- esphome/components/nextion/nextion_commands.cpp +11 -10
- esphome/components/nextion/nextion_component.cpp +28 -28
- esphome/components/nextion/nextion_component.h +53 -18
- esphome/components/nextion/nextion_component_base.h +3 -0
- esphome/components/nextion/nextion_upload.cpp +36 -0
- esphome/components/nextion/nextion_upload_arduino.cpp +10 -35
- esphome/components/nextion/nextion_upload_idf.cpp +9 -33
- esphome/components/nextion/sensor/nextion_sensor.cpp +1 -1
- esphome/components/nextion/switch/nextion_switch.cpp +1 -1
- esphome/components/nextion/text_sensor/nextion_textsensor.cpp +1 -1
- esphome/components/nfc/nfc.cpp +3 -22
- esphome/components/nfc/nfc.h +3 -3
- esphome/components/number/__init__.py +5 -2
- esphome/components/online_image/__init__.py +5 -0
- esphome/components/online_image/online_image.cpp +6 -2
- esphome/components/online_image/online_image.h +4 -1
- esphome/components/opentherm/opentherm.cpp +7 -12
- esphome/components/openthread/__init__.py +47 -40
- esphome/components/openthread/const.py +1 -0
- esphome/components/openthread/openthread_esp.cpp +27 -5
- esphome/components/opt3001/__init__.py +0 -0
- esphome/components/opt3001/opt3001.cpp +122 -0
- esphome/components/opt3001/opt3001.h +27 -0
- esphome/components/opt3001/sensor.py +35 -0
- esphome/components/ota/__init__.py +17 -0
- esphome/components/ota/ota_backend.h +27 -1
- esphome/components/ota/ota_backend_arduino_esp32.cpp +12 -2
- esphome/components/ota/ota_backend_arduino_esp32.h +3 -0
- esphome/components/ota/ota_backend_arduino_esp8266.cpp +18 -4
- esphome/components/ota/ota_backend_arduino_esp8266.h +3 -0
- esphome/components/ota/ota_backend_arduino_libretiny.cpp +12 -2
- esphome/components/ota/ota_backend_arduino_libretiny.h +3 -0
- esphome/components/ota/ota_backend_arduino_rp2040.cpp +9 -2
- esphome/components/ota/ota_backend_arduino_rp2040.h +3 -0
- esphome/components/ota/ota_backend_esp_idf.cpp +10 -16
- esphome/components/ota/ota_backend_esp_idf.h +1 -0
- esphome/components/packages/__init__.py +5 -2
- esphome/components/packet_transport/binary_sensor.py +61 -4
- esphome/components/packet_transport/packet_transport.cpp +31 -1
- esphome/components/packet_transport/packet_transport.h +11 -5
- esphome/components/pcf8574/__init__.py +1 -1
- esphome/components/pi4ioe5v6408/__init__.py +84 -0
- esphome/components/pi4ioe5v6408/pi4ioe5v6408.cpp +171 -0
- esphome/components/pi4ioe5v6408/pi4ioe5v6408.h +70 -0
- esphome/components/pmsa003i/pmsa003i.h +0 -1
- esphome/components/pmsx003/pmsx003.h +0 -1
- esphome/components/pn7150/pn7150.cpp +7 -7
- esphome/components/pn7150/pn7150.h +0 -1
- esphome/components/pn7160/pn7160.cpp +7 -7
- esphome/components/pn7160/pn7160.h +0 -1
- esphome/components/preferences/syncer.h +2 -0
- esphome/components/prometheus/prometheus_handler.h +1 -1
- esphome/components/psram/psram.cpp +0 -20
- esphome/components/pulse_counter/pulse_counter_sensor.h +0 -1
- esphome/components/pulse_meter/pulse_meter_sensor.cpp +8 -4
- esphome/components/pulse_width/pulse_width.h +0 -1
- esphome/components/pvvx_mithermometer/display/pvvx_display.cpp +0 -4
- esphome/components/pvvx_mithermometer/display/pvvx_display.h +0 -2
- esphome/components/pvvx_mithermometer/pvvx_mithermometer.h +0 -1
- esphome/components/qr_code/__init__.py +13 -10
- esphome/components/qwiic_pir/qwiic_pir.h +0 -1
- esphome/components/radon_eye_ble/radon_eye_listener.cpp +1 -1
- esphome/components/rc522/rc522.h +0 -1
- esphome/components/rdm6300/rdm6300.h +0 -2
- esphome/components/remote_base/__init__.py +7 -5
- esphome/components/remote_base/remote_base.cpp +24 -21
- esphome/components/remote_base/remote_base.h +3 -26
- esphome/components/remote_receiver/__init__.py +40 -46
- esphome/components/remote_receiver/remote_receiver.h +4 -18
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +0 -87
- esphome/components/remote_receiver/remote_receiver_esp8266.cpp +1 -1
- esphome/components/remote_transmitter/__init__.py +42 -43
- esphome/components/remote_transmitter/remote_transmitter.h +2 -14
- esphome/components/remote_transmitter/remote_transmitter_esp32.cpp +0 -77
- esphome/components/resistance/resistance_sensor.h +0 -1
- esphome/components/rp2040/__init__.py +1 -0
- esphome/components/rp2040/helpers.cpp +55 -0
- esphome/components/rp2040_pio_led_strip/led_strip.cpp +2 -2
- esphome/components/rpi_dpi_rgb/rpi_dpi_rgb.cpp +0 -4
- esphome/components/rtttl/__init__.py +4 -4
- esphome/components/rtttl/rtttl.cpp +10 -1
- esphome/components/ruuvitag/ruuvitag.h +0 -1
- esphome/components/safe_mode/safe_mode.cpp +2 -0
- esphome/components/safe_mode/safe_mode.h +4 -1
- esphome/components/scd30/scd30.h +0 -1
- esphome/components/scd30/sensor.py +2 -2
- esphome/components/scd4x/scd4x.cpp +61 -54
- esphome/components/scd4x/scd4x.h +17 -15
- esphome/components/scd4x/sensor.py +4 -4
- esphome/components/script/script.h +0 -2
- esphome/components/sdp3x/sensor.py +1 -1
- esphome/components/select/__init__.py +5 -2
- esphome/components/sen5x/sen5x.h +0 -1
- esphome/components/senseair/senseair.h +0 -1
- esphome/components/sensor/__init__.py +4 -2
- esphome/components/sensor/filter.cpp +1 -1
- esphome/components/sensor/sensor.cpp +12 -6
- esphome/components/sensor/sensor.h +13 -5
- esphome/components/servo/servo.h +0 -1
- esphome/components/sfa30/sfa30.h +0 -1
- esphome/components/sgp30/sgp30.h +0 -1
- esphome/components/sgp4x/sgp4x.h +0 -1
- esphome/components/shelly_dimmer/stm32flash.cpp +1 -2
- esphome/components/sht4x/sht4x.h +0 -1
- esphome/components/sm300d2/sm300d2.h +0 -2
- esphome/components/smt100/sensor.py +8 -4
- esphome/components/smt100/smt100.cpp +5 -5
- esphome/components/smt100/smt100.h +3 -3
- esphome/components/sn74hc595/__init__.py +1 -1
- esphome/components/sn74hc595/sn74hc595.cpp +5 -4
- esphome/components/sntp/sntp_component.cpp +9 -3
- esphome/components/sntp/time.py +2 -0
- esphome/components/socket/__init__.py +17 -0
- esphome/components/spi/__init__.py +27 -6
- esphome/components/spi/spi.cpp +3 -2
- esphome/components/spi/spi.h +9 -3
- esphome/components/spi/spi_arduino.cpp +3 -5
- esphome/components/spi/spi_esp_idf.cpp +40 -21
- esphome/components/spi_led_strip/spi_led_strip.cpp +1 -1
- esphome/components/sps30/sps30.h +0 -1
- esphome/components/ssd1306_base/ssd1306_base.cpp +1 -1
- esphome/components/st7701s/st7701s.cpp +0 -4
- esphome/components/status/status_binary_sensor.h +0 -2
- esphome/components/substitutions/__init__.py +76 -19
- esphome/components/substitutions/jinja.py +99 -0
- esphome/components/sun/sun.cpp +3 -4
- esphome/components/switch/__init__.py +5 -2
- esphome/components/switch/binary_sensor/switch_binary_sensor.h +0 -1
- esphome/components/sx126x/__init__.py +317 -0
- esphome/components/sx126x/automation.h +62 -0
- esphome/components/sx126x/packet_transport/__init__.py +26 -0
- esphome/components/sx126x/packet_transport/sx126x_transport.cpp +26 -0
- esphome/components/sx126x/packet_transport/sx126x_transport.h +25 -0
- esphome/components/sx126x/sx126x.cpp +523 -0
- esphome/components/sx126x/sx126x.h +140 -0
- esphome/components/sx126x/sx126x_reg.h +163 -0
- esphome/components/sx127x/__init__.py +325 -0
- esphome/components/sx127x/automation.h +62 -0
- esphome/components/sx127x/packet_transport/__init__.py +26 -0
- esphome/components/sx127x/packet_transport/sx127x_transport.cpp +26 -0
- esphome/components/sx127x/packet_transport/sx127x_transport.h +25 -0
- esphome/components/sx127x/sx127x.cpp +498 -0
- esphome/components/sx127x/sx127x.h +128 -0
- esphome/components/sx127x/sx127x_reg.h +295 -0
- esphome/components/syslog/esphome_syslog.cpp +5 -3
- esphome/components/syslog/esphome_syslog.h +1 -1
- esphome/components/tca9555/__init__.py +1 -1
- esphome/components/template/binary_sensor/template_binary_sensor.cpp +1 -9
- esphome/components/text/__init__.py +5 -2
- esphome/components/text_sensor/__init__.py +5 -2
- esphome/components/thermostat/thermostat_climate.cpp +34 -31
- esphome/components/thermostat/thermostat_climate.h +43 -39
- esphome/components/time/__init__.py +16 -2
- esphome/components/time/real_time_clock.cpp +4 -0
- esphome/components/time/real_time_clock.h +5 -1
- esphome/components/tlc5971/tlc5971.cpp +4 -1
- esphome/components/tmp1075/tmp1075.h +0 -2
- esphome/components/tof10120/tof10120_sensor.h +0 -1
- esphome/components/tormatic/tormatic_cover.h +0 -1
- esphome/components/total_daily_energy/total_daily_energy.h +0 -1
- esphome/components/tsl2591/tsl2591.cpp +1 -1
- esphome/components/ttp229_bsf/ttp229_bsf.h +0 -1
- esphome/components/ttp229_lsf/ttp229_lsf.h +0 -1
- esphome/components/tx20/tx20.cpp +2 -2
- esphome/components/uart/__init__.py +18 -0
- esphome/components/uart/uart_component_esp_idf.cpp +1 -5
- esphome/components/update/__init__.py +5 -2
- esphome/components/update/update_entity.h +8 -0
- esphome/components/usb_host/__init__.py +5 -2
- esphome/components/valve/__init__.py +5 -2
- esphome/components/vbus/vbus.h +0 -1
- esphome/components/veml3235/veml3235.h +0 -1
- esphome/components/veml7700/veml7700.h +0 -1
- esphome/components/vl53l0x/vl53l0x_sensor.h +0 -1
- esphome/components/voice_assistant/voice_assistant.cpp +4 -4
- esphome/components/watchdog/watchdog.cpp +0 -4
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +6 -6
- esphome/components/web_server/__init__.py +34 -19
- esphome/components/web_server/ota/__init__.py +32 -0
- esphome/components/web_server/ota/ota_web_server.cpp +210 -0
- esphome/components/web_server/ota/ota_web_server.h +26 -0
- esphome/components/web_server/web_server.cpp +311 -430
- esphome/components/web_server/web_server.h +33 -23
- esphome/components/web_server/web_server_v1.cpp +4 -5
- esphome/components/web_server_base/__init__.py +5 -2
- esphome/components/web_server_base/web_server_base.cpp +2 -94
- esphome/components/web_server_base/web_server_base.h +5 -25
- esphome/components/web_server_idf/multipart.cpp +254 -0
- esphome/components/web_server_idf/multipart.h +86 -0
- esphome/components/web_server_idf/utils.cpp +32 -0
- esphome/components/web_server_idf/utils.h +10 -0
- esphome/components/web_server_idf/web_server_idf.cpp +162 -16
- esphome/components/web_server_idf/web_server_idf.h +11 -10
- esphome/components/wiegand/wiegand.cpp +2 -2
- esphome/components/wifi/__init__.py +18 -0
- esphome/components/wifi/wifi_component.cpp +17 -22
- esphome/components/wifi/wifi_component.h +27 -23
- esphome/components/wifi/wifi_component_esp32_arduino.cpp +52 -59
- esphome/components/wifi/wifi_component_esp8266.cpp +46 -46
- esphome/components/wifi/wifi_component_esp_idf.cpp +35 -36
- esphome/components/wifi/wifi_component_libretiny.cpp +26 -27
- esphome/components/wifi/wifi_component_pico_w.cpp +3 -3
- esphome/components/wifi_info/wifi_info_text_sensor.cpp +6 -6
- esphome/components/wireguard/__init__.py +2 -11
- esphome/components/xiaomi_ble/xiaomi_ble.cpp +13 -1
- esphome/components/xiaomi_ble/xiaomi_ble.h +1 -0
- esphome/components/xiaomi_cgd1/xiaomi_cgd1.h +0 -1
- esphome/components/xiaomi_cgdk2/xiaomi_cgdk2.h +0 -1
- esphome/components/xiaomi_cgg1/xiaomi_cgg1.h +0 -1
- esphome/components/xiaomi_cgpr1/xiaomi_cgpr1.h +0 -1
- esphome/components/xiaomi_gcls002/xiaomi_gcls002.h +0 -1
- esphome/components/xiaomi_hhccjcy01/xiaomi_hhccjcy01.h +0 -1
- esphome/components/xiaomi_hhccjcy10/xiaomi_hhccjcy10.h +0 -1
- esphome/components/xiaomi_hhccpot002/xiaomi_hhccpot002.h +0 -1
- esphome/components/xiaomi_jqjcy01ym/xiaomi_jqjcy01ym.h +0 -1
- esphome/components/xiaomi_lywsd02/xiaomi_lywsd02.h +0 -1
- esphome/components/xiaomi_lywsd02mmc/xiaomi_lywsd02mmc.h +0 -1
- esphome/components/xiaomi_lywsd03mmc/xiaomi_lywsd03mmc.h +0 -1
- esphome/components/xiaomi_lywsdcgq/xiaomi_lywsdcgq.h +0 -1
- esphome/components/xiaomi_mhoc303/xiaomi_mhoc303.h +0 -1
- esphome/components/xiaomi_mhoc401/xiaomi_mhoc401.h +0 -1
- esphome/components/xiaomi_miscale/xiaomi_miscale.h +0 -1
- esphome/components/xiaomi_mjyd02yla/xiaomi_mjyd02yla.h +0 -1
- esphome/components/xiaomi_mue4094rt/xiaomi_mue4094rt.h +0 -1
- esphome/components/xiaomi_rtcgq02lm/xiaomi_rtcgq02lm.h +0 -1
- esphome/components/xiaomi_wx08zm/xiaomi_wx08zm.h +0 -1
- esphome/components/xiaomi_xmwsdj04mmc/__init__.py +0 -0
- esphome/components/xiaomi_xmwsdj04mmc/sensor.py +77 -0
- esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.cpp +77 -0
- esphome/components/xiaomi_xmwsdj04mmc/xiaomi_xmwsdj04mmc.h +36 -0
- esphome/components/zio_ultrasonic/zio_ultrasonic.h +0 -2
- esphome/components/zyaura/zyaura.h +0 -1
- esphome/config.py +88 -22
- esphome/config_helpers.py +74 -1
- esphome/config_validation.py +12 -1
- esphome/const.py +65 -10
- esphome/core/__init__.py +18 -2
- esphome/core/application.cpp +163 -10
- esphome/core/application.h +145 -165
- esphome/core/area.h +19 -0
- esphome/core/automation.h +58 -9
- esphome/core/color.cpp +3 -5
- esphome/core/color.h +16 -16
- esphome/core/component.cpp +151 -18
- esphome/core/component.h +98 -4
- esphome/core/component_iterator.cpp +7 -7
- esphome/core/component_iterator.h +9 -7
- esphome/core/config.py +155 -6
- esphome/core/controller.cpp +4 -2
- esphome/core/controller.h +1 -1
- esphome/core/datatypes.h +2 -2
- esphome/core/defines.h +17 -2
- esphome/core/device.h +20 -0
- esphome/core/entity_base.cpp +20 -15
- esphome/core/entity_base.h +76 -0
- esphome/core/entity_helpers.py +162 -1
- esphome/core/event_pool.h +81 -0
- esphome/core/helpers.cpp +75 -230
- esphome/core/helpers.h +164 -104
- esphome/core/lock_free_queue.h +151 -0
- esphome/core/log.cpp +2 -2
- esphome/core/log.h +2 -0
- esphome/core/optional.h +5 -0
- esphome/core/ring_buffer.cpp +2 -2
- esphome/core/scheduler.cpp +278 -103
- esphome/core/scheduler.h +157 -17
- esphome/core/time.cpp +5 -5
- esphome/core/time.h +5 -5
- esphome/cpp_generator.py +17 -0
- esphome/cpp_helpers.py +0 -22
- esphome/cpp_types.py +3 -1
- esphome/dashboard/entries.py +1 -1
- esphome/dashboard/util/text.py +5 -21
- esphome/dashboard/web_server.py +9 -1
- esphome/helpers.py +47 -0
- esphome/loader.py +15 -1
- esphome/pins.py +14 -8
- esphome/wizard.py +16 -3
- esphome/writer.py +21 -3
- esphome/yaml_util.py +0 -2
- {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/METADATA +10 -9
- {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/RECORD +593 -533
- esphome/components/esp32_ble/ble_event_pool.h +0 -72
- esphome/components/esp32_ble/queue.h +0 -85
- esphome/components/esp32_hall/esp32_hall.cpp +0 -25
- esphome/components/esp32_hall/esp32_hall.h +0 -23
- esphome/components/esp32_touch/esp32_touch.cpp +0 -355
- esphome/components/ld2410/button/reset_button.cpp +0 -9
- esphome/components/ld2450/button/reset_button.cpp +0 -9
- esphome/components/openthread/tlv.py +0 -65
- /esphome/{dashboard/enum.py → enum.py} +0 -0
- {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/WHEEL +0 -0
- {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/entry_points.txt +0 -0
- {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.6.2.dist-info → esphome-2025.7.0b1.dist-info}/top_level.txt +0 -0
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
// See script/api_protobuf/api_protobuf.py
|
|
3
3
|
#pragma once
|
|
4
4
|
|
|
5
|
-
#include "api_pb2.h"
|
|
6
5
|
#include "esphome/core/defines.h"
|
|
7
6
|
|
|
7
|
+
#include "api_pb2.h"
|
|
8
|
+
|
|
8
9
|
namespace esphome {
|
|
9
10
|
namespace api {
|
|
10
11
|
|
|
@@ -19,7 +20,7 @@ class APIServerConnectionBase : public ProtoService {
|
|
|
19
20
|
|
|
20
21
|
template<typename T> bool send_message(const T &msg) {
|
|
21
22
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
22
|
-
this->log_send_message_(
|
|
23
|
+
this->log_send_message_(msg.message_name(), msg.dump());
|
|
23
24
|
#endif
|
|
24
25
|
return this->send_message_(msg, T::MESSAGE_TYPE);
|
|
25
26
|
}
|
|
@@ -70,7 +71,7 @@ class APIServerConnectionBase : public ProtoService {
|
|
|
70
71
|
|
|
71
72
|
virtual void on_execute_service_request(const ExecuteServiceRequest &value){};
|
|
72
73
|
|
|
73
|
-
#ifdef
|
|
74
|
+
#ifdef USE_CAMERA
|
|
74
75
|
virtual void on_camera_image_request(const CameraImageRequest &value){};
|
|
75
76
|
#endif
|
|
76
77
|
|
|
@@ -199,7 +200,7 @@ class APIServerConnectionBase : public ProtoService {
|
|
|
199
200
|
virtual void on_update_command_request(const UpdateCommandRequest &value){};
|
|
200
201
|
#endif
|
|
201
202
|
protected:
|
|
202
|
-
|
|
203
|
+
void read_message(uint32_t msg_size, uint32_t msg_type, uint8_t *msg_data) override;
|
|
203
204
|
};
|
|
204
205
|
|
|
205
206
|
class APIServerConnection : public APIServerConnectionBase {
|
|
@@ -222,7 +223,7 @@ class APIServerConnection : public APIServerConnectionBase {
|
|
|
222
223
|
#ifdef USE_BUTTON
|
|
223
224
|
virtual void button_command(const ButtonCommandRequest &msg) = 0;
|
|
224
225
|
#endif
|
|
225
|
-
#ifdef
|
|
226
|
+
#ifdef USE_CAMERA
|
|
226
227
|
virtual void camera_image(const CameraImageRequest &msg) = 0;
|
|
227
228
|
#endif
|
|
228
229
|
#ifdef USE_CLIMATE
|
|
@@ -339,7 +340,7 @@ class APIServerConnection : public APIServerConnectionBase {
|
|
|
339
340
|
#ifdef USE_BUTTON
|
|
340
341
|
void on_button_command_request(const ButtonCommandRequest &msg) override;
|
|
341
342
|
#endif
|
|
342
|
-
#ifdef
|
|
343
|
+
#ifdef USE_CAMERA
|
|
343
344
|
void on_camera_image_request(const CameraImageRequest &msg) override;
|
|
344
345
|
#endif
|
|
345
346
|
#ifdef USE_CLIMATE
|
|
@@ -316,15 +316,13 @@ class ProtoSize {
|
|
|
316
316
|
/**
|
|
317
317
|
* @brief Calculates and adds the size of a nested message field to the total message size
|
|
318
318
|
*
|
|
319
|
-
* This
|
|
319
|
+
* This version takes a ProtoMessage object, calculates its size internally,
|
|
320
320
|
* and updates the total_size reference. This eliminates the need for a temporary variable
|
|
321
321
|
* at the call site.
|
|
322
322
|
*
|
|
323
|
-
* @tparam MessageType The type of the nested message (inferred from parameter)
|
|
324
323
|
* @param message The nested message object
|
|
325
324
|
*/
|
|
326
|
-
|
|
327
|
-
static inline void add_message_object(uint32_t &total_size, uint32_t field_id_size, const MessageType &message,
|
|
325
|
+
static inline void add_message_object(uint32_t &total_size, uint32_t field_id_size, const ProtoMessage &message,
|
|
328
326
|
bool force = false) {
|
|
329
327
|
uint32_t nested_size = 0;
|
|
330
328
|
message.calculate_size(nested_size);
|
|
@@ -24,6 +24,14 @@ static const char *const TAG = "api";
|
|
|
24
24
|
// APIServer
|
|
25
25
|
APIServer *global_api_server = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)
|
|
26
26
|
|
|
27
|
+
#ifndef USE_API_YAML_SERVICES
|
|
28
|
+
// Global empty vector to avoid guard variables (saves 8 bytes)
|
|
29
|
+
// This is initialized at program startup before any threads
|
|
30
|
+
static const std::vector<UserServiceDescriptor *> empty_user_services{};
|
|
31
|
+
|
|
32
|
+
const std::vector<UserServiceDescriptor *> &get_empty_user_services_instance() { return empty_user_services; }
|
|
33
|
+
#endif
|
|
34
|
+
|
|
27
35
|
APIServer::APIServer() {
|
|
28
36
|
global_api_server = this;
|
|
29
37
|
// Pre-allocate shared write buffer
|
|
@@ -47,6 +55,11 @@ void APIServer::setup() {
|
|
|
47
55
|
}
|
|
48
56
|
#endif
|
|
49
57
|
|
|
58
|
+
// Schedule reboot if no clients connect within timeout
|
|
59
|
+
if (this->reboot_timeout_ != 0) {
|
|
60
|
+
this->schedule_reboot_timeout_();
|
|
61
|
+
}
|
|
62
|
+
|
|
50
63
|
this->socket_ = socket::socket_ip_loop_monitored(SOCK_STREAM, 0); // monitored for incoming connections
|
|
51
64
|
if (this->socket_ == nullptr) {
|
|
52
65
|
ESP_LOGW(TAG, "Could not create socket");
|
|
@@ -91,34 +104,42 @@ void APIServer::setup() {
|
|
|
91
104
|
|
|
92
105
|
#ifdef USE_LOGGER
|
|
93
106
|
if (logger::global_logger != nullptr) {
|
|
94
|
-
logger::global_logger->add_on_log_callback(
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
logger::global_logger->add_on_log_callback(
|
|
108
|
+
[this](int level, const char *tag, const char *message, size_t message_len) {
|
|
109
|
+
if (this->shutting_down_) {
|
|
110
|
+
// Don't try to send logs during shutdown
|
|
111
|
+
// as it could result in a recursion and
|
|
112
|
+
// we would be filling a buffer we are trying to clear
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
for (auto &c : this->clients_) {
|
|
116
|
+
if (!c->flags_.remove)
|
|
117
|
+
c->try_send_log_message(level, tag, message, message_len);
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
#endif
|
|
122
|
+
|
|
123
|
+
#ifdef USE_CAMERA
|
|
124
|
+
if (camera::Camera::instance() != nullptr && !camera::Camera::instance()->is_internal()) {
|
|
125
|
+
camera::Camera::instance()->add_image_callback([this](const std::shared_ptr<camera::CameraImage> &image) {
|
|
101
126
|
for (auto &c : this->clients_) {
|
|
102
|
-
if (!c->
|
|
103
|
-
c->
|
|
127
|
+
if (!c->flags_.remove)
|
|
128
|
+
c->set_camera_state(image);
|
|
104
129
|
}
|
|
105
130
|
});
|
|
106
131
|
}
|
|
107
132
|
#endif
|
|
133
|
+
}
|
|
108
134
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
c->set_camera_state(image);
|
|
118
|
-
}
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
#endif
|
|
135
|
+
void APIServer::schedule_reboot_timeout_() {
|
|
136
|
+
this->status_set_warning();
|
|
137
|
+
this->set_timeout("api_reboot", this->reboot_timeout_, []() {
|
|
138
|
+
if (!global_api_server->is_connected()) {
|
|
139
|
+
ESP_LOGE(TAG, "No clients; rebooting");
|
|
140
|
+
App.reboot();
|
|
141
|
+
}
|
|
142
|
+
});
|
|
122
143
|
}
|
|
123
144
|
|
|
124
145
|
void APIServer::loop() {
|
|
@@ -130,51 +151,63 @@ void APIServer::loop() {
|
|
|
130
151
|
auto sock = this->socket_->accept_loop_monitored((struct sockaddr *) &source_addr, &addr_len);
|
|
131
152
|
if (!sock)
|
|
132
153
|
break;
|
|
133
|
-
ESP_LOGD(TAG, "
|
|
154
|
+
ESP_LOGD(TAG, "Accept %s", sock->getpeername().c_str());
|
|
134
155
|
|
|
135
156
|
auto *conn = new APIConnection(std::move(sock), this);
|
|
136
157
|
this->clients_.emplace_back(conn);
|
|
137
158
|
conn->start();
|
|
159
|
+
|
|
160
|
+
// Clear warning status and cancel reboot when first client connects
|
|
161
|
+
if (this->clients_.size() == 1 && this->reboot_timeout_ != 0) {
|
|
162
|
+
this->status_clear_warning();
|
|
163
|
+
this->cancel_timeout("api_reboot");
|
|
164
|
+
}
|
|
138
165
|
}
|
|
139
166
|
}
|
|
140
167
|
|
|
168
|
+
if (this->clients_.empty()) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
141
172
|
// Process clients and remove disconnected ones in a single pass
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
// Handle disconnection
|
|
149
|
-
this->client_disconnected_trigger_->trigger(client->client_info_, client->client_peername_);
|
|
150
|
-
ESP_LOGV(TAG, "Removing connection to %s", client->client_info_.c_str());
|
|
151
|
-
|
|
152
|
-
// Swap with the last element and pop (avoids expensive vector shifts)
|
|
153
|
-
if (client_index < this->clients_.size() - 1) {
|
|
154
|
-
std::swap(this->clients_[client_index], this->clients_.back());
|
|
155
|
-
}
|
|
156
|
-
this->clients_.pop_back();
|
|
157
|
-
// Don't increment client_index since we need to process the swapped element
|
|
158
|
-
} else {
|
|
159
|
-
// Process active client
|
|
160
|
-
client->loop();
|
|
161
|
-
client_index++; // Move to next client
|
|
162
|
-
}
|
|
173
|
+
// Check network connectivity once for all clients
|
|
174
|
+
if (!network::is_connected()) {
|
|
175
|
+
// Network is down - disconnect all clients
|
|
176
|
+
for (auto &client : this->clients_) {
|
|
177
|
+
client->on_fatal_error();
|
|
178
|
+
ESP_LOGW(TAG, "%s: Network down; disconnect", client->get_client_combined_info().c_str());
|
|
163
179
|
}
|
|
180
|
+
// Continue to process and clean up the clients below
|
|
164
181
|
}
|
|
165
182
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
183
|
+
size_t client_index = 0;
|
|
184
|
+
while (client_index < this->clients_.size()) {
|
|
185
|
+
auto &client = this->clients_[client_index];
|
|
186
|
+
|
|
187
|
+
if (!client->flags_.remove) {
|
|
188
|
+
// Common case: process active client
|
|
189
|
+
client->loop();
|
|
190
|
+
client_index++;
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Rare case: handle disconnection
|
|
195
|
+
#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
|
|
196
|
+
this->client_disconnected_trigger_->trigger(client->client_info_, client->client_peername_);
|
|
197
|
+
#endif
|
|
198
|
+
ESP_LOGV(TAG, "Remove connection %s", client->client_info_.c_str());
|
|
199
|
+
|
|
200
|
+
// Swap with the last element and pop (avoids expensive vector shifts)
|
|
201
|
+
if (client_index < this->clients_.size() - 1) {
|
|
202
|
+
std::swap(this->clients_[client_index], this->clients_.back());
|
|
203
|
+
}
|
|
204
|
+
this->clients_.pop_back();
|
|
205
|
+
|
|
206
|
+
// Schedule reboot when last client disconnects
|
|
207
|
+
if (this->clients_.empty() && this->reboot_timeout_ != 0) {
|
|
208
|
+
this->schedule_reboot_timeout_();
|
|
177
209
|
}
|
|
210
|
+
// Don't increment client_index since we need to process the swapped element
|
|
178
211
|
}
|
|
179
212
|
}
|
|
180
213
|
|
|
@@ -193,6 +226,7 @@ void APIServer::dump_config() {
|
|
|
193
226
|
#endif
|
|
194
227
|
}
|
|
195
228
|
|
|
229
|
+
#ifdef USE_API_PASSWORD
|
|
196
230
|
bool APIServer::uses_password() const { return !this->password_.empty(); }
|
|
197
231
|
|
|
198
232
|
bool APIServer::check_password(const std::string &password) const {
|
|
@@ -223,192 +257,129 @@ bool APIServer::check_password(const std::string &password) const {
|
|
|
223
257
|
|
|
224
258
|
return result == 0;
|
|
225
259
|
}
|
|
260
|
+
#endif
|
|
226
261
|
|
|
227
262
|
void APIServer::handle_disconnect(APIConnection *conn) {}
|
|
228
263
|
|
|
264
|
+
// Macro for entities without extra parameters
|
|
265
|
+
#define API_DISPATCH_UPDATE(entity_type, entity_name) \
|
|
266
|
+
void APIServer::on_##entity_name##_update(entity_type *obj) { /* NOLINT(bugprone-macro-parentheses) */ \
|
|
267
|
+
if (obj->is_internal()) \
|
|
268
|
+
return; \
|
|
269
|
+
for (auto &c : this->clients_) \
|
|
270
|
+
c->send_##entity_name##_state(obj); \
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// Macro for entities with extra parameters (but parameters not used in send)
|
|
274
|
+
#define API_DISPATCH_UPDATE_IGNORE_PARAMS(entity_type, entity_name, ...) \
|
|
275
|
+
void APIServer::on_##entity_name##_update(entity_type *obj, __VA_ARGS__) { /* NOLINT(bugprone-macro-parentheses) */ \
|
|
276
|
+
if (obj->is_internal()) \
|
|
277
|
+
return; \
|
|
278
|
+
for (auto &c : this->clients_) \
|
|
279
|
+
c->send_##entity_name##_state(obj); \
|
|
280
|
+
}
|
|
281
|
+
|
|
229
282
|
#ifdef USE_BINARY_SENSOR
|
|
230
|
-
|
|
231
|
-
if (obj->is_internal())
|
|
232
|
-
return;
|
|
233
|
-
for (auto &c : this->clients_)
|
|
234
|
-
c->send_binary_sensor_state(obj);
|
|
235
|
-
}
|
|
283
|
+
API_DISPATCH_UPDATE(binary_sensor::BinarySensor, binary_sensor)
|
|
236
284
|
#endif
|
|
237
285
|
|
|
238
286
|
#ifdef USE_COVER
|
|
239
|
-
|
|
240
|
-
if (obj->is_internal())
|
|
241
|
-
return;
|
|
242
|
-
for (auto &c : this->clients_)
|
|
243
|
-
c->send_cover_state(obj);
|
|
244
|
-
}
|
|
287
|
+
API_DISPATCH_UPDATE(cover::Cover, cover)
|
|
245
288
|
#endif
|
|
246
289
|
|
|
247
290
|
#ifdef USE_FAN
|
|
248
|
-
|
|
249
|
-
if (obj->is_internal())
|
|
250
|
-
return;
|
|
251
|
-
for (auto &c : this->clients_)
|
|
252
|
-
c->send_fan_state(obj);
|
|
253
|
-
}
|
|
291
|
+
API_DISPATCH_UPDATE(fan::Fan, fan)
|
|
254
292
|
#endif
|
|
255
293
|
|
|
256
294
|
#ifdef USE_LIGHT
|
|
257
|
-
|
|
258
|
-
if (obj->is_internal())
|
|
259
|
-
return;
|
|
260
|
-
for (auto &c : this->clients_)
|
|
261
|
-
c->send_light_state(obj);
|
|
262
|
-
}
|
|
295
|
+
API_DISPATCH_UPDATE(light::LightState, light)
|
|
263
296
|
#endif
|
|
264
297
|
|
|
265
298
|
#ifdef USE_SENSOR
|
|
266
|
-
|
|
267
|
-
if (obj->is_internal())
|
|
268
|
-
return;
|
|
269
|
-
for (auto &c : this->clients_)
|
|
270
|
-
c->send_sensor_state(obj);
|
|
271
|
-
}
|
|
299
|
+
API_DISPATCH_UPDATE_IGNORE_PARAMS(sensor::Sensor, sensor, float state)
|
|
272
300
|
#endif
|
|
273
301
|
|
|
274
302
|
#ifdef USE_SWITCH
|
|
275
|
-
|
|
276
|
-
if (obj->is_internal())
|
|
277
|
-
return;
|
|
278
|
-
for (auto &c : this->clients_)
|
|
279
|
-
c->send_switch_state(obj);
|
|
280
|
-
}
|
|
303
|
+
API_DISPATCH_UPDATE_IGNORE_PARAMS(switch_::Switch, switch, bool state)
|
|
281
304
|
#endif
|
|
282
305
|
|
|
283
306
|
#ifdef USE_TEXT_SENSOR
|
|
284
|
-
|
|
285
|
-
if (obj->is_internal())
|
|
286
|
-
return;
|
|
287
|
-
for (auto &c : this->clients_)
|
|
288
|
-
c->send_text_sensor_state(obj);
|
|
289
|
-
}
|
|
307
|
+
API_DISPATCH_UPDATE_IGNORE_PARAMS(text_sensor::TextSensor, text_sensor, const std::string &state)
|
|
290
308
|
#endif
|
|
291
309
|
|
|
292
310
|
#ifdef USE_CLIMATE
|
|
293
|
-
|
|
294
|
-
if (obj->is_internal())
|
|
295
|
-
return;
|
|
296
|
-
for (auto &c : this->clients_)
|
|
297
|
-
c->send_climate_state(obj);
|
|
298
|
-
}
|
|
311
|
+
API_DISPATCH_UPDATE(climate::Climate, climate)
|
|
299
312
|
#endif
|
|
300
313
|
|
|
301
314
|
#ifdef USE_NUMBER
|
|
302
|
-
|
|
303
|
-
if (obj->is_internal())
|
|
304
|
-
return;
|
|
305
|
-
for (auto &c : this->clients_)
|
|
306
|
-
c->send_number_state(obj);
|
|
307
|
-
}
|
|
315
|
+
API_DISPATCH_UPDATE_IGNORE_PARAMS(number::Number, number, float state)
|
|
308
316
|
#endif
|
|
309
317
|
|
|
310
318
|
#ifdef USE_DATETIME_DATE
|
|
311
|
-
|
|
312
|
-
if (obj->is_internal())
|
|
313
|
-
return;
|
|
314
|
-
for (auto &c : this->clients_)
|
|
315
|
-
c->send_date_state(obj);
|
|
316
|
-
}
|
|
319
|
+
API_DISPATCH_UPDATE(datetime::DateEntity, date)
|
|
317
320
|
#endif
|
|
318
321
|
|
|
319
322
|
#ifdef USE_DATETIME_TIME
|
|
320
|
-
|
|
321
|
-
if (obj->is_internal())
|
|
322
|
-
return;
|
|
323
|
-
for (auto &c : this->clients_)
|
|
324
|
-
c->send_time_state(obj);
|
|
325
|
-
}
|
|
323
|
+
API_DISPATCH_UPDATE(datetime::TimeEntity, time)
|
|
326
324
|
#endif
|
|
327
325
|
|
|
328
326
|
#ifdef USE_DATETIME_DATETIME
|
|
329
|
-
|
|
330
|
-
if (obj->is_internal())
|
|
331
|
-
return;
|
|
332
|
-
for (auto &c : this->clients_)
|
|
333
|
-
c->send_datetime_state(obj);
|
|
334
|
-
}
|
|
327
|
+
API_DISPATCH_UPDATE(datetime::DateTimeEntity, datetime)
|
|
335
328
|
#endif
|
|
336
329
|
|
|
337
330
|
#ifdef USE_TEXT
|
|
338
|
-
|
|
339
|
-
if (obj->is_internal())
|
|
340
|
-
return;
|
|
341
|
-
for (auto &c : this->clients_)
|
|
342
|
-
c->send_text_state(obj);
|
|
343
|
-
}
|
|
331
|
+
API_DISPATCH_UPDATE_IGNORE_PARAMS(text::Text, text, const std::string &state)
|
|
344
332
|
#endif
|
|
345
333
|
|
|
346
334
|
#ifdef USE_SELECT
|
|
347
|
-
|
|
348
|
-
if (obj->is_internal())
|
|
349
|
-
return;
|
|
350
|
-
for (auto &c : this->clients_)
|
|
351
|
-
c->send_select_state(obj);
|
|
352
|
-
}
|
|
335
|
+
API_DISPATCH_UPDATE_IGNORE_PARAMS(select::Select, select, const std::string &state, size_t index)
|
|
353
336
|
#endif
|
|
354
337
|
|
|
355
338
|
#ifdef USE_LOCK
|
|
356
|
-
|
|
357
|
-
if (obj->is_internal())
|
|
358
|
-
return;
|
|
359
|
-
for (auto &c : this->clients_)
|
|
360
|
-
c->send_lock_state(obj);
|
|
361
|
-
}
|
|
339
|
+
API_DISPATCH_UPDATE(lock::Lock, lock)
|
|
362
340
|
#endif
|
|
363
341
|
|
|
364
342
|
#ifdef USE_VALVE
|
|
365
|
-
|
|
366
|
-
if (obj->is_internal())
|
|
367
|
-
return;
|
|
368
|
-
for (auto &c : this->clients_)
|
|
369
|
-
c->send_valve_state(obj);
|
|
370
|
-
}
|
|
343
|
+
API_DISPATCH_UPDATE(valve::Valve, valve)
|
|
371
344
|
#endif
|
|
372
345
|
|
|
373
346
|
#ifdef USE_MEDIA_PLAYER
|
|
374
|
-
|
|
375
|
-
if (obj->is_internal())
|
|
376
|
-
return;
|
|
377
|
-
for (auto &c : this->clients_)
|
|
378
|
-
c->send_media_player_state(obj);
|
|
379
|
-
}
|
|
347
|
+
API_DISPATCH_UPDATE(media_player::MediaPlayer, media_player)
|
|
380
348
|
#endif
|
|
381
349
|
|
|
382
350
|
#ifdef USE_EVENT
|
|
351
|
+
// Event is a special case - it's the only entity that passes extra parameters to the send method
|
|
383
352
|
void APIServer::on_event(event::Event *obj, const std::string &event_type) {
|
|
353
|
+
if (obj->is_internal())
|
|
354
|
+
return;
|
|
384
355
|
for (auto &c : this->clients_)
|
|
385
356
|
c->send_event(obj, event_type);
|
|
386
357
|
}
|
|
387
358
|
#endif
|
|
388
359
|
|
|
389
360
|
#ifdef USE_UPDATE
|
|
361
|
+
// Update is a special case - the method is called on_update, not on_update_update
|
|
390
362
|
void APIServer::on_update(update::UpdateEntity *obj) {
|
|
363
|
+
if (obj->is_internal())
|
|
364
|
+
return;
|
|
391
365
|
for (auto &c : this->clients_)
|
|
392
366
|
c->send_update_state(obj);
|
|
393
367
|
}
|
|
394
368
|
#endif
|
|
395
369
|
|
|
396
370
|
#ifdef USE_ALARM_CONTROL_PANEL
|
|
397
|
-
|
|
398
|
-
if (obj->is_internal())
|
|
399
|
-
return;
|
|
400
|
-
for (auto &c : this->clients_)
|
|
401
|
-
c->send_alarm_control_panel_state(obj);
|
|
402
|
-
}
|
|
371
|
+
API_DISPATCH_UPDATE(alarm_control_panel::AlarmControlPanel, alarm_control_panel)
|
|
403
372
|
#endif
|
|
404
373
|
|
|
405
374
|
float APIServer::get_setup_priority() const { return setup_priority::AFTER_WIFI; }
|
|
406
375
|
|
|
407
376
|
void APIServer::set_port(uint16_t port) { this->port_ = port; }
|
|
408
377
|
|
|
378
|
+
#ifdef USE_API_PASSWORD
|
|
409
379
|
void APIServer::set_password(const std::string &password) { this->password_ = password; }
|
|
380
|
+
#endif
|
|
410
381
|
|
|
411
|
-
void APIServer::set_batch_delay(
|
|
382
|
+
void APIServer::set_batch_delay(uint16_t batch_delay) { this->batch_delay_ = batch_delay; }
|
|
412
383
|
|
|
413
384
|
void APIServer::send_homeassistant_service_call(const HomeassistantServiceResponse &call) {
|
|
414
385
|
for (auto &client : this->clients_) {
|
|
@@ -479,7 +450,7 @@ bool APIServer::save_noise_psk(psk_t psk, bool make_active) {
|
|
|
479
450
|
#ifdef USE_HOMEASSISTANT_TIME
|
|
480
451
|
void APIServer::request_time() {
|
|
481
452
|
for (auto &client : this->clients_) {
|
|
482
|
-
if (!client->
|
|
453
|
+
if (!client->flags_.remove && client->is_authenticated())
|
|
483
454
|
client->send_time_request();
|
|
484
455
|
}
|
|
485
456
|
}
|
|
@@ -503,8 +474,8 @@ void APIServer::on_shutdown() {
|
|
|
503
474
|
for (auto &c : this->clients_) {
|
|
504
475
|
if (!c->send_message(DisconnectRequest())) {
|
|
505
476
|
// If we can't send the disconnect request directly (tx_buffer full),
|
|
506
|
-
// schedule it
|
|
507
|
-
c->
|
|
477
|
+
// schedule it at the front of the batch so it will be sent with priority
|
|
478
|
+
c->schedule_message_front_(nullptr, &APIConnection::try_send_disconnect_request, DisconnectRequest::MESSAGE_TYPE);
|
|
508
479
|
}
|
|
509
480
|
}
|
|
510
481
|
}
|
|
@@ -25,6 +25,11 @@ struct SavedNoisePsk {
|
|
|
25
25
|
} PACKED; // NOLINT
|
|
26
26
|
#endif
|
|
27
27
|
|
|
28
|
+
#ifndef USE_API_YAML_SERVICES
|
|
29
|
+
// Forward declaration of helper function
|
|
30
|
+
const std::vector<UserServiceDescriptor *> &get_empty_user_services_instance();
|
|
31
|
+
#endif
|
|
32
|
+
|
|
28
33
|
class APIServer : public Component, public Controller {
|
|
29
34
|
public:
|
|
30
35
|
APIServer();
|
|
@@ -35,13 +40,15 @@ class APIServer : public Component, public Controller {
|
|
|
35
40
|
void dump_config() override;
|
|
36
41
|
void on_shutdown() override;
|
|
37
42
|
bool teardown() override;
|
|
43
|
+
#ifdef USE_API_PASSWORD
|
|
38
44
|
bool check_password(const std::string &password) const;
|
|
39
45
|
bool uses_password() const;
|
|
40
|
-
void set_port(uint16_t port);
|
|
41
46
|
void set_password(const std::string &password);
|
|
47
|
+
#endif
|
|
48
|
+
void set_port(uint16_t port);
|
|
42
49
|
void set_reboot_timeout(uint32_t reboot_timeout);
|
|
43
|
-
void set_batch_delay(
|
|
44
|
-
|
|
50
|
+
void set_batch_delay(uint16_t batch_delay);
|
|
51
|
+
uint16_t get_batch_delay() const { return batch_delay_; }
|
|
45
52
|
|
|
46
53
|
// Get reference to shared buffer for API connections
|
|
47
54
|
std::vector<uint8_t> &get_shared_buffer_ref() { return shared_write_buffer_; }
|
|
@@ -54,7 +61,7 @@ class APIServer : public Component, public Controller {
|
|
|
54
61
|
|
|
55
62
|
void handle_disconnect(APIConnection *conn);
|
|
56
63
|
#ifdef USE_BINARY_SENSOR
|
|
57
|
-
void on_binary_sensor_update(binary_sensor::BinarySensor *obj
|
|
64
|
+
void on_binary_sensor_update(binary_sensor::BinarySensor *obj) override;
|
|
58
65
|
#endif
|
|
59
66
|
#ifdef USE_COVER
|
|
60
67
|
void on_cover_update(cover::Cover *obj) override;
|
|
@@ -105,7 +112,18 @@ class APIServer : public Component, public Controller {
|
|
|
105
112
|
void on_media_player_update(media_player::MediaPlayer *obj) override;
|
|
106
113
|
#endif
|
|
107
114
|
void send_homeassistant_service_call(const HomeassistantServiceResponse &call);
|
|
108
|
-
void register_user_service(UserServiceDescriptor *descriptor) {
|
|
115
|
+
void register_user_service(UserServiceDescriptor *descriptor) {
|
|
116
|
+
#ifdef USE_API_YAML_SERVICES
|
|
117
|
+
// Vector is pre-allocated when services are defined in YAML
|
|
118
|
+
this->user_services_.push_back(descriptor);
|
|
119
|
+
#else
|
|
120
|
+
// Lazy allocate vector on first use for CustomAPIDevice
|
|
121
|
+
if (!this->user_services_) {
|
|
122
|
+
this->user_services_ = std::make_unique<std::vector<UserServiceDescriptor *>>();
|
|
123
|
+
}
|
|
124
|
+
this->user_services_->push_back(descriptor);
|
|
125
|
+
#endif
|
|
126
|
+
}
|
|
109
127
|
#ifdef USE_HOMEASSISTANT_TIME
|
|
110
128
|
void request_time();
|
|
111
129
|
#endif
|
|
@@ -134,27 +152,63 @@ class APIServer : public Component, public Controller {
|
|
|
134
152
|
void get_home_assistant_state(std::string entity_id, optional<std::string> attribute,
|
|
135
153
|
std::function<void(std::string)> f);
|
|
136
154
|
const std::vector<HomeAssistantStateSubscription> &get_state_subs() const;
|
|
137
|
-
const std::vector<UserServiceDescriptor *> &get_user_services() const {
|
|
155
|
+
const std::vector<UserServiceDescriptor *> &get_user_services() const {
|
|
156
|
+
#ifdef USE_API_YAML_SERVICES
|
|
157
|
+
return this->user_services_;
|
|
158
|
+
#else
|
|
159
|
+
if (this->user_services_) {
|
|
160
|
+
return *this->user_services_;
|
|
161
|
+
}
|
|
162
|
+
// Return reference to global empty instance (no guard needed)
|
|
163
|
+
return get_empty_user_services_instance();
|
|
164
|
+
#endif
|
|
165
|
+
}
|
|
138
166
|
|
|
167
|
+
#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
|
|
139
168
|
Trigger<std::string, std::string> *get_client_connected_trigger() const { return this->client_connected_trigger_; }
|
|
169
|
+
#endif
|
|
170
|
+
#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
|
|
140
171
|
Trigger<std::string, std::string> *get_client_disconnected_trigger() const {
|
|
141
172
|
return this->client_disconnected_trigger_;
|
|
142
173
|
}
|
|
174
|
+
#endif
|
|
143
175
|
|
|
144
176
|
protected:
|
|
145
|
-
|
|
177
|
+
void schedule_reboot_timeout_();
|
|
178
|
+
// Pointers and pointer-like types first (4 bytes each)
|
|
146
179
|
std::unique_ptr<socket::Socket> socket_ = nullptr;
|
|
147
|
-
|
|
180
|
+
#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
|
|
181
|
+
Trigger<std::string, std::string> *client_connected_trigger_ = new Trigger<std::string, std::string>();
|
|
182
|
+
#endif
|
|
183
|
+
#ifdef USE_API_CLIENT_DISCONNECTED_TRIGGER
|
|
184
|
+
Trigger<std::string, std::string> *client_disconnected_trigger_ = new Trigger<std::string, std::string>();
|
|
185
|
+
#endif
|
|
186
|
+
|
|
187
|
+
// 4-byte aligned types
|
|
148
188
|
uint32_t reboot_timeout_{300000};
|
|
149
|
-
|
|
150
|
-
|
|
189
|
+
|
|
190
|
+
// Vectors and strings (12 bytes each on 32-bit)
|
|
151
191
|
std::vector<std::unique_ptr<APIConnection>> clients_;
|
|
192
|
+
#ifdef USE_API_PASSWORD
|
|
152
193
|
std::string password_;
|
|
194
|
+
#endif
|
|
153
195
|
std::vector<uint8_t> shared_write_buffer_; // Shared proto write buffer for all connections
|
|
154
196
|
std::vector<HomeAssistantStateSubscription> state_subs_;
|
|
197
|
+
#ifdef USE_API_YAML_SERVICES
|
|
198
|
+
// When services are defined in YAML, we know at compile time that services will be registered
|
|
155
199
|
std::vector<UserServiceDescriptor *> user_services_;
|
|
156
|
-
|
|
157
|
-
|
|
200
|
+
#else
|
|
201
|
+
// Services can still be registered at runtime by CustomAPIDevice components even when not
|
|
202
|
+
// defined in YAML. Using unique_ptr allows lazy allocation, saving 12 bytes in the common
|
|
203
|
+
// case where no services (YAML or custom) are used.
|
|
204
|
+
std::unique_ptr<std::vector<UserServiceDescriptor *>> user_services_;
|
|
205
|
+
#endif
|
|
206
|
+
|
|
207
|
+
// Group smaller types together
|
|
208
|
+
uint16_t port_{6053};
|
|
209
|
+
uint16_t batch_delay_{100};
|
|
210
|
+
bool shutting_down_ = false;
|
|
211
|
+
// 5 bytes used, 3 bytes padding
|
|
158
212
|
|
|
159
213
|
#ifdef USE_API_NOISE
|
|
160
214
|
std::shared_ptr<APINoiseContext> noise_ctx_ = std::make_shared<APINoiseContext>();
|