From db2128a3447daaf19ad26f4cb792f07b4075627c Mon Sep 17 00:00:00 2001 From: Oxan van Leeuwen Date: Sun, 28 Nov 2021 20:00:29 +0100 Subject: [PATCH] Fix parsing numbers in Anova (#2816) --- esphome/components/anova/anova_base.cpp | 6 +++--- esphome/core/helpers.cpp | 5 +++++ esphome/core/helpers.h | 6 ++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/esphome/components/anova/anova_base.cpp b/esphome/components/anova/anova_base.cpp index dcef75e483..cb877bef35 100644 --- a/esphome/components/anova/anova_base.cpp +++ b/esphome/components/anova/anova_base.cpp @@ -104,21 +104,21 @@ void AnovaCodec::decode(const uint8_t *data, uint16_t length) { break; } case READ_TARGET_TEMPERATURE: { - this->target_temp_ = parse_number(buf, sizeof(buf)).value_or(0.0f); + this->target_temp_ = parse_number(str_until(buf, '\r')).value_or(0.0f); if (this->fahrenheit_) this->target_temp_ = ftoc(this->target_temp_); this->has_target_temp_ = true; break; } case SET_TARGET_TEMPERATURE: { - this->target_temp_ = parse_number(buf, sizeof(buf)).value_or(0.0f); + this->target_temp_ = parse_number(str_until(buf, '\r')).value_or(0.0f); if (this->fahrenheit_) this->target_temp_ = ftoc(this->target_temp_); this->has_target_temp_ = true; break; } case READ_CURRENT_TEMPERATURE: { - this->current_temp_ = parse_number(buf, sizeof(buf)).value_or(0.0f); + this->current_temp_ = parse_number(str_until(buf, '\r')).value_or(0.0f); if (this->fahrenheit_) this->current_temp_ = ftoc(this->current_temp_); this->has_current_temp_ = true; diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index 27608a84c1..cfc1c74145 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -444,6 +444,11 @@ IRAM_ATTR InterruptLock::~InterruptLock() { portENABLE_INTERRUPTS(); } std::string str_truncate(const std::string &str, size_t length) { return str.length() > length ? str.substr(0, length) : str; } +std::string str_until(const char *str, char ch) { + char *pos = strchr(str, ch); + return pos == nullptr ? std::string(str) : std::string(str, pos - str); +} +std::string str_until(const std::string &str, char ch) { return str.substr(0, str.find(ch)); } std::string str_snake_case(const std::string &str) { std::string result; result.resize(str.length()); diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 9cdbf7ca16..7718c5f1b2 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -351,6 +351,12 @@ template::value, int> = 0> constexpr /// Truncate a string to a specific length. std::string str_truncate(const std::string &str, size_t length); +/// Extract the part of the string until either the first occurence of the specified character, or the end (requires str +/// to be null-terminated). +std::string str_until(const char *str, char ch); +/// Extract the part of the string until either the first occurence of the specified character, or the end. +std::string str_until(const std::string &str, char ch); + /// Convert the string to snake case (lowercase with underscores). std::string str_snake_case(const std::string &str);