ESPHome  2024.11.0
dsmr.h
Go to the documentation of this file.
1 #pragma once
2 
3 #ifdef USE_ARDUINO
4 
9 #include "esphome/core/log.h"
10 #include "esphome/core/defines.h"
11 
12 // don't include <dsmr.h> because it puts everything in global namespace
13 #include <dsmr/parser.h>
14 #include <dsmr/fields.h>
15 
16 #include <vector>
17 
18 namespace esphome {
19 namespace dsmr {
20 
21 using namespace ::dsmr::fields;
22 
23 // DSMR_**_LIST generated by ESPHome and written in esphome/core/defines
24 
25 #if !defined(DSMR_SENSOR_LIST) && !defined(DSMR_TEXT_SENSOR_LIST)
26 // Neither set, set it to a dummy value to not break build
27 #define DSMR_TEXT_SENSOR_LIST(F, SEP) F(identification)
28 #endif
29 
30 #if defined(DSMR_SENSOR_LIST) && defined(DSMR_TEXT_SENSOR_LIST)
31 #define DSMR_BOTH ,
32 #else
33 #define DSMR_BOTH
34 #endif
35 
36 #ifndef DSMR_SENSOR_LIST
37 #define DSMR_SENSOR_LIST(F, SEP)
38 #endif
39 
40 #ifndef DSMR_TEXT_SENSOR_LIST
41 #define DSMR_TEXT_SENSOR_LIST(F, SEP)
42 #endif
43 
44 #define DSMR_DATA_SENSOR(s) s
45 #define DSMR_COMMA ,
46 
47 using MyData = ::dsmr::ParsedData<DSMR_TEXT_SENSOR_LIST(DSMR_DATA_SENSOR, DSMR_COMMA)
48  DSMR_BOTH DSMR_SENSOR_LIST(DSMR_DATA_SENSOR, DSMR_COMMA)>;
49 
50 class Dsmr : public Component, public uart::UARTDevice {
51  public:
52  Dsmr(uart::UARTComponent *uart, bool crc_check) : uart::UARTDevice(uart), crc_check_(crc_check) {}
53 
54  void setup() override;
55  void loop() override;
56 
57  bool parse_telegram();
58 
59  void publish_sensors(MyData &data) {
60 #define DSMR_PUBLISH_SENSOR(s) \
61  if (data.s##_present && this->s_##s##_ != nullptr) \
62  s_##s##_->publish_state(data.s);
63  DSMR_SENSOR_LIST(DSMR_PUBLISH_SENSOR, )
64 
65 #define DSMR_PUBLISH_TEXT_SENSOR(s) \
66  if (data.s##_present && this->s_##s##_ != nullptr) \
67  s_##s##_->publish_state(data.s.c_str());
68  DSMR_TEXT_SENSOR_LIST(DSMR_PUBLISH_TEXT_SENSOR, )
69  };
70 
71  void dump_config() override;
72 
73  void set_decryption_key(const std::string &decryption_key);
74  void set_max_telegram_length(size_t length) { this->max_telegram_len_ = length; }
75  void set_request_pin(GPIOPin *request_pin) { this->request_pin_ = request_pin; }
76  void set_request_interval(uint32_t interval) { this->request_interval_ = interval; }
77  void set_receive_timeout(uint32_t timeout) { this->receive_timeout_ = timeout; }
78 
79 // Sensor setters
80 #define DSMR_SET_SENSOR(s) \
81  void set_##s(sensor::Sensor *sensor) { s_##s##_ = sensor; }
82  DSMR_SENSOR_LIST(DSMR_SET_SENSOR, )
83 
84 #define DSMR_SET_TEXT_SENSOR(s) \
85  void set_##s(text_sensor::TextSensor *sensor) { s_##s##_ = sensor; }
86  DSMR_TEXT_SENSOR_LIST(DSMR_SET_TEXT_SENSOR, )
87 
88  // handled outside dsmr
89  void set_telegram(text_sensor::TextSensor *sensor) { s_telegram_ = sensor; }
90 
91  protected:
92  void receive_telegram_();
93  void receive_encrypted_telegram_();
94  void reset_telegram_();
95 
105  bool available_within_timeout_();
106 
107  // Request telegram
109  bool request_interval_reached_();
110  GPIOPin *request_pin_{nullptr};
111  uint32_t last_request_time_{0};
112  bool requesting_data_{false};
113  bool ready_to_request_data_();
114  void start_requesting_data_();
115  void stop_requesting_data_();
116 
117  // Read telegram
119  bool receive_timeout_reached_();
121  char *telegram_{nullptr};
122  size_t bytes_read_{0};
123  uint8_t *crypt_telegram_{nullptr};
124  size_t crypt_telegram_len_{0};
125  size_t crypt_bytes_read_{0};
126  uint32_t last_read_time_{0};
127  bool header_found_{false};
128  bool footer_found_{false};
129 
130  // handled outside dsmr
131  text_sensor::TextSensor *s_telegram_{nullptr};
132 
133 // Sensor member pointers
134 #define DSMR_DECLARE_SENSOR(s) sensor::Sensor *s_##s##_{nullptr};
135  DSMR_SENSOR_LIST(DSMR_DECLARE_SENSOR, )
136 
137 #define DSMR_DECLARE_TEXT_SENSOR(s) text_sensor::TextSensor *s_##s##_{nullptr};
138  DSMR_TEXT_SENSOR_LIST(DSMR_DECLARE_TEXT_SENSOR, )
139 
140  std::vector<uint8_t> decryption_key_{};
142 };
143 } // namespace dsmr
144 } // namespace esphome
145 
146 #endif // USE_ARDUINO
void setup()
::dsmr::ParsedData< DSMR_TEXT_SENSOR_LIST(DSMR_DATA_SENSOR, DSMR_COMMA) DSMR_BOTH DSMR_SENSOR_LIST(DSMR_DATA_SENSOR, DSMR_COMMA)> MyData
Definition: dsmr.h:48
void loop()
uint32_t receive_timeout_
Definition: dsmr.h:118
void set_request_interval(uint32_t interval)
Definition: dsmr.h:76
STL namespace.
void set_receive_timeout(uint32_t timeout)
Definition: dsmr.h:77
void publish_sensors(MyData &data)
Definition: dsmr.h:59
uint32_t request_interval_
Definition: dsmr.h:108
void set_max_telegram_length(size_t length)
Definition: dsmr.h:74
Dsmr(uart::UARTComponent *uart, bool crc_check)
Definition: dsmr.h:52
size_t max_telegram_len_
Definition: dsmr.h:120
uint16_t length
Definition: tt21100.cpp:12
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
esphome::sensor::Sensor * sensor
Definition: statsd.h:38
void set_request_pin(GPIOPin *request_pin)
Definition: dsmr.h:75