[ltp] Speaking of battery charging....
Steve Thompson
linux-thinkpad@linux-thinkpad.org
Tue, 27 Mar 2007 20:24:20 -0400 (EDT)
--0-595272767-1175041460=:1263
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
Content-Id:
Content-Disposition: inline
I have this tiny little utility that shows battery state and temperature
information in the hardstatus line if you use screen(1). I spen most of
my time looking (or often glaring) at an xterm or console session and like
to keep an eye on what's going on. Screen, besides being generally
indespensible for serious shell work, will run periodically run a program
whose output is displayed in your terminal's hardstatus line.
Tested only with screen 4.0.2.
Regards,
Steve
__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
--0-595272767-1175041460=:1263
Content-Type: text/x-csrc; name="screen_status_line.c"
Content-Description: 3291453960-screen_status_line.c
Content-Disposition: inline; filename="screen_status_line.c"
/*
screen_status_line.c
Extract information from /proc and/or /sys and format
one line of output for `screen` to use in the hardware
status line.
(c) 2007, Steve Thompson <steve49152@yahoo.ca>
version 0.001
You may copy and use this software free of charge. If you redistribute it, either with
or without modifications, you must retain this copyright notice. Neither I nor anyone
else will assume any liabilty from your use of or inability to use this software.
"If it breaks, you get to keep both pieces."
-- Author unknown
Instructons:
1) Compile with gcc under Linux.
2) Install the executable somewhere in your path.
3) Edit your .screenrc and include something like the
following two entries, but modified for your setup:
backtick 1 30 1 /home/you/bin/screen_status_line
hardstatus lastline '%{= BW}%0c %1`%=%{-}'
4) Read any relevant documentation you might need in order to
understand what this program does, how to install it, and
how it is intended to be used.
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <sys/mman.h>
#include <sys/stat.h>
/*
battery()
Typical Info:
-------------
present: yes
design capacity: 47520 mWh
last full capacity: 28800 mWh
battery technology: rechargeable
design voltage: 10800 mV
design capacity warning: 2376 mWh
design capacity low: 475 mWh
capacity granularity 1: 1 mWh
capacity granularity 2: 1 mWh
model number: IBM-08K8040
serial number: 1234
battery type: LION
OEM info: SANYO
Typical State:
---------------
present: yes
capacity state: ok
charging state: charging
present rate: 2873 mW
remaining capacity: 27810 mWh
present voltage: 12494 mV
*/
static char *battery_state_file="/proc/acpi/battery/BAT0/state";
static char *battery_info_file="/proc/acpi/battery/BAT0/info";
struct battery_info {
int present;
int design_capacity;
int last_full_capacity;
int state;
int rate;
int capacity;
int voltage;
};
struct battery_info * get_battery(void) {
static struct battery_info batt;
int fd;
char map[4096];
char *p;
int n;
fd = open(battery_info_file, O_RDONLY);
if(fd == -1) return (NULL);
memset(map, 0, 4096);
n = read(fd, map, 4095);
map[n]=0x00;
close(fd);
p = strstr(map, "present:");
if (!p) return (NULL);
p += 25;
batt.present = (strstr(p, "yes") ? 1 : 0);
p = strstr(map, "design capacity:");
if (!p) return (NULL);
p += 25;
batt.design_capacity = strtol(p, NULL, 0);
p = strstr(map, "last full capacity:");
if (!p) return (NULL);
p += 25;
batt.last_full_capacity = strtol(p, NULL, 0);
fd = open(battery_state_file, O_RDONLY);
if(fd == -1)
return (NULL);
memset(map, 0, 4096);
n = read(fd, map, 4095);
map[n]=0;
close(fd);
p = strstr(map, "charging state:");
if (!p) return (NULL);
p += 25;
if (strncmp(p, "discharging", 11) == 0)
batt.state = 0;
else if (strncmp(p, "charging", 8) == 0)
batt.state = 1;
else if (strncmp(p, "charged", 7) == 0)
batt.state = 2;
else batt.state = 10;
p = strstr(map, "rate:");
if (!p) return (NULL);
p += 25;
batt.rate = strstr(p, "yes") ? 1 : 0;
p = strstr(map, "remaining capacity:");
if (!p) return (NULL);
p += 25;
batt.capacity = strtol(p, NULL, 0);
p = strstr(map, "present voltage:");
if (!p) return (NULL);
p += 25;
batt.voltage = strtol(p, NULL, 0);
return (&batt);
}
/*
Thermal data
>From linux/Documentation/ibm-acpi.txt:
Tentative layout; varies significantly by model.
1: CPU
2: (depends on model)
3: (depends on model)
4: GPU
5: Main battery: main sensor
6: Bay battery: main sensor
7: Main battery: secondary sensor
8: Bay battery: secondary sensor
9-15: (depends on model)
*/
static char *thermal_file="/proc/acpi/ibm/thermal";
struct thermal_info {
int cpu;
int mb;
int gpu;
int hdd;
int batt0;
int batt1;
int batt0b;
int batt1b;
};
struct thermal_info * get_temp(void) {
static struct thermal_info temp;
int fd, r;
char buf[4096];
char *p;
fd = open(thermal_file, O_RDONLY);
if (fd == -1)
return(NULL);
memset(buf, 0x00, 4096);
r = read(fd, buf, 4096);
if (r == -1) {
close(fd);
return(NULL);
}
buf[r] = 0x00;
p = buf;
while(!isdigit(*p) && *p != '+' && *p != '-')
p++;
/* Here I am making an educated WAG as to the correlation
of fields and their corresponding sensors. This is likely
close to being correct, but absent documentation and the will
to freeze chips on the motherboard one-by one, I cannot be
sure. If you do not have a Thinkpad X30, you may have to
make adjustments.
*/
temp.cpu = strtol(p, &p, 0);
while(isspace(*p)) p++;
temp.mb = strtol(p, &p, 0);
while(isspace(*p)) p++;
temp.hdd = strtol(p, &p, 0);
while(isspace(*p)) p++;
temp.gpu = strtol(p, &p, 0);
while(isspace(*p)) p++;
temp.batt0 = strtol(p, &p, 0);
while(isspace(*p)) p++;
temp.batt1 = strtol(p, &p, 0);
while(isspace(*p)) p++;
temp.batt0b = strtol(p, &p, 0);
while(isspace(*p)) p++;
temp.batt1b = strtol(p, &p, 0);
return(&temp);
}
int main(int argc, char **argv) {
struct battery_info * b;
struct thermal_info * t;
char buf[1024];
float percent;
char bstate;
int len=0;
b = get_battery();
t = get_temp();
if(!b)
len += sprintf(buf, "!BATT ");
else {
percent = (float)b->capacity / (float)b->design_capacity * 100.0;
switch(b->state) {
case (0):
bstate = '-';
break;
case (1):
bstate = '+';
break;
case (2):
bstate = ' ';
break;
default:
bstate = '!';
}
len += sprintf(buf, "Charge: %c%2.0f%%", bstate, percent);
}
if(!t)
len += sprintf(buf + len, "!TEMP ");
else {
len += sprintf(buf + len, " cpu:%2d mb:%2d hdd:%2d gpu:%2d batt0:%2d/%2d", t->cpu, t->mb, t->hdd, t->gpu, t->batt0, t->batt0b);
}
write(fileno(stdout), buf, len);
exit(0);
}
--0-595272767-1175041460=:1263--