ESPHome  2022.12.8
pzemdc.cpp
Go to the documentation of this file.
1 #include "pzemdc.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace pzemdc {
6 
7 static const char *const TAG = "pzemdc";
8 
9 static const uint8_t PZEM_CMD_READ_IN_REGISTERS = 0x04;
10 static const uint8_t PZEM_REGISTER_COUNT = 10; // 10x 16-bit registers
11 
12 void PZEMDC::on_modbus_data(const std::vector<uint8_t> &data) {
13  if (data.size() < 16) {
14  ESP_LOGW(TAG, "Invalid size for PZEM DC!");
15  return;
16  }
17 
18  // See https://github.com/esphome/feature-requests/issues/49#issuecomment-538636809
19  // 0 1 2 3 4 5 6 7 = ModBus register
20  // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 = Buffer index
21  // 01 04 10 05 40 00 0A 00 0D 00 00 00 02 00 00 00 00 00 00 D6 29
22  // Id Cc Sz Volt- Curre Power------ Energy----- HiAlm LoAlm Crc--
23 
24  auto pzem_get_16bit = [&](size_t i) -> uint16_t {
25  return (uint16_t(data[i + 0]) << 8) | (uint16_t(data[i + 1]) << 0);
26  };
27  auto pzem_get_32bit = [&](size_t i) -> uint32_t {
28  return (uint32_t(pzem_get_16bit(i + 2)) << 16) | (uint32_t(pzem_get_16bit(i + 0)) << 0);
29  };
30 
31  uint16_t raw_voltage = pzem_get_16bit(0);
32  float voltage = raw_voltage / 100.0f; // max 655.35 V
33 
34  uint16_t raw_current = pzem_get_16bit(2);
35  float current = raw_current / 100.0f; // max 655.35 A
36 
37  uint32_t raw_power = pzem_get_32bit(4);
38  float power = raw_power / 10.0f; // max 429496729.5 W
39 
40  ESP_LOGD(TAG, "PZEM DC: V=%.1f V, I=%.3f A, P=%.1f W", voltage, current, power);
41  if (this->voltage_sensor_ != nullptr)
42  this->voltage_sensor_->publish_state(voltage);
43  if (this->current_sensor_ != nullptr)
44  this->current_sensor_->publish_state(current);
45  if (this->power_sensor_ != nullptr)
46  this->power_sensor_->publish_state(power);
47 }
48 
49 void PZEMDC::update() { this->send(PZEM_CMD_READ_IN_REGISTERS, 0, 8); }
51  ESP_LOGCONFIG(TAG, "PZEMDC:");
52  ESP_LOGCONFIG(TAG, " Address: 0x%02X", this->address_);
53  LOG_SENSOR("", "Voltage", this->voltage_sensor_);
54  LOG_SENSOR("", "Current", this->current_sensor_);
55  LOG_SENSOR("", "Power", this->power_sensor_);
56 }
57 
58 } // namespace pzemdc
59 } // namespace esphome
void dump_config() override
Definition: pzemdc.cpp:50
sensor::Sensor * power_sensor_
Definition: pzemdc.h:29
sensor::Sensor * current_sensor_
Definition: pzemdc.h:28
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:72
Definition: a4988.cpp:4
void send(uint8_t function, uint16_t start_address, uint16_t number_of_entities, uint8_t payload_len=0, const uint8_t *payload=nullptr)
Definition: modbus.h:51
void on_modbus_data(const std::vector< uint8_t > &data) override
Definition: pzemdc.cpp:12
sensor::Sensor * voltage_sensor_
Definition: pzemdc.h:27
void update() override
Definition: pzemdc.cpp:49