I bought my trusty ASUS N46VB (https://www.asus.com/Notebooks/N46VB/ ) at the end of 2013. On 2014, I created a little ruby script to record the battery status, to track its discharge rate.
ARCHIVO="bateria.log"
def bateria
porcentaje=`upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep -E "percentage"`
porcentaje =~ /(\d+)\%/
porcentaje=$1.to_i
tiempo=Time.now.to_i
"#{tiempo}\t#{porcentaje}"
end
open(ARCHIVO, 'a') { |f|
f.puts bateria
}
I added that script to cron via crontab -e, to run it every 5 minutes.
*/5 * * * * ruby ~/bateria.rb
There are 85226 records, the first record dated 2014-08-14 16:24:10 and the last one on 2017-02-08 03:45:01. To test the decline of battery, I diff the whole series, both time and charge. I just keep consecutive readings, looking for diff of exactly 300 seconds, with negative values. If we lookup the data, we can see a clear outlier (62), and some suspicious numbers (35,33).
pandoc.table(table(-(b$db[b$dt==300 & b$db<0])),"Discharge distribution")
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 18 | 26 | 27 | 33 | 35 | 62 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 683 | 3856 | 3447 | 957 | 243 | 77 | 37 | 18 | 15 | 6 | 7 | 6 | 7 | 6 | 8 | 1 | 1 | 1 | 1 | 1 | 1 | 1 |
If we plot the discharge vs time, we can see that discharges higher that 30 are clearly outliers, so we discard them.
plot(bb$t,-bb$db,type="l")
abline(h=30,col=2)
Now, we have 9375 records to analyze. If \(d\) is the discharge rate per 5 minutes, the equation of charge at \(x\) minutes will be
\[ y=100-\frac{dx}{5} \]
And the time on minutes to full discharge will be \[ 0=100-\frac{dx}{5}\\ \frac{dx}{5}=100\\ x=\frac{500}{d} \]
If we graph it, we obtain a very rugged one, because of 1% change rates caused by computer on standy.
plot(500/tiempo.est.b, ylab="time to full discharge",xlab="time on days")
Using moving averages, we could obtain a better visualization of data. The maximum time without charging on the new computers was nearly tree hours, so a window of 36 blocks should be a good starting point.
plot(500/rollmean(tiempo.est.b,36),ylab="time to full discharge",xlab="time on days",ylim=c(0,400))
To have a better look at the trend, we could use a 360 window. We could see that the average time to full discharge now is almost the half than at the beggining.
plot(500/rollmean(tiempo.est.b,360),ylab="time to full discharge",xlab="time on days",ylim=c(0,300))
An alternative way is just aggregate the information. We could take the mean every 30 days and plot it.
scatterplot(500/as.numeric(ag.tiempo)~as.numeric(index(ag.tiempo)),ylab="time to full discharge",xlab="blocks of 30 days",ylim=c(0,250))
Testing some linear models, a cuadratic model on the logs of discharge rate is not perfect, but is relatively linear and control the variance.
lm.1<-lm(log(as.numeric(ag.tiempo))~poly(block.n,2))
summary(lm.1)
##
## Call:
## lm(formula = log(as.numeric(ag.tiempo)) ~ poly(block.n, 2))
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.103203 -0.029835 0.002486 0.026801 0.085896
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 0.998999 0.009191 108.689 < 2e-16 ***
## poly(block.n, 2)1 1.046792 0.050343 20.793 < 2e-16 ***
## poly(block.n, 2)2 0.358815 0.050343 7.127 1.15e-07 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.05034 on 27 degrees of freedom
## Multiple R-squared: 0.9471, Adjusted R-squared: 0.9432
## F-statistic: 241.6 on 2 and 27 DF, p-value: < 2.2e-16
plot(lm.1)
The original data, the prediction curve and the interval for new predictions
plot(500/as.numeric(ag.tiempo),ylim=c(0,250),xlab="block of 30 days",ylab="time until full discharge")
lines(500/exp(pr.1[,1]),col=2)
lines(500/exp(pr.1[,2]),lty=2,col=2)
lines(500/exp(pr.1[,3]),lty=2,col=2)