From 522395de113ef4bc5fec652060296f3a994e6b65 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 12 Oct 2026 17:19:03 -1000 Subject: [PATCH] Read entity names flash-safely in web_server, MQTT and prometheus --- .../mqtt/mqtt_alarm_control_panel.cpp | 8 +- .../components/mqtt/mqtt_binary_sensor.cpp | 2 +- esphome/components/mqtt/mqtt_button.cpp | 4 +- esphome/components/mqtt/mqtt_component.cpp | 18 +- esphome/components/mqtt/mqtt_component.h | 4 +- esphome/components/mqtt/mqtt_cover.cpp | 2 +- esphome/components/mqtt/mqtt_date.cpp | 2 +- esphome/components/mqtt/mqtt_datetime.cpp | 2 +- esphome/components/mqtt/mqtt_event.cpp | 2 +- esphome/components/mqtt/mqtt_fan.cpp | 18 +- esphome/components/mqtt/mqtt_light.cpp | 2 +- esphome/components/mqtt/mqtt_lock.cpp | 4 +- esphome/components/mqtt/mqtt_number.cpp | 2 +- esphome/components/mqtt/mqtt_select.cpp | 2 +- esphome/components/mqtt/mqtt_sensor.cpp | 2 +- esphome/components/mqtt/mqtt_switch.cpp | 4 +- esphome/components/mqtt/mqtt_text.cpp | 2 +- esphome/components/mqtt/mqtt_text_sensor.cpp | 2 +- esphome/components/mqtt/mqtt_time.cpp | 2 +- esphome/components/mqtt/mqtt_update.cpp | 4 +- esphome/components/mqtt/mqtt_valve.cpp | 2 +- .../prometheus/prometheus_handler.cpp | 207 +++++++++--------- .../prometheus/prometheus_handler.h | 4 +- esphome/components/web_server/web_server.cpp | 17 +- .../components/web_server/web_server_v1.cpp | 6 +- 25 files changed, 174 insertions(+), 150 deletions(-) diff --git a/esphome/components/mqtt/mqtt_alarm_control_panel.cpp b/esphome/components/mqtt/mqtt_alarm_control_panel.cpp index 225f839633..7d3f156228 100644 --- a/esphome/components/mqtt/mqtt_alarm_control_panel.cpp +++ b/esphome/components/mqtt/mqtt_alarm_control_panel.cpp @@ -59,9 +59,9 @@ void MQTTAlarmControlPanelComponent::setup() { if (!root.isNull()) { const char *state = root[ESPHOME_F("state")]; if (state == nullptr) { - ESP_LOGW(TAG, "'%s': JSON payload missing 'state' key", this->friendly_name_().c_str()); + ESP_LOGW(TAG, "'%s': JSON payload missing 'state' key", LOG_STR_ARG(this->log_name_())); } else if (!apply_command(call, state)) { - ESP_LOGW(TAG, "'%s': Received unknown state in JSON payload: %s", this->friendly_name_().c_str(), state); + ESP_LOGW(TAG, "'%s': Received unknown state in JSON payload: %s", LOG_STR_ARG(this->log_name_()), state); } else { const char *code = root[ESPHOME_F("code")]; if (code != nullptr) { @@ -70,14 +70,14 @@ void MQTTAlarmControlPanelComponent::setup() { } } } else if (!apply_command(call, payload.c_str())) { - ESP_LOGW(TAG, "'%s': Received unknown command payload %s", this->friendly_name_().c_str(), payload.c_str()); + ESP_LOGW(TAG, "'%s': Received unknown command payload %s", LOG_STR_ARG(this->log_name_()), payload.c_str()); } call.perform(); }); } void MQTTAlarmControlPanelComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT alarm_control_panel '%s':", this->alarm_control_panel_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT alarm_control_panel '%s':", LOG_STR_ARG(this->alarm_control_panel_->get_log_name())); LOG_MQTT_COMPONENT(true, true); ESP_LOGCONFIG(TAG, " Supported Features: %" PRIu32 "\n" diff --git a/esphome/components/mqtt/mqtt_binary_sensor.cpp b/esphome/components/mqtt/mqtt_binary_sensor.cpp index 7a75cca6e8..7e9bf9e7bc 100644 --- a/esphome/components/mqtt/mqtt_binary_sensor.cpp +++ b/esphome/components/mqtt/mqtt_binary_sensor.cpp @@ -18,7 +18,7 @@ void MQTTBinarySensorComponent::setup() { } void MQTTBinarySensorComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Binary Sensor '%s':", this->binary_sensor_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Binary Sensor '%s':", LOG_STR_ARG(this->binary_sensor_->get_log_name())); LOG_MQTT_COMPONENT(true, false); } MQTTBinarySensorComponent::MQTTBinarySensorComponent(binary_sensor::BinarySensor *binary_sensor) diff --git a/esphome/components/mqtt/mqtt_button.cpp b/esphome/components/mqtt/mqtt_button.cpp index a04121e2a1..e03bd943d9 100644 --- a/esphome/components/mqtt/mqtt_button.cpp +++ b/esphome/components/mqtt/mqtt_button.cpp @@ -19,13 +19,13 @@ void MQTTButtonComponent::setup() { if (payload == "PRESS") { this->button_->press(); } else { - ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", this->friendly_name_().c_str(), payload.c_str()); + ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", LOG_STR_ARG(this->log_name_()), payload.c_str()); this->status_momentary_warning(5000); } }); } void MQTTButtonComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Button '%s': ", this->button_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Button '%s': ", LOG_STR_ARG(this->button_->get_log_name())); LOG_MQTT_COMPONENT(false, true); } diff --git a/esphome/components/mqtt/mqtt_component.cpp b/esphome/components/mqtt/mqtt_component.cpp index adb5a95828..e51b06ba38 100644 --- a/esphome/components/mqtt/mqtt_component.cpp +++ b/esphome/components/mqtt/mqtt_component.cpp @@ -186,11 +186,11 @@ bool MQTTComponent::send_discovery_() { StringRef discovery_topic = this->get_discovery_topic_to_(discovery_topic_buf, discovery_info); if (discovery_info.clean) { - ESP_LOGV(TAG, "'%s': Cleaning discovery", this->friendly_name_().c_str()); + ESP_LOGV(TAG, "'%s': Cleaning discovery", LOG_STR_ARG(this->log_name_())); return global_mqtt_client->publish(discovery_topic.c_str(), "", 0, this->qos_, true); } - ESP_LOGV(TAG, "'%s': Sending discovery", this->friendly_name_().c_str()); + ESP_LOGV(TAG, "'%s': Sending discovery", LOG_STR_ARG(this->log_name_())); // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) false positive with ArduinoJson return global_mqtt_client->publish_json( @@ -207,7 +207,12 @@ bool MQTTComponent::send_discovery_() { } // Fields from EntityBase - root[MQTT_NAME] = this->get_entity()->has_own_name() ? this->friendly_name_() : StringRef(); + if (this->get_entity()->has_own_name()) { + // ArduinoJson copies flash strings into the document itself + root[MQTT_NAME] = reinterpret_cast(this->get_entity()->get_name_progmem().progmem_ptr()); + } else { + root[MQTT_NAME] = StringRef(); + } if (this->is_disabled_by_default_()) root[MQTT_ENABLED_BY_DEFAULT] = false; @@ -253,9 +258,10 @@ bool MQTTComponent::send_discovery_() { char object_id_buf[OBJECT_ID_MAX_LEN]; StringRef object_id = this->get_default_object_id_to_(object_id_buf); if (discovery_info.unique_id_generator == MQTT_MAC_ADDRESS_UNIQUE_ID_GENERATOR) { + char name_buf[ENTITY_NAME_BUF_SIZE]; char friendly_name_hash[9]; buf_append_printf(friendly_name_hash, sizeof(friendly_name_hash), 0, "%08" PRIx32, - fnv1_hash(this->friendly_name_().c_str())); + fnv1_hash(this->get_entity()->get_name_to(name_buf).c_str())); // Format: mac-component_type-hash (e.g. "aabbccddeeff-sensor-12345678") // MAC (12) + "-" (1) + domain (max 20) + "-" (1) + hash (8) + null (1) = 43 char unique_id[MAC_ADDRESS_BUFFER_SIZE + ESPHOME_DOMAIN_MAX_LEN + 11]; @@ -407,7 +413,11 @@ void MQTTComponent::schedule_resend_state() { this->resend_state_ = true; } bool MQTTComponent::is_connected_() const { return global_mqtt_client->is_connected(); } // Pull these properties from EntityBase if not overridden +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" const StringRef &MQTTComponent::friendly_name_() const { return this->get_entity()->get_name(); } +#pragma GCC diagnostic pop +const LogString *MQTTComponent::log_name_() const { return this->get_entity()->get_log_name(); } StringRef MQTTComponent::get_default_object_id_to_(std::span buf) const { return this->get_entity()->get_object_id_to(buf); } diff --git a/esphome/components/mqtt/mqtt_component.h b/esphome/components/mqtt/mqtt_component.h index 141b5f12b3..300af2b5a4 100644 --- a/esphome/components/mqtt/mqtt_component.h +++ b/esphome/components/mqtt/mqtt_component.h @@ -300,7 +300,9 @@ class MQTTComponent : public Component { */ virtual const EntityBase *get_entity() const = 0; - /// Get the friendly name of this MQTT component. + /// Entity name for a "%s" log argument. + const LogString *log_name_() const; + ESPDEPRECATED("Use log_name_() for logging. Removed in 2027.5.0", "2026.11.0") const StringRef &friendly_name_() const; /// Get the icon field of this component into a stack buffer diff --git a/esphome/components/mqtt/mqtt_cover.cpp b/esphome/components/mqtt/mqtt_cover.cpp index a7da9a1b22..c05c8d1ceb 100644 --- a/esphome/components/mqtt/mqtt_cover.cpp +++ b/esphome/components/mqtt/mqtt_cover.cpp @@ -63,7 +63,7 @@ void MQTTCoverComponent::setup() { } void MQTTCoverComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT cover '%s':", this->cover_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT cover '%s':", LOG_STR_ARG(this->cover_->get_log_name())); auto traits = this->cover_->get_traits(); bool has_command_topic = traits.get_supports_position() || !traits.get_supports_tilt(); LOG_MQTT_COMPONENT(true, has_command_topic); diff --git a/esphome/components/mqtt/mqtt_date.cpp b/esphome/components/mqtt/mqtt_date.cpp index b5f1cf8fb8..43ee3fc2ea 100644 --- a/esphome/components/mqtt/mqtt_date.cpp +++ b/esphome/components/mqtt/mqtt_date.cpp @@ -35,7 +35,7 @@ void MQTTDateComponent::setup() { } void MQTTDateComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Date '%s':", this->date_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Date '%s':", LOG_STR_ARG(this->date_->get_log_name())); LOG_MQTT_COMPONENT(true, true); } diff --git a/esphome/components/mqtt/mqtt_datetime.cpp b/esphome/components/mqtt/mqtt_datetime.cpp index 8275580938..d54e058107 100644 --- a/esphome/components/mqtt/mqtt_datetime.cpp +++ b/esphome/components/mqtt/mqtt_datetime.cpp @@ -46,7 +46,7 @@ void MQTTDateTimeComponent::setup() { } void MQTTDateTimeComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT DateTime '%s':", this->datetime_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT DateTime '%s':", LOG_STR_ARG(this->datetime_->get_log_name())); LOG_MQTT_COMPONENT(true, true); } diff --git a/esphome/components/mqtt/mqtt_event.cpp b/esphome/components/mqtt/mqtt_event.cpp index 4266722ca8..e5484d0316 100644 --- a/esphome/components/mqtt/mqtt_event.cpp +++ b/esphome/components/mqtt/mqtt_event.cpp @@ -28,7 +28,7 @@ void MQTTEventComponent::setup() { } void MQTTEventComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Event '%s': ", this->event_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Event '%s': ", LOG_STR_ARG(this->event_->get_log_name())); ESP_LOGCONFIG(TAG, "Event Types: "); for (const char *event_type : this->event_->get_event_types()) { ESP_LOGCONFIG(TAG, "- %s", event_type); diff --git a/esphome/components/mqtt/mqtt_fan.cpp b/esphome/components/mqtt/mqtt_fan.cpp index 7aa2f8e9d5..b0eebaca55 100644 --- a/esphome/components/mqtt/mqtt_fan.cpp +++ b/esphome/components/mqtt/mqtt_fan.cpp @@ -32,15 +32,15 @@ void MQTTFanComponent::setup() { auto val = parse_on_off(payload.c_str()); switch (val) { case PARSE_ON: - ESP_LOGD(TAG, "'%s' Turning Fan ON.", this->friendly_name_().c_str()); + ESP_LOGD(TAG, "'%s' Turning Fan ON.", LOG_STR_ARG(this->log_name_())); this->state_->turn_on().perform(); break; case PARSE_OFF: - ESP_LOGD(TAG, "'%s' Turning Fan OFF.", this->friendly_name_().c_str()); + ESP_LOGD(TAG, "'%s' Turning Fan OFF.", LOG_STR_ARG(this->log_name_())); this->state_->turn_off().perform(); break; case PARSE_TOGGLE: - ESP_LOGD(TAG, "'%s' Toggling Fan.", this->friendly_name_().c_str()); + ESP_LOGD(TAG, "'%s' Toggling Fan.", LOG_STR_ARG(this->log_name_())); this->state_->toggle().perform(); break; case PARSE_NONE: @@ -56,11 +56,11 @@ void MQTTFanComponent::setup() { auto val = parse_on_off(payload.c_str(), "forward", "reverse"); switch (val) { case PARSE_ON: - ESP_LOGD(TAG, "'%s': Setting direction FORWARD", this->friendly_name_().c_str()); + ESP_LOGD(TAG, "'%s': Setting direction FORWARD", LOG_STR_ARG(this->log_name_())); this->state_->make_call().set_direction(fan::FanDirection::FORWARD).perform(); break; case PARSE_OFF: - ESP_LOGD(TAG, "'%s': Setting direction REVERSE", this->friendly_name_().c_str()); + ESP_LOGD(TAG, "'%s': Setting direction REVERSE", LOG_STR_ARG(this->log_name_())); this->state_->make_call().set_direction(fan::FanDirection::REVERSE).perform(); break; case PARSE_TOGGLE: @@ -83,11 +83,11 @@ void MQTTFanComponent::setup() { auto val = parse_on_off(payload.c_str(), "oscillate_on", "oscillate_off"); switch (val) { case PARSE_ON: - ESP_LOGD(TAG, "'%s': Setting oscillating ON", this->friendly_name_().c_str()); + ESP_LOGD(TAG, "'%s': Setting oscillating ON", LOG_STR_ARG(this->log_name_())); this->state_->make_call().set_oscillating(true).perform(); break; case PARSE_OFF: - ESP_LOGD(TAG, "'%s': Setting oscillating OFF", this->friendly_name_().c_str()); + ESP_LOGD(TAG, "'%s': Setting oscillating OFF", LOG_STR_ARG(this->log_name_())); this->state_->make_call().set_oscillating(false).perform(); break; case PARSE_TOGGLE: @@ -125,7 +125,7 @@ void MQTTFanComponent::setup() { } void MQTTFanComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Fan '%s': ", this->state_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Fan '%s': ", LOG_STR_ARG(this->state_->get_log_name())); LOG_MQTT_COMPONENT(true, true); if (this->state_->get_traits().supports_direction()) { ESP_LOGCONFIG(TAG, @@ -168,7 +168,7 @@ void MQTTFanComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryConfig bool MQTTFanComponent::publish_state() { char topic_buf[MQTT_DEFAULT_TOPIC_MAX_LEN]; const char *state_s = this->state_->state ? "ON" : "OFF"; - ESP_LOGD(TAG, "'%s' Sending state %s.", this->state_->get_name().c_str(), state_s); + ESP_LOGD(TAG, "'%s' Sending state %s.", LOG_STR_ARG(this->state_->get_log_name()), state_s); this->publish(this->get_state_topic_to_(topic_buf), state_s); bool failed = false; if (this->state_->get_traits().supports_direction()) { diff --git a/esphome/components/mqtt/mqtt_light.cpp b/esphome/components/mqtt/mqtt_light.cpp index e1affae8a2..91bd1010a3 100644 --- a/esphome/components/mqtt/mqtt_light.cpp +++ b/esphome/components/mqtt/mqtt_light.cpp @@ -88,7 +88,7 @@ void MQTTJSONLightComponent::send_discovery(JsonObject root, mqtt::SendDiscovery } bool MQTTJSONLightComponent::send_initial_state() { return this->publish_state_(); } void MQTTJSONLightComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Light '%s':", this->state_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Light '%s':", LOG_STR_ARG(this->state_->get_log_name())); LOG_MQTT_COMPONENT(true, true); } diff --git a/esphome/components/mqtt/mqtt_lock.cpp b/esphome/components/mqtt/mqtt_lock.cpp index 8e9a628985..8d8a0e6562 100644 --- a/esphome/components/mqtt/mqtt_lock.cpp +++ b/esphome/components/mqtt/mqtt_lock.cpp @@ -24,7 +24,7 @@ void MQTTLockComponent::setup() { } else if (ESPHOME_strcasecmp_P(payload.c_str(), ESPHOME_PSTR("OPEN")) == 0) { this->lock_->open(); } else { - ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", this->friendly_name_().c_str(), payload.c_str()); + ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", LOG_STR_ARG(this->log_name_()), payload.c_str()); this->status_momentary_warning(5000); } }); @@ -32,7 +32,7 @@ void MQTTLockComponent::setup() { [this](LockState /*state*/) { this->defer(SEND_DEFER_ID, [this]() { this->publish_state(); }); }); } void MQTTLockComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Lock '%s': ", this->lock_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Lock '%s': ", LOG_STR_ARG(this->lock_->get_log_name())); LOG_MQTT_COMPONENT(true, true); } diff --git a/esphome/components/mqtt/mqtt_number.cpp b/esphome/components/mqtt/mqtt_number.cpp index 3b2bebf291..53306ef02e 100644 --- a/esphome/components/mqtt/mqtt_number.cpp +++ b/esphome/components/mqtt/mqtt_number.cpp @@ -33,7 +33,7 @@ void MQTTNumberComponent::setup() { } void MQTTNumberComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Number '%s':", this->number_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Number '%s':", LOG_STR_ARG(this->number_->get_log_name())); LOG_MQTT_COMPONENT(true, false); } diff --git a/esphome/components/mqtt/mqtt_select.cpp b/esphome/components/mqtt/mqtt_select.cpp index 42c0ae002e..892a6a3fbc 100644 --- a/esphome/components/mqtt/mqtt_select.cpp +++ b/esphome/components/mqtt/mqtt_select.cpp @@ -24,7 +24,7 @@ void MQTTSelectComponent::setup() { } void MQTTSelectComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Select '%s':", this->select_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Select '%s':", LOG_STR_ARG(this->select_->get_log_name())); LOG_MQTT_COMPONENT(true, false); } diff --git a/esphome/components/mqtt/mqtt_sensor.cpp b/esphome/components/mqtt/mqtt_sensor.cpp index bdaaa47e8f..794eab5e86 100644 --- a/esphome/components/mqtt/mqtt_sensor.cpp +++ b/esphome/components/mqtt/mqtt_sensor.cpp @@ -25,7 +25,7 @@ void MQTTSensorComponent::setup() { } void MQTTSensorComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Sensor '%s':", this->sensor_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Sensor '%s':", LOG_STR_ARG(this->sensor_->get_log_name())); if (this->get_expire_after() > 0) { ESP_LOGCONFIG(TAG, " Expire After: %" PRIu32 "s", this->get_expire_after() / 1000); } diff --git a/esphome/components/mqtt/mqtt_switch.cpp b/esphome/components/mqtt/mqtt_switch.cpp index 44ce249772..90536c0a2e 100644 --- a/esphome/components/mqtt/mqtt_switch.cpp +++ b/esphome/components/mqtt/mqtt_switch.cpp @@ -28,7 +28,7 @@ void MQTTSwitchComponent::setup() { break; case PARSE_NONE: default: - ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", this->friendly_name_().c_str(), payload.c_str()); + ESP_LOGW(TAG, "'%s': Received unknown status payload: %s", LOG_STR_ARG(this->log_name_()), payload.c_str()); this->status_momentary_warning(5000); break; } @@ -37,7 +37,7 @@ void MQTTSwitchComponent::setup() { [this](bool enabled) { this->defer(SEND_DEFER_ID, [this, enabled]() { this->publish_state(enabled); }); }); } void MQTTSwitchComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Switch '%s': ", this->switch_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Switch '%s': ", LOG_STR_ARG(this->switch_->get_log_name())); LOG_MQTT_COMPONENT(true, true); } diff --git a/esphome/components/mqtt/mqtt_text.cpp b/esphome/components/mqtt/mqtt_text.cpp index dd43a8e2cb..95813a25b3 100644 --- a/esphome/components/mqtt/mqtt_text.cpp +++ b/esphome/components/mqtt/mqtt_text.cpp @@ -29,7 +29,7 @@ void MQTTTextComponent::setup() { } void MQTTTextComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT text '%s':", this->text_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT text '%s':", LOG_STR_ARG(this->text_->get_log_name())); LOG_MQTT_COMPONENT(true, true); } diff --git a/esphome/components/mqtt/mqtt_text_sensor.cpp b/esphome/components/mqtt/mqtt_text_sensor.cpp index d105aaac99..3cf501d054 100644 --- a/esphome/components/mqtt/mqtt_text_sensor.cpp +++ b/esphome/components/mqtt/mqtt_text_sensor.cpp @@ -21,7 +21,7 @@ void MQTTTextSensor::setup() { } void MQTTTextSensor::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Text Sensor '%s':", this->sensor_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Text Sensor '%s':", LOG_STR_ARG(this->sensor_->get_log_name())); LOG_MQTT_COMPONENT(true, false); } diff --git a/esphome/components/mqtt/mqtt_time.cpp b/esphome/components/mqtt/mqtt_time.cpp index 889ee2bf34..f572f88789 100644 --- a/esphome/components/mqtt/mqtt_time.cpp +++ b/esphome/components/mqtt/mqtt_time.cpp @@ -35,7 +35,7 @@ void MQTTTimeComponent::setup() { } void MQTTTimeComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Time '%s':", this->time_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Time '%s':", LOG_STR_ARG(this->time_->get_log_name())); LOG_MQTT_COMPONENT(true, true); } diff --git a/esphome/components/mqtt/mqtt_update.cpp b/esphome/components/mqtt/mqtt_update.cpp index 69b2f64771..29a1821b86 100644 --- a/esphome/components/mqtt/mqtt_update.cpp +++ b/esphome/components/mqtt/mqtt_update.cpp @@ -19,7 +19,7 @@ void MQTTUpdateComponent::setup() { if (payload == "INSTALL") { this->update_->perform(); } else { - ESP_LOGW(TAG, "'%s': Received unknown update payload: %s", this->friendly_name_().c_str(), payload.c_str()); + ESP_LOGW(TAG, "'%s': Received unknown update payload: %s", LOG_STR_ARG(this->log_name_()), payload.c_str()); this->status_momentary_warning(5000); } }); @@ -49,7 +49,7 @@ void MQTTUpdateComponent::send_discovery(JsonObject root, mqtt::SendDiscoveryCon bool MQTTUpdateComponent::send_initial_state() { return this->publish_state(); } void MQTTUpdateComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT Update '%s': ", this->update_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT Update '%s': ", LOG_STR_ARG(this->update_->get_log_name())); LOG_MQTT_COMPONENT(true, true); } diff --git a/esphome/components/mqtt/mqtt_valve.cpp b/esphome/components/mqtt/mqtt_valve.cpp index b41a482de9..7ca3e959b4 100644 --- a/esphome/components/mqtt/mqtt_valve.cpp +++ b/esphome/components/mqtt/mqtt_valve.cpp @@ -51,7 +51,7 @@ void MQTTValveComponent::setup() { } void MQTTValveComponent::dump_config() { - ESP_LOGCONFIG(TAG, "MQTT valve '%s':", this->valve_->get_name().c_str()); + ESP_LOGCONFIG(TAG, "MQTT valve '%s':", LOG_STR_ARG(this->valve_->get_log_name())); auto traits = this->valve_->get_traits(); bool has_command_topic = traits.get_supports_position(); LOG_MQTT_COMPONENT(true, has_command_topic); diff --git a/esphome/components/prometheus/prometheus_handler.cpp b/esphome/components/prometheus/prometheus_handler.cpp index 00c2e04310..502ffa1557 100644 --- a/esphome/components/prometheus/prometheus_handler.cpp +++ b/esphome/components/prometheus/prometheus_handler.cpp @@ -109,18 +109,23 @@ void PrometheusHandler::handleRequest(AsyncWebServerRequest *req) { req->send(stream); } -std::string PrometheusHandler::relabel_id_(EntityBase *obj) { +void PrometheusHandler::print_relabel_id_(AsyncResponseStream *stream, EntityBase *obj) { auto item = relabel_map_id_.find(obj); if (item != relabel_map_id_.end()) { - return item->second; + stream->print(item->second.c_str()); + return; } char object_id_buf[OBJECT_ID_MAX_LEN]; - return obj->get_object_id_to(object_id_buf).str(); + stream->print(obj->get_object_id_to(object_id_buf).c_str()); } -std::string PrometheusHandler::relabel_name_(EntityBase *obj) { +void PrometheusHandler::print_relabel_name_(AsyncResponseStream *stream, EntityBase *obj) { auto item = relabel_map_name_.find(obj); - return item == relabel_map_name_.end() ? obj->get_name() : item->second; + if (item != relabel_map_name_.end()) { + stream->print(item->second.c_str()); + return; + } + stream->print(reinterpret_cast(obj->get_name_progmem().progmem_ptr())); } void PrometheusHandler::add_area_label_(AsyncResponseStream *stream, std::string &area) { @@ -148,12 +153,12 @@ void PrometheusHandler::print_metric_labels_(AsyncResponseStream *stream, Progme std::string &area, std::string &node, std::string &friendly_name) { stream->print(metric_name); stream->print(ESPHOME_F("{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); } // Type-specific implementation @@ -169,21 +174,21 @@ void PrometheusHandler::sensor_row_(AsyncResponseStream *stream, sensor::Sensor if (!std::isnan(obj->state)) { // We have a valid value, output this value stream->print(ESPHOME_F("esphome_sensor_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_sensor_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",unit=\"")); stream->print(obj->get_unit_of_measurement_ref().c_str()); stream->print(ESPHOME_F("\"} ")); @@ -194,12 +199,12 @@ void PrometheusHandler::sensor_row_(AsyncResponseStream *stream, sensor::Sensor } else { // Invalid state stream->print(ESPHOME_F("esphome_sensor_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 1\n")); } } @@ -218,33 +223,33 @@ void PrometheusHandler::binary_sensor_row_(AsyncResponseStream *stream, binary_s if (obj->has_state()) { // We have a valid value, output this value stream->print(ESPHOME_F("esphome_binary_sensor_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_binary_sensor_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); stream->print(obj->state); stream->print(ESPHOME_F("\n")); } else { // Invalid state stream->print(ESPHOME_F("esphome_binary_sensor_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 1\n")); } } @@ -262,33 +267,33 @@ void PrometheusHandler::fan_row_(AsyncResponseStream *stream, fan::Fan *obj, std if (obj->is_internal() && !this->include_internal_) return; stream->print(ESPHOME_F("esphome_fan_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_fan_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); stream->print(obj->state); stream->print(ESPHOME_F("\n")); // Speed if available if (obj->get_traits().supports_speed()) { stream->print(ESPHOME_F("esphome_fan_speed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); stream->print(obj->speed); stream->print(ESPHOME_F("\n")); @@ -296,12 +301,12 @@ void PrometheusHandler::fan_row_(AsyncResponseStream *stream, fan::Fan *obj, std // Oscillation if available if (obj->get_traits().supports_oscillation()) { stream->print(ESPHOME_F("esphome_fan_oscillation{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); stream->print(obj->oscillating); stream->print(ESPHOME_F("\n")); @@ -385,32 +390,32 @@ void PrometheusHandler::cover_row_(AsyncResponseStream *stream, cover::Cover *ob if (!std::isnan(obj->position)) { // We have a valid value, output this value stream->print(ESPHOME_F("esphome_cover_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_cover_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); stream->print(obj->position); stream->print(ESPHOME_F("\n")); if (obj->get_traits().get_supports_tilt()) { stream->print(ESPHOME_F("esphome_cover_tilt{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); stream->print(obj->tilt); stream->print(ESPHOME_F("\n")); @@ -418,12 +423,12 @@ void PrometheusHandler::cover_row_(AsyncResponseStream *stream, cover::Cover *ob } else { // Invalid state stream->print(ESPHOME_F("esphome_cover_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 1\n")); } } @@ -439,21 +444,21 @@ void PrometheusHandler::switch_row_(AsyncResponseStream *stream, switch_::Switch if (obj->is_internal() && !this->include_internal_) return; stream->print(ESPHOME_F("esphome_switch_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_switch_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); stream->print(obj->state); stream->print(ESPHOME_F("\n")); @@ -470,21 +475,21 @@ void PrometheusHandler::lock_row_(AsyncResponseStream *stream, lock::Lock *obj, if (obj->is_internal() && !this->include_internal_) return; stream->print(ESPHOME_F("esphome_lock_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_lock_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); stream->print(obj->state); stream->print(ESPHOME_F("\n")); @@ -504,21 +509,21 @@ void PrometheusHandler::text_sensor_row_(AsyncResponseStream *stream, text_senso if (obj->has_state()) { // We have a valid value, output this value stream->print(ESPHOME_F("esphome_text_sensor_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_text_sensor_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",value=\"")); stream->print(obj->state.c_str()); stream->print(ESPHOME_F("\"} ")); @@ -527,12 +532,12 @@ void PrometheusHandler::text_sensor_row_(AsyncResponseStream *stream, text_senso } else { // Invalid state stream->print(ESPHOME_F("esphome_text_sensor_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 1\n")); } } @@ -551,21 +556,21 @@ void PrometheusHandler::text_row_(AsyncResponseStream *stream, text::Text *obj, if (obj->has_state()) { // We have a valid value, output this value stream->print(ESPHOME_F("esphome_text_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_text_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",value=\"")); stream->print(obj->state.c_str()); stream->print(ESPHOME_F("\"} ")); @@ -574,12 +579,12 @@ void PrometheusHandler::text_row_(AsyncResponseStream *stream, text::Text *obj, } else { // Invalid state stream->print(ESPHOME_F("esphome_text_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 1\n")); } } @@ -598,21 +603,21 @@ void PrometheusHandler::event_row_(AsyncResponseStream *stream, event::Event *ob if (obj->has_event()) { // We have a valid event type, output this value stream->print(ESPHOME_F("esphome_event_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_event_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",last_event_type=\"")); // get_last_event_type() returns StringRef (null-terminated) stream->print(obj->get_last_event_type().c_str()); @@ -622,12 +627,12 @@ void PrometheusHandler::event_row_(AsyncResponseStream *stream, event::Event *ob } else { // No event triggered yet stream->print(ESPHOME_F("esphome_event_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 1\n")); } } @@ -646,33 +651,33 @@ void PrometheusHandler::number_row_(AsyncResponseStream *stream, number::Number if (!std::isnan(obj->state)) { // We have a valid value, output this value stream->print(ESPHOME_F("esphome_number_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_number_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); stream->print(obj->state); stream->print(ESPHOME_F("\n")); } else { // Invalid state stream->print(ESPHOME_F("esphome_number_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 1\n")); } } @@ -690,21 +695,21 @@ void PrometheusHandler::select_row_(AsyncResponseStream *stream, select::Select if (obj->has_state()) { // We have a valid value, output this value stream->print(ESPHOME_F("esphome_select_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_select_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",value=\"")); // c_str() is safe as option values are null-terminated strings from codegen stream->print(obj->current_option().c_str()); @@ -714,12 +719,12 @@ void PrometheusHandler::select_row_(AsyncResponseStream *stream, select::Select } else { // Invalid state stream->print(ESPHOME_F("esphome_select_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 1\n")); } } @@ -737,43 +742,43 @@ void PrometheusHandler::media_player_row_(AsyncResponseStream *stream, media_pla if (obj->is_internal() && !this->include_internal_) return; stream->print(ESPHOME_F("esphome_media_player_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_media_player_state_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",value=\"")); stream->print(media_player::media_player_state_to_string(obj->state)); stream->print(ESPHOME_F("\"} ")); stream->print(ESPHOME_F("1.0")); stream->print(ESPHOME_F("\n")); stream->print(ESPHOME_F("esphome_media_player_volume{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); stream->print(obj->volume); stream->print(ESPHOME_F("\n")); stream->print(ESPHOME_F("esphome_media_player_is_muted{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); if (obj->is_muted()) { stream->print(ESPHOME_F("1.0")); @@ -818,21 +823,21 @@ void PrometheusHandler::update_entity_row_(AsyncResponseStream *stream, update:: if (obj->has_state()) { // We have a valid value, output this value stream->print(ESPHOME_F("esphome_update_entity_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // First update state stream->print(ESPHOME_F("esphome_update_entity_state{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",value=\"")); handle_update_state_(stream, obj->state); stream->print(ESPHOME_F("\"} ")); @@ -840,12 +845,12 @@ void PrometheusHandler::update_entity_row_(AsyncResponseStream *stream, update:: stream->print(ESPHOME_F("\n")); // Next update info stream->print(ESPHOME_F("esphome_update_entity_info{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",current_version=\"")); stream->print(obj->update_info.current_version.c_str()); stream->print(ESPHOME_F("\",latest_version=\"")); @@ -858,12 +863,12 @@ void PrometheusHandler::update_entity_row_(AsyncResponseStream *stream, update:: } else { // Invalid state stream->print(ESPHOME_F("esphome_update_entity_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 1\n")); } } @@ -881,21 +886,21 @@ void PrometheusHandler::valve_row_(AsyncResponseStream *stream, valve::Valve *ob if (obj->is_internal() && !this->include_internal_) return; stream->print(ESPHOME_F("esphome_valve_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} 0\n")); // Data itself stream->print(ESPHOME_F("esphome_valve_operation{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",operation=\"")); stream->print(reinterpret_cast(valve::valve_operation_to_str(obj->current_operation))); stream->print(ESPHOME_F("\"} ")); @@ -904,12 +909,12 @@ void PrometheusHandler::valve_row_(AsyncResponseStream *stream, valve::Valve *ob // Now see if position is supported if (obj->get_traits().get_supports_position()) { stream->print(ESPHOME_F("esphome_valve_position{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\"} ")); stream->print(obj->position); stream->print(ESPHOME_F("\n")); @@ -928,12 +933,12 @@ void PrometheusHandler::climate_setting_row_(AsyncResponseStream *stream, climat std::string &node, std::string &friendly_name, std::string &setting, const LogString *setting_value) { stream->print(ESPHOME_F("esphome_climate_setting{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",category=\"")); stream->print(setting.c_str()); stream->print(ESPHOME_F("\",setting_value=\"")); @@ -951,12 +956,12 @@ void PrometheusHandler::climate_value_row_(AsyncResponseStream *stream, climate: std::string &node, std::string &friendly_name, std::string &category, const char *climate_value) { stream->print(ESPHOME_F("esphome_climate_value{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",category=\"")); stream->print(category.c_str()); stream->print(ESPHOME_F("\"} ")); @@ -968,12 +973,12 @@ void PrometheusHandler::climate_failed_row_(AsyncResponseStream *stream, climate std::string &node, std::string &friendly_name, std::string &category, bool is_failed_value) { stream->print(ESPHOME_F("esphome_climate_failed{id=\"")); - stream->print(relabel_id_(obj).c_str()); + this->print_relabel_id_(stream, obj); add_area_label_(stream, area); add_node_label_(stream, node); add_friendly_name_label_(stream, friendly_name); stream->print(ESPHOME_F("\",name=\"")); - stream->print(relabel_name_(obj).c_str()); + this->print_relabel_name_(stream, obj); stream->print(ESPHOME_F("\",category=\"")); stream->print(category.c_str()); stream->print(ESPHOME_F("\"} ")); diff --git a/esphome/components/prometheus/prometheus_handler.h b/esphome/components/prometheus/prometheus_handler.h index 9dcbf7e686..a5a83995bd 100644 --- a/esphome/components/prometheus/prometheus_handler.h +++ b/esphome/components/prometheus/prometheus_handler.h @@ -63,8 +63,8 @@ class PrometheusHandler final : public AsyncWebHandler, public Component { } protected: - std::string relabel_id_(EntityBase *obj); - std::string relabel_name_(EntityBase *obj); + void print_relabel_id_(AsyncResponseStream *stream, EntityBase *obj); + void print_relabel_name_(AsyncResponseStream *stream, EntityBase *obj); void add_area_label_(AsyncResponseStream *stream, std::string &area); void add_node_label_(AsyncResponseStream *stream, std::string &node); void add_friendly_name_label_(AsyncResponseStream *stream, std::string &friendly_name); diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index b0da010561..094159a7e0 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -218,7 +218,7 @@ EntityMatchResult UrlMatch::match_entity(EntityBase *entity) const { #endif // Match by entity name - if (this->id == entity->get_name()) { + if (entity->name_equals(this->id)) { result.matched = true; } @@ -651,9 +651,7 @@ void WebServer::handle_js_request(AsyncWebServerRequest *request) { // Build unique id as: {domain}/{device_name}/{entity_name} or {domain}/{entity_name} // Uses names (not object_id) to avoid UTF-8 collision issues static void set_json_id(JsonObject root, EntityBase *obj, const char *prefix, JsonDetail start_config) { - const StringRef &name = obj->get_name(); size_t prefix_len = strlen(prefix); - size_t name_len = name.size(); #ifdef USE_DEVICES Device *device = obj->get_device(); @@ -683,13 +681,20 @@ static void set_json_id(JsonObject root, EntityBase *obj, const char *prefix, Js *p++ = '/'; } #endif - memcpy(p, name.c_str(), name_len); - p[name_len] = '\0'; +#ifdef USE_ESP8266 + const char *name = p; +#endif + obj->write_name_to(p, id_buf + ID_BUF_SIZE - p); root[ESPHOME_F("id")] = static_cast(id_buf); if (start_config == DETAIL_ALL) { root[ESPHOME_F("domain")] = linked(prefix, prefix_len); - root[ESPHOME_F("name")] = linked(name); +#ifdef USE_ESP8266 + root[ESPHOME_F("name")] = name; // in id_buf on the stack, so copied +#else + const StringRef &ram_name = obj->get_name_progmem().ram_ref(); + root[ESPHOME_F("name")] = linked(ram_name.c_str(), ram_name.size()); +#endif #ifdef USE_DEVICES if (device_name) { root[ESPHOME_F("device")] = linked(device_name, device_len); diff --git a/esphome/components/web_server/web_server_v1.cpp b/esphome/components/web_server/web_server_v1.cpp index 08654e353a..e49cb76ffa 100644 --- a/esphome/components/web_server/web_server_v1.cpp +++ b/esphome/components/web_server/web_server_v1.cpp @@ -42,8 +42,10 @@ void write_row(AsyncResponseStream *stream, EntityBase *obj, const std::string & // Add data attributes for hierarchical URL support stream->print("\" data-domain=\""); stream->print(klass.c_str()); + char name_buf[ENTITY_NAME_BUF_SIZE]; + const char *name = obj->get_name_to(name_buf).c_str(); stream->print("\" data-name=\""); - write_html_escaped(stream, obj->get_name().c_str()); + write_html_escaped(stream, name); #ifdef USE_DEVICES Device *device = obj->get_device(); if (device != nullptr) { @@ -59,7 +61,7 @@ void write_row(AsyncResponseStream *stream, EntityBase *obj, const std::string & stream->print("] "); } #endif - write_html_escaped(stream, obj->get_name().c_str()); + write_html_escaped(stream, name); stream->print(""); stream->print(action.c_str()); if (action_func) {