ESPHome 2026.5.1
Loading...
Searching...
No Matches
dsmr.h
Go to the documentation of this file.
1#pragma once
2
3// Ignore Zephyr. It doesn't have any encryption library.
4#if defined(USE_ESP32) || defined(USE_ARDUINO) || defined(USE_HOST)
5
10#include "esphome/core/log.h"
11#include <dsmr_parser/dlms_packet_decryptor.h>
12#include <dsmr_parser/fields.h>
13#include <dsmr_parser/packet_accumulator.h>
14#include <dsmr_parser/parser.h>
15#include <array>
16#include <span>
17#include <vector>
18
19#if __has_include(<psa/crypto.h>)
20#include <dsmr_parser/decryption/aes128gcm_tfpsa.h>
21#elif __has_include(<mbedtls/gcm.h>)
22#if __has_include(<mbedtls/esp_config.h>)
23#include <mbedtls/esp_config.h>
24#endif
25#include <dsmr_parser/decryption/aes128gcm_mbedtls.h>
26#elif __has_include(<bearssl/bearssl.h>)
27#include <dsmr_parser/decryption/aes128gcm_bearssl.h>
28#else
29#error "The platform doesn't provide a compatible encryption library for dsmr_parser"
30#endif
31
32namespace esphome::dsmr {
33
34#if __has_include(<psa/crypto.h>)
35using Aes128GcmDecryptorImpl = dsmr_parser::Aes128GcmTfPsa;
36#elif __has_include(<mbedtls/gcm.h>)
37using Aes128GcmDecryptorImpl = dsmr_parser::Aes128GcmMbedTls;
38#else
39using Aes128GcmDecryptorImpl = dsmr_parser::Aes128GcmBearSsl;
40#endif
41
42using namespace dsmr_parser::fields;
43
44#ifndef DSMR_SENSOR_LIST
45#define DSMR_SENSOR_LIST(F, SEP)
46#endif
47
48#ifndef DSMR_TEXT_SENSOR_LIST
49#define DSMR_TEXT_SENSOR_LIST(F, SEP)
50#endif
51
52#define DSMR_IDENTITY(s) s
53#define DSMR_COMMA ,
54#define DSMR_PREPEND_COMMA(...) __VA_OPT__(, ) __VA_ARGS__
55
56#ifdef DSMR_TEXT_SENSOR_LIST_DEFINED
57using MyData = dsmr_parser::ParsedData<DSMR_TEXT_SENSOR_LIST(DSMR_IDENTITY, DSMR_COMMA)
58 DSMR_PREPEND_COMMA(DSMR_SENSOR_LIST(DSMR_IDENTITY, DSMR_COMMA))>;
59#else
60using MyData = dsmr_parser::ParsedData<DSMR_SENSOR_LIST(DSMR_IDENTITY, DSMR_COMMA)>;
61#endif
62
63class Dsmr : public Component, public uart::UARTDevice {
64 public:
65 Dsmr(uart::UARTComponent *uart, bool crc_check, size_t max_telegram_length, uint32_t request_interval,
66 uint32_t receive_timeout, GPIOPin *request_pin, const char *decryption_key)
67 : uart::UARTDevice(uart),
68 request_interval_(request_interval),
69 receive_timeout_(receive_timeout),
70 request_pin_(request_pin),
71 buffer_(max_telegram_length),
72 packet_accumulator_(buffer_, crc_check) {
73 this->set_decryption_key_(decryption_key);
74 }
75
76 void setup() override;
77 void loop() override;
78
79 void publish_sensors(MyData &data) {
80#define DSMR_PUBLISH_SENSOR(s) \
81 if (data.s##_present && this->s_##s##_ != nullptr) \
82 s_##s##_->publish_state(data.s);
83 DSMR_SENSOR_LIST(DSMR_PUBLISH_SENSOR, )
84
85#define DSMR_PUBLISH_TEXT_SENSOR(s) \
86 if (data.s##_present && this->s_##s##_ != nullptr) \
87 s_##s##_->publish_state(data.s.data(), data.s.size());
88 DSMR_TEXT_SENSOR_LIST(DSMR_PUBLISH_TEXT_SENSOR, )
89 };
90
91 void dump_config() override;
92
93 // Remove before 2026.8.0
94 ESPDEPRECATED("Use 'decryption_key' configuration parameter. This method will be removed in 2026.8.0", "2026.2.0")
95 void set_decryption_key(const std::string &decryption_key) { this->set_decryption_key_(decryption_key.c_str()); }
96
97// Sensor setters
98#define DSMR_SET_SENSOR(s) \
99 void set_##s(sensor::Sensor *sensor) { s_##s##_ = sensor; }
100 DSMR_SENSOR_LIST(DSMR_SET_SENSOR, )
101
102#define DSMR_SET_TEXT_SENSOR(s) \
103 void set_##s(text_sensor::TextSensor *sensor) { s_##s##_ = sensor; }
104 DSMR_TEXT_SENSOR_LIST(DSMR_SET_TEXT_SENSOR, )
105
106 // handled outside dsmr
107 void set_telegram(text_sensor::TextSensor *sensor) { s_telegram_ = sensor; }
108
109 protected:
110 void set_decryption_key_(const char *decryption_key);
111 void receive_telegram_();
113 void flush_rx_buffer_();
114
115 bool parse_telegram_(const dsmr_parser::DsmrUnencryptedTelegram &telegram);
116 bool request_interval_reached_() const;
120 std::span<uint8_t> uart_read_chunk_();
121
122 // Config
127#define DSMR_DECLARE_SENSOR(s) sensor::Sensor *s_##s##_{nullptr};
128 DSMR_SENSOR_LIST(DSMR_DECLARE_SENSOR, )
129#define DSMR_DECLARE_TEXT_SENSOR(s) text_sensor::TextSensor *s_##s##_{nullptr};
130 DSMR_TEXT_SENSOR_LIST(DSMR_DECLARE_TEXT_SENSOR, )
131
132 // State
135 bool requesting_data_{false};
137 size_t buffer_pos_{0};
138 std::vector<uint8_t> buffer_;
139 dsmr_parser::PacketAccumulator packet_accumulator_;
141 dsmr_parser::DlmsPacketDecryptor dlms_decryptor_{gcm_decryptor_};
142 std::array<uint8_t, 256> uart_chunk_reading_buf_;
143};
144} // namespace esphome::dsmr
145
146#endif
ESPDEPRECATED("Use 'decryption_key' configuration parameter. This method will be removed in 2026.8.0", "2026.2.0") void set_decryption_key(const std
Definition dsmr.h:94
void stop_requesting_data_()
Definition dsmr.cpp:87
Dsmr(uart::UARTComponent *uart, bool crc_check, size_t max_telegram_length, uint32_t request_interval, uint32_t receive_timeout, GPIOPin *request_pin, const char *decryption_key)
Definition dsmr.h:65
uint32_t last_request_time_
Definition dsmr.h:133
GPIOPin * request_pin_
Definition dsmr.h:125
uint32_t receive_timeout_
Definition dsmr.h:124
void set_telegram(text_sensor::TextSensor *sensor)
Definition dsmr.h:107
size_t buffer_pos_
Definition dsmr.h:137
bool request_interval_reached_() const
Definition dsmr.cpp:63
bool ready_to_request_data_()
Definition dsmr.cpp:56
dsmr_parser::DlmsPacketDecryptor dlms_decryptor_
Definition dsmr.h:141
void set_decryption_key_(const char *decryption_key)
Definition dsmr.cpp:195
text_sensor::TextSensor * s_telegram_
Definition dsmr.h:126
void flush_rx_buffer_()
Definition dsmr.cpp:100
void publish_sensors(MyData &data)
Definition dsmr.h:79
void start_requesting_data_()
Definition dsmr.cpp:70
dsmr_parser::PacketAccumulator packet_accumulator_
Definition dsmr.h:139
void receive_telegram_()
Definition dsmr.cpp:106
bool encryption_enabled_
Definition dsmr.h:136
uint32_t last_read_time_
Definition dsmr.h:134
DSMR_SENSOR_LIST(DSMR_SET_SENSOR,) DSMR_TEXT_SENSOR_LIST(DSMR_SET_TEXT_SENSOR
bool requesting_data_
Definition dsmr.h:135
void loop() override
Definition dsmr.cpp:44
uint32_t request_interval_
Definition dsmr.h:123
DSMR_SENSOR_LIST(DSMR_DECLARE_SENSOR,) DSMR_TEXT_SENSOR_LIST(DSMR_DECLARE_TEXT_SENSOR
std::array< uint8_t, 256 > uart_chunk_reading_buf_
Definition dsmr.h:142
void setup() override
Definition dsmr.cpp:37
void dump_config() override
Definition dsmr.cpp:175
Aes128GcmDecryptorImpl gcm_decryptor_
Definition dsmr.h:140
void receive_encrypted_telegram_()
Definition dsmr.cpp:120
bool parse_telegram_(const dsmr_parser::DsmrUnencryptedTelegram &telegram)
Definition dsmr.cpp:153
std::vector< uint8_t > buffer_
Definition dsmr.h:138
std::span< uint8_t > uart_read_chunk_()
Definition dsmr.cpp:214
dsmr_parser::Aes128GcmTfPsa Aes128GcmDecryptorImpl
Definition dsmr.h:35
dsmr_parser::ParsedData< DSMR_TEXT_SENSOR_LIST(DSMR_IDENTITY, DSMR_COMMA) DSMR_PREPEND_COMMA(DSMR_SENSOR_LIST(DSMR_IDENTITY, DSMR_COMMA))> MyData
Definition dsmr.h:57
static void uint32_t