I put together a preliminary patch to switch powertop to use the power
supply class (/sys/class/power_supply/) instead of the deprecated /proc
interface (/proc/acpi/battery/). This is compatible with 2.6.23 and
newer kernels. I'm not really sure what powertop's backwards
compatibility goal is, but I dropped code for the old interface.
Caveats: Using the ACPI battery module on my Lenovo ThinkPad T61,
current was reported in watts instead of amps, so I used watts_drawn
instead of amperes_drawn as I had expected. This appears to violate the
kernel documentation in power/power_supply_class.txt so perhaps it
should get fixed in the kernel. Similar holds true for energy_now -- it
reported watts instead of watt-hours. If either of these isn't true for
your computer, this patch won't work. You can check by comparing the
contents of /proc/acpi/battery/*/state with
/sys/class/power_supply/*/*_now.
I'd appreciate any comments you have.
Thanks,
Donnie
Switch powertop to use the power supply class (/sys/class/power_supply/)
instead of the deprecated /proc interface (/proc/acpi/battery/). This is
compatible with 2.6.23 and newer kernels.
Caveats: Using the ACPI battery module on my Lenovo ThinkPad T61,
current was reported in watts instead of amps, so I used watts_drawn
instead of amperes_drawn as I had expected. This appears to violate the
kernel documentation in power/power_supply_class.txt so perhaps it
should get fixed in the kernel. Similar holds true for energy_now -- it
reported watts instead of watt-hours. If either of these isn't true for
your computer, this patch won't work. You can check by comparing the
contents of /proc/acpi/battery/*/state with
/sys/class/power_supply/*/*_now.
-Donnie Berkholz <[EMAIL PROTECTED]>
Index: powertop.c
===================================================================
--- powertop.c (revision 273)
+++ powertop.c (working copy)
@@ -353,7 +353,7 @@
char filename[256];
- dir = opendir("/proc/acpi/battery");
+ dir = opendir("/sys/class/power_supply");
if (!dir)
return;
@@ -362,53 +362,68 @@
double voltage = 0.0;
double amperes_drawn = 0.0;
double watts_drawn = 0.0;
- double amperes_left = 0.0;
double watts_left = 0.0;
char line[1024];
- if (strlen(dirent->d_name) < 3)
+ if (strstr(dirent->d_name, "AC"))
continue;
- sprintf(filename, "/proc/acpi/battery/%s/state",
dirent->d_name);
+ sprintf(filename, "/sys/class/power_supply/%s/present",
dirent->d_name);
file = fopen(filename, "r");
if (!file)
continue;
- memset(line, 0, 1024);
- while (fgets(line, 1024, file) != NULL) {
- char *c;
- if (strstr(line, "present:") && strstr(line, "no"))
+ int s;
+ if ((s = getc(file)) != EOF) {
+ if (s == 0)
break;
+ }
+ fclose(file);
- if (strstr(line, "charging state:")
- && !strstr(line, "discharging"))
+ sprintf(filename, "/sys/class/power_supply/%s/status",
dirent->d_name);
+ file = fopen(filename, "r");
+ if (!file)
+ continue;
+ memset(line, 0, 1024);
+ if (fgets(line, 1024, file) != NULL) {
+ if (!strstr(line, "Discharging"))
dontcount = 1;
- c = strchr(line, ':');
- if (!c)
- continue;
- c++;
+ }
+ fclose(file);
- if (strstr(line, "present voltage"))
- voltage = strtoull(c, NULL, 10) / 1000.0;
-
- if (strstr(line, "remaining capacity") && strstr(c,
"mW"))
- watts_left = strtoull(c, NULL, 10) / 1000.0;
+ sprintf(filename, "/sys/class/power_supply/%s/voltage_now",
dirent->d_name);
+ file = fopen(filename, "r");
+ if (!file)
+ continue;
+ memset(line, 0, 1024);
+ if (fgets(line, 1024, file) != NULL) {
+ voltage = strtoull(line, NULL, 10) / 1000000.0;
+ }
+ fclose(file);
- if (strstr(line, "remaining capacity") && strstr(c,
"mAh"))
- amperes_left = strtoull(c, NULL, 10) / 1000.0;
+ sprintf(filename, "/sys/class/power_supply/%s/energy_now",
dirent->d_name);
+ file = fopen(filename, "r");
+ if (!file)
+ continue;
+ memset(line, 0, 1024);
+ if (fgets(line, 1024, file) != NULL) {
+ watts_left = strtoull(line, NULL, 10) / 1000000.0;
+ }
+ fclose(file);
- if (strstr(line, "present rate") && strstr(c, "mW"))
- watts_drawn = strtoull(c, NULL, 10) / 1000.0 ;
-
- if (strstr(line, "present rate") && strstr(c, "mA"))
- amperes_drawn = strtoull(c, NULL, 10) / 1000.0;
-
+ sprintf(filename, "/sys/class/power_supply/%s/current_now",
dirent->d_name);
+ file = fopen(filename, "r");
+ if (!file)
+ continue;
+ memset(line, 0, 1024);
+ if (fgets(line, 1024, file) != NULL) {
+ watts_drawn = strtoull(line, NULL, 10) / 1000000.0;
}
fclose(file);
if (!dontcount) {
rate += watts_drawn + voltage * amperes_drawn;
}
- cap += watts_left + voltage * amperes_left;
+ cap += watts_left;
}
_______________________________________________
Power mailing list
[email protected]
http://www.bughost.org/mailman/listinfo/power