Hi David, *, acpitool currently assumes, that the file it reads from sysfs has its information in a certain order and on certain lines. This makes it fail on my ThinkPad X31, and others, because my /sys/class/power_supply/BAT0/uevent looks like this (STATUS on line 3, not 6):
POWER_SUPPLY_NAME=BAT0
POWER_SUPPLY_TYPE=Battery
POWER_SUPPLY_STATUS=Charging
POWER_SUPPLY_PRESENT=1
POWER_SUPPLY_TECHNOLOGY=Li-ion
POWER_SUPPLY_VOLTAGE_MIN_DESIGN=10800000
POWER_SUPPLY_VOLTAGE_NOW=12174000
POWER_SUPPLY_CURRENT_NOW=26563000
POWER_SUPPLY_ENERGY_FULL_DESIGN=47520000
POWER_SUPPLY_ENERGY_FULL=18930000
POWER_SUPPLY_ENERGY_NOW=210000
POWER_SUPPLY_MODEL_NAME=IBM-08K8040
POWER_SUPPLY_MANUFACTURER=SANYO
POWER_SUPPLY_SERIAL_NUMBER= 315
>From reading linux-2.6/drivers/power/power_supply_sysfs.c, one sees
that we maybe can be sure to get the information in a certain ordner,
but the line-numbers will vary on different systems (as not all
information is available everywhere).
Attached you find a patch that makes acpitool correctly understand the
contents of this file and which produces a working output for me.
Before the patch:
% acpitool -B
Battery is not present, bailing out.
Battery #1 : slot empty
After the patch:
% ./src/acpitool -B
Battery #1 : present
Remaining capacity : 18830000, 99.47%, 00:04:21
Design capacity : 47520000
Last full capacity : 18930000, 39.84% of design capacity
Capacity loss : 60.16%
Present rate : 1375000
Charging state : Charging
Battery type : Li-ion, Battery
Model number : IBM-08K8040
Serial number : 315
You maybe want to tweak it a bit, but that's what works for me and thus
I wanted to share it now.
Regards
Evgeni
--
Bruce Schneier Fact Number 1165:
Bruce Schneier can zoom in further than you can on Google Maps.
--- acpitool-0.5.orig/src/battery.cpp 2008-07-24 01:04:16.000000000 +0200
+++ acpitool-0.5/src/battery.cpp 2009-05-14 21:58:06.000000000 +0200
@@ -133,13 +133,13 @@
else
Precision = 4;
- if(strncmp(Batt_Info[i]->Charging_State,"char",4)==0)
+ if(strncasecmp(Batt_Info[i]->Charging_State,"char",4)==0)
{
Is_Charging = 1;
}
else
{
- if(strncmp(Batt_Info[i]->Charging_State,"disch",5)==0) Is_Discharging = 1;
+ if(strncasecmp(Batt_Info[i]->Charging_State,"disch",5)==0) Is_Discharging = 1;
}
if(Show_Time) // calculate remaining or charging time only if present battery rate != 0 //
@@ -482,7 +482,7 @@
int Get_Battery_Info_from_Sys(const int bat_nr, Battery_Info *bat_info, int verbose)
{
ifstream file_in;
- char filename[6][65], str[100], temp[100];
+ char filename[6][65], str[100], temp[100], attr[100];
int bat_count = 0, start = 0, findex = 0;
DIR *battery_dir;
char *name, *dirname;
@@ -588,142 +588,66 @@
return -1;
}
- memset(str, '\0', 100);
- for(int t=0; t<5; t++)
- fgets(str, 100, power_fp); /* skip first 5 lines */
+ strncpy(bat_info->Technology, "unknown", 7);
+ strncpy(bat_info->Voltage_Now, "unknown", 7);
+ strncpy(bat_info->Present_Rate, "unknown", 7);
+ strncpy(bat_info->Design_Cap, "unknown", 7);
+ strncpy(bat_info->LastFull_Cap, "unknown", 7);
+ strncpy(bat_info->Remaining_Cap, "unknown", 7);
+ strncpy(bat_info->Model, "unknown", 7);
+ strncpy(bat_info->Serial, "unknown", 7);
+
+ // see linux-2.6/drivers/power/power_supply_sysfs.c
+ // there can be different number of lines, so read up to 40 lines
+ for(int t=0; t<40; t++) {
- /* get battery status (full, charging, ...) */
memset(str, '\0', 100);
- fgets(str, 100, power_fp);
- if (strlen(str)>0)
- {
+ memset(attr, '\0', 100);
memset(temp, '\0', 100);
+ fgets(str, 100, power_fp);
+ sscanf(str, "%[^=]s %*s %[^\n]", attr);
sscanf(str, "%*[^=] %*c %s %[^\n]",temp);
+ if (strcmp(attr,"POWER_SUPPLY_STATUS")==0) {
strncpy(bat_info->Charging_State, temp, 12);
}
-
-
- /* get battery presence (0 or 1) */
- memset(str, '\0', 100);
- fgets(str, 100, power_fp);
- if (strlen(str)>0)
- {
- memset(temp, '\0', 100);
- strncpy(temp, str+21, 1);
- if(strncmp(temp,"1",1)==0)
- bat_info->Battery_Present = 1; /* yes, we have a battery */
- else
- {
- bat_info->Battery_Present = 0;
- printf(" Battery is not present, bailing out. \n");
- return 0; /* bail out if battery is not present */
- }
+ else if (strcmp(attr,"POWER_SUPPLY_TYPE")==0) {
+ strncpy(bat_info->Bat_Type, temp, 12);
}
-
-
- /* get technology */
- fgets(str, 100, power_fp);
- if (strlen(str)>0)
- {
- memset(temp, '\0', 100);
- sscanf(str, "%*[^=] %*c %s %[^\n]",temp);
+ else if (strcmp(attr,"POWER_SUPPLY_TECHNOLOGY")==0) {
strncpy(bat_info->Technology, temp, 12);
}
- else
- strncpy(bat_info->Technology, "unknown", 7);
-
-
- fgets(str, 100, power_fp); /* skip 1 line */
-
-
- /* get voltage_now */
- fgets(str, 100, power_fp);
- if (strlen(str)>0)
- {
- memset(temp, '\0', 100);
- sscanf(str, "%*[^=] %*c %s %[^\n]",temp);
+ else if (strcmp(attr,"POWER_SUPPLY_VOLTAGE_NOW")==0) {
strncpy(bat_info->Voltage_Now, temp, 12);
}
- else
- strncpy(bat_info->Voltage_Now, "unknown", 7);
-
-
- /* get current_now, which I believe is the charging rate ? */
- fgets(str, 100, power_fp);
- if (strlen(str)>0)
- {
- memset(temp, '\0', 100);
- sscanf(str, "%*[^=] %*c %s %[^\n]",temp);
- strncpy(bat_info->Present_Rate, temp, 12);
+ else if (strcmp(attr,"POWER_SUPPLY_CURRENT_NOW")==0) {
+ strncpy(bat_info->Present_Rate, temp, 9);
}
- else
- strncpy(bat_info->Present_Rate, "unknown", 7);
-
-
- /* get charge_full_design */
- fgets(str, 100, power_fp);
- if (strlen(str)>0)
- {
- memset(temp, '\0', 100);
- sscanf(str, "%*[^=] %*c %s %[^\n]",temp);
- strncpy(bat_info->Design_Cap, temp, 12);
+ else if (strcmp(attr,"POWER_SUPPLY_ENERGY_FULL_DESIGN")==0) {
+ strncpy(bat_info->Design_Cap, temp, 9);
}
- else
- strncpy(bat_info->Design_Cap, "unknown", 7);
-
-
- /* get charge_full, which is the last full capacity I guess ? */
- fgets(str, 100, power_fp);
- if (strlen(str)>0)
- {
- memset(temp, '\0', 100);
- sscanf(str, "%*[^=] %*c %s %[^\n]",temp);
- strncpy(bat_info->LastFull_Cap, temp, 12);
+ else if (strcmp(attr,"POWER_SUPPLY_ENERGY_FULL")==0 ) {
+ strncpy(bat_info->LastFull_Cap, temp, 9);
}
- else
- strncpy(bat_info->LastFull_Cap, "unknown", 7);
-
-
- /* get charge_now */
- fgets(str, 100, power_fp);
- if (strlen(str)>0)
- {
- memset(temp, '\0', 100);
- sscanf(str, "%*[^=] %*c %s %[^\n]",temp);
- strncpy(bat_info->Remaining_Cap, temp, 12);
+ else if (strcmp(attr,"POWER_SUPPLY_ENERGY_NOW")==0) {
+ strncpy(bat_info->Remaining_Cap, temp, 9);
}
- else
- strncpy(bat_info->Remaining_Cap, "unknown", 7);
-
-
- /* get model_name */
-
- fgets(str, 100, power_fp);
- if (strlen(str)>0)
- {
- memset(temp, '\0', 100);
- strncpy(temp, str+24, 12); // use strncpy here because sscanf chokes on blanks in this one ? //
-
- memset(str, '\0', 100);
- sscanf(temp, "%[^\n]", str); // strip trailing \n, fucks up output //
-
- strncpy(bat_info->Model, str, 12);
+ else if (strcmp(attr,"POWER_SUPPLY_MODEL_NAME")==0) {
+ strncpy(bat_info->Model, temp, 12);
}
- else
- strncpy(bat_info->Model, "unknown", 7);
-
- fgets(str, 100, power_fp);
-
- /* get serial */
- fgets(str, 100, power_fp);
- if (strlen(str)!=0)
- {
- memset(temp, '\0', 100);
- sscanf(str, "%*[^=] %*c %s %[^\n]",temp);
+ else if (strcmp(attr,"POWER_SUPPLY_SERIAL_NUMBER")==0) {
strncpy(bat_info->Serial, temp, 12);
}
- else
- strncpy(bat_info->Serial, "unknown", 7);
+ else if (strcmp(attr,"POWER_SUPPLY_PRESENT")==0) {
+ if(strncmp(temp,"1",1)==0) {
+ bat_info->Battery_Present = 1;
+ }
+ else {
+ bat_info->Battery_Present = 0;
+ printf(" Battery is not present, bailing out. \n");
+ return 0;
+ }
+ }
+ }
fclose(power_fp);
}
pgp2h6NQ4oQCV.pgp
Description: PGP signature

