Hello, I have extended battery-stats to use ACPI information by means of libacpi, which in turn reads from /proc. libacpi is preferred over libapm, if libacpi reports ACPI support.
I hope this patch works as a motivation for the maintainer, to keep the package in better shape :) Otherwise, I offer my help. Best regards, Michael
diff -u -r battery-stats-0.3.3-orig/battery-stats-collector.c battery-stats-0.3.4/battery-stats-collector.c --- battery-stats-0.3.3-orig/battery-stats-collector.c 2003-03-21 02:12:01.000000000 +0100 +++ battery-stats-0.3.4/battery-stats-collector.c 2008-04-11 16:32:46.000000000 +0200 @@ -1,6 +1,6 @@ /* battery-stats-collector - collects statistics about battery performance - Copyright (C) 2002 Karl E. Jørgensen <[EMAIL PROTECTED]> + Copyright (C) 2002 Karl E. Jørgensen <[EMAIL PROTECTED]> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +23,7 @@ #include <time.h> #include <apm.h> #include <syslog.h> +#include <libacpi.h> static struct option long_options[] = { { "output", required_argument, NULL, 'o' }, @@ -37,11 +38,15 @@ }; static void apmdump(FILE *output, int ignore_missing_battery); +static void acpidump(FILE *output, const int ignore_missing_battery, + global_t *libacpi_global); +void check_and_write_log_line(FILE *output, const int percentage, + const int ac_state, const int remaining_time); static void show_version(void); static void show_usage(void); static char *myname = "battery-stats-collector"; -static char *myversion = "0.3.3"; +static char *myversion = "0.3.4"; static int do_syslog = 0; #define COMPLAIN(loglevel, args...) if (do_syslog) syslog(loglevel, ## args); \ @@ -154,10 +159,56 @@ exit(2); } + // initialize libacpi and determine ACPI support + global_t *libacpi_global = malloc (sizeof (global_t)); + int acpi_supported = check_acpi_support() == SUCCESS; + COMPLAIN(LOG_INFO, "Using lib%s.\n", acpi_supported ? "acpi" : "apm"); + if(acpi_supported) + { + int retval = init_acpi_batt(libacpi_global); + switch(retval) + { + case SUCCESS: + COMPLAIN(LOG_INFO, "Number of batteries: %i.%s\n", + libacpi_global->batt_count, + libacpi_global->batt_count > 1 ? + " Reading info from first battery only. " : ""); + break; + case NOT_SUPPORTED: + COMPLAIN(LOG_WARNING, "You have more than %i batteries. " + "Reading info from first battery only anyway.\n", MAX_ITEMS); + break; + case ALLOC_ERR: + COMPLAIN(LOG_ERR, "libacpi allocation error.\n"); + exit(2); + case ITEM_EXCEED: + COMPLAIN(LOG_WARNING, "You have more than %i batteries. " + "Reading info from first battery only anyway.\n", MAX_ITEMS); + break; + default: + COMPLAIN(LOG_ERR, "init_acpi_batt() returned unknown value: %i\n", + retval); + exit(2); + } + retval = init_acpi_acadapt(libacpi_global); + switch(retval) + { + case SUCCESS: + break; + case NOT_SUPPORTED: + COMPLAIN(LOG_ERR, "init_acpi_acadapt() returned NOT_SUPPORTED.\n"); + exit(2); + case ALLOC_ERR: + COMPLAIN(LOG_ERR, "libacpi allocation error.\n"); + exit(2); + } + } flush_count = 0; while (1) { - apmdump(stats_file, ignore_missing_battery); + if(acpi_supported) acpidump(stats_file, ignore_missing_battery, + libacpi_global); + else apmdump(stats_file, ignore_missing_battery); flush_count++; if (flush_count >= flush_interval) { @@ -170,6 +221,7 @@ sleep(sample_interval_secs); } + free(libacpi_global); fclose(stats_file); if (do_syslog) closelog(); @@ -207,8 +259,6 @@ { struct apm_info ai; int rc; - time_t theTime; - struct tm *tm; rc = apm_read(&ai); @@ -218,15 +268,6 @@ return; } - time(&theTime); - if (theTime == -1) - { - COMPLAIN(LOG_ERR, "Cannot get current time !?"); - return; - } - - tm = gmtime(&theTime); - #ifdef DEBUG apm_fulldump(&ai); #endif @@ -250,26 +291,10 @@ return; } - if (ai.battery_percentage > 100) - { - COMPLAIN(LOG_ERR, "Battery percentage > 100 (%d) !?"); - return; - } - - if (ai.battery_percentage < 0) - { - COMPLAIN(LOG_ERR, "Negative battery percentage (%d) !?"); - return; - } - - fprintf(output, "%ld %d %d %04d/%02d/%02d %02d:%02d:%02d %d\n", - theTime, - ai.battery_percentage, - (ai.ac_line_status == AC_LINE_STATUS_OFF) ? 0 - : ((ai.ac_line_status == AC_LINE_STATUS_ON) ? 1 : 2), - tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, - ai.battery_time - ); + check_and_write_log_line(output, ai.battery_percentage, + (ai.ac_line_status == AC_LINE_STATUS_OFF) ? 0 + : ((ai.ac_line_status == AC_LINE_STATUS_ON) ? 1 : 2), + ai.battery_time); } #ifdef DEBUG @@ -318,3 +343,66 @@ } #endif +static void acpidump(FILE *output, const int ignore_missing_battery, + global_t *libacpi_global) +{ + int rc = read_acpi_batt(0); + if (rc != SUCCESS) + { + COMPLAIN(LOG_ERR,"read_acpi_batt(0) failed with error code %d\n", rc); + return; + } + if (!batteries[0].present) + { + if (!ignore_missing_battery) + COMPLAIN(LOG_WARNING, "Battery 0 absent\n"); + return; + } + + read_acpi_acstate(libacpi_global); + if (libacpi_global->adapt.ac_state == P_ERR) + { + COMPLAIN(LOG_ERR, "AC Line status unknown\n"); + return; + } + + check_and_write_log_line(output, batteries[0].percentage, + (libacpi_global->adapt.ac_state == P_BATT) ? 2 : + ((libacpi_global->adapt.ac_state == P_AC) ? 1 : 0), + batteries[0].remaining_time); +} + +void check_and_write_log_line(FILE *output, const int percentage, + const int ac_state, const int remaining_time) +{ + time_t theTime; + time(&theTime); + if (theTime == -1) + { + COMPLAIN(LOG_ERR, "Cannot get current time !?\n"); + return; + } + + struct tm *tm = gmtime(&theTime); + + if (percentage > 100) + { + COMPLAIN(LOG_ERR, "Battery percentage > 100 (%d) !?\n", + percentage); + return; + } + + if (percentage < 0) + { + COMPLAIN(LOG_ERR, "Negative battery percentage (%d) !?\n", + percentage); + return; + } + + fprintf(output, "%ld %d %d %04d/%02d/%02d %02d:%02d:%02d %d\n", + theTime, percentage, ac_state, + tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec, + remaining_time); +} + diff -u -r battery-stats-0.3.3-orig/debian/control battery-stats-0.3.4/debian/control --- battery-stats-0.3.3-orig/debian/control 2008-04-11 16:40:11.000000000 +0200 +++ battery-stats-0.3.4/debian/control 2008-04-11 14:47:19.000000000 +0200 @@ -2,7 +2,7 @@ Section: admin Priority: extra Maintainer: Karl E. Jorgensen <[EMAIL PROTECTED]> -Build-Depends: debhelper (>> 3.0.0), libapm-dev +Build-Depends: debhelper (>> 3.0.0), libapm-dev, libacpi-dev Standards-Version: 3.5.6.1 Package: battery-stats @@ -16,4 +16,4 @@ It also contains a simple graph utility to show the battery charge/discharge patterns over time. . - Note: This requires APM to be enabled and working in your kernel. + Note: This requires APM or ACPI to be enabled and working in your kernel. diff -u -r battery-stats-0.3.3-orig/History battery-stats-0.3.4/History --- battery-stats-0.3.3-orig/History 2003-03-21 02:14:28.000000000 +0100 +++ battery-stats-0.3.4/History 2008-04-11 14:43:20.000000000 +0200 @@ -1,3 +1,5 @@ +0.3.4 + - Michael Bunk <[EMAIL PROTECTED]>: Add ACPI support. 0.3.3 - Converted part of the CVS changelog into this. The debian/changelog is exclusively for use by debian-specific changes from now on. diff -u -r battery-stats-0.3.3-orig/Makefile battery-stats-0.3.4/Makefile --- battery-stats-0.3.3-orig/Makefile 2003-01-16 15:11:47.000000000 +0100 +++ battery-stats-0.3.4/Makefile 2008-04-11 14:42:14.000000000 +0200 @@ -42,7 +42,7 @@ # Allow the caller to play with variables as they wish ALL_CFLAGS = $(CFLAGS) -ALL_LDLIBS = -lapm $(LDLIBS) +ALL_LDLIBS = -lapm -lacpi $(LDLIBS) .PHONY : all all : battery-stats-collector