ESPHome 2025.6.3
Loading...
Searching...
No Matches
hlw8012.cpp
Go to the documentation of this file.
1#include "hlw8012.h"
2#include "esphome/core/log.h"
3
4namespace esphome {
5namespace hlw8012 {
6
7static const char *const TAG = "hlw8012";
8
9// valid for HLW8012 and CSE7759
10static const uint32_t HLW8012_CLOCK_FREQUENCY = 3579000;
11
13 float reference_voltage = 0;
14 ESP_LOGCONFIG(TAG, "Running setup");
15 this->sel_pin_->setup();
19
20 // Initialize multipliers
22 reference_voltage = 1.218f;
23 this->power_multiplier_ =
24 reference_voltage * reference_voltage * this->voltage_divider_ / this->current_resistor_ / 1721506.0f;
25 this->current_multiplier_ = reference_voltage / this->current_resistor_ / 94638.0f;
26 this->voltage_multiplier_ = reference_voltage * this->voltage_divider_ / 15397.0f;
27 } else {
28 // HLW8012 and CSE7759 have same reference specs
29 reference_voltage = 2.43f;
30 this->power_multiplier_ = reference_voltage * reference_voltage * this->voltage_divider_ / this->current_resistor_ *
31 64.0f / 24.0f / HLW8012_CLOCK_FREQUENCY;
32 this->current_multiplier_ = reference_voltage / this->current_resistor_ * 512.0f / 24.0f / HLW8012_CLOCK_FREQUENCY;
33 this->voltage_multiplier_ = reference_voltage * this->voltage_divider_ * 256.0f / HLW8012_CLOCK_FREQUENCY;
34 }
35}
37 ESP_LOGCONFIG(TAG, "HLW8012:");
38 LOG_PIN(" SEL Pin: ", this->sel_pin_)
39 LOG_PIN(" CF Pin: ", this->cf_pin_)
40 LOG_PIN(" CF1 Pin: ", this->cf1_pin_)
41 ESP_LOGCONFIG(TAG,
42 " Change measurement mode every %" PRIu32 "\n"
43 " Current resistor: %.1f mΩ\n"
44 " Voltage Divider: %.1f",
45 this->change_mode_every_, this->current_resistor_ * 1000.0f, this->voltage_divider_);
46 LOG_UPDATE_INTERVAL(this)
47 LOG_SENSOR(" ", "Voltage", this->voltage_sensor_)
48 LOG_SENSOR(" ", "Current", this->current_sensor_)
49 LOG_SENSOR(" ", "Power", this->power_sensor_)
50 LOG_SENSOR(" ", "Energy", this->energy_sensor_)
51}
54 // HLW8012 has 50% duty cycle
57 float cf_hz = raw_cf / (this->get_update_interval() / 1000.0f);
58 if (raw_cf <= 1) {
59 // don't count single pulse as power
60 cf_hz = 0.0f;
61 }
62 float cf1_hz = raw_cf1 / (this->get_update_interval() / 1000.0f);
63 if (raw_cf1 <= 1) {
64 // don't count single pulse as anything
65 cf1_hz = 0.0f;
66 }
67
68 if (this->nth_value_++ < 2) {
69 return;
70 }
71
72 float power = cf_hz * this->power_multiplier_;
73
74 if (this->change_mode_at_ != 0 || this->change_mode_every_ == 0) {
75 // Only read cf1 after one cycle. Apparently it's quite unstable after being changed.
76 if (this->current_mode_) {
77 float current = cf1_hz * this->current_multiplier_;
78 ESP_LOGD(TAG, "Got power=%.1fW, current=%.1fA", power, current);
79 if (this->current_sensor_ != nullptr) {
80 this->current_sensor_->publish_state(current);
81 }
82 } else {
83 float voltage = cf1_hz * this->voltage_multiplier_;
84 ESP_LOGD(TAG, "Got power=%.1fW, voltage=%.1fV", power, voltage);
85 if (this->voltage_sensor_ != nullptr) {
86 this->voltage_sensor_->publish_state(voltage);
87 }
88 }
89 }
90
91 if (this->power_sensor_ != nullptr) {
92 this->power_sensor_->publish_state(power);
93 }
94
95 if (this->energy_sensor_ != nullptr) {
96 cf_total_pulses_ += raw_cf;
97 float energy = cf_total_pulses_ * this->power_multiplier_ / 3600;
98 this->energy_sensor_->publish_state(energy);
99 }
100
101 if (this->change_mode_every_ != 0 && this->change_mode_at_++ == this->change_mode_every_) {
102 this->current_mode_ = !this->current_mode_;
103 ESP_LOGV(TAG, "Changing mode to %s mode", this->current_mode_ ? "CURRENT" : "VOLTAGE");
104 this->change_mode_at_ = 0;
106 }
107}
108
109} // namespace hlw8012
110} // namespace esphome
virtual void setup()=0
virtual void digital_write(bool value)=0
virtual uint32_t get_update_interval() const
Get the update interval in ms of this sensor.
sensor::Sensor * voltage_sensor_
Definition hlw8012.h:66
sensor::Sensor * current_sensor_
Definition hlw8012.h:67
pulse_counter::PulseCounterStorageBase & cf_store_
Definition hlw8012.h:63
sensor::Sensor * power_sensor_
Definition hlw8012.h:68
pulse_counter::PulseCounterStorageBase & cf1_store_
Definition hlw8012.h:65
HLW8012SensorModels sensor_model_
Definition hlw8012.h:59
sensor::Sensor * energy_sensor_
Definition hlw8012.h:69
float get_setup_priority() const override
Definition hlw8012.cpp:52
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:39
@ HLW8012_SENSOR_MODEL_BL0937
Definition hlw8012.h:18
const float DATA
For components that import data from directly connected sensors like DHT.
Definition component.cpp:20
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
virtual pulse_counter_t read_raw_value()=0
virtual bool pulse_counter_setup(InternalGPIOPin *pin)=0