Hi,
Here is the nmu I uploaded for ibam to fix this bug.
Thank you,
Barry deFreese
diff -u wmibam-0.0.1/debian/rules wmibam-0.0.1/debian/rules
--- wmibam-0.0.1/debian/rules
+++ wmibam-0.0.1/debian/rules
@@ -15,7 +15,7 @@
clean:
dh_testdir
dh_testroot
- -$(MAKE) clean
+ [ ! -f Makefile ] || $(MAKE) clean
dh_clean
install: build
diff -u wmibam-0.0.1/debian/control wmibam-0.0.1/debian/control
--- wmibam-0.0.1/debian/control
+++ wmibam-0.0.1/debian/control
@@ -3,7 +3,7 @@
Priority: optional
Maintainer: Florian Ragwitz <[EMAIL PROTECTED]>
Build-Depends: debhelper (>= 4.0.0), libx11-dev, libxext-dev, libxpm-dev
-Standards-Version: 3.6.2
+Standards-Version: 3.8.0
Package: wmibam
Architecture: any
diff -u wmibam-0.0.1/debian/changelog wmibam-0.0.1/debian/changelog
--- wmibam-0.0.1/debian/changelog
+++ wmibam-0.0.1/debian/changelog
@@ -1,3 +1,12 @@
+wmibam (0.0.1-2.1) unstable; urgency=low
+
+ * Non-maintainer upload.
+ * Replace ibam.* files from ibam package. (Closes: #501041).
+ * Make clean not ignore errors.
+ * Bump Standards Version to 3.8.0. (No changes needed).
+
+ -- Barry deFreese <[EMAIL PROTECTED]> Wed, 15 Oct 2008 11:00:37 -0400
+
wmibam (0.0.1-2) unstable; urgency=low
* Removed xlibs-dev build-dep in favour of dependencies to the individual
only in patch2:
unchanged:
--- wmibam-0.0.1.orig/ibam.hpp
+++ wmibam-0.0.1/ibam.hpp
@@ -1,8 +1,6 @@
// IBAM, the Intelligent Battery Monitor
// Copyright (C) 2001-2003, Sebastian Ritterbusch ([EMAIL PROTECTED])
//
-// adapted for wmibam by Florian Ragwitz <[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 the Free Software Foundation; either version 2
@@ -22,7 +20,6 @@
#define IBAM_MINIMAL_SECONDS_PER_PERCENT 10
#define IBAM_MAXIMAL_SECONDS_PER_PERCENT 800
#define IBAM_ASSUME_DEFAULT_BATTERY_MIN 120
-
#define IBAM_MAXIMAL_PROFILES 500
#include <iostream>
@@ -38,26 +35,46 @@
#include <sys/stat.h> // for mkdir
#include <sys/types.h> // for mkdir
-class apm_status
+class battery_status
{
- private:
- string driverVersion;
- string biosVersion;
- int apmFlags;
- int acLineStatus;
- int batteryStatus;
- int batteryFlag;
- int remainingBatteryPercent;
- int remainingBatteryLifeSeconds;
+ protected:
+ int acLineStatus;
+ int batteryStatus;
+ int chargeStatus;
+ int remainingBatteryPercent;
+ int remainingBatteryLifeSeconds;
+ string Path;
public:
inline int onBattery(void) const;
inline int charging(void) const;
inline int percent(void) const;
inline int seconds(void) const;
- inline void update(char *path="/proc/apm");
- inline apm_status(char *path="/proc/apm");
+ virtual inline void update(void) = 0;
+ inline battery_status(string path);
+ virtual inline ~battery_status(void);
+};
+
+class apm_status : public battery_status
+{
+ public:
+ inline void update(void);
+ inline apm_status(string path="/proc/apm");
};
+class pmu_status : public battery_status
+{
+ public:
+ inline void update(void);
+ inline pmu_status(string path="/proc/pmu");
+};
+
+class acpi_status : public battery_status
+{
+ public:
+ inline void update(void);
+ inline acpi_status(string path="/proc/acpi");
+};
+
class percent_data
{
private:
@@ -88,7 +105,7 @@
private:
percent_data data;
int data_changed; // 1 if save of ibam.rc demanded
- apm_status apm;
+ battery_status *apm;
percent_data battery;
int battery_loaded;
int battery_changed;
@@ -97,11 +114,10 @@
int charge_changed;
int profile_changed;
- double adaptive_damping_battery,adaptive_damping_charge;
-
unsigned long lasttime;
int lastpercent;
double lastratio;
+ int lastratiocount;
int laststatus;
double last_sec_per_min;
only in patch2:
unchanged:
--- wmibam-0.0.1.orig/ibam.inl
+++ wmibam-0.0.1/ibam.inl
@@ -1,8 +1,6 @@
// IBAM, the Intelligent Battery Monitor
// Copyright (C) 2001-2003, Sebastian Ritterbusch ([EMAIL PROTECTED])
//
-// adapted for wmibam by Florian Ragwitz <[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 the Free Software Foundation; either version 2
@@ -19,6 +17,7 @@
//
#include <iostream>
+#include <sstream>
#include <fstream>
#include <string>
#include <math.h>
@@ -27,6 +26,8 @@
#include <unistd.h>
#include <time.h>
#include <locale.h> // thus I may prevent evil krells to change to others..
+#include <dirent.h> // for acpi multiple batteries
+
#include <sys/stat.h> // for mkdir
#include <sys/types.h> // for mkdir
@@ -68,48 +69,74 @@
+ -1: Unknown
+ 8) min = minutes; sec = seconds */
-inline int apm_status::onBattery(void) const { return acLineStatus==0; }
-inline int apm_status::charging(void) const { return (batteryFlag&8)!=0; }
-inline int apm_status::percent(void) const { return remainingBatteryPercent; }
-inline int apm_status::seconds(void) const { return remainingBatteryLifeSeconds; }
-
-inline void apm_status::update(char *path)
+inline int battery_status::onBattery(void) const { return acLineStatus==0; }
+inline int battery_status::charging(void) const { return chargeStatus; }
+inline int battery_status::percent(void) const { return remainingBatteryPercent; }
+inline int battery_status::seconds(void) const { return remainingBatteryLifeSeconds; }
+
+inline battery_status::battery_status(string path) {
+ Path = path;
+}
+
+inline battery_status::~battery_status(void) { }
+
+inline void battery_status::update(void) {
+ cout << "battery_status::update() called. This should never happen!" << endl;
+}
+
+
+inline apm_status::apm_status(string path) : battery_status(path)
+{
+ update();
+}
+
+inline pmu_status::pmu_status(string path) : battery_status(path)
+{
+ update();
+}
+
+inline acpi_status::acpi_status(string path) : battery_status(path)
+{
+ update();
+}
+
+inline void apm_status::update(void)
{
ifstream in;
- int i;
- in.open(path);
+ int i;
+ in.open(Path.c_str());
for(i=0;i<10 && in.fail();i++)
- in.open(path);
+ in.open(Path.c_str());
if(in.fail())
{
- driverVersion="";
- biosVersion="";
- apmFlags=0;
acLineStatus=0;
batteryStatus=0;
- batteryFlag=0;
+ chargeStatus=0;
remainingBatteryPercent=-1;
remainingBatteryLifeSeconds=-1;
- return;
+ return;
}
+ string driverVersion, biosVersion;
+ int apmFlags, batteryFlag;
char c,d;
in >> driverVersion;
in >> biosVersion;
in >> c >> d; // 0x
- in >> c >> d;
+ in >> c >> d;
apmFlags=(c>'9'?c-'a'+10:c-'0')*16+(d>'9'?d-'a'+10:d-'0');
in >> c >> d; // 0x
- in >> c >> d;
+ in >> c >> d;
acLineStatus=(c>'9'?c-'a'+10:c-'0')*16+(d>'9'?d-'a'+10:d-'0');
in >> c >> d; // 0x
- in >> c >> d;
+ in >> c >> d;
batteryStatus=(c>'9'?c-'a'+10:c-'0')*16+(d>'9'?d-'a'+10:d-'0');
in >> c >> d; // 0x
- in >> c >> d;
+ in >> c >> d;
batteryFlag=(c>'9'?c-'a'+10:c-'0')*16+(d>'9'?d-'a'+10:d-'0');
- in >> remainingBatteryPercent >> c; // %
- string minsec;
- in >> remainingBatteryLifeSeconds >> minsec;
+ chargeStatus = (batteryStatus&8)!=0;
+ in >> remainingBatteryPercent >> c; // %
+ string minsec;
+ in >> remainingBatteryLifeSeconds >> minsec;
if(minsec=="min") remainingBatteryLifeSeconds*=60;
#ifdef DEBUG
cout << "Driver Version: " << driverVersion << endl;
@@ -123,9 +150,242 @@
#endif
}
-inline apm_status::apm_status(char *path)
+inline void pmu_status::update(void)
{
- update(path);
+ ifstream in;
+ int i;
+ in.open((Path+"/info").c_str());
+ for (i = 0; i < 10 && in.fail(); i++)
+ in.open((Path+"/info").c_str());
+ if (in.fail())
+ {
+ acLineStatus = 0;
+ chargeStatus = 0;
+ remainingBatteryLifeSeconds = -1;
+ remainingBatteryPercent = -1;
+ return;
+ }
+
+ stringbuf buf;
+ char c;
+ int d, cur_charge = 0, max_charge = 0;
+ for (i = 0; i < 4; i++) {
+ in.get(buf, ':');
+ in >> c >> d;
+ if (i == 2)
+ acLineStatus = d;
+ }
+ in.close();
+ in.open((Path+"/battery_0").c_str());
+ for (i = 0; i < 10 && in.fail(); i++)
+ in.open((Path+"/battery_0").c_str());
+ if (in.fail()) {
+ acLineStatus = 0;
+ chargeStatus = 0;
+ remainingBatteryLifeSeconds = -1;
+ remainingBatteryPercent = -1;
+ return;
+ }
+
+ for (i = 0; i < 6; i++) {
+ in.get(buf, ':');
+ in >> c >> d;
+ if (i == 0)
+ chargeStatus = (d&2)==0;
+ if (i == 1)
+ cur_charge = d;
+ if (i == 2)
+ max_charge = d;
+ if (i == 5)
+ remainingBatteryLifeSeconds = d;
+ }
+
+ remainingBatteryPercent = (int)(cur_charge*100/max_charge);
+}
+
+// Acpi Percentage and Remaining time computation based upon
+// http://www.acpi.info/spec.htm V3.0
+//
+// [...]
+// 3.9.3 Battery Gas Gauge
+//
+// At the most basic level, the OS calculates Remaining Battery
+// Percentage [%] using the following formula:
+//
+// Battery Remaining Capacity [mAh/mWh]
+// Remaining Battery Percentage [%] = ------------------------------------ * 100
+// Last Full Charged Capacity [mAh/mWh]
+//
+// Control Method Battery also reports the Present Drain Rate [mA or mW]
+// for calculating the remaining battery life. At the most basic level,
+// Remaining Battery life is calculated by following formula:
+//
+// Battery Remaining Capacity [mAh/mWh]
+// Remaining Battery Life [h] = ------------------------------------
+// Battery Present Drain Rate [mA/mW]
+//
+// Smart Batteries also report the present rate of drain, but since they
+// can directly report the estimated runtime, this function should be used
+// instead as it can more accurately account for variations specific to
+// the battery
+// [...]
+//
+// I don't have a "Smart Battery", so I don't know, how /proc/acpi would
+// report that. Contributions are greatly appreciated.
+//
+// See also http://www.tldp.org/HOWTO/ACPI-HOWTO/usingacpi.html
+//
+
+inline void acpi_status::update(void)
+{
+ ifstream in;
+ DIR *acpi_battery_dir;
+ struct dirent *battery_entry;
+ int i;
+
+ acpi_battery_dir=opendir((Path+"/battery").c_str());
+
+ if (acpi_battery_dir==NULL)
+ {
+ acLineStatus = 0;
+ chargeStatus = 0;
+ remainingBatteryLifeSeconds = -1;
+ remainingBatteryPercent = -1;
+ return;
+ }
+
+ long total_capacity=0;
+ long total_remain=0;
+ long total_rate=0;
+
+ while ((battery_entry=readdir(acpi_battery_dir)))
+ {
+ if(battery_entry->d_name!=string(".")
+ && battery_entry->d_name!=string(".."))
+ {
+ in.open((((Path+"/battery/")+battery_entry->d_name)+"/info").c_str());
+ stringbuf buf;
+ char c;
+ int capacity=0;
+
+ for (i=0; i<3; i++)
+ {
+ in.get(buf, ':');
+ in >> c;
+ if (i==0)
+ {
+ in >> c;
+ if(c!='y') // present: yes
+ i=3;
+ } else if(i==2)
+ {
+ in >> capacity;
+ total_capacity+=capacity;
+ }
+ }
+
+ in.close();
+
+ #ifdef DEBUG
+ cout << "Battery "<<battery_entry->d_name<<": Capacity " << capacity;
+ #endif
+
+ if(capacity)
+ {
+ in.open((((Path+"/battery/")+battery_entry->d_name)+"/state").c_str());
+
+ for (i=0; i<5; i++)
+ {
+ in.get(buf, ':');
+ in >> c;
+ if (i==2)
+ {
+ char d,e,f,g,h;
+ in >> c >> d >> e >> f >> g >> h; // OUCH... #-} Somebody, please fix me
+ if(c=='c' && h=='i') // charging state: charging
+ {
+ acLineStatus=1;
+ batteryStatus=3;
+ chargeStatus=1;
+ #ifdef DEBUG
+ cout << " charging";
+ #endif
+ } else
+ if(c=='d') // charging state: discharge
+ {
+ acLineStatus=0;
+ batteryStatus=0;
+ chargeStatus=0;
+ #ifdef DEBUG
+ cout << " discharging";
+ #endif
+ } else
+ if(c=='c' && h=='e') // charging state: charged
+ {
+ acLineStatus=1;
+ batteryStatus=0;
+ chargeStatus=0;
+ #ifdef DEBUG
+ cout << " charged";
+ #endif
+ }
+ } else
+ if(i==3)
+ {
+ int rate=0;
+ in >> rate;
+ total_rate+=rate;
+ #ifdef DEBUG
+ cout << " Rate " << rate;
+ #endif
+
+ } else
+ if(i==4)
+ {
+ int remain=0;
+ in >> remain;
+ total_remain+=remain;
+ #ifdef DEBUG
+ cout << " Remain " << remain;
+ #endif
+ }
+ }
+ in.close();
+
+ } // has capacity
+
+ #ifdef DEBUG
+ cout << endl;
+ #endif
+
+ }
+ }
+ closedir(acpi_battery_dir);
+
+ if(total_capacity)
+ remainingBatteryPercent=int((100.*total_remain)/total_capacity+.5);
+ else
+ remainingBatteryPercent=100;
+
+ if(remainingBatteryPercent>100)
+ remainingBatteryPercent=100; // Don't ask...
+
+ if(remainingBatteryPercent<100 && acLineStatus==1 && chargeStatus==0) // Deal with strange Acpi-Data?
+ {
+ acLineStatus=1;
+ batteryStatus=3;
+ chargeStatus=1;
+ }
+
+ if(total_rate)
+ remainingBatteryLifeSeconds=(total_remain*60*60)/total_rate;
+ else
+ remainingBatteryLifeSeconds=(remainingBatteryPercent*IBAM_ASSUME_DEFAULT_BATTERY_MIN*60)/100;
+
+ #ifdef DEBUG
+ cout << "Remaining percent: " << remainingBatteryPercent << endl;
+ cout << "Remaining battery life seconds: " << remainingBatteryLifeSeconds << endl;
+ #endif
}
inline void percent_data::size_to(int newpercents)
@@ -388,13 +648,36 @@
data_changed(0),
battery_loaded(0),battery_changed(0),
charge_loaded(0),charge_changed(0),
- profile_changed(0),adaptive_damping_battery(15),
- adaptive_damping_charge(15),
- lasttime(time(NULL)),lastpercent(0),lastratio(1),
+ profile_changed(0),
+ lasttime(time(NULL)),lastpercent(0),
+ lastratio(1),lastratiocount(1),
laststatus(-1),
currenttime(time(NULL)),isvalid(0),profile_logging(1),
profile_number(0),profile_active(0)
{
+ string pmu_path = "/proc/pmu"; // These strings are already in ibam.hpp,
+ string acpi_path = "/proc/acpi"; // maybe a static function should check this
+ ifstream pmu,acpi;
+ pmu.open((pmu_path+"/info").c_str());
+ acpi.open((acpi_path+"/info").c_str());
+ if (pmu.is_open()) {
+#ifdef DEBUG
+ cout << "using pmu" << endl;
+#endif
+ pmu.close();
+ apm = new pmu_status();
+ } else if (acpi.is_open()) {
+#ifdef DEBUG
+ cout << "using acpi" << endl;
+#endif
+ acpi.close();
+ apm = new acpi_status();
+ } else {
+#ifdef DEBUG
+ cout << "using apm" << endl;
+#endif
+ apm = new apm_status();
+ }
home=getenv("HOME");
if(home!="")
home+="/";
@@ -402,46 +685,49 @@
ifstream in((home+".ibam/ibam.rc").c_str());
string saveversion;
in >> saveversion;
- if(saveversion==IBAM_VERSION)
- in >> lasttime >> lastpercent >> lastratio >> laststatus >> adaptive_damping_battery >> adaptive_damping_charge >> profile_logging >> profile_number >> profile_active;
+ double dummy;
+ if(saveversion==string("0.3"))
+ {
+ in >> lasttime >> lastpercent >> lastratio >> laststatus >> dummy >> dummy >> profile_logging >> profile_number >> profile_active;
+ data_changed=1;
+ }
+ if(saveversion==VERSION)
+ in >> lasttime >> lastpercent >> lastratio >> lastratiocount >> laststatus >> profile_logging >> profile_number >> profile_active;
else
data_changed=1; // force update
in.close();
- if(adaptive_damping_battery<2)
- adaptive_damping_battery=2;
- if(adaptive_damping_charge<2)
- adaptive_damping_charge=2;
- if(adaptive_damping_battery>200)
- adaptive_damping_battery=200;
- if(adaptive_damping_charge>200)
- adaptive_damping_charge=200;
-
- currentpercent=apm.percent();
+ currentpercent=apm->percent();
if(currentpercent!=-1)
isvalid=1;
- currentstatus=apm.onBattery()?1:apm.charging()?2:0;
+ currentstatus=apm->onBattery()?1:apm->charging()?2:0;
if(currentstatus!=laststatus)
+ {
lastratio=1;
+ lastratiocount=1;
+ }
}
inline void ibam::update(void)
{
save();
- apm.update();
+ apm->update();
currenttime=time(NULL);
- currentpercent=apm.percent();
+ currentpercent=apm->percent();
if(currentpercent!=-1)
isvalid=1;
else
isvalid=0;
- currentstatus=apm.onBattery()?1:apm.charging()?2:0;
+ currentstatus=apm->onBattery()?1:apm->charging()?2:0;
if(currentstatus!=laststatus)
+ {
lastratio=1;
+ lastratiocount=1;
+ }
}
inline int ibam::valid(void) const { return isvalid; }
@@ -494,14 +780,6 @@
double sec_per_min=(currenttime-lasttime)/double(lastpercent-currentpercent);
double last_av=battery.average(currentpercent,lastpercent);
- if(fabs(last_av-sec_per_min)<1.01*fabs(last_av*lastratio-sec_per_min))
- {
- if((lastratio<1 && last_av<sec_per_min)
- || (lastratio>1 && last_av>sec_per_min))
- adaptive_damping_battery*=1.01;
- else
- adaptive_damping_battery*=.99;
- }
if(sec_per_min>=IBAM_MINIMAL_SECONDS_PER_PERCENT
&& sec_per_min<=IBAM_MAXIMAL_SECONDS_PER_PERCENT)
{
@@ -509,9 +787,17 @@
last_sec_per_min=sec_per_min;
last_sec_per_min_prediction=last_av;
profile_changed=1;
+
+ if(lastpercent-currentpercent>lastratiocount)
+ lastratiocount=(lastpercent-currentpercent);
for(i=currentpercent;i<=lastpercent;i++)
- lastratio=(lastratio*adaptive_damping_battery+battery.add_data(i,sec_per_min))/(adaptive_damping_battery+1);
+ {
+ if(lastratiocount>2 || lastpercent==100) // Don't trust the first
+ lastratio=(lastratio*lastratiocount+battery.add_data(i,sec_per_min))/(lastratiocount+1);
+ lastratiocount++;
+ }
+
battery_changed=1;
data_changed=1;
}
@@ -532,15 +818,6 @@
sec_per_min=(currenttime-lasttime)/double(currentpercent-lastpercent);
double last_av=charge.average(lastpercent,currentpercent);
- if(fabs(last_av-sec_per_min)<1.01*fabs(last_av/lastratio-sec_per_min))
- {
- if((lastratio>1 && last_av<sec_per_min)
- || (lastratio<1 && last_av>sec_per_min))
- adaptive_damping_charge*=1.01;
- else
- adaptive_damping_charge*=.99;
- }
-
if(sec_per_min<=IBAM_MAXIMAL_SECONDS_PER_PERCENT
&& sec_per_min>=IBAM_MINIMAL_SECONDS_PER_PERCENT)
{
@@ -549,8 +826,16 @@
last_sec_per_min_prediction=last_av;
profile_changed=1;
- for(i=currentpercent;i>=lastpercent;i--)
- lastratio=(lastratio*adaptive_damping_charge+1/charge.add_data(i,sec_per_min))/(adaptive_damping_charge+1);
+ if(currentpercent-lastpercent>lastratiocount)
+ lastratiocount=(currentpercent-lastpercent);
+
+ for(i=lastpercent;i<=currentpercent;i++)
+ {
+ if(lastratiocount>2) // Don't trust the first
+ lastratio=(lastratio*lastratiocount+1./charge.add_data(i,sec_per_min))/(lastratiocount+1);
+ lastratiocount++;
+ }
+
charge_changed=1;
data_changed=1;
}
@@ -620,14 +905,16 @@
if(data_changed)
{
ofstream out((home+".ibam/ibam.rc").c_str());
- out << IBAM_VERSION << '\t' << currenttime
- << '\t' << currentpercent << '\t'
- << lastratio << '\t' << currentstatus
- << '\t' << adaptive_damping_battery
- << '\t' << adaptive_damping_charge
+ out << VERSION
+ << '\t' << currenttime
+ << '\t' << currentpercent
+ << '\t' << lastratio
+ << '\t' << lastratiocount
+ << '\t' << currentstatus
<< '\t' << profile_logging
<< '\t' << profile_number
- << '\t' << profile_active << endl;
+ << '\t' << profile_active
+ << '\t' << endl;
lasttime=currenttime;
lastpercent=currentpercent;
laststatus=currentstatus;
@@ -638,11 +925,11 @@
inline void ibam::set_profile_logging(int a) { data_changed=(a!=profile_logging);profile_logging=a; }
inline int ibam::profile_logging_setting(void) const { return profile_logging; }
-inline int ibam::seconds_left_battery_bios(void) { return apm.seconds(); }
+inline int ibam::seconds_left_battery_bios(void) { return apm->seconds(); }
inline int ibam::seconds_left_battery(void) { load_battery(); return int(battery.remain(currentpercent)+.5); }
inline int ibam::seconds_left_battery_adaptive(void) { load_battery(); return int(battery.remain(currentpercent)*lastratio+.5); }
-inline int ibam::percent_battery_bios(void) { return apm.percent(); }
+inline int ibam::percent_battery_bios(void) { return apm->percent(); }
inline int ibam::percent_battery(void) { load_battery(); return int((100.*seconds_left_battery())/battery.total()+.5); }
inline int ibam::seconds_left_charge(void) { load_charge(); return int(charge.inverted_remain(currentpercent)+.5); }
@@ -680,8 +967,8 @@
return int((currenttime-lasttime)/(battery.average(currentpercent-1,currentpercent+1)/charge.average(currentpercent-1,currentpercent+1))+.5);
}
-inline int ibam::onBattery(void) { return apm.onBattery(); }
-inline int ibam::charging(void) { return apm.charging(); }
+inline int ibam::onBattery(void) { return apm->onBattery(); }
+inline int ibam::charging(void) { return apm->charging(); }
inline double percent_data::average_derivation(int a,int b) // average standard derivation from a to b
{