summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Berg <bberg@redhat.com>2022-07-15 16:52:54 +0200
committerBenjamin Berg <bberg@redhat.com>2022-07-21 11:06:49 +0200
commit9dd78a74dd403473e6623c97179938ce96890e27 (patch)
tree97bd24308578d8e90af494ced42eae98772468c2
parente6a5d9a7f56156dfff6c97a05d5c189d64fedd88 (diff)
downloadupower-9dd78a74dd403473e6623c97179938ce96890e27.tar.gz
battery: Better separate power usage estimation code
The up_device_battery_estimate function did more than just estimating the current power consumption (and doing some state guessing). Move the time to full/empty checking out of the function. Also, let it directly modify the reported state before it is pushed into the ring-buffer.
-rw-r--r--src/up-device-battery.c78
1 files changed, 40 insertions, 38 deletions
diff --git a/src/up-device-battery.c b/src/up-device-battery.c
index 6df5f7f..507c189 100644
--- a/src/up-device-battery.c
+++ b/src/up-device-battery.c
@@ -90,37 +90,34 @@ up_device_battery_charge_to_energy (UpDeviceBattery *self, gdouble charge)
}
static void
-up_device_battery_estimate (UpDeviceBattery *self, UpDeviceState *effective_state)
+up_device_battery_estimate_power (UpDeviceBattery *self, UpBatteryValues *cur)
{
UpDeviceBatteryPrivate *priv = up_device_battery_get_instance_private (self);
+ UpDeviceState reported_state;
UpBatteryValues *ref = NULL;
- UpBatteryValues *cur;
gdouble energy_rate = 0.0;
gint64 ref_td = 999 * G_USEC_PER_SEC; /* We need to be able to do math with this */
- gint64 time_to_empty = 0;
- gint64 time_to_full = 0;
gint i;
- g_assert (priv->hw_data_len >= 1);
-
priv->have_good_estimates = FALSE;
- cur = &priv->hw_data[priv->hw_data_last];
- *effective_state = cur->state;
+ /* Same item, but it is copied in already. */
+ g_assert (cur->ts_us != priv->hw_data[priv->hw_data_last].ts_us);
+ reported_state = cur->state;
- if (*effective_state != UP_DEVICE_STATE_CHARGING &&
- *effective_state != UP_DEVICE_STATE_DISCHARGING &&
- *effective_state != UP_DEVICE_STATE_UNKNOWN) {
+ if (cur->state != UP_DEVICE_STATE_CHARGING &&
+ cur->state != UP_DEVICE_STATE_DISCHARGING &&
+ cur->state != UP_DEVICE_STATE_UNKNOWN) {
priv->have_good_estimates = TRUE;
- goto out;
+ return;
}
- for (i = 1; i < priv->hw_data_len; i++) {
+ for (i = 0; i < priv->hw_data_len; i++) {
int pos = (priv->hw_data_last - i + G_N_ELEMENTS (priv->hw_data)) % G_N_ELEMENTS (priv->hw_data);
gint64 td;
/* Stop searching if the hardware state changed. */
- if (priv->hw_data[pos].state != cur->state)
+ if (priv->hw_data[pos].state != reported_state)
break;
td = cur->ts_us - priv->hw_data[pos].ts_us;
@@ -146,7 +143,7 @@ up_device_battery_estimate (UpDeviceBattery *self, UpDeviceState *effective_stat
* For now, this is better than what we used to do.
*/
if (!ref)
- goto out;
+ return;
/* energy is in Wh, rate in W */
energy_rate = (cur->energy.cur - ref->energy.cur) / (ref_td / ((gdouble) 3600 * G_USEC_PER_SEC));
@@ -155,46 +152,33 @@ up_device_battery_estimate (UpDeviceBattery *self, UpDeviceState *effective_stat
* Note that the history is discarded when the AC is plugged, as such
* we should only err on the side of showing CHARGING for too long.
*/
- if (*effective_state == UP_DEVICE_STATE_UNKNOWN) {
+ if (cur->state == UP_DEVICE_STATE_UNKNOWN) {
/* Consider a rate of 0.5W as "no change", otherwise set CHARGING/DISCHARGING */
if (abs(energy_rate) < 0.5) {
priv->have_good_estimates = TRUE;
- goto out;
+ return;
} else if (energy_rate < 0.0) {
- *effective_state = UP_DEVICE_STATE_DISCHARGING;
+ cur->state = UP_DEVICE_STATE_DISCHARGING;
} else {
- *effective_state = UP_DEVICE_STATE_CHARGING;
+ cur->state = UP_DEVICE_STATE_CHARGING;
}
}
/* The rate is defined to be positive during both charge and discharge. */
- if (*effective_state == UP_DEVICE_STATE_DISCHARGING)
+ if (cur->state == UP_DEVICE_STATE_DISCHARGING)
energy_rate *= -1.0;
/* This hopefully gives us sane values, but lets print a message if not. */
if (energy_rate < 0.1 || energy_rate > 300) {
g_message ("The estimated %scharge rate is %fW, which is not realistic",
- *effective_state == UP_DEVICE_STATE_DISCHARGING ? "dis" : "",
+ cur->state == UP_DEVICE_STATE_DISCHARGING ? "dis" : "",
energy_rate);
energy_rate = 0;
- goto out;
+ return;
}
- /* Here we could factor in collected data about charge rates */
- /* FIXME: Use charge-stop-threshold here */
- if (*effective_state == UP_DEVICE_STATE_CHARGING)
- time_to_full = 3600 * (priv->energy_full - cur->energy.cur) / energy_rate;
- else
- time_to_empty = 3600 * cur->energy.cur / energy_rate;
-
priv->have_good_estimates = TRUE;
-
-out:
- g_object_set (self,
- "energy-rate", energy_rate,
- "time-to-empty", time_to_empty,
- "time-to-full", time_to_full,
- NULL);
+ cur->energy.rate = energy_rate;
}
static void
@@ -249,6 +233,8 @@ up_device_battery_report (UpDeviceBattery *self,
UpRefreshReason reason)
{
UpDeviceBatteryPrivate *priv = up_device_battery_get_instance_private (self);
+ gint64 time_to_empty = 0;
+ gint64 time_to_full = 0;
if (!priv->present) {
g_warning ("Got a battery report for a battery that is not present");
@@ -331,13 +317,26 @@ up_device_battery_report (UpDeviceBattery *self,
* about the AC state and we only have "one" battery.
*/
+ /* Do power estimations based on energy/charge data */
+ up_device_battery_estimate_power (self, values);
+
+
/* Push into our ring buffer */
priv->hw_data_last = (priv->hw_data_last + 1) % G_N_ELEMENTS (priv->hw_data);
priv->hw_data_len = MIN (priv->hw_data_len + 1, G_N_ELEMENTS (priv->hw_data));
priv->hw_data[priv->hw_data_last] = *values;
- /* Do estimations */
- up_device_battery_estimate (self, &values->state);
+ /* Calculate time to full/empty
+ *
+ * Here we could factor in collected data about charge rates
+ * FIXME: Use charge-stop-threshold here
+ */
+ if (values->energy.rate > 0) {
+ if (values->state == UP_DEVICE_STATE_CHARGING)
+ time_to_full = 3600 * (priv->energy_full - values->energy.cur) / values->energy.rate;
+ else
+ time_to_empty = 3600 * values->energy.cur / values->energy.rate;
+ }
/* QUIRK: Do a FULL/EMPTY guess if the state is still unknown
* Maybe limit to when we have good estimates
@@ -360,6 +359,9 @@ up_device_battery_report (UpDeviceBattery *self,
"state", values->state,
"voltage", values->voltage,
"temperature", values->temperature,
+ "energy-rate", values->energy.rate,
+ "time-to-empty", time_to_empty,
+ "time-to-full", time_to_full,
/* XXX: Move "update-time" updates elsewhere? */
"update-time", (guint64) g_get_real_time () / G_USEC_PER_SEC,
NULL);