esphome 2025.4.1__py3-none-any.whl → 2025.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/__main__.py +16 -14
- esphome/components/ac_dimmer/ac_dimmer.cpp +3 -2
- esphome/components/adc/__init__.py +51 -34
- esphome/components/airthings_wave_base/__init__.py +1 -1
- esphome/components/alarm_control_panel/__init__.py +37 -2
- esphome/components/am43/cover/__init__.py +4 -5
- esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +6 -4
- esphome/components/analog_threshold/analog_threshold_binary_sensor.h +4 -5
- esphome/components/analog_threshold/binary_sensor.py +10 -8
- esphome/components/anova/climate.py +4 -5
- esphome/components/api/__init__.py +25 -8
- esphome/components/api/api_connection.cpp +416 -662
- esphome/components/api/api_connection.h +256 -57
- esphome/components/api/api_frame_helper.cpp +232 -177
- esphome/components/api/api_frame_helper.h +61 -8
- esphome/components/api/api_noise_context.h +13 -4
- esphome/components/api/api_pb2.cpp +1422 -1
- esphome/components/api/api_pb2.h +255 -1
- esphome/components/api/api_pb2_service.cpp +162 -49
- esphome/components/api/api_pb2_service.h +90 -51
- esphome/components/api/api_pb2_size.h +361 -0
- esphome/components/api/api_server.cpp +110 -34
- esphome/components/api/api_server.h +8 -0
- esphome/components/api/proto.h +86 -17
- esphome/components/as3935_i2c/as3935_i2c.h +0 -3
- esphome/components/as7341/as7341.h +1 -1
- esphome/components/at581x/at581x.h +4 -4
- esphome/components/atm90e32/__init__.py +1 -0
- esphome/components/atm90e32/atm90e32.cpp +576 -199
- esphome/components/atm90e32/atm90e32.h +128 -31
- esphome/components/atm90e32/atm90e32_reg.h +4 -2
- esphome/components/atm90e32/button/__init__.py +62 -10
- esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
- esphome/components/atm90e32/button/atm90e32_button.h +36 -4
- esphome/components/atm90e32/number/__init__.py +130 -0
- esphome/components/atm90e32/number/atm90e32_number.h +16 -0
- esphome/components/atm90e32/sensor.py +21 -4
- esphome/components/atm90e32/text_sensor/__init__.py +48 -0
- esphome/components/audio/__init__.py +96 -49
- esphome/components/audio/audio.h +48 -0
- esphome/components/audio/audio_decoder.cpp +1 -1
- esphome/components/audio/audio_resampler.cpp +2 -0
- esphome/components/audio/audio_resampler.h +1 -0
- esphome/components/ballu/climate.py +2 -9
- esphome/components/bang_bang/climate.py +5 -6
- esphome/components/bedjet/bedjet_hub.cpp +1 -0
- esphome/components/bedjet/climate/__init__.py +3 -8
- esphome/components/bedjet/fan/__init__.py +2 -11
- esphome/components/binary/fan/__init__.py +13 -16
- esphome/components/binary_sensor/__init__.py +13 -10
- esphome/components/bl0906/constants.h +16 -16
- esphome/components/ble_client/text_sensor/__init__.py +3 -5
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +136 -21
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
- esphome/components/button/__init__.py +11 -8
- esphome/components/canbus/canbus.cpp +3 -0
- esphome/components/canbus/canbus.h +16 -0
- esphome/components/ccs811/sensor.py +9 -6
- esphome/components/climate/__init__.py +35 -2
- esphome/components/climate/climate_mode.h +1 -1
- esphome/components/climate/climate_traits.h +63 -57
- esphome/components/climate_ir/__init__.py +57 -17
- esphome/components/climate_ir_lg/climate.py +2 -5
- esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
- esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
- esphome/components/color/__init__.py +2 -0
- esphome/components/const/__init__.py +5 -0
- esphome/components/coolix/climate.py +2 -9
- esphome/components/copy/cover/__init__.py +10 -9
- esphome/components/copy/fan/__init__.py +11 -9
- esphome/components/copy/lock/__init__.py +11 -9
- esphome/components/copy/text/__init__.py +9 -6
- esphome/components/cover/__init__.py +37 -2
- esphome/components/cse7766/cse7766.cpp +2 -1
- esphome/components/cst226/binary_sensor/__init__.py +28 -0
- esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
- esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
- esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
- esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
- esphome/components/current_based/cover.py +37 -36
- esphome/components/current_based/current_based_cover.cpp +2 -1
- esphome/components/daikin/climate.py +2 -9
- esphome/components/daikin/daikin.cpp +15 -9
- esphome/components/daikin/daikin.h +5 -5
- esphome/components/daikin_arc/climate.py +2 -7
- esphome/components/daikin_brc/climate.py +3 -5
- esphome/components/dallas_temp/dallas_temp.cpp +17 -24
- esphome/components/dallas_temp/dallas_temp.h +0 -1
- esphome/components/daly_bms/daly_bms.cpp +2 -1
- esphome/components/debug/debug_component.cpp +6 -1
- esphome/components/debug/debug_component.h +8 -0
- esphome/components/debug/debug_esp32.cpp +109 -254
- esphome/components/debug/sensor.py +14 -0
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
- esphome/components/delonghi/climate.py +2 -9
- esphome/components/demo/__init__.py +18 -20
- esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
- esphome/components/display/rect.cpp +4 -9
- esphome/components/display/rect.h +1 -1
- esphome/components/dps310/sensor.py +6 -6
- esphome/components/ee895/sensor.py +9 -9
- esphome/components/emmeti/climate.py +2 -9
- esphome/components/endstop/cover.py +17 -16
- esphome/components/endstop/endstop_cover.cpp +2 -1
- esphome/components/ens160_base/__init__.py +12 -9
- esphome/components/esp32/__init__.py +60 -3
- esphome/components/esp32/core.cpp +11 -5
- esphome/components/esp32/gpio.cpp +86 -24
- esphome/components/esp32/gpio.py +15 -16
- esphome/components/esp32/gpio_esp32.py +1 -2
- esphome/components/esp32/gpio_esp32_c2.py +1 -1
- esphome/components/esp32/gpio_esp32_c3.py +1 -1
- esphome/components/esp32/gpio_esp32_c6.py +1 -1
- esphome/components/esp32/gpio_esp32_h2.py +1 -1
- esphome/components/esp32_ble/ble.cpp +1 -8
- esphome/components/esp32_ble/ble.h +5 -3
- esphome/components/esp32_ble/ble_advertising.cpp +2 -1
- esphome/components/esp32_ble/ble_advertising.h +1 -0
- esphome/components/esp32_ble_server/__init__.py +3 -0
- esphome/components/esp32_ble_tracker/__init__.py +7 -1
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
- esphome/components/esp32_camera/__init__.py +1 -1
- esphome/components/esp32_camera/esp32_camera.cpp +2 -10
- esphome/components/esp32_camera/esp32_camera.h +1 -1
- esphome/components/esp32_can/esp32_can.cpp +1 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
- esphome/components/esp32_rmt_led_strip/light.py +9 -1
- esphome/components/esp32_touch/esp32_touch.cpp +1 -1
- esphome/components/esp8266/gpio.cpp +69 -8
- esphome/components/ethernet/ethernet_component.cpp +1 -1
- esphome/components/event/__init__.py +13 -10
- esphome/components/factory_reset/switch/__init__.py +7 -21
- esphome/components/fan/__init__.py +52 -5
- esphome/components/fastled_base/__init__.py +1 -4
- esphome/components/fastled_base/fastled_light.cpp +1 -1
- esphome/components/feedback/cover.py +38 -33
- esphome/components/feedback/feedback_cover.cpp +2 -1
- esphome/components/fujitsu_general/climate.py +2 -9
- esphome/components/gcja5/gcja5.cpp +2 -1
- esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
- esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
- esphome/components/gpio_expander/cached_gpio.h +22 -7
- esphome/components/gps/__init__.py +47 -17
- esphome/components/gps/gps.cpp +42 -23
- esphome/components/gps/gps.h +17 -13
- esphome/components/graph/__init__.py +1 -2
- esphome/components/gree/climate.py +4 -6
- esphome/components/gree/gree.cpp +16 -2
- esphome/components/gree/gree.h +2 -2
- esphome/components/growatt_solar/growatt_solar.cpp +2 -1
- esphome/components/haier/climate.py +37 -34
- esphome/components/hbridge/fan/__init__.py +19 -17
- esphome/components/he60r/cover.py +4 -5
- esphome/components/heatpumpir/climate.py +3 -6
- esphome/components/hitachi_ac344/climate.py +2 -9
- esphome/components/hitachi_ac424/climate.py +2 -9
- esphome/components/hlw8012/hlw8012.cpp +1 -1
- esphome/components/hm3301/hm3301.h +1 -1
- esphome/components/hte501/sensor.py +6 -6
- esphome/components/http_request/__init__.py +39 -6
- esphome/components/http_request/http_request.cpp +20 -0
- esphome/components/http_request/http_request.h +57 -15
- esphome/components/http_request/http_request_arduino.cpp +22 -6
- esphome/components/http_request/http_request_arduino.h +4 -3
- esphome/components/http_request/http_request_host.cpp +141 -0
- esphome/components/http_request/http_request_host.h +37 -0
- esphome/components/http_request/http_request_idf.cpp +35 -3
- esphome/components/http_request/http_request_idf.h +10 -3
- esphome/components/http_request/httplib.h +9691 -0
- esphome/components/http_request/update/__init__.py +11 -8
- esphome/components/hyt271/sensor.py +6 -6
- esphome/components/i2c/i2c.h +4 -0
- esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
- esphome/components/i2s_audio/__init__.py +131 -22
- esphome/components/i2s_audio/i2s_audio.h +44 -4
- esphome/components/i2s_audio/media_player/__init__.py +19 -9
- esphome/components/i2s_audio/microphone/__init__.py +63 -5
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
- esphome/components/i2s_audio/speaker/__init__.py +31 -5
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
- esphome/components/ili9xxx/ili9xxx_init.h +1 -1
- esphome/components/image/__init__.py +37 -17
- esphome/components/image/image.cpp +25 -8
- esphome/components/internal_temperature/internal_temperature.cpp +6 -4
- esphome/components/key_collector/__init__.py +35 -0
- esphome/components/key_collector/key_collector.cpp +8 -0
- esphome/components/key_collector/key_collector.h +10 -0
- esphome/components/kuntze/kuntze.cpp +2 -1
- esphome/components/ld2410/ld2410.h +1 -1
- esphome/components/ld2450/ld2450.h +1 -1
- esphome/components/light/__init__.py +57 -0
- esphome/components/lock/__init__.py +51 -4
- esphome/components/lock/automation.h +2 -13
- esphome/components/logger/__init__.py +22 -0
- esphome/components/logger/logger.cpp +154 -103
- esphome/components/logger/logger.h +211 -36
- esphome/components/logger/task_log_buffer.cpp +138 -0
- esphome/components/logger/task_log_buffer.h +69 -0
- esphome/components/lvgl/__init__.py +13 -5
- esphome/components/lvgl/automation.py +50 -1
- esphome/components/lvgl/defines.py +0 -1
- esphome/components/lvgl/lv_validation.py +10 -1
- esphome/components/lvgl/lvgl_esphome.cpp +5 -1
- esphome/components/lvgl/schemas.py +14 -14
- esphome/components/lvgl/text/__init__.py +1 -2
- esphome/components/lvgl/widgets/arc.py +7 -6
- esphome/components/lvgl/widgets/buttonmatrix.py +3 -3
- esphome/components/lvgl/widgets/checkbox.py +2 -2
- esphome/components/lvgl/widgets/dropdown.py +2 -1
- esphome/components/lvgl/widgets/img.py +15 -12
- esphome/components/mapping/__init__.py +134 -0
- esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
- esphome/components/max7219digit/max7219digit.cpp +28 -27
- esphome/components/mdns/__init__.py +11 -5
- esphome/components/mdns/mdns_component.cpp +11 -5
- esphome/components/mdns/mdns_component.h +3 -2
- esphome/components/mdns/mdns_esp32.cpp +4 -3
- esphome/components/mdns/mdns_esp8266.cpp +4 -2
- esphome/components/mdns/mdns_libretiny.cpp +4 -2
- esphome/components/mdns/mdns_rp2040.cpp +4 -2
- esphome/components/media_player/__init__.py +40 -6
- esphome/components/mhz19/sensor.py +11 -7
- esphome/components/micro_wake_word/__init__.py +99 -31
- esphome/components/micro_wake_word/automation.h +54 -0
- esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
- esphome/components/micro_wake_word/micro_wake_word.h +58 -105
- esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
- esphome/components/micro_wake_word/streaming_model.cpp +158 -41
- esphome/components/micro_wake_word/streaming_model.h +85 -13
- esphome/components/microphone/__init__.py +139 -9
- esphome/components/microphone/automation.h +14 -2
- esphome/components/microphone/microphone.cpp +21 -0
- esphome/components/microphone/microphone.h +14 -5
- esphome/components/microphone/microphone_source.cpp +95 -0
- esphome/components/microphone/microphone_source.h +80 -0
- esphome/components/mics_4514/sensor.py +25 -14
- esphome/components/midea/climate.py +3 -4
- esphome/components/midea_ir/climate.py +3 -5
- esphome/components/mipi_spi/__init__.py +15 -0
- esphome/components/mipi_spi/display.py +474 -0
- esphome/components/mipi_spi/mipi_spi.cpp +481 -0
- esphome/components/mipi_spi/mipi_spi.h +171 -0
- esphome/components/mipi_spi/models/__init__.py +65 -0
- esphome/components/mipi_spi/models/amoled.py +72 -0
- esphome/components/mipi_spi/models/commands.py +82 -0
- esphome/components/mipi_spi/models/cyd.py +10 -0
- esphome/components/mipi_spi/models/ili.py +749 -0
- esphome/components/mipi_spi/models/jc.py +260 -0
- esphome/components/mipi_spi/models/lanbon.py +15 -0
- esphome/components/mipi_spi/models/lilygo.py +60 -0
- esphome/components/mipi_spi/models/waveshare.py +139 -0
- esphome/components/mitsubishi/climate.py +2 -5
- esphome/components/mitsubishi/mitsubishi.cpp +9 -9
- esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
- esphome/components/mixer/speaker/mixer_speaker.h +1 -3
- esphome/components/mlx90393/sensor.py +5 -0
- esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
- esphome/components/mlx90393/sensor_mlx90393.h +21 -4
- esphome/components/modbus/modbus.cpp +2 -1
- esphome/components/mqtt/__init__.py +1 -1
- esphome/components/mqtt/mqtt_client.cpp +6 -2
- esphome/components/mqtt/mqtt_const.h +4 -0
- esphome/components/mqtt/mqtt_fan.cpp +39 -0
- esphome/components/mqtt/mqtt_fan.h +2 -0
- esphome/components/ms5611/sensor.py +6 -6
- esphome/components/ms8607/sensor.py +3 -3
- esphome/components/network/__init__.py +1 -1
- esphome/components/nextion/base_component.py +17 -16
- esphome/components/nextion/display.py +11 -2
- esphome/components/nextion/nextion.cpp +39 -1
- esphome/components/nextion/nextion.h +50 -0
- esphome/components/noblex/climate.py +2 -9
- esphome/components/number/__init__.py +12 -9
- esphome/components/one_wire/one_wire_bus.cpp +14 -10
- esphome/components/one_wire/one_wire_bus.h +14 -8
- esphome/components/online_image/bmp_image.cpp +48 -11
- esphome/components/online_image/bmp_image.h +2 -0
- esphome/components/opentherm/binary_sensor/__init__.py +2 -4
- esphome/components/opentherm/number/__init__.py +11 -20
- esphome/components/opentherm/sensor/__init__.py +3 -3
- esphome/components/opentherm/switch/__init__.py +3 -5
- esphome/components/output/lock/__init__.py +11 -9
- esphome/components/packages/__init__.py +33 -31
- esphome/components/packet_transport/__init__.py +201 -0
- esphome/components/packet_transport/binary_sensor.py +19 -0
- esphome/components/packet_transport/packet_transport.cpp +534 -0
- esphome/components/packet_transport/packet_transport.h +154 -0
- esphome/components/packet_transport/sensor.py +19 -0
- esphome/components/pca9685/pca9685_output.cpp +2 -1
- esphome/components/pid/climate.py +2 -4
- esphome/components/pm2005/__init__.py +1 -0
- esphome/components/pm2005/pm2005.cpp +123 -0
- esphome/components/pm2005/pm2005.h +46 -0
- esphome/components/pm2005/sensor.py +86 -0
- esphome/components/pmsa003i/pmsa003i.cpp +43 -16
- esphome/components/pmsa003i/pmsa003i.h +25 -25
- esphome/components/pmsx003/pmsx003.cpp +195 -230
- esphome/components/pmsx003/pmsx003.h +51 -33
- esphome/components/pmsx003/sensor.py +21 -11
- esphome/components/pn7150/pn7150.h +2 -2
- esphome/components/pn7160/pn7160.h +2 -2
- esphome/components/prometheus/prometheus_handler.cpp +174 -0
- esphome/components/prometheus/prometheus_handler.h +17 -0
- esphome/components/psram/__init__.py +7 -5
- esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
- esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
- esphome/components/pzem004t/pzem004t.cpp +2 -1
- esphome/components/qspi_dbi/__init__.py +0 -1
- esphome/components/qspi_dbi/display.py +2 -1
- esphome/components/qspi_dbi/models.py +1 -2
- esphome/components/remote_base/__init__.py +91 -0
- esphome/components/remote_base/beo4_protocol.cpp +153 -0
- esphome/components/remote_base/beo4_protocol.h +43 -0
- esphome/components/remote_base/gobox_protocol.cpp +131 -0
- esphome/components/remote_base/gobox_protocol.h +54 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
- esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
- esphome/components/resampler/speaker/resampler_speaker.h +1 -1
- esphome/components/rf_bridge/rf_bridge.cpp +2 -1
- esphome/components/scd30/sensor.py +2 -3
- esphome/components/scd4x/sensor.py +4 -5
- esphome/components/sdp3x/sensor.py +2 -1
- esphome/components/sds011/sds011.cpp +2 -1
- esphome/components/select/__init__.py +19 -20
- esphome/components/sen5x/sen5x.cpp +55 -36
- esphome/components/sen5x/sensor.py +1 -1
- esphome/components/senseair/sensor.py +3 -3
- esphome/components/sensor/__init__.py +158 -14
- esphome/components/sensor/filter.cpp +23 -0
- esphome/components/sensor/filter.h +22 -0
- esphome/components/sgp30/sensor.py +14 -16
- esphome/components/sgp4x/sensor.py +1 -1
- esphome/components/sht4x/sht4x.cpp +43 -22
- esphome/components/sht4x/sht4x.h +1 -1
- esphome/components/shtcx/sensor.py +6 -6
- esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
- esphome/components/sml/text_sensor/__init__.py +4 -6
- esphome/components/sound_level/__init__.py +0 -0
- esphome/components/sound_level/sensor.py +97 -0
- esphome/components/sound_level/sound_level.cpp +194 -0
- esphome/components/sound_level/sound_level.h +73 -0
- esphome/components/speaker/media_player/__init__.py +4 -8
- esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
- esphome/components/speaker/media_player/speaker_media_player.h +0 -11
- esphome/components/speaker/speaker.h +4 -7
- esphome/components/speed/fan/__init__.py +17 -16
- esphome/components/spi/spi.h +11 -1
- esphome/components/sprinkler/__init__.py +18 -19
- esphome/components/sprinkler/sprinkler.cpp +6 -5
- esphome/components/switch/__init__.py +32 -42
- esphome/components/syslog/__init__.py +41 -0
- esphome/components/syslog/esphome_syslog.cpp +49 -0
- esphome/components/syslog/esphome_syslog.h +27 -0
- esphome/components/t6615/sensor.py +3 -3
- esphome/components/t6615/t6615.cpp +2 -1
- esphome/components/tca9555/tca9555.cpp +11 -6
- esphome/components/tcl112/climate.py +2 -9
- esphome/components/template/alarm_control_panel/__init__.py +7 -6
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
- esphome/components/template/cover/__init__.py +27 -21
- esphome/components/template/fan/__init__.py +14 -12
- esphome/components/template/lock/__init__.py +20 -25
- esphome/components/template/lock/automation.h +18 -0
- esphome/components/template/text/__init__.py +4 -3
- esphome/components/template/valve/__init__.py +32 -21
- esphome/components/template/valve/automation.h +24 -0
- esphome/components/text/__init__.py +32 -1
- esphome/components/text_sensor/__init__.py +24 -29
- esphome/components/thermostat/climate.py +5 -5
- esphome/components/time_based/cover.py +17 -16
- esphome/components/time_based/time_based_cover.cpp +2 -1
- esphome/components/tm1638/switch/__init__.py +10 -7
- esphome/components/tormatic/cover.py +4 -5
- esphome/components/toshiba/climate.py +3 -5
- esphome/components/touchscreen/touchscreen.cpp +3 -1
- esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
- esphome/components/tuya/climate/__init__.py +5 -6
- esphome/components/tuya/cover/__init__.py +6 -11
- esphome/components/tuya/select/__init__.py +15 -5
- esphome/components/tuya/select/tuya_select.cpp +6 -1
- esphome/components/tuya/select/tuya_select.h +5 -1
- esphome/components/uart/packet_transport/__init__.py +20 -0
- esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
- esphome/components/uart/packet_transport/uart_transport.h +41 -0
- esphome/components/uart/switch/uart_switch.cpp +2 -1
- esphome/components/udp/__init__.py +126 -128
- esphome/components/udp/automation.h +40 -0
- esphome/components/udp/binary_sensor.py +3 -25
- esphome/components/udp/packet_transport/__init__.py +29 -0
- esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
- esphome/components/udp/packet_transport/udp_transport.h +28 -0
- esphome/components/udp/sensor.py +3 -25
- esphome/components/udp/udp_component.cpp +26 -470
- esphome/components/udp/udp_component.h +21 -128
- esphome/components/update/__init__.py +31 -1
- esphome/components/uponor_smatrix/climate/__init__.py +4 -9
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
- esphome/components/uptime/text_sensor/__init__.py +47 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
- esphome/components/valve/__init__.py +34 -3
- esphome/components/valve/automation.h +1 -19
- esphome/components/vl53l0x/sensor.py +11 -0
- esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
- esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
- esphome/components/voice_assistant/__init__.py +36 -10
- esphome/components/voice_assistant/voice_assistant.cpp +170 -144
- esphome/components/voice_assistant/voice_assistant.h +26 -25
- esphome/components/waveshare_epaper/display.py +6 -0
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
- esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
- esphome/components/weikai/weikai.cpp +0 -52
- esphome/components/whirlpool/climate.py +3 -5
- esphome/components/whynter/climate.py +3 -5
- esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
- esphome/components/yashima/climate.py +6 -6
- esphome/components/zhlt01/climate.py +2 -7
- esphome/config.py +13 -13
- esphome/config_validation.py +38 -58
- esphome/const.py +15 -1
- esphome/core/__init__.py +2 -0
- esphome/core/application.cpp +27 -10
- esphome/core/application.h +9 -1
- esphome/core/automation.h +4 -3
- esphome/core/component.cpp +28 -7
- esphome/core/component.h +10 -1
- esphome/core/defines.h +23 -17
- esphome/core/doxygen.h +13 -0
- esphome/core/macros.h +4 -0
- esphome/core/scheduler.cpp +7 -1
- esphome/cpp_generator.py +6 -2
- esphome/dashboard/web_server.py +3 -3
- esphome/helpers.py +39 -0
- esphome/loader.py +4 -0
- esphome/log.py +15 -19
- esphome/mqtt.py +23 -10
- esphome/platformio_api.py +1 -1
- esphome/schema_extractors.py +0 -1
- esphome/voluptuous_schema.py +3 -1
- esphome/vscode.py +15 -0
- esphome/wizard.py +47 -37
- esphome/zeroconf.py +7 -3
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/METADATA +10 -11
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/RECORD +456 -396
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/WHEEL +1 -1
- esphome/components/esp32_ble/const_esp32c6.h +0 -74
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/entry_points.txt +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/top_level.txt +0 -0
@@ -3,6 +3,7 @@
|
|
3
3
|
#include <list>
|
4
4
|
#include <map>
|
5
5
|
#include <memory>
|
6
|
+
#include <set>
|
6
7
|
#include <utility>
|
7
8
|
#include <vector>
|
8
9
|
|
@@ -95,9 +96,19 @@ class HttpContainer : public Parented<HttpRequestComponent> {
|
|
95
96
|
|
96
97
|
size_t get_bytes_read() const { return this->bytes_read_; }
|
97
98
|
|
99
|
+
/**
|
100
|
+
* @brief Get response headers.
|
101
|
+
*
|
102
|
+
* @return The key is the lower case response header name, the value is the header value.
|
103
|
+
*/
|
104
|
+
std::map<std::string, std::list<std::string>> get_response_headers() { return this->response_headers_; }
|
105
|
+
|
106
|
+
std::string get_response_header(const std::string &header_name);
|
107
|
+
|
98
108
|
protected:
|
99
109
|
size_t bytes_read_{0};
|
100
110
|
bool secure_{false};
|
111
|
+
std::map<std::string, std::list<std::string>> response_headers_{};
|
101
112
|
};
|
102
113
|
|
103
114
|
class HttpRequestResponseTrigger : public Trigger<std::shared_ptr<HttpContainer>, std::string &> {
|
@@ -119,21 +130,46 @@ class HttpRequestComponent : public Component {
|
|
119
130
|
void set_follow_redirects(bool follow_redirects) { this->follow_redirects_ = follow_redirects; }
|
120
131
|
void set_redirect_limit(uint16_t limit) { this->redirect_limit_ = limit; }
|
121
132
|
|
122
|
-
std::shared_ptr<HttpContainer> get(std::string url) { return this->start(
|
123
|
-
std::shared_ptr<HttpContainer> get(std::string url, std::list<Header>
|
124
|
-
return this->start(
|
133
|
+
std::shared_ptr<HttpContainer> get(const std::string &url) { return this->start(url, "GET", "", {}); }
|
134
|
+
std::shared_ptr<HttpContainer> get(const std::string &url, const std::list<Header> &request_headers) {
|
135
|
+
return this->start(url, "GET", "", request_headers);
|
136
|
+
}
|
137
|
+
std::shared_ptr<HttpContainer> get(const std::string &url, const std::list<Header> &request_headers,
|
138
|
+
const std::set<std::string> &collect_headers) {
|
139
|
+
return this->start(url, "GET", "", request_headers, collect_headers);
|
140
|
+
}
|
141
|
+
std::shared_ptr<HttpContainer> post(const std::string &url, const std::string &body) {
|
142
|
+
return this->start(url, "POST", body, {});
|
143
|
+
}
|
144
|
+
std::shared_ptr<HttpContainer> post(const std::string &url, const std::string &body,
|
145
|
+
const std::list<Header> &request_headers) {
|
146
|
+
return this->start(url, "POST", body, request_headers);
|
125
147
|
}
|
126
|
-
std::shared_ptr<HttpContainer> post(std::string url, std::string body
|
127
|
-
|
148
|
+
std::shared_ptr<HttpContainer> post(const std::string &url, const std::string &body,
|
149
|
+
const std::list<Header> &request_headers,
|
150
|
+
const std::set<std::string> &collect_headers) {
|
151
|
+
return this->start(url, "POST", body, request_headers, collect_headers);
|
128
152
|
}
|
129
|
-
|
130
|
-
|
153
|
+
|
154
|
+
std::shared_ptr<HttpContainer> start(const std::string &url, const std::string &method, const std::string &body,
|
155
|
+
const std::list<Header> &request_headers) {
|
156
|
+
return this->start(url, method, body, request_headers, {});
|
131
157
|
}
|
132
158
|
|
133
|
-
|
134
|
-
|
159
|
+
std::shared_ptr<HttpContainer> start(const std::string &url, const std::string &method, const std::string &body,
|
160
|
+
const std::list<Header> &request_headers,
|
161
|
+
const std::set<std::string> &collect_headers) {
|
162
|
+
std::set<std::string> lower_case_collect_headers;
|
163
|
+
for (const std::string &collect_header : collect_headers) {
|
164
|
+
lower_case_collect_headers.insert(str_lower_case(collect_header));
|
165
|
+
}
|
166
|
+
return this->perform(url, method, body, request_headers, lower_case_collect_headers);
|
167
|
+
}
|
135
168
|
|
136
169
|
protected:
|
170
|
+
virtual std::shared_ptr<HttpContainer> perform(std::string url, std::string method, std::string body,
|
171
|
+
std::list<Header> request_headers,
|
172
|
+
std::set<std::string> collect_headers) = 0;
|
137
173
|
const char *useragent_{nullptr};
|
138
174
|
bool follow_redirects_{};
|
139
175
|
uint16_t redirect_limit_{};
|
@@ -149,7 +185,11 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
|
|
149
185
|
TEMPLATABLE_VALUE(std::string, body)
|
150
186
|
TEMPLATABLE_VALUE(bool, capture_response)
|
151
187
|
|
152
|
-
void
|
188
|
+
void add_request_header(const char *key, TemplatableValue<const char *, Ts...> value) {
|
189
|
+
this->request_headers_.insert({key, value});
|
190
|
+
}
|
191
|
+
|
192
|
+
void add_collect_header(const char *value) { this->collect_headers_.insert(value); }
|
153
193
|
|
154
194
|
void add_json(const char *key, TemplatableValue<std::string, Ts...> value) { this->json_.insert({key, value}); }
|
155
195
|
|
@@ -176,16 +216,17 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
|
|
176
216
|
auto f = std::bind(&HttpRequestSendAction<Ts...>::encode_json_func_, this, x..., std::placeholders::_1);
|
177
217
|
body = json::build_json(f);
|
178
218
|
}
|
179
|
-
std::list<Header>
|
180
|
-
for (const auto &item : this->
|
219
|
+
std::list<Header> request_headers;
|
220
|
+
for (const auto &item : this->request_headers_) {
|
181
221
|
auto val = item.second;
|
182
222
|
Header header;
|
183
223
|
header.name = item.first;
|
184
224
|
header.value = val.value(x...);
|
185
|
-
|
225
|
+
request_headers.push_back(header);
|
186
226
|
}
|
187
227
|
|
188
|
-
auto container = this->parent_->start(this->url_.value(x...), this->method_.value(x...), body,
|
228
|
+
auto container = this->parent_->start(this->url_.value(x...), this->method_.value(x...), body, request_headers,
|
229
|
+
this->collect_headers_);
|
189
230
|
|
190
231
|
if (container == nullptr) {
|
191
232
|
for (auto *trigger : this->error_triggers_)
|
@@ -238,7 +279,8 @@ template<typename... Ts> class HttpRequestSendAction : public Action<Ts...> {
|
|
238
279
|
}
|
239
280
|
void encode_json_func_(Ts... x, JsonObject root) { this->json_func_(x..., root); }
|
240
281
|
HttpRequestComponent *parent_;
|
241
|
-
std::map<const char *, TemplatableValue<const char *, Ts...>>
|
282
|
+
std::map<const char *, TemplatableValue<const char *, Ts...>> request_headers_{};
|
283
|
+
std::set<std::string> collect_headers_{"content-type", "content-length"};
|
242
284
|
std::map<const char *, TemplatableValue<std::string, Ts...>> json_{};
|
243
285
|
std::function<void(Ts..., JsonObject)> json_func_{nullptr};
|
244
286
|
std::vector<HttpRequestResponseTrigger *> response_triggers_{};
|
@@ -14,8 +14,9 @@ namespace http_request {
|
|
14
14
|
|
15
15
|
static const char *const TAG = "http_request.arduino";
|
16
16
|
|
17
|
-
std::shared_ptr<HttpContainer> HttpRequestArduino::
|
18
|
-
|
17
|
+
std::shared_ptr<HttpContainer> HttpRequestArduino::perform(std::string url, std::string method, std::string body,
|
18
|
+
std::list<Header> request_headers,
|
19
|
+
std::set<std::string> collect_headers) {
|
19
20
|
if (!network::is_connected()) {
|
20
21
|
this->status_momentary_error("failed", 1000);
|
21
22
|
ESP_LOGW(TAG, "HTTP Request failed; Not connected to network");
|
@@ -95,14 +96,17 @@ std::shared_ptr<HttpContainer> HttpRequestArduino::start(std::string url, std::s
|
|
95
96
|
if (this->useragent_ != nullptr) {
|
96
97
|
container->client_.setUserAgent(this->useragent_);
|
97
98
|
}
|
98
|
-
for (const auto &header :
|
99
|
+
for (const auto &header : request_headers) {
|
99
100
|
container->client_.addHeader(header.name.c_str(), header.value.c_str(), false, true);
|
100
101
|
}
|
101
102
|
|
102
103
|
// returned needed headers must be collected before the requests
|
103
|
-
|
104
|
-
|
105
|
-
|
104
|
+
const char *header_keys[collect_headers.size()];
|
105
|
+
int index = 0;
|
106
|
+
for (auto const &header_name : collect_headers) {
|
107
|
+
header_keys[index++] = header_name.c_str();
|
108
|
+
}
|
109
|
+
container->client_.collectHeaders(header_keys, index);
|
106
110
|
|
107
111
|
App.feed_wdt();
|
108
112
|
container->status_code = container->client_.sendRequest(method.c_str(), body.c_str());
|
@@ -121,6 +125,18 @@ std::shared_ptr<HttpContainer> HttpRequestArduino::start(std::string url, std::s
|
|
121
125
|
// Still return the container, so it can be used to get the status code and error message
|
122
126
|
}
|
123
127
|
|
128
|
+
container->response_headers_ = {};
|
129
|
+
auto header_count = container->client_.headers();
|
130
|
+
for (int i = 0; i < header_count; i++) {
|
131
|
+
const std::string header_name = str_lower_case(container->client_.headerName(i).c_str());
|
132
|
+
if (collect_headers.count(header_name) > 0) {
|
133
|
+
std::string header_value = container->client_.header(i).c_str();
|
134
|
+
ESP_LOGD(TAG, "Received response header, name: %s, value: %s", header_name.c_str(), header_value.c_str());
|
135
|
+
container->response_headers_[header_name].push_back(header_value);
|
136
|
+
break;
|
137
|
+
}
|
138
|
+
}
|
139
|
+
|
124
140
|
int content_length = container->client_.getSize();
|
125
141
|
ESP_LOGD(TAG, "Content-Length: %d", content_length);
|
126
142
|
container->content_length = (size_t) content_length;
|
@@ -29,9 +29,10 @@ class HttpContainerArduino : public HttpContainer {
|
|
29
29
|
};
|
30
30
|
|
31
31
|
class HttpRequestArduino : public HttpRequestComponent {
|
32
|
-
|
33
|
-
std::shared_ptr<HttpContainer>
|
34
|
-
|
32
|
+
protected:
|
33
|
+
std::shared_ptr<HttpContainer> perform(std::string url, std::string method, std::string body,
|
34
|
+
std::list<Header> request_headers,
|
35
|
+
std::set<std::string> collect_headers) override;
|
35
36
|
};
|
36
37
|
|
37
38
|
} // namespace http_request
|
@@ -0,0 +1,141 @@
|
|
1
|
+
#include "http_request_host.h"
|
2
|
+
|
3
|
+
#ifdef USE_HOST
|
4
|
+
|
5
|
+
#include <regex>
|
6
|
+
#include "esphome/components/network/util.h"
|
7
|
+
#include "esphome/components/watchdog/watchdog.h"
|
8
|
+
|
9
|
+
#include "esphome/core/application.h"
|
10
|
+
#include "esphome/core/log.h"
|
11
|
+
|
12
|
+
namespace esphome {
|
13
|
+
namespace http_request {
|
14
|
+
|
15
|
+
static const char *const TAG = "http_request.host";
|
16
|
+
|
17
|
+
std::shared_ptr<HttpContainer> HttpRequestHost::perform(std::string url, std::string method, std::string body,
|
18
|
+
std::list<Header> request_headers,
|
19
|
+
std::set<std::string> response_headers) {
|
20
|
+
if (!network::is_connected()) {
|
21
|
+
this->status_momentary_error("failed", 1000);
|
22
|
+
ESP_LOGW(TAG, "HTTP Request failed; Not connected to network");
|
23
|
+
return nullptr;
|
24
|
+
}
|
25
|
+
|
26
|
+
std::regex url_regex(R"(^(([^:\/?#]+):)?(//([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?)", std::regex::extended);
|
27
|
+
std::smatch url_match_result;
|
28
|
+
|
29
|
+
if (!std::regex_match(url, url_match_result, url_regex) || url_match_result.length() < 7) {
|
30
|
+
ESP_LOGE(TAG, "HTTP Request failed; Malformed URL: %s", url.c_str());
|
31
|
+
return nullptr;
|
32
|
+
}
|
33
|
+
auto host = url_match_result[4].str();
|
34
|
+
auto scheme_host = url_match_result[1].str() + url_match_result[3].str();
|
35
|
+
auto path = url_match_result[5].str() + url_match_result[6].str();
|
36
|
+
if (path.empty())
|
37
|
+
path = "/";
|
38
|
+
|
39
|
+
std::shared_ptr<HttpContainerHost> container = std::make_shared<HttpContainerHost>();
|
40
|
+
container->set_parent(this);
|
41
|
+
|
42
|
+
const uint32_t start = millis();
|
43
|
+
|
44
|
+
watchdog::WatchdogManager wdm(this->get_watchdog_timeout());
|
45
|
+
|
46
|
+
httplib::Headers h_headers;
|
47
|
+
h_headers.emplace("Host", host.c_str());
|
48
|
+
h_headers.emplace("User-Agent", this->useragent_);
|
49
|
+
for (const auto &[name, value] : request_headers) {
|
50
|
+
h_headers.emplace(name, value);
|
51
|
+
}
|
52
|
+
httplib::Client client(scheme_host.c_str());
|
53
|
+
if (!client.is_valid()) {
|
54
|
+
ESP_LOGE(TAG, "HTTP Request failed; Invalid URL: %s", url.c_str());
|
55
|
+
return nullptr;
|
56
|
+
}
|
57
|
+
client.set_follow_location(this->follow_redirects_);
|
58
|
+
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
59
|
+
if (this->ca_path_ != nullptr)
|
60
|
+
client.set_ca_cert_path(this->ca_path_);
|
61
|
+
#endif
|
62
|
+
|
63
|
+
httplib::Result result;
|
64
|
+
if (method == "GET") {
|
65
|
+
result = client.Get(path, h_headers, [&](const char *data, size_t data_length) {
|
66
|
+
ESP_LOGV(TAG, "Got data length: %zu", data_length);
|
67
|
+
container->response_body_.insert(container->response_body_.end(), (const uint8_t *) data,
|
68
|
+
(const uint8_t *) data + data_length);
|
69
|
+
return true;
|
70
|
+
});
|
71
|
+
} else if (method == "HEAD") {
|
72
|
+
result = client.Head(path, h_headers);
|
73
|
+
} else if (method == "PUT") {
|
74
|
+
result = client.Put(path, h_headers, body, "");
|
75
|
+
if (result) {
|
76
|
+
auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
|
77
|
+
container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
|
78
|
+
}
|
79
|
+
} else if (method == "PATCH") {
|
80
|
+
result = client.Patch(path, h_headers, body, "");
|
81
|
+
if (result) {
|
82
|
+
auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
|
83
|
+
container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
|
84
|
+
}
|
85
|
+
} else if (method == "POST") {
|
86
|
+
result = client.Post(path, h_headers, body, "");
|
87
|
+
if (result) {
|
88
|
+
auto data = std::vector<uint8_t>(result->body.begin(), result->body.end());
|
89
|
+
container->response_body_.insert(container->response_body_.end(), data.begin(), data.end());
|
90
|
+
}
|
91
|
+
} else {
|
92
|
+
ESP_LOGW(TAG, "HTTP Request failed - unsupported method %s; URL: %s", method.c_str(), url.c_str());
|
93
|
+
container->end();
|
94
|
+
return nullptr;
|
95
|
+
}
|
96
|
+
App.feed_wdt();
|
97
|
+
if (!result) {
|
98
|
+
ESP_LOGW(TAG, "HTTP Request failed; URL: %s, error code: %u", url.c_str(), (unsigned) result.error());
|
99
|
+
container->end();
|
100
|
+
this->status_momentary_error("failed", 1000);
|
101
|
+
return nullptr;
|
102
|
+
}
|
103
|
+
App.feed_wdt();
|
104
|
+
auto response = *result;
|
105
|
+
container->status_code = response.status;
|
106
|
+
if (!is_success(response.status)) {
|
107
|
+
ESP_LOGE(TAG, "HTTP Request failed; URL: %s; Code: %d", url.c_str(), response.status);
|
108
|
+
this->status_momentary_error("failed", 1000);
|
109
|
+
// Still return the container, so it can be used to get the status code and error message
|
110
|
+
}
|
111
|
+
|
112
|
+
container->content_length = container->response_body_.size();
|
113
|
+
for (auto header : response.headers) {
|
114
|
+
ESP_LOGD(TAG, "Header: %s: %s", header.first.c_str(), header.second.c_str());
|
115
|
+
auto lower_name = str_lower_case(header.first);
|
116
|
+
if (response_headers.find(lower_name) != response_headers.end()) {
|
117
|
+
container->response_headers_[lower_name].emplace_back(header.second);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
container->duration_ms = millis() - start;
|
121
|
+
return container;
|
122
|
+
}
|
123
|
+
|
124
|
+
int HttpContainerHost::read(uint8_t *buf, size_t max_len) {
|
125
|
+
auto bytes_remaining = this->response_body_.size() - this->bytes_read_;
|
126
|
+
auto read_len = std::min(max_len, bytes_remaining);
|
127
|
+
memcpy(buf, this->response_body_.data() + this->bytes_read_, read_len);
|
128
|
+
this->bytes_read_ += read_len;
|
129
|
+
return read_len;
|
130
|
+
}
|
131
|
+
|
132
|
+
void HttpContainerHost::end() {
|
133
|
+
watchdog::WatchdogManager wdm(this->parent_->get_watchdog_timeout());
|
134
|
+
this->response_body_ = std::vector<uint8_t>();
|
135
|
+
this->bytes_read_ = 0;
|
136
|
+
}
|
137
|
+
|
138
|
+
} // namespace http_request
|
139
|
+
} // namespace esphome
|
140
|
+
|
141
|
+
#endif // USE_HOST
|
@@ -0,0 +1,37 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "http_request.h"
|
4
|
+
|
5
|
+
#ifdef USE_HOST
|
6
|
+
|
7
|
+
#define CPPHTTPLIB_NO_EXCEPTIONS
|
8
|
+
#include "httplib.h"
|
9
|
+
namespace esphome {
|
10
|
+
namespace http_request {
|
11
|
+
|
12
|
+
class HttpRequestHost;
|
13
|
+
class HttpContainerHost : public HttpContainer {
|
14
|
+
public:
|
15
|
+
int read(uint8_t *buf, size_t max_len) override;
|
16
|
+
void end() override;
|
17
|
+
|
18
|
+
protected:
|
19
|
+
friend class HttpRequestHost;
|
20
|
+
std::vector<uint8_t> response_body_{};
|
21
|
+
};
|
22
|
+
|
23
|
+
class HttpRequestHost : public HttpRequestComponent {
|
24
|
+
public:
|
25
|
+
std::shared_ptr<HttpContainer> perform(std::string url, std::string method, std::string body,
|
26
|
+
std::list<Header> request_headers,
|
27
|
+
std::set<std::string> response_headers) override;
|
28
|
+
void set_ca_path(const char *ca_path) { this->ca_path_ = ca_path; }
|
29
|
+
|
30
|
+
protected:
|
31
|
+
const char *ca_path_{};
|
32
|
+
};
|
33
|
+
|
34
|
+
} // namespace http_request
|
35
|
+
} // namespace esphome
|
36
|
+
|
37
|
+
#endif // USE_HOST
|
@@ -19,14 +19,41 @@ namespace http_request {
|
|
19
19
|
|
20
20
|
static const char *const TAG = "http_request.idf";
|
21
21
|
|
22
|
+
struct UserData {
|
23
|
+
const std::set<std::string> &collect_headers;
|
24
|
+
std::map<std::string, std::list<std::string>> response_headers;
|
25
|
+
};
|
26
|
+
|
22
27
|
void HttpRequestIDF::dump_config() {
|
23
28
|
HttpRequestComponent::dump_config();
|
24
29
|
ESP_LOGCONFIG(TAG, " Buffer Size RX: %u", this->buffer_size_rx_);
|
25
30
|
ESP_LOGCONFIG(TAG, " Buffer Size TX: %u", this->buffer_size_tx_);
|
26
31
|
}
|
27
32
|
|
28
|
-
|
29
|
-
|
33
|
+
esp_err_t HttpRequestIDF::http_event_handler(esp_http_client_event_t *evt) {
|
34
|
+
UserData *user_data = (UserData *) evt->user_data;
|
35
|
+
|
36
|
+
switch (evt->event_id) {
|
37
|
+
case HTTP_EVENT_ON_HEADER: {
|
38
|
+
const std::string header_name = str_lower_case(evt->header_key);
|
39
|
+
if (user_data->collect_headers.count(header_name)) {
|
40
|
+
const std::string header_value = evt->header_value;
|
41
|
+
ESP_LOGD(TAG, "Received response header, name: %s, value: %s", header_name.c_str(), header_value.c_str());
|
42
|
+
user_data->response_headers[header_name].push_back(header_value);
|
43
|
+
break;
|
44
|
+
}
|
45
|
+
break;
|
46
|
+
}
|
47
|
+
default: {
|
48
|
+
break;
|
49
|
+
}
|
50
|
+
}
|
51
|
+
return ESP_OK;
|
52
|
+
}
|
53
|
+
|
54
|
+
std::shared_ptr<HttpContainer> HttpRequestIDF::perform(std::string url, std::string method, std::string body,
|
55
|
+
std::list<Header> request_headers,
|
56
|
+
std::set<std::string> collect_headers) {
|
30
57
|
if (!network::is_connected()) {
|
31
58
|
this->status_momentary_error("failed", 1000);
|
32
59
|
ESP_LOGE(TAG, "HTTP Request failed; Not connected to network");
|
@@ -76,6 +103,10 @@ std::shared_ptr<HttpContainer> HttpRequestIDF::start(std::string url, std::strin
|
|
76
103
|
const uint32_t start = millis();
|
77
104
|
watchdog::WatchdogManager wdm(this->get_watchdog_timeout());
|
78
105
|
|
106
|
+
config.event_handler = http_event_handler;
|
107
|
+
auto user_data = UserData{collect_headers, {}};
|
108
|
+
config.user_data = static_cast<void *>(&user_data);
|
109
|
+
|
79
110
|
esp_http_client_handle_t client = esp_http_client_init(&config);
|
80
111
|
|
81
112
|
std::shared_ptr<HttpContainerIDF> container = std::make_shared<HttpContainerIDF>(client);
|
@@ -83,7 +114,7 @@ std::shared_ptr<HttpContainer> HttpRequestIDF::start(std::string url, std::strin
|
|
83
114
|
|
84
115
|
container->set_secure(secure);
|
85
116
|
|
86
|
-
for (const auto &header :
|
117
|
+
for (const auto &header : request_headers) {
|
87
118
|
esp_http_client_set_header(client, header.name.c_str(), header.value.c_str());
|
88
119
|
}
|
89
120
|
|
@@ -124,6 +155,7 @@ std::shared_ptr<HttpContainer> HttpRequestIDF::start(std::string url, std::strin
|
|
124
155
|
container->feed_wdt();
|
125
156
|
container->status_code = esp_http_client_get_status_code(client);
|
126
157
|
container->feed_wdt();
|
158
|
+
container->set_response_headers(user_data.response_headers);
|
127
159
|
if (is_success(container->status_code)) {
|
128
160
|
container->duration_ms = millis() - start;
|
129
161
|
return container;
|
@@ -21,6 +21,10 @@ class HttpContainerIDF : public HttpContainer {
|
|
21
21
|
/// @brief Feeds the watchdog timer if the executing task has one attached
|
22
22
|
void feed_wdt();
|
23
23
|
|
24
|
+
void set_response_headers(std::map<std::string, std::list<std::string>> &response_headers) {
|
25
|
+
this->response_headers_ = std::move(response_headers);
|
26
|
+
}
|
27
|
+
|
24
28
|
protected:
|
25
29
|
esp_http_client_handle_t client_;
|
26
30
|
};
|
@@ -29,16 +33,19 @@ class HttpRequestIDF : public HttpRequestComponent {
|
|
29
33
|
public:
|
30
34
|
void dump_config() override;
|
31
35
|
|
32
|
-
std::shared_ptr<HttpContainer> start(std::string url, std::string method, std::string body,
|
33
|
-
std::list<Header> headers) override;
|
34
|
-
|
35
36
|
void set_buffer_size_rx(uint16_t buffer_size_rx) { this->buffer_size_rx_ = buffer_size_rx; }
|
36
37
|
void set_buffer_size_tx(uint16_t buffer_size_tx) { this->buffer_size_tx_ = buffer_size_tx; }
|
37
38
|
|
38
39
|
protected:
|
40
|
+
std::shared_ptr<HttpContainer> perform(std::string url, std::string method, std::string body,
|
41
|
+
std::list<Header> request_headers,
|
42
|
+
std::set<std::string> collect_headers) override;
|
39
43
|
// if zero ESP-IDF will use DEFAULT_HTTP_BUF_SIZE
|
40
44
|
uint16_t buffer_size_rx_{};
|
41
45
|
uint16_t buffer_size_tx_{};
|
46
|
+
|
47
|
+
/// @brief Monitors the http client events to gather response headers
|
48
|
+
static esp_err_t http_event_handler(esp_http_client_event_t *evt);
|
42
49
|
};
|
43
50
|
|
44
51
|
} // namespace http_request
|