This commit is contained in:
J. Nick Koston
2025-12-19 15:08:02 -10:00
parent cd6240541b
commit 01224f25f7
3 changed files with 32 additions and 11 deletions
+5 -4
View File
@@ -404,10 +404,11 @@ void WebServer::handle_js_request(AsyncWebServerRequest *request) {
// Helper functions to reduce code size by avoiding macro expansion
static void set_json_id(JsonObject &root, EntityBase *obj, const char *prefix, JsonDetail start_config) {
char object_id_buf[OBJECT_ID_MAX_LEN];
StringRef object_id = obj->get_object_id_to(object_id_buf);
char id_buf[160]; // object_id can be up to 128 chars + prefix + dash + null
snprintf(id_buf, sizeof(id_buf), "%s-%s", prefix, object_id.c_str());
char id_buf[160]; // prefix + dash + object_id (up to 128) + null
size_t len = strlen(prefix);
memcpy(id_buf, prefix, len);
id_buf[len++] = '-';
obj->write_object_id_to(id_buf + len, sizeof(id_buf) - len);
root[ESPHOME_F("id")] = id_buf;
if (start_config == DETAIL_ALL) {
root[ESPHOME_F("name")] = obj->get_name();
+23 -7
View File
@@ -78,18 +78,34 @@ void EntityBase::calc_object_id_() {
this->object_id_hash_ = fnv1_hash(object_id.c_str());
}
size_t EntityBase::write_object_id_to(char *buf, size_t buf_size) const {
if (!this->is_object_id_dynamic_()) {
// Static case: copy from stored c_str
const char *src = this->object_id_c_str_ == nullptr ? "" : this->object_id_c_str_;
size_t len = strlen(src);
if (len >= buf_size)
len = buf_size - 1;
memcpy(buf, src, len);
buf[len] = '\0';
return len;
}
// Dynamic case: format into buffer
const std::string &name = App.get_friendly_name();
size_t len = std::min(name.size(), buf_size - 1);
for (size_t i = 0; i < len; i++) {
buf[i] = to_sanitized_char(to_snake_case_char(name[i]));
}
buf[len] = '\0';
return len;
}
StringRef EntityBase::get_object_id_to(std::span<char, OBJECT_ID_MAX_LEN> buf) const {
if (!this->is_object_id_dynamic_()) {
// Static case: return direct reference, buffer unused
return this->object_id_c_str_ == nullptr ? StringRef() : StringRef(this->object_id_c_str_);
}
// Dynamic case: format into buffer
const std::string &name = App.get_friendly_name();
size_t len = std::min(name.size(), buf.size() - 1);
for (size_t i = 0; i < len; i++) {
buf[i] = to_sanitized_char(to_snake_case_char(name[i]));
}
buf[len] = '\0';
// Dynamic case: write to buffer and return StringRef
size_t len = this->write_object_id_to(buf.data(), buf.size());
return StringRef(buf.data(), len);
}
+4
View File
@@ -47,6 +47,10 @@ class EntityBase {
/// For dynamic case: formats into buffer and returns StringRef to buffer
StringRef get_object_id_to(std::span<char, OBJECT_ID_MAX_LEN> buf) const;
/// Write object_id directly to buffer, returns length written (excluding null)
/// Useful for building compound strings without intermediate buffer
size_t write_object_id_to(char *buf, size_t buf_size) const;
// Get/set whether this Entity should be hidden outside ESPHome
bool is_internal() const { return this->flags_.internal; }
void set_internal(bool internal) { this->flags_.internal = internal; }