Compare commits

..

No commits in common. "c9bbbd574ca1f637ba5263e9c07ded11816e7ee2" and "81bbd19c091ff4b650d5dfbef83ccbf866d917c6" have entirely different histories.

4 changed files with 65 additions and 108 deletions

View File

@ -5,7 +5,8 @@
#include <cmath> #include <cmath>
#include <cstring> #include <cstring>
#include <cstdio> #include <sstream>
#include <iomanip>
#include <algorithm> #include <algorithm>
namespace esphome { namespace esphome {
@ -65,11 +66,7 @@ size_t DlmsParser::parse(const uint8_t *buffer, size_t length, DlmsDataCallback
// First byte after flag should be the data type (usually Structure or Array) // First byte after flag should be the data type (usually Structure or Array)
uint8_t start_type = this->read_byte_(); uint8_t start_type = this->read_byte_();
if (start_type != DLMS_DATA_TYPE_STRUCTURE && start_type != DLMS_DATA_TYPE_ARRAY) { if (start_type != DLMS_DATA_TYPE_STRUCTURE && start_type != DLMS_DATA_TYPE_ARRAY) {
if (this->show_log_) { if (this->show_log_) ESP_LOGW(TAG, "Expected STRUCTURE or ARRAY after header, found type %02X at position %zu", start_type, this->pos_ - 1);
ESP_LOGW(TAG, "Expected STRUCTURE or ARRAY after header, found type %02X at position %zu",
start_type, this->pos_ - 1);
}
return 0; return 0;
} }
@ -79,10 +76,7 @@ size_t DlmsParser::parse(const uint8_t *buffer, size_t length, DlmsDataCallback
ESP_LOGV(TAG, "Some errors occurred parsing DLMS data, or unexpected end of buffer."); ESP_LOGV(TAG, "Some errors occurred parsing DLMS data, or unexpected end of buffer.");
} }
if (this->show_log_) { if (this->show_log_) ESP_LOGD(TAG, "Parsing completed. Processed %zu bytes, found %zu objects", this->pos_, this->objects_found_);
ESP_LOGD(TAG, "Parsing completed. Processed %zu bytes, found %zu objects", this->pos_, this->objects_found_);
}
return this->objects_found_; return this->objects_found_;
} }
@ -256,11 +250,7 @@ bool DlmsParser::parse_sequence_(uint8_t type, uint8_t depth) {
} }
if (this->pos_ >= this->buffer_len_) { if (this->pos_ >= this->buffer_len_) {
if (this->show_log_) { if (this->show_log_) ESP_LOGV(TAG, "Unexpected end while reading element %d of %s", elements_consumed + 1, type == DLMS_DATA_TYPE_STRUCTURE ? "STRUCTURE" : "ARRAY");
ESP_LOGV(TAG, "Unexpected end while reading element %d of %s", elements_consumed + 1,
type == DLMS_DATA_TYPE_STRUCTURE ? "STRUCTURE" : "ARRAY");
}
return false; return false;
} }
@ -269,11 +259,7 @@ bool DlmsParser::parse_sequence_(uint8_t type, uint8_t depth) {
elements_consumed++; elements_consumed++;
if (this->pos_ == original_position) { if (this->pos_ == original_position) {
if (this->show_log_) { if (this->show_log_) ESP_LOGV(TAG, "No progress parsing element %d at position %zu, aborting to avoid infinite loop", elements_consumed, original_position);
ESP_LOGV(TAG, "No progress parsing element %d at position %zu, aborting to avoid infinite loop",
elements_consumed, original_position);
}
return false; return false;
} }
} }
@ -335,8 +321,7 @@ bool DlmsParser::try_match_patterns_(uint8_t elem_idx) {
return false; return false;
} }
bool DlmsParser::match_pattern_(uint8_t elem_idx, const AxdrDescriptorPattern &pat, bool DlmsParser::match_pattern_(uint8_t elem_idx, const AxdrDescriptorPattern &pat, uint8_t &elements_consumed_at_level0) {
uint8_t &elements_consumed_at_level0) {
AxdrCaptures cap{}; AxdrCaptures cap{};
elements_consumed_at_level0 = 0; elements_consumed_at_level0 = 0;
uint8_t level = 0; uint8_t level = 0;
@ -415,16 +400,10 @@ bool DlmsParser::match_pattern_(uint8_t elem_idx, const AxdrDescriptorPattern &p
void DlmsParser::emit_object_(const AxdrDescriptorPattern &pat, const AxdrCaptures &c) { void DlmsParser::emit_object_(const AxdrDescriptorPattern &pat, const AxdrCaptures &c) {
if (!c.obis || !this->callback_) return; if (!c.obis || !this->callback_) return;
// Use stack-allocated buffer for OBIS to avoid heap allocation std::string obis_str = this->obis_to_string_(c.obis);
char obis_str_buf[32];
this->obis_to_string_(c.obis, obis_str_buf, sizeof(obis_str_buf));
float raw_val_f = this->data_as_float_(c.value_type, c.value_ptr, c.value_len); float raw_val_f = this->data_as_float_(c.value_type, c.value_ptr, c.value_len);
float val_f = raw_val_f; float val_f = raw_val_f;
std::string val_s = this->data_as_string_(c.value_type, c.value_ptr, c.value_len);
// Use stack-allocated buffer for formatting data
char val_s_buf[128];
this->data_to_string_(c.value_type, c.value_ptr, c.value_len, val_s_buf, sizeof(val_s_buf));
bool is_numeric = (c.value_type != DLMS_DATA_TYPE_OCTET_STRING && bool is_numeric = (c.value_type != DLMS_DATA_TYPE_OCTET_STRING &&
c.value_type != DLMS_DATA_TYPE_STRING && c.value_type != DLMS_DATA_TYPE_STRING &&
@ -438,7 +417,7 @@ void DlmsParser::emit_object_(const AxdrDescriptorPattern &pat, const AxdrCaptur
ESP_LOGD(TAG, "Pattern match '%s' at idx %u ===============", pat.name.c_str(), c.elem_idx); ESP_LOGD(TAG, "Pattern match '%s' at idx %u ===============", pat.name.c_str(), c.elem_idx);
uint16_t cid = c.class_id ? c.class_id : pat.default_class_id; uint16_t cid = c.class_id ? c.class_id : pat.default_class_id;
ESP_LOGI(TAG, "Found attribute descriptor: class_id=%d, obis=%s", cid, obis_str_buf); ESP_LOGI(TAG, "Found attribute descriptor: class_id=%d, obis=%s", cid, obis_str.c_str());
if (c.has_scaler_unit) { if (c.has_scaler_unit) {
ESP_LOGI(TAG, "Value type: %s, len %d, scaler %d, unit %d", ESP_LOGI(TAG, "Value type: %s, len %d, scaler %d, unit %d",
@ -448,11 +427,9 @@ void DlmsParser::emit_object_(const AxdrDescriptorPattern &pat, const AxdrCaptur
} }
if (c.value_ptr && c.value_len > 0) { if (c.value_ptr && c.value_len > 0) {
char hex_buf[512]; ESP_LOGI(TAG, " as hex dump : %s", esphome::format_hex_pretty(c.value_ptr, c.value_len).c_str());
esphome::format_hex_pretty_to(hex_buf, sizeof(hex_buf), c.value_ptr, c.value_len);
ESP_LOGI(TAG, " as hex dump : %s", hex_buf);
} }
ESP_LOGI(TAG, " as string :'%s'", val_s_buf); ESP_LOGI(TAG, " as string :'%s'", val_s.c_str());
ESP_LOGI(TAG, " as number : %f", raw_val_f); ESP_LOGI(TAG, " as number : %f", raw_val_f);
if (c.has_scaler_unit && is_numeric) { if (c.has_scaler_unit && is_numeric) {
@ -460,7 +437,7 @@ void DlmsParser::emit_object_(const AxdrDescriptorPattern &pat, const AxdrCaptur
} }
} }
this->callback_(obis_str_buf, val_f, val_s_buf, is_numeric); this->callback_(obis_str, val_f, val_s, is_numeric);
this->objects_found_++; this->objects_found_++;
} }
@ -468,9 +445,7 @@ float DlmsParser::data_as_float_(DlmsDataType value_type, const uint8_t *ptr, ui
if (!ptr || len == 0) return 0.0f; if (!ptr || len == 0) return 0.0f;
auto be16 = [](const uint8_t *p) { return (uint16_t)((p[0] << 8) | p[1]); }; auto be16 = [](const uint8_t *p) { return (uint16_t)((p[0] << 8) | p[1]); };
auto be32 = [](const uint8_t *p) { auto be32 = [](const uint8_t *p) { return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3]; };
return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3];
};
auto be64 = [](const uint8_t *p) { auto be64 = [](const uint8_t *p) {
return ((uint64_t)p[0] << 56) | ((uint64_t)p[1] << 48) | ((uint64_t)p[2] << 40) | ((uint64_t)p[3] << 32) | return ((uint64_t)p[0] << 56) | ((uint64_t)p[1] << 48) | ((uint64_t)p[2] << 40) | ((uint64_t)p[3] << 32) |
((uint64_t)p[4] << 24) | ((uint64_t)p[5] << 16) | ((uint64_t)p[6] << 8) | (uint64_t)p[7]; ((uint64_t)p[4] << 24) | ((uint64_t)p[5] << 16) | ((uint64_t)p[6] << 8) | (uint64_t)p[7];
@ -506,24 +481,20 @@ float DlmsParser::data_as_float_(DlmsDataType value_type, const uint8_t *ptr, ui
} }
} }
void DlmsParser::data_to_string_(DlmsDataType value_type, const uint8_t *ptr, uint8_t len, std::string DlmsParser::data_as_string_(DlmsDataType value_type, const uint8_t *ptr, uint8_t len) {
char *buffer, size_t max_len) { if (!ptr || len == 0) return "";
if (max_len > 0) buffer[0] = '\0';
if (!ptr || len == 0 || max_len == 0) return;
auto hex_of = [](const uint8_t *p, uint8_t l, char *out, size_t max_out) { auto hex_of = [](const uint8_t *p, uint8_t l) {
if (max_out == 0) return; std::ostringstream ss;
out[0] = '\0'; ss << std::hex << std::setfill('0');
size_t pos = 0; for (uint8_t i = 0; i < l; i++) {
for (uint8_t i = 0; i < l && pos + 2 < max_out; i++) { ss << std::setw(2) << static_cast<int>(p[i]);
pos += snprintf(out + pos, max_out - pos, "%02x", p[i]);
} }
return ss.str();
}; };
auto be16 = [](const uint8_t *p) { return (uint16_t)((p[0] << 8) | p[1]); }; auto be16 = [](const uint8_t *p) { return (uint16_t)((p[0] << 8) | p[1]); };
auto be32 = [](const uint8_t *p) { auto be32 = [](const uint8_t *p) { return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3]; };
return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16) | ((uint32_t)p[2] << 8) | (uint32_t)p[3];
};
auto be64 = [](const uint8_t *p) { auto be64 = [](const uint8_t *p) {
uint64_t v = 0; uint64_t v = 0;
for (int i = 0; i < 8; i++) v = (v << 8) | p[i]; for (int i = 0; i < 8; i++) v = (v << 8) | p[i];
@ -533,70 +504,58 @@ void DlmsParser::data_to_string_(DlmsDataType value_type, const uint8_t *ptr, ui
switch (value_type) { switch (value_type) {
case DLMS_DATA_TYPE_OCTET_STRING: case DLMS_DATA_TYPE_OCTET_STRING:
case DLMS_DATA_TYPE_STRING: case DLMS_DATA_TYPE_STRING:
case DLMS_DATA_TYPE_STRING_UTF8: { case DLMS_DATA_TYPE_STRING_UTF8:
size_t copy_len = std::min((size_t)len, max_len - 1); return std::string(reinterpret_cast<const char *>(ptr), len);
std::memcpy(buffer, ptr, copy_len);
buffer[copy_len] = '\0';
break;
}
case DLMS_DATA_TYPE_BIT_STRING: case DLMS_DATA_TYPE_BIT_STRING:
case DLMS_DATA_TYPE_BINARY_CODED_DESIMAL: case DLMS_DATA_TYPE_BINARY_CODED_DESIMAL:
case DLMS_DATA_TYPE_DATETIME: case DLMS_DATA_TYPE_DATETIME:
case DLMS_DATA_TYPE_DATE: case DLMS_DATA_TYPE_DATE:
case DLMS_DATA_TYPE_TIME: case DLMS_DATA_TYPE_TIME:
hex_of(ptr, len, buffer, max_len); return hex_of(ptr, len);
break;
case DLMS_DATA_TYPE_BOOLEAN: case DLMS_DATA_TYPE_BOOLEAN:
case DLMS_DATA_TYPE_ENUM: case DLMS_DATA_TYPE_ENUM:
case DLMS_DATA_TYPE_UINT8: case DLMS_DATA_TYPE_UINT8:
snprintf(buffer, max_len, "%u", static_cast<unsigned>(ptr[0])); return std::to_string(static_cast<unsigned>(ptr[0]));
break;
case DLMS_DATA_TYPE_INT8: case DLMS_DATA_TYPE_INT8:
snprintf(buffer, max_len, "%d", static_cast<int>(static_cast<int8_t>(ptr[0]))); return std::to_string(static_cast<int>(static_cast<int8_t>(ptr[0])));
break;
case DLMS_DATA_TYPE_UINT16: case DLMS_DATA_TYPE_UINT16:
if (len >= 2) snprintf(buffer, max_len, "%u", be16(ptr)); return len >= 2 ? std::to_string(be16(ptr)) : "";
break;
case DLMS_DATA_TYPE_INT16: case DLMS_DATA_TYPE_INT16:
if (len >= 2) snprintf(buffer, max_len, "%d", static_cast<int16_t>(be16(ptr))); return len >= 2 ? std::to_string(static_cast<int16_t>(be16(ptr))) : "";
break;
case DLMS_DATA_TYPE_UINT32: case DLMS_DATA_TYPE_UINT32:
if (len >= 4) snprintf(buffer, max_len, "%lu", (unsigned long)be32(ptr)); return len >= 4 ? std::to_string(be32(ptr)) : "";
break;
case DLMS_DATA_TYPE_INT32: case DLMS_DATA_TYPE_INT32:
if (len >= 4) snprintf(buffer, max_len, "%ld", (long)static_cast<int32_t>(be32(ptr))); return len >= 4 ? std::to_string(static_cast<int32_t>(be32(ptr))) : "";
break;
case DLMS_DATA_TYPE_UINT64: case DLMS_DATA_TYPE_UINT64:
if (len >= 8) snprintf(buffer, max_len, "%llu", (unsigned long long)be64(ptr)); return len >= 8 ? std::to_string(be64(ptr)) : "";
break;
case DLMS_DATA_TYPE_INT64: case DLMS_DATA_TYPE_INT64:
if (len >= 8) snprintf(buffer, max_len, "%lld", (long long)static_cast<int64_t>(be64(ptr))); return len >= 8 ? std::to_string(static_cast<int64_t>(be64(ptr))) : "";
break;
case DLMS_DATA_TYPE_FLOAT32: case DLMS_DATA_TYPE_FLOAT32:
case DLMS_DATA_TYPE_FLOAT64: { case DLMS_DATA_TYPE_FLOAT64: {
snprintf(buffer, max_len, "%f", this->data_as_float_(value_type, ptr, len)); std::ostringstream ss;
break; ss << this->data_as_float_(value_type, ptr, len);
return ss.str();
} }
default: default:
break; return "";
} }
} }
void DlmsParser::obis_to_string_(const uint8_t *obis, char *buffer, size_t max_len) { std::string DlmsParser::obis_to_string_(const uint8_t *obis) {
if (max_len > 0) buffer[0] = '\0'; char buf[32];
if (!obis || max_len == 0) return; snprintf(buf, sizeof(buf), "%u.%u.%u.%u.%u.%u", obis[0], obis[1], obis[2], obis[3], obis[4], obis[5]);
snprintf(buffer, max_len, "%u.%u.%u.%u.%u.%u", obis[0], obis[1], obis[2], obis[3], obis[4], obis[5]); return std::string(buf);
} }
const char *DlmsParser::dlms_data_type_to_string_(DlmsDataType vt) { const char *DlmsParser::dlms_data_type_to_string_(DlmsDataType vt) {
@ -639,7 +598,7 @@ void DlmsParser::register_pattern_dsl_(const std::string &name, const std::strin
return s.substr(b, e - b + 1); return s.substr(b, e - b + 1);
}; };
std::vector<std::string> tokens; std::list<std::string> tokens;
std::string current; std::string current;
int paren = 0; int paren = 0;
for (char c : dsl) { for (char c : dsl) {
@ -658,8 +617,8 @@ void DlmsParser::register_pattern_dsl_(const std::string &name, const std::strin
} }
if (!current.empty()) tokens.push_back(trim(current)); if (!current.empty()) tokens.push_back(trim(current));
for (size_t i = 0; i < tokens.size(); i++) { for (auto it = tokens.begin(); it != tokens.end(); ++it) {
std::string tok = tokens[i]; std::string tok = *it;
if (tok.empty()) continue; if (tok.empty()) continue;
if (tok == "F") pat.steps.push_back({AxdrTokenType::EXPECT_TO_BE_FIRST}); if (tok == "F") pat.steps.push_back({AxdrTokenType::EXPECT_TO_BE_FIRST});
@ -690,7 +649,7 @@ void DlmsParser::register_pattern_dsl_(const std::string &name, const std::strin
size_t r = tok.rfind(')'); size_t r = tok.rfind(')');
if (l != std::string::npos && r != std::string::npos && r > l + 1) { if (l != std::string::npos && r != std::string::npos && r > l + 1) {
std::string inner = tok.substr(l + 1, r - l - 1); std::string inner = tok.substr(l + 1, r - l - 1);
std::vector<std::string> inner_tokens; std::list<std::string> inner_tokens;
std::string cur; std::string cur;
for (char c2 : inner) { for (char c2 : inner) {
if (c2 == ',') { if (c2 == ',') {
@ -704,9 +663,9 @@ void DlmsParser::register_pattern_dsl_(const std::string &name, const std::strin
if (!inner_tokens.empty()) { if (!inner_tokens.empty()) {
pat.steps.push_back({AxdrTokenType::EXPECT_STRUCTURE_N, static_cast<uint8_t>(inner_tokens.size())}); pat.steps.push_back({AxdrTokenType::EXPECT_STRUCTURE_N, static_cast<uint8_t>(inner_tokens.size())});
inner_tokens.insert(inner_tokens.begin(), "DN"); inner_tokens.push_front("DN");
inner_tokens.push_back("UP"); inner_tokens.push_back("UP");
tokens.insert(tokens.begin() + i + 1, inner_tokens.begin(), inner_tokens.end()); tokens.insert(std::next(it), inner_tokens.begin(), inner_tokens.end());
} }
} }
} }

View File

@ -4,6 +4,7 @@
#include <functional> #include <functional>
#include <string> #include <string>
#include <vector> #include <vector>
#include <list>
namespace esphome { namespace esphome {
namespace dlms_push { namespace dlms_push {
@ -36,8 +37,7 @@ enum DlmsDataType : uint8_t {
}; };
// Callback for the hub: OBIS code (e.g. "1.0.1.8.0.255"), numeric value, string value, is_numeric flag // Callback for the hub: OBIS code (e.g. "1.0.1.8.0.255"), numeric value, string value, is_numeric flag
using DlmsDataCallback = std::function<void(const char *obis_code, float float_val, const char *str_val, using DlmsDataCallback = std::function<void(const std::string &obis_code, float float_val, const std::string &str_val, bool is_numeric)>;
bool is_numeric)>;
// --- Pattern Matching Enums & Structs --- // --- Pattern Matching Enums & Structs ---
enum class AxdrTokenType : uint8_t { enum class AxdrTokenType : uint8_t {
@ -113,8 +113,8 @@ class DlmsParser {
void emit_object_(const AxdrDescriptorPattern &pat, const AxdrCaptures &c); void emit_object_(const AxdrDescriptorPattern &pat, const AxdrCaptures &c);
float data_as_float_(DlmsDataType value_type, const uint8_t *ptr, uint8_t len); float data_as_float_(DlmsDataType value_type, const uint8_t *ptr, uint8_t len);
void data_to_string_(DlmsDataType value_type, const uint8_t *ptr, uint8_t len, char *buffer, size_t max_len); std::string data_as_string_(DlmsDataType value_type, const uint8_t *ptr, uint8_t len);
void obis_to_string_(const uint8_t *obis, char *buffer, size_t max_len); std::string obis_to_string_(const uint8_t *obis);
const char *dlms_data_type_to_string_(DlmsDataType vt); const char *dlms_data_type_to_string_(DlmsDataType vt);
const uint8_t *buffer_{nullptr}; const uint8_t *buffer_{nullptr};

View File

@ -2,7 +2,6 @@
#include "dlms_parser.h" #include "dlms_parser.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
#include "esphome/core/application.h"
#include "esphome/core/helpers.h" #include "esphome/core/helpers.h"
namespace esphome { namespace esphome {
@ -11,7 +10,7 @@ namespace dlms_push {
static const char *const TAG = "dlms_push"; static const char *const TAG = "dlms_push";
DlmsPushComponent::DlmsPushComponent() { DlmsPushComponent::DlmsPushComponent() {
this->parser_ = std::make_unique<DlmsParser>(); this->parser_ = new DlmsParser();
} }
void DlmsPushComponent::setup() { void DlmsPushComponent::setup() {
@ -58,7 +57,7 @@ void DlmsPushComponent::dump_config() {
void DlmsPushComponent::loop() { void DlmsPushComponent::loop() {
this->read_rx_buffer_(); this->read_rx_buffer_();
if (this->receiving_ && (App.get_loop_component_start_time()-this->last_rx_char_time_ > this->receive_timeout_ms_)) { if (this->receiving_ && (millis() - this->last_rx_char_time_ > this->receive_timeout_ms_)) {
this->receiving_ = false; this->receiving_ = false;
this->process_frame_(); this->process_frame_();
} }
@ -69,7 +68,7 @@ void DlmsPushComponent::read_rx_buffer_() {
if (available == 0) return; if (available == 0) return;
this->receiving_ = true; this->receiving_ = true;
this->last_rx_char_time_ = App.get_loop_component_start_time(); this->last_rx_char_time_ = millis();
while (this->available()) { while (this->available()) {
if (this->rx_buffer_len_ >= MAX_RX_BUFFER_SIZE) { if (this->rx_buffer_len_ >= MAX_RX_BUFFER_SIZE) {
@ -96,21 +95,20 @@ void DlmsPushComponent::process_frame_() {
ESP_LOGD(TAG, "PUSH frame size: %zu bytes", this->rx_buffer_len_); ESP_LOGD(TAG, "PUSH frame size: %zu bytes", this->rx_buffer_len_);
} }
auto callback = [this](const char *obis_code, float float_val, const char *str_val, bool is_numeric) { auto callback = [this](const std::string &obis_code, float float_val, const std::string &str_val, bool is_numeric) {
this->on_data_parsed_(obis_code, float_val, str_val, is_numeric); this->on_data_parsed_(obis_code, float_val, str_val, is_numeric);
}; };
size_t parsed_objects = this->parser_->parse(this->rx_buffer_.get(), this->rx_buffer_len_, callback, this->show_log_); size_t parsed_objects = this->parser_->parse(this->rx_buffer_.get(), this->rx_buffer_len_, callback, this->show_log_);
if (this->show_log_) { if (this->show_log_) {
ESP_LOGD(TAG, "PUSH data parsing complete: %zu objects, bytes consumed %zu/%zu", parsed_objects, ESP_LOGD(TAG, "PUSH data parsing complete: %zu objects, bytes consumed %zu/%zu", parsed_objects, this->rx_buffer_len_, this->rx_buffer_len_);
this->rx_buffer_len_, this->rx_buffer_len_);
} }
this->rx_buffer_len_ = 0; this->rx_buffer_len_ = 0;
} }
void DlmsPushComponent::on_data_parsed_(const char *obis_code, float float_val, const char *str_val, bool is_numeric) { void DlmsPushComponent::on_data_parsed_(const std::string &obis_code, float float_val, const std::string &str_val, bool is_numeric) {
int updated_count = 0; int updated_count = 0;
#ifdef USE_SENSOR #ifdef USE_SENSOR
@ -118,7 +116,7 @@ void DlmsPushComponent::on_data_parsed_(const char *obis_code, float float_val,
for (const auto &entry : this->sensors_) { for (const auto &entry : this->sensors_) {
if (entry.obis == obis_code) { if (entry.obis == obis_code) {
if (this->show_log_) { if (this->show_log_) {
ESP_LOGD(TAG, "Found sensor for OBIS code %s: '%s'", obis_code, entry.sensor->get_name().c_str()); ESP_LOGD(TAG, "Found sensor for OBIS code %s: '%s'", obis_code.c_str(), entry.sensor->get_name().c_str());
ESP_LOGD(TAG, "Publishing data"); ESP_LOGD(TAG, "Publishing data");
} }
entry.sensor->publish_state(float_val); entry.sensor->publish_state(float_val);
@ -132,7 +130,7 @@ void DlmsPushComponent::on_data_parsed_(const char *obis_code, float float_val,
for (const auto &entry : this->text_sensors_) { for (const auto &entry : this->text_sensors_) {
if (entry.obis == obis_code) { if (entry.obis == obis_code) {
if (this->show_log_) { if (this->show_log_) {
ESP_LOGD(TAG, "Found sensor for OBIS code %s: '%s'", obis_code, entry.sensor->get_name().c_str()); ESP_LOGD(TAG, "Found sensor for OBIS code %s: '%s'", obis_code.c_str(), entry.sensor->get_name().c_str());
ESP_LOGD(TAG, "Publishing data"); ESP_LOGD(TAG, "Publishing data");
} }
entry.sensor->publish_state(str_val); entry.sensor->publish_state(str_val);
@ -147,7 +145,7 @@ void DlmsPushComponent::on_data_parsed_(const char *obis_code, float float_val,
for (const auto &entry : this->binary_sensors_) { for (const auto &entry : this->binary_sensors_) {
if (entry.obis == obis_code) { if (entry.obis == obis_code) {
if (this->show_log_) { if (this->show_log_) {
ESP_LOGD(TAG, "Found sensor for OBIS code %s: '%s'", obis_code, entry.sensor->get_name().c_str()); ESP_LOGD(TAG, "Found sensor for OBIS code %s: '%s'", obis_code.c_str(), entry.sensor->get_name().c_str());
ESP_LOGD(TAG, "Publishing data"); ESP_LOGD(TAG, "Publishing data");
} }
entry.sensor->publish_state(state); entry.sensor->publish_state(state);
@ -158,7 +156,7 @@ void DlmsPushComponent::on_data_parsed_(const char *obis_code, float float_val,
#endif #endif
if (this->show_log_ && updated_count == 0) { if (this->show_log_ && updated_count == 0) {
ESP_LOGV(TAG, "Received OBIS %s, but no sensors are registered for it.", obis_code); ESP_LOGV(TAG, "Received OBIS %s, but no sensors are registered for it.", obis_code.c_str());
} }
} }

View File

@ -14,9 +14,9 @@
#endif #endif
#include <vector> #include <vector>
#include <map>
#include <string> #include <string>
#include <array> #include <array>
#include <memory>
namespace esphome { namespace esphome {
namespace dlms_push { namespace dlms_push {
@ -50,7 +50,7 @@ class DlmsPushComponent : public Component, public uart::UARTDevice {
void read_rx_buffer_(); void read_rx_buffer_();
void process_frame_(); void process_frame_();
void on_data_parsed_(const char *obis_code, float float_val, const char *str_val, bool is_numeric); void on_data_parsed_(const std::string &obis_code, float float_val, const std::string &str_val, bool is_numeric);
uint32_t receive_timeout_ms_{50}; uint32_t receive_timeout_ms_{50};
bool show_log_{false}; bool show_log_{false};
@ -62,7 +62,7 @@ class DlmsPushComponent : public Component, public uart::UARTDevice {
uint32_t last_rx_char_time_{0}; uint32_t last_rx_char_time_{0};
bool receiving_{false}; bool receiving_{false};
std::unique_ptr<DlmsParser> parser_; DlmsParser *parser_{nullptr};
#ifdef USE_SENSOR #ifdef USE_SENSOR
struct NumericSensorEntry { struct NumericSensorEntry {