# ACPI - battery state



## multix (Feb 28, 2013)

Hi,

I take care that all application I maintain work on FreeBSD. The battery monitor for gnustep is really a pain to maintain, due to the myriad of power management systems and different BIOS's!

Anyway, the problem: the battery state. For FreeBSD I have this code:


```
if( battio.bst.state & ACPI_BATT_STAT_CRITICAL )
      batteryType = @"CRITICAL ";		// could be complementary!
    
    if( battio.bst.state & ACPI_BATT_STAT_CHARGING )
      status = @"Charging";
    else if( battio.bst.state & ACPI_BATT_STAT_DISCHARG )
      status = @"Discharging";
    else if (battio.bst.state & ACPI_BATT_STAT_INVALID )
      status = @"Invalid";
    else
      NSLog(@"unknown state: %u", battio.bst.state);
```

On my laptop however I get sometimes nothing and the state is unknown. I don't see any other states defined in acpiio.h

*apiconf -i0* tells me:

```
State:                  high
Remaining capacity:     100%
Remaining time:         unknown
```
May I suppose that a firth state is implicit, that is if no flags are set the state is of neither charge nor discharge and thus "high"? I like explicit states, it is clearer 

Riccardo


----------



## fluca1978 (Feb 28, 2013)

Well, in the _if-else_ branch the _else_ branch just logs that the battery state is not known, but it does not set it. However, the usrs.sbin/acpi/acpiconf/acpiconf.c does set the state to _high_:


```
printf("State:\t\t\t");
                if (battio.battinfo.state == 0)
                        printf("high ");
                if (battio.battinfo.state & ACPI_BATT_STAT_CRITICAL)
                        printf("critical ");
                if (battio.battinfo.state & ACPI_BATT_STAT_DISCHARG)
                        printf("discharging ");
                if (battio.battinfo.state & ACPI_BATT_STAT_CHARGING)
                        printf("charging ");
```

and therefore I suspect your code must change to include another status, the *0* one (don't know why it has not be labeled):


```
else if (battio.bst.state == 0 )
      status = @"High";
```


----------



## multix (Feb 28, 2013)

Hi,

I agree with your suspect,

```
if (battio.battinfo.state == 0)
                        printf("high ");
```

However it would been nice that to know that from the FreeBSD kernel, instead of reverse-engineering another application 

Riccardo


----------



## fluca1978 (Mar 1, 2013)

There is also a comment on the acpio.h, where all the level but high are declared:


```
/*
 * Note that the following definitions represent status bits for internal
 * driver state.  [B]The first three of them (charging, discharging and critical)
 * conveninetly conform to ACPI specification of status returned by _BST
 * method. [/B] Other definitions (not present, etc) are synthetic.
 * Also note that according to the specification the charging and discharging
 * status bits must not be set at the same time.
 */
#define ACPI_BATT_STAT_DISCHARG         0x0001
#define ACPI_BATT_STAT_CHARGING         0x0002
#define ACPI_BATT_STAT_CRITICAL         0x0004
```

Therefore I believe the problem is not in the kernel.


----------



## multix (Mar 2, 2013)

You are correct, it is probably something unspecified in ACPI. Anyway, the comment is enough to make the kernel behaviour predictable.

The new GNUstep battery monitor will have largely improved FreeBSD (and NetBSD) support. And the new ACPI interface of the linux kernel is total, utter crap to program with. But no intention of starting a troll war, just expressing a developer opinion.

Thanks, Riccardo


----------

