ESPHome 2026.10.0-dev
Loading...
Searching...
No Matches
sdm_meter.cpp
Go to the documentation of this file.
1#include "sdm_meter.h"
3#include "esphome/core/log.h"
4
6
7namespace helpers = modbus::helpers;
8
9static const char *const TAG = "sdm_meter";
10
11static const uint8_t MODBUS_REGISTER_COUNT = 80; // 80 x 16-bit registers (40 float values)
12
13void SDMMeter::on_read_input_registers(uint16_t start_address, std::span<const uint16_t> registers,
16 return; // the hub already logs exception responses
17
18 // Publish a sensor if both of its registers are in this response; skipping absent registers keeps
19 // this correct for any read range, so the poll may be split into multiple requests.
20 auto publish = [&](uint16_t reg, sensor::Sensor *sensor) {
21 if (sensor == nullptr)
22 return;
24 sensor->publish_state(*value);
25 };
26
27 for (uint8_t i = 0; i < 3; i++) {
28 auto &phase = this->phases_[i];
29 if (!phase.setup)
30 continue;
31 publish(SDM_PHASE_1_VOLTAGE + i * 2, phase.voltage_sensor_);
32 publish(SDM_PHASE_1_CURRENT + i * 2, phase.current_sensor_);
33 publish(SDM_PHASE_1_ACTIVE_POWER + i * 2, phase.active_power_sensor_);
34 publish(SDM_PHASE_1_APPARENT_POWER + i * 2, phase.apparent_power_sensor_);
35 publish(SDM_PHASE_1_REACTIVE_POWER + i * 2, phase.reactive_power_sensor_);
36 publish(SDM_PHASE_1_POWER_FACTOR + i * 2, phase.power_factor_sensor_);
37 publish(SDM_PHASE_1_ANGLE + i * 2, phase.phase_angle_sensor_);
38 }
39
40 publish(SDM_TOTAL_SYSTEM_POWER, this->total_power_sensor_);
41 publish(SDM_FREQUENCY, this->frequency_sensor_);
42 publish(SDM_IMPORT_ACTIVE_ENERGY, this->import_active_energy_sensor_);
43 publish(SDM_EXPORT_ACTIVE_ENERGY, this->export_active_energy_sensor_);
44 publish(SDM_IMPORT_REACTIVE_ENERGY, this->import_reactive_energy_sensor_);
45 publish(SDM_EXPORT_REACTIVE_ENERGY, this->export_reactive_energy_sensor_);
46}
47
48void SDMMeter::update() { this->read_input_registers(0, MODBUS_REGISTER_COUNT); }
50 ESP_LOGCONFIG(TAG,
51 "SDM Meter:\n"
52 " Address: 0x%02X",
53 this->address_);
54 for (uint8_t i = 0; i < 3; i++) {
55 auto phase = this->phases_[i];
56 if (!phase.setup)
57 continue;
58 ESP_LOGCONFIG(TAG, " Phase %c", i + 'A');
59 LOG_SENSOR(" ", "Voltage", phase.voltage_sensor_);
60 LOG_SENSOR(" ", "Current", phase.current_sensor_);
61 LOG_SENSOR(" ", "Active Power", phase.active_power_sensor_);
62 LOG_SENSOR(" ", "Apparent Power", phase.apparent_power_sensor_);
63 LOG_SENSOR(" ", "Reactive Power", phase.reactive_power_sensor_);
64 LOG_SENSOR(" ", "Power Factor", phase.power_factor_sensor_);
65 LOG_SENSOR(" ", "Phase Angle", phase.phase_angle_sensor_);
66 }
67 LOG_SENSOR(" ", "Total Power", this->total_power_sensor_);
68 LOG_SENSOR(" ", "Frequency", this->frequency_sensor_);
69 LOG_SENSOR(" ", "Import Active Energy", this->import_active_energy_sensor_);
70 LOG_SENSOR(" ", "Export Active Energy", this->export_active_energy_sensor_);
71 LOG_SENSOR(" ", "Import Reactive Energy", this->import_reactive_energy_sensor_);
72 LOG_SENSOR(" ", "Export Reactive Energy", this->export_reactive_energy_sensor_);
73}
74
75} // namespace esphome::sdm_meter
uint8_t status
Definition bl0942.h:8
sensor::Sensor * export_active_energy_sensor_
Definition sdm_meter.h:77
void on_read_input_registers(uint16_t start_address, std::span< const uint16_t > registers, modbus::ResponseStatus status) override
Definition sdm_meter.cpp:13
sensor::Sensor * total_power_sensor_
Definition sdm_meter.h:75
void dump_config() override
Definition sdm_meter.cpp:49
sensor::Sensor * export_reactive_energy_sensor_
Definition sdm_meter.h:79
struct esphome::sdm_meter::SDMMeter::SDMPhase phases_[3]
sensor::Sensor * import_active_energy_sensor_
Definition sdm_meter.h:76
sensor::Sensor * import_reactive_energy_sensor_
Definition sdm_meter.h:78
sensor::Sensor * frequency_sensor_
Definition sdm_meter.h:74
Base-class for all sensors.
Definition sensor.h:47
constexpr std::optional< RegisterValueType< VALUE_TYPE > > value_at(std::span< const uint16_t > registers, uint16_t start_address, uint16_t address)
The value stored at an absolute register address, or nullopt when it is not wholly inside this respon...
std::optional< ExceptionCode > ResponseStatus
Definition modbus.h:306
bool succeeded(ResponseStatus status)
True when a transaction carried no exception.
Definition modbus.h:309