8 static const char *
const TAG =
"sml";
14 : server_id(
std::move(server_id)), obis_code(
std::move(obis_code)) {}
17 this->incoming_mask_ = (this->incoming_mask_ << 2) |
get_code(byte);
21 if ((this->incoming_mask_ >> 6) ==
END_MASK)
22 return END_BYTES_DETECTED;
28 const char c = read();
31 this->sml_data_.emplace_back(c);
33 switch (this->check_start_end_bytes_(c)) {
36 this->sml_data_.clear();
41 this->record_ =
false;
47 this->sml_data_.resize(this->sml_data_.size() - 8);
48 this->process_sml_file_(this->sml_data_);
59 this->publish_obis_info_(obis_info);
61 this->log_obis_info_(obis_info);
65 ESP_LOGD(TAG,
"OBIS info:");
66 for (
auto const &obis_info : obis_info_vec) {
68 info +=
" (" +
bytes_repr(obis_info.server_id) +
") ";
69 info += obis_info.code_repr();
70 info +=
" [0x" +
bytes_repr(obis_info.value) +
"]";
71 ESP_LOGD(TAG,
"%s", info.c_str());
76 for (
auto const &obis_info : obis_info_vec) {
77 this->publish_value_(obis_info);
82 for (
auto const &sml_listener : sml_listeners_) {
83 if ((!sml_listener->server_id.empty()) && (
bytes_repr(obis_info.
server_id) != sml_listener->server_id))
85 if (obis_info.
code_repr() != sml_listener->obis_code)
87 sml_listener->publish_val(obis_info);
96 if (buffer.size() < 2) {
97 ESP_LOGW(TAG,
"Checksum error in received SML data.");
101 uint16_t crc_received = (buffer.at(buffer.size() - 2) << 8) | buffer.at(buffer.size() - 1);
102 if (crc_received ==
calc_crc16_x25(buffer.begin(), buffer.end() - 2, 0x6e23)) {
103 ESP_LOGV(TAG,
"Checksum verification successful with CRC16/X25.");
107 if (crc_received ==
calc_crc16_kermit(buffer.begin(), buffer.end() - 2, 0xed50)) {
108 ESP_LOGV(TAG,
"Checksum verification successful with CRC16/KERMIT.");
112 ESP_LOGW(TAG,
"Checksum error in received SML data.");
116 uint16_t
calc_crc16_p1021(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum) {
117 for (
auto it = begin; it != end; it++) {
123 uint16_t
calc_crc16_x25(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum = 0) {
125 return (crcsum >> 8) | ((crcsum & 0xff) << 8);
128 uint16_t
calc_crc16_kermit(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum = 0) {
std::string bytes_repr(const bytes &buffer)
uint16_t calc_crc16_p1021(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum)
const uint16_t START_MASK
void log_obis_info_(const std::vector< ObisInfo > &obis_info_vec)
SmlListener(std::string server_id, std::string obis_code)
const uint16_t CRC16_X25_TABLE[256]
void publish_value_(const ObisInfo &obis_info)
void register_sml_listener(SmlListener *listener)
const char END_BYTES_DETECTED
const char START_BYTES_DETECTED
char check_start_end_bytes_(uint8_t byte)
uint16_t calc_crc16_x25(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum=0)
uint8_t get_code(uint8_t byte)
void process_sml_file_(const bytes &sml_data)
std::vector< ObisInfo > get_obis_info()
uint16_t calc_crc16_kermit(bytes::const_iterator begin, bytes::const_iterator end, uint16_t crcsum=0)
std::vector< uint8_t > bytes
void publish_obis_info_(const std::vector< ObisInfo > &obis_info_vec)
bool check_sml_data(const bytes &buffer)
void dump_config() override
std::string code_repr() const