On Fri, 23 May 2008 23:18:30 +0200, Bertram Bourdrez wrote:

> I tried the patch, and it doesn't give me an estimate for the time remaining
> on charging or discharging my battery. It appears that this is because it
> reads the wrong files (like /sys/class/power_supply/BAT0/charge_now, which
> doesn't exist on my system), producing output like:
> 
>      Battery 1 (Battery): Discharging, (null)

That's why I believe every system is different, i.e. it makes different files
in /sys/ (or /proc/).

This is working on my system:

$ ./acpi -p
     Battery 1 (Battery): Discharging, 3814000
  AC Adapter 2 (Mains): online
$ # I'm connecting the AC plug
$ ./acpi -p
     Battery 1 (Battery): Full, 3814000
  AC Adapter 2 (Mains): online
$


From the `ls -lR` you reported, the wanted file might be "energy_now" (I don't
have it on my system, for example). What does it contain?

You might want to try the patch I'm attaching: I've added also energy_now, but
it overrides any value from charge_now (or the contrary, whichever comes
first). I don't really know if both files will ever cohexist though.


Kindly,
David

-- 
 . ''`.  Debian maintainer | http://wiki.debian.org/DavidPaleino
 : :'  : Linuxer #334216 --|-- http://www.hanskalabs.net/
 `. `'`  GPG: 1392B174 ----|---- http://snipr.com/qa_page
   `-   2BAB C625 4E66 E7B8 450A C3E1 E6AA 9017 1392 B174
--- acpi-0.09.orig/main.c
+++ acpi-0.09/main.c
@@ -25,34 +25,22 @@
 #include <getopt.h>
 #include "acpi.h"
 
-static void do_show_batteries(char *acpi_path, int show_empty_slots)/*{{{*/
+static void do_show_power_supplies(char *acpi_path, int show_empty_slots)
 {
-	struct list *batteries;
+	struct list *power_supplies;
 
-	batteries = find_devices(acpi_path, "battery", TRUE);
-	print_battery_information(batteries, show_empty_slots);
-	free_devices(batteries);
+	power_supplies = find_devices(acpi_path, "power_supply", TRUE);
+	print_power_supply_information(power_supplies, show_empty_slots);
+	free_devices(power_supplies);
 }
 
 static void do_show_thermal(char *acpi_path, int show_empty_slots, int temperature_units) {/*{{{*/
 	struct list *thermal;
-	thermal = find_devices(acpi_path, "thermal_zone", FALSE);
-	if (!thermal) {
-		/* old acpi directory structure */
-		thermal = find_devices(acpi_path, "thermal", TRUE); 
-	}
+	thermal = find_devices(acpi_path, "thermal", FALSE);
 	print_thermal_information(thermal, show_empty_slots, temperature_units);
 	free_devices(thermal);
 }
 
-static void do_show_ac_adapter(char *acpi_path, int show_empty_slots)/*{{{*/
-{
-	struct list *ac_adapter;
-	ac_adapter = find_devices(acpi_path, "ac_adapter", TRUE);
-	print_ac_adapter_information(ac_adapter, show_empty_slots);
-	free_devices(ac_adapter);
-}
-
 static int version(void)/*{{{*/
 {
 	printf(ACPI_VERSION_STRING "\n"
@@ -68,26 +56,24 @@
 {
 	printf(
 "Usage: acpi [OPTION]...\n"
-"Shows information from the /proc filesystem, such as battery status or\n"
+"Shows information from the /sys filesystem, such as battery status or\n"
 "thermal information.\n"
 "\n"
-"  -b, --battery				battery information\n"
-"  -B, --without-battery		suppress battery information\n"
 "  -t, --thermal				thermal information\n"
 "  -T, --without-thermal		suppress thermal information\n"
-"  -a, --ac-adapter			 ac adapter information\n"
-"  -A, --without-ac-adapter	 suppress ac-adapter information\n"
+"  -p, --power-supplies				power supplies information\n"
+"  -P, --without-power-supplies		suppress power supplies information\n"
 "  -V, --everything			 show every device, overrides above options\n"
 "  -s, --show-empty			 show non-operational devices\n"
 "  -S, --hide-empty			 hide non-operational devices\n"
-"  -c, --celsius				use celsius as the temperature unit\n"
-"  -f, --fahrenheit			 use fahrenheit as the temperature unit\n"
-"  -k, --kelvin				 use kelvin as the temperature unit\n"
-"  -d, --directory <dir>		path to ACPI info (/proc/acpi)\n"
+//"  -c, --celsius				use celsius as the temperature unit\n"
+//"  -f, --fahrenheit			 use fahrenheit as the temperature unit\n"
+//"  -k, --kelvin				 use kelvin as the temperature unit\n"
+"  -d, --directory <dir>		path to ACPI info (/sys/class)\n"
 "  -h, --help				   display this help and exit\n"
 "  -v, --version				output version information and exit\n"
 "\n"
-"By default, acpi displays information on installed system batteries.\n"
+"By default, acpi displays information on installed system power supplies.\n"
 "Non-operational devices, for example empty battery slots are hidden.\n"
 "The default unit of temperature is degrees celsius.\n"
 "\n"
@@ -100,12 +86,10 @@
 	{ "help", 0, 0, 'h' }, 
 	{ "version", 0, 0, 'v' }, 
 	{ "verbose", 0, 0, 'V' }, 
-	{ "battery", 0, 0, 'b' }, 
-	{ "without-battery", 0, 0, 'B' }, 
 	{ "thermal", 0, 0, 't' }, 
 	{ "without-thermal", 0, 0, 'T' }, 
-	{ "ac-adapter", 0, 0, 'a' }, 
-	{ "without-ac-adapter", 0, 0, 'A' }, 
+	{ "power-supplies", 0, 0, 'p' },
+	{ "without-power-supplies", 0, 0, 'P' },
 	{ "show-empty", 0, 0, 's' }, 
 	{ "hide-empty", 0, 0, 'S' }, 
 	{ "celcius", 0, 0, 'c' }, 
@@ -120,9 +104,8 @@
 int main(int argc, char *argv[])/*{{{*/
 {
 	int show_everything = 0;
-	int show_batteries = 1;
 	int show_thermal = 0;
-	int show_ac_adapter = 0;
+	int show_power_supplies = 1;
 	int show_empty_slots = 0;
 	int temperature_units = TEMP_CELSIUS;
 	int ch, option_index;
@@ -133,28 +116,22 @@
 		return -1;
 	}
 
-	while ((ch = getopt_long(argc, argv, "VbBtTaAsShvfkcd:", long_options, &option_index)) != -1) {
+	while ((ch = getopt_long(argc, argv, "VbBtTpPsShvfkcd:", long_options, &option_index)) != -1) {
 		switch (ch) {
 			case 'V':
 				show_everything = 1;
 				break;
-			case 'b':
-				show_batteries = 1;
-				break;
-			case 'B':
-				show_batteries = 0;
-				break;
 			case 't':
 				show_thermal = 1;
 				break;
 			case 'T':
 				show_thermal = 0;
 				break;
-			case 'a':
-				show_ac_adapter = 1;
+			case 'p':
+				show_power_supplies = 1;
 				break;
-			case 'A':
-				show_ac_adapter = 0;
+			case 'P':
+				show_power_supplies = 0;
 				break;
 			case 's':
 				show_empty_slots = 1;
@@ -165,6 +142,7 @@
 			case 'v':
 				return version();
 				break;
+			/*
 			case 'f':
 				temperature_units = TEMP_FAHRENHEIT;
 				break;
@@ -174,6 +152,7 @@
 			case 'c':
 				temperature_units = TEMP_CELSIUS;
 				break;
+			*/
 			case 'd':
 				free(acpi_path);
 				acpi_path = strdup(optarg);
@@ -188,15 +167,11 @@
 		}
 	}
 
-	if (show_everything || show_batteries) {
-		do_show_batteries(acpi_path, show_empty_slots);
-	}
 	if (show_everything || show_thermal) {
 		do_show_thermal(acpi_path, show_empty_slots, temperature_units);
 	}
-	if (show_everything || show_ac_adapter) {
-		do_show_ac_adapter(acpi_path, show_empty_slots);
+	if (show_everything || show_power_supplies) {
+		do_show_power_supplies(acpi_path, show_empty_slots);
 	}
 	return 0;
 }
-
--- acpi-0.09.orig/acpi.c
+++ acpi-0.09/acpi.c
@@ -44,7 +44,7 @@
 		!strcmp(de->d_name, "..");
 }
 
-static struct field *parse_field(char *buf)
+static struct list *parse_field(char *filename, char *buf)
 {
 	struct field *rval;
 	char *p;
@@ -62,23 +62,9 @@
 		exit(1);
 	}
 
-	p = buf;
-	while (*(p++)) {
-		if (*p == ':') {
-			strncpy(attr, buf, p - buf);
-			has_attr = 1;
-			break;
-		}
-	}
-	if (!has_attr) {
-		free(attr); free(value); free(rval);
-		return NULL;
-	}
-	p++;
-	while (*(p++)) {
-		if (*p != ' ') { break; }
-	}
-	strncpy(value, p, BUF_SIZE);
+	strncpy(attr, filename, BUF_SIZE);
+	strncpy(value, buf, BUF_SIZE);
+
 	rval->attr = attr;
 	rval->value = value;
 	return rval;
@@ -88,6 +74,7 @@
 {
 	FILE *fd;
 	char buf[BUF_SIZE];
+	int i;
 
 	fd = fopen(filename, "r");
 	if (!fd) {
@@ -95,7 +82,7 @@
 	}
 	while (fgets(buf, BUF_SIZE, fd)) {
 		struct field *f;
-		f = parse_field(buf);
+		f = parse_field(filename, buf);
 		if (!f) { continue; }
 		l = list_append(l, f);
 	}
@@ -110,11 +97,13 @@
 	if (chdir(device_name) < 0) {
 		return NULL;
 	}
-	rval = parse_info_file(rval, "state");
 	rval = parse_info_file(rval, "status");
-	rval = parse_info_file(rval, "info");
-	rval = parse_info_file(rval, "temperature");
-	rval = parse_info_file(rval, "cooling_mode");
+	rval = parse_info_file(rval, "type");
+	rval = parse_info_file(rval, "charge_now");
+	rval = parse_info_file(rval, "energy_now");
+	rval = parse_info_file(rval, "online");
+	rval = parse_info_file(rval, "temp");
+	rval = parse_info_file(rval, "cur_state");
 	chdir("..");
 	return rval;
 }
@@ -153,6 +142,7 @@
 		}
 		exit(1);
 	}
+
 	if (chdir(device_type) < 0) {
 		if (showerr) {
 			fprintf(stderr, "No support for device type: %s\n", device_type);
@@ -181,33 +171,51 @@
 	return n;
 }
 
-void print_ac_adapter_information(struct list *ac_adapters, int show_empty_slots)
+void print_power_supply_information(struct list *power_supplies, int show_empty_slots)
 {
-	struct list *adapter = ac_adapters;
+	struct list *supply = power_supplies;
 	struct list *fields;
 	struct field *value;
-	int adapter_num = 1;
+	int supply_num = 1;
 
-	while (adapter) {
+	while (supply) {
 		char *state = NULL;
+		char *charge = NULL;
+		char *type = NULL;
+		char *online = NULL;
 
-		fields = adapter->data;
+		fields = supply->data;
 		while (fields) {
 			value = fields->data;
-			if (!strcmp(value->attr, "state") || !strcmp(value->attr, "Status")) {
+			if (!strcmp(value->attr, "state") || !strcmp(value->attr, "status")) {
 				state = value->value;
+			} else if (!strcmp(value->attr, "type")) {
+				type = value->value;
+			} else if (!strcmp(value->attr, "online")) {
+				online = value->value;
+			// Do charge_now and energy_now cohexist? If yes, FIXME.
+			} else if (!strcmp(value->attr, "charge_now")) {
+				charge = value->value;
+			} else if (!strcmp(value->attr, "energy_now")) {
+				charge = value->value;
 			}
 			fields = list_next(fields);
 		}
+
 		if (!state) {
-			if (show_empty_slots) {
-				printf("%12s %d: slot empty\n", AC_ADAPTER_DESC, adapter_num);
+			/* it's an AC_ADAPTER */
+			if (!strcmp(online, "0")) {
+				printf("%12s %d (%s): offline\n", AC_ADAPTER_DESC, supply_num, type);
+			} else {
+				printf("%12s %d (%s): online\n", AC_ADAPTER_DESC, supply_num, type);
 			}
 		} else {
-			printf("%12s %d: %s\n", AC_ADAPTER_DESC, adapter_num, state);
+			/* it's a BATTERY */
+			printf("%12s %d (%s): %s, %s\n", BATTERY_DESC, supply_num, type, state, charge);
 		}
-		adapter_num++;
-		adapter = list_next(adapter);
+
+		supply_num++;
+		supply = list_next(supply);
 	}
 }
 
@@ -219,137 +227,45 @@
 	int sensor_num = 1;
 
 	while (sensor) {
-		float temperature = -1;
-		char *state = NULL, *scale;
+		float temp = -1;
+		char *cur_state = "X";
+		char *scale, *type;
 		double real_temp;
-		
+
 		fields = sensor->data;
 		while (fields) {
 			value = fields->data;
-			if (!strcmp(value->attr, "state")) {
-				state = value->value;
-			} else if (!strcmp(value->attr, "temperature")) {
-				temperature = get_unit_value(value->value);
-		if (strstr(value->value, "dK")) {
-			temperature = (temperature / 10) - ABSOLUTE_ZERO;
-		}
+			if (!strcmp(value->attr, "type")) {
+				type = value->value;
+			} else if (!strcmp(value->attr, "temp")) {
+				temp = get_unit_value(value->value);
+				temp = temp/1000;
+			} else if (!strcmp(value->attr, "cur_state")) {
+				cur_state = value->value;
 			}
 			fields = list_next(fields);
 		}
-		if (temperature < 0 || !state) {
-			if (show_empty_slots) {
-				printf("%12s %d: slot empty\n", THERMAL_DESC, sensor_num);
-			}
-		} else {
-			real_temp = (double)temperature;
-			switch (temp_units) {
-				case TEMP_CELSIUS:
-					scale = "degrees C";
-					break;
-				case TEMP_FAHRENHEIT:
-					real_temp = (real_temp * 1.8) + 32;
-					scale = "degrees F";
-					break;
-				case TEMP_KELVIN:
-				default:
-					real_temp += ABSOLUTE_ZERO;
-					scale = "kelvin";
-					break;
-			}
-			printf("%12s %d: %s, %.1f %s\n", THERMAL_DESC, sensor_num, state, real_temp, scale);
-		}
-		sensor_num++;
-		sensor = list_next(sensor);
-	} 
-}
-
-void print_battery_information(struct list *batteries, int show_empty_slots)
-{
-	struct list *battery = batteries;
-	struct list *fields;
-	struct field *value;
-	int battery_num = 1;
 
-	while (battery) {
-		int remaining_capacity = -1;
-		int present_rate = -1;
-		int design_capacity = -1;
-		int hours, minutes, seconds;
-		int found_fields = 0;
-		double pct = 0;
-		int percentage;
-		char *state = NULL, *poststr;
-
-		fields = battery->data;
-		while (fields) {
-			value = fields->data;
-			if (!strcasecmp(value->attr, "remaining capacity")) {
-				remaining_capacity = get_unit_value(value->value);
-				found_fields++;
-			} else if (!strcasecmp(value->attr, "present rate")) {
-				present_rate = get_unit_value(value->value);
-				found_fields++;
-			} else if (!strcasecmp(value->attr, "last full capacity")) {
-				design_capacity = get_unit_value(value->value);
-				found_fields++;
-			} else if (!strcmp(value->attr, "charging state") ||
-				   !strcmp(value->attr, "State")) {
-				state = value->value;
-				found_fields++;
-			}
-			/* have we found every field we need? */
-			if (found_fields >= 4) {
-				break;
-			}
-			fields = list_next(fields);
-		}
-		if (remaining_capacity < 0 || design_capacity < 0 || !state) {
-			if (show_empty_slots) {
-				printf("%12s %d: slot empty\n", BATTERY_DESC, battery_num);
-			}
-		} else {
-			if (design_capacity < MIN_CAPACITY) {
-				pct = 0;
+		if (cur_state != "X") {
+			// it's not a temperature sensor, show generic info
+			if (!strcmp(cur_state, "0")) {
+				printf("%12s %d (%s): off\n", THERMAL_DESC, sensor_num, type);
 			} else {
-				pct = (double)remaining_capacity / design_capacity;
+				printf("%12s %d (%s): on\n", THERMAL_DESC, sensor_num, type);
 			}
-			percentage = pct * 100;
-			if (percentage > 100)
-				percentage = 100;
-			printf("%12s %d: %s, %d%%", BATTERY_DESC, battery_num, state, percentage);
-			if (present_rate == -1) {
-				poststr = "rate information unavailable.";
-				seconds = -1;
-			} else if (!strcmp(state, "charging")) {
-				if (present_rate > MIN_PRESENT_RATE) {
-					seconds = 3600 * (double)(design_capacity - remaining_capacity) / present_rate;
-					poststr = " until charged";
-				} else {
-					poststr = "charging at zero rate - will never fully charge.";
-					seconds = -1;
+		} else {
+			if (temp < 0) {
+				if (show_empty_slots) {
+					printf("%12s %d (%s): slot empty\n", THERMAL_DESC, sensor_num, type);
 				}
-			} else if (!strcmp(state, "discharging")) {
-				seconds = 3600 * (float)remaining_capacity / present_rate;
-				poststr = " remaining";
 			} else {
-				poststr = NULL;
-				seconds = -1;
+				real_temp = (double)temp;
+				scale = "degrees C";
+				printf("%12s %d (%s): %.1f %s\n", THERMAL_DESC, sensor_num, type, real_temp, scale);
 			}
-			if (seconds > 0) {
-				hours = seconds / 3600;
-				seconds -= 3600 * hours;
-				minutes = seconds / 60;
-				seconds -= 60 * minutes;
-				printf(", %02d:%02d:%02d%s", hours, minutes, seconds, poststr);
-			} else if ((seconds < 0) && (poststr != NULL)) {
-				printf(", %s", poststr);
-			}
-			printf("\n");
 		}
-		battery = list_next(battery);
-		battery_num++;
+
+		sensor_num++;
+		sensor = list_next(sensor);
 	}
 }
-
-
-
--- acpi-0.09.orig/acpi.h
+++ acpi-0.09/acpi.h
@@ -28,7 +28,7 @@
 /* remember to update this when making new releases */
 #define ACPI_VERSION_STRING "acpi " VERSION
 
-#define ACPI_PATH   "/proc/acpi"
+#define ACPI_PATH   "/sys/class"
 #define BUF_SIZE    1024
 
 #define TEMP_KELVIN     0
@@ -49,7 +49,7 @@
 
 void print_battery_information(struct list *batteries, int show_empty_slots);
 
-void print_ac_adapter_information(struct list *batteries, int show_empty_slots);
+void print_power_supply_information(struct list *power_supplies, int show_empty_slots);
 
 void print_thermal_information(struct list *batteries, int show_empty_slots, int temp_units);
 

Attachment: signature.asc
Description: PGP signature

Reply via email to