Skip to content

feat(battery): add option to smooth power for more stable time_remaining estimates#4761

Open
Benji-clm wants to merge 1 commit intoAlexays:masterfrom
Benji-clm:smooth-power
Open

feat(battery): add option to smooth power for more stable time_remaining estimates#4761
Benji-clm wants to merge 1 commit intoAlexays:masterfrom
Benji-clm:smooth-power

Conversation

@Benji-clm
Copy link

This PR adds support for an option to have power based on current and past power readings to stabilize the estimation of the time remaining on the battery.

How aggressive the smoothing/responsive to changes/noise can be changed by changing smooth-power-time-constant which is the half life, in seconds, of each measurement.

I've decided to not use the smooth power for charging, as battery charging curves tend to be much less noisy and more predictable/smoother.

"battery": {
    "smooth-power": true, // default is false if not present
    "smooth-power-time-constant": 260.0, // default is 260.0 if not present
},

Fixes #4755

@jannickj
Copy link

@Alexays, this PR is getting stale :D

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds an optional power smoothing feature to the battery module to stabilize time remaining estimates by using exponential smoothing over current and historical power readings. The feature addresses issue #4755 where battery time estimates fluctuate wildly due to instantaneous power variations.

Changes:

  • Added configurable power smoothing with exponential moving average algorithm
  • Introduced smooth-power boolean config option (default: false) and smooth-power-time-constant numeric option (default: 260.0 seconds)
  • Modified time remaining calculation to use smoothed power values for discharging state only

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
include/modules/battery.hpp Added member variables for smooth power tracking: enable flag, time constant, smoothed power value, timestamp, and status tracking
src/modules/battery.cpp Implemented configuration parsing, exponential smoothing algorithm, and integrated smoothed power into time remaining calculations

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +6 to 8
#include <cstdio>
#include <string>

Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These includes appear to be unused. The header file already includes <string> (line 14 of include/modules/battery.hpp), and there are no uses of cstdio functions like printf, sprintf, or fprintf in the added code. Consider removing these unnecessary includes.

Suggested change
#include <cstdio>
#include <string>

Copilot uses AI. Check for mistakes.
Comment on lines +573 to +591
if (total_energy_exists && total_power_exists && total_power != 0) {
if (!smoothPowerEnable_) {
smooth_power_ = total_power;
} else {
if (status != old_status_raw_) {
smooth_power_ = total_power;
last_t_ = std::chrono::steady_clock::now();
} else {
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
double dt_s =
std::chrono::duration_cast<std::chrono::duration<double> >(now - last_t_).count();
smooth_power_ = smooth_power_ + ((1 - std::exp(-dt_s / time_constant_s_)) *
(total_power - smooth_power_));
last_t_ = now;
}

old_status_raw_ = status;
}
}
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The smoothing algorithm updates smooth_power_ regardless of battery status, but according to the PR description, smoothing is only intended for discharging. While smooth_power_ is correctly only used when discharging (line 597) and gets reset when status changes (line 578), updating it during charging is unnecessary computation since the value is discarded on status change. Consider wrapping the smoothing logic with a condition like if (status == "Discharging") to avoid updating smooth_power_ when it won't be used.

Copilot uses AI. Check for mistakes.
if (time_to_empty_now != 0) time_remaining = (float)time_to_empty_now / 3600.0f;
} else if (status == "Discharging" && total_power_exists && total_energy_exists) {
if (total_power != 0) time_remaining = (float)total_energy / total_power;
if (smooth_power_ != 0) time_remaining = (float)total_energy / smooth_power_;
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When total_power is 0, the smoothing logic at line 573 won't execute, leaving smooth_power_ at its previous value. This means line 597 could calculate time_remaining using a stale smooth_power_ value when total_power is 0, which differs from the original behavior where time_remaining wouldn't be calculated if total_power was 0. Consider either resetting smooth_power_ to 0 when total_power is 0, or checking total_power in addition to smooth_power_ on line 597.

Suggested change
if (smooth_power_ != 0) time_remaining = (float)total_energy / smooth_power_;
if (total_power != 0 && smooth_power_ != 0)
time_remaining = (float)total_energy / smooth_power_;

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Battery time estimate is extremely unstable due to stateless calculation

2 participants