mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 09:18:00 +01:00
[opentherm] Fix out of memory errors on ESP8266 (#7835)
This commit is contained in:
parent
cf835d1580
commit
89ecfc2004
5 changed files with 39 additions and 37 deletions
|
@ -138,7 +138,7 @@ OpenthermHub::OpenthermHub() : Component(), in_pin_{}, out_pin_{} {}
|
|||
void OpenthermHub::process_response(OpenthermData &data) {
|
||||
ESP_LOGD(TAG, "Received OpenTherm response with id %d (%s)", data.id,
|
||||
this->opentherm_->message_id_to_str((MessageId) data.id));
|
||||
ESP_LOGD(TAG, "%s", this->opentherm_->debug_data(data).c_str());
|
||||
this->opentherm_->debug_data(data);
|
||||
|
||||
switch (data.id) {
|
||||
OPENTHERM_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_RESPONSE_MESSAGE, OPENTHERM_MESSAGE_RESPONSE_ENTITY, ,
|
||||
|
@ -315,7 +315,7 @@ void OpenthermHub::start_conversation_() {
|
|||
|
||||
ESP_LOGD(TAG, "Sending request with id %d (%s)", request.id,
|
||||
this->opentherm_->message_id_to_str((MessageId) request.id));
|
||||
ESP_LOGD(TAG, "%s", this->opentherm_->debug_data(request).c_str());
|
||||
this->opentherm_->debug_data(request);
|
||||
// Send the request
|
||||
this->last_conversation_start_ = millis();
|
||||
this->opentherm_->send(request);
|
||||
|
@ -340,19 +340,18 @@ void OpenthermHub::stop_opentherm_() {
|
|||
this->opentherm_->stop();
|
||||
this->last_conversation_end_ = millis();
|
||||
}
|
||||
|
||||
void OpenthermHub::handle_protocol_write_error_() {
|
||||
ESP_LOGW(TAG, "Error while sending request: %s",
|
||||
this->opentherm_->operation_mode_to_str(this->opentherm_->get_mode()));
|
||||
ESP_LOGW(TAG, "%s", this->opentherm_->debug_data(this->last_request_).c_str());
|
||||
this->opentherm_->debug_data(this->last_request_);
|
||||
}
|
||||
|
||||
void OpenthermHub::handle_protocol_read_error_() {
|
||||
OpenThermError error;
|
||||
this->opentherm_->get_protocol_error(error);
|
||||
ESP_LOGW(TAG, "Protocol error occured while receiving response: %s", this->opentherm_->debug_error(error).c_str());
|
||||
ESP_LOGW(TAG, "Protocol error occured while receiving response: %s",
|
||||
this->opentherm_->protocol_error_to_to_str(error.error_type));
|
||||
this->opentherm_->debug_error(error);
|
||||
}
|
||||
|
||||
void OpenthermHub::handle_timeout_error_() {
|
||||
ESP_LOGW(TAG, "Receive response timed out at a protocol level");
|
||||
this->stop_opentherm_();
|
||||
|
|
|
@ -15,15 +15,11 @@
|
|||
#include "Arduino.h"
|
||||
#endif
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <bitset>
|
||||
|
||||
namespace esphome {
|
||||
namespace opentherm {
|
||||
|
||||
using std::string;
|
||||
using std::bitset;
|
||||
using std::stringstream;
|
||||
using std::to_string;
|
||||
|
||||
static const char *const TAG = "opentherm";
|
||||
|
@ -545,29 +541,17 @@ const char *OpenTherm::message_id_to_str(MessageId id) {
|
|||
}
|
||||
}
|
||||
|
||||
string OpenTherm::debug_data(OpenthermData &data) {
|
||||
stringstream result;
|
||||
result << bitset<8>(data.type) << " " << bitset<8>(data.id) << " " << bitset<8>(data.valueHB) << " "
|
||||
<< bitset<8>(data.valueLB) << "\n";
|
||||
result << "type: " << this->message_type_to_str((MessageType) data.type) << "; ";
|
||||
result << "id: " << to_string(data.id) << "; ";
|
||||
result << "HB: " << to_string(data.valueHB) << "; ";
|
||||
result << "LB: " << to_string(data.valueLB) << "; ";
|
||||
result << "uint_16: " << to_string(data.u16()) << "; ";
|
||||
result << "float: " << to_string(data.f88());
|
||||
|
||||
return result.str();
|
||||
void OpenTherm::debug_data(OpenthermData &data) {
|
||||
ESP_LOGD(TAG, "%s %s %s %s", format_bin(data.type).c_str(), format_bin(data.id).c_str(),
|
||||
format_bin(data.valueHB).c_str(), format_bin(data.valueLB).c_str());
|
||||
ESP_LOGD(TAG, "type: %s; id: %s; HB: %s; LB: %s; uint_16: %s; float: %s",
|
||||
this->message_type_to_str((MessageType) data.type), to_string(data.id).c_str(),
|
||||
to_string(data.valueHB).c_str(), to_string(data.valueLB).c_str(), to_string(data.u16()).c_str(),
|
||||
to_string(data.f88()).c_str());
|
||||
}
|
||||
std::string OpenTherm::debug_error(OpenThermError &error) {
|
||||
stringstream result;
|
||||
result << "type: " << this->protocol_error_to_to_str(error.error_type) << "; ";
|
||||
result << "data: ";
|
||||
result << format_hex(error.data);
|
||||
result << "; clock: " << to_string(clock_);
|
||||
result << "; capture: " << bitset<32>(error.capture);
|
||||
result << "; bit_pos: " << to_string(error.bit_pos);
|
||||
|
||||
return result.str();
|
||||
void OpenTherm::debug_error(OpenThermError &error) const {
|
||||
ESP_LOGD(TAG, "data: %s; clock: %s; capture: %s; bit_pos: %s", format_hex(error.data).c_str(),
|
||||
to_string(clock_).c_str(), format_bin(error.capture).c_str(), to_string(error.bit_pos).c_str());
|
||||
}
|
||||
|
||||
float OpenthermData::f88() { return ((float) this->s16()) / 256.0; }
|
||||
|
|
|
@ -8,10 +8,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
#if defined(ESP32) || defined(USE_ESP_IDF)
|
||||
#include "driver/timer.h"
|
||||
|
@ -318,8 +317,8 @@ class OpenTherm {
|
|||
|
||||
OperationMode get_mode() { return mode_; }
|
||||
|
||||
std::string debug_data(OpenthermData &data);
|
||||
std::string debug_error(OpenThermError &error);
|
||||
void debug_data(OpenthermData &data);
|
||||
void debug_error(OpenThermError &error) const;
|
||||
|
||||
const char *protocol_error_to_to_str(ProtocolErrorType error_type);
|
||||
const char *message_type_to_str(MessageType message_type);
|
||||
|
|
|
@ -397,6 +397,18 @@ std::string format_hex_pretty(const uint16_t *data, size_t length) {
|
|||
}
|
||||
std::string format_hex_pretty(const std::vector<uint16_t> &data) { return format_hex_pretty(data.data(), data.size()); }
|
||||
|
||||
std::string format_bin(const uint8_t *data, size_t length) {
|
||||
std::string result;
|
||||
result.resize(length * 8);
|
||||
for (size_t byte_idx = 0; byte_idx < length; byte_idx++) {
|
||||
for (size_t bit_idx = 0; bit_idx < 8; bit_idx++) {
|
||||
result[byte_idx * 8 + bit_idx] = ((data[byte_idx] >> (7 - bit_idx)) & 1) + '0';
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ParseOnOffState parse_on_off(const char *str, const char *on, const char *off) {
|
||||
if (on == nullptr && strcasecmp(str, "on") == 0)
|
||||
return PARSE_ON;
|
||||
|
|
|
@ -420,6 +420,14 @@ template<typename T, enable_if_t<std::is_unsigned<T>::value, int> = 0> std::stri
|
|||
return format_hex_pretty(reinterpret_cast<uint8_t *>(&val), sizeof(T));
|
||||
}
|
||||
|
||||
/// Format the byte array \p data of length \p len in binary.
|
||||
std::string format_bin(const uint8_t *data, size_t length);
|
||||
/// Format an unsigned integer in binary, starting with the most significant byte.
|
||||
template<typename T, enable_if_t<std::is_unsigned<T>::value, int> = 0> std::string format_bin(T val) {
|
||||
val = convert_big_endian(val);
|
||||
return format_bin(reinterpret_cast<uint8_t *>(&val), sizeof(T));
|
||||
}
|
||||
|
||||
/// Return values for parse_on_off().
|
||||
enum ParseOnOffState {
|
||||
PARSE_NONE = 0,
|
||||
|
|
Loading…
Reference in a new issue