diff -uNr upower-0.99.5/src/linux/up-device-supply.c upower-0.99.5-patched/src/linux/up-device-supply.c --- upower-0.99.5/src/linux/up-device-supply.c 2017-04-10 13:16:37.000000000 +0200 +++ upower-0.99.5-patched/src/linux/up-device-supply.c 2017-08-18 23:13:41.519668391 +0200 @@ -212,12 +212,17 @@ guint first = supply->priv->energy_old_first; guint new_position = (first + UP_DEVICE_SUPPLY_ENERGY_OLD_LENGTH - 1) % UP_DEVICE_SUPPLY_ENERGY_OLD_LENGTH; + GTimeVal now; + g_get_current_time (&now); /* check if the energy value has changed and, if that's the case, - * store the new values in the buffer. */ - if (supply->priv->energy_old[first] != energy) { + * store the new values in the buffer. + * if the energy values has not changed and enough time has passed, + * store the value anyway. */ + if (supply->priv->energy_old[first] != energy || + now.tv_sec - supply->priv->energy_old_timespec[first].tv_sec >= 300) { supply->priv->energy_old[new_position] = energy; - g_get_current_time (&supply->priv->energy_old_timespec[new_position]); + supply->priv->energy_old_timespec[new_position] = now; supply->priv->energy_old_first = new_position; return TRUE; } @@ -256,7 +261,7 @@ now = supply->priv->energy_old_timespec[i]; do { /* only use this value if it seems valid */ - if (supply->priv->energy_old_timespec[i].tv_sec && supply->priv->energy_old[i]) { + if (supply->priv->energy_old_timespec[i].tv_sec) { /* This is the square of t_i^2 */ sum_x += (now.tv_sec - supply->priv->energy_old_timespec[i].tv_sec) * (now.tv_sec - supply->priv->energy_old_timespec[i].tv_sec); @@ -272,16 +277,14 @@ } while (i != supply->priv->energy_old_first); /* Check that at least 3 points were involved in computation */ - if (sum_x == 0.0f || valid_values < 3) + if (valid_values < 3) return supply->priv->rate_old; /* Compute the discharge per hour, and not per second */ rate /= sum_x / SECONDS_PER_HOUR_F; - /* if the rate is zero, use the old rate. It will usually happens if no - * data is in the buffer yet. If the rate is too high, i.e. more than, - * 100W don't use it. */ - if (rate == 0.0f || rate > 100.0f) + /* If the rate is too high, i.e. more than 100W don't use it. */ + if (rate > 100.0f) return supply->priv->rate_old; return rate;