esphome 2025.7.0b1__py3-none-any.whl → 2025.7.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of esphome might be problematic. Click here for more details.
- esphome/components/api/__init__.py +19 -5
- esphome/components/api/api_connection.cpp +53 -175
- esphome/components/api/api_connection.h +28 -25
- esphome/components/api/api_frame_helper.cpp +2 -3
- esphome/components/api/api_frame_helper.h +7 -9
- esphome/components/api/api_pb2.cpp +1862 -5133
- esphome/components/api/api_pb2.h +291 -533
- esphome/components/api/api_pb2_dump.cpp +99 -0
- esphome/components/api/api_pb2_service.cpp +4 -0
- esphome/components/api/api_pb2_service.h +6 -0
- esphome/components/api/api_server.cpp +2 -9
- esphome/components/api/api_server.h +7 -33
- esphome/components/api/custom_api_device.h +8 -0
- esphome/components/api/list_entities.cpp +2 -0
- esphome/components/api/list_entities.h +3 -1
- esphome/components/api/proto.h +506 -23
- esphome/components/api/user_services.h +2 -0
- esphome/components/debug/debug_esp32.cpp +2 -0
- esphome/components/esp32/__init__.py +1 -0
- esphome/components/esp32_camera/__init__.py +1 -1
- esphome/components/esp32_touch/esp32_touch_v1.cpp +12 -10
- esphome/components/esp8266/__init__.py +1 -0
- esphome/components/host/__init__.py +1 -0
- esphome/components/ld2410/ld2410.cpp +12 -28
- esphome/components/libretiny/__init__.py +1 -0
- esphome/components/mqtt/mqtt_backend_esp32.cpp +6 -2
- esphome/components/packet_transport/packet_transport.cpp +3 -0
- esphome/components/rp2040/__init__.py +1 -0
- esphome/components/sx126x/__init__.py +3 -3
- esphome/components/sx127x/__init__.py +2 -2
- esphome/components/usb_host/usb_host_client.cpp +10 -10
- esphome/components/usb_uart/cp210x.cpp +1 -1
- esphome/components/usb_uart/usb_uart.cpp +41 -44
- esphome/components/usb_uart/usb_uart.h +4 -3
- esphome/const.py +1 -1
- esphome/core/component_iterator.cpp +4 -2
- esphome/core/component_iterator.h +3 -3
- esphome/core/defines.h +1 -1
- esphome/core/entity_helpers.py +6 -0
- esphome/core/scheduler.cpp +9 -12
- esphome/core/scheduler.h +0 -3
- esphome/wizard.py +1 -1
- {esphome-2025.7.0b1.dist-info → esphome-2025.7.0b2.dist-info}/METADATA +2 -2
- {esphome-2025.7.0b1.dist-info → esphome-2025.7.0b2.dist-info}/RECORD +48 -49
- esphome/components/api/api_pb2_size.h +0 -359
- {esphome-2025.7.0b1.dist-info → esphome-2025.7.0b2.dist-info}/WHEEL +0 -0
- {esphome-2025.7.0b1.dist-info → esphome-2025.7.0b2.dist-info}/entry_points.txt +0 -0
- {esphome-2025.7.0b1.dist-info → esphome-2025.7.0b2.dist-info}/licenses/LICENSE +0 -0
- {esphome-2025.7.0b1.dist-info → esphome-2025.7.0b2.dist-info}/top_level.txt +0 -0
|
@@ -24,8 +24,9 @@ from esphome.const import (
|
|
|
24
24
|
CONF_TRIGGER_ID,
|
|
25
25
|
CONF_VARIABLES,
|
|
26
26
|
)
|
|
27
|
-
from esphome.core import coroutine_with_priority
|
|
27
|
+
from esphome.core import CORE, coroutine_with_priority
|
|
28
28
|
|
|
29
|
+
DOMAIN = "api"
|
|
29
30
|
DEPENDENCIES = ["network"]
|
|
30
31
|
AUTO_LOAD = ["socket"]
|
|
31
32
|
CODEOWNERS = ["@OttoWinter"]
|
|
@@ -51,6 +52,7 @@ SERVICE_ARG_NATIVE_TYPES = {
|
|
|
51
52
|
}
|
|
52
53
|
CONF_ENCRYPTION = "encryption"
|
|
53
54
|
CONF_BATCH_DELAY = "batch_delay"
|
|
55
|
+
CONF_CUSTOM_SERVICES = "custom_services"
|
|
54
56
|
|
|
55
57
|
|
|
56
58
|
def validate_encryption_key(value):
|
|
@@ -115,6 +117,7 @@ CONFIG_SCHEMA = cv.All(
|
|
|
115
117
|
cv.positive_time_period_milliseconds,
|
|
116
118
|
cv.Range(max=cv.TimePeriod(milliseconds=65535)),
|
|
117
119
|
),
|
|
120
|
+
cv.Optional(CONF_CUSTOM_SERVICES, default=False): cv.boolean,
|
|
118
121
|
cv.Optional(CONF_ON_CLIENT_CONNECTED): automation.validate_automation(
|
|
119
122
|
single=True
|
|
120
123
|
),
|
|
@@ -139,8 +142,11 @@ async def to_code(config):
|
|
|
139
142
|
cg.add(var.set_reboot_timeout(config[CONF_REBOOT_TIMEOUT]))
|
|
140
143
|
cg.add(var.set_batch_delay(config[CONF_BATCH_DELAY]))
|
|
141
144
|
|
|
145
|
+
# Set USE_API_SERVICES if any services are enabled
|
|
146
|
+
if config.get(CONF_ACTIONS) or config[CONF_CUSTOM_SERVICES]:
|
|
147
|
+
cg.add_define("USE_API_SERVICES")
|
|
148
|
+
|
|
142
149
|
if actions := config.get(CONF_ACTIONS, []):
|
|
143
|
-
cg.add_define("USE_API_YAML_SERVICES")
|
|
144
150
|
for conf in actions:
|
|
145
151
|
template_args = []
|
|
146
152
|
func_args = []
|
|
@@ -317,7 +323,10 @@ async def api_connected_to_code(config, condition_id, template_arg, args):
|
|
|
317
323
|
|
|
318
324
|
|
|
319
325
|
def FILTER_SOURCE_FILES() -> list[str]:
|
|
320
|
-
"""Filter out api_pb2_dump.cpp when proto message dumping is not enabled
|
|
326
|
+
"""Filter out api_pb2_dump.cpp when proto message dumping is not enabled
|
|
327
|
+
and user_services.cpp when no services are defined."""
|
|
328
|
+
files_to_filter = []
|
|
329
|
+
|
|
321
330
|
# api_pb2_dump.cpp is only needed when HAS_PROTO_MESSAGE_DUMP is defined
|
|
322
331
|
# This is a particularly large file that still needs to be opened and read
|
|
323
332
|
# all the way to the end even when ifdef'd out
|
|
@@ -325,6 +334,11 @@ def FILTER_SOURCE_FILES() -> list[str]:
|
|
|
325
334
|
# HAS_PROTO_MESSAGE_DUMP is defined when ESPHOME_LOG_HAS_VERY_VERBOSE is set,
|
|
326
335
|
# which happens when the logger level is VERY_VERBOSE
|
|
327
336
|
if get_logger_level() != "VERY_VERBOSE":
|
|
328
|
-
|
|
337
|
+
files_to_filter.append("api_pb2_dump.cpp")
|
|
338
|
+
|
|
339
|
+
# user_services.cpp is only needed when services are defined
|
|
340
|
+
config = CORE.config.get(DOMAIN, {})
|
|
341
|
+
if config and not config.get(CONF_ACTIONS) and not config[CONF_CUSTOM_SERVICES]:
|
|
342
|
+
files_to_filter.append("user_services.cpp")
|
|
329
343
|
|
|
330
|
-
return
|
|
344
|
+
return files_to_filter
|
|
@@ -193,14 +193,15 @@ void APIConnection::loop() {
|
|
|
193
193
|
// If we can't send the ping request directly (tx_buffer full),
|
|
194
194
|
// schedule it at the front of the batch so it will be sent with priority
|
|
195
195
|
ESP_LOGW(TAG, "Buffer full, ping queued");
|
|
196
|
-
this->schedule_message_front_(nullptr, &APIConnection::try_send_ping_request, PingRequest::MESSAGE_TYPE
|
|
196
|
+
this->schedule_message_front_(nullptr, &APIConnection::try_send_ping_request, PingRequest::MESSAGE_TYPE,
|
|
197
|
+
PingRequest::ESTIMATED_SIZE);
|
|
197
198
|
this->flags_.sent_ping = true; // Mark as sent to avoid scheduling multiple pings
|
|
198
199
|
}
|
|
199
200
|
}
|
|
200
201
|
|
|
201
202
|
#ifdef USE_CAMERA
|
|
202
203
|
if (this->image_reader_ && this->image_reader_->available() && this->helper_->can_write_without_blocking()) {
|
|
203
|
-
uint32_t to_send = std::min((size_t)
|
|
204
|
+
uint32_t to_send = std::min((size_t) MAX_BATCH_PACKET_SIZE, this->image_reader_->available());
|
|
204
205
|
bool done = this->image_reader_->available() == to_send;
|
|
205
206
|
uint32_t msg_size = 0;
|
|
206
207
|
ProtoSize::add_fixed_field<4>(msg_size, 1, true);
|
|
@@ -265,7 +266,7 @@ void APIConnection::on_disconnect_response(const DisconnectResponse &value) {
|
|
|
265
266
|
|
|
266
267
|
// Encodes a message to the buffer and returns the total number of bytes used,
|
|
267
268
|
// including header and footer overhead. Returns 0 if the message doesn't fit.
|
|
268
|
-
uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg,
|
|
269
|
+
uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg, uint8_t message_type, APIConnection *conn,
|
|
269
270
|
uint32_t remaining_size, bool is_single) {
|
|
270
271
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
271
272
|
// If in log-only mode, just log and return
|
|
@@ -316,7 +317,7 @@ uint16_t APIConnection::encode_message_to_buffer(ProtoMessage &msg, uint16_t mes
|
|
|
316
317
|
#ifdef USE_BINARY_SENSOR
|
|
317
318
|
bool APIConnection::send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor) {
|
|
318
319
|
return this->send_message_smart_(binary_sensor, &APIConnection::try_send_binary_sensor_state,
|
|
319
|
-
BinarySensorStateResponse::MESSAGE_TYPE);
|
|
320
|
+
BinarySensorStateResponse::MESSAGE_TYPE, BinarySensorStateResponse::ESTIMATED_SIZE);
|
|
320
321
|
}
|
|
321
322
|
|
|
322
323
|
uint16_t APIConnection::try_send_binary_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -343,7 +344,8 @@ uint16_t APIConnection::try_send_binary_sensor_info(EntityBase *entity, APIConne
|
|
|
343
344
|
|
|
344
345
|
#ifdef USE_COVER
|
|
345
346
|
bool APIConnection::send_cover_state(cover::Cover *cover) {
|
|
346
|
-
return this->send_message_smart_(cover, &APIConnection::try_send_cover_state, CoverStateResponse::MESSAGE_TYPE
|
|
347
|
+
return this->send_message_smart_(cover, &APIConnection::try_send_cover_state, CoverStateResponse::MESSAGE_TYPE,
|
|
348
|
+
CoverStateResponse::ESTIMATED_SIZE);
|
|
347
349
|
}
|
|
348
350
|
uint16_t APIConnection::try_send_cover_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
349
351
|
bool is_single) {
|
|
@@ -400,7 +402,8 @@ void APIConnection::cover_command(const CoverCommandRequest &msg) {
|
|
|
400
402
|
|
|
401
403
|
#ifdef USE_FAN
|
|
402
404
|
bool APIConnection::send_fan_state(fan::Fan *fan) {
|
|
403
|
-
return this->send_message_smart_(fan, &APIConnection::try_send_fan_state, FanStateResponse::MESSAGE_TYPE
|
|
405
|
+
return this->send_message_smart_(fan, &APIConnection::try_send_fan_state, FanStateResponse::MESSAGE_TYPE,
|
|
406
|
+
FanStateResponse::ESTIMATED_SIZE);
|
|
404
407
|
}
|
|
405
408
|
uint16_t APIConnection::try_send_fan_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
406
409
|
bool is_single) {
|
|
@@ -455,7 +458,8 @@ void APIConnection::fan_command(const FanCommandRequest &msg) {
|
|
|
455
458
|
|
|
456
459
|
#ifdef USE_LIGHT
|
|
457
460
|
bool APIConnection::send_light_state(light::LightState *light) {
|
|
458
|
-
return this->send_message_smart_(light, &APIConnection::try_send_light_state, LightStateResponse::MESSAGE_TYPE
|
|
461
|
+
return this->send_message_smart_(light, &APIConnection::try_send_light_state, LightStateResponse::MESSAGE_TYPE,
|
|
462
|
+
LightStateResponse::ESTIMATED_SIZE);
|
|
459
463
|
}
|
|
460
464
|
uint16_t APIConnection::try_send_light_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
461
465
|
bool is_single) {
|
|
@@ -543,7 +547,8 @@ void APIConnection::light_command(const LightCommandRequest &msg) {
|
|
|
543
547
|
|
|
544
548
|
#ifdef USE_SENSOR
|
|
545
549
|
bool APIConnection::send_sensor_state(sensor::Sensor *sensor) {
|
|
546
|
-
return this->send_message_smart_(sensor, &APIConnection::try_send_sensor_state, SensorStateResponse::MESSAGE_TYPE
|
|
550
|
+
return this->send_message_smart_(sensor, &APIConnection::try_send_sensor_state, SensorStateResponse::MESSAGE_TYPE,
|
|
551
|
+
SensorStateResponse::ESTIMATED_SIZE);
|
|
547
552
|
}
|
|
548
553
|
|
|
549
554
|
uint16_t APIConnection::try_send_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -575,7 +580,8 @@ uint16_t APIConnection::try_send_sensor_info(EntityBase *entity, APIConnection *
|
|
|
575
580
|
|
|
576
581
|
#ifdef USE_SWITCH
|
|
577
582
|
bool APIConnection::send_switch_state(switch_::Switch *a_switch) {
|
|
578
|
-
return this->send_message_smart_(a_switch, &APIConnection::try_send_switch_state, SwitchStateResponse::MESSAGE_TYPE
|
|
583
|
+
return this->send_message_smart_(a_switch, &APIConnection::try_send_switch_state, SwitchStateResponse::MESSAGE_TYPE,
|
|
584
|
+
SwitchStateResponse::ESTIMATED_SIZE);
|
|
579
585
|
}
|
|
580
586
|
|
|
581
587
|
uint16_t APIConnection::try_send_switch_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -611,7 +617,7 @@ void APIConnection::switch_command(const SwitchCommandRequest &msg) {
|
|
|
611
617
|
#ifdef USE_TEXT_SENSOR
|
|
612
618
|
bool APIConnection::send_text_sensor_state(text_sensor::TextSensor *text_sensor) {
|
|
613
619
|
return this->send_message_smart_(text_sensor, &APIConnection::try_send_text_sensor_state,
|
|
614
|
-
TextSensorStateResponse::MESSAGE_TYPE);
|
|
620
|
+
TextSensorStateResponse::MESSAGE_TYPE, TextSensorStateResponse::ESTIMATED_SIZE);
|
|
615
621
|
}
|
|
616
622
|
|
|
617
623
|
uint16_t APIConnection::try_send_text_sensor_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -638,7 +644,8 @@ uint16_t APIConnection::try_send_text_sensor_info(EntityBase *entity, APIConnect
|
|
|
638
644
|
|
|
639
645
|
#ifdef USE_CLIMATE
|
|
640
646
|
bool APIConnection::send_climate_state(climate::Climate *climate) {
|
|
641
|
-
return this->send_message_smart_(climate, &APIConnection::try_send_climate_state, ClimateStateResponse::MESSAGE_TYPE
|
|
647
|
+
return this->send_message_smart_(climate, &APIConnection::try_send_climate_state, ClimateStateResponse::MESSAGE_TYPE,
|
|
648
|
+
ClimateStateResponse::ESTIMATED_SIZE);
|
|
642
649
|
}
|
|
643
650
|
uint16_t APIConnection::try_send_climate_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
644
651
|
bool is_single) {
|
|
@@ -734,7 +741,8 @@ void APIConnection::climate_command(const ClimateCommandRequest &msg) {
|
|
|
734
741
|
|
|
735
742
|
#ifdef USE_NUMBER
|
|
736
743
|
bool APIConnection::send_number_state(number::Number *number) {
|
|
737
|
-
return this->send_message_smart_(number, &APIConnection::try_send_number_state, NumberStateResponse::MESSAGE_TYPE
|
|
744
|
+
return this->send_message_smart_(number, &APIConnection::try_send_number_state, NumberStateResponse::MESSAGE_TYPE,
|
|
745
|
+
NumberStateResponse::ESTIMATED_SIZE);
|
|
738
746
|
}
|
|
739
747
|
|
|
740
748
|
uint16_t APIConnection::try_send_number_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -770,7 +778,8 @@ void APIConnection::number_command(const NumberCommandRequest &msg) {
|
|
|
770
778
|
|
|
771
779
|
#ifdef USE_DATETIME_DATE
|
|
772
780
|
bool APIConnection::send_date_state(datetime::DateEntity *date) {
|
|
773
|
-
return this->send_message_smart_(date, &APIConnection::try_send_date_state, DateStateResponse::MESSAGE_TYPE
|
|
781
|
+
return this->send_message_smart_(date, &APIConnection::try_send_date_state, DateStateResponse::MESSAGE_TYPE,
|
|
782
|
+
DateStateResponse::ESTIMATED_SIZE);
|
|
774
783
|
}
|
|
775
784
|
uint16_t APIConnection::try_send_date_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
776
785
|
bool is_single) {
|
|
@@ -800,7 +809,8 @@ void APIConnection::date_command(const DateCommandRequest &msg) {
|
|
|
800
809
|
|
|
801
810
|
#ifdef USE_DATETIME_TIME
|
|
802
811
|
bool APIConnection::send_time_state(datetime::TimeEntity *time) {
|
|
803
|
-
return this->send_message_smart_(time, &APIConnection::try_send_time_state, TimeStateResponse::MESSAGE_TYPE
|
|
812
|
+
return this->send_message_smart_(time, &APIConnection::try_send_time_state, TimeStateResponse::MESSAGE_TYPE,
|
|
813
|
+
TimeStateResponse::ESTIMATED_SIZE);
|
|
804
814
|
}
|
|
805
815
|
uint16_t APIConnection::try_send_time_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
806
816
|
bool is_single) {
|
|
@@ -831,7 +841,7 @@ void APIConnection::time_command(const TimeCommandRequest &msg) {
|
|
|
831
841
|
#ifdef USE_DATETIME_DATETIME
|
|
832
842
|
bool APIConnection::send_datetime_state(datetime::DateTimeEntity *datetime) {
|
|
833
843
|
return this->send_message_smart_(datetime, &APIConnection::try_send_datetime_state,
|
|
834
|
-
DateTimeStateResponse::MESSAGE_TYPE);
|
|
844
|
+
DateTimeStateResponse::MESSAGE_TYPE, DateTimeStateResponse::ESTIMATED_SIZE);
|
|
835
845
|
}
|
|
836
846
|
uint16_t APIConnection::try_send_datetime_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
837
847
|
bool is_single) {
|
|
@@ -862,7 +872,8 @@ void APIConnection::datetime_command(const DateTimeCommandRequest &msg) {
|
|
|
862
872
|
|
|
863
873
|
#ifdef USE_TEXT
|
|
864
874
|
bool APIConnection::send_text_state(text::Text *text) {
|
|
865
|
-
return this->send_message_smart_(text, &APIConnection::try_send_text_state, TextStateResponse::MESSAGE_TYPE
|
|
875
|
+
return this->send_message_smart_(text, &APIConnection::try_send_text_state, TextStateResponse::MESSAGE_TYPE,
|
|
876
|
+
TextStateResponse::ESTIMATED_SIZE);
|
|
866
877
|
}
|
|
867
878
|
|
|
868
879
|
uint16_t APIConnection::try_send_text_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -896,7 +907,8 @@ void APIConnection::text_command(const TextCommandRequest &msg) {
|
|
|
896
907
|
|
|
897
908
|
#ifdef USE_SELECT
|
|
898
909
|
bool APIConnection::send_select_state(select::Select *select) {
|
|
899
|
-
return this->send_message_smart_(select, &APIConnection::try_send_select_state, SelectStateResponse::MESSAGE_TYPE
|
|
910
|
+
return this->send_message_smart_(select, &APIConnection::try_send_select_state, SelectStateResponse::MESSAGE_TYPE,
|
|
911
|
+
SelectStateResponse::ESTIMATED_SIZE);
|
|
900
912
|
}
|
|
901
913
|
|
|
902
914
|
uint16_t APIConnection::try_send_select_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -944,7 +956,8 @@ void esphome::api::APIConnection::button_command(const ButtonCommandRequest &msg
|
|
|
944
956
|
|
|
945
957
|
#ifdef USE_LOCK
|
|
946
958
|
bool APIConnection::send_lock_state(lock::Lock *a_lock) {
|
|
947
|
-
return this->send_message_smart_(a_lock, &APIConnection::try_send_lock_state, LockStateResponse::MESSAGE_TYPE
|
|
959
|
+
return this->send_message_smart_(a_lock, &APIConnection::try_send_lock_state, LockStateResponse::MESSAGE_TYPE,
|
|
960
|
+
LockStateResponse::ESTIMATED_SIZE);
|
|
948
961
|
}
|
|
949
962
|
|
|
950
963
|
uint16_t APIConnection::try_send_lock_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
@@ -986,7 +999,8 @@ void APIConnection::lock_command(const LockCommandRequest &msg) {
|
|
|
986
999
|
|
|
987
1000
|
#ifdef USE_VALVE
|
|
988
1001
|
bool APIConnection::send_valve_state(valve::Valve *valve) {
|
|
989
|
-
return this->send_message_smart_(valve, &APIConnection::try_send_valve_state, ValveStateResponse::MESSAGE_TYPE
|
|
1002
|
+
return this->send_message_smart_(valve, &APIConnection::try_send_valve_state, ValveStateResponse::MESSAGE_TYPE,
|
|
1003
|
+
ValveStateResponse::ESTIMATED_SIZE);
|
|
990
1004
|
}
|
|
991
1005
|
uint16_t APIConnection::try_send_valve_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
992
1006
|
bool is_single) {
|
|
@@ -1023,7 +1037,7 @@ void APIConnection::valve_command(const ValveCommandRequest &msg) {
|
|
|
1023
1037
|
#ifdef USE_MEDIA_PLAYER
|
|
1024
1038
|
bool APIConnection::send_media_player_state(media_player::MediaPlayer *media_player) {
|
|
1025
1039
|
return this->send_message_smart_(media_player, &APIConnection::try_send_media_player_state,
|
|
1026
|
-
MediaPlayerStateResponse::MESSAGE_TYPE);
|
|
1040
|
+
MediaPlayerStateResponse::MESSAGE_TYPE, MediaPlayerStateResponse::ESTIMATED_SIZE);
|
|
1027
1041
|
}
|
|
1028
1042
|
uint16_t APIConnection::try_send_media_player_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1029
1043
|
bool is_single) {
|
|
@@ -1262,7 +1276,8 @@ void APIConnection::voice_assistant_set_configuration(const VoiceAssistantSetCon
|
|
|
1262
1276
|
#ifdef USE_ALARM_CONTROL_PANEL
|
|
1263
1277
|
bool APIConnection::send_alarm_control_panel_state(alarm_control_panel::AlarmControlPanel *a_alarm_control_panel) {
|
|
1264
1278
|
return this->send_message_smart_(a_alarm_control_panel, &APIConnection::try_send_alarm_control_panel_state,
|
|
1265
|
-
AlarmControlPanelStateResponse::MESSAGE_TYPE
|
|
1279
|
+
AlarmControlPanelStateResponse::MESSAGE_TYPE,
|
|
1280
|
+
AlarmControlPanelStateResponse::ESTIMATED_SIZE);
|
|
1266
1281
|
}
|
|
1267
1282
|
uint16_t APIConnection::try_send_alarm_control_panel_state(EntityBase *entity, APIConnection *conn,
|
|
1268
1283
|
uint32_t remaining_size, bool is_single) {
|
|
@@ -1316,7 +1331,8 @@ void APIConnection::alarm_control_panel_command(const AlarmControlPanelCommandRe
|
|
|
1316
1331
|
|
|
1317
1332
|
#ifdef USE_EVENT
|
|
1318
1333
|
void APIConnection::send_event(event::Event *event, const std::string &event_type) {
|
|
1319
|
-
this->schedule_message_(event, MessageCreator(event_type), EventResponse::MESSAGE_TYPE
|
|
1334
|
+
this->schedule_message_(event, MessageCreator(event_type), EventResponse::MESSAGE_TYPE,
|
|
1335
|
+
EventResponse::ESTIMATED_SIZE);
|
|
1320
1336
|
}
|
|
1321
1337
|
uint16_t APIConnection::try_send_event_response(event::Event *event, const std::string &event_type, APIConnection *conn,
|
|
1322
1338
|
uint32_t remaining_size, bool is_single) {
|
|
@@ -1341,7 +1357,8 @@ uint16_t APIConnection::try_send_event_info(EntityBase *entity, APIConnection *c
|
|
|
1341
1357
|
|
|
1342
1358
|
#ifdef USE_UPDATE
|
|
1343
1359
|
bool APIConnection::send_update_state(update::UpdateEntity *update) {
|
|
1344
|
-
return this->send_message_smart_(update, &APIConnection::try_send_update_state, UpdateStateResponse::MESSAGE_TYPE
|
|
1360
|
+
return this->send_message_smart_(update, &APIConnection::try_send_update_state, UpdateStateResponse::MESSAGE_TYPE,
|
|
1361
|
+
UpdateStateResponse::ESTIMATED_SIZE);
|
|
1345
1362
|
}
|
|
1346
1363
|
uint16_t APIConnection::try_send_update_state(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1347
1364
|
bool is_single) {
|
|
@@ -1534,6 +1551,7 @@ void APIConnection::on_home_assistant_state_response(const HomeAssistantStateRes
|
|
|
1534
1551
|
}
|
|
1535
1552
|
}
|
|
1536
1553
|
}
|
|
1554
|
+
#ifdef USE_API_SERVICES
|
|
1537
1555
|
void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
|
|
1538
1556
|
bool found = false;
|
|
1539
1557
|
for (auto *service : this->parent_->get_user_services()) {
|
|
@@ -1545,6 +1563,7 @@ void APIConnection::execute_service(const ExecuteServiceRequest &msg) {
|
|
|
1545
1563
|
ESP_LOGV(TAG, "Could not find service");
|
|
1546
1564
|
}
|
|
1547
1565
|
}
|
|
1566
|
+
#endif
|
|
1548
1567
|
#ifdef USE_API_NOISE
|
|
1549
1568
|
NoiseEncryptionSetKeyResponse APIConnection::noise_encryption_set_key(const NoiseEncryptionSetKeyRequest &msg) {
|
|
1550
1569
|
psk_t psk{};
|
|
@@ -1588,7 +1607,7 @@ bool APIConnection::try_to_clear_buffer(bool log_out_of_space) {
|
|
|
1588
1607
|
}
|
|
1589
1608
|
return false;
|
|
1590
1609
|
}
|
|
1591
|
-
bool APIConnection::send_buffer(ProtoWriteBuffer buffer,
|
|
1610
|
+
bool APIConnection::send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) {
|
|
1592
1611
|
if (!this->try_to_clear_buffer(message_type != SubscribeLogsResponse::MESSAGE_TYPE)) { // SubscribeLogsResponse
|
|
1593
1612
|
return false;
|
|
1594
1613
|
}
|
|
@@ -1622,7 +1641,8 @@ void APIConnection::on_fatal_error() {
|
|
|
1622
1641
|
this->flags_.remove = true;
|
|
1623
1642
|
}
|
|
1624
1643
|
|
|
1625
|
-
void APIConnection::DeferredBatch::add_item(EntityBase *entity, MessageCreator creator,
|
|
1644
|
+
void APIConnection::DeferredBatch::add_item(EntityBase *entity, MessageCreator creator, uint8_t message_type,
|
|
1645
|
+
uint8_t estimated_size) {
|
|
1626
1646
|
// Check if we already have a message of this type for this entity
|
|
1627
1647
|
// This provides deduplication per entity/message_type combination
|
|
1628
1648
|
// O(n) but optimized for RAM and not performance.
|
|
@@ -1637,12 +1657,13 @@ void APIConnection::DeferredBatch::add_item(EntityBase *entity, MessageCreator c
|
|
|
1637
1657
|
}
|
|
1638
1658
|
|
|
1639
1659
|
// No existing item found, add new one
|
|
1640
|
-
items.emplace_back(entity, std::move(creator), message_type);
|
|
1660
|
+
items.emplace_back(entity, std::move(creator), message_type, estimated_size);
|
|
1641
1661
|
}
|
|
1642
1662
|
|
|
1643
|
-
void APIConnection::DeferredBatch::add_item_front(EntityBase *entity, MessageCreator creator,
|
|
1663
|
+
void APIConnection::DeferredBatch::add_item_front(EntityBase *entity, MessageCreator creator, uint8_t message_type,
|
|
1664
|
+
uint8_t estimated_size) {
|
|
1644
1665
|
// Insert at front for high priority messages (no deduplication check)
|
|
1645
|
-
items.insert(items.begin(), BatchItem(entity, std::move(creator), message_type));
|
|
1666
|
+
items.insert(items.begin(), BatchItem(entity, std::move(creator), message_type, estimated_size));
|
|
1646
1667
|
}
|
|
1647
1668
|
|
|
1648
1669
|
bool APIConnection::schedule_batch_() {
|
|
@@ -1714,7 +1735,7 @@ void APIConnection::process_batch_() {
|
|
|
1714
1735
|
uint32_t total_estimated_size = 0;
|
|
1715
1736
|
for (size_t i = 0; i < this->deferred_batch_.size(); i++) {
|
|
1716
1737
|
const auto &item = this->deferred_batch_[i];
|
|
1717
|
-
total_estimated_size +=
|
|
1738
|
+
total_estimated_size += item.estimated_size;
|
|
1718
1739
|
}
|
|
1719
1740
|
|
|
1720
1741
|
// Calculate total overhead for all messages
|
|
@@ -1752,9 +1773,9 @@ void APIConnection::process_batch_() {
|
|
|
1752
1773
|
|
|
1753
1774
|
// Update tracking variables
|
|
1754
1775
|
items_processed++;
|
|
1755
|
-
// After first message, set remaining size to
|
|
1776
|
+
// After first message, set remaining size to MAX_BATCH_PACKET_SIZE to avoid fragmentation
|
|
1756
1777
|
if (items_processed == 1) {
|
|
1757
|
-
remaining_size =
|
|
1778
|
+
remaining_size = MAX_BATCH_PACKET_SIZE;
|
|
1758
1779
|
}
|
|
1759
1780
|
remaining_size -= payload_size;
|
|
1760
1781
|
// Calculate where the next message's header padding will start
|
|
@@ -1808,7 +1829,7 @@ void APIConnection::process_batch_() {
|
|
|
1808
1829
|
}
|
|
1809
1830
|
|
|
1810
1831
|
uint16_t APIConnection::MessageCreator::operator()(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
1811
|
-
bool is_single,
|
|
1832
|
+
bool is_single, uint8_t message_type) const {
|
|
1812
1833
|
#ifdef USE_EVENT
|
|
1813
1834
|
// Special case: EventResponse uses string pointer
|
|
1814
1835
|
if (message_type == EventResponse::MESSAGE_TYPE) {
|
|
@@ -1839,149 +1860,6 @@ uint16_t APIConnection::try_send_ping_request(EntityBase *entity, APIConnection
|
|
|
1839
1860
|
return encode_message_to_buffer(req, PingRequest::MESSAGE_TYPE, conn, remaining_size, is_single);
|
|
1840
1861
|
}
|
|
1841
1862
|
|
|
1842
|
-
uint16_t APIConnection::get_estimated_message_size(uint16_t message_type) {
|
|
1843
|
-
// Use generated ESTIMATED_SIZE constants from each message type
|
|
1844
|
-
switch (message_type) {
|
|
1845
|
-
#ifdef USE_BINARY_SENSOR
|
|
1846
|
-
case BinarySensorStateResponse::MESSAGE_TYPE:
|
|
1847
|
-
return BinarySensorStateResponse::ESTIMATED_SIZE;
|
|
1848
|
-
case ListEntitiesBinarySensorResponse::MESSAGE_TYPE:
|
|
1849
|
-
return ListEntitiesBinarySensorResponse::ESTIMATED_SIZE;
|
|
1850
|
-
#endif
|
|
1851
|
-
#ifdef USE_SENSOR
|
|
1852
|
-
case SensorStateResponse::MESSAGE_TYPE:
|
|
1853
|
-
return SensorStateResponse::ESTIMATED_SIZE;
|
|
1854
|
-
case ListEntitiesSensorResponse::MESSAGE_TYPE:
|
|
1855
|
-
return ListEntitiesSensorResponse::ESTIMATED_SIZE;
|
|
1856
|
-
#endif
|
|
1857
|
-
#ifdef USE_SWITCH
|
|
1858
|
-
case SwitchStateResponse::MESSAGE_TYPE:
|
|
1859
|
-
return SwitchStateResponse::ESTIMATED_SIZE;
|
|
1860
|
-
case ListEntitiesSwitchResponse::MESSAGE_TYPE:
|
|
1861
|
-
return ListEntitiesSwitchResponse::ESTIMATED_SIZE;
|
|
1862
|
-
#endif
|
|
1863
|
-
#ifdef USE_TEXT_SENSOR
|
|
1864
|
-
case TextSensorStateResponse::MESSAGE_TYPE:
|
|
1865
|
-
return TextSensorStateResponse::ESTIMATED_SIZE;
|
|
1866
|
-
case ListEntitiesTextSensorResponse::MESSAGE_TYPE:
|
|
1867
|
-
return ListEntitiesTextSensorResponse::ESTIMATED_SIZE;
|
|
1868
|
-
#endif
|
|
1869
|
-
#ifdef USE_NUMBER
|
|
1870
|
-
case NumberStateResponse::MESSAGE_TYPE:
|
|
1871
|
-
return NumberStateResponse::ESTIMATED_SIZE;
|
|
1872
|
-
case ListEntitiesNumberResponse::MESSAGE_TYPE:
|
|
1873
|
-
return ListEntitiesNumberResponse::ESTIMATED_SIZE;
|
|
1874
|
-
#endif
|
|
1875
|
-
#ifdef USE_TEXT
|
|
1876
|
-
case TextStateResponse::MESSAGE_TYPE:
|
|
1877
|
-
return TextStateResponse::ESTIMATED_SIZE;
|
|
1878
|
-
case ListEntitiesTextResponse::MESSAGE_TYPE:
|
|
1879
|
-
return ListEntitiesTextResponse::ESTIMATED_SIZE;
|
|
1880
|
-
#endif
|
|
1881
|
-
#ifdef USE_SELECT
|
|
1882
|
-
case SelectStateResponse::MESSAGE_TYPE:
|
|
1883
|
-
return SelectStateResponse::ESTIMATED_SIZE;
|
|
1884
|
-
case ListEntitiesSelectResponse::MESSAGE_TYPE:
|
|
1885
|
-
return ListEntitiesSelectResponse::ESTIMATED_SIZE;
|
|
1886
|
-
#endif
|
|
1887
|
-
#ifdef USE_LOCK
|
|
1888
|
-
case LockStateResponse::MESSAGE_TYPE:
|
|
1889
|
-
return LockStateResponse::ESTIMATED_SIZE;
|
|
1890
|
-
case ListEntitiesLockResponse::MESSAGE_TYPE:
|
|
1891
|
-
return ListEntitiesLockResponse::ESTIMATED_SIZE;
|
|
1892
|
-
#endif
|
|
1893
|
-
#ifdef USE_EVENT
|
|
1894
|
-
case EventResponse::MESSAGE_TYPE:
|
|
1895
|
-
return EventResponse::ESTIMATED_SIZE;
|
|
1896
|
-
case ListEntitiesEventResponse::MESSAGE_TYPE:
|
|
1897
|
-
return ListEntitiesEventResponse::ESTIMATED_SIZE;
|
|
1898
|
-
#endif
|
|
1899
|
-
#ifdef USE_COVER
|
|
1900
|
-
case CoverStateResponse::MESSAGE_TYPE:
|
|
1901
|
-
return CoverStateResponse::ESTIMATED_SIZE;
|
|
1902
|
-
case ListEntitiesCoverResponse::MESSAGE_TYPE:
|
|
1903
|
-
return ListEntitiesCoverResponse::ESTIMATED_SIZE;
|
|
1904
|
-
#endif
|
|
1905
|
-
#ifdef USE_FAN
|
|
1906
|
-
case FanStateResponse::MESSAGE_TYPE:
|
|
1907
|
-
return FanStateResponse::ESTIMATED_SIZE;
|
|
1908
|
-
case ListEntitiesFanResponse::MESSAGE_TYPE:
|
|
1909
|
-
return ListEntitiesFanResponse::ESTIMATED_SIZE;
|
|
1910
|
-
#endif
|
|
1911
|
-
#ifdef USE_LIGHT
|
|
1912
|
-
case LightStateResponse::MESSAGE_TYPE:
|
|
1913
|
-
return LightStateResponse::ESTIMATED_SIZE;
|
|
1914
|
-
case ListEntitiesLightResponse::MESSAGE_TYPE:
|
|
1915
|
-
return ListEntitiesLightResponse::ESTIMATED_SIZE;
|
|
1916
|
-
#endif
|
|
1917
|
-
#ifdef USE_CLIMATE
|
|
1918
|
-
case ClimateStateResponse::MESSAGE_TYPE:
|
|
1919
|
-
return ClimateStateResponse::ESTIMATED_SIZE;
|
|
1920
|
-
case ListEntitiesClimateResponse::MESSAGE_TYPE:
|
|
1921
|
-
return ListEntitiesClimateResponse::ESTIMATED_SIZE;
|
|
1922
|
-
#endif
|
|
1923
|
-
#ifdef USE_ESP32_CAMERA
|
|
1924
|
-
case ListEntitiesCameraResponse::MESSAGE_TYPE:
|
|
1925
|
-
return ListEntitiesCameraResponse::ESTIMATED_SIZE;
|
|
1926
|
-
#endif
|
|
1927
|
-
#ifdef USE_BUTTON
|
|
1928
|
-
case ListEntitiesButtonResponse::MESSAGE_TYPE:
|
|
1929
|
-
return ListEntitiesButtonResponse::ESTIMATED_SIZE;
|
|
1930
|
-
#endif
|
|
1931
|
-
#ifdef USE_MEDIA_PLAYER
|
|
1932
|
-
case MediaPlayerStateResponse::MESSAGE_TYPE:
|
|
1933
|
-
return MediaPlayerStateResponse::ESTIMATED_SIZE;
|
|
1934
|
-
case ListEntitiesMediaPlayerResponse::MESSAGE_TYPE:
|
|
1935
|
-
return ListEntitiesMediaPlayerResponse::ESTIMATED_SIZE;
|
|
1936
|
-
#endif
|
|
1937
|
-
#ifdef USE_ALARM_CONTROL_PANEL
|
|
1938
|
-
case AlarmControlPanelStateResponse::MESSAGE_TYPE:
|
|
1939
|
-
return AlarmControlPanelStateResponse::ESTIMATED_SIZE;
|
|
1940
|
-
case ListEntitiesAlarmControlPanelResponse::MESSAGE_TYPE:
|
|
1941
|
-
return ListEntitiesAlarmControlPanelResponse::ESTIMATED_SIZE;
|
|
1942
|
-
#endif
|
|
1943
|
-
#ifdef USE_DATETIME_DATE
|
|
1944
|
-
case DateStateResponse::MESSAGE_TYPE:
|
|
1945
|
-
return DateStateResponse::ESTIMATED_SIZE;
|
|
1946
|
-
case ListEntitiesDateResponse::MESSAGE_TYPE:
|
|
1947
|
-
return ListEntitiesDateResponse::ESTIMATED_SIZE;
|
|
1948
|
-
#endif
|
|
1949
|
-
#ifdef USE_DATETIME_TIME
|
|
1950
|
-
case TimeStateResponse::MESSAGE_TYPE:
|
|
1951
|
-
return TimeStateResponse::ESTIMATED_SIZE;
|
|
1952
|
-
case ListEntitiesTimeResponse::MESSAGE_TYPE:
|
|
1953
|
-
return ListEntitiesTimeResponse::ESTIMATED_SIZE;
|
|
1954
|
-
#endif
|
|
1955
|
-
#ifdef USE_DATETIME_DATETIME
|
|
1956
|
-
case DateTimeStateResponse::MESSAGE_TYPE:
|
|
1957
|
-
return DateTimeStateResponse::ESTIMATED_SIZE;
|
|
1958
|
-
case ListEntitiesDateTimeResponse::MESSAGE_TYPE:
|
|
1959
|
-
return ListEntitiesDateTimeResponse::ESTIMATED_SIZE;
|
|
1960
|
-
#endif
|
|
1961
|
-
#ifdef USE_VALVE
|
|
1962
|
-
case ValveStateResponse::MESSAGE_TYPE:
|
|
1963
|
-
return ValveStateResponse::ESTIMATED_SIZE;
|
|
1964
|
-
case ListEntitiesValveResponse::MESSAGE_TYPE:
|
|
1965
|
-
return ListEntitiesValveResponse::ESTIMATED_SIZE;
|
|
1966
|
-
#endif
|
|
1967
|
-
#ifdef USE_UPDATE
|
|
1968
|
-
case UpdateStateResponse::MESSAGE_TYPE:
|
|
1969
|
-
return UpdateStateResponse::ESTIMATED_SIZE;
|
|
1970
|
-
case ListEntitiesUpdateResponse::MESSAGE_TYPE:
|
|
1971
|
-
return ListEntitiesUpdateResponse::ESTIMATED_SIZE;
|
|
1972
|
-
#endif
|
|
1973
|
-
case ListEntitiesServicesResponse::MESSAGE_TYPE:
|
|
1974
|
-
return ListEntitiesServicesResponse::ESTIMATED_SIZE;
|
|
1975
|
-
case ListEntitiesDoneResponse::MESSAGE_TYPE:
|
|
1976
|
-
return ListEntitiesDoneResponse::ESTIMATED_SIZE;
|
|
1977
|
-
case DisconnectRequest::MESSAGE_TYPE:
|
|
1978
|
-
return DisconnectRequest::ESTIMATED_SIZE;
|
|
1979
|
-
default:
|
|
1980
|
-
// Fallback for unknown message types
|
|
1981
|
-
return 24;
|
|
1982
|
-
}
|
|
1983
|
-
}
|
|
1984
|
-
|
|
1985
1863
|
} // namespace api
|
|
1986
1864
|
} // namespace esphome
|
|
1987
1865
|
#endif
|
|
@@ -33,7 +33,7 @@ class APIConnection : public APIServerConnection {
|
|
|
33
33
|
|
|
34
34
|
bool send_list_info_done() {
|
|
35
35
|
return this->schedule_message_(nullptr, &APIConnection::try_send_list_info_done,
|
|
36
|
-
ListEntitiesDoneResponse::MESSAGE_TYPE);
|
|
36
|
+
ListEntitiesDoneResponse::MESSAGE_TYPE, ListEntitiesDoneResponse::ESTIMATED_SIZE);
|
|
37
37
|
}
|
|
38
38
|
#ifdef USE_BINARY_SENSOR
|
|
39
39
|
bool send_binary_sensor_state(binary_sensor::BinarySensor *binary_sensor);
|
|
@@ -195,7 +195,9 @@ class APIConnection : public APIServerConnection {
|
|
|
195
195
|
// TODO
|
|
196
196
|
return {};
|
|
197
197
|
}
|
|
198
|
+
#ifdef USE_API_SERVICES
|
|
198
199
|
void execute_service(const ExecuteServiceRequest &msg) override;
|
|
200
|
+
#endif
|
|
199
201
|
#ifdef USE_API_NOISE
|
|
200
202
|
NoiseEncryptionSetKeyResponse noise_encryption_set_key(const NoiseEncryptionSetKeyRequest &msg) override;
|
|
201
203
|
#endif
|
|
@@ -256,7 +258,7 @@ class APIConnection : public APIServerConnection {
|
|
|
256
258
|
}
|
|
257
259
|
|
|
258
260
|
bool try_to_clear_buffer(bool log_out_of_space);
|
|
259
|
-
bool send_buffer(ProtoWriteBuffer buffer,
|
|
261
|
+
bool send_buffer(ProtoWriteBuffer buffer, uint8_t message_type) override;
|
|
260
262
|
|
|
261
263
|
std::string get_client_combined_info() const {
|
|
262
264
|
if (this->client_info_ == this->client_peername_) {
|
|
@@ -298,7 +300,7 @@ class APIConnection : public APIServerConnection {
|
|
|
298
300
|
}
|
|
299
301
|
|
|
300
302
|
// Non-template helper to encode any ProtoMessage
|
|
301
|
-
static uint16_t encode_message_to_buffer(ProtoMessage &msg,
|
|
303
|
+
static uint16_t encode_message_to_buffer(ProtoMessage &msg, uint8_t message_type, APIConnection *conn,
|
|
302
304
|
uint32_t remaining_size, bool is_single);
|
|
303
305
|
|
|
304
306
|
#ifdef USE_VOICE_ASSISTANT
|
|
@@ -443,9 +445,6 @@ class APIConnection : public APIServerConnection {
|
|
|
443
445
|
static uint16_t try_send_disconnect_request(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
444
446
|
bool is_single);
|
|
445
447
|
|
|
446
|
-
// Helper function to get estimated message size for buffer pre-allocation
|
|
447
|
-
static uint16_t get_estimated_message_size(uint16_t message_type);
|
|
448
|
-
|
|
449
448
|
// Batch message method for ping requests
|
|
450
449
|
static uint16_t try_send_ping_request(EntityBase *entity, APIConnection *conn, uint32_t remaining_size,
|
|
451
450
|
bool is_single);
|
|
@@ -505,10 +504,10 @@ class APIConnection : public APIServerConnection {
|
|
|
505
504
|
|
|
506
505
|
// Call operator - uses message_type to determine union type
|
|
507
506
|
uint16_t operator()(EntityBase *entity, APIConnection *conn, uint32_t remaining_size, bool is_single,
|
|
508
|
-
|
|
507
|
+
uint8_t message_type) const;
|
|
509
508
|
|
|
510
509
|
// Manual cleanup method - must be called before destruction for string types
|
|
511
|
-
void cleanup(
|
|
510
|
+
void cleanup(uint8_t message_type) {
|
|
512
511
|
#ifdef USE_EVENT
|
|
513
512
|
if (message_type == EventResponse::MESSAGE_TYPE && data_.string_ptr != nullptr) {
|
|
514
513
|
delete data_.string_ptr;
|
|
@@ -529,11 +528,12 @@ class APIConnection : public APIServerConnection {
|
|
|
529
528
|
struct BatchItem {
|
|
530
529
|
EntityBase *entity; // Entity pointer
|
|
531
530
|
MessageCreator creator; // Function that creates the message when needed
|
|
532
|
-
|
|
531
|
+
uint8_t message_type; // Message type for overhead calculation (max 255)
|
|
532
|
+
uint8_t estimated_size; // Estimated message size (max 255 bytes)
|
|
533
533
|
|
|
534
534
|
// Constructor for creating BatchItem
|
|
535
|
-
BatchItem(EntityBase *entity, MessageCreator creator,
|
|
536
|
-
: entity(entity), creator(std::move(creator)), message_type(message_type) {}
|
|
535
|
+
BatchItem(EntityBase *entity, MessageCreator creator, uint8_t message_type, uint8_t estimated_size)
|
|
536
|
+
: entity(entity), creator(std::move(creator)), message_type(message_type), estimated_size(estimated_size) {}
|
|
537
537
|
};
|
|
538
538
|
|
|
539
539
|
std::vector<BatchItem> items;
|
|
@@ -559,9 +559,9 @@ class APIConnection : public APIServerConnection {
|
|
|
559
559
|
}
|
|
560
560
|
|
|
561
561
|
// Add item to the batch
|
|
562
|
-
void add_item(EntityBase *entity, MessageCreator creator,
|
|
562
|
+
void add_item(EntityBase *entity, MessageCreator creator, uint8_t message_type, uint8_t estimated_size);
|
|
563
563
|
// Add item to the front of the batch (for high priority messages like ping)
|
|
564
|
-
void add_item_front(EntityBase *entity, MessageCreator creator,
|
|
564
|
+
void add_item_front(EntityBase *entity, MessageCreator creator, uint8_t message_type, uint8_t estimated_size);
|
|
565
565
|
|
|
566
566
|
// Clear all items with proper cleanup
|
|
567
567
|
void clear() {
|
|
@@ -630,7 +630,7 @@ class APIConnection : public APIServerConnection {
|
|
|
630
630
|
// to send in one go. This is the maximum size of a single packet
|
|
631
631
|
// that can be sent over the network.
|
|
632
632
|
// This is to avoid fragmentation of the packet.
|
|
633
|
-
static constexpr size_t
|
|
633
|
+
static constexpr size_t MAX_BATCH_PACKET_SIZE = 1390; // MTU
|
|
634
634
|
|
|
635
635
|
bool schedule_batch_();
|
|
636
636
|
void process_batch_();
|
|
@@ -641,9 +641,9 @@ class APIConnection : public APIServerConnection {
|
|
|
641
641
|
|
|
642
642
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
643
643
|
// Helper to log a proto message from a MessageCreator object
|
|
644
|
-
void log_proto_message_(EntityBase *entity, const MessageCreator &creator,
|
|
644
|
+
void log_proto_message_(EntityBase *entity, const MessageCreator &creator, uint8_t message_type) {
|
|
645
645
|
this->flags_.log_only_mode = true;
|
|
646
|
-
creator(entity, this,
|
|
646
|
+
creator(entity, this, MAX_BATCH_PACKET_SIZE, true, message_type);
|
|
647
647
|
this->flags_.log_only_mode = false;
|
|
648
648
|
}
|
|
649
649
|
|
|
@@ -654,7 +654,8 @@ class APIConnection : public APIServerConnection {
|
|
|
654
654
|
#endif
|
|
655
655
|
|
|
656
656
|
// Helper method to send a message either immediately or via batching
|
|
657
|
-
bool send_message_smart_(EntityBase *entity, MessageCreatorPtr creator,
|
|
657
|
+
bool send_message_smart_(EntityBase *entity, MessageCreatorPtr creator, uint8_t message_type,
|
|
658
|
+
uint8_t estimated_size) {
|
|
658
659
|
// Try to send immediately if:
|
|
659
660
|
// 1. We should try to send immediately (should_try_send_immediately = true)
|
|
660
661
|
// 2. Batch delay is 0 (user has opted in to immediate sending)
|
|
@@ -662,7 +663,7 @@ class APIConnection : public APIServerConnection {
|
|
|
662
663
|
if (this->flags_.should_try_send_immediately && this->get_batch_delay_ms_() == 0 &&
|
|
663
664
|
this->helper_->can_write_without_blocking()) {
|
|
664
665
|
// Now actually encode and send
|
|
665
|
-
if (creator(entity, this,
|
|
666
|
+
if (creator(entity, this, MAX_BATCH_PACKET_SIZE, true) &&
|
|
666
667
|
this->send_buffer(ProtoWriteBuffer{&this->parent_->get_shared_buffer_ref()}, message_type)) {
|
|
667
668
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
|
668
669
|
// Log the message in verbose mode
|
|
@@ -675,23 +676,25 @@ class APIConnection : public APIServerConnection {
|
|
|
675
676
|
}
|
|
676
677
|
|
|
677
678
|
// Fall back to scheduled batching
|
|
678
|
-
return this->schedule_message_(entity, creator, message_type);
|
|
679
|
+
return this->schedule_message_(entity, creator, message_type, estimated_size);
|
|
679
680
|
}
|
|
680
681
|
|
|
681
682
|
// Helper function to schedule a deferred message with known message type
|
|
682
|
-
bool schedule_message_(EntityBase *entity, MessageCreator creator,
|
|
683
|
-
this->deferred_batch_.add_item(entity, std::move(creator), message_type);
|
|
683
|
+
bool schedule_message_(EntityBase *entity, MessageCreator creator, uint8_t message_type, uint8_t estimated_size) {
|
|
684
|
+
this->deferred_batch_.add_item(entity, std::move(creator), message_type, estimated_size);
|
|
684
685
|
return this->schedule_batch_();
|
|
685
686
|
}
|
|
686
687
|
|
|
687
688
|
// Overload for function pointers (for info messages and current state reads)
|
|
688
|
-
bool schedule_message_(EntityBase *entity, MessageCreatorPtr function_ptr,
|
|
689
|
-
|
|
689
|
+
bool schedule_message_(EntityBase *entity, MessageCreatorPtr function_ptr, uint8_t message_type,
|
|
690
|
+
uint8_t estimated_size) {
|
|
691
|
+
return schedule_message_(entity, MessageCreator(function_ptr), message_type, estimated_size);
|
|
690
692
|
}
|
|
691
693
|
|
|
692
694
|
// Helper function to schedule a high priority message at the front of the batch
|
|
693
|
-
bool schedule_message_front_(EntityBase *entity, MessageCreatorPtr function_ptr,
|
|
694
|
-
|
|
695
|
+
bool schedule_message_front_(EntityBase *entity, MessageCreatorPtr function_ptr, uint8_t message_type,
|
|
696
|
+
uint8_t estimated_size) {
|
|
697
|
+
this->deferred_batch_.add_item_front(entity, MessageCreator(function_ptr), message_type, estimated_size);
|
|
695
698
|
return this->schedule_batch_();
|
|
696
699
|
}
|
|
697
700
|
};
|