Bug 8593 - When discharging, battery level only shows 3 states
When discharging, battery level only shows 3 states
Status: RESOLVED FIXED
Product: hal
Classification: Unclassified
Component: hald
unspecified
x86 (IA32) Linux (All)
: high normal
Assigned To: Danny Kukawka
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2006-10-10 13:37 UTC by FrogPR
Modified: 2006-10-13 06:08 UTC (History)
0 users

See Also:


Attachments
patch to fix 1mV problem (1.66 KB, patch)
2006-10-11 07:40 UTC, Danny Kukawka
Details | Splinter Review

Note You need to log in before you can comment on or make changes to this bug.
Description FrogPR 2006-10-10 13:37:14 UTC
It shows only 100%, 66% and 33%. The according remaining times are 3h:00, 2h:00
and 1h:00. While these three "states" are true (i.e. 66% corresponds indeed to a
66% real battery level but stays like this until it drops down to 33% and so
forth), before 0.5.8.1 (i.e. 0.5.7.1) I had "continuous" battery levels. I use
powersaved along with kpowersave which use the hal values
"battery.charge_level.percentage" and "battery.remaining_time" and thus noticed
the wrong battery values. In hal-device-manager they show the same wrong values
as in kpowersave. When charging, everything works perfectly.
I'm using Debian unstable. With 0.5.7.1 everything was working fine. Other
applications like gkrellm still show the right levels and remaining time.
I use an ACER Laptop 1694WLMi.
I attach some outputs for the discharging battery state:

cat /proc/acpi/battery/BAT1/state
present:                 yes
capacity state:          ok
charging state:          discharging
present rate:            1420 mA
remaining capacity:      3580 mAh
present voltage:         1 mV

cat /proc/acpi/battery/BAT1/info
present:                 yes
design capacity:         4300 mAh
last full capacity:      3719 mAh
battery technology:      rechargeable
design voltage:          14800 mV
design capacity warning: 300 mAh
design capacity low:     132 mAh
capacity granularity 1:  32 mAh
capacity granularity 2:  32 mAh
model number:            ZL08
serial number:           22338
battery type:            LION
OEM info:                SONY

lshal output for battery 1:

udi = '/org/freedesktop/Hal/devices/acpi_BAT1'
  battery.remaining_time = 10800  (0x2a30)  (int)
  info.udi = '/org/freedesktop/Hal/devices/acpi_BAT1'  (string)
  linux.hotplug_type = 4  (0x4)  (int)
  battery.charge_level.percentage = 100  (0x64)  (int) <-- this is actually 91%
  battery.charge_level.rate = 1  (0x1)  (int)
  battery.charge_level.last_full = 3  (0x3)  (int)
  battery.charge_level.current = 3  (0x3)  (int)
  battery.voltage.current = 1  (0x1)  (int)
  battery.reporting.rate = 1475  (0x5c3)  (int)
  battery.reporting.current = 3516  (0xdbc)  (int)
  battery.charge_level.capacity_state = 'ok'  (string)
  battery.rechargeable.is_discharging = true  (bool)
  battery.rechargeable.is_charging = false  (bool)
  battery.is_rechargeable = true  (bool)
  battery.charge_level.unit = 'mWh'  (string)
  battery.charge_level.granularity_2 = 473  (0x1d9)  (int)
  battery.charge_level.granularity_1 = 473  (0x1d9)  (int)
  battery.charge_level.low = 1953  (0x7a1)  (int)
  battery.charge_level.warning = 4440  (0x1158)  (int)
  battery.charge_level.design = 63640  (0xf898)  (int)
  battery.voltage.design = 14800  (0x39d0)  (int)
  battery.voltage.unit = 'mV'  (string)
  battery.reporting.granularity_2 = 32  (0x20)  (int)
  battery.reporting.granularity_1 = 32  (0x20)  (int)
  battery.reporting.low = 132  (0x84)  (int)
  battery.reporting.warning = 300  (0x12c)  (int)
  battery.reporting.design = 4300  (0x10cc)  (int)
  battery.reporting.last_full = 3719  (0xe87)  (int)
  battery.reporting.unit = 'mAh'  (string)
  battery.technology = 'lithium-ion'  (string)
  battery.reporting.technology = 'LION'  (string)
  battery.serial = '22338'  (string)
  battery.model = 'ZL08'  (string)
  battery.vendor = 'SONY'  (string)
  battery.present = true  (bool)
  info.capabilities = {'battery'} (string list)
  info.category = 'battery'  (string)
  battery.type = 'primary'  (string)
  info.product = 'Battery Bay'  (string)
  info.parent = '/org/freedesktop/Hal/devices/computer'  (string)
  linux.acpi_type = 0  (0x0)  (int)
  linux.acpi_path = '/proc/acpi/battery/BAT1'  (string)
Comment 1 Danny Kukawka 2006-10-11 02:08:42 UTC
Could you please start "lshal --monitor", remove the AC plug and wait until the 
battery is down to 10 % and attach this output to the bug?
Comment 2 FrogPR 2006-10-11 07:13:18 UTC
I looked a bit into the issue and found something pretty weird (at least for me
as a physicist) for the calculation of battery level. Apparently, some laptop
vendors specify the remaining capacity in mWh. While this sounds reasonable in
the first place, it is a bit strange on second thought. The reason for this is
that, to measure the remaining capacity of any rechargeable battery you only
have one thing on your disposal, that is the voltage. The voltage decreases with
capacity, not always in a linear way though. Thus, from the current voltage you
can estimate (as opposed to measure) the current remaining capacity in mAh (or
even in mWh) BUT you cannot by any means measure the remaining capacity directly
in terms of mAh or mWh. One can then of course multiply both (i.e. voltage and
current) to yield the remaining capacity in mWh but the important point here is,
that no additional accuracy or any new information has gone into this new value
in mWh. Hence, there is no sense in converting the mAh values to mWh. I assume,
that if the remaining capacity is given in mAh, also the last full capacity and
the present rate is given in this same unit, so why converting? There would only
be a need to convert if the units of these three values are different, something
I unfortunately cannot rule out for ANY laptop out there, but would be really
stupid.
Anyway, this mWh-conversion-approach would work, but only if "present voltage"
and many other things are reported correctly, which are not in my case (see
previous post: "present voltage: 1 mV", which is absolutely impossible). Btw.,
by looking at the conversion block in acpi.c there seem to be many more things
that are often not reported correctly... So why complicate the matter?

With this in mind I simply commented out the entire mWh-conversion block in
acpi.c and was just using:

normalised_current = reporting_current;
normalised_lastfull = reporting_lastfull;
normalised_rate = reporting_rate;

After compiling and installing hal 0.5.8.1, everything works ok now.

I can still do that (i.e. the "lshal --monitor" thing), what you requested, but
I guess the source of the error is found. Anyway, let me know, if you still need
this info.
Comment 3 Danny Kukawka 2006-10-11 07:40:44 UTC
Created attachment 7354 [details] [review]
patch to fix 1mV problem

Could you check if this patch helps you?
Comment 4 FrogPR 2006-10-11 08:55:46 UTC
This might work, but sometimes the present voltage goes up to 2mV or 3mV or
whatever.

Apart from this, PLEASE consider carefully the following!! It is NOT necessary
to convert mAh to mWh, it is simply superfluous and by looking into your
calculation, you cannot even do this that way. The voltage of the battery DROPS
with capacity thus the calculation:

normalised_current = (reporting_current * voltage) / 1000;
normalised_lastfull = (reporting_lastfull * voltage) / 1000;
normalised_rate = (reporting_rate * voltage) / 1000;

is wrong, because the voltage for the lastfull state is different (i.e. higher)
from the current voltage. Anyway, as i said before, it is not even necessary to
do this conversion, because battery levels are usually given in mAh (go to a
shop and look at normal batteries or car batteries or whatever). So the perfect
fix for this and any other problemn related to this is to just use the battery
levels in mAh, they _don't_ need any conversion. This is again due to the fact,
that levels given in mAh and mWh are _calculated_ from one and the same physical
property, that is the voltage and thus contain the same level of accuracy.

I hope, this time it is more clear. Anyway, thanks for the quick response.
Comment 5 Danny Kukawka 2006-10-11 09:15:55 UTC
(In reply to comment #4)
> from the current voltage. Anyway, as i said before, it is not even necessary 
to
> do this conversion, because battery levels are usually given in mAh (go to a
> shop and look at normal batteries or car batteries or whatever). So the 
perfect

Well. 2 Things.
- You can have two batteries in one machine with different Voltages.
- The battery reports either mAh or mWh.

> fix for this and any other problemn related to this is to just use the battery
> levels in mAh, they _don't_ need any conversion. This is again due to the 
fact,
> that levels given in mAh and mWh are _calculated_ from one and the same 
physical
> property, that is the voltage and thus contain the same level of accuracy.

Another thing is, that these batteries not just somehow convert their current 
voltage to a charge level in any unit as you seem to suggest. These "smart 
batteries" actually contain a microprocessor and they measure the amount of 
energy fed to them during charge and drained from them during discharge.

> I hope, this time it is more clear. Anyway, thanks for the quick response.

Just suggest a solution for the following:

Battery A has 16800mV and 4400mAh lastfull, 4235mAh remaining
Battery B has 10400mv and 3500mAh lastfull, 3472mAh remaining

How do you suggest we calculate the remaining time?
Battery A is "idle", battery B is discharging at 2234mA.
Comment 6 Danny Kukawka 2006-10-11 09:17:32 UTC
(In reply to comment #4)
> This might work, but sometimes the present voltage goes up to 2mV or 3mV or
> whatever.

This is simply broken hardware reporting insane values. You should maybe try a 
BIOS update. Btw. I can add a more fuzzy logic in this place.
Comment 7 FrogPR 2006-10-11 13:08:45 UTC
Yeah, i guess it's broken, but unfortunately there's no BIOS update available.
It's strange that it reports these low values for the voltage. 

Anyway, the "present rate" shows a correct value and by simply dividing
"remaining capacity" by "present rate" one gets the remaining time in hours
(here for bat. 1: 1.55h or 1h 33min) provided the former has the unit mAh and
the latter mA. That's what I mean, you don't need the voltage for calculating
the remaining battery time and therefore you don't need to convert to mWh.
The problem changes a bit when you have two batteries with different voltages.
As far as I understand from the given example, the batteries are used
consecutively rather than at the same time. Thus, you have to add both remaining
times of each battery to get the total remaining time. For the battery that's
being used, one can use the same method as if there was only one battery. For
the second one, it is a bit more "complicated". As there is no discharging rate,
one can only try to estimate how long it will last. The power the laptop uses is
certainly the same regardless of the battery being used. The power can simply be
computed by P=U*I, which is about 23.2 Watts. Dividing this by the voltage of
the second battery yields the current, which is 1383 mA. Although the voltage of
the second battery will decrease with its usage, it is still a good estimate to
calculate the remaining time by again dividing "remaining capacity" by "present
rate" (i.e. 1383), that is 3.06 h. Thus, the total remaining time is about 4.6h
or 4h 36min.
I agree, that for calculating the remaining time when there are two batteries
one needs the voltage information to get an estimate for the currently unused
battery. But i don't think it is necessary for a single battery to simply get
its remaining operating time. Also, in this example i have not converted
anything to mWh (this might be necessary though, when the batteries use
different units).

So, i still don't see why it is necessary to convert to mWh :-) Am I'm
doing/thinking something wrong?
Comment 8 Danny Kukawka 2006-10-13 06:08:40 UTC
 hald/linux/acpi.c |   67 ++++++++++++++++++++----------------------------------
 1 files changed, 25 insertions(+), 42 deletions(-)

New commits:
diff-tree 9c99fc03fbac6380032a6678c641a76ef02ad834 (from 
0a9965e4aa4ffc2f382d7fe1286937308439fd1f)
Author: Danny Kukawka <danny.kukawka@web.de>
Date:   Fri Oct 13 12:33:11 2006 +0200

    fixed acpi problems with incorrect low current voltage values
    
    This patch fixes the fd.o bug #8593 where wrong low current voltage battery
    values causes a wrong remaining percentage.
    
    Now we assume if the current voltage is lower than 50% of the design voltage
    that this is from broken hardware and use the design voltage to normalise 
the
    battery values.
    
    Also included some little cleanups in acpi.c and removed duplicated code.