GNOME Bugzilla – Bug 104942
New feature: time remaining.
Last modified: 2004-12-22 21:47:04 UTC
I wanted the ability to see aproximately how much time I had left while running my laptop on battery power. As with all methods of predicting the future, this one suffers from a fair amound of innaccuracy. The life of a battery's change depends on the way the laptop is being used, so one should not expect this number to change linerally with time, but to fluctuate with current draw. One should think of the time remaining as: "The approximate number of minutes remaining on the battery at the current rate of discharge." While I haven't tested this with APM, or on any other arch, I think it will "just work" as I didn't change anything fundmental. There are a few corner cases to mention, when the laptop is plugged in and the battery is fully charged, a divide by zero condition exists in which I simply display 0 minutes instead of infinity (I suppose someone could find correct character for this but it probably isn't worth anyone's time). Another intersting case exists when the machine is plugged in, /proc/acpi reports the charge rate of the battery (instead of the discharge rate). I chose to change the meaning from "the number of minutes until empty" to "the number of minute until full", since I can no longer determine the former. This is where I feel my patch is the weakest, the battery does not charge at a linear rate, and thus the amount of change time left is going to be incorrect. Undoubtibly, all batteries charge at different rates (this has not been tested by me ;-), so the best one could hope for is some sort of generic charging curve, possibly based on the type of reported battery (LION, vs. NiCad, vs. MNiH). I decided that I would ask for input on this before bothering to implement some prediction algorithem which is going to be inherrently incorrect anyway. Best to have a simple and easy to understand patch at first, and make it complicated after it is accepted. (: --- gnome-applets-2.2.0/battstat/acpi-linux.c.orig Sun Jan 26 09:39:30 2003 +++ gnome-applets-2.2.0/battstat/acpi-linux.c Fri Jan 31 12:40:16 2003 @@ -142,7 +142,7 @@ */ gboolean acpi_linux_read(struct apm_info *apminfo) { - guint32 max_capacity, low_capacity, critical_capacity, remain; + guint32 max_capacity, low_capacity, critical_capacity, remain, rate; gboolean charging, ac_online; gulong acpi_ver; char buf[BUFSIZ]; @@ -166,6 +166,7 @@ critical_capacity = 0; charging = FALSE; remain = 0; + rate = 0; ac_online = FALSE; hash = read_file ("/proc/acpi/info", buf, sizeof (buf)); @@ -212,6 +213,7 @@ charging = s ? (strcmp (s, "charging") == 0) : 0; } remain += read_long (hash, "remaining capacity"); + rate += read_long (hash, "present rate"); g_hash_table_destroy (hash); } } @@ -246,6 +248,9 @@ apminfo->battery_status = remain < low_capacity ? 1 : remain < critical_capac ity ? 2 : 0; apminfo->battery_percentage = (int) (remain/(float)max_capacity*100); apminfo->battery_flags = charging ? 0x8 : 0; + apminfo->battery_time = charging ? (int) rate ? (((max_capacity-remain)/(float)rate)*60) : 0 + : (int) rate ? ((remain/(float)rate)*60) : 0; + apminfo->using_minutes = 1; return TRUE; } --- gnome-applets-2.2.0/battstat/battstat_applet.c.orig Sun Jan 26 09:39:30 2003 +++ gnome-applets-2.2.0/battstat/battstat_applet.c Fri Jan 31 12:40:16 2003 @@ -304,6 +304,7 @@ guint batt_life; guint acline_status; guint batt_state; + guint batt_time; guint progress_value; guint pixmap_index; guint charging; @@ -348,21 +349,25 @@ acline_status = apminfo.ai_acline ? 1 : 0; batt_state = apminfo.ai_batt_stat; batt_life = apminfo.ai_batt_life; + batt_time = apminfo.using_minutes ? apminfo.battery_time : 0; /* untested */ charging = (batt_state == 3) ? TRUE : FALSE; #elif __OpenBSD__ acline_status = apminfo.ac_state ? 1 : 0; batt_state = apminfo.battery_state; batt_life = apminfo.battery_life; + batt_time = apminfo.using_minutes ? apminfo.battery_time : 0; /* untested */ charging = (batt_state == 3) ? TRUE : FALSE; #elif __linux__ acline_status = apminfo.ac_line_status ? 1 : 0; batt_state = apminfo.battery_status; batt_life = (guint) apminfo.battery_percentage; + batt_time = apminfo.using_minutes ? apminfo.battery_time : 0; charging = (apminfo.battery_flags & 0x8) ? TRUE : FALSE; #else acline_status = 1; batt_state = 0; batt_life = 100; + batt_time = 0; charging = TRUE; batterypresent = FALSE; #endif @@ -596,15 +601,19 @@ snprintf(new_string, sizeof(new_string), /* This string will display as a tooltip over the battery frame when the computer is using battery power.*/ - _("System is running on battery power. Battery: %d%% (%s)"), + _("System is running on battery power. Battery: %d%% %d:%.2d (%s)"), batt_life, + batt_time/60, + batt_time%60, _(status[batt_state])); } else { snprintf(new_string, sizeof(new_string), /* This string will display as a tooltip over the battery frame when the computer is using AC power.*/ - _("System is running on AC power. Battery: %d%% (%s)"), + _("System is running on AC power. Battery: %d%% %d:%.2d (%s)"), batt_life, + batt_time/60, + batt_time%60, _(status[batt_state])); } } else { @@ -629,8 +638,10 @@ /* Displayed as a tooltip over the battery meter when there is a battery present. %d will hold the current charge and %s will hold the status of the battery, (High, Low, Critical, Charging. */ - (_("Battery: %d%% (%s)")), + (_("Battery: %d%% %d:%.2d (%s)")), batt_life, + batt_time/60, + batt_time%60, _(status[batt_state])); } else { snprintf(new_string, sizeof(new_string),
Adding PATCH keyword and setting the priority->high because of the patch. Also, note that this is closely related to bug 109912, which talks about adaptive prediction of time remaining and gives a link to a GPL project on sourceforge which supposedly does this.
Mike, FWIW, it would be good if you attached the patch, instead of pasting it in- pasting it in tends to impossibly break whitespace, making it hard for someone else to test it.
I think the time remaining could be a very nice feature. Sorry that we didn't take notice about it before 2.6 freezes. Mike if you still feel like it, could you update the patch for CVS, attach it to the bug and i'll look into it right after 2.6 release.
You might want to look at: http://bugzilla.gnome.org/show_bug.cgi?id=125585 It's a patch for the same functionality. From a quick glance i think 125585 might be more correct, but i am not sure.
I'm adding the BLOCKED_BY_FREEZE keyword. Dennis: Just FYI, you don't have to provide the full URL. You can simply type 'bug xxxxxx' and bugzilla will automatically linkify it for you.
Also, both patches seem to miss out ACPI. Please look into providing the same feature there if possible. (And portability across supported platforms is a point too)
Umm, no. The battery applet, at least up to version 2.4.1, supports ACPI via a hack which simply approximates the APM system. Please note that I patched the function acpi_linux_read() in acpi-linux.c As far as portibility, I don't know what you expect. I only have access to my Linux laptop, if you really want someone to contribute that kind of thing, then you should include this patch and let the SparcBook users add in the necessary code if they feel the need. This is open source after all, just because this patch isn't perfect, and doesn't provide every feature that you would like, is no reason to put a hold on the patch. Once there is something in the code that provides the feature, I'm sure that others will be happy to extend it.
Sorry if I came off as negative to your work. That was never my intention. I'll let the maintainer decide what to do with the patch and I can assure you that the work you've put in is appreciated. :)
Marking this bug as a duplicate of bug #138959 as that one was the one that was CLOSED. It's in HEAD now and will appear in GNOME 2.8. *** This bug has been marked as a duplicate of 138959 ***