mirror of
https://github.com/esphome/esphome.git
synced 2026-09-20 16:50:42 +08:00
Reduce binary size with field-level conditional compilation for protobuf messages (#9473)
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
This commit is contained in:
co-authored by
pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
parent
f3c0c0c00c
commit
3ab1ee7a04
+100
-100
File diff suppressed because it is too large
Load Diff
@@ -1463,7 +1463,9 @@ DeviceInfoResponse APIConnection::device_info(const DeviceInfoRequest &msg) {
|
||||
#endif
|
||||
resp.name = App.get_name();
|
||||
resp.friendly_name = App.get_friendly_name();
|
||||
#ifdef USE_AREAS
|
||||
resp.suggested_area = App.get_area();
|
||||
#endif
|
||||
resp.mac_address = get_mac_address_pretty();
|
||||
resp.esphome_version = ESPHOME_VERSION;
|
||||
resp.compilation_time = App.get_compilation_time();
|
||||
|
||||
@@ -286,8 +286,10 @@ class APIConnection : public APIServerConnection {
|
||||
if (entity->has_own_name())
|
||||
response.name = entity->get_name();
|
||||
|
||||
// Set common EntityBase properties
|
||||
// Set common EntityBase properties
|
||||
#ifdef USE_ENTITY_ICON
|
||||
response.icon = entity->get_icon();
|
||||
#endif
|
||||
response.disabled_by_default = entity->is_disabled_by_default();
|
||||
response.entity_category = static_cast<enums::EntityCategory>(entity->get_entity_category());
|
||||
#ifdef USE_DEVICES
|
||||
|
||||
@@ -23,3 +23,7 @@ extend google.protobuf.MessageOptions {
|
||||
optional bool no_delay = 1040 [default=false];
|
||||
optional string base_class = 1041;
|
||||
}
|
||||
|
||||
extend google.protobuf.FieldOptions {
|
||||
optional string field_ifdef = 1042;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -491,22 +491,50 @@ class DeviceInfoResponse : public ProtoMessage {
|
||||
std::string esphome_version{};
|
||||
std::string compilation_time{};
|
||||
std::string model{};
|
||||
#ifdef USE_DEEP_SLEEP
|
||||
bool has_deep_sleep{false};
|
||||
#endif
|
||||
#ifdef ESPHOME_PROJECT_NAME
|
||||
std::string project_name{};
|
||||
#endif
|
||||
#ifdef ESPHOME_PROJECT_NAME
|
||||
std::string project_version{};
|
||||
#endif
|
||||
#ifdef USE_WEBSERVER
|
||||
uint32_t webserver_port{0};
|
||||
#endif
|
||||
#ifdef USE_BLUETOOTH_PROXY
|
||||
uint32_t legacy_bluetooth_proxy_version{0};
|
||||
#endif
|
||||
#ifdef USE_BLUETOOTH_PROXY
|
||||
uint32_t bluetooth_proxy_feature_flags{0};
|
||||
#endif
|
||||
std::string manufacturer{};
|
||||
std::string friendly_name{};
|
||||
#ifdef USE_VOICE_ASSISTANT
|
||||
uint32_t legacy_voice_assistant_version{0};
|
||||
#endif
|
||||
#ifdef USE_VOICE_ASSISTANT
|
||||
uint32_t voice_assistant_feature_flags{0};
|
||||
#endif
|
||||
#ifdef USE_AREAS
|
||||
std::string suggested_area{};
|
||||
#endif
|
||||
#ifdef USE_BLUETOOTH_PROXY
|
||||
std::string bluetooth_mac_address{};
|
||||
#endif
|
||||
#ifdef USE_API_NOISE
|
||||
bool api_encryption_supported{false};
|
||||
#endif
|
||||
#ifdef USE_DEVICES
|
||||
std::vector<DeviceInfo> devices{};
|
||||
#endif
|
||||
#ifdef USE_AREAS
|
||||
std::vector<AreaInfo> areas{};
|
||||
#endif
|
||||
#ifdef USE_AREAS
|
||||
AreaInfo area{};
|
||||
#endif
|
||||
void encode(ProtoWriteBuffer buffer) const override;
|
||||
void calculate_size(uint32_t &total_size) const override;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -75,6 +75,30 @@ def indent(text: str, padding: str = " ") -> str:
|
||||
return "\n".join(indent_list(text, padding))
|
||||
|
||||
|
||||
def wrap_with_ifdef(content: str | list[str], ifdef: str | None) -> list[str]:
|
||||
"""Wrap content with #ifdef directives if ifdef is provided.
|
||||
|
||||
Args:
|
||||
content: Single string or list of strings to wrap
|
||||
ifdef: The ifdef condition, or None to skip wrapping
|
||||
|
||||
Returns:
|
||||
List of strings with ifdef wrapping if needed
|
||||
"""
|
||||
if not ifdef:
|
||||
if isinstance(content, str):
|
||||
return [content]
|
||||
return content
|
||||
|
||||
result = [f"#ifdef {ifdef}"]
|
||||
if isinstance(content, str):
|
||||
result.append(content)
|
||||
else:
|
||||
result.extend(content)
|
||||
result.append("#endif")
|
||||
return result
|
||||
|
||||
|
||||
def camel_to_snake(name: str) -> str:
|
||||
# https://stackoverflow.com/a/1176023
|
||||
s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name)
|
||||
@@ -1064,26 +1088,62 @@ def build_message_type(
|
||||
# Skip field declarations for fields that are in the base class
|
||||
# but include their encode/decode logic
|
||||
if field.name not in common_field_names:
|
||||
protected_content.extend(ti.protected_content)
|
||||
public_content.extend(ti.public_content)
|
||||
# Check for field_ifdef option
|
||||
field_ifdef = None
|
||||
if field.options.HasExtension(pb.field_ifdef):
|
||||
field_ifdef = field.options.Extensions[pb.field_ifdef]
|
||||
|
||||
if ti.protected_content:
|
||||
protected_content.extend(
|
||||
wrap_with_ifdef(ti.protected_content, field_ifdef)
|
||||
)
|
||||
if ti.public_content:
|
||||
public_content.extend(wrap_with_ifdef(ti.public_content, field_ifdef))
|
||||
|
||||
# Only collect encode logic if this message needs it
|
||||
if needs_encode:
|
||||
encode.append(ti.encode_content)
|
||||
size_calc.append(ti.get_size_calculation(f"this->{ti.field_name}"))
|
||||
# Check for field_ifdef option
|
||||
field_ifdef = None
|
||||
if field.options.HasExtension(pb.field_ifdef):
|
||||
field_ifdef = field.options.Extensions[pb.field_ifdef]
|
||||
|
||||
encode.extend(wrap_with_ifdef(ti.encode_content, field_ifdef))
|
||||
size_calc.extend(
|
||||
wrap_with_ifdef(
|
||||
ti.get_size_calculation(f"this->{ti.field_name}"), field_ifdef
|
||||
)
|
||||
)
|
||||
|
||||
# Only collect decode methods if this message needs them
|
||||
if needs_decode:
|
||||
# Check for field_ifdef option for decode as well
|
||||
field_ifdef = None
|
||||
if field.options.HasExtension(pb.field_ifdef):
|
||||
field_ifdef = field.options.Extensions[pb.field_ifdef]
|
||||
|
||||
if ti.decode_varint_content:
|
||||
decode_varint.append(ti.decode_varint_content)
|
||||
decode_varint.extend(
|
||||
wrap_with_ifdef(ti.decode_varint_content, field_ifdef)
|
||||
)
|
||||
if ti.decode_length_content:
|
||||
decode_length.append(ti.decode_length_content)
|
||||
decode_length.extend(
|
||||
wrap_with_ifdef(ti.decode_length_content, field_ifdef)
|
||||
)
|
||||
if ti.decode_32bit_content:
|
||||
decode_32bit.append(ti.decode_32bit_content)
|
||||
decode_32bit.extend(
|
||||
wrap_with_ifdef(ti.decode_32bit_content, field_ifdef)
|
||||
)
|
||||
if ti.decode_64bit_content:
|
||||
decode_64bit.append(ti.decode_64bit_content)
|
||||
decode_64bit.extend(
|
||||
wrap_with_ifdef(ti.decode_64bit_content, field_ifdef)
|
||||
)
|
||||
if ti.dump_content:
|
||||
dump.append(ti.dump_content)
|
||||
# Check for field_ifdef option for dump as well
|
||||
field_ifdef = None
|
||||
if field.options.HasExtension(pb.field_ifdef):
|
||||
field_ifdef = field.options.Extensions[pb.field_ifdef]
|
||||
|
||||
dump.extend(wrap_with_ifdef(ti.dump_content, field_ifdef))
|
||||
|
||||
cpp = ""
|
||||
if decode_varint:
|
||||
|
||||
Reference in New Issue
Block a user