esphome 2025.6.2__py3-none-any.whl → 2025.7.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +57 -21
- esphome/components/api/api_connection.cpp +344 -539
- esphome/components/api/api_connection.h +224 -141
- esphome/components/api/api_frame_helper.cpp +91 -127
- esphome/components/api/api_frame_helper.h +64 -54
- esphome/components/api/api_pb2.cpp +1837 -9044
- esphome/components/api/api_pb2.h +532 -685
- esphome/components/api/api_pb2_dump.cpp +4432 -0
- esphome/components/api/api_pb2_service.cpp +184 -425
- esphome/components/api/api_pb2_service.h +13 -6
- esphome/components/api/api_server.cpp +131 -167
- esphome/components/api/api_server.h +38 -10
- esphome/components/api/client.py +10 -4
- esphome/components/api/custom_api_device.h +8 -0
- esphome/components/api/list_entities.cpp +37 -104
- esphome/components/api/list_entities.h +33 -23
- esphome/components/api/proto.h +532 -26
- esphome/components/api/subscribe_state.cpp +23 -29
- esphome/components/api/subscribe_state.h +26 -19
- esphome/components/api/user_services.h +2 -0
- esphome/components/as3935_spi/as3935_spi.h +0 -2
- 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/debug/debug_esp32.cpp +2 -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 +103 -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 +112 -98
- 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 +240 -0
- esphome/components/esp32_touch/esp32_touch_v2.cpp +397 -0
- esphome/components/esp8266/__init__.py +2 -0
- esphome/components/esp8266/gpio.cpp +10 -10
- esphome/components/esp8266/helpers.cpp +31 -0
- esphome/components/esp_ldo/__init__.py +10 -8
- esphome/components/esp_ldo/esp_ldo.h +3 -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/fan/fan.cpp +4 -0
- 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 +39 -1
- 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 +3 -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 +35 -16
- 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/__init__.py +1 -1
- 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/json/__init__.py +1 -1
- esphome/components/json/json_util.cpp +56 -63
- 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 +421 -268
- 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/binary_sensor/ld2420_binary_sensor.cpp +2 -2
- esphome/components/ld2420/button/reconfig_buttons.cpp +1 -1
- esphome/components/ld2420/ld2420.cpp +252 -147
- esphome/components/ld2420/ld2420.h +52 -126
- esphome/components/ld2420/number/__init__.py +2 -2
- esphome/components/ld2420/number/gate_config_number.cpp +1 -1
- esphome/components/ld2420/select/operating_mode_select.cpp +1 -1
- esphome/components/ld2420/sensor/__init__.py +6 -2
- esphome/components/ld2420/sensor/ld2420_sensor.cpp +2 -2
- esphome/components/ld2420/sensor/ld2420_sensor.h +1 -1
- esphome/components/ld2420/text_sensor/text_sensor.cpp +2 -2
- 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 +5 -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_json_schema.cpp +17 -16
- 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/lvgl/widgets/meter.py +20 -13
- 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_alarm_control_panel.cpp +2 -1
- esphome/components/mqtt/mqtt_backend.h +2 -1
- esphome/components/mqtt/mqtt_backend_esp32.cpp +132 -47
- esphome/components/mqtt/mqtt_backend_esp32.h +106 -4
- esphome/components/mqtt/mqtt_binary_sensor.cpp +1 -0
- esphome/components/mqtt/mqtt_button.cpp +4 -1
- esphome/components/mqtt/mqtt_client.cpp +17 -9
- esphome/components/mqtt/mqtt_client.h +8 -3
- esphome/components/mqtt/mqtt_climate.cpp +6 -4
- esphome/components/mqtt/mqtt_component.cpp +3 -1
- esphome/components/mqtt/mqtt_cover.cpp +1 -0
- esphome/components/mqtt/mqtt_date.cpp +4 -3
- esphome/components/mqtt/mqtt_datetime.cpp +7 -6
- esphome/components/mqtt/mqtt_event.cpp +6 -3
- esphome/components/mqtt/mqtt_fan.cpp +1 -0
- esphome/components/mqtt/mqtt_light.cpp +8 -4
- esphome/components/mqtt/mqtt_lock.cpp +3 -1
- esphome/components/mqtt/mqtt_number.cpp +1 -0
- esphome/components/mqtt/mqtt_select.cpp +2 -1
- esphome/components/mqtt/mqtt_sensor.cpp +3 -1
- esphome/components/mqtt/mqtt_switch.cpp +3 -1
- esphome/components/mqtt/mqtt_text.cpp +1 -0
- esphome/components/mqtt/mqtt_text_sensor.cpp +3 -1
- esphome/components/mqtt/mqtt_time.cpp +4 -3
- esphome/components/mqtt/mqtt_update.cpp +1 -0
- esphome/components/mqtt/mqtt_valve.cpp +3 -1
- esphome/components/ms8607/ms8607.cpp +1 -1
- 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 +9 -1
- esphome/components/online_image/online_image.cpp +17 -7
- esphome/components/online_image/online_image.h +10 -2
- esphome/components/opentherm/opentherm.cpp +7 -12
- esphome/components/opentherm/output/output.cpp +1 -1
- 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 +34 -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 +2 -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.cpp +2 -2
- 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 +81 -21
- 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/usb_host/usb_host_client.cpp +10 -10
- esphome/components/usb_uart/cp210x.cpp +1 -1
- esphome/components/usb_uart/usb_uart.cpp +41 -44
- esphome/components/usb_uart/usb_uart.h +4 -3
- 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 +324 -439
- 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 +164 -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 +169 -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 +156 -22
- esphome/core/component.h +98 -4
- esphome/core/component_iterator.cpp +11 -9
- esphome/core/component_iterator.h +12 -10
- 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 +168 -1
- esphome/core/event_pool.h +81 -0
- esphome/core/helpers.cpp +75 -230
- esphome/core/helpers.h +165 -105
- 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 +275 -103
- esphome/core/scheduler.h +154 -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/platformio_api.py +2 -0
- esphome/wizard.py +17 -4
- esphome/writer.py +44 -3
- esphome/yaml_util.py +0 -2
- {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/METADATA +10 -9
- {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/RECORD +639 -580
- esphome/components/api/api_pb2_size.h +0 -361
- 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.0.dist-info}/WHEEL +0 -0
- {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/entry_points.txt +0 -0
- {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.6.2.dist-info → esphome-2025.7.0.dist-info}/top_level.txt +0 -0
|
@@ -28,8 +28,32 @@
|
|
|
28
28
|
namespace esphome {
|
|
29
29
|
namespace api {
|
|
30
30
|
|
|
31
|
+
// Read a maximum of 5 messages per loop iteration to prevent starving other components.
|
|
32
|
+
// This is a balance between API responsiveness and allowing other components to run.
|
|
33
|
+
// Since each message could contain multiple protobuf messages when using packet batching,
|
|
34
|
+
// this limits the number of messages processed, not the number of TCP packets.
|
|
35
|
+
static constexpr uint8_t MAX_MESSAGES_PER_LOOP = 5;
|
|
36
|
+
static constexpr uint8_t MAX_PING_RETRIES = 60;
|
|
37
|
+
static constexpr uint16_t PING_RETRY_INTERVAL = 1000;
|
|
38
|
+
static constexpr uint32_t KEEPALIVE_DISCONNECT_TIMEOUT = (KEEPALIVE_TIMEOUT_MS * 5) / 2;
|
|
39
|
+
|
|
31
40
|
static const char *const TAG = "api.connection";
|
|
32
|
-
|
|
41
|
+
#ifdef USE_CAMERA
|
|
42
|
+
static const int CAMERA_STOP_STREAM = 5000;
|
|
43
|
+
#endif
|
|
44
|
+
|
|
45
|
+
// Helper macro for entity command handlers - gets entity by key, returns if not found, and creates call object
|
|
46
|
+
#define ENTITY_COMMAND_MAKE_CALL(entity_type, entity_var, getter_name) \
|
|
47
|
+
entity_type *entity_var = App.get_##getter_name##_by_key(msg.key); \
|
|
48
|
+
if ((entity_var) == nullptr) \
|
|
49
|
+
return; \
|
|
50
|
+
auto call = (entity_var)->make_call();
|
|
51
|
+
|
|
52
|
+
// Helper macro for entity command handlers that don't use make_call() - gets entity by key and returns if not found
|
|
53
|
+
#define ENTITY_COMMAND_GET(entity_type, entity_var, getter_name) \
|
|
54
|
+
entity_type *entity_var = App.get_##getter_name##_by_key(msg.key); \
|
|
55
|
+
if ((entity_var) == nullptr) \
|
|
56
|
+
return;
|
|
33
57
|
|
|
34
58
|
APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *parent)
|
|
35
59
|
: parent_(parent), initial_state_iterator_(this), list_entities_iterator_(this) {
|
|
@@ -47,6 +71,11 @@ APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *pa
|
|
|
47
71
|
#else
|
|
48
72
|
#error "No frame helper defined"
|
|
49
73
|
#endif
|
|
74
|
+
#ifdef USE_CAMERA
|
|
75
|
+
if (camera::Camera::instance() != nullptr) {
|
|
76
|
+
this->image_reader_ = std::unique_ptr<camera::CameraImageReader>{camera::Camera::instance()->create_image_reader()};
|
|
77
|
+
}
|
|
78
|
+
#endif
|
|
50
79
|
}
|
|
51
80
|
|
|
52
81
|
uint32_t APIConnection::get_batch_delay_ms_() const { return this->parent_->get_batch_delay(); }
|
|
@@ -54,15 +83,11 @@ uint32_t APIConnection::get_batch_delay_ms_() const { return this->parent_->get_
|
|
|
54
83
|
void APIConnection::start() {
|
|
55
84
|
this->last_traffic_ = App.get_loop_component_start_time();
|
|
56
85
|
|
|
57
|
-
// Set next_ping_retry_ to prevent immediate ping
|
|
58
|
-
// This ensures the first ping happens after the keepalive period
|
|
59
|
-
this->next_ping_retry_ = this->last_traffic_ + KEEPALIVE_TIMEOUT_MS;
|
|
60
|
-
|
|
61
86
|
APIError err = this->helper_->init();
|
|
62
87
|
if (err != APIError::OK) {
|
|
63
88
|
on_fatal_error();
|
|
64
|
-
ESP_LOGW(TAG, "%s: Helper init failed: %s errno=%d", this->
|
|
65
|
-
errno);
|
|
89
|
+
ESP_LOGW(TAG, "%s: Helper init failed: %s errno=%d", this->get_client_combined_info().c_str(),
|
|
90
|
+
api_error_to_str(err), errno);
|
|
66
91
|
return;
|
|
67
92
|
}
|
|
68
93
|
this->client_info_ = helper_->getpeername();
|
|
@@ -84,104 +109,100 @@ APIConnection::~APIConnection() {
|
|
|
84
109
|
}
|
|
85
110
|
|
|
86
111
|
void APIConnection::loop() {
|
|
87
|
-
if (this->
|
|
88
|
-
return;
|
|
89
|
-
|
|
90
|
-
if (!network::is_connected()) {
|
|
91
|
-
// when network is disconnected force disconnect immediately
|
|
92
|
-
// don't wait for timeout
|
|
93
|
-
this->on_fatal_error();
|
|
94
|
-
ESP_LOGW(TAG, "%s: Network unavailable; disconnecting", this->client_combined_info_.c_str());
|
|
95
|
-
return;
|
|
96
|
-
}
|
|
97
|
-
if (this->next_close_) {
|
|
112
|
+
if (this->flags_.next_close) {
|
|
98
113
|
// requested a disconnect
|
|
99
114
|
this->helper_->close();
|
|
100
|
-
this->
|
|
115
|
+
this->flags_.remove = true;
|
|
101
116
|
return;
|
|
102
117
|
}
|
|
103
118
|
|
|
104
119
|
APIError err = this->helper_->loop();
|
|
105
120
|
if (err != APIError::OK) {
|
|
106
121
|
on_fatal_error();
|
|
107
|
-
ESP_LOGW(TAG, "%s: Socket operation failed: %s errno=%d", this->
|
|
122
|
+
ESP_LOGW(TAG, "%s: Socket operation failed: %s errno=%d", this->get_client_combined_info().c_str(),
|
|
108
123
|
api_error_to_str(err), errno);
|
|
109
124
|
return;
|
|
110
125
|
}
|
|
111
126
|
|
|
127
|
+
const uint32_t now = App.get_loop_component_start_time();
|
|
112
128
|
// Check if socket has data ready before attempting to read
|
|
113
129
|
if (this->helper_->is_socket_ready()) {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
if (buffer.data_len > 0) {
|
|
133
|
-
this->read_message(buffer.data_len, buffer.type, &buffer.container[buffer.data_offset]);
|
|
130
|
+
// Read up to MAX_MESSAGES_PER_LOOP messages per loop to improve throughput
|
|
131
|
+
for (uint8_t message_count = 0; message_count < MAX_MESSAGES_PER_LOOP; message_count++) {
|
|
132
|
+
ReadPacketBuffer buffer;
|
|
133
|
+
err = this->helper_->read_packet(&buffer);
|
|
134
|
+
if (err == APIError::WOULD_BLOCK) {
|
|
135
|
+
// No more data available
|
|
136
|
+
break;
|
|
137
|
+
} else if (err != APIError::OK) {
|
|
138
|
+
on_fatal_error();
|
|
139
|
+
if (err == APIError::SOCKET_READ_FAILED && errno == ECONNRESET) {
|
|
140
|
+
ESP_LOGW(TAG, "%s: Connection reset", this->get_client_combined_info().c_str());
|
|
141
|
+
} else if (err == APIError::CONNECTION_CLOSED) {
|
|
142
|
+
ESP_LOGW(TAG, "%s: Connection closed", this->get_client_combined_info().c_str());
|
|
143
|
+
} else {
|
|
144
|
+
ESP_LOGW(TAG, "%s: Reading failed: %s errno=%d", this->get_client_combined_info().c_str(),
|
|
145
|
+
api_error_to_str(err), errno);
|
|
146
|
+
}
|
|
147
|
+
return;
|
|
134
148
|
} else {
|
|
135
|
-
this->
|
|
149
|
+
this->last_traffic_ = now;
|
|
150
|
+
// read a packet
|
|
151
|
+
if (buffer.data_len > 0) {
|
|
152
|
+
this->read_message(buffer.data_len, buffer.type, &buffer.container[buffer.data_offset]);
|
|
153
|
+
} else {
|
|
154
|
+
this->read_message(0, buffer.type, nullptr);
|
|
155
|
+
}
|
|
156
|
+
if (this->flags_.remove)
|
|
157
|
+
return;
|
|
136
158
|
}
|
|
137
|
-
if (this->remove_)
|
|
138
|
-
return;
|
|
139
159
|
}
|
|
140
160
|
}
|
|
141
161
|
|
|
142
|
-
// Process deferred batch if scheduled
|
|
143
|
-
if (this->
|
|
144
|
-
App.get_loop_component_start_time() - this->deferred_batch_.batch_start_time >= this->get_batch_delay_ms_()) {
|
|
162
|
+
// Process deferred batch if scheduled and timer has expired
|
|
163
|
+
if (this->flags_.batch_scheduled && now - this->deferred_batch_.batch_start_time >= this->get_batch_delay_ms_()) {
|
|
145
164
|
this->process_batch_();
|
|
146
165
|
}
|
|
147
166
|
|
|
148
|
-
if (!this->list_entities_iterator_.completed())
|
|
149
|
-
this->list_entities_iterator_
|
|
150
|
-
if (!this->initial_state_iterator_.completed()
|
|
151
|
-
this->initial_state_iterator_
|
|
167
|
+
if (!this->list_entities_iterator_.completed()) {
|
|
168
|
+
this->process_iterator_batch_(this->list_entities_iterator_);
|
|
169
|
+
} else if (!this->initial_state_iterator_.completed()) {
|
|
170
|
+
this->process_iterator_batch_(this->initial_state_iterator_);
|
|
152
171
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
172
|
+
// If we've completed initial states, process any remaining and clear the flag
|
|
173
|
+
if (this->initial_state_iterator_.completed()) {
|
|
174
|
+
// Process any remaining batched messages immediately
|
|
175
|
+
if (!this->deferred_batch_.empty()) {
|
|
176
|
+
this->process_batch_();
|
|
177
|
+
}
|
|
178
|
+
// Now that everything is sent, enable immediate sending for future state changes
|
|
179
|
+
this->flags_.should_try_send_immediately = true;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (this->flags_.sent_ping) {
|
|
157
184
|
// Disconnect if not responded within 2.5*keepalive
|
|
158
|
-
if (now - this->last_traffic_ >
|
|
185
|
+
if (now - this->last_traffic_ > KEEPALIVE_DISCONNECT_TIMEOUT) {
|
|
159
186
|
on_fatal_error();
|
|
160
|
-
ESP_LOGW(TAG, "%s is unresponsive; disconnecting", this->
|
|
187
|
+
ESP_LOGW(TAG, "%s is unresponsive; disconnecting", this->get_client_combined_info().c_str());
|
|
161
188
|
}
|
|
162
|
-
} else if (now - this->last_traffic_ > KEEPALIVE_TIMEOUT_MS
|
|
189
|
+
} else if (now - this->last_traffic_ > KEEPALIVE_TIMEOUT_MS) {
|
|
163
190
|
ESP_LOGVV(TAG, "Sending keepalive PING");
|
|
164
|
-
this->
|
|
165
|
-
if (!this->
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
ESP_LOGE(TAG, "%s disconnecting", warn_str.c_str());
|
|
173
|
-
} else if (this->ping_retries_ >= 10) {
|
|
174
|
-
ESP_LOGW(TAG, "%s retrying in %u ms", warn_str.c_str(), ping_retry_interval);
|
|
175
|
-
} else {
|
|
176
|
-
ESP_LOGD(TAG, "%s retrying in %u ms", warn_str.c_str(), ping_retry_interval);
|
|
177
|
-
}
|
|
191
|
+
this->flags_.sent_ping = this->send_message(PingRequest());
|
|
192
|
+
if (!this->flags_.sent_ping) {
|
|
193
|
+
// If we can't send the ping request directly (tx_buffer full),
|
|
194
|
+
// schedule it at the front of the batch so it will be sent with priority
|
|
195
|
+
ESP_LOGW(TAG, "Buffer full, ping queued");
|
|
196
|
+
this->schedule_message_front_(nullptr, &APIConnection::try_send_ping_request, PingRequest::MESSAGE_TYPE,
|
|
197
|
+
PingRequest::ESTIMATED_SIZE);
|
|
198
|
+
this->flags_.sent_ping = true; // Mark as sent to avoid scheduling multiple pings
|
|
178
199
|
}
|
|
179
200
|
}
|
|
180
201
|
|
|
181
|
-
#ifdef
|
|
182
|
-
if (this->image_reader_
|
|
183
|
-
uint32_t to_send = std::min((size_t)
|
|
184
|
-
bool done = this->image_reader_
|
|
202
|
+
#ifdef USE_CAMERA
|
|
203
|
+
if (this->image_reader_ && this->image_reader_->available() && this->helper_->can_write_without_blocking()) {
|
|
204
|
+
uint32_t to_send = std::min((size_t) MAX_BATCH_PACKET_SIZE, this->image_reader_->available());
|
|
205
|
+
bool done = this->image_reader_->available() == to_send;
|
|
185
206
|
uint32_t msg_size = 0;
|
|
186
207
|
ProtoSize::add_fixed_field<4>(msg_size, 1, true);
|
|
187
208
|
// partial message size calculated manually since its a special case
|
|
@@ -191,28 +212,26 @@ void APIConnection::loop() {
|
|
|
191
212
|
|
|
192
213
|
auto buffer = this->create_buffer(msg_size);
|
|
193
214
|
// fixed32 key = 1;
|
|
194
|
-
buffer.encode_fixed32(1,
|
|
215
|
+
buffer.encode_fixed32(1, camera::Camera::instance()->get_object_id_hash());
|
|
195
216
|
// bytes data = 2;
|
|
196
|
-
buffer.encode_bytes(2, this->image_reader_
|
|
217
|
+
buffer.encode_bytes(2, this->image_reader_->peek_data_buffer(), to_send);
|
|
197
218
|
// bool done = 3;
|
|
198
219
|
buffer.encode_bool(3, done);
|
|
199
220
|
|
|
200
|
-
bool success = this->send_buffer(buffer,
|
|
221
|
+
bool success = this->send_buffer(buffer, CameraImageResponse::MESSAGE_TYPE);
|
|
201
222
|
|
|
202
223
|
if (success) {
|
|
203
|
-
this->image_reader_
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
224
|
+
this->image_reader_->consume_data(to_send);
|
|
225
|
+
if (done) {
|
|
226
|
+
this->image_reader_->return_image();
|
|
227
|
+
}
|
|
207
228
|
}
|
|
208
229
|
}
|
|
209
230
|
#endif
|
|
210
231
|
|
|
211
|
-
if (state_subs_at_
|
|
232
|
+
if (state_subs_at_ >= 0) {
|
|
212
233
|
const auto &subs = this->parent_->get_state_subs();
|
|
213
|
-
if (state_subs_at_
|
|
214
|
-
state_subs_at_ = -1;
|
|
215
|
-
} else {
|
|
234
|
+
if (state_subs_at_ < static_cast<int>(subs.size())) {
|
|
216
235
|
auto &it = subs[state_subs_at_];
|
|
217
236
|
SubscribeHomeAssistantStateResponse resp;
|
|
218
237
|
resp.entity_id = it.entity_id;
|
|
@@ -221,6 +240,8 @@ void APIConnection::loop() {
|
|
|
221
240
|
if (this->send_message(resp)) {
|
|
222
241
|
state_subs_at_++;
|
|
223
242
|
}
|
|
243
|
+
} else {
|
|
244
|
+
state_subs_at_ = -1;
|
|
224
245
|
}
|
|
225
246
|
}
|
|
226
247
|
}
|
|
@@ -233,20 +254,28 @@ DisconnectResponse APIConnection::disconnect(const DisconnectRequest &msg) {
|
|
|
233
254
|
// remote initiated disconnect_client
|
|
234
255
|
// don't close yet, we still need to send the disconnect response
|
|
235
256
|
// close will happen on next loop
|
|
236
|
-
ESP_LOGD(TAG, "%s disconnected", this->
|
|
237
|
-
this->
|
|
257
|
+
ESP_LOGD(TAG, "%s disconnected", this->get_client_combined_info().c_str());
|
|
258
|
+
this->flags_.next_close = true;
|
|
238
259
|
DisconnectResponse resp;
|
|
239
260
|
return resp;
|
|
240
261
|
}
|
|
241
262
|
void APIConnection::on_disconnect_response(const DisconnectResponse &value) {
|
|
242
263
|
this->helper_->close();
|
|
243
|
-
this->
|
|
264
|
+
this->flags_.remove = true;
|
|
244
265
|
}
|
|
245
266
|
|
|
246
267
|
// Encodes a message to the buffer and returns the total number of bytes used,
|
|
247
268
|
// including header and footer overhead. Returns 0 if the message doesn't fit.
|
|
248
|
-
uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg,
|
|
269
|
+
uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg, uint8_t message_type, APIConnection *conn,
|
|
249
270
|
uint32_t remaining_size, bool is_single) {
|
|
271
|
+
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
272
|
+
// If in log-only mode, just log and return
|
|
273
|
+
if (conn->flags_.log_only_mode) {
|
|
274
|
+
conn->log_send_message_(msg.message_name(), msg.dump());
|
|
275
|
+
return 1; // Return non-zero to indicate "success" for logging
|
|
276
|
+
}
|
|
277
|
+
#endif
|
|
278
|
+
|
|
250
279
|
// Calculate size
|
|
251
280
|
uint32_t calculated_size = 0;
|
|
252
281
|
msg.calculate_size(calculated_size);
|
|
@@ -287,12 +316,8 @@ uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg, uint16_t mes
|
|
|
287
316
|
|
|
288
317
|
#ifdef USE_BINARY_SENSOR
|
|
289
318
|
bool APIConnection::send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor) {
|
|
290
|
-
return this->
|
|
291
|
-
|
|
292
|
-
}
|
|
293
|
-
void APIConnection::send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor) {
|
|
294
|
-
this->schedule_message_(binary_sensor, &APIConnection::try_send_binary_sensor_info,
|
|
295
|
-
ListEntitiesBinarySensorResponse::MESSAGE_TYPE);
|
|
319
|
+
return this->send_message_smart_(binary_sensor, &APIConnection::try_send_binary_sensor_state,
|
|
320
|
+
BinarySensorStateResponse::MESSAGE_TYPE, BinarySensorStateResponse::ESTIMATED_SIZE);
|
|
296
321
|
}
|
|
297
322
|
|
|
298
323
|
uint16_t APIConnection::try_send_binary_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -319,10 +344,8 @@ uint16_t APIConnection::try_send_binary_sensor_info(EntityBase *entity, APIConne
|
|
|
319
344
|
|
|
320
345
|
#ifdef USE_COVER
|
|
321
346
|
bool APIConnection::send_cover_state(cover::Cover *cover) {
|
|
322
|
-
return this->
|
|
323
|
-
|
|
324
|
-
void APIConnection::send_cover_info(cover::Cover *cover) {
|
|
325
|
-
this->schedule_message_(cover, &APIConnection::try_send_cover_info, ListEntitiesCoverResponse::MESSAGE_TYPE);
|
|
347
|
+
return this->send_message_smart_(cover, &APIConnection::try_send_cover_state, CoverStateResponse::MESSAGE_TYPE,
|
|
348
|
+
CoverStateResponse::ESTIMATED_SIZE);
|
|
326
349
|
}
|
|
327
350
|
uint16_t APIConnection::try_send_cover_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
328
351
|
bool is_single) {
|
|
@@ -353,11 +376,7 @@ uint16_t APIConnection::try_send_cover_info(EntityBase *entity, APIConnection *c
|
|
|
353
376
|
return encode_message_to_buffer(msg, ListEntitiesCoverResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
354
377
|
}
|
|
355
378
|
void APIConnection::cover_command(const CoverCommandRequest &msg) {
|
|
356
|
-
cover::Cover
|
|
357
|
-
if (cover == nullptr)
|
|
358
|
-
return;
|
|
359
|
-
|
|
360
|
-
auto call = cover->make_call();
|
|
379
|
+
ENTITY_COMMAND_MAKE_CALL(cover::Cover, cover, cover)
|
|
361
380
|
if (msg.has_legacy_command) {
|
|
362
381
|
switch (msg.legacy_command) {
|
|
363
382
|
case enums::LEGACY_COVER_COMMAND_OPEN:
|
|
@@ -383,10 +402,8 @@ void APIConnection::cover_command(const CoverCommandRequest &msg) {
|
|
|
383
402
|
|
|
384
403
|
#ifdef USE_FAN
|
|
385
404
|
bool APIConnection::send_fan_state(fan::Fan *fan) {
|
|
386
|
-
return this->
|
|
387
|
-
|
|
388
|
-
void APIConnection::send_fan_info(fan::Fan *fan) {
|
|
389
|
-
this->schedule_message_(fan, &APIConnection::try_send_fan_info, ListEntitiesFanResponse::MESSAGE_TYPE);
|
|
405
|
+
return this->send_message_smart_(fan, &APIConnection::try_send_fan_state, FanStateResponse::MESSAGE_TYPE,
|
|
406
|
+
FanStateResponse::ESTIMATED_SIZE);
|
|
390
407
|
}
|
|
391
408
|
uint16_t APIConnection::try_send_fan_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
392
409
|
bool is_single) {
|
|
@@ -422,11 +439,7 @@ uint16_t APIConnection::try_send_fan_info(EntityBase *entity, APIConnection *con
|
|
|
422
439
|
return encode_message_to_buffer(msg, ListEntitiesFanResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
423
440
|
}
|
|
424
441
|
void APIConnection::fan_command(const FanCommandRequest &msg) {
|
|
425
|
-
fan::Fan
|
|
426
|
-
if (fan == nullptr)
|
|
427
|
-
return;
|
|
428
|
-
|
|
429
|
-
auto call = fan->make_call();
|
|
442
|
+
ENTITY_COMMAND_MAKE_CALL(fan::Fan, fan, fan)
|
|
430
443
|
if (msg.has_state)
|
|
431
444
|
call.set_state(msg.state);
|
|
432
445
|
if (msg.has_oscillating)
|
|
@@ -445,10 +458,8 @@ void APIConnection::fan_command(const FanCommandRequest &msg) {
|
|
|
445
458
|
|
|
446
459
|
#ifdef USE_LIGHT
|
|
447
460
|
bool APIConnection::send_light_state(light::LightState *light) {
|
|
448
|
-
return this->
|
|
449
|
-
|
|
450
|
-
void APIConnection::send_light_info(light::LightState *light) {
|
|
451
|
-
this->schedule_message_(light, &APIConnection::try_send_light_info, ListEntitiesLightResponse::MESSAGE_TYPE);
|
|
461
|
+
return this->send_message_smart_(light, &APIConnection::try_send_light_state, LightStateResponse::MESSAGE_TYPE,
|
|
462
|
+
LightStateResponse::ESTIMATED_SIZE);
|
|
452
463
|
}
|
|
453
464
|
uint16_t APIConnection::try_send_light_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
454
465
|
bool is_single) {
|
|
@@ -502,11 +513,7 @@ uint16_t APIConnection::try_send_light_info(EntityBase *entity, APIConnection *c
|
|
|
502
513
|
return encode_message_to_buffer(msg, ListEntitiesLightResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
503
514
|
}
|
|
504
515
|
void APIConnection::light_command(const LightCommandRequest &msg) {
|
|
505
|
-
light::LightState
|
|
506
|
-
if (light == nullptr)
|
|
507
|
-
return;
|
|
508
|
-
|
|
509
|
-
auto call = light->make_call();
|
|
516
|
+
ENTITY_COMMAND_MAKE_CALL(light::LightState, light, light)
|
|
510
517
|
if (msg.has_state)
|
|
511
518
|
call.set_state(msg.state);
|
|
512
519
|
if (msg.has_brightness)
|
|
@@ -540,10 +547,8 @@ void APIConnection::light_command(const LightCommandRequest &msg) {
|
|
|
540
547
|
|
|
541
548
|
#ifdef USE_SENSOR
|
|
542
549
|
bool APIConnection::send_sensor_state(sensor::Sensor *sensor) {
|
|
543
|
-
return this->
|
|
544
|
-
|
|
545
|
-
void APIConnection::send_sensor_info(sensor::Sensor *sensor) {
|
|
546
|
-
this->schedule_message_(sensor, &APIConnection::try_send_sensor_info, ListEntitiesSensorResponse::MESSAGE_TYPE);
|
|
550
|
+
return this->send_message_smart_(sensor, &APIConnection::try_send_sensor_state, SensorStateResponse::MESSAGE_TYPE,
|
|
551
|
+
SensorStateResponse::ESTIMATED_SIZE);
|
|
547
552
|
}
|
|
548
553
|
|
|
549
554
|
uint16_t APIConnection::try_send_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -575,10 +580,8 @@ uint16_t APIConnection::try_send_sensor_info(EntityBase *entity, APIConnection *
|
|
|
575
580
|
|
|
576
581
|
#ifdef USE_SWITCH
|
|
577
582
|
bool APIConnection::send_switch_state(switch_::Switch *a_switch) {
|
|
578
|
-
return this->
|
|
579
|
-
|
|
580
|
-
void APIConnection::send_switch_info(switch_::Switch *a_switch) {
|
|
581
|
-
this->schedule_message_(a_switch, &APIConnection::try_send_switch_info, ListEntitiesSwitchResponse::MESSAGE_TYPE);
|
|
583
|
+
return this->send_message_smart_(a_switch, &APIConnection::try_send_switch_state, SwitchStateResponse::MESSAGE_TYPE,
|
|
584
|
+
SwitchStateResponse::ESTIMATED_SIZE);
|
|
582
585
|
}
|
|
583
586
|
|
|
584
587
|
uint16_t APIConnection::try_send_switch_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -601,9 +604,7 @@ uint16_t APIConnection::try_send_switch_info(EntityBase *entity, APIConnection *
|
|
|
601
604
|
return encode_message_to_buffer(msg, ListEntitiesSwitchResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
602
605
|
}
|
|
603
606
|
void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
|
604
|
-
switch_::Switch
|
|
605
|
-
if (a_switch == nullptr)
|
|
606
|
-
return;
|
|
607
|
+
ENTITY_COMMAND_GET(switch_::Switch, a_switch, switch)
|
|
607
608
|
|
|
608
609
|
if (msg.state) {
|
|
609
610
|
a_switch->turn_on();
|
|
@@ -615,12 +616,8 @@ void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
|
|
615
616
|
|
|
616
617
|
#ifdef USE_TEXT_SENSOR
|
|
617
618
|
bool APIConnection::send_text_sensor_state(text_sensor::TextSensor *text_sensor) {
|
|
618
|
-
return this->
|
|
619
|
-
|
|
620
|
-
}
|
|
621
|
-
void APIConnection::send_text_sensor_info(text_sensor::TextSensor *text_sensor) {
|
|
622
|
-
this->schedule_message_(text_sensor, &APIConnection::try_send_text_sensor_info,
|
|
623
|
-
ListEntitiesTextSensorResponse::MESSAGE_TYPE);
|
|
619
|
+
return this->send_message_smart_(text_sensor, &APIConnection::try_send_text_sensor_state,
|
|
620
|
+
TextSensorStateResponse::MESSAGE_TYPE, TextSensorStateResponse::ESTIMATED_SIZE);
|
|
624
621
|
}
|
|
625
622
|
|
|
626
623
|
uint16_t APIConnection::try_send_text_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -647,7 +644,8 @@ uint16_t APIConnection::try_send_text_sensor_info(EntityBase *entity, APIConnect
|
|
|
647
644
|
|
|
648
645
|
#ifdef USE_CLIMATE
|
|
649
646
|
bool APIConnection::send_climate_state(climate::Climate *climate) {
|
|
650
|
-
return this->
|
|
647
|
+
return this->send_message_smart_(climate, &APIConnection::try_send_climate_state, ClimateStateResponse::MESSAGE_TYPE,
|
|
648
|
+
ClimateStateResponse::ESTIMATED_SIZE);
|
|
651
649
|
}
|
|
652
650
|
uint16_t APIConnection::try_send_climate_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
653
651
|
bool is_single) {
|
|
@@ -682,9 +680,6 @@ uint16_t APIConnection::try_send_climate_state(EntityBase *entity, APIConnection
|
|
|
682
680
|
resp.target_humidity = climate->target_humidity;
|
|
683
681
|
return encode_message_to_buffer(resp, ClimateStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
684
682
|
}
|
|
685
|
-
void APIConnection::send_climate_info(climate::Climate *climate) {
|
|
686
|
-
this->schedule_message_(climate, &APIConnection::try_send_climate_info, ListEntitiesClimateResponse::MESSAGE_TYPE);
|
|
687
|
-
}
|
|
688
683
|
uint16_t APIConnection::try_send_climate_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
689
684
|
bool is_single) {
|
|
690
685
|
auto *climate = static_cast<climate::Climate *>(entity);
|
|
@@ -719,11 +714,7 @@ uint16_t APIConnection::try_send_climate_info(EntityBase *entity, APIConnection
|
|
|
719
714
|
return encode_message_to_buffer(msg, ListEntitiesClimateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
720
715
|
}
|
|
721
716
|
void APIConnection::climate_command(const ClimateCommandRequest &msg) {
|
|
722
|
-
climate::Climate
|
|
723
|
-
if (climate == nullptr)
|
|
724
|
-
return;
|
|
725
|
-
|
|
726
|
-
auto call = climate->make_call();
|
|
717
|
+
ENTITY_COMMAND_MAKE_CALL(climate::Climate, climate, climate)
|
|
727
718
|
if (msg.has_mode)
|
|
728
719
|
call.set_mode(static_cast<climate::ClimateMode>(msg.mode));
|
|
729
720
|
if (msg.has_target_temperature)
|
|
@@ -750,10 +741,8 @@ void APIConnection::climate_command(const ClimateCommandRequest &msg) {
|
|
|
750
741
|
|
|
751
742
|
#ifdef USE_NUMBER
|
|
752
743
|
bool APIConnection::send_number_state(number::Number *number) {
|
|
753
|
-
return this->
|
|
754
|
-
|
|
755
|
-
void APIConnection::send_number_info(number::Number *number) {
|
|
756
|
-
this->schedule_message_(number, &APIConnection::try_send_number_info, ListEntitiesNumberResponse::MESSAGE_TYPE);
|
|
744
|
+
return this->send_message_smart_(number, &APIConnection::try_send_number_state, NumberStateResponse::MESSAGE_TYPE,
|
|
745
|
+
NumberStateResponse::ESTIMATED_SIZE);
|
|
757
746
|
}
|
|
758
747
|
|
|
759
748
|
uint16_t APIConnection::try_send_number_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -781,11 +770,7 @@ uint16_t APIConnection::try_send_number_info(EntityBase *entity, APIConnection *
|
|
|
781
770
|
return encode_message_to_buffer(msg, ListEntitiesNumberResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
782
771
|
}
|
|
783
772
|
void APIConnection::number_command(const NumberCommandRequest &msg) {
|
|
784
|
-
number::Number
|
|
785
|
-
if (number == nullptr)
|
|
786
|
-
return;
|
|
787
|
-
|
|
788
|
-
auto call = number->make_call();
|
|
773
|
+
ENTITY_COMMAND_MAKE_CALL(number::Number, number, number)
|
|
789
774
|
call.set_value(msg.state);
|
|
790
775
|
call.perform();
|
|
791
776
|
}
|
|
@@ -793,7 +778,8 @@ void APIConnection::number_command(const NumberCommandRequest &msg) {
|
|
|
793
778
|
|
|
794
779
|
#ifdef USE_DATETIME_DATE
|
|
795
780
|
bool APIConnection::send_date_state(datetime::DateEntity *date) {
|
|
796
|
-
return this->
|
|
781
|
+
return this->send_message_smart_(date, &APIConnection::try_send_date_state, DateStateResponse::MESSAGE_TYPE,
|
|
782
|
+
DateStateResponse::ESTIMATED_SIZE);
|
|
797
783
|
}
|
|
798
784
|
uint16_t APIConnection::try_send_date_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
799
785
|
bool is_single) {
|
|
@@ -806,9 +792,6 @@ uint16_t APIConnection::try_send_date_state(EntityBase *entity, APIConnection *c
|
|
|
806
792
|
fill_entity_state_base(date, resp);
|
|
807
793
|
return encode_message_to_buffer(resp, DateStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
808
794
|
}
|
|
809
|
-
void APIConnection::send_date_info(datetime::DateEntity *date) {
|
|
810
|
-
this->schedule_message_(date, &APIConnection::try_send_date_info, ListEntitiesDateResponse::MESSAGE_TYPE);
|
|
811
|
-
}
|
|
812
795
|
uint16_t APIConnection::try_send_date_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
813
796
|
bool is_single) {
|
|
814
797
|
auto *date = static_cast<datetime::DateEntity *>(entity);
|
|
@@ -818,11 +801,7 @@ uint16_t APIConnection::try_send_date_info(EntityBase *entity, APIConnection *co
|
|
|
818
801
|
return encode_message_to_buffer(msg, ListEntitiesDateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
819
802
|
}
|
|
820
803
|
void APIConnection::date_command(const DateCommandRequest &msg) {
|
|
821
|
-
datetime::DateEntity
|
|
822
|
-
if (date == nullptr)
|
|
823
|
-
return;
|
|
824
|
-
|
|
825
|
-
auto call = date->make_call();
|
|
804
|
+
ENTITY_COMMAND_MAKE_CALL(datetime::DateEntity, date, date)
|
|
826
805
|
call.set_date(msg.year, msg.month, msg.day);
|
|
827
806
|
call.perform();
|
|
828
807
|
}
|
|
@@ -830,7 +809,8 @@ void APIConnection::date_command(const DateCommandRequest &msg) {
|
|
|
830
809
|
|
|
831
810
|
#ifdef USE_DATETIME_TIME
|
|
832
811
|
bool APIConnection::send_time_state(datetime::TimeEntity *time) {
|
|
833
|
-
return this->
|
|
812
|
+
return this->send_message_smart_(time, &APIConnection::try_send_time_state, TimeStateResponse::MESSAGE_TYPE,
|
|
813
|
+
TimeStateResponse::ESTIMATED_SIZE);
|
|
834
814
|
}
|
|
835
815
|
uint16_t APIConnection::try_send_time_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
836
816
|
bool is_single) {
|
|
@@ -843,9 +823,6 @@ uint16_t APIConnection::try_send_time_state(EntityBase *entity, APIConnection *c
|
|
|
843
823
|
fill_entity_state_base(time, resp);
|
|
844
824
|
return encode_message_to_buffer(resp, TimeStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
845
825
|
}
|
|
846
|
-
void APIConnection::send_time_info(datetime::TimeEntity *time) {
|
|
847
|
-
this->schedule_message_(time, &APIConnection::try_send_time_info, ListEntitiesTimeResponse::MESSAGE_TYPE);
|
|
848
|
-
}
|
|
849
826
|
uint16_t APIConnection::try_send_time_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
850
827
|
bool is_single) {
|
|
851
828
|
auto *time = static_cast<datetime::TimeEntity *>(entity);
|
|
@@ -855,11 +832,7 @@ uint16_t APIConnection::try_send_time_info(EntityBase *entity, APIConnection *co
|
|
|
855
832
|
return encode_message_to_buffer(msg, ListEntitiesTimeResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
856
833
|
}
|
|
857
834
|
void APIConnection::time_command(const TimeCommandRequest &msg) {
|
|
858
|
-
datetime::TimeEntity
|
|
859
|
-
if (time == nullptr)
|
|
860
|
-
return;
|
|
861
|
-
|
|
862
|
-
auto call = time->make_call();
|
|
835
|
+
ENTITY_COMMAND_MAKE_CALL(datetime::TimeEntity, time, time)
|
|
863
836
|
call.set_time(msg.hour, msg.minute, msg.second);
|
|
864
837
|
call.perform();
|
|
865
838
|
}
|
|
@@ -867,8 +840,8 @@ void APIConnection::time_command(const TimeCommandRequest &msg) {
|
|
|
867
840
|
|
|
868
841
|
#ifdef USE_DATETIME_DATETIME
|
|
869
842
|
bool APIConnection::send_datetime_state(datetime::DateTimeEntity *datetime) {
|
|
870
|
-
return this->
|
|
871
|
-
|
|
843
|
+
return this->send_message_smart_(datetime, &APIConnection::try_send_datetime_state,
|
|
844
|
+
DateTimeStateResponse::MESSAGE_TYPE, DateTimeStateResponse::ESTIMATED_SIZE);
|
|
872
845
|
}
|
|
873
846
|
uint16_t APIConnection::try_send_datetime_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
874
847
|
bool is_single) {
|
|
@@ -882,9 +855,6 @@ uint16_t APIConnection::try_send_datetime_state(EntityBase *entity, APIConnectio
|
|
|
882
855
|
fill_entity_state_base(datetime, resp);
|
|
883
856
|
return encode_message_to_buffer(resp, DateTimeStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
884
857
|
}
|
|
885
|
-
void APIConnection::send_datetime_info(datetime::DateTimeEntity *datetime) {
|
|
886
|
-
this->schedule_message_(datetime, &APIConnection::try_send_datetime_info, ListEntitiesDateTimeResponse::MESSAGE_TYPE);
|
|
887
|
-
}
|
|
888
858
|
uint16_t APIConnection::try_send_datetime_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
889
859
|
bool is_single) {
|
|
890
860
|
auto *datetime = static_cast<datetime::DateTimeEntity *>(entity);
|
|
@@ -894,11 +864,7 @@ uint16_t APIConnection::try_send_datetime_info(EntityBase *entity, APIConnection
|
|
|
894
864
|
return encode_message_to_buffer(msg, ListEntitiesDateTimeResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
895
865
|
}
|
|
896
866
|
void APIConnection::datetime_command(const DateTimeCommandRequest &msg) {
|
|
897
|
-
datetime::DateTimeEntity
|
|
898
|
-
if (datetime == nullptr)
|
|
899
|
-
return;
|
|
900
|
-
|
|
901
|
-
auto call = datetime->make_call();
|
|
867
|
+
ENTITY_COMMAND_MAKE_CALL(datetime::DateTimeEntity, datetime, datetime)
|
|
902
868
|
call.set_datetime(msg.epoch_seconds);
|
|
903
869
|
call.perform();
|
|
904
870
|
}
|
|
@@ -906,10 +872,8 @@ void APIConnection::datetime_command(const DateTimeCommandRequest &msg) {
|
|
|
906
872
|
|
|
907
873
|
#ifdef USE_TEXT
|
|
908
874
|
bool APIConnection::send_text_state(text::Text *text) {
|
|
909
|
-
return this->
|
|
910
|
-
|
|
911
|
-
void APIConnection::send_text_info(text::Text *text) {
|
|
912
|
-
this->schedule_message_(text, &APIConnection::try_send_text_info, ListEntitiesTextResponse::MESSAGE_TYPE);
|
|
875
|
+
return this->send_message_smart_(text, &APIConnection::try_send_text_state, TextStateResponse::MESSAGE_TYPE,
|
|
876
|
+
TextStateResponse::ESTIMATED_SIZE);
|
|
913
877
|
}
|
|
914
878
|
|
|
915
879
|
uint16_t APIConnection::try_send_text_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -935,11 +899,7 @@ uint16_t APIConnection::try_send_text_info(EntityBase *entity, APIConnection *co
|
|
|
935
899
|
return encode_message_to_buffer(msg, ListEntitiesTextResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
936
900
|
}
|
|
937
901
|
void APIConnection::text_command(const TextCommandRequest &msg) {
|
|
938
|
-
text::Text
|
|
939
|
-
if (text == nullptr)
|
|
940
|
-
return;
|
|
941
|
-
|
|
942
|
-
auto call = text->make_call();
|
|
902
|
+
ENTITY_COMMAND_MAKE_CALL(text::Text, text, text)
|
|
943
903
|
call.set_value(msg.state);
|
|
944
904
|
call.perform();
|
|
945
905
|
}
|
|
@@ -947,10 +907,8 @@ void APIConnection::text_command(const TextCommandRequest &msg) {
|
|
|
947
907
|
|
|
948
908
|
#ifdef USE_SELECT
|
|
949
909
|
bool APIConnection::send_select_state(select::Select *select) {
|
|
950
|
-
return this->
|
|
951
|
-
|
|
952
|
-
void APIConnection::send_select_info(select::Select *select) {
|
|
953
|
-
this->schedule_message_(select, &APIConnection::try_send_select_info, ListEntitiesSelectResponse::MESSAGE_TYPE);
|
|
910
|
+
return this->send_message_smart_(select, &APIConnection::try_send_select_state, SelectStateResponse::MESSAGE_TYPE,
|
|
911
|
+
SelectStateResponse::ESTIMATED_SIZE);
|
|
954
912
|
}
|
|
955
913
|
|
|
956
914
|
uint16_t APIConnection::try_send_select_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -974,20 +932,13 @@ uint16_t APIConnection::try_send_select_info(EntityBase *entity, APIConnection *
|
|
|
974
932
|
return encode_message_to_buffer(msg, ListEntitiesSelectResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
975
933
|
}
|
|
976
934
|
void APIConnection::select_command(const SelectCommandRequest &msg) {
|
|
977
|
-
select::Select
|
|
978
|
-
if (select == nullptr)
|
|
979
|
-
return;
|
|
980
|
-
|
|
981
|
-
auto call = select->make_call();
|
|
935
|
+
ENTITY_COMMAND_MAKE_CALL(select::Select, select, select)
|
|
982
936
|
call.set_option(msg.state);
|
|
983
937
|
call.perform();
|
|
984
938
|
}
|
|
985
939
|
#endif
|
|
986
940
|
|
|
987
941
|
#ifdef USE_BUTTON
|
|
988
|
-
void esphome::api::APIConnection::send_button_info(button::Button *button) {
|
|
989
|
-
this->schedule_message_(button, &APIConnection::try_send_button_info, ListEntitiesButtonResponse::MESSAGE_TYPE);
|
|
990
|
-
}
|
|
991
942
|
uint16_t APIConnection::try_send_button_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
992
943
|
bool is_single) {
|
|
993
944
|
auto *button = static_cast<button::Button *>(entity);
|
|
@@ -998,20 +949,15 @@ uint16_t APIConnection::try_send_button_info(EntityBase *entity, APIConnection *
|
|
|
998
949
|
return encode_message_to_buffer(msg, ListEntitiesButtonResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
999
950
|
}
|
|
1000
951
|
void esphome::api::APIConnection::button_command(const ButtonCommandRequest &msg) {
|
|
1001
|
-
button::Button
|
|
1002
|
-
if (button == nullptr)
|
|
1003
|
-
return;
|
|
1004
|
-
|
|
952
|
+
ENTITY_COMMAND_GET(button::Button, button, button)
|
|
1005
953
|
button->press();
|
|
1006
954
|
}
|
|
1007
955
|
#endif
|
|
1008
956
|
|
|
1009
957
|
#ifdef USE_LOCK
|
|
1010
958
|
bool APIConnection::send_lock_state(lock::Lock *a_lock) {
|
|
1011
|
-
return this->
|
|
1012
|
-
|
|
1013
|
-
void APIConnection::send_lock_info(lock::Lock *a_lock) {
|
|
1014
|
-
this->schedule_message_(a_lock, &APIConnection::try_send_lock_info, ListEntitiesLockResponse::MESSAGE_TYPE);
|
|
959
|
+
return this->send_message_smart_(a_lock, &APIConnection::try_send_lock_state, LockStateResponse::MESSAGE_TYPE,
|
|
960
|
+
LockStateResponse::ESTIMATED_SIZE);
|
|
1015
961
|
}
|
|
1016
962
|
|
|
1017
963
|
uint16_t APIConnection::try_send_lock_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -1035,9 +981,7 @@ uint16_t APIConnection::try_send_lock_info(EntityBase *entity, APIConnection *co
|
|
|
1035
981
|
return encode_message_to_buffer(msg, ListEntitiesLockResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
1036
982
|
}
|
|
1037
983
|
void APIConnection::lock_command(const LockCommandRequest &msg) {
|
|
1038
|
-
lock::Lock
|
|
1039
|
-
if (a_lock == nullptr)
|
|
1040
|
-
return;
|
|
984
|
+
ENTITY_COMMAND_GET(lock::Lock, a_lock, lock)
|
|
1041
985
|
|
|
1042
986
|
switch (msg.command) {
|
|
1043
987
|
case enums::LOCK_UNLOCK:
|
|
@@ -1055,7 +999,8 @@ void APIConnection::lock_command(const LockCommandRequest &msg) {
|
|
|
1055
999
|
|
|
1056
1000
|
#ifdef USE_VALVE
|
|
1057
1001
|
bool APIConnection::send_valve_state(valve::Valve *valve) {
|
|
1058
|
-
return this->
|
|
1002
|
+
return this->send_message_smart_(valve, &APIConnection::try_send_valve_state, ValveStateResponse::MESSAGE_TYPE,
|
|
1003
|
+
ValveStateResponse::ESTIMATED_SIZE);
|
|
1059
1004
|
}
|
|
1060
1005
|
uint16_t APIConnection::try_send_valve_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1061
1006
|
bool is_single) {
|
|
@@ -1066,9 +1011,6 @@ uint16_t APIConnection::try_send_valve_state(EntityBase *entity, APIConnection *
|
|
|
1066
1011
|
fill_entity_state_base(valve, resp);
|
|
1067
1012
|
return encode_message_to_buffer(resp, ValveStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
1068
1013
|
}
|
|
1069
|
-
void APIConnection::send_valve_info(valve::Valve *valve) {
|
|
1070
|
-
this->schedule_message_(valve, &APIConnection::try_send_valve_info, ListEntitiesValveResponse::MESSAGE_TYPE);
|
|
1071
|
-
}
|
|
1072
1014
|
uint16_t APIConnection::try_send_valve_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1073
1015
|
bool is_single) {
|
|
1074
1016
|
auto *valve = static_cast<valve::Valve *>(entity);
|
|
@@ -1083,11 +1025,7 @@ uint16_t APIConnection::try_send_valve_info(EntityBase *entity, APIConnection *c
|
|
|
1083
1025
|
return encode_message_to_buffer(msg, ListEntitiesValveResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
1084
1026
|
}
|
|
1085
1027
|
void APIConnection::valve_command(const ValveCommandRequest &msg) {
|
|
1086
|
-
valve::Valve
|
|
1087
|
-
if (valve == nullptr)
|
|
1088
|
-
return;
|
|
1089
|
-
|
|
1090
|
-
auto call = valve->make_call();
|
|
1028
|
+
ENTITY_COMMAND_MAKE_CALL(valve::Valve, valve, valve)
|
|
1091
1029
|
if (msg.has_position)
|
|
1092
1030
|
call.set_position(msg.position);
|
|
1093
1031
|
if (msg.stop)
|
|
@@ -1098,8 +1036,8 @@ void APIConnection::valve_command(const ValveCommandRequest &msg) {
|
|
|
1098
1036
|
|
|
1099
1037
|
#ifdef USE_MEDIA_PLAYER
|
|
1100
1038
|
bool APIConnection::send_media_player_state(media_player::MediaPlayer *media_player) {
|
|
1101
|
-
return this->
|
|
1102
|
-
|
|
1039
|
+
return this->send_message_smart_(media_player, &APIConnection::try_send_media_player_state,
|
|
1040
|
+
MediaPlayerStateResponse::MESSAGE_TYPE, MediaPlayerStateResponse::ESTIMATED_SIZE);
|
|
1103
1041
|
}
|
|
1104
1042
|
uint16_t APIConnection::try_send_media_player_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1105
1043
|
bool is_single) {
|
|
@@ -1114,10 +1052,6 @@ uint16_t APIConnection::try_send_media_player_state(EntityBase *entity, APIConne
|
|
|
1114
1052
|
fill_entity_state_base(media_player, resp);
|
|
1115
1053
|
return encode_message_to_buffer(resp, MediaPlayerStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
1116
1054
|
}
|
|
1117
|
-
void APIConnection::send_media_player_info(media_player::MediaPlayer *media_player) {
|
|
1118
|
-
this->schedule_message_(media_player, &APIConnection::try_send_media_player_info,
|
|
1119
|
-
ListEntitiesMediaPlayerResponse::MESSAGE_TYPE);
|
|
1120
|
-
}
|
|
1121
1055
|
uint16_t APIConnection::try_send_media_player_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1122
1056
|
bool is_single) {
|
|
1123
1057
|
auto *media_player = static_cast<media_player::MediaPlayer *>(entity);
|
|
@@ -1138,11 +1072,7 @@ uint16_t APIConnection::try_send_media_player_info(EntityBase *entity, APIConnec
|
|
|
1138
1072
|
return encode_message_to_buffer(msg, ListEntitiesMediaPlayerResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
1139
1073
|
}
|
|
1140
1074
|
void APIConnection::media_player_command(const MediaPlayerCommandRequest &msg) {
|
|
1141
|
-
media_player::MediaPlayer
|
|
1142
|
-
if (media_player == nullptr)
|
|
1143
|
-
return;
|
|
1144
|
-
|
|
1145
|
-
auto call = media_player->make_call();
|
|
1075
|
+
ENTITY_COMMAND_MAKE_CALL(media_player::MediaPlayer, media_player, media_player)
|
|
1146
1076
|
if (msg.has_command) {
|
|
1147
1077
|
call.set_command(static_cast<media_player::MediaPlayerCommand>(msg.command));
|
|
1148
1078
|
}
|
|
@@ -1159,39 +1089,36 @@ void APIConnection::media_player_command(const MediaPlayerCommandRequest &msg) {
|
|
|
1159
1089
|
}
|
|
1160
1090
|
#endif
|
|
1161
1091
|
|
|
1162
|
-
#ifdef
|
|
1163
|
-
void APIConnection::set_camera_state(std::shared_ptr<
|
|
1164
|
-
if (!this->
|
|
1092
|
+
#ifdef USE_CAMERA
|
|
1093
|
+
void APIConnection::set_camera_state(std::shared_ptr<camera::CameraImage> image) {
|
|
1094
|
+
if (!this->flags_.state_subscription)
|
|
1165
1095
|
return;
|
|
1166
|
-
if (this->image_reader_
|
|
1096
|
+
if (!this->image_reader_)
|
|
1167
1097
|
return;
|
|
1168
|
-
if (
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
void APIConnection::send_camera_info(esp32_camera::ESP32Camera *camera) {
|
|
1173
|
-
this->schedule_message_(camera, &APIConnection::try_send_camera_info, ListEntitiesCameraResponse::MESSAGE_TYPE);
|
|
1098
|
+
if (this->image_reader_->available())
|
|
1099
|
+
return;
|
|
1100
|
+
if (image->was_requested_by(esphome::camera::API_REQUESTER) || image->was_requested_by(esphome::camera::IDLE))
|
|
1101
|
+
this->image_reader_->set_image(std::move(image));
|
|
1174
1102
|
}
|
|
1175
1103
|
uint16_t APIConnection::try_send_camera_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1176
1104
|
bool is_single) {
|
|
1177
|
-
auto *camera = static_cast<
|
|
1105
|
+
auto *camera = static_cast<camera::Camera *>(entity);
|
|
1178
1106
|
ListEntitiesCameraResponse msg;
|
|
1179
1107
|
msg.unique_id = get_default_unique_id("camera", camera);
|
|
1180
1108
|
fill_entity_info_base(camera, msg);
|
|
1181
1109
|
return encode_message_to_buffer(msg, ListEntitiesCameraResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
1182
1110
|
}
|
|
1183
1111
|
void APIConnection::camera_image(const CameraImageRequest &msg) {
|
|
1184
|
-
if (
|
|
1112
|
+
if (camera::Camera::instance() == nullptr)
|
|
1185
1113
|
return;
|
|
1186
1114
|
|
|
1187
1115
|
if (msg.single)
|
|
1188
|
-
|
|
1116
|
+
camera::Camera::instance()->request_image(esphome::camera::API_REQUESTER);
|
|
1189
1117
|
if (msg.stream) {
|
|
1190
|
-
|
|
1118
|
+
camera::Camera::instance()->start_stream(esphome::camera::API_REQUESTER);
|
|
1191
1119
|
|
|
1192
|
-
App.scheduler.set_timeout(this->parent_, "
|
|
1193
|
-
|
|
1194
|
-
});
|
|
1120
|
+
App.scheduler.set_timeout(this->parent_, "api_camera_stop_stream", CAMERA_STOP_STREAM,
|
|
1121
|
+
[]() { camera::Camera::instance()->stop_stream(esphome::camera::API_REQUESTER); });
|
|
1195
1122
|
}
|
|
1196
1123
|
}
|
|
1197
1124
|
#endif
|
|
@@ -1263,66 +1190,53 @@ void APIConnection::bluetooth_scanner_set_mode(const BluetoothScannerSetModeRequ
|
|
|
1263
1190
|
#endif
|
|
1264
1191
|
|
|
1265
1192
|
#ifdef USE_VOICE_ASSISTANT
|
|
1193
|
+
bool APIConnection::check_voice_assistant_api_connection_() const {
|
|
1194
|
+
return voice_assistant::global_voice_assistant != nullptr &&
|
|
1195
|
+
voice_assistant::global_voice_assistant->get_api_connection() == this;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1266
1198
|
void APIConnection::subscribe_voice_assistant(const SubscribeVoiceAssistantRequest &msg) {
|
|
1267
1199
|
if (voice_assistant::global_voice_assistant != nullptr) {
|
|
1268
1200
|
voice_assistant::global_voice_assistant->client_subscription(this, msg.subscribe);
|
|
1269
1201
|
}
|
|
1270
1202
|
}
|
|
1271
1203
|
void APIConnection::on_voice_assistant_response(const VoiceAssistantResponse &msg) {
|
|
1272
|
-
if (
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
}
|
|
1204
|
+
if (!this->check_voice_assistant_api_connection_()) {
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1276
1207
|
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
}
|
|
1208
|
+
if (msg.error) {
|
|
1209
|
+
voice_assistant::global_voice_assistant->failed_to_start();
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
if (msg.port == 0) {
|
|
1213
|
+
// Use API Audio
|
|
1214
|
+
voice_assistant::global_voice_assistant->start_streaming();
|
|
1215
|
+
} else {
|
|
1216
|
+
struct sockaddr_storage storage;
|
|
1217
|
+
socklen_t len = sizeof(storage);
|
|
1218
|
+
this->helper_->getpeername((struct sockaddr *) &storage, &len);
|
|
1219
|
+
voice_assistant::global_voice_assistant->start_streaming(&storage, msg.port);
|
|
1290
1220
|
}
|
|
1291
1221
|
};
|
|
1292
1222
|
void APIConnection::on_voice_assistant_event_response(const VoiceAssistantEventResponse &msg) {
|
|
1293
|
-
if (
|
|
1294
|
-
if (voice_assistant::global_voice_assistant->get_api_connection() != this) {
|
|
1295
|
-
return;
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1223
|
+
if (this->check_voice_assistant_api_connection_()) {
|
|
1298
1224
|
voice_assistant::global_voice_assistant->on_event(msg);
|
|
1299
1225
|
}
|
|
1300
1226
|
}
|
|
1301
1227
|
void APIConnection::on_voice_assistant_audio(const VoiceAssistantAudio &msg) {
|
|
1302
|
-
if (
|
|
1303
|
-
if (voice_assistant::global_voice_assistant->get_api_connection() != this) {
|
|
1304
|
-
return;
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1228
|
+
if (this->check_voice_assistant_api_connection_()) {
|
|
1307
1229
|
voice_assistant::global_voice_assistant->on_audio(msg);
|
|
1308
1230
|
}
|
|
1309
1231
|
};
|
|
1310
1232
|
void APIConnection::on_voice_assistant_timer_event_response(const VoiceAssistantTimerEventResponse &msg) {
|
|
1311
|
-
if (
|
|
1312
|
-
if (voice_assistant::global_voice_assistant->get_api_connection() != this) {
|
|
1313
|
-
return;
|
|
1314
|
-
}
|
|
1315
|
-
|
|
1233
|
+
if (this->check_voice_assistant_api_connection_()) {
|
|
1316
1234
|
voice_assistant::global_voice_assistant->on_timer_event(msg);
|
|
1317
1235
|
}
|
|
1318
1236
|
};
|
|
1319
1237
|
|
|
1320
1238
|
void APIConnection::on_voice_assistant_announce_request(const VoiceAssistantAnnounceRequest &msg) {
|
|
1321
|
-
if (
|
|
1322
|
-
if (voice_assistant::global_voice_assistant->get_api_connection() != this) {
|
|
1323
|
-
return;
|
|
1324
|
-
}
|
|
1325
|
-
|
|
1239
|
+
if (this->check_voice_assistant_api_connection_()) {
|
|
1326
1240
|
voice_assistant::global_voice_assistant->on_announce(msg);
|
|
1327
1241
|
}
|
|
1328
1242
|
}
|
|
@@ -1330,35 +1244,29 @@ void APIConnection::on_voice_assistant_announce_request(const VoiceAssistantAnno
|
|
|
1330
1244
|
VoiceAssistantConfigurationResponse APIConnection::voice_assistant_get_configuration(
|
|
1331
1245
|
const VoiceAssistantConfigurationRequest &msg) {
|
|
1332
1246
|
VoiceAssistantConfigurationResponse resp;
|
|
1333
|
-
if (
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
}
|
|
1247
|
+
if (!this->check_voice_assistant_api_connection_()) {
|
|
1248
|
+
return resp;
|
|
1249
|
+
}
|
|
1337
1250
|
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
}
|
|
1346
|
-
resp.available_wake_words.push_back(std::move(resp_wake_word));
|
|
1347
|
-
}
|
|
1348
|
-
for (auto &wake_word_id : config.active_wake_words) {
|
|
1349
|
-
resp.active_wake_words.push_back(wake_word_id);
|
|
1251
|
+
auto &config = voice_assistant::global_voice_assistant->get_configuration();
|
|
1252
|
+
for (auto &wake_word : config.available_wake_words) {
|
|
1253
|
+
VoiceAssistantWakeWord resp_wake_word;
|
|
1254
|
+
resp_wake_word.id = wake_word.id;
|
|
1255
|
+
resp_wake_word.wake_word = wake_word.wake_word;
|
|
1256
|
+
for (const auto &lang : wake_word.trained_languages) {
|
|
1257
|
+
resp_wake_word.trained_languages.push_back(lang);
|
|
1350
1258
|
}
|
|
1351
|
-
resp.
|
|
1259
|
+
resp.available_wake_words.push_back(std::move(resp_wake_word));
|
|
1260
|
+
}
|
|
1261
|
+
for (auto &wake_word_id : config.active_wake_words) {
|
|
1262
|
+
resp.active_wake_words.push_back(wake_word_id);
|
|
1352
1263
|
}
|
|
1264
|
+
resp.max_active_wake_words = config.max_active_wake_words;
|
|
1353
1265
|
return resp;
|
|
1354
1266
|
}
|
|
1355
1267
|
|
|
1356
1268
|
void APIConnection::voice_assistant_set_configuration(const VoiceAssistantSetConfiguration &msg) {
|
|
1357
|
-
if (
|
|
1358
|
-
if (voice_assistant::global_voice_assistant->get_api_connection() != this) {
|
|
1359
|
-
return;
|
|
1360
|
-
}
|
|
1361
|
-
|
|
1269
|
+
if (this->check_voice_assistant_api_connection_()) {
|
|
1362
1270
|
voice_assistant::global_voice_assistant->on_set_configuration(msg.active_wake_words);
|
|
1363
1271
|
}
|
|
1364
1272
|
}
|
|
@@ -1367,8 +1275,9 @@ void APIConnection::voice_assistant_set_configuration(const VoiceAssistantSetCon
|
|
|
1367
1275
|
|
|
1368
1276
|
#ifdef USE_ALARM_CONTROL_PANEL
|
|
1369
1277
|
bool APIConnection::send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
|
1370
|
-
return this->
|
|
1371
|
-
|
|
1278
|
+
return this->send_message_smart_(a_alarm_control_panel, &APIConnection::try_send_alarm_control_panel_state,
|
|
1279
|
+
AlarmControlPanelStateResponse::MESSAGE_TYPE,
|
|
1280
|
+
AlarmControlPanelStateResponse::ESTIMATED_SIZE);
|
|
1372
1281
|
}
|
|
1373
1282
|
uint16_t APIConnection::try_send_alarm_control_panel_state(EntityBase *entity, APIConnection *conn,
|
|
1374
1283
|
uint32_t remaining_size, bool is_single) {
|
|
@@ -1378,10 +1287,6 @@ uint16_t APIConnection::try_send_alarm_control_panel_state(EntityBase *entity, A
|
|
|
1378
1287
|
fill_entity_state_base(a_alarm_control_panel, resp);
|
|
1379
1288
|
return encode_message_to_buffer(resp, AlarmControlPanelStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
1380
1289
|
}
|
|
1381
|
-
void APIConnection::send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
|
1382
|
-
this->schedule_message_(a_alarm_control_panel, &APIConnection::try_send_alarm_control_panel_info,
|
|
1383
|
-
ListEntitiesAlarmControlPanelResponse::MESSAGE_TYPE);
|
|
1384
|
-
}
|
|
1385
1290
|
uint16_t APIConnection::try_send_alarm_control_panel_info(EntityBase *entity, APIConnection *conn,
|
|
1386
1291
|
uint32_t remaining_size, bool is_single) {
|
|
1387
1292
|
auto *a_alarm_control_panel = static_cast<alarm_control_panel::AlarmControlPanel *>(entity);
|
|
@@ -1395,11 +1300,7 @@ uint16_t APIConnection::try_send_alarm_control_panel_info(EntityBase *entity, AP
|
|
|
1395
1300
|
is_single);
|
|
1396
1301
|
}
|
|
1397
1302
|
void APIConnection::alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) {
|
|
1398
|
-
alarm_control_panel::AlarmControlPanel
|
|
1399
|
-
if (a_alarm_control_panel == nullptr)
|
|
1400
|
-
return;
|
|
1401
|
-
|
|
1402
|
-
auto call = a_alarm_control_panel->make_call();
|
|
1303
|
+
ENTITY_COMMAND_MAKE_CALL(alarm_control_panel::AlarmControlPanel, a_alarm_control_panel, alarm_control_panel)
|
|
1403
1304
|
switch (msg.command) {
|
|
1404
1305
|
case enums::ALARM_CONTROL_PANEL_DISARM:
|
|
1405
1306
|
call.disarm();
|
|
@@ -1430,10 +1331,8 @@ void APIConnection::alarm_control_panel_command(const AlarmControlPanelCommandRe
|
|
|
1430
1331
|
|
|
1431
1332
|
#ifdef USE_EVENT
|
|
1432
1333
|
void APIConnection::send_event(event::Event *event, const std::string &event_type) {
|
|
1433
|
-
this->schedule_message_(event, MessageCreator(event_type, EventResponse::MESSAGE_TYPE
|
|
1434
|
-
|
|
1435
|
-
void APIConnection::send_event_info(event::Event *event) {
|
|
1436
|
-
this->schedule_message_(event, &APIConnection::try_send_event_info, ListEntitiesEventResponse::MESSAGE_TYPE);
|
|
1334
|
+
this->schedule_message_(event, MessageCreator(event_type), EventResponse::MESSAGE_TYPE,
|
|
1335
|
+
EventResponse::ESTIMATED_SIZE);
|
|
1437
1336
|
}
|
|
1438
1337
|
uint16_t APIConnection::try_send_event_response(event::Event *event, const std::string &event_type, APIConnection *conn,
|
|
1439
1338
|
uint32_t remaining_size, bool is_single) {
|
|
@@ -1458,7 +1357,8 @@ uint16_t APIConnection::try_send_event_info(EntityBase *entity, APIConnection *c
|
|
|
1458
1357
|
|
|
1459
1358
|
#ifdef USE_UPDATE
|
|
1460
1359
|
bool APIConnection::send_update_state(update::UpdateEntity *update) {
|
|
1461
|
-
return this->
|
|
1360
|
+
return this->send_message_smart_(update, &APIConnection::try_send_update_state, UpdateStateResponse::MESSAGE_TYPE,
|
|
1361
|
+
UpdateStateResponse::ESTIMATED_SIZE);
|
|
1462
1362
|
}
|
|
1463
1363
|
uint16_t APIConnection::try_send_update_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1464
1364
|
bool is_single) {
|
|
@@ -1480,9 +1380,6 @@ uint16_t APIConnection::try_send_update_state(EntityBase *entity, APIConnection
|
|
|
1480
1380
|
fill_entity_state_base(update, resp);
|
|
1481
1381
|
return encode_message_to_buffer(resp, UpdateStateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
1482
1382
|
}
|
|
1483
|
-
void APIConnection::send_update_info(update::UpdateEntity *update) {
|
|
1484
|
-
this->schedule_message_(update, &APIConnection::try_send_update_info, ListEntitiesUpdateResponse::MESSAGE_TYPE);
|
|
1485
|
-
}
|
|
1486
1383
|
uint16_t APIConnection::try_send_update_info(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1487
1384
|
bool is_single) {
|
|
1488
1385
|
auto *update = static_cast<update::UpdateEntity *>(entity);
|
|
@@ -1493,9 +1390,7 @@ uint16_t APIConnection::try_send_update_info(EntityBase *entity, APIConnection *
|
|
|
1493
1390
|
return encode_message_to_buffer(msg, ListEntitiesUpdateResponse::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
1494
1391
|
}
|
|
1495
1392
|
void APIConnection::update_command(const UpdateCommandRequest &msg) {
|
|
1496
|
-
update::UpdateEntity
|
|
1497
|
-
if (update == nullptr)
|
|
1498
|
-
return;
|
|
1393
|
+
ENTITY_COMMAND_GET(update::UpdateEntity, update, update)
|
|
1499
1394
|
|
|
1500
1395
|
switch (msg.command) {
|
|
1501
1396
|
case enums::UPDATE_COMMAND_UPDATE:
|
|
@@ -1514,12 +1409,11 @@ void APIConnection::update_command(const UpdateCommandRequest &msg) {
|
|
|
1514
1409
|
}
|
|
1515
1410
|
#endif
|
|
1516
1411
|
|
|
1517
|
-
bool APIConnection::try_send_log_message(int level, const char *tag, const char *line) {
|
|
1518
|
-
if (this->
|
|
1412
|
+
bool APIConnection::try_send_log_message(int level, const char *tag, const char *line, size_t message_len) {
|
|
1413
|
+
if (this->flags_.log_subscription < level)
|
|
1519
1414
|
return false;
|
|
1520
1415
|
|
|
1521
1416
|
// Pre-calculate message size to avoid reallocations
|
|
1522
|
-
const size_t line_length = strlen(line);
|
|
1523
1417
|
uint32_t msg_size = 0;
|
|
1524
1418
|
|
|
1525
1419
|
// Add size for level field (field ID 1, varint type)
|
|
@@ -1528,14 +1422,14 @@ bool APIConnection::try_send_log_message(int level, const char *tag, const char
|
|
|
1528
1422
|
|
|
1529
1423
|
// Add size for string field (field ID 3, string type)
|
|
1530
1424
|
// 1 byte for field tag + size of length varint + string length
|
|
1531
|
-
msg_size += 1 + api::ProtoSize::varint(static_cast<uint32_t>(
|
|
1425
|
+
msg_size += 1 + api::ProtoSize::varint(static_cast<uint32_t>(message_len)) + message_len;
|
|
1532
1426
|
|
|
1533
1427
|
// Create a pre-sized buffer
|
|
1534
1428
|
auto buffer = this->create_buffer(msg_size);
|
|
1535
1429
|
|
|
1536
1430
|
// Encode the message (SubscribeLogsResponse)
|
|
1537
1431
|
buffer.encode_uint32(1, static_cast<uint32_t>(level)); // LogLevel level = 1
|
|
1538
|
-
buffer.encode_string(3, line,
|
|
1432
|
+
buffer.encode_string(3, line, message_len); // string message = 3
|
|
1539
1433
|
|
|
1540
1434
|
// SubscribeLogsResponse - 29
|
|
1541
1435
|
return this->send_buffer(buffer, SubscribeLogsResponse::MESSAGE_TYPE);
|
|
@@ -1544,8 +1438,7 @@ bool APIConnection::try_send_log_message(int level, const char *tag, const char
|
|
|
1544
1438
|
HelloResponse APIConnection::hello(const HelloRequest &msg) {
|
|
1545
1439
|
this->client_info_ = msg.client_info;
|
|
1546
1440
|
this->client_peername_ = this->helper_->getpeername();
|
|
1547
|
-
this->
|
|
1548
|
-
this->helper_->set_log_info(this->client_combined_info_);
|
|
1441
|
+
this->helper_->set_log_info(this->get_client_combined_info());
|
|
1549
1442
|
this->client_api_version_major_ = msg.api_version_major;
|
|
1550
1443
|
this->client_api_version_minor_ = msg.api_version_minor;
|
|
1551
1444
|
ESP_LOGV(TAG, "Hello from client: '%s' | %s | API Version %" PRIu32 ".%" PRIu32, this->client_info_.c_str(),
|
|
@@ -1557,19 +1450,24 @@ HelloResponse APIConnection::hello(const HelloRequest &msg) {
|
|
|
1557
1450
|
resp.server_info = App.get_name() + " (esphome v" ESPHOME_VERSION ")";
|
|
1558
1451
|
resp.name = App.get_name();
|
|
1559
1452
|
|
|
1560
|
-
this->
|
|
1453
|
+
this->flags_.connection_state = static_cast<uint8_t>(ConnectionState::CONNECTED);
|
|
1561
1454
|
return resp;
|
|
1562
1455
|
}
|
|
1563
1456
|
ConnectResponse APIConnection::connect(const ConnectRequest &msg) {
|
|
1564
|
-
bool correct =
|
|
1457
|
+
bool correct = true;
|
|
1458
|
+
#ifdef USE_API_PASSWORD
|
|
1459
|
+
correct = this->parent_->check_password(msg.password);
|
|
1460
|
+
#endif
|
|
1565
1461
|
|
|
1566
1462
|
ConnectResponse resp;
|
|
1567
1463
|
// bool invalid_password = 1;
|
|
1568
1464
|
resp.invalid_password = !correct;
|
|
1569
1465
|
if (correct) {
|
|
1570
|
-
ESP_LOGD(TAG, "%s connected", this->
|
|
1571
|
-
this->
|
|
1466
|
+
ESP_LOGD(TAG, "%s connected", this->get_client_combined_info().c_str());
|
|
1467
|
+
this->flags_.connection_state = static_cast<uint8_t>(ConnectionState::AUTHENTICATED);
|
|
1468
|
+
#ifdef USE_API_CLIENT_CONNECTED_TRIGGER
|
|
1572
1469
|
this->parent_->get_client_connected_trigger()->trigger(this->client_info_, this->client_peername_);
|
|
1470
|
+
#endif
|
|
1573
1471
|
#ifdef USE_HOMEASSISTANT_TIME
|
|
1574
1472
|
if (homeassistant::global_homeassistant_time != nullptr) {
|
|
1575
1473
|
this->send_time_request();
|
|
@@ -1580,7 +1478,11 @@ ConnectResponse APIConnection::connect(const ConnectRequest &msg) {
|
|
|
1580
1478
|
}
|
|
1581
1479
|
DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
|
|
1582
1480
|
DeviceInfoResponse resp{};
|
|
1481
|
+
#ifdef USE_API_PASSWORD
|
|
1583
1482
|
resp.uses_password = this->parent_->uses_password();
|
|
1483
|
+
#else
|
|
1484
|
+
resp.uses_password = false;
|
|
1485
|
+
#endif
|
|
1584
1486
|
resp.name = App.get_name();
|
|
1585
1487
|
resp.friendly_name = App.get_friendly_name();
|
|
1586
1488
|
resp.suggested_area = App.get_area();
|
|
@@ -1593,6 +1495,8 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
|
|
|
1593
1495
|
resp.manufacturer = "Raspberry Pi";
|
|
1594
1496
|
#elif defined(USE_BK72XX)
|
|
1595
1497
|
resp.manufacturer = "Beken";
|
|
1498
|
+
#elif defined(USE_LN882X)
|
|
1499
|
+
resp.manufacturer = "Lightning";
|
|
1596
1500
|
#elif defined(USE_RTL87XX)
|
|
1597
1501
|
resp.manufacturer = "Realtek";
|
|
1598
1502
|
#elif defined(USE_HOST)
|
|
@@ -1620,6 +1524,23 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
|
|
|
1620
1524
|
#endif
|
|
1621
1525
|
#ifdef USE_API_NOISE
|
|
1622
1526
|
resp.api_encryption_supported = true;
|
|
1527
|
+
#endif
|
|
1528
|
+
#ifdef USE_DEVICES
|
|
1529
|
+
for (auto const &device : App.get_devices()) {
|
|
1530
|
+
DeviceInfo device_info;
|
|
1531
|
+
device_info.device_id = device->get_device_id();
|
|
1532
|
+
device_info.name = device->get_name();
|
|
1533
|
+
device_info.area_id = device->get_area_id();
|
|
1534
|
+
resp.devices.push_back(device_info);
|
|
1535
|
+
}
|
|
1536
|
+
#endif
|
|
1537
|
+
#ifdef USE_AREAS
|
|
1538
|
+
for (auto const &area : App.get_areas()) {
|
|
1539
|
+
AreaInfo area_info;
|
|
1540
|
+
area_info.area_id = area->get_area_id();
|
|
1541
|
+
area_info.name = area->get_name();
|
|
1542
|
+
resp.areas.push_back(area_info);
|
|
1543
|
+
}
|
|
1623
1544
|
#endif
|
|
1624
1545
|
return resp;
|
|
1625
1546
|
}
|
|
@@ -1630,6 +1551,7 @@ void APIConnection::on_home_assistant_state_response(const HomeAssistantStateRes
|
|
|
1630
1551
|
}
|
|
1631
1552
|
}
|
|
1632
1553
|
}
|
|
1554
|
+
#ifdef USE_API_SERVICES
|
|
1633
1555
|
void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
|
|
1634
1556
|
bool found = false;
|
|
1635
1557
|
for (auto *service : this->parent_->get_user_services()) {
|
|
@@ -1641,6 +1563,7 @@ void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
|
|
|
1641
1563
|
ESP_LOGV(TAG, "Could not find service");
|
|
1642
1564
|
}
|
|
1643
1565
|
}
|
|
1566
|
+
#endif
|
|
1644
1567
|
#ifdef USE_API_NOISE
|
|
1645
1568
|
NoiseEncryptionSetKeyResponse APIConnection::noise_encryption_set_key(const NoiseEncryptionSetKeyRequest &msg) {
|
|
1646
1569
|
psk_t psk{};
|
|
@@ -1665,7 +1588,7 @@ void APIConnection::subscribe_home_assistant_states(const SubscribeHomeAssistant
|
|
|
1665
1588
|
state_subs_at_ = 0;
|
|
1666
1589
|
}
|
|
1667
1590
|
bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
|
|
1668
|
-
if (this->
|
|
1591
|
+
if (this->flags_.remove)
|
|
1669
1592
|
return false;
|
|
1670
1593
|
if (this->helper_->can_write_without_blocking())
|
|
1671
1594
|
return true;
|
|
@@ -1673,7 +1596,7 @@ bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
|
|
|
1673
1596
|
APIError err = this->helper_->loop();
|
|
1674
1597
|
if (err != APIError::OK) {
|
|
1675
1598
|
on_fatal_error();
|
|
1676
|
-
ESP_LOGW(TAG, "%s: Socket operation failed: %s errno=%d", this->
|
|
1599
|
+
ESP_LOGW(TAG, "%s: Socket operation failed: %s errno=%d", this->get_client_combined_info().c_str(),
|
|
1677
1600
|
api_error_to_str(err), errno);
|
|
1678
1601
|
return false;
|
|
1679
1602
|
}
|
|
@@ -1684,7 +1607,7 @@ bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
|
|
|
1684
1607
|
}
|
|
1685
1608
|
return false;
|
|
1686
1609
|
}
|
|
1687
|
-
bool APIConnection::send_buffer(ProtoWriteBuffer buffer,
|
|
1610
|
+
bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) {
|
|
1688
1611
|
if (!this->try_to_clear_buffer(message_type != SubscribeLogsResponse::MESSAGE_TYPE)) { // SubscribeLogsResponse
|
|
1689
1612
|
return false;
|
|
1690
1613
|
}
|
|
@@ -1695,10 +1618,10 @@ bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint16_t message_type)
|
|
|
1695
1618
|
if (err != APIError::OK) {
|
|
1696
1619
|
on_fatal_error();
|
|
1697
1620
|
if (err == APIError::SOCKET_WRITE_FAILED && errno == ECONNRESET) {
|
|
1698
|
-
ESP_LOGW(TAG, "%s: Connection reset", this->
|
|
1621
|
+
ESP_LOGW(TAG, "%s: Connection reset", this->get_client_combined_info().c_str());
|
|
1699
1622
|
} else {
|
|
1700
|
-
ESP_LOGW(TAG, "%s: Packet write failed %s errno=%d", this->
|
|
1701
|
-
errno);
|
|
1623
|
+
ESP_LOGW(TAG, "%s: Packet write failed %s errno=%d", this->get_client_combined_info().c_str(),
|
|
1624
|
+
api_error_to_str(err), errno);
|
|
1702
1625
|
}
|
|
1703
1626
|
return false;
|
|
1704
1627
|
}
|
|
@@ -1707,36 +1630,45 @@ bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint16_t message_type)
|
|
|
1707
1630
|
}
|
|
1708
1631
|
void APIConnection::on_unauthenticated_access() {
|
|
1709
1632
|
this->on_fatal_error();
|
|
1710
|
-
ESP_LOGD(TAG, "%s requested access without authentication", this->
|
|
1633
|
+
ESP_LOGD(TAG, "%s requested access without authentication", this->get_client_combined_info().c_str());
|
|
1711
1634
|
}
|
|
1712
1635
|
void APIConnection::on_no_setup_connection() {
|
|
1713
1636
|
this->on_fatal_error();
|
|
1714
|
-
ESP_LOGD(TAG, "%s requested access without full connection", this->
|
|
1637
|
+
ESP_LOGD(TAG, "%s requested access without full connection", this->get_client_combined_info().c_str());
|
|
1715
1638
|
}
|
|
1716
1639
|
void APIConnection::on_fatal_error() {
|
|
1717
1640
|
this->helper_->close();
|
|
1718
|
-
this->
|
|
1641
|
+
this->flags_.remove = true;
|
|
1719
1642
|
}
|
|
1720
1643
|
|
|
1721
|
-
void APIConnection::DeferredBatch::add_item(EntityBase *entity, MessageCreator creator,
|
|
1644
|
+
void APIConnection::DeferredBatch::add_item(EntityBase *entity, MessageCreator creator, uint8_t message_type,
|
|
1645
|
+
uint8_t estimated_size) {
|
|
1722
1646
|
// Check if we already have a message of this type for this entity
|
|
1723
1647
|
// This provides deduplication per entity/message_type combination
|
|
1724
1648
|
// O(n) but optimized for RAM and not performance.
|
|
1725
1649
|
for (auto &item : items) {
|
|
1726
1650
|
if (item.entity == entity && item.message_type == message_type) {
|
|
1727
|
-
//
|
|
1651
|
+
// Clean up old creator before replacing
|
|
1652
|
+
item.creator.cleanup(message_type);
|
|
1653
|
+
// Move assign the new creator
|
|
1728
1654
|
item.creator = std::move(creator);
|
|
1729
1655
|
return;
|
|
1730
1656
|
}
|
|
1731
1657
|
}
|
|
1732
1658
|
|
|
1733
1659
|
// No existing item found, add new one
|
|
1734
|
-
items.emplace_back(entity, std::move(creator), message_type);
|
|
1660
|
+
items.emplace_back(entity, std::move(creator), message_type, estimated_size);
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
void APIConnection::DeferredBatch::add_item_front(EntityBase *entity, MessageCreator creator, uint8_t message_type,
|
|
1664
|
+
uint8_t estimated_size) {
|
|
1665
|
+
// Insert at front for high priority messages (no deduplication check)
|
|
1666
|
+
items.insert(items.begin(), BatchItem(entity, std::move(creator), message_type, estimated_size));
|
|
1735
1667
|
}
|
|
1736
1668
|
|
|
1737
1669
|
bool APIConnection::schedule_batch_() {
|
|
1738
|
-
if (!this->
|
|
1739
|
-
this->
|
|
1670
|
+
if (!this->flags_.batch_scheduled) {
|
|
1671
|
+
this->flags_.batch_scheduled = true;
|
|
1740
1672
|
this->deferred_batch_.batch_start_time = App.get_loop_component_start_time();
|
|
1741
1673
|
}
|
|
1742
1674
|
return true;
|
|
@@ -1745,14 +1677,14 @@ bool APIConnection::schedule_batch_() {
|
|
|
1745
1677
|
ProtoWriteBuffer APIConnection::allocate_single_message_buffer(uint16_t size) { return this->create_buffer(size); }
|
|
1746
1678
|
|
|
1747
1679
|
ProtoWriteBuffer APIConnection::allocate_batch_message_buffer(uint16_t size) {
|
|
1748
|
-
ProtoWriteBuffer result = this->prepare_message_buffer(size, this->
|
|
1749
|
-
this->
|
|
1680
|
+
ProtoWriteBuffer result = this->prepare_message_buffer(size, this->flags_.batch_first_message);
|
|
1681
|
+
this->flags_.batch_first_message = false;
|
|
1750
1682
|
return result;
|
|
1751
1683
|
}
|
|
1752
1684
|
|
|
1753
1685
|
void APIConnection::process_batch_() {
|
|
1754
1686
|
if (this->deferred_batch_.empty()) {
|
|
1755
|
-
this->
|
|
1687
|
+
this->flags_.batch_scheduled = false;
|
|
1756
1688
|
return;
|
|
1757
1689
|
}
|
|
1758
1690
|
|
|
@@ -1762,22 +1694,28 @@ void APIConnection::process_batch_() {
|
|
|
1762
1694
|
return;
|
|
1763
1695
|
}
|
|
1764
1696
|
|
|
1765
|
-
size_t num_items = this->deferred_batch_.
|
|
1697
|
+
size_t num_items = this->deferred_batch_.size();
|
|
1766
1698
|
|
|
1767
1699
|
// Fast path for single message - allocate exact size needed
|
|
1768
1700
|
if (num_items == 1) {
|
|
1769
|
-
const auto &item = this->deferred_batch_
|
|
1701
|
+
const auto &item = this->deferred_batch_[0];
|
|
1770
1702
|
|
|
1771
1703
|
// Let the creator calculate size and encode if it fits
|
|
1772
|
-
uint16_t payload_size =
|
|
1704
|
+
uint16_t payload_size =
|
|
1705
|
+
item.creator(item.entity, this, std::numeric_limits<uint16_t>::max(), true, item.message_type);
|
|
1773
1706
|
|
|
1774
1707
|
if (payload_size > 0 &&
|
|
1775
1708
|
this->send_buffer(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()}, item.message_type)) {
|
|
1776
|
-
|
|
1709
|
+
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
1710
|
+
// Log messages after send attempt for VV debugging
|
|
1711
|
+
// It's safe to use the buffer for logging at this point regardless of send result
|
|
1712
|
+
this->log_batch_item_(item);
|
|
1713
|
+
#endif
|
|
1714
|
+
this->clear_batch_();
|
|
1777
1715
|
} else if (payload_size == 0) {
|
|
1778
1716
|
// Message too large
|
|
1779
1717
|
ESP_LOGW(TAG, "Message too large to send: type=%u", item.message_type);
|
|
1780
|
-
this->
|
|
1718
|
+
this->clear_batch_();
|
|
1781
1719
|
}
|
|
1782
1720
|
return;
|
|
1783
1721
|
}
|
|
@@ -1795,8 +1733,9 @@ void APIConnection::process_batch_() {
|
|
|
1795
1733
|
|
|
1796
1734
|
// Pre-calculate exact buffer size needed based on message types
|
|
1797
1735
|
uint32_t total_estimated_size = 0;
|
|
1798
|
-
for (
|
|
1799
|
-
|
|
1736
|
+
for (size_t i = 0; i < this->deferred_batch_.size(); i++) {
|
|
1737
|
+
const auto &item = this->deferred_batch_[i];
|
|
1738
|
+
total_estimated_size += item.estimated_size;
|
|
1800
1739
|
}
|
|
1801
1740
|
|
|
1802
1741
|
// Calculate total overhead for all messages
|
|
@@ -1804,7 +1743,7 @@ void APIConnection::process_batch_() {
|
|
|
1804
1743
|
|
|
1805
1744
|
// Reserve based on estimated size (much more accurate than 24-byte worst-case)
|
|
1806
1745
|
this->parent_->get_shared_buffer_ref().reserve(total_estimated_size + total_overhead);
|
|
1807
|
-
this->
|
|
1746
|
+
this->flags_.batch_first_message = true;
|
|
1808
1747
|
|
|
1809
1748
|
size_t items_processed = 0;
|
|
1810
1749
|
uint16_t remaining_size = std::numeric_limits<uint16_t>::max();
|
|
@@ -1816,10 +1755,11 @@ void APIConnection::process_batch_() {
|
|
|
1816
1755
|
uint32_t current_offset = 0;
|
|
1817
1756
|
|
|
1818
1757
|
// Process items and encode directly to buffer
|
|
1819
|
-
for (
|
|
1758
|
+
for (size_t i = 0; i < this->deferred_batch_.size(); i++) {
|
|
1759
|
+
const auto &item = this->deferred_batch_[i];
|
|
1820
1760
|
// Try to encode message
|
|
1821
1761
|
// The creator will calculate overhead to determine if the message fits
|
|
1822
|
-
uint16_t payload_size = item.creator(item.entity, this, remaining_size, false);
|
|
1762
|
+
uint16_t payload_size = item.creator(item.entity, this, remaining_size, false, item.message_type);
|
|
1823
1763
|
|
|
1824
1764
|
if (payload_size == 0) {
|
|
1825
1765
|
// Message won't fit, stop processing
|
|
@@ -1833,9 +1773,9 @@ void APIConnection::process_batch_() {
|
|
|
1833
1773
|
|
|
1834
1774
|
// Update tracking variables
|
|
1835
1775
|
items_processed++;
|
|
1836
|
-
// After first message, set remaining size to
|
|
1776
|
+
// After first message, set remaining size to MAX_BATCH_PACKET_SIZE to avoid fragmentation
|
|
1837
1777
|
if (items_processed == 1) {
|
|
1838
|
-
remaining_size =
|
|
1778
|
+
remaining_size = MAX_BATCH_PACKET_SIZE;
|
|
1839
1779
|
}
|
|
1840
1780
|
remaining_size -= payload_size;
|
|
1841
1781
|
// Calculate where the next message's header padding will start
|
|
@@ -1860,44 +1800,46 @@ void APIConnection::process_batch_() {
|
|
|
1860
1800
|
if (err != APIError::OK && err != APIError::WOULD_BLOCK) {
|
|
1861
1801
|
on_fatal_error();
|
|
1862
1802
|
if (err == APIError::SOCKET_WRITE_FAILED && errno == ECONNRESET) {
|
|
1863
|
-
ESP_LOGW(TAG, "%s: Connection reset during batch write", this->
|
|
1803
|
+
ESP_LOGW(TAG, "%s: Connection reset during batch write", this->get_client_combined_info().c_str());
|
|
1864
1804
|
} else {
|
|
1865
|
-
ESP_LOGW(TAG, "%s: Batch write failed %s errno=%d", this->
|
|
1866
|
-
errno);
|
|
1805
|
+
ESP_LOGW(TAG, "%s: Batch write failed %s errno=%d", this->get_client_combined_info().c_str(),
|
|
1806
|
+
api_error_to_str(err), errno);
|
|
1867
1807
|
}
|
|
1868
1808
|
}
|
|
1869
1809
|
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1810
|
+
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
1811
|
+
// Log messages after send attempt for VV debugging
|
|
1812
|
+
// It's safe to use the buffer for logging at this point regardless of send result
|
|
1813
|
+
for (size_t i = 0; i < items_processed; i++) {
|
|
1814
|
+
const auto &item = this->deferred_batch_[i];
|
|
1815
|
+
this->log_batch_item_(item);
|
|
1816
|
+
}
|
|
1817
|
+
#endif
|
|
1875
1818
|
|
|
1819
|
+
// Handle remaining items more efficiently
|
|
1820
|
+
if (items_processed < this->deferred_batch_.size()) {
|
|
1821
|
+
// Remove processed items from the beginning with proper cleanup
|
|
1822
|
+
this->deferred_batch_.remove_front(items_processed);
|
|
1876
1823
|
// Reschedule for remaining items
|
|
1877
1824
|
this->schedule_batch_();
|
|
1878
1825
|
} else {
|
|
1879
1826
|
// All items processed
|
|
1880
|
-
this->
|
|
1827
|
+
this->clear_batch_();
|
|
1881
1828
|
}
|
|
1882
1829
|
}
|
|
1883
1830
|
|
|
1884
1831
|
uint16_t APIConnection::MessageCreator::operator()(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1885
|
-
bool is_single) const {
|
|
1886
|
-
switch (message_type_) {
|
|
1887
|
-
case 0: // Function pointer
|
|
1888
|
-
return data_.ptr(entity, conn, remaining_size, is_single);
|
|
1889
|
-
|
|
1832
|
+
bool is_single, uint8_t message_type) const {
|
|
1890
1833
|
#ifdef USE_EVENT
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1834
|
+
// Special case: EventResponse uses string pointer
|
|
1835
|
+
if (message_type == EventResponse::MESSAGE_TYPE) {
|
|
1836
|
+
auto *e = static_cast<event::Event *>(entity);
|
|
1837
|
+
return APIConnection::try_send_event_response(e, *data_.string_ptr, conn, remaining_size, is_single);
|
|
1838
|
+
}
|
|
1895
1839
|
#endif
|
|
1896
1840
|
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
return 0;
|
|
1900
|
-
}
|
|
1841
|
+
// All other message types use function pointers
|
|
1842
|
+
return data_.function_ptr(entity, conn, remaining_size, is_single);
|
|
1901
1843
|
}
|
|
1902
1844
|
|
|
1903
1845
|
uint16_t APIConnection::try_send_list_info_done(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -1912,147 +1854,10 @@ uint16_t APIConnection::try_send_disconnect_request(EntityBase *entity, APIConne
|
|
|
1912
1854
|
return encode_message_to_buffer(req, DisconnectRequest::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
1913
1855
|
}
|
|
1914
1856
|
|
|
1915
|
-
uint16_t APIConnection::
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
case BinarySensorStateResponse::MESSAGE_TYPE:
|
|
1920
|
-
return BinarySensorStateResponse::ESTIMATED_SIZE;
|
|
1921
|
-
case ListEntitiesBinarySensorResponse::MESSAGE_TYPE:
|
|
1922
|
-
return ListEntitiesBinarySensorResponse::ESTIMATED_SIZE;
|
|
1923
|
-
#endif
|
|
1924
|
-
#ifdef USE_SENSOR
|
|
1925
|
-
case SensorStateResponse::MESSAGE_TYPE:
|
|
1926
|
-
return SensorStateResponse::ESTIMATED_SIZE;
|
|
1927
|
-
case ListEntitiesSensorResponse::MESSAGE_TYPE:
|
|
1928
|
-
return ListEntitiesSensorResponse::ESTIMATED_SIZE;
|
|
1929
|
-
#endif
|
|
1930
|
-
#ifdef USE_SWITCH
|
|
1931
|
-
case SwitchStateResponse::MESSAGE_TYPE:
|
|
1932
|
-
return SwitchStateResponse::ESTIMATED_SIZE;
|
|
1933
|
-
case ListEntitiesSwitchResponse::MESSAGE_TYPE:
|
|
1934
|
-
return ListEntitiesSwitchResponse::ESTIMATED_SIZE;
|
|
1935
|
-
#endif
|
|
1936
|
-
#ifdef USE_TEXT_SENSOR
|
|
1937
|
-
case TextSensorStateResponse::MESSAGE_TYPE:
|
|
1938
|
-
return TextSensorStateResponse::ESTIMATED_SIZE;
|
|
1939
|
-
case ListEntitiesTextSensorResponse::MESSAGE_TYPE:
|
|
1940
|
-
return ListEntitiesTextSensorResponse::ESTIMATED_SIZE;
|
|
1941
|
-
#endif
|
|
1942
|
-
#ifdef USE_NUMBER
|
|
1943
|
-
case NumberStateResponse::MESSAGE_TYPE:
|
|
1944
|
-
return NumberStateResponse::ESTIMATED_SIZE;
|
|
1945
|
-
case ListEntitiesNumberResponse::MESSAGE_TYPE:
|
|
1946
|
-
return ListEntitiesNumberResponse::ESTIMATED_SIZE;
|
|
1947
|
-
#endif
|
|
1948
|
-
#ifdef USE_TEXT
|
|
1949
|
-
case TextStateResponse::MESSAGE_TYPE:
|
|
1950
|
-
return TextStateResponse::ESTIMATED_SIZE;
|
|
1951
|
-
case ListEntitiesTextResponse::MESSAGE_TYPE:
|
|
1952
|
-
return ListEntitiesTextResponse::ESTIMATED_SIZE;
|
|
1953
|
-
#endif
|
|
1954
|
-
#ifdef USE_SELECT
|
|
1955
|
-
case SelectStateResponse::MESSAGE_TYPE:
|
|
1956
|
-
return SelectStateResponse::ESTIMATED_SIZE;
|
|
1957
|
-
case ListEntitiesSelectResponse::MESSAGE_TYPE:
|
|
1958
|
-
return ListEntitiesSelectResponse::ESTIMATED_SIZE;
|
|
1959
|
-
#endif
|
|
1960
|
-
#ifdef USE_LOCK
|
|
1961
|
-
case LockStateResponse::MESSAGE_TYPE:
|
|
1962
|
-
return LockStateResponse::ESTIMATED_SIZE;
|
|
1963
|
-
case ListEntitiesLockResponse::MESSAGE_TYPE:
|
|
1964
|
-
return ListEntitiesLockResponse::ESTIMATED_SIZE;
|
|
1965
|
-
#endif
|
|
1966
|
-
#ifdef USE_EVENT
|
|
1967
|
-
case EventResponse::MESSAGE_TYPE:
|
|
1968
|
-
return EventResponse::ESTIMATED_SIZE;
|
|
1969
|
-
case ListEntitiesEventResponse::MESSAGE_TYPE:
|
|
1970
|
-
return ListEntitiesEventResponse::ESTIMATED_SIZE;
|
|
1971
|
-
#endif
|
|
1972
|
-
#ifdef USE_COVER
|
|
1973
|
-
case CoverStateResponse::MESSAGE_TYPE:
|
|
1974
|
-
return CoverStateResponse::ESTIMATED_SIZE;
|
|
1975
|
-
case ListEntitiesCoverResponse::MESSAGE_TYPE:
|
|
1976
|
-
return ListEntitiesCoverResponse::ESTIMATED_SIZE;
|
|
1977
|
-
#endif
|
|
1978
|
-
#ifdef USE_FAN
|
|
1979
|
-
case FanStateResponse::MESSAGE_TYPE:
|
|
1980
|
-
return FanStateResponse::ESTIMATED_SIZE;
|
|
1981
|
-
case ListEntitiesFanResponse::MESSAGE_TYPE:
|
|
1982
|
-
return ListEntitiesFanResponse::ESTIMATED_SIZE;
|
|
1983
|
-
#endif
|
|
1984
|
-
#ifdef USE_LIGHT
|
|
1985
|
-
case LightStateResponse::MESSAGE_TYPE:
|
|
1986
|
-
return LightStateResponse::ESTIMATED_SIZE;
|
|
1987
|
-
case ListEntitiesLightResponse::MESSAGE_TYPE:
|
|
1988
|
-
return ListEntitiesLightResponse::ESTIMATED_SIZE;
|
|
1989
|
-
#endif
|
|
1990
|
-
#ifdef USE_CLIMATE
|
|
1991
|
-
case ClimateStateResponse::MESSAGE_TYPE:
|
|
1992
|
-
return ClimateStateResponse::ESTIMATED_SIZE;
|
|
1993
|
-
case ListEntitiesClimateResponse::MESSAGE_TYPE:
|
|
1994
|
-
return ListEntitiesClimateResponse::ESTIMATED_SIZE;
|
|
1995
|
-
#endif
|
|
1996
|
-
#ifdef USE_ESP32_CAMERA
|
|
1997
|
-
case ListEntitiesCameraResponse::MESSAGE_TYPE:
|
|
1998
|
-
return ListEntitiesCameraResponse::ESTIMATED_SIZE;
|
|
1999
|
-
#endif
|
|
2000
|
-
#ifdef USE_BUTTON
|
|
2001
|
-
case ListEntitiesButtonResponse::MESSAGE_TYPE:
|
|
2002
|
-
return ListEntitiesButtonResponse::ESTIMATED_SIZE;
|
|
2003
|
-
#endif
|
|
2004
|
-
#ifdef USE_MEDIA_PLAYER
|
|
2005
|
-
case MediaPlayerStateResponse::MESSAGE_TYPE:
|
|
2006
|
-
return MediaPlayerStateResponse::ESTIMATED_SIZE;
|
|
2007
|
-
case ListEntitiesMediaPlayerResponse::MESSAGE_TYPE:
|
|
2008
|
-
return ListEntitiesMediaPlayerResponse::ESTIMATED_SIZE;
|
|
2009
|
-
#endif
|
|
2010
|
-
#ifdef USE_ALARM_CONTROL_PANEL
|
|
2011
|
-
case AlarmControlPanelStateResponse::MESSAGE_TYPE:
|
|
2012
|
-
return AlarmControlPanelStateResponse::ESTIMATED_SIZE;
|
|
2013
|
-
case ListEntitiesAlarmControlPanelResponse::MESSAGE_TYPE:
|
|
2014
|
-
return ListEntitiesAlarmControlPanelResponse::ESTIMATED_SIZE;
|
|
2015
|
-
#endif
|
|
2016
|
-
#ifdef USE_DATETIME_DATE
|
|
2017
|
-
case DateStateResponse::MESSAGE_TYPE:
|
|
2018
|
-
return DateStateResponse::ESTIMATED_SIZE;
|
|
2019
|
-
case ListEntitiesDateResponse::MESSAGE_TYPE:
|
|
2020
|
-
return ListEntitiesDateResponse::ESTIMATED_SIZE;
|
|
2021
|
-
#endif
|
|
2022
|
-
#ifdef USE_DATETIME_TIME
|
|
2023
|
-
case TimeStateResponse::MESSAGE_TYPE:
|
|
2024
|
-
return TimeStateResponse::ESTIMATED_SIZE;
|
|
2025
|
-
case ListEntitiesTimeResponse::MESSAGE_TYPE:
|
|
2026
|
-
return ListEntitiesTimeResponse::ESTIMATED_SIZE;
|
|
2027
|
-
#endif
|
|
2028
|
-
#ifdef USE_DATETIME_DATETIME
|
|
2029
|
-
case DateTimeStateResponse::MESSAGE_TYPE:
|
|
2030
|
-
return DateTimeStateResponse::ESTIMATED_SIZE;
|
|
2031
|
-
case ListEntitiesDateTimeResponse::MESSAGE_TYPE:
|
|
2032
|
-
return ListEntitiesDateTimeResponse::ESTIMATED_SIZE;
|
|
2033
|
-
#endif
|
|
2034
|
-
#ifdef USE_VALVE
|
|
2035
|
-
case ValveStateResponse::MESSAGE_TYPE:
|
|
2036
|
-
return ValveStateResponse::ESTIMATED_SIZE;
|
|
2037
|
-
case ListEntitiesValveResponse::MESSAGE_TYPE:
|
|
2038
|
-
return ListEntitiesValveResponse::ESTIMATED_SIZE;
|
|
2039
|
-
#endif
|
|
2040
|
-
#ifdef USE_UPDATE
|
|
2041
|
-
case UpdateStateResponse::MESSAGE_TYPE:
|
|
2042
|
-
return UpdateStateResponse::ESTIMATED_SIZE;
|
|
2043
|
-
case ListEntitiesUpdateResponse::MESSAGE_TYPE:
|
|
2044
|
-
return ListEntitiesUpdateResponse::ESTIMATED_SIZE;
|
|
2045
|
-
#endif
|
|
2046
|
-
case ListEntitiesServicesResponse::MESSAGE_TYPE:
|
|
2047
|
-
return ListEntitiesServicesResponse::ESTIMATED_SIZE;
|
|
2048
|
-
case ListEntitiesDoneResponse::MESSAGE_TYPE:
|
|
2049
|
-
return ListEntitiesDoneResponse::ESTIMATED_SIZE;
|
|
2050
|
-
case DisconnectRequest::MESSAGE_TYPE:
|
|
2051
|
-
return DisconnectRequest::ESTIMATED_SIZE;
|
|
2052
|
-
default:
|
|
2053
|
-
// Fallback for unknown message types
|
|
2054
|
-
return 24;
|
|
2055
|
-
}
|
|
1857
|
+
uint16_t APIConnection::try_send_ping_request(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1858
|
+
bool is_single) {
|
|
1859
|
+
PingRequest req;
|
|
1860
|
+
return encode_message_to_buffer(req, PingRequest::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
2056
1861
|
}
|
|
2057
1862
|
|
|
2058
1863
|
} // namespace api
|