mirror of
https://github.com/esphome/esphome.git
synced 2026-06-24 13:27:14 +00:00
[ade7880] Fix reverse active energy reading from reserved register (#16822)
This commit is contained in:
@@ -87,14 +87,24 @@ void ADE7880::update_sensor_from_s16_register16_(sensor::Sensor *sensor, uint16_
|
|||||||
sensor->publish_state(f(val));
|
sensor->publish_state(f(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F>
|
void ADE7880::update_active_energy_(PowerChannel *channel, uint16_t a_register) {
|
||||||
void ADE7880::update_sensor_from_s32_register16_(sensor::Sensor *sensor, uint16_t a_register, F &&f) {
|
if (channel->forward_active_energy == nullptr && channel->reverse_active_energy == nullptr) {
|
||||||
if (sensor == nullptr) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float val = this->read_s32_register16_(a_register);
|
// The ADE7880 has no separate forward/reverse active energy accumulators. The xWATTHR registers
|
||||||
sensor->publish_state(f(val));
|
// accumulate signed energy since the last read (positive = imported/forward, negative = exported/
|
||||||
|
// reverse), so split the value by sign into the forward and reverse running totals.
|
||||||
|
float val = this->read_s32_register16_(a_register) / 14400.0f;
|
||||||
|
if (val >= 0.0f) {
|
||||||
|
if (channel->forward_active_energy != nullptr) {
|
||||||
|
channel->forward_active_energy->publish_state(channel->forward_active_energy_total += val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (channel->reverse_active_energy != nullptr) {
|
||||||
|
channel->reverse_active_energy->publish_state(channel->reverse_active_energy_total -= val);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADE7880::update() {
|
void ADE7880::update() {
|
||||||
@@ -117,12 +127,7 @@ void ADE7880::update() {
|
|||||||
this->update_sensor_from_s24zp_register16_(chan->apparent_power, AVA, [](float val) { return val / 100.0f; });
|
this->update_sensor_from_s24zp_register16_(chan->apparent_power, AVA, [](float val) { return val / 100.0f; });
|
||||||
this->update_sensor_from_s16_register16_(chan->power_factor, APF,
|
this->update_sensor_from_s16_register16_(chan->power_factor, APF,
|
||||||
[](float val) { return std::abs(val / -327.68f); });
|
[](float val) { return std::abs(val / -327.68f); });
|
||||||
this->update_sensor_from_s32_register16_(chan->forward_active_energy, AFWATTHR, [&chan](float val) {
|
this->update_active_energy_(chan, AWATTHR);
|
||||||
return chan->forward_active_energy_total += val / 14400.0f;
|
|
||||||
});
|
|
||||||
this->update_sensor_from_s32_register16_(chan->reverse_active_energy, ARWATTHR, [&chan](float val) {
|
|
||||||
return chan->reverse_active_energy_total += val / 14400.0f;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->channel_b_ != nullptr) {
|
if (this->channel_b_ != nullptr) {
|
||||||
@@ -133,12 +138,7 @@ void ADE7880::update() {
|
|||||||
this->update_sensor_from_s24zp_register16_(chan->apparent_power, BVA, [](float val) { return val / 100.0f; });
|
this->update_sensor_from_s24zp_register16_(chan->apparent_power, BVA, [](float val) { return val / 100.0f; });
|
||||||
this->update_sensor_from_s16_register16_(chan->power_factor, BPF,
|
this->update_sensor_from_s16_register16_(chan->power_factor, BPF,
|
||||||
[](float val) { return std::abs(val / -327.68f); });
|
[](float val) { return std::abs(val / -327.68f); });
|
||||||
this->update_sensor_from_s32_register16_(chan->forward_active_energy, BFWATTHR, [&chan](float val) {
|
this->update_active_energy_(chan, BWATTHR);
|
||||||
return chan->forward_active_energy_total += val / 14400.0f;
|
|
||||||
});
|
|
||||||
this->update_sensor_from_s32_register16_(chan->reverse_active_energy, BRWATTHR, [&chan](float val) {
|
|
||||||
return chan->reverse_active_energy_total += val / 14400.0f;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this->channel_c_ != nullptr) {
|
if (this->channel_c_ != nullptr) {
|
||||||
@@ -149,12 +149,7 @@ void ADE7880::update() {
|
|||||||
this->update_sensor_from_s24zp_register16_(chan->apparent_power, CVA, [](float val) { return val / 100.0f; });
|
this->update_sensor_from_s24zp_register16_(chan->apparent_power, CVA, [](float val) { return val / 100.0f; });
|
||||||
this->update_sensor_from_s16_register16_(chan->power_factor, CPF,
|
this->update_sensor_from_s16_register16_(chan->power_factor, CPF,
|
||||||
[](float val) { return std::abs(val / -327.68f); });
|
[](float val) { return std::abs(val / -327.68f); });
|
||||||
this->update_sensor_from_s32_register16_(chan->forward_active_energy, CFWATTHR, [&chan](float val) {
|
this->update_active_energy_(chan, CWATTHR);
|
||||||
return chan->forward_active_energy_total += val / 14400.0f;
|
|
||||||
});
|
|
||||||
this->update_sensor_from_s32_register16_(chan->reverse_active_energy, CRWATTHR, [&chan](float val) {
|
|
||||||
return chan->reverse_active_energy_total += val / 14400.0f;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGD(TAG, "update took %" PRIu32 " ms", millis() - start);
|
ESP_LOGD(TAG, "update took %" PRIu32 " ms", millis() - start);
|
||||||
|
|||||||
@@ -105,7 +105,8 @@ class ADE7880 : public i2c::I2CDevice, public PollingComponent {
|
|||||||
// the callable will be passed a 'float' value and is expected to return a 'float'
|
// the callable will be passed a 'float' value and is expected to return a 'float'
|
||||||
template<typename F> void update_sensor_from_s24zp_register16_(sensor::Sensor *sensor, uint16_t a_register, F &&f);
|
template<typename F> void update_sensor_from_s24zp_register16_(sensor::Sensor *sensor, uint16_t a_register, F &&f);
|
||||||
template<typename F> void update_sensor_from_s16_register16_(sensor::Sensor *sensor, uint16_t a_register, F &&f);
|
template<typename F> void update_sensor_from_s16_register16_(sensor::Sensor *sensor, uint16_t a_register, F &&f);
|
||||||
template<typename F> void update_sensor_from_s32_register16_(sensor::Sensor *sensor, uint16_t a_register, F &&f);
|
|
||||||
|
void update_active_energy_(PowerChannel *channel, uint16_t a_register);
|
||||||
|
|
||||||
void reset_device_();
|
void reset_device_();
|
||||||
|
|
||||||
|
|||||||
@@ -84,9 +84,7 @@ constexpr uint16_t CWATTHR = 0xE402;
|
|||||||
constexpr uint16_t AFWATTHR = 0xE403;
|
constexpr uint16_t AFWATTHR = 0xE403;
|
||||||
constexpr uint16_t BFWATTHR = 0xE404;
|
constexpr uint16_t BFWATTHR = 0xE404;
|
||||||
constexpr uint16_t CFWATTHR = 0xE405;
|
constexpr uint16_t CFWATTHR = 0xE405;
|
||||||
constexpr uint16_t ARWATTHR = 0xE406;
|
// 0xE406-0xE408 are reserved on the ADE7880 (it does not implement total reactive energy accumulation)
|
||||||
constexpr uint16_t BRWATTHR = 0xE407;
|
|
||||||
constexpr uint16_t CRWATTHR = 0xE408;
|
|
||||||
constexpr uint16_t AFVARHR = 0xE409;
|
constexpr uint16_t AFVARHR = 0xE409;
|
||||||
constexpr uint16_t BFVARHR = 0xE40A;
|
constexpr uint16_t BFVARHR = 0xE40A;
|
||||||
constexpr uint16_t CFVARHR = 0xE40B;
|
constexpr uint16_t CFVARHR = 0xE40B;
|
||||||
|
|||||||
Reference in New Issue
Block a user