8 static const char *
const TAG =
"sdm_meter";
10 static const uint8_t MODBUS_CMD_READ_IN_REGISTERS = 0x04;
11 static const uint8_t MODBUS_REGISTER_COUNT = 80;
14 if (data.size() < MODBUS_REGISTER_COUNT * 2) {
15 ESP_LOGW(TAG,
"Invalid size for SDMMeter!");
19 auto sdm_meter_get_float = [&](
size_t i) ->
float {
20 uint32_t temp =
encode_uint32(data[i], data[i + 1], data[i + 2], data[i + 3]);
22 memcpy(&f, &temp,
sizeof(f));
26 for (uint8_t i = 0; i < 3; i++) {
31 float voltage = sdm_meter_get_float(SDM_PHASE_1_VOLTAGE * 2 + (i * 4));
32 float current = sdm_meter_get_float(SDM_PHASE_1_CURRENT * 2 + (i * 4));
33 float active_power = sdm_meter_get_float(SDM_PHASE_1_ACTIVE_POWER * 2 + (i * 4));
34 float apparent_power = sdm_meter_get_float(SDM_PHASE_1_APPARENT_POWER * 2 + (i * 4));
35 float reactive_power = sdm_meter_get_float(SDM_PHASE_1_REACTIVE_POWER * 2 + (i * 4));
36 float power_factor = sdm_meter_get_float(SDM_PHASE_1_POWER_FACTOR * 2 + (i * 4));
37 float phase_angle = sdm_meter_get_float(SDM_PHASE_1_ANGLE * 2 + (i * 4));
41 "SDMMeter Phase %c: V=%.3f V, I=%.3f A, Active P=%.3f W, Apparent P=%.3f VA, Reactive P=%.3f VAR, PF=%.3f, " 43 i +
'A', voltage, current, active_power, apparent_power, reactive_power, power_factor, phase_angle);
44 if (phase.voltage_sensor_ !=
nullptr)
45 phase.voltage_sensor_->publish_state(voltage);
46 if (phase.current_sensor_ !=
nullptr)
47 phase.current_sensor_->publish_state(current);
48 if (phase.active_power_sensor_ !=
nullptr)
49 phase.active_power_sensor_->publish_state(active_power);
50 if (phase.apparent_power_sensor_ !=
nullptr)
51 phase.apparent_power_sensor_->publish_state(apparent_power);
52 if (phase.reactive_power_sensor_ !=
nullptr)
53 phase.reactive_power_sensor_->publish_state(reactive_power);
54 if (phase.power_factor_sensor_ !=
nullptr)
55 phase.power_factor_sensor_->publish_state(power_factor);
56 if (phase.phase_angle_sensor_ !=
nullptr)
57 phase.phase_angle_sensor_->publish_state(phase_angle);
60 float total_power = sdm_meter_get_float(SDM_TOTAL_SYSTEM_POWER * 2);
61 float frequency = sdm_meter_get_float(SDM_FREQUENCY * 2);
62 float import_active_energy = sdm_meter_get_float(SDM_IMPORT_ACTIVE_ENERGY * 2);
63 float export_active_energy = sdm_meter_get_float(SDM_EXPORT_ACTIVE_ENERGY * 2);
64 float import_reactive_energy = sdm_meter_get_float(SDM_IMPORT_REACTIVE_ENERGY * 2);
65 float export_reactive_energy = sdm_meter_get_float(SDM_EXPORT_REACTIVE_ENERGY * 2);
67 ESP_LOGD(TAG,
"SDMMeter: F=%.3f Hz, Im.A.E=%.3f Wh, Ex.A.E=%.3f Wh, Im.R.E=%.3f VARh, Ex.R.E=%.3f VARh, T.P=%.3f W",
68 frequency, import_active_energy, export_active_energy, import_reactive_energy, export_reactive_energy,
87 ESP_LOGCONFIG(TAG,
"SDM Meter:");
88 ESP_LOGCONFIG(TAG,
" Address: 0x%02X", this->
address_);
89 for (uint8_t i = 0; i < 3; i++) {
93 ESP_LOGCONFIG(TAG,
" Phase %c", i +
'A');
94 LOG_SENSOR(
" ",
"Voltage", phase.voltage_sensor_);
95 LOG_SENSOR(
" ",
"Current", phase.current_sensor_);
96 LOG_SENSOR(
" ",
"Active Power", phase.active_power_sensor_);
97 LOG_SENSOR(
" ",
"Apparent Power", phase.apparent_power_sensor_);
98 LOG_SENSOR(
" ",
"Reactive Power", phase.reactive_power_sensor_);
99 LOG_SENSOR(
" ",
"Power Factor", phase.power_factor_sensor_);
100 LOG_SENSOR(
" ",
"Phase Angle", phase.phase_angle_sensor_);
sensor::Sensor * import_active_energy_sensor_
void dump_config() override
struct esphome::sdm_meter::SDMMeter::SDMPhase phases_[3]
sensor::Sensor * frequency_sensor_
constexpr uint32_t encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4)
Encode a 32-bit value given four bytes in most to least significant byte order.
sensor::Sensor * export_active_energy_sensor_
void publish_state(float state)
Publish a new state to the front-end.
sensor::Sensor * export_reactive_energy_sensor_
sensor::Sensor * import_reactive_energy_sensor_
Implementation of SPI Controller mode.
void on_modbus_data(const std::vector< uint8_t > &data) override
void send(uint8_t function, uint16_t start_address, uint16_t number_of_entities, uint8_t payload_len=0, const uint8_t *payload=nullptr)
sensor::Sensor * total_power_sensor_