mirror of
https://github.com/esphome/esphome.git
synced 2026-02-05 23:33:05 +08:00
[mqtt] Avoid intermediate string allocations in publish calls (#13174)
This commit is contained in:
@@ -13,13 +13,13 @@ bool CustomMQTTDevice::publish(const std::string &topic, const std::string &payl
|
||||
}
|
||||
bool CustomMQTTDevice::publish(const std::string &topic, float value, int8_t number_decimals) {
|
||||
char buf[VALUE_ACCURACY_MAX_LEN];
|
||||
value_accuracy_to_buf(buf, value, number_decimals);
|
||||
return this->publish(topic, buf);
|
||||
size_t len = value_accuracy_to_buf(buf, value, number_decimals);
|
||||
return global_mqtt_client->publish(topic, buf, len);
|
||||
}
|
||||
bool CustomMQTTDevice::publish(const std::string &topic, int value) {
|
||||
char buffer[24];
|
||||
sprintf(buffer, "%d", value);
|
||||
return this->publish(topic, buffer);
|
||||
int len = snprintf(buffer, sizeof(buffer), "%d", value);
|
||||
return global_mqtt_client->publish(topic, buffer, len);
|
||||
}
|
||||
bool CustomMQTTDevice::publish_json(const std::string &topic, const json::json_build_t &f, uint8_t qos, bool retain) {
|
||||
return global_mqtt_client->publish_json(topic, f, qos, retain);
|
||||
|
||||
@@ -292,36 +292,37 @@ bool MQTTClimateComponent::publish_state_() {
|
||||
int8_t target_accuracy = traits.get_target_temperature_accuracy_decimals();
|
||||
int8_t current_accuracy = traits.get_current_temperature_accuracy_decimals();
|
||||
char payload[VALUE_ACCURACY_MAX_LEN];
|
||||
size_t len;
|
||||
if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_TEMPERATURE) &&
|
||||
!std::isnan(this->device_->current_temperature)) {
|
||||
value_accuracy_to_buf(payload, this->device_->current_temperature, current_accuracy);
|
||||
if (!this->publish(this->get_current_temperature_state_topic(), payload))
|
||||
len = value_accuracy_to_buf(payload, this->device_->current_temperature, current_accuracy);
|
||||
if (!this->publish(this->get_current_temperature_state_topic(), payload, len))
|
||||
success = false;
|
||||
}
|
||||
if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_TWO_POINT_TARGET_TEMPERATURE |
|
||||
climate::CLIMATE_REQUIRES_TWO_POINT_TARGET_TEMPERATURE)) {
|
||||
value_accuracy_to_buf(payload, this->device_->target_temperature_low, target_accuracy);
|
||||
if (!this->publish(this->get_target_temperature_low_state_topic(), payload))
|
||||
len = value_accuracy_to_buf(payload, this->device_->target_temperature_low, target_accuracy);
|
||||
if (!this->publish(this->get_target_temperature_low_state_topic(), payload, len))
|
||||
success = false;
|
||||
value_accuracy_to_buf(payload, this->device_->target_temperature_high, target_accuracy);
|
||||
if (!this->publish(this->get_target_temperature_high_state_topic(), payload))
|
||||
len = value_accuracy_to_buf(payload, this->device_->target_temperature_high, target_accuracy);
|
||||
if (!this->publish(this->get_target_temperature_high_state_topic(), payload, len))
|
||||
success = false;
|
||||
} else {
|
||||
value_accuracy_to_buf(payload, this->device_->target_temperature, target_accuracy);
|
||||
if (!this->publish(this->get_target_temperature_state_topic(), payload))
|
||||
len = value_accuracy_to_buf(payload, this->device_->target_temperature, target_accuracy);
|
||||
if (!this->publish(this->get_target_temperature_state_topic(), payload, len))
|
||||
success = false;
|
||||
}
|
||||
|
||||
if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_CURRENT_HUMIDITY) &&
|
||||
!std::isnan(this->device_->current_humidity)) {
|
||||
value_accuracy_to_buf(payload, this->device_->current_humidity, 0);
|
||||
if (!this->publish(this->get_current_humidity_state_topic(), payload))
|
||||
len = value_accuracy_to_buf(payload, this->device_->current_humidity, 0);
|
||||
if (!this->publish(this->get_current_humidity_state_topic(), payload, len))
|
||||
success = false;
|
||||
}
|
||||
if (traits.has_feature_flags(climate::CLIMATE_SUPPORTS_TARGET_HUMIDITY) &&
|
||||
!std::isnan(this->device_->target_humidity)) {
|
||||
value_accuracy_to_buf(payload, this->device_->target_humidity, 0);
|
||||
if (!this->publish(this->get_target_humidity_state_topic(), payload))
|
||||
len = value_accuracy_to_buf(payload, this->device_->target_humidity, 0);
|
||||
if (!this->publish(this->get_target_humidity_state_topic(), payload, len))
|
||||
success = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,9 +106,13 @@ std::string MQTTComponent::get_command_topic_() const {
|
||||
}
|
||||
|
||||
bool MQTTComponent::publish(const std::string &topic, const std::string &payload) {
|
||||
return this->publish(topic, payload.data(), payload.size());
|
||||
}
|
||||
|
||||
bool MQTTComponent::publish(const std::string &topic, const char *payload, size_t payload_length) {
|
||||
if (topic.empty())
|
||||
return false;
|
||||
return global_mqtt_client->publish(topic, payload, this->qos_, this->retain_);
|
||||
return global_mqtt_client->publish(topic, payload, payload_length, this->qos_, this->retain_);
|
||||
}
|
||||
|
||||
bool MQTTComponent::publish_json(const std::string &topic, const json::json_build_t &f) {
|
||||
|
||||
@@ -140,6 +140,14 @@ class MQTTComponent : public Component {
|
||||
*/
|
||||
bool publish(const std::string &topic, const std::string &payload);
|
||||
|
||||
/** Send a MQTT message.
|
||||
*
|
||||
* @param topic The topic.
|
||||
* @param payload The payload buffer.
|
||||
* @param payload_length The length of the payload.
|
||||
*/
|
||||
bool publish(const std::string &topic, const char *payload, size_t payload_length);
|
||||
|
||||
/** Construct and send a JSON MQTT message.
|
||||
*
|
||||
* @param topic The topic.
|
||||
|
||||
@@ -99,14 +99,14 @@ bool MQTTCoverComponent::publish_state() {
|
||||
bool success = true;
|
||||
if (traits.get_supports_position()) {
|
||||
char pos[VALUE_ACCURACY_MAX_LEN];
|
||||
value_accuracy_to_buf(pos, roundf(this->cover_->position * 100), 0);
|
||||
if (!this->publish(this->get_position_state_topic(), pos))
|
||||
size_t len = value_accuracy_to_buf(pos, roundf(this->cover_->position * 100), 0);
|
||||
if (!this->publish(this->get_position_state_topic(), pos, len))
|
||||
success = false;
|
||||
}
|
||||
if (traits.get_supports_tilt()) {
|
||||
char pos[VALUE_ACCURACY_MAX_LEN];
|
||||
value_accuracy_to_buf(pos, roundf(this->cover_->tilt * 100), 0);
|
||||
if (!this->publish(this->get_tilt_state_topic(), pos))
|
||||
size_t len = value_accuracy_to_buf(pos, roundf(this->cover_->tilt * 100), 0);
|
||||
if (!this->publish(this->get_tilt_state_topic(), pos, len))
|
||||
success = false;
|
||||
}
|
||||
const char *state_s = this->cover_->current_operation == COVER_OPERATION_OPENING ? "opening"
|
||||
|
||||
@@ -174,8 +174,9 @@ bool MQTTFanComponent::publish_state() {
|
||||
}
|
||||
auto traits = this->state_->get_traits();
|
||||
if (traits.supports_speed()) {
|
||||
std::string payload = to_string(this->state_->speed);
|
||||
bool success = this->publish(this->get_speed_level_state_topic(), payload);
|
||||
char buf[12];
|
||||
int len = snprintf(buf, sizeof(buf), "%d", this->state_->speed);
|
||||
bool success = this->publish(this->get_speed_level_state_topic(), buf, len);
|
||||
failed = failed || !success;
|
||||
}
|
||||
return !failed;
|
||||
|
||||
@@ -80,11 +80,11 @@ bool MQTTSensorComponent::send_initial_state() {
|
||||
}
|
||||
bool MQTTSensorComponent::publish_state(float value) {
|
||||
if (mqtt::global_mqtt_client->is_publish_nan_as_none() && std::isnan(value))
|
||||
return this->publish(this->get_state_topic_(), "None");
|
||||
return this->publish(this->get_state_topic_(), "None", 4);
|
||||
int8_t accuracy = this->sensor_->get_accuracy_decimals();
|
||||
char buf[VALUE_ACCURACY_MAX_LEN];
|
||||
value_accuracy_to_buf(buf, value, accuracy);
|
||||
return this->publish(this->get_state_topic_(), buf);
|
||||
size_t len = value_accuracy_to_buf(buf, value, accuracy);
|
||||
return this->publish(this->get_state_topic_(), buf, len);
|
||||
}
|
||||
|
||||
} // namespace esphome::mqtt
|
||||
|
||||
@@ -74,8 +74,8 @@ bool MQTTValveComponent::publish_state() {
|
||||
bool success = true;
|
||||
if (traits.get_supports_position()) {
|
||||
char pos[VALUE_ACCURACY_MAX_LEN];
|
||||
value_accuracy_to_buf(pos, roundf(this->valve_->position * 100), 0);
|
||||
if (!this->publish(this->get_position_state_topic(), pos))
|
||||
size_t len = value_accuracy_to_buf(pos, roundf(this->valve_->position * 100), 0);
|
||||
if (!this->publish(this->get_position_state_topic(), pos, len))
|
||||
success = false;
|
||||
}
|
||||
const char *state_s = this->valve_->current_operation == VALVE_OPERATION_OPENING ? "opening"
|
||||
|
||||
Reference in New Issue
Block a user