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);
 	}

Attachment: pgp2h6NQ4oQCV.pgp
Description: PGP signature

Reply via email to