ESPHome  2024.4.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  protected:
89  void receive_telegram_();
90  void receive_encrypted_telegram_();
91  void reset_telegram_();
92 
102  bool available_within_timeout_();
103 
104  // Request telegram
106  bool request_interval_reached_();
107  GPIOPin *request_pin_{nullptr};
108  uint32_t last_request_time_{0};
109  bool requesting_data_{false};
110  bool ready_to_request_data_();
111  void start_requesting_data_();
112  void stop_requesting_data_();
113 
114  // Read telegram
116  bool receive_timeout_reached_();
118  char *telegram_{nullptr};
119  size_t bytes_read_{0};
120  uint8_t *crypt_telegram_{nullptr};
121  size_t crypt_telegram_len_{0};
122  size_t crypt_bytes_read_{0};
123  uint32_t last_read_time_{0};
124  bool header_found_{false};
125  bool footer_found_{false};
126 
127 // Sensor member pointers
128 #define DSMR_DECLARE_SENSOR(s) sensor::Sensor *s_##s##_{nullptr};
129  DSMR_SENSOR_LIST(DSMR_DECLARE_SENSOR, )
130 
131 #define DSMR_DECLARE_TEXT_SENSOR(s) text_sensor::TextSensor *s_##s##_{nullptr};
132  DSMR_TEXT_SENSOR_LIST(DSMR_DECLARE_TEXT_SENSOR, )
133 
134  std::vector<uint8_t> decryption_key_{};
136 };
137 } // namespace dsmr
138 } // namespace esphome
139 
140 #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:115
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:105
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:117
uint16_t length
Definition: tt21100.cpp:12
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void set_request_pin(GPIOPin *request_pin)
Definition: dsmr.h:75