ESPHome 2026.3.0-dev
Loading...
Searching...
No Matches
dlms_meter.h
Go to the documentation of this file.
1#pragma once
2
5#include "esphome/core/log.h"
6#ifdef USE_SENSOR
8#endif
9#ifdef USE_TEXT_SENSOR
11#endif
13
14#include "mbus.h"
15#include "dlms.h"
16#include "obis.h"
17
18#include <array>
19#include <vector>
20
21namespace esphome::dlms_meter {
22
23#ifndef DLMS_METER_SENSOR_LIST
24#define DLMS_METER_SENSOR_LIST(F, SEP)
25#endif
26
27#ifndef DLMS_METER_TEXT_SENSOR_LIST
28#define DLMS_METER_TEXT_SENSOR_LIST(F, SEP)
29#endif
30
31struct MeterData {
32 float voltage_l1 = 0.0f; // Voltage L1
33 float voltage_l2 = 0.0f; // Voltage L2
34 float voltage_l3 = 0.0f; // Voltage L3
35 float current_l1 = 0.0f; // Current L1
36 float current_l2 = 0.0f; // Current L2
37 float current_l3 = 0.0f; // Current L3
38 float active_power_plus = 0.0f; // Active power taken from grid
39 float active_power_minus = 0.0f; // Active power put into grid
40 float active_energy_plus = 0.0f; // Active energy taken from grid
41 float active_energy_minus = 0.0f; // Active energy put into grid
42 float reactive_energy_plus = 0.0f; // Reactive energy taken from grid
43 float reactive_energy_minus = 0.0f; // Reactive energy put into grid
44 char timestamp[27]{}; // Text sensor for the timestamp value
45
46 // Netz NOE
47 float power_factor = 0.0f; // Power Factor
48 char meternumber[13]{}; // Text sensor for the meterNumber value
49};
50
51// Provider constants
52enum Providers : uint32_t { PROVIDER_GENERIC = 0x00, PROVIDER_NETZNOE = 0x01 };
53
55 public:
56 DlmsMeterComponent() = default;
57
58 void dump_config() override;
59 void loop() override;
60
61 void set_decryption_key(const std::array<uint8_t, 16> &key) { this->decryption_key_ = key; }
62 void set_provider(uint32_t provider) { this->provider_ = provider; }
63
65#define DLMS_METER_PUBLISH_SENSOR(s) \
66 if (this->s##_sensor_ != nullptr) \
67 s##_sensor_->publish_state(data.s);
68 DLMS_METER_SENSOR_LIST(DLMS_METER_PUBLISH_SENSOR, )
69
70#define DLMS_METER_PUBLISH_TEXT_SENSOR(s) \
71 if (this->s##_text_sensor_ != nullptr) \
72 s##_text_sensor_->publish_state(data.s);
73 DLMS_METER_TEXT_SENSOR_LIST(DLMS_METER_PUBLISH_TEXT_SENSOR, )
74 }
75
77 DLMS_METER_TEXT_SENSOR_LIST(SUB_TEXT_SENSOR, )
78
79 protected:
80 bool parse_mbus_(std::vector<uint8_t> &mbus_payload);
81 bool parse_dlms_(const std::vector<uint8_t> &mbus_payload, uint16_t &message_length, uint8_t &systitle_length,
82 uint16_t &header_offset);
83 bool decrypt_(std::vector<uint8_t> &mbus_payload, uint16_t message_length, uint8_t systitle_length,
84 uint16_t header_offset);
85 void decode_obis_(uint8_t *plaintext, uint16_t message_length);
86
87 std::vector<uint8_t> receive_buffer_; // Stores the packet currently being received
88 std::vector<uint8_t> mbus_payload_; // Parsed M-Bus payload, reused to avoid heap churn
89 uint32_t last_read_ = 0; // Timestamp when data was last read
90 uint32_t read_timeout_ = 1000; // Time to wait after last byte before considering data complete
91
92 uint32_t provider_ = PROVIDER_GENERIC; // Provider of the meter / your grid operator
93 std::array<uint8_t, 16> decryption_key_;
94};
95
96} // namespace esphome::dlms_meter
void set_provider(uint32_t provider)
Definition dlms_meter.h:62
bool parse_dlms_(const std::vector< uint8_t > &mbus_payload, uint16_t &message_length, uint8_t &systitle_length, uint16_t &header_offset)
bool decrypt_(std::vector< uint8_t > &mbus_payload, uint16_t message_length, uint8_t systitle_length, uint16_t header_offset)
void set_decryption_key(const std::array< uint8_t, 16 > &key)
Definition dlms_meter.h:61
std::vector< uint8_t > mbus_payload_
Definition dlms_meter.h:88
bool parse_mbus_(std::vector< uint8_t > &mbus_payload)
void decode_obis_(uint8_t *plaintext, uint16_t message_length)
void publish_sensors(MeterData &data)
Definition dlms_meter.h:64
std::vector< uint8_t > receive_buffer_
Definition dlms_meter.h:87
std::array< uint8_t, 16 > decryption_key_
Definition dlms_meter.h:93
DLMS_METER_SENSOR_LIST(SUB_SENSOR,) DLMS_METER_TEXT_SENSOR_LIST(SUB_TEXT_SENSOR