/***************************************************************************
* CVSID: $Id$
*
* utili_pm.c - Various Powermanagement related utilities
*
* Copyright (C) 2005 Richard Hughes <richard@hughsie.com>
* Copyright (C) 2005 Danny Kukawka <danny.kukawka@web.de>
*
* Licensed under the Academic Free License version 2.1
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
**************************************************************************/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#include <stdint.h>
#include <glib.h>
#include "logger.h"
#include "util_pm.h"
typedef struct {
int last_level;
int last_chargeRate;
} batteryInfo;
/** Convert the hardware reported value into a few sane choices
*
* This is needed as ACPI does not specify the description text for a
* battery, and so we have to calculate it from the hardware output
*
* @param type The battery type recieved from the hardware
* @return The battery technology which is one of:
* unknown, lithium-ion or lead-acid
*/
const char *
{
return "unknown";
}
/* every case combination of Li-Ion is commonly used.. */
return "lithium-ion";
}
return "lead-acid";
}
return "lithium-polymer";
}
return "nickel-metal-hydride";
}
return "unknown";
}
/** Given all the required parameters, this function will return the percentage
* charge remaining. There are lots of checks here as ACPI is often broken.
*
* @param id Optional ID given to this battery. Unused at present.
* @param chargeLevel The current charge level of the battery (typically mWh)
* @param chargeLastFull The last "full" charge of the battery (typically mWh)
* @return Percentage, -1 if invalid
*/
int
int chargeLevel,
int chargeLastFull)
{
int percentage;
/* make sure we have chargelevel */
if (chargeLevel <= 0) {
return -1;
}
/* make sure not division by zero */
if (chargeLastFull > 0)
else {
return -1;
}
/* Some bios's will report this higher than 100, limit it here */
if (percentage > 100) {
return 100;
}
/* Something really isn't right if we get a negative... */
if (percentage < 0) {
return -1;
}
return percentage;
}
/** Given all the required parameters, this function will return the number
* of seconds until the battery is charged (if charging) or the number
* of seconds until empty (if discharging)
*
* @param id Optional ID given to this battery. Unused at present.
* @param chargeRate The "rate" (typically mW)
* @param chargeLevel The current charge level of the battery (typically mWh)
* @param chargeLastFull The last "full" charge of the battery (typically mWh)
* @param isDischarging If battery is discharging
* @param isCharging If battery is charging
* @param guessChargeRate If ignore chargeRate and guess them.
* @return Number of seconds, or -1 if invalid
*/
int
int chargeRate,
int chargeLevel,
int chargeLastFull,
{
int remaining_time = 0;
/* should not get negative values */
HAL_WARNING (("chargeRate, chargeLevel or chargeLastFull < 0, returning -1"));
return -1;
}
/* batteries cannot charge and discharge at the same time */
if (isDischarging && isCharging) {
HAL_WARNING (("isDischarging & isCharging TRUE, returning -1"));
return -1;
}
/*
* Some laptops don't supply any rate info, but that's no reason for HAL not
* to. We use the current and previous chargeLevel to estimate the rate.
* The info is stored in a GHashTable because there could be more than one battery.
*/
if (chargeRate == 0 || guessChargeRate) {
/* Initialize the save_battery_info GHashTable */
if (!saved_battery_info)
/* check this to prevent division by zero */
/* if we can't calculate because nothing changed, use last
* chargeRate to prevent removing battery.remaining_time.
*/
} else {
chargeRate = ((chargeLevel - battery_info->last_level) * 60 * 60) / (cur_time - battery_info->last_time);
/*
* During discharging chargeRate would be negative, which would
* mess up the the calculation below, so we make sure it's always
* positive.
*/
}
} else {
battery_info->last_chargeRate = 0;
return -1;
}
}
if (chargeRate == 0)
return -1;
if (isDischarging) {
} else if (isCharging) {
/*
* Some ACPI BIOS's don't update chargeLastFull,
* so return 0 as we don't know how much more there is left
*/
if (chargeLevel > chargeLastFull ) {
HAL_WARNING (("chargeLevel > chargeLastFull, returning -1"));
return -1;
}
}
/* This shouldn't happen, but check for completeness */
if (remaining_time < 0) {
remaining_time = -1;
}
/* Battery life cannot be above 60 hours */
HAL_WARNING (("remaining_time *very* high, returning -1"));
remaining_time = -1;
}
return remaining_time;
}