esphome 2025.4.1__py3-none-any.whl → 2025.5.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- esphome/__main__.py +16 -14
- esphome/components/ac_dimmer/ac_dimmer.cpp +3 -2
- esphome/components/adc/__init__.py +51 -34
- esphome/components/airthings_wave_base/__init__.py +1 -1
- esphome/components/alarm_control_panel/__init__.py +37 -2
- esphome/components/am43/cover/__init__.py +4 -5
- esphome/components/analog_threshold/analog_threshold_binary_sensor.cpp +6 -4
- esphome/components/analog_threshold/analog_threshold_binary_sensor.h +4 -5
- esphome/components/analog_threshold/binary_sensor.py +10 -8
- esphome/components/anova/climate.py +4 -5
- esphome/components/api/__init__.py +25 -8
- esphome/components/api/api_connection.cpp +416 -662
- esphome/components/api/api_connection.h +256 -57
- esphome/components/api/api_frame_helper.cpp +232 -177
- esphome/components/api/api_frame_helper.h +61 -8
- esphome/components/api/api_noise_context.h +13 -4
- esphome/components/api/api_pb2.cpp +1422 -1
- esphome/components/api/api_pb2.h +255 -1
- esphome/components/api/api_pb2_service.cpp +162 -49
- esphome/components/api/api_pb2_service.h +90 -51
- esphome/components/api/api_pb2_size.h +361 -0
- esphome/components/api/api_server.cpp +110 -34
- esphome/components/api/api_server.h +8 -0
- esphome/components/api/proto.h +86 -17
- esphome/components/as3935_i2c/as3935_i2c.h +0 -3
- esphome/components/as7341/as7341.h +1 -1
- esphome/components/at581x/at581x.h +4 -4
- esphome/components/atm90e32/__init__.py +1 -0
- esphome/components/atm90e32/atm90e32.cpp +576 -199
- esphome/components/atm90e32/atm90e32.h +128 -31
- esphome/components/atm90e32/atm90e32_reg.h +4 -2
- esphome/components/atm90e32/button/__init__.py +62 -10
- esphome/components/atm90e32/button/atm90e32_button.cpp +63 -4
- esphome/components/atm90e32/button/atm90e32_button.h +36 -4
- esphome/components/atm90e32/number/__init__.py +130 -0
- esphome/components/atm90e32/number/atm90e32_number.h +16 -0
- esphome/components/atm90e32/sensor.py +21 -4
- esphome/components/atm90e32/text_sensor/__init__.py +48 -0
- esphome/components/audio/__init__.py +96 -49
- esphome/components/audio/audio.h +48 -0
- esphome/components/audio/audio_decoder.cpp +1 -1
- esphome/components/audio/audio_resampler.cpp +2 -0
- esphome/components/audio/audio_resampler.h +1 -0
- esphome/components/ballu/climate.py +2 -9
- esphome/components/bang_bang/climate.py +5 -6
- esphome/components/bedjet/bedjet_hub.cpp +1 -0
- esphome/components/bedjet/climate/__init__.py +3 -8
- esphome/components/bedjet/fan/__init__.py +2 -11
- esphome/components/binary/fan/__init__.py +13 -16
- esphome/components/binary_sensor/__init__.py +13 -10
- esphome/components/bl0906/constants.h +16 -16
- esphome/components/ble_client/text_sensor/__init__.py +3 -5
- esphome/components/bluetooth_proxy/bluetooth_connection.cpp +4 -6
- esphome/components/bluetooth_proxy/bluetooth_proxy.cpp +136 -21
- esphome/components/bluetooth_proxy/bluetooth_proxy.h +7 -0
- esphome/components/button/__init__.py +11 -8
- esphome/components/canbus/canbus.cpp +3 -0
- esphome/components/canbus/canbus.h +16 -0
- esphome/components/ccs811/sensor.py +9 -6
- esphome/components/climate/__init__.py +35 -2
- esphome/components/climate/climate_mode.h +1 -1
- esphome/components/climate/climate_traits.h +63 -57
- esphome/components/climate_ir/__init__.py +57 -17
- esphome/components/climate_ir_lg/climate.py +2 -5
- esphome/components/climate_ir_lg/climate_ir_lg.cpp +7 -7
- esphome/components/climate_ir_lg/climate_ir_lg.h +1 -1
- esphome/components/color/__init__.py +2 -0
- esphome/components/const/__init__.py +5 -0
- esphome/components/coolix/climate.py +2 -9
- esphome/components/copy/cover/__init__.py +10 -9
- esphome/components/copy/fan/__init__.py +11 -9
- esphome/components/copy/lock/__init__.py +11 -9
- esphome/components/copy/text/__init__.py +9 -6
- esphome/components/cover/__init__.py +37 -2
- esphome/components/cse7766/cse7766.cpp +2 -1
- esphome/components/cst226/binary_sensor/__init__.py +28 -0
- esphome/components/cst226/binary_sensor/cs226_button.h +22 -0
- esphome/components/cst226/binary_sensor/cstt6_button.cpp +19 -0
- esphome/components/cst226/touchscreen/cst226_touchscreen.cpp +27 -5
- esphome/components/cst226/touchscreen/cst226_touchscreen.h +10 -10
- esphome/components/current_based/cover.py +37 -36
- esphome/components/current_based/current_based_cover.cpp +2 -1
- esphome/components/daikin/climate.py +2 -9
- esphome/components/daikin/daikin.cpp +15 -9
- esphome/components/daikin/daikin.h +5 -5
- esphome/components/daikin_arc/climate.py +2 -7
- esphome/components/daikin_brc/climate.py +3 -5
- esphome/components/dallas_temp/dallas_temp.cpp +17 -24
- esphome/components/dallas_temp/dallas_temp.h +0 -1
- esphome/components/daly_bms/daly_bms.cpp +2 -1
- esphome/components/debug/debug_component.cpp +6 -1
- esphome/components/debug/debug_component.h +8 -0
- esphome/components/debug/debug_esp32.cpp +109 -254
- esphome/components/debug/sensor.py +14 -0
- esphome/components/deep_sleep/deep_sleep_esp32.cpp +13 -1
- esphome/components/delonghi/climate.py +2 -9
- esphome/components/demo/__init__.py +18 -20
- esphome/components/dfrobot_sen0395/switch/__init__.py +21 -22
- esphome/components/display/rect.cpp +4 -9
- esphome/components/display/rect.h +1 -1
- esphome/components/dps310/sensor.py +6 -6
- esphome/components/ee895/sensor.py +9 -9
- esphome/components/emmeti/climate.py +2 -9
- esphome/components/endstop/cover.py +17 -16
- esphome/components/endstop/endstop_cover.cpp +2 -1
- esphome/components/ens160_base/__init__.py +12 -9
- esphome/components/esp32/__init__.py +60 -3
- esphome/components/esp32/core.cpp +11 -5
- esphome/components/esp32/gpio.cpp +86 -24
- esphome/components/esp32/gpio.py +15 -16
- esphome/components/esp32/gpio_esp32.py +1 -2
- esphome/components/esp32/gpio_esp32_c2.py +1 -1
- esphome/components/esp32/gpio_esp32_c3.py +1 -1
- esphome/components/esp32/gpio_esp32_c6.py +1 -1
- esphome/components/esp32/gpio_esp32_h2.py +1 -1
- esphome/components/esp32_ble/ble.cpp +1 -8
- esphome/components/esp32_ble/ble.h +5 -3
- esphome/components/esp32_ble/ble_advertising.cpp +2 -1
- esphome/components/esp32_ble/ble_advertising.h +1 -0
- esphome/components/esp32_ble_server/__init__.py +3 -0
- esphome/components/esp32_ble_tracker/__init__.py +7 -1
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.cpp +192 -118
- esphome/components/esp32_ble_tracker/esp32_ble_tracker.h +29 -3
- esphome/components/esp32_camera/__init__.py +1 -1
- esphome/components/esp32_camera/esp32_camera.cpp +2 -10
- esphome/components/esp32_camera/esp32_camera.h +1 -1
- esphome/components/esp32_can/esp32_can.cpp +1 -1
- esphome/components/esp32_improv/esp32_improv_component.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.cpp +1 -1
- esphome/components/esp32_rmt_led_strip/led_strip.h +7 -5
- esphome/components/esp32_rmt_led_strip/light.py +9 -1
- esphome/components/esp32_touch/esp32_touch.cpp +1 -1
- esphome/components/esp8266/gpio.cpp +69 -8
- esphome/components/ethernet/ethernet_component.cpp +1 -1
- esphome/components/event/__init__.py +13 -10
- esphome/components/factory_reset/switch/__init__.py +7 -21
- esphome/components/fan/__init__.py +52 -5
- esphome/components/fastled_base/__init__.py +1 -4
- esphome/components/fastled_base/fastled_light.cpp +1 -1
- esphome/components/feedback/cover.py +38 -33
- esphome/components/feedback/feedback_cover.cpp +2 -1
- esphome/components/fujitsu_general/climate.py +2 -9
- esphome/components/gcja5/gcja5.cpp +2 -1
- esphome/components/gpio/one_wire/gpio_one_wire.cpp +45 -43
- esphome/components/gpio/one_wire/gpio_one_wire.h +2 -1
- esphome/components/gpio_expander/cached_gpio.h +22 -7
- esphome/components/gps/__init__.py +47 -17
- esphome/components/gps/gps.cpp +42 -23
- esphome/components/gps/gps.h +17 -13
- esphome/components/graph/__init__.py +1 -2
- esphome/components/gree/climate.py +4 -6
- esphome/components/gree/gree.cpp +16 -2
- esphome/components/gree/gree.h +2 -2
- esphome/components/growatt_solar/growatt_solar.cpp +2 -1
- esphome/components/haier/climate.py +37 -34
- esphome/components/hbridge/fan/__init__.py +19 -17
- esphome/components/he60r/cover.py +4 -5
- esphome/components/heatpumpir/climate.py +3 -6
- esphome/components/hitachi_ac344/climate.py +2 -9
- esphome/components/hitachi_ac424/climate.py +2 -9
- esphome/components/hlw8012/hlw8012.cpp +1 -1
- esphome/components/hm3301/hm3301.h +1 -1
- esphome/components/hte501/sensor.py +6 -6
- esphome/components/http_request/__init__.py +39 -6
- esphome/components/http_request/http_request.cpp +20 -0
- esphome/components/http_request/http_request.h +57 -15
- esphome/components/http_request/http_request_arduino.cpp +22 -6
- esphome/components/http_request/http_request_arduino.h +4 -3
- esphome/components/http_request/http_request_host.cpp +141 -0
- esphome/components/http_request/http_request_host.h +37 -0
- esphome/components/http_request/http_request_idf.cpp +35 -3
- esphome/components/http_request/http_request_idf.h +10 -3
- esphome/components/http_request/httplib.h +9691 -0
- esphome/components/http_request/update/__init__.py +11 -8
- esphome/components/hyt271/sensor.py +6 -6
- esphome/components/i2c/i2c.h +4 -0
- esphome/components/i2c/i2c_bus_esp_idf.cpp +1 -1
- esphome/components/i2s_audio/__init__.py +131 -22
- esphome/components/i2s_audio/i2s_audio.h +44 -4
- esphome/components/i2s_audio/media_player/__init__.py +19 -9
- esphome/components/i2s_audio/microphone/__init__.py +63 -5
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.cpp +351 -61
- esphome/components/i2s_audio/microphone/i2s_audio_microphone.h +40 -6
- esphome/components/i2s_audio/speaker/__init__.py +31 -5
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.cpp +155 -19
- esphome/components/i2s_audio/speaker/i2s_audio_speaker.h +17 -4
- esphome/components/ili9xxx/ili9xxx_init.h +1 -1
- esphome/components/image/__init__.py +37 -17
- esphome/components/image/image.cpp +25 -8
- esphome/components/internal_temperature/internal_temperature.cpp +6 -4
- esphome/components/key_collector/__init__.py +35 -0
- esphome/components/key_collector/key_collector.cpp +8 -0
- esphome/components/key_collector/key_collector.h +10 -0
- esphome/components/kuntze/kuntze.cpp +2 -1
- esphome/components/ld2410/ld2410.h +1 -1
- esphome/components/ld2450/ld2450.h +1 -1
- esphome/components/light/__init__.py +57 -0
- esphome/components/lock/__init__.py +51 -4
- esphome/components/lock/automation.h +2 -13
- esphome/components/logger/__init__.py +22 -0
- esphome/components/logger/logger.cpp +154 -103
- esphome/components/logger/logger.h +211 -36
- esphome/components/logger/task_log_buffer.cpp +138 -0
- esphome/components/logger/task_log_buffer.h +69 -0
- esphome/components/lvgl/__init__.py +13 -5
- esphome/components/lvgl/automation.py +50 -1
- esphome/components/lvgl/defines.py +0 -1
- esphome/components/lvgl/lv_validation.py +10 -1
- esphome/components/lvgl/lvgl_esphome.cpp +5 -1
- esphome/components/lvgl/schemas.py +14 -14
- esphome/components/lvgl/text/__init__.py +1 -2
- esphome/components/lvgl/widgets/arc.py +7 -6
- esphome/components/lvgl/widgets/buttonmatrix.py +3 -3
- esphome/components/lvgl/widgets/checkbox.py +2 -2
- esphome/components/lvgl/widgets/dropdown.py +2 -1
- esphome/components/lvgl/widgets/img.py +15 -12
- esphome/components/mapping/__init__.py +134 -0
- esphome/components/matrix_keypad/matrix_keypad.cpp +2 -1
- esphome/components/max7219digit/max7219digit.cpp +28 -27
- esphome/components/mdns/__init__.py +11 -5
- esphome/components/mdns/mdns_component.cpp +11 -5
- esphome/components/mdns/mdns_component.h +3 -2
- esphome/components/mdns/mdns_esp32.cpp +4 -3
- esphome/components/mdns/mdns_esp8266.cpp +4 -2
- esphome/components/mdns/mdns_libretiny.cpp +4 -2
- esphome/components/mdns/mdns_rp2040.cpp +4 -2
- esphome/components/media_player/__init__.py +40 -6
- esphome/components/mhz19/sensor.py +11 -7
- esphome/components/micro_wake_word/__init__.py +99 -31
- esphome/components/micro_wake_word/automation.h +54 -0
- esphome/components/micro_wake_word/micro_wake_word.cpp +331 -319
- esphome/components/micro_wake_word/micro_wake_word.h +58 -105
- esphome/components/micro_wake_word/preprocessor_settings.h +19 -2
- esphome/components/micro_wake_word/streaming_model.cpp +158 -41
- esphome/components/micro_wake_word/streaming_model.h +85 -13
- esphome/components/microphone/__init__.py +139 -9
- esphome/components/microphone/automation.h +14 -2
- esphome/components/microphone/microphone.cpp +21 -0
- esphome/components/microphone/microphone.h +14 -5
- esphome/components/microphone/microphone_source.cpp +95 -0
- esphome/components/microphone/microphone_source.h +80 -0
- esphome/components/mics_4514/sensor.py +25 -14
- esphome/components/midea/climate.py +3 -4
- esphome/components/midea_ir/climate.py +3 -5
- esphome/components/mipi_spi/__init__.py +15 -0
- esphome/components/mipi_spi/display.py +474 -0
- esphome/components/mipi_spi/mipi_spi.cpp +481 -0
- esphome/components/mipi_spi/mipi_spi.h +171 -0
- esphome/components/mipi_spi/models/__init__.py +65 -0
- esphome/components/mipi_spi/models/amoled.py +72 -0
- esphome/components/mipi_spi/models/commands.py +82 -0
- esphome/components/mipi_spi/models/cyd.py +10 -0
- esphome/components/mipi_spi/models/ili.py +749 -0
- esphome/components/mipi_spi/models/jc.py +260 -0
- esphome/components/mipi_spi/models/lanbon.py +15 -0
- esphome/components/mipi_spi/models/lilygo.py +60 -0
- esphome/components/mipi_spi/models/waveshare.py +139 -0
- esphome/components/mitsubishi/climate.py +2 -5
- esphome/components/mitsubishi/mitsubishi.cpp +9 -9
- esphome/components/mixer/speaker/mixer_speaker.cpp +12 -22
- esphome/components/mixer/speaker/mixer_speaker.h +1 -3
- esphome/components/mlx90393/sensor.py +5 -0
- esphome/components/mlx90393/sensor_mlx90393.cpp +195 -13
- esphome/components/mlx90393/sensor_mlx90393.h +21 -4
- esphome/components/modbus/modbus.cpp +2 -1
- esphome/components/mqtt/__init__.py +1 -1
- esphome/components/mqtt/mqtt_client.cpp +6 -2
- esphome/components/mqtt/mqtt_const.h +4 -0
- esphome/components/mqtt/mqtt_fan.cpp +39 -0
- esphome/components/mqtt/mqtt_fan.h +2 -0
- esphome/components/ms5611/sensor.py +6 -6
- esphome/components/ms8607/sensor.py +3 -3
- esphome/components/network/__init__.py +1 -1
- esphome/components/nextion/base_component.py +17 -16
- esphome/components/nextion/display.py +11 -2
- esphome/components/nextion/nextion.cpp +39 -1
- esphome/components/nextion/nextion.h +50 -0
- esphome/components/noblex/climate.py +2 -9
- esphome/components/number/__init__.py +12 -9
- esphome/components/one_wire/one_wire_bus.cpp +14 -10
- esphome/components/one_wire/one_wire_bus.h +14 -8
- esphome/components/online_image/bmp_image.cpp +48 -11
- esphome/components/online_image/bmp_image.h +2 -0
- esphome/components/opentherm/binary_sensor/__init__.py +2 -4
- esphome/components/opentherm/number/__init__.py +11 -20
- esphome/components/opentherm/sensor/__init__.py +3 -3
- esphome/components/opentherm/switch/__init__.py +3 -5
- esphome/components/output/lock/__init__.py +11 -9
- esphome/components/packages/__init__.py +33 -31
- esphome/components/packet_transport/__init__.py +201 -0
- esphome/components/packet_transport/binary_sensor.py +19 -0
- esphome/components/packet_transport/packet_transport.cpp +534 -0
- esphome/components/packet_transport/packet_transport.h +154 -0
- esphome/components/packet_transport/sensor.py +19 -0
- esphome/components/pca9685/pca9685_output.cpp +2 -1
- esphome/components/pid/climate.py +2 -4
- esphome/components/pm2005/__init__.py +1 -0
- esphome/components/pm2005/pm2005.cpp +123 -0
- esphome/components/pm2005/pm2005.h +46 -0
- esphome/components/pm2005/sensor.py +86 -0
- esphome/components/pmsa003i/pmsa003i.cpp +43 -16
- esphome/components/pmsa003i/pmsa003i.h +25 -25
- esphome/components/pmsx003/pmsx003.cpp +195 -230
- esphome/components/pmsx003/pmsx003.h +51 -33
- esphome/components/pmsx003/sensor.py +21 -11
- esphome/components/pn7150/pn7150.h +2 -2
- esphome/components/pn7160/pn7160.h +2 -2
- esphome/components/prometheus/prometheus_handler.cpp +174 -0
- esphome/components/prometheus/prometheus_handler.h +17 -0
- esphome/components/psram/__init__.py +7 -5
- esphome/components/pulse_meter/pulse_meter_sensor.cpp +32 -12
- esphome/components/pulse_meter/pulse_meter_sensor.h +5 -5
- esphome/components/pzem004t/pzem004t.cpp +2 -1
- esphome/components/qspi_dbi/__init__.py +0 -1
- esphome/components/qspi_dbi/display.py +2 -1
- esphome/components/qspi_dbi/models.py +1 -2
- esphome/components/remote_base/__init__.py +91 -0
- esphome/components/remote_base/beo4_protocol.cpp +153 -0
- esphome/components/remote_base/beo4_protocol.h +43 -0
- esphome/components/remote_base/gobox_protocol.cpp +131 -0
- esphome/components/remote_base/gobox_protocol.h +54 -0
- esphome/components/remote_receiver/remote_receiver_esp32.cpp +16 -9
- esphome/components/resampler/speaker/resampler_speaker.cpp +12 -10
- esphome/components/resampler/speaker/resampler_speaker.h +1 -1
- esphome/components/rf_bridge/rf_bridge.cpp +2 -1
- esphome/components/scd30/sensor.py +2 -3
- esphome/components/scd4x/sensor.py +4 -5
- esphome/components/sdp3x/sensor.py +2 -1
- esphome/components/sds011/sds011.cpp +2 -1
- esphome/components/select/__init__.py +19 -20
- esphome/components/sen5x/sen5x.cpp +55 -36
- esphome/components/sen5x/sensor.py +1 -1
- esphome/components/senseair/sensor.py +3 -3
- esphome/components/sensor/__init__.py +158 -14
- esphome/components/sensor/filter.cpp +23 -0
- esphome/components/sensor/filter.h +22 -0
- esphome/components/sgp30/sensor.py +14 -16
- esphome/components/sgp4x/sensor.py +1 -1
- esphome/components/sht4x/sht4x.cpp +43 -22
- esphome/components/sht4x/sht4x.h +1 -1
- esphome/components/shtcx/sensor.py +6 -6
- esphome/components/slow_pwm/slow_pwm_output.cpp +2 -1
- esphome/components/sml/text_sensor/__init__.py +4 -6
- esphome/components/sound_level/__init__.py +0 -0
- esphome/components/sound_level/sensor.py +97 -0
- esphome/components/sound_level/sound_level.cpp +194 -0
- esphome/components/sound_level/sound_level.h +73 -0
- esphome/components/speaker/media_player/__init__.py +4 -8
- esphome/components/speaker/media_player/speaker_media_player.cpp +0 -18
- esphome/components/speaker/media_player/speaker_media_player.h +0 -11
- esphome/components/speaker/speaker.h +4 -7
- esphome/components/speed/fan/__init__.py +17 -16
- esphome/components/spi/spi.h +11 -1
- esphome/components/sprinkler/__init__.py +18 -19
- esphome/components/sprinkler/sprinkler.cpp +6 -5
- esphome/components/switch/__init__.py +32 -42
- esphome/components/syslog/__init__.py +41 -0
- esphome/components/syslog/esphome_syslog.cpp +49 -0
- esphome/components/syslog/esphome_syslog.h +27 -0
- esphome/components/t6615/sensor.py +3 -3
- esphome/components/t6615/t6615.cpp +2 -1
- esphome/components/tca9555/tca9555.cpp +11 -6
- esphome/components/tcl112/climate.py +2 -9
- esphome/components/template/alarm_control_panel/__init__.py +7 -6
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +21 -17
- esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +2 -1
- esphome/components/template/cover/__init__.py +27 -21
- esphome/components/template/fan/__init__.py +14 -12
- esphome/components/template/lock/__init__.py +20 -25
- esphome/components/template/lock/automation.h +18 -0
- esphome/components/template/text/__init__.py +4 -3
- esphome/components/template/valve/__init__.py +32 -21
- esphome/components/template/valve/automation.h +24 -0
- esphome/components/text/__init__.py +32 -1
- esphome/components/text_sensor/__init__.py +24 -29
- esphome/components/thermostat/climate.py +5 -5
- esphome/components/time_based/cover.py +17 -16
- esphome/components/time_based/time_based_cover.cpp +2 -1
- esphome/components/tm1638/switch/__init__.py +10 -7
- esphome/components/tormatic/cover.py +4 -5
- esphome/components/toshiba/climate.py +3 -5
- esphome/components/touchscreen/touchscreen.cpp +3 -1
- esphome/components/tt21100/touchscreen/tt21100.cpp +1 -1
- esphome/components/tuya/climate/__init__.py +5 -6
- esphome/components/tuya/cover/__init__.py +6 -11
- esphome/components/tuya/select/__init__.py +15 -5
- esphome/components/tuya/select/tuya_select.cpp +6 -1
- esphome/components/tuya/select/tuya_select.h +5 -1
- esphome/components/uart/packet_transport/__init__.py +20 -0
- esphome/components/uart/packet_transport/uart_transport.cpp +88 -0
- esphome/components/uart/packet_transport/uart_transport.h +41 -0
- esphome/components/uart/switch/uart_switch.cpp +2 -1
- esphome/components/udp/__init__.py +126 -128
- esphome/components/udp/automation.h +40 -0
- esphome/components/udp/binary_sensor.py +3 -25
- esphome/components/udp/packet_transport/__init__.py +29 -0
- esphome/components/udp/packet_transport/udp_transport.cpp +36 -0
- esphome/components/udp/packet_transport/udp_transport.h +28 -0
- esphome/components/udp/sensor.py +3 -25
- esphome/components/udp/udp_component.cpp +26 -470
- esphome/components/udp/udp_component.h +21 -128
- esphome/components/update/__init__.py +31 -1
- esphome/components/uponor_smatrix/climate/__init__.py +4 -9
- esphome/components/uponor_smatrix/climate/uponor_smatrix_climate.cpp +2 -1
- esphome/components/uponor_smatrix/uponor_smatrix.cpp +2 -1
- esphome/components/uptime/text_sensor/__init__.py +47 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.cpp +12 -7
- esphome/components/uptime/text_sensor/uptime_text_sensor.h +19 -0
- esphome/components/valve/__init__.py +34 -3
- esphome/components/valve/automation.h +1 -19
- esphome/components/vl53l0x/sensor.py +11 -0
- esphome/components/vl53l0x/vl53l0x_sensor.cpp +5 -1
- esphome/components/vl53l0x/vl53l0x_sensor.h +2 -1
- esphome/components/voice_assistant/__init__.py +36 -10
- esphome/components/voice_assistant/voice_assistant.cpp +170 -144
- esphome/components/voice_assistant/voice_assistant.h +26 -25
- esphome/components/waveshare_epaper/display.py +6 -0
- esphome/components/waveshare_epaper/waveshare_epaper.cpp +439 -37
- esphome/components/waveshare_epaper/waveshare_epaper.h +60 -11
- esphome/components/weikai/weikai.cpp +0 -52
- esphome/components/whirlpool/climate.py +3 -5
- esphome/components/whynter/climate.py +3 -5
- esphome/components/xpt2046/touchscreen/xpt2046.cpp +1 -1
- esphome/components/yashima/climate.py +6 -6
- esphome/components/zhlt01/climate.py +2 -7
- esphome/config.py +13 -13
- esphome/config_validation.py +38 -58
- esphome/const.py +15 -1
- esphome/core/__init__.py +2 -0
- esphome/core/application.cpp +27 -10
- esphome/core/application.h +9 -1
- esphome/core/automation.h +4 -3
- esphome/core/component.cpp +28 -7
- esphome/core/component.h +10 -1
- esphome/core/defines.h +23 -17
- esphome/core/doxygen.h +13 -0
- esphome/core/macros.h +4 -0
- esphome/core/scheduler.cpp +7 -1
- esphome/cpp_generator.py +6 -2
- esphome/dashboard/web_server.py +3 -3
- esphome/helpers.py +39 -0
- esphome/loader.py +4 -0
- esphome/log.py +15 -19
- esphome/mqtt.py +23 -10
- esphome/platformio_api.py +1 -1
- esphome/schema_extractors.py +0 -1
- esphome/voluptuous_schema.py +3 -1
- esphome/vscode.py +15 -0
- esphome/wizard.py +47 -37
- esphome/zeroconf.py +7 -3
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/METADATA +10 -11
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/RECORD +456 -396
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/WHEEL +1 -1
- esphome/components/esp32_ble/const_esp32c6.h +0 -74
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/entry_points.txt +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.4.1.dist-info → esphome-2025.5.0.dist-info}/top_level.txt +0 -0
@@ -8,6 +8,7 @@
|
|
8
8
|
#include "esphome/core/hal.h"
|
9
9
|
#include "esphome/core/log.h"
|
10
10
|
#include "esphome/core/version.h"
|
11
|
+
#include "esphome/core/application.h"
|
11
12
|
|
12
13
|
#ifdef USE_DEEP_SLEEP
|
13
14
|
#include "esphome/components/deep_sleep/deep_sleep_component.h"
|
@@ -29,7 +30,7 @@ static const char *const TAG = "api.connection";
|
|
29
30
|
static const int ESP32_CAMERA_STOP_STREAM = 5000;
|
30
31
|
|
31
32
|
// helper for allowing only unique entries in the queue
|
32
|
-
void DeferredMessageQueue::dmq_push_back_with_dedup_(void *source, send_message_t
|
33
|
+
void DeferredMessageQueue::dmq_push_back_with_dedup_(void *source, send_message_t send_message) {
|
33
34
|
DeferredMessage item(source, send_message);
|
34
35
|
|
35
36
|
auto iter = std::find_if(this->deferred_queue_.begin(), this->deferred_queue_.end(),
|
@@ -45,7 +46,7 @@ void DeferredMessageQueue::dmq_push_back_with_dedup_(void *source, send_message_
|
|
45
46
|
void DeferredMessageQueue::process_queue() {
|
46
47
|
while (!deferred_queue_.empty()) {
|
47
48
|
DeferredMessage &de = deferred_queue_.front();
|
48
|
-
if (
|
49
|
+
if ((this->api_connection_->*(de.send_message_))(de.source_)) {
|
49
50
|
// O(n) but memory efficiency is more important than speed here which is why std::vector was chosen
|
50
51
|
deferred_queue_.erase(deferred_queue_.begin());
|
51
52
|
} else {
|
@@ -54,7 +55,7 @@ void DeferredMessageQueue::process_queue() {
|
|
54
55
|
}
|
55
56
|
}
|
56
57
|
|
57
|
-
void DeferredMessageQueue::defer(void *source, send_message_t
|
58
|
+
void DeferredMessageQueue::defer(void *source, send_message_t send_message) {
|
58
59
|
this->dmq_push_back_with_dedup_(source, send_message);
|
59
60
|
}
|
60
61
|
|
@@ -62,7 +63,14 @@ APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *pa
|
|
62
63
|
: parent_(parent), deferred_message_queue_(this), initial_state_iterator_(this), list_entities_iterator_(this) {
|
63
64
|
this->proto_write_buffer_.reserve(64);
|
64
65
|
|
65
|
-
#if defined(USE_API_PLAINTEXT)
|
66
|
+
#if defined(USE_API_PLAINTEXT) && defined(USE_API_NOISE)
|
67
|
+
auto noise_ctx = parent->get_noise_ctx();
|
68
|
+
if (noise_ctx->has_psk()) {
|
69
|
+
this->helper_ = std::unique_ptr<APIFrameHelper>{new APINoiseFrameHelper(std::move(sock), noise_ctx)};
|
70
|
+
} else {
|
71
|
+
this->helper_ = std::unique_ptr<APIFrameHelper>{new APIPlaintextFrameHelper(std::move(sock))};
|
72
|
+
}
|
73
|
+
#elif defined(USE_API_PLAINTEXT)
|
66
74
|
this->helper_ = std::unique_ptr<APIFrameHelper>{new APIPlaintextFrameHelper(std::move(sock))};
|
67
75
|
#elif defined(USE_API_NOISE)
|
68
76
|
this->helper_ = std::unique_ptr<APIFrameHelper>{new APINoiseFrameHelper(std::move(sock), parent->get_noise_ctx())};
|
@@ -71,7 +79,11 @@ APIConnection::APIConnection(std::unique_ptr<socket::Socket> sock, APIServer *pa
|
|
71
79
|
#endif
|
72
80
|
}
|
73
81
|
void APIConnection::start() {
|
74
|
-
this->last_traffic_ =
|
82
|
+
this->last_traffic_ = App.get_loop_component_start_time();
|
83
|
+
|
84
|
+
// Set next_ping_retry_ to prevent immediate ping
|
85
|
+
// This ensures the first ping happens after the keepalive period
|
86
|
+
this->next_ping_retry_ = this->last_traffic_ + KEEPALIVE_TIMEOUT_MS;
|
75
87
|
|
76
88
|
APIError err = this->helper_->init();
|
77
89
|
if (err != APIError::OK) {
|
@@ -139,31 +151,32 @@ void APIConnection::loop() {
|
|
139
151
|
}
|
140
152
|
return;
|
141
153
|
} else {
|
142
|
-
this->last_traffic_ =
|
154
|
+
this->last_traffic_ = App.get_loop_component_start_time();
|
143
155
|
// read a packet
|
144
156
|
this->read_message(buffer.data_len, buffer.type, &buffer.container[buffer.data_offset]);
|
145
157
|
if (this->remove_)
|
146
158
|
return;
|
147
159
|
}
|
148
160
|
|
149
|
-
this->deferred_message_queue_.
|
161
|
+
if (!this->deferred_message_queue_.empty() && this->helper_->can_write_without_blocking()) {
|
162
|
+
this->deferred_message_queue_.process_queue();
|
163
|
+
}
|
150
164
|
|
151
165
|
if (!this->list_entities_iterator_.completed())
|
152
166
|
this->list_entities_iterator_.advance();
|
153
167
|
if (!this->initial_state_iterator_.completed() && this->list_entities_iterator_.completed())
|
154
168
|
this->initial_state_iterator_.advance();
|
155
169
|
|
156
|
-
static uint32_t keepalive = 60000;
|
157
170
|
static uint8_t max_ping_retries = 60;
|
158
171
|
static uint16_t ping_retry_interval = 1000;
|
159
|
-
const uint32_t now =
|
172
|
+
const uint32_t now = App.get_loop_component_start_time();
|
160
173
|
if (this->sent_ping_) {
|
161
174
|
// Disconnect if not responded within 2.5*keepalive
|
162
|
-
if (now - this->last_traffic_ > (
|
175
|
+
if (now - this->last_traffic_ > (KEEPALIVE_TIMEOUT_MS * 5) / 2) {
|
163
176
|
on_fatal_error();
|
164
177
|
ESP_LOGW(TAG, "%s didn't respond to ping request in time. Disconnecting...", this->client_combined_info_.c_str());
|
165
178
|
}
|
166
|
-
} else if (now - this->last_traffic_ >
|
179
|
+
} else if (now - this->last_traffic_ > KEEPALIVE_TIMEOUT_MS && now > this->next_ping_retry_) {
|
167
180
|
ESP_LOGVV(TAG, "Sending keepalive PING...");
|
168
181
|
this->sent_ping_ = this->send_ping_request(PingRequest());
|
169
182
|
if (!this->sent_ping_) {
|
@@ -185,15 +198,34 @@ void APIConnection::loop() {
|
|
185
198
|
|
186
199
|
#ifdef USE_ESP32_CAMERA
|
187
200
|
if (this->image_reader_.available() && this->helper_->can_write_without_blocking()) {
|
188
|
-
|
189
|
-
|
201
|
+
// Message will use 8 more bytes than the minimum size, and typical
|
202
|
+
// MTU is 1500. Sometimes users will see as low as 1460 MTU.
|
203
|
+
// If its IPv6 the header is 40 bytes, and if its IPv4
|
204
|
+
// the header is 20 bytes. So we have 1460 - 40 = 1420 bytes
|
205
|
+
// available for the payload. But we also need to add the size of
|
206
|
+
// the protobuf overhead, which is 8 bytes.
|
207
|
+
//
|
208
|
+
// To be safe we pick 1390 bytes as the maximum size
|
209
|
+
// to send in one go. This is the maximum size of a single packet
|
210
|
+
// that can be sent over the network.
|
211
|
+
// This is to avoid fragmentation of the packet.
|
212
|
+
uint32_t to_send = std::min((size_t) 1390, this->image_reader_.available());
|
213
|
+
bool done = this->image_reader_.available() == to_send;
|
214
|
+
uint32_t msg_size = 0;
|
215
|
+
ProtoSize::add_fixed_field<4>(msg_size, 1, true);
|
216
|
+
// partial message size calculated manually since its a special case
|
217
|
+
// 1 for the data field, varint for the data size, and the data itself
|
218
|
+
msg_size += 1 + ProtoSize::varint(to_send) + to_send;
|
219
|
+
ProtoSize::add_bool_field(msg_size, 1, done);
|
220
|
+
|
221
|
+
auto buffer = this->create_buffer(msg_size);
|
190
222
|
// fixed32 key = 1;
|
191
223
|
buffer.encode_fixed32(1, esp32_camera::global_esp32_camera->get_object_id_hash());
|
192
224
|
// bytes data = 2;
|
193
225
|
buffer.encode_bytes(2, this->image_reader_.peek_data_buffer(), to_send);
|
194
226
|
// bool done = 3;
|
195
|
-
bool done = this->image_reader_.available() == to_send;
|
196
227
|
buffer.encode_bool(3, done);
|
228
|
+
|
197
229
|
bool success = this->send_buffer(buffer, 44);
|
198
230
|
|
199
231
|
if (success) {
|
@@ -241,96 +273,65 @@ void APIConnection::on_disconnect_response(const DisconnectResponse &value) {
|
|
241
273
|
|
242
274
|
#ifdef USE_BINARY_SENSOR
|
243
275
|
bool APIConnection::send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor, bool state) {
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
if (!APIConnection::try_send_binary_sensor_state(this, binary_sensor, state)) {
|
248
|
-
this->deferred_message_queue_.defer(binary_sensor, try_send_binary_sensor_state);
|
249
|
-
}
|
250
|
-
|
251
|
-
return true;
|
276
|
+
return this->send_state_with_value_(binary_sensor, &APIConnection::try_send_binary_sensor_state_,
|
277
|
+
&APIConnection::try_send_binary_sensor_state_, state);
|
252
278
|
}
|
253
279
|
void APIConnection::send_binary_sensor_info(binary_sensor::BinarySensor *binary_sensor) {
|
254
|
-
|
255
|
-
|
256
|
-
}
|
280
|
+
this->send_info_(static_cast<EntityBase *>(binary_sensor),
|
281
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_binary_sensor_info_));
|
257
282
|
}
|
258
|
-
bool APIConnection::
|
259
|
-
|
260
|
-
return APIConnection::try_send_binary_sensor_state(api, binary_sensor, binary_sensor->state);
|
283
|
+
bool APIConnection::try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor) {
|
284
|
+
return this->try_send_binary_sensor_state_(binary_sensor, binary_sensor->state);
|
261
285
|
}
|
262
|
-
bool APIConnection::
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
return api->send_binary_sensor_state_response(resp);
|
286
|
+
bool APIConnection::try_send_binary_sensor_state_(binary_sensor::BinarySensor *binary_sensor, bool state) {
|
287
|
+
BinarySensorStateResponse msg;
|
288
|
+
msg.state = state;
|
289
|
+
msg.missing_state = !binary_sensor->has_state();
|
290
|
+
msg.key = binary_sensor->get_object_id_hash();
|
291
|
+
return this->send_binary_sensor_state_response(msg);
|
269
292
|
}
|
270
|
-
bool APIConnection::
|
271
|
-
binary_sensor::BinarySensor *binary_sensor = reinterpret_cast<binary_sensor::BinarySensor *>(v_binary_sensor);
|
293
|
+
bool APIConnection::try_send_binary_sensor_info_(binary_sensor::BinarySensor *binary_sensor) {
|
272
294
|
ListEntitiesBinarySensorResponse msg;
|
273
|
-
msg.object_id = binary_sensor->get_object_id();
|
274
|
-
msg.key = binary_sensor->get_object_id_hash();
|
275
|
-
if (binary_sensor->has_own_name())
|
276
|
-
msg.name = binary_sensor->get_name();
|
277
|
-
msg.unique_id = get_default_unique_id("binary_sensor", binary_sensor);
|
278
295
|
msg.device_class = binary_sensor->get_device_class();
|
279
296
|
msg.is_status_binary_sensor = binary_sensor->is_status_binary_sensor();
|
280
|
-
msg.
|
281
|
-
|
282
|
-
|
283
|
-
return api->send_list_entities_binary_sensor_response(msg);
|
297
|
+
msg.unique_id = get_default_unique_id("binary_sensor", binary_sensor);
|
298
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(binary_sensor), msg,
|
299
|
+
&APIConnection::send_list_entities_binary_sensor_response);
|
284
300
|
}
|
285
301
|
#endif
|
286
302
|
|
287
303
|
#ifdef USE_COVER
|
288
304
|
bool APIConnection::send_cover_state(cover::Cover *cover) {
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
if (!APIConnection::try_send_cover_state(this, cover)) {
|
293
|
-
this->deferred_message_queue_.defer(cover, try_send_cover_state);
|
294
|
-
}
|
295
|
-
|
296
|
-
return true;
|
305
|
+
return this->send_state_(static_cast<EntityBase *>(cover),
|
306
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_cover_state_));
|
297
307
|
}
|
298
308
|
void APIConnection::send_cover_info(cover::Cover *cover) {
|
299
|
-
|
300
|
-
|
301
|
-
}
|
309
|
+
this->send_info_(static_cast<EntityBase *>(cover),
|
310
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_cover_info_));
|
302
311
|
}
|
303
|
-
bool APIConnection::
|
304
|
-
|
312
|
+
bool APIConnection::try_send_cover_state_(cover::Cover *cover) {
|
313
|
+
CoverStateResponse msg;
|
305
314
|
auto traits = cover->get_traits();
|
306
|
-
|
307
|
-
resp.key = cover->get_object_id_hash();
|
308
|
-
resp.legacy_state =
|
315
|
+
msg.legacy_state =
|
309
316
|
(cover->position == cover::COVER_OPEN) ? enums::LEGACY_COVER_STATE_OPEN : enums::LEGACY_COVER_STATE_CLOSED;
|
310
|
-
|
317
|
+
msg.position = cover->position;
|
311
318
|
if (traits.get_supports_tilt())
|
312
|
-
|
313
|
-
|
314
|
-
|
319
|
+
msg.tilt = cover->tilt;
|
320
|
+
msg.current_operation = static_cast<enums::CoverOperation>(cover->current_operation);
|
321
|
+
msg.key = cover->get_object_id_hash();
|
322
|
+
return this->send_cover_state_response(msg);
|
315
323
|
}
|
316
|
-
bool APIConnection::
|
317
|
-
cover::Cover *cover = reinterpret_cast<cover::Cover *>(v_cover);
|
318
|
-
auto traits = cover->get_traits();
|
324
|
+
bool APIConnection::try_send_cover_info_(cover::Cover *cover) {
|
319
325
|
ListEntitiesCoverResponse msg;
|
320
|
-
|
321
|
-
msg.object_id = cover->get_object_id();
|
322
|
-
if (cover->has_own_name())
|
323
|
-
msg.name = cover->get_name();
|
324
|
-
msg.unique_id = get_default_unique_id("cover", cover);
|
326
|
+
auto traits = cover->get_traits();
|
325
327
|
msg.assumed_state = traits.get_is_assumed_state();
|
326
328
|
msg.supports_position = traits.get_supports_position();
|
327
329
|
msg.supports_tilt = traits.get_supports_tilt();
|
328
330
|
msg.supports_stop = traits.get_supports_stop();
|
329
331
|
msg.device_class = cover->get_device_class();
|
330
|
-
msg.
|
331
|
-
|
332
|
-
|
333
|
-
return api->send_list_entities_cover_response(msg);
|
332
|
+
msg.unique_id = get_default_unique_id("cover", cover);
|
333
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(cover), msg,
|
334
|
+
&APIConnection::send_list_entities_cover_response);
|
334
335
|
}
|
335
336
|
void APIConnection::cover_command(const CoverCommandRequest &msg) {
|
336
337
|
cover::Cover *cover = App.get_cover_by_key(msg.key);
|
@@ -363,56 +364,41 @@ void APIConnection::cover_command(const CoverCommandRequest &msg) {
|
|
363
364
|
|
364
365
|
#ifdef USE_FAN
|
365
366
|
bool APIConnection::send_fan_state(fan::Fan *fan) {
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
if (!APIConnection::try_send_fan_state(this, fan)) {
|
370
|
-
this->deferred_message_queue_.defer(fan, try_send_fan_state);
|
371
|
-
}
|
372
|
-
|
373
|
-
return true;
|
367
|
+
return this->send_state_(static_cast<EntityBase *>(fan),
|
368
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_fan_state_));
|
374
369
|
}
|
375
370
|
void APIConnection::send_fan_info(fan::Fan *fan) {
|
376
|
-
|
377
|
-
|
378
|
-
}
|
371
|
+
this->send_info_(static_cast<EntityBase *>(fan),
|
372
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_fan_info_));
|
379
373
|
}
|
380
|
-
bool APIConnection::
|
381
|
-
|
374
|
+
bool APIConnection::try_send_fan_state_(fan::Fan *fan) {
|
375
|
+
FanStateResponse msg;
|
382
376
|
auto traits = fan->get_traits();
|
383
|
-
|
384
|
-
resp.key = fan->get_object_id_hash();
|
385
|
-
resp.state = fan->state;
|
377
|
+
msg.state = fan->state;
|
386
378
|
if (traits.supports_oscillation())
|
387
|
-
|
379
|
+
msg.oscillating = fan->oscillating;
|
388
380
|
if (traits.supports_speed()) {
|
389
|
-
|
381
|
+
msg.speed_level = fan->speed;
|
390
382
|
}
|
391
383
|
if (traits.supports_direction())
|
392
|
-
|
384
|
+
msg.direction = static_cast<enums::FanDirection>(fan->direction);
|
393
385
|
if (traits.supports_preset_modes())
|
394
|
-
|
395
|
-
|
386
|
+
msg.preset_mode = fan->preset_mode;
|
387
|
+
msg.key = fan->get_object_id_hash();
|
388
|
+
return this->send_fan_state_response(msg);
|
396
389
|
}
|
397
|
-
bool APIConnection::
|
398
|
-
fan::Fan *fan = reinterpret_cast<fan::Fan *>(v_fan);
|
399
|
-
auto traits = fan->get_traits();
|
390
|
+
bool APIConnection::try_send_fan_info_(fan::Fan *fan) {
|
400
391
|
ListEntitiesFanResponse msg;
|
401
|
-
|
402
|
-
msg.object_id = fan->get_object_id();
|
403
|
-
if (fan->has_own_name())
|
404
|
-
msg.name = fan->get_name();
|
405
|
-
msg.unique_id = get_default_unique_id("fan", fan);
|
392
|
+
auto traits = fan->get_traits();
|
406
393
|
msg.supports_oscillation = traits.supports_oscillation();
|
407
394
|
msg.supports_speed = traits.supports_speed();
|
408
395
|
msg.supports_direction = traits.supports_direction();
|
409
396
|
msg.supported_speed_count = traits.supported_speed_count();
|
410
397
|
for (auto const &preset : traits.supported_preset_modes())
|
411
398
|
msg.supported_preset_modes.push_back(preset);
|
412
|
-
msg.
|
413
|
-
|
414
|
-
|
415
|
-
return api->send_list_entities_fan_response(msg);
|
399
|
+
msg.unique_id = get_default_unique_id("fan", fan);
|
400
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(fan), msg,
|
401
|
+
&APIConnection::send_list_entities_fan_response);
|
416
402
|
}
|
417
403
|
void APIConnection::fan_command(const FanCommandRequest &msg) {
|
418
404
|
fan::Fan *fan = App.get_fan_by_key(msg.key);
|
@@ -438,28 +424,18 @@ void APIConnection::fan_command(const FanCommandRequest &msg) {
|
|
438
424
|
|
439
425
|
#ifdef USE_LIGHT
|
440
426
|
bool APIConnection::send_light_state(light::LightState *light) {
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
if (!APIConnection::try_send_light_state(this, light)) {
|
445
|
-
this->deferred_message_queue_.defer(light, try_send_light_state);
|
446
|
-
}
|
447
|
-
|
448
|
-
return true;
|
427
|
+
return this->send_state_(static_cast<EntityBase *>(light),
|
428
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_light_state_));
|
449
429
|
}
|
450
430
|
void APIConnection::send_light_info(light::LightState *light) {
|
451
|
-
|
452
|
-
|
453
|
-
}
|
431
|
+
this->send_info_(static_cast<EntityBase *>(light),
|
432
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_light_info_));
|
454
433
|
}
|
455
|
-
bool APIConnection::
|
456
|
-
|
434
|
+
bool APIConnection::try_send_light_state_(light::LightState *light) {
|
435
|
+
LightStateResponse resp;
|
457
436
|
auto traits = light->get_traits();
|
458
437
|
auto values = light->remote_values;
|
459
438
|
auto color_mode = values.get_color_mode();
|
460
|
-
LightStateResponse resp{};
|
461
|
-
|
462
|
-
resp.key = light->get_object_id_hash();
|
463
439
|
resp.state = values.is_on();
|
464
440
|
resp.color_mode = static_cast<enums::ColorMode>(color_mode);
|
465
441
|
resp.brightness = values.get_brightness();
|
@@ -473,25 +449,14 @@ bool APIConnection::try_send_light_state(APIConnection *api, void *v_light) {
|
|
473
449
|
resp.warm_white = values.get_warm_white();
|
474
450
|
if (light->supports_effects())
|
475
451
|
resp.effect = light->get_effect_name();
|
476
|
-
|
452
|
+
resp.key = light->get_object_id_hash();
|
453
|
+
return this->send_light_state_response(resp);
|
477
454
|
}
|
478
|
-
bool APIConnection::
|
479
|
-
light::LightState *light = reinterpret_cast<light::LightState *>(v_light);
|
480
|
-
auto traits = light->get_traits();
|
455
|
+
bool APIConnection::try_send_light_info_(light::LightState *light) {
|
481
456
|
ListEntitiesLightResponse msg;
|
482
|
-
|
483
|
-
msg.object_id = light->get_object_id();
|
484
|
-
if (light->has_own_name())
|
485
|
-
msg.name = light->get_name();
|
486
|
-
msg.unique_id = get_default_unique_id("light", light);
|
487
|
-
|
488
|
-
msg.disabled_by_default = light->is_disabled_by_default();
|
489
|
-
msg.icon = light->get_icon();
|
490
|
-
msg.entity_category = static_cast<enums::EntityCategory>(light->get_entity_category());
|
491
|
-
|
457
|
+
auto traits = light->get_traits();
|
492
458
|
for (auto mode : traits.get_supported_color_modes())
|
493
459
|
msg.supported_color_modes.push_back(static_cast<enums::ColorMode>(mode));
|
494
|
-
|
495
460
|
msg.legacy_supports_brightness = traits.supports_color_capability(light::ColorCapability::BRIGHTNESS);
|
496
461
|
msg.legacy_supports_rgb = traits.supports_color_capability(light::ColorCapability::RGB);
|
497
462
|
msg.legacy_supports_white_value =
|
@@ -499,17 +464,19 @@ bool APIConnection::try_send_light_info(APIConnection *api, void *v_light) {
|
|
499
464
|
traits.supports_color_capability(light::ColorCapability::COLD_WARM_WHITE));
|
500
465
|
msg.legacy_supports_color_temperature = traits.supports_color_capability(light::ColorCapability::COLOR_TEMPERATURE) ||
|
501
466
|
traits.supports_color_capability(light::ColorCapability::COLD_WARM_WHITE);
|
502
|
-
|
503
467
|
if (msg.legacy_supports_color_temperature) {
|
504
468
|
msg.min_mireds = traits.get_min_mireds();
|
505
469
|
msg.max_mireds = traits.get_max_mireds();
|
506
470
|
}
|
507
471
|
if (light->supports_effects()) {
|
508
472
|
msg.effects.emplace_back("None");
|
509
|
-
for (auto *effect : light->get_effects())
|
473
|
+
for (auto *effect : light->get_effects()) {
|
510
474
|
msg.effects.push_back(effect->get_name());
|
475
|
+
}
|
511
476
|
}
|
512
|
-
|
477
|
+
msg.unique_id = get_default_unique_id("light", light);
|
478
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(light), msg,
|
479
|
+
&APIConnection::send_list_entities_light_response);
|
513
480
|
}
|
514
481
|
void APIConnection::light_command(const LightCommandRequest &msg) {
|
515
482
|
light::LightState *light = App.get_light_by_key(msg.key);
|
@@ -550,93 +517,65 @@ void APIConnection::light_command(const LightCommandRequest &msg) {
|
|
550
517
|
|
551
518
|
#ifdef USE_SENSOR
|
552
519
|
bool APIConnection::send_sensor_state(sensor::Sensor *sensor, float state) {
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
if (!APIConnection::try_send_sensor_state(this, sensor, state)) {
|
557
|
-
this->deferred_message_queue_.defer(sensor, try_send_sensor_state);
|
558
|
-
}
|
559
|
-
|
560
|
-
return true;
|
520
|
+
return this->send_state_with_value_(sensor, &APIConnection::try_send_sensor_state_,
|
521
|
+
&APIConnection::try_send_sensor_state_, state);
|
561
522
|
}
|
562
523
|
void APIConnection::send_sensor_info(sensor::Sensor *sensor) {
|
563
|
-
|
564
|
-
|
565
|
-
}
|
524
|
+
this->send_info_(static_cast<EntityBase *>(sensor),
|
525
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_sensor_info_));
|
566
526
|
}
|
567
|
-
bool APIConnection::
|
568
|
-
|
569
|
-
return APIConnection::try_send_sensor_state(api, sensor, sensor->state);
|
527
|
+
bool APIConnection::try_send_sensor_state_(sensor::Sensor *sensor) {
|
528
|
+
return this->try_send_sensor_state_(sensor, sensor->state);
|
570
529
|
}
|
571
|
-
bool APIConnection::
|
572
|
-
SensorStateResponse resp
|
573
|
-
resp.key = sensor->get_object_id_hash();
|
530
|
+
bool APIConnection::try_send_sensor_state_(sensor::Sensor *sensor, float state) {
|
531
|
+
SensorStateResponse resp;
|
574
532
|
resp.state = state;
|
575
533
|
resp.missing_state = !sensor->has_state();
|
576
|
-
|
534
|
+
|
535
|
+
resp.key = sensor->get_object_id_hash();
|
536
|
+
return this->send_sensor_state_response(resp);
|
577
537
|
}
|
578
|
-
bool APIConnection::
|
579
|
-
sensor::Sensor *sensor = reinterpret_cast<sensor::Sensor *>(v_sensor);
|
538
|
+
bool APIConnection::try_send_sensor_info_(sensor::Sensor *sensor) {
|
580
539
|
ListEntitiesSensorResponse msg;
|
581
|
-
msg.key = sensor->get_object_id_hash();
|
582
|
-
msg.object_id = sensor->get_object_id();
|
583
|
-
if (sensor->has_own_name())
|
584
|
-
msg.name = sensor->get_name();
|
585
|
-
msg.unique_id = sensor->unique_id();
|
586
|
-
if (msg.unique_id.empty())
|
587
|
-
msg.unique_id = get_default_unique_id("sensor", sensor);
|
588
|
-
msg.icon = sensor->get_icon();
|
589
540
|
msg.unit_of_measurement = sensor->get_unit_of_measurement();
|
590
541
|
msg.accuracy_decimals = sensor->get_accuracy_decimals();
|
591
542
|
msg.force_update = sensor->get_force_update();
|
592
543
|
msg.device_class = sensor->get_device_class();
|
593
544
|
msg.state_class = static_cast<enums::SensorStateClass>(sensor->get_state_class());
|
594
|
-
msg.
|
595
|
-
msg.
|
596
|
-
|
545
|
+
msg.unique_id = sensor->unique_id();
|
546
|
+
if (msg.unique_id.empty())
|
547
|
+
msg.unique_id = get_default_unique_id("sensor", sensor);
|
548
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(sensor), msg,
|
549
|
+
&APIConnection::send_list_entities_sensor_response);
|
597
550
|
}
|
598
551
|
#endif
|
599
552
|
|
600
553
|
#ifdef USE_SWITCH
|
601
554
|
bool APIConnection::send_switch_state(switch_::Switch *a_switch, bool state) {
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
if (!APIConnection::try_send_switch_state(this, a_switch, state)) {
|
606
|
-
this->deferred_message_queue_.defer(a_switch, try_send_switch_state);
|
607
|
-
}
|
608
|
-
|
609
|
-
return true;
|
555
|
+
return this->send_state_with_value_(a_switch, &APIConnection::try_send_switch_state_,
|
556
|
+
&APIConnection::try_send_switch_state_, state);
|
610
557
|
}
|
611
558
|
void APIConnection::send_switch_info(switch_::Switch *a_switch) {
|
612
|
-
|
613
|
-
|
614
|
-
}
|
559
|
+
this->send_info_(static_cast<EntityBase *>(a_switch),
|
560
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_switch_info_));
|
615
561
|
}
|
616
|
-
bool APIConnection::
|
617
|
-
|
618
|
-
return APIConnection::try_send_switch_state(api, a_switch, a_switch->state);
|
562
|
+
bool APIConnection::try_send_switch_state_(switch_::Switch *a_switch) {
|
563
|
+
return this->try_send_switch_state_(a_switch, a_switch->state);
|
619
564
|
}
|
620
|
-
bool APIConnection::
|
621
|
-
SwitchStateResponse resp
|
622
|
-
resp.key = a_switch->get_object_id_hash();
|
565
|
+
bool APIConnection::try_send_switch_state_(switch_::Switch *a_switch, bool state) {
|
566
|
+
SwitchStateResponse resp;
|
623
567
|
resp.state = state;
|
624
|
-
|
568
|
+
|
569
|
+
resp.key = a_switch->get_object_id_hash();
|
570
|
+
return this->send_switch_state_response(resp);
|
625
571
|
}
|
626
|
-
bool APIConnection::
|
627
|
-
switch_::Switch *a_switch = reinterpret_cast<switch_::Switch *>(v_a_switch);
|
572
|
+
bool APIConnection::try_send_switch_info_(switch_::Switch *a_switch) {
|
628
573
|
ListEntitiesSwitchResponse msg;
|
629
|
-
msg.key = a_switch->get_object_id_hash();
|
630
|
-
msg.object_id = a_switch->get_object_id();
|
631
|
-
if (a_switch->has_own_name())
|
632
|
-
msg.name = a_switch->get_name();
|
633
|
-
msg.unique_id = get_default_unique_id("switch", a_switch);
|
634
|
-
msg.icon = a_switch->get_icon();
|
635
574
|
msg.assumed_state = a_switch->assumed_state();
|
636
|
-
msg.disabled_by_default = a_switch->is_disabled_by_default();
|
637
|
-
msg.entity_category = static_cast<enums::EntityCategory>(a_switch->get_entity_category());
|
638
575
|
msg.device_class = a_switch->get_device_class();
|
639
|
-
|
576
|
+
msg.unique_id = get_default_unique_id("switch", a_switch);
|
577
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(a_switch), msg,
|
578
|
+
&APIConnection::send_list_entities_switch_response);
|
640
579
|
}
|
641
580
|
void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
642
581
|
switch_::Switch *a_switch = App.get_switch_by_key(msg.key);
|
@@ -653,70 +592,48 @@ void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
|
653
592
|
|
654
593
|
#ifdef USE_TEXT_SENSOR
|
655
594
|
bool APIConnection::send_text_sensor_state(text_sensor::TextSensor *text_sensor, std::string state) {
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
if (!APIConnection::try_send_text_sensor_state(this, text_sensor, std::move(state))) {
|
660
|
-
this->deferred_message_queue_.defer(text_sensor, try_send_text_sensor_state);
|
661
|
-
}
|
662
|
-
|
663
|
-
return true;
|
595
|
+
return this->send_state_with_value_(text_sensor, &APIConnection::try_send_text_sensor_state_,
|
596
|
+
&APIConnection::try_send_text_sensor_state_, std::move(state));
|
664
597
|
}
|
665
598
|
void APIConnection::send_text_sensor_info(text_sensor::TextSensor *text_sensor) {
|
666
|
-
|
667
|
-
|
668
|
-
}
|
599
|
+
this->send_info_(static_cast<EntityBase *>(text_sensor),
|
600
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_text_sensor_info_));
|
669
601
|
}
|
670
|
-
bool APIConnection::
|
671
|
-
|
672
|
-
return APIConnection::try_send_text_sensor_state(api, text_sensor, text_sensor->state);
|
602
|
+
bool APIConnection::try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor) {
|
603
|
+
return this->try_send_text_sensor_state_(text_sensor, text_sensor->state);
|
673
604
|
}
|
674
|
-
bool APIConnection::
|
675
|
-
|
676
|
-
TextSensorStateResponse resp{};
|
677
|
-
resp.key = text_sensor->get_object_id_hash();
|
605
|
+
bool APIConnection::try_send_text_sensor_state_(text_sensor::TextSensor *text_sensor, std::string state) {
|
606
|
+
TextSensorStateResponse resp;
|
678
607
|
resp.state = std::move(state);
|
679
608
|
resp.missing_state = !text_sensor->has_state();
|
680
|
-
|
609
|
+
|
610
|
+
resp.key = text_sensor->get_object_id_hash();
|
611
|
+
return this->send_text_sensor_state_response(resp);
|
681
612
|
}
|
682
|
-
bool APIConnection::
|
683
|
-
text_sensor::TextSensor *text_sensor = reinterpret_cast<text_sensor::TextSensor *>(v_text_sensor);
|
613
|
+
bool APIConnection::try_send_text_sensor_info_(text_sensor::TextSensor *text_sensor) {
|
684
614
|
ListEntitiesTextSensorResponse msg;
|
685
|
-
msg.
|
686
|
-
msg.object_id = text_sensor->get_object_id();
|
687
|
-
msg.name = text_sensor->get_name();
|
615
|
+
msg.device_class = text_sensor->get_device_class();
|
688
616
|
msg.unique_id = text_sensor->unique_id();
|
689
617
|
if (msg.unique_id.empty())
|
690
618
|
msg.unique_id = get_default_unique_id("text_sensor", text_sensor);
|
691
|
-
|
692
|
-
|
693
|
-
msg.entity_category = static_cast<enums::EntityCategory>(text_sensor->get_entity_category());
|
694
|
-
msg.device_class = text_sensor->get_device_class();
|
695
|
-
return api->send_list_entities_text_sensor_response(msg);
|
619
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(text_sensor), msg,
|
620
|
+
&APIConnection::send_list_entities_text_sensor_response);
|
696
621
|
}
|
697
622
|
#endif
|
698
623
|
|
699
624
|
#ifdef USE_CLIMATE
|
700
625
|
bool APIConnection::send_climate_state(climate::Climate *climate) {
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
if (!APIConnection::try_send_climate_state(this, climate)) {
|
705
|
-
this->deferred_message_queue_.defer(climate, try_send_climate_state);
|
706
|
-
}
|
707
|
-
|
708
|
-
return true;
|
626
|
+
return this->send_state_(static_cast<EntityBase *>(climate),
|
627
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_climate_state_));
|
709
628
|
}
|
710
629
|
void APIConnection::send_climate_info(climate::Climate *climate) {
|
711
|
-
|
712
|
-
|
713
|
-
}
|
630
|
+
this->send_info_(static_cast<EntityBase *>(climate),
|
631
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_climate_info_));
|
714
632
|
}
|
715
|
-
bool APIConnection::
|
716
|
-
|
717
|
-
auto traits = climate->get_traits();
|
718
|
-
ClimateStateResponse resp{};
|
633
|
+
bool APIConnection::try_send_climate_state_(climate::Climate *climate) {
|
634
|
+
ClimateStateResponse resp;
|
719
635
|
resp.key = climate->get_object_id_hash();
|
636
|
+
auto traits = climate->get_traits();
|
720
637
|
resp.mode = static_cast<enums::ClimateMode>(climate->mode);
|
721
638
|
resp.action = static_cast<enums::ClimateAction>(climate->action);
|
722
639
|
if (traits.get_supports_current_temperature())
|
@@ -742,40 +659,25 @@ bool APIConnection::try_send_climate_state(APIConnection *api, void *v_climate)
|
|
742
659
|
resp.current_humidity = climate->current_humidity;
|
743
660
|
if (traits.get_supports_target_humidity())
|
744
661
|
resp.target_humidity = climate->target_humidity;
|
745
|
-
return
|
662
|
+
return this->send_climate_state_response(resp);
|
746
663
|
}
|
747
|
-
bool APIConnection::
|
748
|
-
climate::Climate *climate = reinterpret_cast<climate::Climate *>(v_climate);
|
749
|
-
auto traits = climate->get_traits();
|
664
|
+
bool APIConnection::try_send_climate_info_(climate::Climate *climate) {
|
750
665
|
ListEntitiesClimateResponse msg;
|
751
|
-
|
752
|
-
msg.object_id = climate->get_object_id();
|
753
|
-
if (climate->has_own_name())
|
754
|
-
msg.name = climate->get_name();
|
755
|
-
msg.unique_id = get_default_unique_id("climate", climate);
|
756
|
-
|
757
|
-
msg.disabled_by_default = climate->is_disabled_by_default();
|
758
|
-
msg.icon = climate->get_icon();
|
759
|
-
msg.entity_category = static_cast<enums::EntityCategory>(climate->get_entity_category());
|
760
|
-
|
666
|
+
auto traits = climate->get_traits();
|
761
667
|
msg.supports_current_temperature = traits.get_supports_current_temperature();
|
762
668
|
msg.supports_current_humidity = traits.get_supports_current_humidity();
|
763
669
|
msg.supports_two_point_target_temperature = traits.get_supports_two_point_target_temperature();
|
764
670
|
msg.supports_target_humidity = traits.get_supports_target_humidity();
|
765
|
-
|
766
671
|
for (auto mode : traits.get_supported_modes())
|
767
672
|
msg.supported_modes.push_back(static_cast<enums::ClimateMode>(mode));
|
768
|
-
|
769
673
|
msg.visual_min_temperature = traits.get_visual_min_temperature();
|
770
674
|
msg.visual_max_temperature = traits.get_visual_max_temperature();
|
771
675
|
msg.visual_target_temperature_step = traits.get_visual_target_temperature_step();
|
772
676
|
msg.visual_current_temperature_step = traits.get_visual_current_temperature_step();
|
773
677
|
msg.visual_min_humidity = traits.get_visual_min_humidity();
|
774
678
|
msg.visual_max_humidity = traits.get_visual_max_humidity();
|
775
|
-
|
776
679
|
msg.legacy_supports_away = traits.supports_preset(climate::CLIMATE_PRESET_AWAY);
|
777
680
|
msg.supports_action = traits.get_supports_action();
|
778
|
-
|
779
681
|
for (auto fan_mode : traits.get_supported_fan_modes())
|
780
682
|
msg.supported_fan_modes.push_back(static_cast<enums::ClimateFanMode>(fan_mode));
|
781
683
|
for (auto const &custom_fan_mode : traits.get_supported_custom_fan_modes())
|
@@ -786,7 +688,9 @@ bool APIConnection::try_send_climate_info(APIConnection *api, void *v_climate) {
|
|
786
688
|
msg.supported_custom_presets.push_back(custom_preset);
|
787
689
|
for (auto swing_mode : traits.get_supported_swing_modes())
|
788
690
|
msg.supported_swing_modes.push_back(static_cast<enums::ClimateSwingMode>(swing_mode));
|
789
|
-
|
691
|
+
msg.unique_id = get_default_unique_id("climate", climate);
|
692
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(climate), msg,
|
693
|
+
&APIConnection::send_list_entities_climate_response);
|
790
694
|
}
|
791
695
|
void APIConnection::climate_command(const ClimateCommandRequest &msg) {
|
792
696
|
climate::Climate *climate = App.get_climate_by_key(msg.key);
|
@@ -820,51 +724,35 @@ void APIConnection::climate_command(const ClimateCommandRequest &msg) {
|
|
820
724
|
|
821
725
|
#ifdef USE_NUMBER
|
822
726
|
bool APIConnection::send_number_state(number::Number *number, float state) {
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
if (!APIConnection::try_send_number_state(this, number, state)) {
|
827
|
-
this->deferred_message_queue_.defer(number, try_send_number_state);
|
828
|
-
}
|
829
|
-
|
830
|
-
return true;
|
727
|
+
return this->send_state_with_value_(number, &APIConnection::try_send_number_state_,
|
728
|
+
&APIConnection::try_send_number_state_, state);
|
831
729
|
}
|
832
730
|
void APIConnection::send_number_info(number::Number *number) {
|
833
|
-
|
834
|
-
|
835
|
-
}
|
731
|
+
this->send_info_(static_cast<EntityBase *>(number),
|
732
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_number_info_));
|
836
733
|
}
|
837
|
-
bool APIConnection::
|
838
|
-
|
839
|
-
return APIConnection::try_send_number_state(api, number, number->state);
|
734
|
+
bool APIConnection::try_send_number_state_(number::Number *number) {
|
735
|
+
return this->try_send_number_state_(number, number->state);
|
840
736
|
}
|
841
|
-
bool APIConnection::
|
842
|
-
NumberStateResponse resp
|
843
|
-
resp.key = number->get_object_id_hash();
|
737
|
+
bool APIConnection::try_send_number_state_(number::Number *number, float state) {
|
738
|
+
NumberStateResponse resp;
|
844
739
|
resp.state = state;
|
845
740
|
resp.missing_state = !number->has_state();
|
846
|
-
|
741
|
+
|
742
|
+
resp.key = number->get_object_id_hash();
|
743
|
+
return this->send_number_state_response(resp);
|
847
744
|
}
|
848
|
-
bool APIConnection::
|
849
|
-
number::Number *number = reinterpret_cast<number::Number *>(v_number);
|
745
|
+
bool APIConnection::try_send_number_info_(number::Number *number) {
|
850
746
|
ListEntitiesNumberResponse msg;
|
851
|
-
msg.key = number->get_object_id_hash();
|
852
|
-
msg.object_id = number->get_object_id();
|
853
|
-
if (number->has_own_name())
|
854
|
-
msg.name = number->get_name();
|
855
|
-
msg.unique_id = get_default_unique_id("number", number);
|
856
|
-
msg.icon = number->get_icon();
|
857
|
-
msg.disabled_by_default = number->is_disabled_by_default();
|
858
|
-
msg.entity_category = static_cast<enums::EntityCategory>(number->get_entity_category());
|
859
747
|
msg.unit_of_measurement = number->traits.get_unit_of_measurement();
|
860
748
|
msg.mode = static_cast<enums::NumberMode>(number->traits.get_mode());
|
861
749
|
msg.device_class = number->traits.get_device_class();
|
862
|
-
|
863
750
|
msg.min_value = number->traits.get_min_value();
|
864
751
|
msg.max_value = number->traits.get_max_value();
|
865
752
|
msg.step = number->traits.get_step();
|
866
|
-
|
867
|
-
return
|
753
|
+
msg.unique_id = get_default_unique_id("number", number);
|
754
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(number), msg,
|
755
|
+
&APIConnection::send_list_entities_number_response);
|
868
756
|
}
|
869
757
|
void APIConnection::number_command(const NumberCommandRequest &msg) {
|
870
758
|
number::Number *number = App.get_number_by_key(msg.key);
|
@@ -879,43 +767,28 @@ void APIConnection::number_command(const NumberCommandRequest &msg) {
|
|
879
767
|
|
880
768
|
#ifdef USE_DATETIME_DATE
|
881
769
|
bool APIConnection::send_date_state(datetime::DateEntity *date) {
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
if (!APIConnection::try_send_date_state(this, date)) {
|
886
|
-
this->deferred_message_queue_.defer(date, try_send_date_state);
|
887
|
-
}
|
888
|
-
|
889
|
-
return true;
|
770
|
+
return this->send_state_(static_cast<EntityBase *>(date),
|
771
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_date_state_));
|
890
772
|
}
|
891
773
|
void APIConnection::send_date_info(datetime::DateEntity *date) {
|
892
|
-
|
893
|
-
|
894
|
-
}
|
774
|
+
this->send_info_(static_cast<EntityBase *>(date),
|
775
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_date_info_));
|
895
776
|
}
|
896
|
-
bool APIConnection::
|
897
|
-
|
898
|
-
DateStateResponse resp{};
|
899
|
-
resp.key = date->get_object_id_hash();
|
777
|
+
bool APIConnection::try_send_date_state_(datetime::DateEntity *date) {
|
778
|
+
DateStateResponse resp;
|
900
779
|
resp.missing_state = !date->has_state();
|
901
780
|
resp.year = date->year;
|
902
781
|
resp.month = date->month;
|
903
782
|
resp.day = date->day;
|
904
|
-
|
783
|
+
|
784
|
+
resp.key = date->get_object_id_hash();
|
785
|
+
return this->send_date_state_response(resp);
|
905
786
|
}
|
906
|
-
bool APIConnection::
|
907
|
-
datetime::DateEntity *date = reinterpret_cast<datetime::DateEntity *>(v_date);
|
787
|
+
bool APIConnection::try_send_date_info_(datetime::DateEntity *date) {
|
908
788
|
ListEntitiesDateResponse msg;
|
909
|
-
msg.key = date->get_object_id_hash();
|
910
|
-
msg.object_id = date->get_object_id();
|
911
|
-
if (date->has_own_name())
|
912
|
-
msg.name = date->get_name();
|
913
789
|
msg.unique_id = get_default_unique_id("date", date);
|
914
|
-
|
915
|
-
|
916
|
-
msg.entity_category = static_cast<enums::EntityCategory>(date->get_entity_category());
|
917
|
-
|
918
|
-
return api->send_list_entities_date_response(msg);
|
790
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(date), msg,
|
791
|
+
&APIConnection::send_list_entities_date_response);
|
919
792
|
}
|
920
793
|
void APIConnection::date_command(const DateCommandRequest &msg) {
|
921
794
|
datetime::DateEntity *date = App.get_date_by_key(msg.key);
|
@@ -930,43 +803,28 @@ void APIConnection::date_command(const DateCommandRequest &msg) {
|
|
930
803
|
|
931
804
|
#ifdef USE_DATETIME_TIME
|
932
805
|
bool APIConnection::send_time_state(datetime::TimeEntity *time) {
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
if (!APIConnection::try_send_time_state(this, time)) {
|
937
|
-
this->deferred_message_queue_.defer(time, try_send_time_state);
|
938
|
-
}
|
939
|
-
|
940
|
-
return true;
|
806
|
+
return this->send_state_(static_cast<EntityBase *>(time),
|
807
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_time_state_));
|
941
808
|
}
|
942
809
|
void APIConnection::send_time_info(datetime::TimeEntity *time) {
|
943
|
-
|
944
|
-
|
945
|
-
}
|
810
|
+
this->send_info_(static_cast<EntityBase *>(time),
|
811
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_time_info_));
|
946
812
|
}
|
947
|
-
bool APIConnection::
|
948
|
-
|
949
|
-
TimeStateResponse resp{};
|
950
|
-
resp.key = time->get_object_id_hash();
|
813
|
+
bool APIConnection::try_send_time_state_(datetime::TimeEntity *time) {
|
814
|
+
TimeStateResponse resp;
|
951
815
|
resp.missing_state = !time->has_state();
|
952
816
|
resp.hour = time->hour;
|
953
817
|
resp.minute = time->minute;
|
954
818
|
resp.second = time->second;
|
955
|
-
|
819
|
+
|
820
|
+
resp.key = time->get_object_id_hash();
|
821
|
+
return this->send_time_state_response(resp);
|
956
822
|
}
|
957
|
-
bool APIConnection::
|
958
|
-
datetime::TimeEntity *time = reinterpret_cast<datetime::TimeEntity *>(v_time);
|
823
|
+
bool APIConnection::try_send_time_info_(datetime::TimeEntity *time) {
|
959
824
|
ListEntitiesTimeResponse msg;
|
960
|
-
msg.key = time->get_object_id_hash();
|
961
|
-
msg.object_id = time->get_object_id();
|
962
|
-
if (time->has_own_name())
|
963
|
-
msg.name = time->get_name();
|
964
825
|
msg.unique_id = get_default_unique_id("time", time);
|
965
|
-
|
966
|
-
|
967
|
-
msg.entity_category = static_cast<enums::EntityCategory>(time->get_entity_category());
|
968
|
-
|
969
|
-
return api->send_list_entities_time_response(msg);
|
826
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(time), msg,
|
827
|
+
&APIConnection::send_list_entities_time_response);
|
970
828
|
}
|
971
829
|
void APIConnection::time_command(const TimeCommandRequest &msg) {
|
972
830
|
datetime::TimeEntity *time = App.get_time_by_key(msg.key);
|
@@ -981,44 +839,29 @@ void APIConnection::time_command(const TimeCommandRequest &msg) {
|
|
981
839
|
|
982
840
|
#ifdef USE_DATETIME_DATETIME
|
983
841
|
bool APIConnection::send_datetime_state(datetime::DateTimeEntity *datetime) {
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
if (!APIConnection::try_send_datetime_state(this, datetime)) {
|
988
|
-
this->deferred_message_queue_.defer(datetime, try_send_datetime_state);
|
989
|
-
}
|
990
|
-
|
991
|
-
return true;
|
842
|
+
return this->send_state_(static_cast<EntityBase *>(datetime),
|
843
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_datetime_state_));
|
992
844
|
}
|
993
845
|
void APIConnection::send_datetime_info(datetime::DateTimeEntity *datetime) {
|
994
|
-
|
995
|
-
|
996
|
-
}
|
846
|
+
this->send_info_(static_cast<EntityBase *>(datetime),
|
847
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_datetime_info_));
|
997
848
|
}
|
998
|
-
bool APIConnection::
|
999
|
-
|
1000
|
-
DateTimeStateResponse resp{};
|
1001
|
-
resp.key = datetime->get_object_id_hash();
|
849
|
+
bool APIConnection::try_send_datetime_state_(datetime::DateTimeEntity *datetime) {
|
850
|
+
DateTimeStateResponse resp;
|
1002
851
|
resp.missing_state = !datetime->has_state();
|
1003
852
|
if (datetime->has_state()) {
|
1004
853
|
ESPTime state = datetime->state_as_esptime();
|
1005
854
|
resp.epoch_seconds = state.timestamp;
|
1006
855
|
}
|
1007
|
-
|
856
|
+
|
857
|
+
resp.key = datetime->get_object_id_hash();
|
858
|
+
return this->send_date_time_state_response(resp);
|
1008
859
|
}
|
1009
|
-
bool APIConnection::
|
1010
|
-
datetime::DateTimeEntity *datetime = reinterpret_cast<datetime::DateTimeEntity *>(v_datetime);
|
860
|
+
bool APIConnection::try_send_datetime_info_(datetime::DateTimeEntity *datetime) {
|
1011
861
|
ListEntitiesDateTimeResponse msg;
|
1012
|
-
msg.key = datetime->get_object_id_hash();
|
1013
|
-
msg.object_id = datetime->get_object_id();
|
1014
|
-
if (datetime->has_own_name())
|
1015
|
-
msg.name = datetime->get_name();
|
1016
862
|
msg.unique_id = get_default_unique_id("datetime", datetime);
|
1017
|
-
|
1018
|
-
|
1019
|
-
msg.entity_category = static_cast<enums::EntityCategory>(datetime->get_entity_category());
|
1020
|
-
|
1021
|
-
return api->send_list_entities_date_time_response(msg);
|
863
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(datetime), msg,
|
864
|
+
&APIConnection::send_list_entities_date_time_response);
|
1022
865
|
}
|
1023
866
|
void APIConnection::datetime_command(const DateTimeCommandRequest &msg) {
|
1024
867
|
datetime::DateTimeEntity *datetime = App.get_datetime_by_key(msg.key);
|
@@ -1033,47 +876,31 @@ void APIConnection::datetime_command(const DateTimeCommandRequest &msg) {
|
|
1033
876
|
|
1034
877
|
#ifdef USE_TEXT
|
1035
878
|
bool APIConnection::send_text_state(text::Text *text, std::string state) {
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
if (!APIConnection::try_send_text_state(this, text, std::move(state))) {
|
1040
|
-
this->deferred_message_queue_.defer(text, try_send_text_state);
|
1041
|
-
}
|
1042
|
-
|
1043
|
-
return true;
|
879
|
+
return this->send_state_with_value_(text, &APIConnection::try_send_text_state_, &APIConnection::try_send_text_state_,
|
880
|
+
std::move(state));
|
1044
881
|
}
|
1045
882
|
void APIConnection::send_text_info(text::Text *text) {
|
1046
|
-
|
1047
|
-
|
1048
|
-
}
|
1049
|
-
}
|
1050
|
-
bool APIConnection::try_send_text_state(APIConnection *api, void *v_text) {
|
1051
|
-
text::Text *text = reinterpret_cast<text::Text *>(v_text);
|
1052
|
-
return APIConnection::try_send_text_state(api, text, text->state);
|
883
|
+
this->send_info_(static_cast<EntityBase *>(text),
|
884
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_text_info_));
|
1053
885
|
}
|
1054
|
-
bool APIConnection::
|
1055
|
-
|
1056
|
-
resp
|
886
|
+
bool APIConnection::try_send_text_state_(text::Text *text) { return this->try_send_text_state_(text, text->state); }
|
887
|
+
bool APIConnection::try_send_text_state_(text::Text *text, std::string state) {
|
888
|
+
TextStateResponse resp;
|
1057
889
|
resp.state = std::move(state);
|
1058
890
|
resp.missing_state = !text->has_state();
|
1059
|
-
|
891
|
+
|
892
|
+
resp.key = text->get_object_id_hash();
|
893
|
+
return this->send_text_state_response(resp);
|
1060
894
|
}
|
1061
|
-
bool APIConnection::
|
1062
|
-
text::Text *text = reinterpret_cast<text::Text *>(v_text);
|
895
|
+
bool APIConnection::try_send_text_info_(text::Text *text) {
|
1063
896
|
ListEntitiesTextResponse msg;
|
1064
|
-
msg.key = text->get_object_id_hash();
|
1065
|
-
msg.object_id = text->get_object_id();
|
1066
|
-
msg.name = text->get_name();
|
1067
|
-
msg.icon = text->get_icon();
|
1068
|
-
msg.disabled_by_default = text->is_disabled_by_default();
|
1069
|
-
msg.entity_category = static_cast<enums::EntityCategory>(text->get_entity_category());
|
1070
897
|
msg.mode = static_cast<enums::TextMode>(text->traits.get_mode());
|
1071
|
-
|
1072
898
|
msg.min_length = text->traits.get_min_length();
|
1073
899
|
msg.max_length = text->traits.get_max_length();
|
1074
900
|
msg.pattern = text->traits.get_pattern();
|
1075
|
-
|
1076
|
-
return
|
901
|
+
msg.unique_id = get_default_unique_id("text", text);
|
902
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(text), msg,
|
903
|
+
&APIConnection::send_list_entities_text_response);
|
1077
904
|
}
|
1078
905
|
void APIConnection::text_command(const TextCommandRequest &msg) {
|
1079
906
|
text::Text *text = App.get_text_by_key(msg.key);
|
@@ -1088,47 +915,31 @@ void APIConnection::text_command(const TextCommandRequest &msg) {
|
|
1088
915
|
|
1089
916
|
#ifdef USE_SELECT
|
1090
917
|
bool APIConnection::send_select_state(select::Select *select, std::string state) {
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
if (!APIConnection::try_send_select_state(this, select, std::move(state))) {
|
1095
|
-
this->deferred_message_queue_.defer(select, try_send_select_state);
|
1096
|
-
}
|
1097
|
-
|
1098
|
-
return true;
|
918
|
+
return this->send_state_with_value_(select, &APIConnection::try_send_select_state_,
|
919
|
+
&APIConnection::try_send_select_state_, std::move(state));
|
1099
920
|
}
|
1100
921
|
void APIConnection::send_select_info(select::Select *select) {
|
1101
|
-
|
1102
|
-
|
1103
|
-
}
|
922
|
+
this->send_info_(static_cast<EntityBase *>(select),
|
923
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_select_info_));
|
1104
924
|
}
|
1105
|
-
bool APIConnection::
|
1106
|
-
|
1107
|
-
return APIConnection::try_send_select_state(api, select, select->state);
|
925
|
+
bool APIConnection::try_send_select_state_(select::Select *select) {
|
926
|
+
return this->try_send_select_state_(select, select->state);
|
1108
927
|
}
|
1109
|
-
bool APIConnection::
|
1110
|
-
SelectStateResponse resp
|
1111
|
-
resp.key = select->get_object_id_hash();
|
928
|
+
bool APIConnection::try_send_select_state_(select::Select *select, std::string state) {
|
929
|
+
SelectStateResponse resp;
|
1112
930
|
resp.state = std::move(state);
|
1113
931
|
resp.missing_state = !select->has_state();
|
1114
|
-
|
932
|
+
|
933
|
+
resp.key = select->get_object_id_hash();
|
934
|
+
return this->send_select_state_response(resp);
|
1115
935
|
}
|
1116
|
-
bool APIConnection::
|
1117
|
-
select::Select *select = reinterpret_cast<select::Select *>(v_select);
|
936
|
+
bool APIConnection::try_send_select_info_(select::Select *select) {
|
1118
937
|
ListEntitiesSelectResponse msg;
|
1119
|
-
msg.key = select->get_object_id_hash();
|
1120
|
-
msg.object_id = select->get_object_id();
|
1121
|
-
if (select->has_own_name())
|
1122
|
-
msg.name = select->get_name();
|
1123
|
-
msg.unique_id = get_default_unique_id("select", select);
|
1124
|
-
msg.icon = select->get_icon();
|
1125
|
-
msg.disabled_by_default = select->is_disabled_by_default();
|
1126
|
-
msg.entity_category = static_cast<enums::EntityCategory>(select->get_entity_category());
|
1127
|
-
|
1128
938
|
for (const auto &option : select->traits.get_options())
|
1129
939
|
msg.options.push_back(option);
|
1130
|
-
|
1131
|
-
return
|
940
|
+
msg.unique_id = get_default_unique_id("select", select);
|
941
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(select), msg,
|
942
|
+
&APIConnection::send_list_entities_select_response);
|
1132
943
|
}
|
1133
944
|
void APIConnection::select_command(const SelectCommandRequest &msg) {
|
1134
945
|
select::Select *select = App.get_select_by_key(msg.key);
|
@@ -1142,26 +953,18 @@ void APIConnection::select_command(const SelectCommandRequest &msg) {
|
|
1142
953
|
#endif
|
1143
954
|
|
1144
955
|
#ifdef USE_BUTTON
|
1145
|
-
void APIConnection::send_button_info(button::Button *button) {
|
1146
|
-
|
1147
|
-
|
1148
|
-
}
|
956
|
+
void esphome::api::APIConnection::send_button_info(button::Button *button) {
|
957
|
+
this->send_info_(static_cast<EntityBase *>(button),
|
958
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_button_info_));
|
1149
959
|
}
|
1150
|
-
bool APIConnection::
|
1151
|
-
button::Button *button = reinterpret_cast<button::Button *>(v_button);
|
960
|
+
bool esphome::api::APIConnection::try_send_button_info_(button::Button *button) {
|
1152
961
|
ListEntitiesButtonResponse msg;
|
1153
|
-
msg.key = button->get_object_id_hash();
|
1154
|
-
msg.object_id = button->get_object_id();
|
1155
|
-
if (button->has_own_name())
|
1156
|
-
msg.name = button->get_name();
|
1157
|
-
msg.unique_id = get_default_unique_id("button", button);
|
1158
|
-
msg.icon = button->get_icon();
|
1159
|
-
msg.disabled_by_default = button->is_disabled_by_default();
|
1160
|
-
msg.entity_category = static_cast<enums::EntityCategory>(button->get_entity_category());
|
1161
962
|
msg.device_class = button->get_device_class();
|
1162
|
-
|
963
|
+
msg.unique_id = get_default_unique_id("button", button);
|
964
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(button), msg,
|
965
|
+
&APIConnection::send_list_entities_button_response);
|
1163
966
|
}
|
1164
|
-
void APIConnection::button_command(const ButtonCommandRequest &msg) {
|
967
|
+
void esphome::api::APIConnection::button_command(const ButtonCommandRequest &msg) {
|
1165
968
|
button::Button *button = App.get_button_by_key(msg.key);
|
1166
969
|
if (button == nullptr)
|
1167
970
|
return;
|
@@ -1172,45 +975,31 @@ void APIConnection::button_command(const ButtonCommandRequest &msg) {
|
|
1172
975
|
|
1173
976
|
#ifdef USE_LOCK
|
1174
977
|
bool APIConnection::send_lock_state(lock::Lock *a_lock, lock::LockState state) {
|
1175
|
-
|
1176
|
-
|
1177
|
-
|
1178
|
-
if (!APIConnection::try_send_lock_state(this, a_lock, state)) {
|
1179
|
-
this->deferred_message_queue_.defer(a_lock, try_send_lock_state);
|
1180
|
-
}
|
1181
|
-
|
1182
|
-
return true;
|
978
|
+
return this->send_state_with_value_(a_lock, &APIConnection::try_send_lock_state_,
|
979
|
+
&APIConnection::try_send_lock_state_, state);
|
1183
980
|
}
|
1184
981
|
void APIConnection::send_lock_info(lock::Lock *a_lock) {
|
1185
|
-
|
1186
|
-
|
1187
|
-
}
|
982
|
+
this->send_info_(static_cast<EntityBase *>(a_lock),
|
983
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_lock_info_));
|
1188
984
|
}
|
1189
|
-
bool APIConnection::
|
1190
|
-
|
1191
|
-
return APIConnection::try_send_lock_state(api, a_lock, a_lock->state);
|
985
|
+
bool APIConnection::try_send_lock_state_(lock::Lock *a_lock) {
|
986
|
+
return this->try_send_lock_state_(a_lock, a_lock->state);
|
1192
987
|
}
|
1193
|
-
bool APIConnection::
|
1194
|
-
LockStateResponse resp
|
1195
|
-
resp.key = a_lock->get_object_id_hash();
|
988
|
+
bool APIConnection::try_send_lock_state_(lock::Lock *a_lock, lock::LockState state) {
|
989
|
+
LockStateResponse resp;
|
1196
990
|
resp.state = static_cast<enums::LockState>(state);
|
1197
|
-
|
991
|
+
|
992
|
+
resp.key = a_lock->get_object_id_hash();
|
993
|
+
return this->send_lock_state_response(resp);
|
1198
994
|
}
|
1199
|
-
bool APIConnection::
|
1200
|
-
lock::Lock *a_lock = reinterpret_cast<lock::Lock *>(v_a_lock);
|
995
|
+
bool APIConnection::try_send_lock_info_(lock::Lock *a_lock) {
|
1201
996
|
ListEntitiesLockResponse msg;
|
1202
|
-
msg.key = a_lock->get_object_id_hash();
|
1203
|
-
msg.object_id = a_lock->get_object_id();
|
1204
|
-
if (a_lock->has_own_name())
|
1205
|
-
msg.name = a_lock->get_name();
|
1206
|
-
msg.unique_id = get_default_unique_id("lock", a_lock);
|
1207
|
-
msg.icon = a_lock->get_icon();
|
1208
997
|
msg.assumed_state = a_lock->traits.get_assumed_state();
|
1209
|
-
msg.disabled_by_default = a_lock->is_disabled_by_default();
|
1210
|
-
msg.entity_category = static_cast<enums::EntityCategory>(a_lock->get_entity_category());
|
1211
998
|
msg.supports_open = a_lock->traits.get_supports_open();
|
1212
999
|
msg.requires_code = a_lock->traits.get_requires_code();
|
1213
|
-
|
1000
|
+
msg.unique_id = get_default_unique_id("lock", a_lock);
|
1001
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(a_lock), msg,
|
1002
|
+
&APIConnection::send_list_entities_lock_response);
|
1214
1003
|
}
|
1215
1004
|
void APIConnection::lock_command(const LockCommandRequest &msg) {
|
1216
1005
|
lock::Lock *a_lock = App.get_lock_by_key(msg.key);
|
@@ -1233,45 +1022,31 @@ void APIConnection::lock_command(const LockCommandRequest &msg) {
|
|
1233
1022
|
|
1234
1023
|
#ifdef USE_VALVE
|
1235
1024
|
bool APIConnection::send_valve_state(valve::Valve *valve) {
|
1236
|
-
|
1237
|
-
|
1238
|
-
|
1239
|
-
if (!APIConnection::try_send_valve_state(this, valve)) {
|
1240
|
-
this->deferred_message_queue_.defer(valve, try_send_valve_state);
|
1241
|
-
}
|
1242
|
-
|
1243
|
-
return true;
|
1025
|
+
return this->send_state_(static_cast<EntityBase *>(valve),
|
1026
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_valve_state_));
|
1244
1027
|
}
|
1245
1028
|
void APIConnection::send_valve_info(valve::Valve *valve) {
|
1246
|
-
|
1247
|
-
|
1248
|
-
}
|
1029
|
+
this->send_info_(static_cast<EntityBase *>(valve),
|
1030
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_valve_info_));
|
1249
1031
|
}
|
1250
|
-
bool APIConnection::
|
1251
|
-
|
1252
|
-
ValveStateResponse resp{};
|
1253
|
-
resp.key = valve->get_object_id_hash();
|
1032
|
+
bool APIConnection::try_send_valve_state_(valve::Valve *valve) {
|
1033
|
+
ValveStateResponse resp;
|
1254
1034
|
resp.position = valve->position;
|
1255
1035
|
resp.current_operation = static_cast<enums::ValveOperation>(valve->current_operation);
|
1256
|
-
|
1036
|
+
|
1037
|
+
resp.key = valve->get_object_id_hash();
|
1038
|
+
return this->send_valve_state_response(resp);
|
1257
1039
|
}
|
1258
|
-
bool APIConnection::
|
1259
|
-
valve::Valve *valve = reinterpret_cast<valve::Valve *>(v_valve);
|
1260
|
-
auto traits = valve->get_traits();
|
1040
|
+
bool APIConnection::try_send_valve_info_(valve::Valve *valve) {
|
1261
1041
|
ListEntitiesValveResponse msg;
|
1262
|
-
|
1263
|
-
msg.object_id = valve->get_object_id();
|
1264
|
-
if (valve->has_own_name())
|
1265
|
-
msg.name = valve->get_name();
|
1266
|
-
msg.unique_id = get_default_unique_id("valve", valve);
|
1267
|
-
msg.icon = valve->get_icon();
|
1268
|
-
msg.disabled_by_default = valve->is_disabled_by_default();
|
1269
|
-
msg.entity_category = static_cast<enums::EntityCategory>(valve->get_entity_category());
|
1042
|
+
auto traits = valve->get_traits();
|
1270
1043
|
msg.device_class = valve->get_device_class();
|
1271
1044
|
msg.assumed_state = traits.get_is_assumed_state();
|
1272
1045
|
msg.supports_position = traits.get_supports_position();
|
1273
1046
|
msg.supports_stop = traits.get_supports_stop();
|
1274
|
-
|
1047
|
+
msg.unique_id = get_default_unique_id("valve", valve);
|
1048
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(valve), msg,
|
1049
|
+
&APIConnection::send_list_entities_valve_response);
|
1275
1050
|
}
|
1276
1051
|
void APIConnection::valve_command(const ValveCommandRequest &msg) {
|
1277
1052
|
valve::Valve *valve = App.get_valve_by_key(msg.key);
|
@@ -1289,48 +1064,29 @@ void APIConnection::valve_command(const ValveCommandRequest &msg) {
|
|
1289
1064
|
|
1290
1065
|
#ifdef USE_MEDIA_PLAYER
|
1291
1066
|
bool APIConnection::send_media_player_state(media_player::MediaPlayer *media_player) {
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
if (!APIConnection::try_send_media_player_state(this, media_player)) {
|
1296
|
-
this->deferred_message_queue_.defer(media_player, try_send_media_player_state);
|
1297
|
-
}
|
1298
|
-
|
1299
|
-
return true;
|
1067
|
+
return this->send_state_(static_cast<EntityBase *>(media_player),
|
1068
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_media_player_state_));
|
1300
1069
|
}
|
1301
1070
|
void APIConnection::send_media_player_info(media_player::MediaPlayer *media_player) {
|
1302
|
-
|
1303
|
-
|
1304
|
-
}
|
1071
|
+
this->send_info_(static_cast<EntityBase *>(media_player),
|
1072
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_media_player_info_));
|
1305
1073
|
}
|
1306
|
-
bool APIConnection::
|
1307
|
-
|
1308
|
-
MediaPlayerStateResponse resp{};
|
1309
|
-
resp.key = media_player->get_object_id_hash();
|
1310
|
-
|
1074
|
+
bool APIConnection::try_send_media_player_state_(media_player::MediaPlayer *media_player) {
|
1075
|
+
MediaPlayerStateResponse resp;
|
1311
1076
|
media_player::MediaPlayerState report_state = media_player->state == media_player::MEDIA_PLAYER_STATE_ANNOUNCING
|
1312
1077
|
? media_player::MEDIA_PLAYER_STATE_PLAYING
|
1313
1078
|
: media_player->state;
|
1314
1079
|
resp.state = static_cast<enums::MediaPlayerState>(report_state);
|
1315
1080
|
resp.volume = media_player->volume;
|
1316
1081
|
resp.muted = media_player->is_muted();
|
1317
|
-
|
1082
|
+
|
1083
|
+
resp.key = media_player->get_object_id_hash();
|
1084
|
+
return this->send_media_player_state_response(resp);
|
1318
1085
|
}
|
1319
|
-
bool APIConnection::
|
1320
|
-
media_player::MediaPlayer *media_player = reinterpret_cast<media_player::MediaPlayer *>(v_media_player);
|
1086
|
+
bool APIConnection::try_send_media_player_info_(media_player::MediaPlayer *media_player) {
|
1321
1087
|
ListEntitiesMediaPlayerResponse msg;
|
1322
|
-
msg.key = media_player->get_object_id_hash();
|
1323
|
-
msg.object_id = media_player->get_object_id();
|
1324
|
-
if (media_player->has_own_name())
|
1325
|
-
msg.name = media_player->get_name();
|
1326
|
-
msg.unique_id = get_default_unique_id("media_player", media_player);
|
1327
|
-
msg.icon = media_player->get_icon();
|
1328
|
-
msg.disabled_by_default = media_player->is_disabled_by_default();
|
1329
|
-
msg.entity_category = static_cast<enums::EntityCategory>(media_player->get_entity_category());
|
1330
|
-
|
1331
1088
|
auto traits = media_player->get_traits();
|
1332
1089
|
msg.supports_pause = traits.get_supports_pause();
|
1333
|
-
|
1334
1090
|
for (auto &supported_format : traits.get_supported_formats()) {
|
1335
1091
|
MediaPlayerSupportedFormat media_format;
|
1336
1092
|
media_format.format = supported_format.format;
|
@@ -1340,8 +1096,9 @@ bool APIConnection::try_send_media_player_info(APIConnection *api, void *v_media
|
|
1340
1096
|
media_format.sample_bytes = supported_format.sample_bytes;
|
1341
1097
|
msg.supported_formats.push_back(media_format);
|
1342
1098
|
}
|
1343
|
-
|
1344
|
-
return
|
1099
|
+
msg.unique_id = get_default_unique_id("media_player", media_player);
|
1100
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(media_player), msg,
|
1101
|
+
&APIConnection::send_list_entities_media_player_response);
|
1345
1102
|
}
|
1346
1103
|
void APIConnection::media_player_command(const MediaPlayerCommandRequest &msg) {
|
1347
1104
|
media_player::MediaPlayer *media_player = App.get_media_player_by_key(msg.key);
|
@@ -1376,22 +1133,14 @@ void APIConnection::set_camera_state(std::shared_ptr<esp32_camera::CameraImage>
|
|
1376
1133
|
this->image_reader_.set_image(std::move(image));
|
1377
1134
|
}
|
1378
1135
|
void APIConnection::send_camera_info(esp32_camera::ESP32Camera *camera) {
|
1379
|
-
|
1380
|
-
|
1381
|
-
}
|
1136
|
+
this->send_info_(static_cast<EntityBase *>(camera),
|
1137
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_camera_info_));
|
1382
1138
|
}
|
1383
|
-
bool APIConnection::
|
1384
|
-
esp32_camera::ESP32Camera *camera = reinterpret_cast<esp32_camera::ESP32Camera *>(v_camera);
|
1139
|
+
bool APIConnection::try_send_camera_info_(esp32_camera::ESP32Camera *camera) {
|
1385
1140
|
ListEntitiesCameraResponse msg;
|
1386
|
-
msg.key = camera->get_object_id_hash();
|
1387
|
-
msg.object_id = camera->get_object_id();
|
1388
|
-
if (camera->has_own_name())
|
1389
|
-
msg.name = camera->get_name();
|
1390
1141
|
msg.unique_id = get_default_unique_id("camera", camera);
|
1391
|
-
|
1392
|
-
|
1393
|
-
msg.entity_category = static_cast<enums::EntityCategory>(camera->get_entity_category());
|
1394
|
-
return api->send_list_entities_camera_response(msg);
|
1142
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(camera), msg,
|
1143
|
+
&APIConnection::send_list_entities_camera_response);
|
1395
1144
|
}
|
1396
1145
|
void APIConnection::camera_image(const CameraImageRequest &msg) {
|
1397
1146
|
if (esp32_camera::global_esp32_camera == nullptr)
|
@@ -1468,6 +1217,11 @@ BluetoothConnectionsFreeResponse APIConnection::subscribe_bluetooth_connections_
|
|
1468
1217
|
resp.limit = bluetooth_proxy::global_bluetooth_proxy->get_bluetooth_connections_limit();
|
1469
1218
|
return resp;
|
1470
1219
|
}
|
1220
|
+
|
1221
|
+
void APIConnection::bluetooth_scanner_set_mode(const BluetoothScannerSetModeRequest &msg) {
|
1222
|
+
bluetooth_proxy::global_bluetooth_proxy->bluetooth_scanner_set_mode(
|
1223
|
+
msg.mode == enums::BluetoothScannerMode::BLUETOOTH_SCANNER_MODE_ACTIVE);
|
1224
|
+
}
|
1471
1225
|
#endif
|
1472
1226
|
|
1473
1227
|
#ifdef USE_VOICE_ASSISTANT
|
@@ -1575,43 +1329,28 @@ void APIConnection::voice_assistant_set_configuration(const VoiceAssistantSetCon
|
|
1575
1329
|
|
1576
1330
|
#ifdef USE_ALARM_CONTROL_PANEL
|
1577
1331
|
bool APIConnection::send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
if (!APIConnection::try_send_alarm_control_panel_state(this, a_alarm_control_panel)) {
|
1582
|
-
this->deferred_message_queue_.defer(a_alarm_control_panel, try_send_alarm_control_panel_state);
|
1583
|
-
}
|
1584
|
-
|
1585
|
-
return true;
|
1332
|
+
return this->send_state_(static_cast<EntityBase *>(a_alarm_control_panel),
|
1333
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_alarm_control_panel_state_));
|
1586
1334
|
}
|
1587
1335
|
void APIConnection::send_alarm_control_panel_info(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
1588
|
-
|
1589
|
-
|
1590
|
-
}
|
1336
|
+
this->send_info_(static_cast<EntityBase *>(a_alarm_control_panel),
|
1337
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_alarm_control_panel_info_));
|
1591
1338
|
}
|
1592
|
-
bool APIConnection::
|
1593
|
-
|
1594
|
-
reinterpret_cast<alarm_control_panel::AlarmControlPanel *>(v_a_alarm_control_panel);
|
1595
|
-
AlarmControlPanelStateResponse resp{};
|
1596
|
-
resp.key = a_alarm_control_panel->get_object_id_hash();
|
1339
|
+
bool APIConnection::try_send_alarm_control_panel_state_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
1340
|
+
AlarmControlPanelStateResponse resp;
|
1597
1341
|
resp.state = static_cast<enums::AlarmControlPanelState>(a_alarm_control_panel->get_state());
|
1598
|
-
|
1342
|
+
|
1343
|
+
resp.key = a_alarm_control_panel->get_object_id_hash();
|
1344
|
+
return this->send_alarm_control_panel_state_response(resp);
|
1599
1345
|
}
|
1600
|
-
bool APIConnection::
|
1601
|
-
alarm_control_panel::AlarmControlPanel *a_alarm_control_panel =
|
1602
|
-
reinterpret_cast<alarm_control_panel::AlarmControlPanel *>(v_a_alarm_control_panel);
|
1346
|
+
bool APIConnection::try_send_alarm_control_panel_info_(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
1603
1347
|
ListEntitiesAlarmControlPanelResponse msg;
|
1604
|
-
msg.key = a_alarm_control_panel->get_object_id_hash();
|
1605
|
-
msg.object_id = a_alarm_control_panel->get_object_id();
|
1606
|
-
msg.name = a_alarm_control_panel->get_name();
|
1607
|
-
msg.unique_id = get_default_unique_id("alarm_control_panel", a_alarm_control_panel);
|
1608
|
-
msg.icon = a_alarm_control_panel->get_icon();
|
1609
|
-
msg.disabled_by_default = a_alarm_control_panel->is_disabled_by_default();
|
1610
|
-
msg.entity_category = static_cast<enums::EntityCategory>(a_alarm_control_panel->get_entity_category());
|
1611
1348
|
msg.supported_features = a_alarm_control_panel->get_supported_features();
|
1612
1349
|
msg.requires_code = a_alarm_control_panel->get_requires_code();
|
1613
1350
|
msg.requires_code_to_arm = a_alarm_control_panel->get_requires_code_to_arm();
|
1614
|
-
|
1351
|
+
msg.unique_id = get_default_unique_id("alarm_control_panel", a_alarm_control_panel);
|
1352
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(a_alarm_control_panel), msg,
|
1353
|
+
&APIConnection::send_list_entities_alarm_control_panel_response);
|
1615
1354
|
}
|
1616
1355
|
void APIConnection::alarm_control_panel_command(const AlarmControlPanelCommandRequest &msg) {
|
1617
1356
|
alarm_control_panel::AlarmControlPanel *a_alarm_control_panel = App.get_alarm_control_panel_by_key(msg.key);
|
@@ -1649,63 +1388,45 @@ void APIConnection::alarm_control_panel_command(const AlarmControlPanelCommandRe
|
|
1649
1388
|
|
1650
1389
|
#ifdef USE_EVENT
|
1651
1390
|
void APIConnection::send_event(event::Event *event, std::string event_type) {
|
1652
|
-
|
1653
|
-
|
1654
|
-
}
|
1391
|
+
this->send_state_with_value_(event, &APIConnection::try_send_event_, &APIConnection::try_send_event_,
|
1392
|
+
std::move(event_type));
|
1655
1393
|
}
|
1656
1394
|
void APIConnection::send_event_info(event::Event *event) {
|
1657
|
-
|
1658
|
-
|
1659
|
-
}
|
1395
|
+
this->send_info_(static_cast<EntityBase *>(event),
|
1396
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_event_info_));
|
1660
1397
|
}
|
1661
|
-
bool APIConnection::
|
1662
|
-
event
|
1663
|
-
return APIConnection::try_send_event(api, event, *(event->last_event_type));
|
1398
|
+
bool APIConnection::try_send_event_(event::Event *event) {
|
1399
|
+
return this->try_send_event_(event, *(event->last_event_type));
|
1664
1400
|
}
|
1665
|
-
bool APIConnection::
|
1666
|
-
EventResponse resp
|
1667
|
-
resp.key = event->get_object_id_hash();
|
1401
|
+
bool APIConnection::try_send_event_(event::Event *event, std::string event_type) {
|
1402
|
+
EventResponse resp;
|
1668
1403
|
resp.event_type = std::move(event_type);
|
1669
|
-
|
1404
|
+
|
1405
|
+
resp.key = event->get_object_id_hash();
|
1406
|
+
return this->send_event_response(resp);
|
1670
1407
|
}
|
1671
|
-
bool APIConnection::
|
1672
|
-
event::Event *event = reinterpret_cast<event::Event *>(v_event);
|
1408
|
+
bool APIConnection::try_send_event_info_(event::Event *event) {
|
1673
1409
|
ListEntitiesEventResponse msg;
|
1674
|
-
msg.key = event->get_object_id_hash();
|
1675
|
-
msg.object_id = event->get_object_id();
|
1676
|
-
if (event->has_own_name())
|
1677
|
-
msg.name = event->get_name();
|
1678
|
-
msg.unique_id = get_default_unique_id("event", event);
|
1679
|
-
msg.icon = event->get_icon();
|
1680
|
-
msg.disabled_by_default = event->is_disabled_by_default();
|
1681
|
-
msg.entity_category = static_cast<enums::EntityCategory>(event->get_entity_category());
|
1682
1410
|
msg.device_class = event->get_device_class();
|
1683
1411
|
for (const auto &event_type : event->get_event_types())
|
1684
1412
|
msg.event_types.push_back(event_type);
|
1685
|
-
|
1413
|
+
msg.unique_id = get_default_unique_id("event", event);
|
1414
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(event), msg,
|
1415
|
+
&APIConnection::send_list_entities_event_response);
|
1686
1416
|
}
|
1687
1417
|
#endif
|
1688
1418
|
|
1689
1419
|
#ifdef USE_UPDATE
|
1690
1420
|
bool APIConnection::send_update_state(update::UpdateEntity *update) {
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
if (!APIConnection::try_send_update_state(this, update)) {
|
1695
|
-
this->deferred_message_queue_.defer(update, try_send_update_state);
|
1696
|
-
}
|
1697
|
-
|
1698
|
-
return true;
|
1421
|
+
return this->send_state_(static_cast<EntityBase *>(update),
|
1422
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_update_state_));
|
1699
1423
|
}
|
1700
1424
|
void APIConnection::send_update_info(update::UpdateEntity *update) {
|
1701
|
-
|
1702
|
-
|
1703
|
-
}
|
1425
|
+
this->send_info_(static_cast<EntityBase *>(update),
|
1426
|
+
reinterpret_cast<send_message_t>(&APIConnection::try_send_update_info_));
|
1704
1427
|
}
|
1705
|
-
bool APIConnection::
|
1706
|
-
|
1707
|
-
UpdateStateResponse resp{};
|
1708
|
-
resp.key = update->get_object_id_hash();
|
1428
|
+
bool APIConnection::try_send_update_state_(update::UpdateEntity *update) {
|
1429
|
+
UpdateStateResponse resp;
|
1709
1430
|
resp.missing_state = !update->has_state();
|
1710
1431
|
if (update->has_state()) {
|
1711
1432
|
resp.in_progress = update->state == update::UpdateState::UPDATE_STATE_INSTALLING;
|
@@ -1720,21 +1441,15 @@ bool APIConnection::try_send_update_state(APIConnection *api, void *v_update) {
|
|
1720
1441
|
resp.release_url = update->update_info.release_url;
|
1721
1442
|
}
|
1722
1443
|
|
1723
|
-
|
1444
|
+
resp.key = update->get_object_id_hash();
|
1445
|
+
return this->send_update_state_response(resp);
|
1724
1446
|
}
|
1725
|
-
bool APIConnection::
|
1726
|
-
update::UpdateEntity *update = reinterpret_cast<update::UpdateEntity *>(v_update);
|
1447
|
+
bool APIConnection::try_send_update_info_(update::UpdateEntity *update) {
|
1727
1448
|
ListEntitiesUpdateResponse msg;
|
1728
|
-
msg.key = update->get_object_id_hash();
|
1729
|
-
msg.object_id = update->get_object_id();
|
1730
|
-
if (update->has_own_name())
|
1731
|
-
msg.name = update->get_name();
|
1732
|
-
msg.unique_id = get_default_unique_id("update", update);
|
1733
|
-
msg.icon = update->get_icon();
|
1734
|
-
msg.disabled_by_default = update->is_disabled_by_default();
|
1735
|
-
msg.entity_category = static_cast<enums::EntityCategory>(update->get_entity_category());
|
1736
1449
|
msg.device_class = update->get_device_class();
|
1737
|
-
|
1450
|
+
msg.unique_id = get_default_unique_id("update", update);
|
1451
|
+
return this->try_send_entity_info_(static_cast<EntityBase *>(update), msg,
|
1452
|
+
&APIConnection::send_list_entities_update_response);
|
1738
1453
|
}
|
1739
1454
|
void APIConnection::update_command(const UpdateCommandRequest &msg) {
|
1740
1455
|
update::UpdateEntity *update = App.get_update_by_key(msg.key);
|
@@ -1762,12 +1477,25 @@ bool APIConnection::try_send_log_message(int level, const char *tag, const char
|
|
1762
1477
|
if (this->log_subscription_ < level)
|
1763
1478
|
return false;
|
1764
1479
|
|
1765
|
-
//
|
1766
|
-
|
1767
|
-
|
1768
|
-
|
1769
|
-
//
|
1770
|
-
|
1480
|
+
// Pre-calculate message size to avoid reallocations
|
1481
|
+
const size_t line_length = strlen(line);
|
1482
|
+
uint32_t msg_size = 0;
|
1483
|
+
|
1484
|
+
// Add size for level field (field ID 1, varint type)
|
1485
|
+
// 1 byte for field tag + size of the level varint
|
1486
|
+
msg_size += 1 + api::ProtoSize::varint(static_cast<uint32_t>(level));
|
1487
|
+
|
1488
|
+
// Add size for string field (field ID 3, string type)
|
1489
|
+
// 1 byte for field tag + size of length varint + string length
|
1490
|
+
msg_size += 1 + api::ProtoSize::varint(static_cast<uint32_t>(line_length)) + line_length;
|
1491
|
+
|
1492
|
+
// Create a pre-sized buffer
|
1493
|
+
auto buffer = this->create_buffer(msg_size);
|
1494
|
+
|
1495
|
+
// Encode the message (SubscribeLogsResponse)
|
1496
|
+
buffer.encode_uint32(1, static_cast<uint32_t>(level)); // LogLevel level = 1
|
1497
|
+
buffer.encode_string(3, line, line_length); // string message = 3
|
1498
|
+
|
1771
1499
|
// SubscribeLogsResponse - 29
|
1772
1500
|
return this->send_buffer(buffer, 29);
|
1773
1501
|
}
|
@@ -1848,6 +1576,9 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
|
|
1848
1576
|
#ifdef USE_VOICE_ASSISTANT
|
1849
1577
|
resp.legacy_voice_assistant_version = voice_assistant::global_voice_assistant->get_legacy_version();
|
1850
1578
|
resp.voice_assistant_feature_flags = voice_assistant::global_voice_assistant->get_feature_flags();
|
1579
|
+
#endif
|
1580
|
+
#ifdef USE_API_NOISE
|
1581
|
+
resp.api_encryption_supported = true;
|
1851
1582
|
#endif
|
1852
1583
|
return resp;
|
1853
1584
|
}
|
@@ -1869,32 +1600,55 @@ void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
|
|
1869
1600
|
ESP_LOGV(TAG, "Could not find matching service!");
|
1870
1601
|
}
|
1871
1602
|
}
|
1603
|
+
#ifdef USE_API_NOISE
|
1604
|
+
NoiseEncryptionSetKeyResponse APIConnection::noise_encryption_set_key(const NoiseEncryptionSetKeyRequest &msg) {
|
1605
|
+
psk_t psk{};
|
1606
|
+
NoiseEncryptionSetKeyResponse resp;
|
1607
|
+
if (base64_decode(msg.key, psk.data(), msg.key.size()) != psk.size()) {
|
1608
|
+
ESP_LOGW(TAG, "Invalid encryption key length");
|
1609
|
+
resp.success = false;
|
1610
|
+
return resp;
|
1611
|
+
}
|
1612
|
+
|
1613
|
+
if (!this->parent_->save_noise_psk(psk, true)) {
|
1614
|
+
ESP_LOGW(TAG, "Failed to save encryption key");
|
1615
|
+
resp.success = false;
|
1616
|
+
return resp;
|
1617
|
+
}
|
1618
|
+
|
1619
|
+
resp.success = true;
|
1620
|
+
return resp;
|
1621
|
+
}
|
1622
|
+
#endif
|
1872
1623
|
void APIConnection::subscribe_home_assistant_states(const SubscribeHomeAssistantStatesRequest &msg) {
|
1873
1624
|
state_subs_at_ = 0;
|
1874
1625
|
}
|
1875
|
-
bool APIConnection::
|
1626
|
+
bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
|
1876
1627
|
if (this->remove_)
|
1877
1628
|
return false;
|
1878
|
-
if (
|
1879
|
-
|
1880
|
-
|
1881
|
-
|
1882
|
-
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
|
1891
|
-
|
1892
|
-
|
1893
|
-
|
1894
|
-
|
1629
|
+
if (this->helper_->can_write_without_blocking())
|
1630
|
+
return true;
|
1631
|
+
delay(0);
|
1632
|
+
APIError err = this->helper_->loop();
|
1633
|
+
if (err != APIError::OK) {
|
1634
|
+
on_fatal_error();
|
1635
|
+
ESP_LOGW(TAG, "%s: Socket operation failed: %s errno=%d", this->client_combined_info_.c_str(),
|
1636
|
+
api_error_to_str(err), errno);
|
1637
|
+
return false;
|
1638
|
+
}
|
1639
|
+
if (this->helper_->can_write_without_blocking())
|
1640
|
+
return true;
|
1641
|
+
if (log_out_of_space) {
|
1642
|
+
ESP_LOGV(TAG, "Cannot send message because of TCP buffer space");
|
1643
|
+
}
|
1644
|
+
return false;
|
1645
|
+
}
|
1646
|
+
bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint32_t message_type) {
|
1647
|
+
if (!this->try_to_clear_buffer(message_type != 29)) { // SubscribeLogsResponse
|
1648
|
+
return false;
|
1895
1649
|
}
|
1896
1650
|
|
1897
|
-
APIError err = this->helper_->
|
1651
|
+
APIError err = this->helper_->write_protobuf_packet(message_type, buffer);
|
1898
1652
|
if (err == APIError::WOULD_BLOCK)
|
1899
1653
|
return false;
|
1900
1654
|
if (err != APIError::OK) {
|