ADE7953: Add the ability to use accumulating energy registers, more precise power reporting (#6311)

Co-authored-by: Jesse Hills <3060199+jesserockz@users.noreply.github.com>
This commit is contained in:
Sorin Iordachescu 2024-03-12 23:17:06 +00:00 committed by GitHub
parent c7305e15a7
commit 77214a677b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 40 additions and 12 deletions

View file

@ -41,6 +41,7 @@ CONF_CURRENT_GAIN_A = "current_gain_a"
CONF_CURRENT_GAIN_B = "current_gain_b" CONF_CURRENT_GAIN_B = "current_gain_b"
CONF_ACTIVE_POWER_GAIN_A = "active_power_gain_a" CONF_ACTIVE_POWER_GAIN_A = "active_power_gain_a"
CONF_ACTIVE_POWER_GAIN_B = "active_power_gain_b" CONF_ACTIVE_POWER_GAIN_B = "active_power_gain_b"
CONF_USE_ACCUMULATED_ENERGY_REGISTERS = "use_accumulated_energy_registers"
PGA_GAINS = { PGA_GAINS = {
"1x": 0b000, "1x": 0b000,
"2x": 0b001, "2x": 0b001,
@ -155,6 +156,7 @@ ADE7953_CONFIG_SCHEMA = cv.Schema(
cv.Optional(CONF_ACTIVE_POWER_GAIN_B, default=0x400000): cv.hex_int_range( cv.Optional(CONF_ACTIVE_POWER_GAIN_B, default=0x400000): cv.hex_int_range(
min=0x100000, max=0x800000 min=0x100000, max=0x800000
), ),
cv.Optional(CONF_USE_ACCUMULATED_ENERGY_REGISTERS, default=False): cv.boolean,
} }
).extend(cv.polling_component_schema("60s")) ).extend(cv.polling_component_schema("60s"))
@ -174,6 +176,9 @@ async def register_ade7953(var, config):
cg.add(var.set_bigain(config.get(CONF_CURRENT_GAIN_B))) cg.add(var.set_bigain(config.get(CONF_CURRENT_GAIN_B)))
cg.add(var.set_awgain(config.get(CONF_ACTIVE_POWER_GAIN_A))) cg.add(var.set_awgain(config.get(CONF_ACTIVE_POWER_GAIN_A)))
cg.add(var.set_bwgain(config.get(CONF_ACTIVE_POWER_GAIN_B))) cg.add(var.set_bwgain(config.get(CONF_ACTIVE_POWER_GAIN_B)))
cg.add(
var.set_use_acc_energy_regs(config.get(CONF_USE_ACCUMULATED_ENERGY_REGISTERS))
)
for key in [ for key in [
CONF_VOLTAGE, CONF_VOLTAGE,

View file

@ -6,6 +6,9 @@ namespace ade7953_base {
static const char *const TAG = "ade7953"; static const char *const TAG = "ade7953";
static const float ADE_POWER_FACTOR = 154.0f;
static const float ADE_WATTSEC_POWER_FACTOR = ADE_POWER_FACTOR * ADE_POWER_FACTOR / 3600;
void ADE7953::setup() { void ADE7953::setup() {
if (this->irq_pin_ != nullptr) { if (this->irq_pin_ != nullptr) {
this->irq_pin_->setup(); this->irq_pin_->setup();
@ -34,6 +37,7 @@ void ADE7953::setup() {
this->ade_read_32(BIGAIN_32, &bigain_); this->ade_read_32(BIGAIN_32, &bigain_);
this->ade_read_32(AWGAIN_32, &awgain_); this->ade_read_32(AWGAIN_32, &awgain_);
this->ade_read_32(BWGAIN_32, &bwgain_); this->ade_read_32(BWGAIN_32, &bwgain_);
this->last_update_ = millis();
this->is_setup_ = true; this->is_setup_ = true;
}); });
} }
@ -52,6 +56,7 @@ void ADE7953::dump_config() {
LOG_SENSOR(" ", "Active Power B Sensor", this->active_power_b_sensor_); LOG_SENSOR(" ", "Active Power B Sensor", this->active_power_b_sensor_);
LOG_SENSOR(" ", "Rective Power A Sensor", this->reactive_power_a_sensor_); LOG_SENSOR(" ", "Rective Power A Sensor", this->reactive_power_a_sensor_);
LOG_SENSOR(" ", "Reactive Power B Sensor", this->reactive_power_b_sensor_); LOG_SENSOR(" ", "Reactive Power B Sensor", this->reactive_power_b_sensor_);
ESP_LOGCONFIG(TAG, " USE_ACC_ENERGY_REGS: %d", this->use_acc_energy_regs_);
ESP_LOGCONFIG(TAG, " PGA_V_8: 0x%X", pga_v_); ESP_LOGCONFIG(TAG, " PGA_V_8: 0x%X", pga_v_);
ESP_LOGCONFIG(TAG, " PGA_IA_8: 0x%X", pga_ia_); ESP_LOGCONFIG(TAG, " PGA_IA_8: 0x%X", pga_ia_);
ESP_LOGCONFIG(TAG, " PGA_IB_8: 0x%X", pga_ib_); ESP_LOGCONFIG(TAG, " PGA_IB_8: 0x%X", pga_ib_);
@ -85,6 +90,7 @@ void ADE7953::update() {
uint32_t val; uint32_t val;
uint16_t val_16; uint16_t val_16;
uint16_t reg;
// Power factor // Power factor
err = this->ade_read_16(0x010A, &val_16); err = this->ade_read_16(0x010A, &val_16);
@ -92,23 +98,36 @@ void ADE7953::update() {
err = this->ade_read_16(0x010B, &val_16); err = this->ade_read_16(0x010B, &val_16);
ADE_PUBLISH(power_factor_b, (int16_t) val_16, (0x7FFF / 100.0f)); ADE_PUBLISH(power_factor_b, (int16_t) val_16, (0x7FFF / 100.0f));
float pf = ADE_POWER_FACTOR;
if (this->use_acc_energy_regs_) {
const uint32_t now = millis();
const auto diff = now - this->last_update_;
this->last_update_ = now;
// prevent DIV/0
pf = ADE_WATTSEC_POWER_FACTOR * (diff < 10 ? 10 : diff) / 1000;
ESP_LOGVV(TAG, "ADE7953::update() diff=%d pf=%f", diff, pf);
}
// Apparent power // Apparent power
err = this->ade_read_32(0x0310, &val); reg = this->use_acc_energy_regs_ ? 0x0322 : 0x0310;
ADE_PUBLISH(apparent_power_a, (int32_t) val, 154.0f); err = this->ade_read_32(reg, &val);
err = this->ade_read_32(0x0311, &val); ADE_PUBLISH(apparent_power_a, (int32_t) val, pf);
ADE_PUBLISH(apparent_power_b, (int32_t) val, 154.0f); err = this->ade_read_32(reg + 1, &val);
ADE_PUBLISH(apparent_power_b, (int32_t) val, pf);
// Active power // Active power
err = this->ade_read_32(0x0312, &val); reg = this->use_acc_energy_regs_ ? 0x031E : 0x0312;
ADE_PUBLISH(active_power_a, (int32_t) val, 154.0f); err = this->ade_read_32(reg, &val);
err = this->ade_read_32(0x0313, &val); ADE_PUBLISH(active_power_a, (int32_t) val, pf);
ADE_PUBLISH(active_power_b, (int32_t) val, 154.0f); err = this->ade_read_32(reg + 1, &val);
ADE_PUBLISH(active_power_b, (int32_t) val, pf);
// Reactive power // Reactive power
err = this->ade_read_32(0x0314, &val); reg = this->use_acc_energy_regs_ ? 0x0320 : 0x0314;
ADE_PUBLISH(reactive_power_a, (int32_t) val, 154.0f); err = this->ade_read_32(reg, &val);
err = this->ade_read_32(0x0315, &val); ADE_PUBLISH(reactive_power_a, (int32_t) val, pf);
ADE_PUBLISH(reactive_power_b, (int32_t) val, 154.0f); err = this->ade_read_32(reg + 1, &val);
ADE_PUBLISH(reactive_power_b, (int32_t) val, pf);
// Current // Current
err = this->ade_read_32(0x031A, &val); err = this->ade_read_32(0x031A, &val);

View file

@ -52,6 +52,8 @@ class ADE7953 : public PollingComponent, public sensor::Sensor {
void set_awgain(uint32_t awgain) { awgain_ = awgain; } void set_awgain(uint32_t awgain) { awgain_ = awgain; }
void set_bwgain(uint32_t bwgain) { bwgain_ = bwgain; } void set_bwgain(uint32_t bwgain) { bwgain_ = bwgain; }
void set_use_acc_energy_regs(bool use_acc_energy_regs) { use_acc_energy_regs_ = use_acc_energy_regs; }
void set_voltage_sensor(sensor::Sensor *voltage_sensor) { voltage_sensor_ = voltage_sensor; } void set_voltage_sensor(sensor::Sensor *voltage_sensor) { voltage_sensor_ = voltage_sensor; }
void set_frequency_sensor(sensor::Sensor *frequency_sensor) { frequency_sensor_ = frequency_sensor; } void set_frequency_sensor(sensor::Sensor *frequency_sensor) { frequency_sensor_ = frequency_sensor; }
@ -103,6 +105,8 @@ class ADE7953 : public PollingComponent, public sensor::Sensor {
uint32_t bigain_; uint32_t bigain_;
uint32_t awgain_; uint32_t awgain_;
uint32_t bwgain_; uint32_t bwgain_;
bool use_acc_energy_regs_{false};
uint32_t last_update_;
virtual bool ade_write_8(uint16_t reg, uint8_t value) = 0; virtual bool ade_write_8(uint16_t reg, uint8_t value) = 0;