Linux Battery Percentage Correction
Tags: battery, linux, tweaks, dotfiles
Published: 2019-07-29 16:37:36

---
title: Linux Battery Percentage Correction
published: true
tags: battery, linux, tweaks, dotfiles
canonical_url: https://samerickson.me/blog/linux-battery-percentage-correction/
---

## The problem
The problem I had in my initial arch linux installation on my macbook pro, was the battery. Fully charged it was showing 84%, and if I then immediately booted into macOS, it would show 100%. So what is going on there?

## The fix
I did some digging, and found lots of forms where users were asking the same question, but with no real answer as to why or any solution. I started looking into how my computer was getting all the battery information.

In _i3blocks_, the command was `cat /sys/class/power_supply/BAT0/capacity`. Naturally, I `cd` into that directory to get a look at what is going on. I found the following files:

```
.
├── alarm
├── capacity
├── charge_full
├── charge_full_design
├── charge_now
├── current_avg
├── current_now
├── cycle_count
├── device -> ../../../ACPI0002:00
├── manufacturer
├── model_name
├── power/
├── present
├── status
├── subsystem -> ../../../../../../../../../../class/power_supply
├── technology
├── temp
├── type
├── uevent
├── voltage_min_design
└── voltage_now
```

The four files I was interested in are:

- `capacity`
- `charge_full`
- `charge_full_design`
- `charge_now`

When you divide `charge_now` by `charge_full_design` you get `capacity`, and when you divide `charge_now` by `charge_full` you get what **macOS** displays as the current battery level.

So I changed the command in my _i3blocks config_ to run the following script:

```
#!/bin/bash

charge_current="$(cat /sys/class/power_supply/BAT0/charge_now)"
charge_full="$(cat /sys/class/power_supply/BAT0/charge_full)"
current=$(echo "scale=2;$charge_current/$charge_full" | bc | cut -c 2-)

echo "$current%"
```

I will admit it is a little bit slow, and I later read the [i3blocks documentation](https://github.com/vivien/i3blocks#i3bar-properties) and found their suggested battery module code:

```
#!/bin/bash

BAT=$(acpi -b | grep -E -o '[0-9][0-9]?%')

# Full and short texts
echo "Battery: $BAT"
echo "BAT: $BAT"

# Set urgent flag below 5% or use orange below 20%
[ ${BAT%?} -le 5 ] && exit 33
[ ${BAT%?} -le 20 ] && echo "#FF8000"

exit 0
```

Which works just as well, but with no completion time difference, and one more dependency. This would have saved me a little bit of time, but I am happy with my fix for now.

## Why is this the case?
Different versions of batteries have different strengths and weaknesses, in the case of rechargeable lithium-ion batteries, like those found in laptops, they are only designed for a certain amount of cycles before they are used up. With each charge, you lose effectiveness, the max charge from the factory does not match the _actual_ max charge. This causes linux to provide an incorrect battery reading as the battery degrades.

This is helpful when you want to know the current life state of your battery,
but not helpful if you want to know how much time you have before you need to
recharge.

## Summary
There are lots of ways to check the battery status in linux, you just need to
find the one that suits your needs.