mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 00:18:11 +01:00
hlw8012: fix constants for BL0937 (#1973)
Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
parent
52d19fa43d
commit
d31040f5d8
4 changed files with 46 additions and 12 deletions
|
@ -6,15 +6,32 @@ namespace hlw8012 {
|
||||||
|
|
||||||
static const char *const TAG = "hlw8012";
|
static const char *const TAG = "hlw8012";
|
||||||
|
|
||||||
|
// valid for HLW8012 and CSE7759
|
||||||
static const uint32_t HLW8012_CLOCK_FREQUENCY = 3579000;
|
static const uint32_t HLW8012_CLOCK_FREQUENCY = 3579000;
|
||||||
static const float HLW8012_REFERENCE_VOLTAGE = 2.43f;
|
|
||||||
|
|
||||||
void HLW8012Component::setup() {
|
void HLW8012Component::setup() {
|
||||||
|
float reference_voltage = 0;
|
||||||
ESP_LOGCONFIG(TAG, "Setting up HLW8012...");
|
ESP_LOGCONFIG(TAG, "Setting up HLW8012...");
|
||||||
this->sel_pin_->setup();
|
this->sel_pin_->setup();
|
||||||
this->sel_pin_->digital_write(this->current_mode_);
|
this->sel_pin_->digital_write(this->current_mode_);
|
||||||
this->cf_store_.pulse_counter_setup(this->cf_pin_);
|
this->cf_store_.pulse_counter_setup(this->cf_pin_);
|
||||||
this->cf1_store_.pulse_counter_setup(this->cf1_pin_);
|
this->cf1_store_.pulse_counter_setup(this->cf1_pin_);
|
||||||
|
|
||||||
|
// Initialize multipliers
|
||||||
|
if (this->sensor_model_ == HLW8012_SENSOR_MODEL_BL0937) {
|
||||||
|
reference_voltage = 1.218f;
|
||||||
|
this->power_multiplier_ =
|
||||||
|
reference_voltage * reference_voltage * this->voltage_divider_ / this->current_resistor_ / 1721506.0f;
|
||||||
|
this->current_multiplier_ = reference_voltage / this->current_resistor_ / 94638.0f;
|
||||||
|
this->voltage_multiplier_ = reference_voltage * this->voltage_divider_ / 15397.0f;
|
||||||
|
} else {
|
||||||
|
// HLW8012 and CSE7759 have same reference specs
|
||||||
|
reference_voltage = 2.43f;
|
||||||
|
this->power_multiplier_ = reference_voltage * reference_voltage * this->voltage_divider_ / this->current_resistor_ *
|
||||||
|
64.0f / 24.0f / HLW8012_CLOCK_FREQUENCY;
|
||||||
|
this->current_multiplier_ = reference_voltage / this->current_resistor_ * 512.0f / 24.0f / HLW8012_CLOCK_FREQUENCY;
|
||||||
|
this->voltage_multiplier_ = reference_voltage * this->voltage_divider_ * 256.0f / HLW8012_CLOCK_FREQUENCY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
void HLW8012Component::dump_config() {
|
void HLW8012Component::dump_config() {
|
||||||
ESP_LOGCONFIG(TAG, "HLW8012:");
|
ESP_LOGCONFIG(TAG, "HLW8012:");
|
||||||
|
@ -49,25 +66,18 @@ void HLW8012Component::update() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float v_ref_squared = HLW8012_REFERENCE_VOLTAGE * HLW8012_REFERENCE_VOLTAGE;
|
float power = cf_hz * this->power_multiplier_;
|
||||||
const float power_multiplier_micros =
|
|
||||||
64000000.0f * v_ref_squared * this->voltage_divider_ / this->current_resistor_ / 24.0f / HLW8012_CLOCK_FREQUENCY;
|
|
||||||
float power = cf_hz * power_multiplier_micros / 1000000.0f;
|
|
||||||
|
|
||||||
if (this->change_mode_at_ != 0) {
|
if (this->change_mode_at_ != 0) {
|
||||||
// Only read cf1 after one cycle. Apparently it's quite unstable after being changed.
|
// Only read cf1 after one cycle. Apparently it's quite unstable after being changed.
|
||||||
if (this->current_mode_) {
|
if (this->current_mode_) {
|
||||||
const float current_multiplier_micros =
|
float current = cf1_hz * this->current_multiplier_;
|
||||||
512000000.0f * HLW8012_REFERENCE_VOLTAGE / this->current_resistor_ / 24.0f / HLW8012_CLOCK_FREQUENCY;
|
|
||||||
float current = cf1_hz * current_multiplier_micros / 1000000.0f;
|
|
||||||
ESP_LOGD(TAG, "Got power=%.1fW, current=%.1fA", power, current);
|
ESP_LOGD(TAG, "Got power=%.1fW, current=%.1fA", power, current);
|
||||||
if (this->current_sensor_ != nullptr) {
|
if (this->current_sensor_ != nullptr) {
|
||||||
this->current_sensor_->publish_state(current);
|
this->current_sensor_->publish_state(current);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const float voltage_multiplier_micros =
|
float voltage = cf1_hz * this->voltage_multiplier_;
|
||||||
256000000.0f * HLW8012_REFERENCE_VOLTAGE * this->voltage_divider_ / HLW8012_CLOCK_FREQUENCY;
|
|
||||||
float voltage = cf1_hz * voltage_multiplier_micros / 1000000.0f;
|
|
||||||
ESP_LOGD(TAG, "Got power=%.1fW, voltage=%.1fV", power, voltage);
|
ESP_LOGD(TAG, "Got power=%.1fW, voltage=%.1fV", power, voltage);
|
||||||
if (this->voltage_sensor_ != nullptr) {
|
if (this->voltage_sensor_ != nullptr) {
|
||||||
this->voltage_sensor_->publish_state(voltage);
|
this->voltage_sensor_->publish_state(voltage);
|
||||||
|
@ -81,7 +91,7 @@ void HLW8012Component::update() {
|
||||||
|
|
||||||
if (this->energy_sensor_ != nullptr) {
|
if (this->energy_sensor_ != nullptr) {
|
||||||
cf_total_pulses_ += raw_cf;
|
cf_total_pulses_ += raw_cf;
|
||||||
float energy = cf_total_pulses_ * power_multiplier_micros / 3600 / 1000000.0f;
|
float energy = cf_total_pulses_ * this->power_multiplier_ / 3600;
|
||||||
this->energy_sensor_->publish_state(energy);
|
this->energy_sensor_->publish_state(energy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,12 @@ namespace hlw8012 {
|
||||||
|
|
||||||
enum HLW8012InitialMode { HLW8012_INITIAL_MODE_CURRENT = 0, HLW8012_INITIAL_MODE_VOLTAGE };
|
enum HLW8012InitialMode { HLW8012_INITIAL_MODE_CURRENT = 0, HLW8012_INITIAL_MODE_VOLTAGE };
|
||||||
|
|
||||||
|
enum HLW8012SensorModels {
|
||||||
|
HLW8012_SENSOR_MODEL_HLW8012 = 0,
|
||||||
|
HLW8012_SENSOR_MODEL_CSE7759,
|
||||||
|
HLW8012_SENSOR_MODEL_BL0937
|
||||||
|
};
|
||||||
|
|
||||||
class HLW8012Component : public PollingComponent {
|
class HLW8012Component : public PollingComponent {
|
||||||
public:
|
public:
|
||||||
void setup() override;
|
void setup() override;
|
||||||
|
@ -20,6 +26,7 @@ class HLW8012Component : public PollingComponent {
|
||||||
void set_initial_mode(HLW8012InitialMode initial_mode) {
|
void set_initial_mode(HLW8012InitialMode initial_mode) {
|
||||||
current_mode_ = initial_mode == HLW8012_INITIAL_MODE_CURRENT;
|
current_mode_ = initial_mode == HLW8012_INITIAL_MODE_CURRENT;
|
||||||
}
|
}
|
||||||
|
void set_sensor_model(HLW8012SensorModels sensor_model) { sensor_model_ = sensor_model; }
|
||||||
void set_change_mode_every(uint32_t change_mode_every) { change_mode_every_ = change_mode_every; }
|
void set_change_mode_every(uint32_t change_mode_every) { change_mode_every_ = change_mode_every; }
|
||||||
void set_current_resistor(float current_resistor) { current_resistor_ = current_resistor; }
|
void set_current_resistor(float current_resistor) { current_resistor_ = current_resistor; }
|
||||||
void set_voltage_divider(float voltage_divider) { voltage_divider_ = voltage_divider; }
|
void set_voltage_divider(float voltage_divider) { voltage_divider_ = voltage_divider; }
|
||||||
|
@ -38,6 +45,7 @@ class HLW8012Component : public PollingComponent {
|
||||||
uint32_t change_mode_every_{8};
|
uint32_t change_mode_every_{8};
|
||||||
float current_resistor_{0.001};
|
float current_resistor_{0.001};
|
||||||
float voltage_divider_{2351};
|
float voltage_divider_{2351};
|
||||||
|
HLW8012SensorModels sensor_model_{HLW8012_SENSOR_MODEL_HLW8012};
|
||||||
uint64_t cf_total_pulses_{0};
|
uint64_t cf_total_pulses_{0};
|
||||||
GPIOPin *sel_pin_;
|
GPIOPin *sel_pin_;
|
||||||
GPIOPin *cf_pin_;
|
GPIOPin *cf_pin_;
|
||||||
|
@ -48,6 +56,10 @@ class HLW8012Component : public PollingComponent {
|
||||||
sensor::Sensor *current_sensor_{nullptr};
|
sensor::Sensor *current_sensor_{nullptr};
|
||||||
sensor::Sensor *power_sensor_{nullptr};
|
sensor::Sensor *power_sensor_{nullptr};
|
||||||
sensor::Sensor *energy_sensor_{nullptr};
|
sensor::Sensor *energy_sensor_{nullptr};
|
||||||
|
|
||||||
|
float voltage_multiplier_{0.0f};
|
||||||
|
float current_multiplier_{0.0f};
|
||||||
|
float power_multiplier_{0.0f};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace hlw8012
|
} // namespace hlw8012
|
||||||
|
|
|
@ -11,6 +11,7 @@ from esphome.const import (
|
||||||
CONF_POWER,
|
CONF_POWER,
|
||||||
CONF_ENERGY,
|
CONF_ENERGY,
|
||||||
CONF_SEL_PIN,
|
CONF_SEL_PIN,
|
||||||
|
CONF_MODEL,
|
||||||
CONF_VOLTAGE,
|
CONF_VOLTAGE,
|
||||||
CONF_VOLTAGE_DIVIDER,
|
CONF_VOLTAGE_DIVIDER,
|
||||||
DEVICE_CLASS_CURRENT,
|
DEVICE_CLASS_CURRENT,
|
||||||
|
@ -31,11 +32,19 @@ AUTO_LOAD = ["pulse_counter"]
|
||||||
hlw8012_ns = cg.esphome_ns.namespace("hlw8012")
|
hlw8012_ns = cg.esphome_ns.namespace("hlw8012")
|
||||||
HLW8012Component = hlw8012_ns.class_("HLW8012Component", cg.PollingComponent)
|
HLW8012Component = hlw8012_ns.class_("HLW8012Component", cg.PollingComponent)
|
||||||
HLW8012InitialMode = hlw8012_ns.enum("HLW8012InitialMode")
|
HLW8012InitialMode = hlw8012_ns.enum("HLW8012InitialMode")
|
||||||
|
HLW8012SensorModels = hlw8012_ns.enum("HLW8012SensorModels")
|
||||||
|
|
||||||
INITIAL_MODES = {
|
INITIAL_MODES = {
|
||||||
CONF_CURRENT: HLW8012InitialMode.HLW8012_INITIAL_MODE_CURRENT,
|
CONF_CURRENT: HLW8012InitialMode.HLW8012_INITIAL_MODE_CURRENT,
|
||||||
CONF_VOLTAGE: HLW8012InitialMode.HLW8012_INITIAL_MODE_VOLTAGE,
|
CONF_VOLTAGE: HLW8012InitialMode.HLW8012_INITIAL_MODE_VOLTAGE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MODELS = {
|
||||||
|
"HLW8012": HLW8012SensorModels.HLW8012_SENSOR_MODEL_HLW8012,
|
||||||
|
"CSE7759": HLW8012SensorModels.HLW8012_SENSOR_MODEL_CSE7759,
|
||||||
|
"BL0937": HLW8012SensorModels.HLW8012_SENSOR_MODEL_BL0937,
|
||||||
|
}
|
||||||
|
|
||||||
CONF_CF1_PIN = "cf1_pin"
|
CONF_CF1_PIN = "cf1_pin"
|
||||||
CONF_CF_PIN = "cf_pin"
|
CONF_CF_PIN = "cf_pin"
|
||||||
CONFIG_SCHEMA = cv.Schema(
|
CONFIG_SCHEMA = cv.Schema(
|
||||||
|
@ -62,6 +71,7 @@ CONFIG_SCHEMA = cv.Schema(
|
||||||
),
|
),
|
||||||
cv.Optional(CONF_CURRENT_RESISTOR, default=0.001): cv.resistance,
|
cv.Optional(CONF_CURRENT_RESISTOR, default=0.001): cv.resistance,
|
||||||
cv.Optional(CONF_VOLTAGE_DIVIDER, default=2351): cv.positive_float,
|
cv.Optional(CONF_VOLTAGE_DIVIDER, default=2351): cv.positive_float,
|
||||||
|
cv.Optional(CONF_MODEL, default="HLW8012"): cv.enum(MODELS, upper=True),
|
||||||
cv.Optional(CONF_CHANGE_MODE_EVERY, default=8): cv.All(
|
cv.Optional(CONF_CHANGE_MODE_EVERY, default=8): cv.All(
|
||||||
cv.uint32_t, cv.Range(min=1)
|
cv.uint32_t, cv.Range(min=1)
|
||||||
),
|
),
|
||||||
|
@ -99,3 +109,4 @@ async def to_code(config):
|
||||||
cg.add(var.set_voltage_divider(config[CONF_VOLTAGE_DIVIDER]))
|
cg.add(var.set_voltage_divider(config[CONF_VOLTAGE_DIVIDER]))
|
||||||
cg.add(var.set_change_mode_every(config[CONF_CHANGE_MODE_EVERY]))
|
cg.add(var.set_change_mode_every(config[CONF_CHANGE_MODE_EVERY]))
|
||||||
cg.add(var.set_initial_mode(INITIAL_MODES[config[CONF_INITIAL_MODE]]))
|
cg.add(var.set_initial_mode(INITIAL_MODES[config[CONF_INITIAL_MODE]]))
|
||||||
|
cg.add(var.set_sensor_model(config[CONF_MODEL]))
|
||||||
|
|
|
@ -514,6 +514,7 @@ sensor:
|
||||||
voltage_divider: 2351
|
voltage_divider: 2351
|
||||||
change_mode_every: 16
|
change_mode_every: 16
|
||||||
initial_mode: VOLTAGE
|
initial_mode: VOLTAGE
|
||||||
|
model: hlw8012
|
||||||
- platform: total_daily_energy
|
- platform: total_daily_energy
|
||||||
power_id: hlw8012_power
|
power_id: hlw8012_power
|
||||||
name: 'HLW8012 Total Daily Energy'
|
name: 'HLW8012 Total Daily Energy'
|
||||||
|
|
Loading…
Reference in a new issue