mirror of
https://github.com/esphome/esphome.git
synced 2024-12-19 16:07:47 +01:00
[opentherm] Fix out of memory errors on ESP8266 (#7835)
This commit is contained in:
parent
e6da55b925
commit
39cbc6b183
@ -138,7 +138,7 @@ OpenthermHub::OpenthermHub() : Component(), in_pin_{}, out_pin_{} {}
|
|||||||
void OpenthermHub::process_response(OpenthermData &data) {
|
void OpenthermHub::process_response(OpenthermData &data) {
|
||||||
ESP_LOGD(TAG, "Received OpenTherm response with id %d (%s)", data.id,
|
ESP_LOGD(TAG, "Received OpenTherm response with id %d (%s)", data.id,
|
||||||
this->opentherm_->message_id_to_str((MessageId) 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) {
|
switch (data.id) {
|
||||||
OPENTHERM_SENSOR_MESSAGE_HANDLERS(OPENTHERM_MESSAGE_RESPONSE_MESSAGE, OPENTHERM_MESSAGE_RESPONSE_ENTITY, ,
|
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,
|
ESP_LOGD(TAG, "Sending request with id %d (%s)", request.id,
|
||||||
this->opentherm_->message_id_to_str((MessageId) 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
|
// Send the request
|
||||||
this->last_conversation_start_ = millis();
|
this->last_conversation_start_ = millis();
|
||||||
this->opentherm_->send(request);
|
this->opentherm_->send(request);
|
||||||
@ -340,19 +340,18 @@ void OpenthermHub::stop_opentherm_() {
|
|||||||
this->opentherm_->stop();
|
this->opentherm_->stop();
|
||||||
this->last_conversation_end_ = millis();
|
this->last_conversation_end_ = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenthermHub::handle_protocol_write_error_() {
|
void OpenthermHub::handle_protocol_write_error_() {
|
||||||
ESP_LOGW(TAG, "Error while sending request: %s",
|
ESP_LOGW(TAG, "Error while sending request: %s",
|
||||||
this->opentherm_->operation_mode_to_str(this->opentherm_->get_mode()));
|
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_() {
|
void OpenthermHub::handle_protocol_read_error_() {
|
||||||
OpenThermError error;
|
OpenThermError error;
|
||||||
this->opentherm_->get_protocol_error(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_() {
|
void OpenthermHub::handle_timeout_error_() {
|
||||||
ESP_LOGW(TAG, "Receive response timed out at a protocol level");
|
ESP_LOGW(TAG, "Receive response timed out at a protocol level");
|
||||||
this->stop_opentherm_();
|
this->stop_opentherm_();
|
||||||
|
@ -15,15 +15,11 @@
|
|||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#endif
|
#endif
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
|
||||||
#include <bitset>
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace opentherm {
|
namespace opentherm {
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::bitset;
|
|
||||||
using std::stringstream;
|
|
||||||
using std::to_string;
|
using std::to_string;
|
||||||
|
|
||||||
static const char *const TAG = "opentherm";
|
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) {
|
void OpenTherm::debug_data(OpenthermData &data) {
|
||||||
stringstream result;
|
ESP_LOGD(TAG, "%s %s %s %s", format_bin(data.type).c_str(), format_bin(data.id).c_str(),
|
||||||
result << bitset<8>(data.type) << " " << bitset<8>(data.id) << " " << bitset<8>(data.valueHB) << " "
|
format_bin(data.valueHB).c_str(), format_bin(data.valueLB).c_str());
|
||||||
<< bitset<8>(data.valueLB) << "\n";
|
ESP_LOGD(TAG, "type: %s; id: %s; HB: %s; LB: %s; uint_16: %s; float: %s",
|
||||||
result << "type: " << this->message_type_to_str((MessageType) data.type) << "; ";
|
this->message_type_to_str((MessageType) data.type), to_string(data.id).c_str(),
|
||||||
result << "id: " << to_string(data.id) << "; ";
|
to_string(data.valueHB).c_str(), to_string(data.valueLB).c_str(), to_string(data.u16()).c_str(),
|
||||||
result << "HB: " << to_string(data.valueHB) << "; ";
|
to_string(data.f88()).c_str());
|
||||||
result << "LB: " << to_string(data.valueLB) << "; ";
|
|
||||||
result << "uint_16: " << to_string(data.u16()) << "; ";
|
|
||||||
result << "float: " << to_string(data.f88());
|
|
||||||
|
|
||||||
return result.str();
|
|
||||||
}
|
}
|
||||||
std::string OpenTherm::debug_error(OpenThermError &error) {
|
void OpenTherm::debug_error(OpenThermError &error) const {
|
||||||
stringstream result;
|
ESP_LOGD(TAG, "data: %s; clock: %s; capture: %s; bit_pos: %s", format_hex(error.data).c_str(),
|
||||||
result << "type: " << this->protocol_error_to_to_str(error.error_type) << "; ";
|
to_string(clock_).c_str(), format_bin(error.capture).c_str(), to_string(error.bit_pos).c_str());
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float OpenthermData::f88() { return ((float) this->s16()) / 256.0; }
|
float OpenthermData::f88() { return ((float) this->s16()) / 256.0; }
|
||||||
|
@ -8,10 +8,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <sstream>
|
|
||||||
#include <iomanip>
|
|
||||||
#include "esphome/core/hal.h"
|
#include "esphome/core/hal.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
#if defined(ESP32) || defined(USE_ESP_IDF)
|
#if defined(ESP32) || defined(USE_ESP_IDF)
|
||||||
#include "driver/timer.h"
|
#include "driver/timer.h"
|
||||||
@ -318,8 +317,8 @@ class OpenTherm {
|
|||||||
|
|
||||||
OperationMode get_mode() { return mode_; }
|
OperationMode get_mode() { return mode_; }
|
||||||
|
|
||||||
std::string debug_data(OpenthermData &data);
|
void debug_data(OpenthermData &data);
|
||||||
std::string debug_error(OpenThermError &error);
|
void debug_error(OpenThermError &error) const;
|
||||||
|
|
||||||
const char *protocol_error_to_to_str(ProtocolErrorType error_type);
|
const char *protocol_error_to_to_str(ProtocolErrorType error_type);
|
||||||
const char *message_type_to_str(MessageType message_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_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) {
|
ParseOnOffState parse_on_off(const char *str, const char *on, const char *off) {
|
||||||
if (on == nullptr && strcasecmp(str, "on") == 0)
|
if (on == nullptr && strcasecmp(str, "on") == 0)
|
||||||
return PARSE_ON;
|
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));
|
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().
|
/// Return values for parse_on_off().
|
||||||
enum ParseOnOffState {
|
enum ParseOnOffState {
|
||||||
PARSE_NONE = 0,
|
PARSE_NONE = 0,
|
||||||
|
Loading…
Reference in New Issue
Block a user