#!/bin/sh # Copyright One Laptop Per Child # Power loging script # Released under GPLv3 VERSION="2.0.1" FDATE=`date "+%y%m%d-%H%M%S"` HOST=`hostname -s` B_INFO=/sys/class/power_supply/olpc-battery # This is the delay in the wallclock_delay. Its the minimum sample time for the # system date. WALL_PERIOD=5 # This is the (approx) delay inbetween readings. # This delay should be some where in the middle of integer mutiples of WALL_PERIOD # delays that bound the desired delay. # That way if our timer and system date are out of phase you don't end up having to wait a whole # new WALL_PERIOD for the RTC check to expire. # DELAY=12 # As of ver 1.14 I've switched back to using sleep rather than my wallclock_delay. # I the previous issues I had with using sleep were never resolved. # I'm going to try to resolve them this time if I see them since they are considered # a bug. # A delay of 10 seconds seems to be too low. DELAY=20 if [ -e /sys/class/dmi/id/product_version ] then XO_VERSION=$(< /sys/class/dmi/id/product_version ) else XO_VERSION="1" fi KERNVER=`uname -r | cut -c 1-6 | sed 's/\.//g'` if [[ $KERNVER -gt 2625 ]]; then KERNAPI=2 else KERNAPI=1 fi echo "Checking/waiting for a battery" until [ $(< $B_INFO/present ) = 1 ] do sleep 1 done # If we just inserted a battery the EC needs time to # read all the info. echo "Found one." echo "Pausing to let the EC think" sleep 3 # Now that we wait for a battery we can use the battery serial number in the filename DS_SERNUM=$(< $B_INFO/serial_number ) LOGFILE="pwr-$FDATE-$DS_SERNUM.csv" ACR_PROP="charge_counter" if [ ! -e $B_INFO/$ACR_PROP ] then ACR_PROP="accum_current" fi if [ -e /boot/olpc_build ] then BUILD=$(< /boot/olpc_build ) fi if [ -e /bootpart/boot/olpc_build ] then BUILD=$(< /bootpart/boot/olpc_build ) fi if [ -e $B_INFO/eeprom ] then # Skip 64 bytes and read 5 bytes; display without an address and in single byte mode # I don't use od directly since the -j skip does not do a real fseek. echo "Reading eeprom data." MFG_SER=`dd if=$B_INFO/eeprom bs=1 skip=64 count=5 2> /dev/null | od -A n -t x1` CHGCNT=`dd if=$B_INFO/eeprom bs=1 skip=74 count=2 2> /dev/null| od -A n -t x1 ` CHGSOC=`dd if=$B_INFO/eeprom bs=1 skip=76 count=1 2> /dev/null| od -A n -t x1 ` DISCNT=`dd if=$B_INFO/eeprom bs=1 skip=77 count=2 2> /dev/null| od -A n -t x1 ` DISSOC=`dd if=$B_INFO/eeprom bs=1 skip=79 count=1 2> /dev/null| od -A n -t x1 ` else echo "Can't read the eeprom data because your kernel dosen't support eeprom dump" MFG_SER="NA" CHGCNT="NA" CHGSOC="NA" DISCNT="NA" DISSOC="NA" fi echo "Starting log $LOGFILE" echo echo "pwr_log Ver: $VERSION" > $LOGFILE echo -n "HOST: " >> $LOGFILE echo $HOST >> $LOGFILE echo -n "DATE: " >> $LOGFILE echo `date` >> $LOGFILE echo -n "ECVER: " >> $LOGFILE echo `cat /ofw/ec-name` >> $LOGFILE echo -n "OFWVER: " >> $LOGFILE echo `cat /ofw/openprom/model` >> $LOGFILE echo -n "MODEL: " >> $LOGFILE echo `cat /ofw/model` >> $LOGFILE echo -n "SERNUM: " >> $LOGFILE echo `cat /ofw/serial-number` >> $LOGFILE echo -n "BATTECH: " >> $LOGFILE echo `cat $B_INFO/technology` >> $LOGFILE echo -n "BATMFG: " >> $LOGFILE echo `cat $B_INFO/manufacturer` >> $LOGFILE echo -n "BATSER: " >> $LOGFILE echo $DS_SERNUM >> $LOGFILE echo -n "BUILD: " >> $LOGFILE echo $BUILD >> $LOGFILE echo -n "MFGSER: " >> $LOGFILE echo $MFG_SER >> $LOGFILE echo -n "CHGCNT: " >> $LOGFILE echo $CHGCNT >> $LOGFILE echo -n "CHGSOC: " >> $LOGFILE echo $CHGSOC >> $LOGFILE echo -n "DISCNT: " >> $LOGFILE echo $DISCNT >> $LOGFILE echo -n "DISSOC: " >> $LOGFILE echo $DISSOC >> $LOGFILE echo -n "WALL_PERIOD: " >> $LOGFILE echo $WALL_PERIOD: >> $LOGFILE echo -n "DELAY: " >> $LOGFILE echo $DELAY: >> $LOGFILE echo -n "XOVER: " >> $LOGFILE echo $XO_VERSION >> $LOGFILE echo -n "KERNVER: " >> $LOGFILE echo $KERNVER >> $LOGFILE echo -n "KERNAPI: " >> $LOGFILE echo $KERNAPI >> $LOGFILE # Allow the addition of some descriptive text from the cmd line echo -n "COMMENT: " >> $LOGFILE echo $1 >> $LOGFILE echo "" >> $LOGFILE # feed this the wall clock time in seconds you wish to delay # It will spin until that time has passed. If the system is suspeneded # it may sleep more. function wallclock_delay { DATE1=`date +%s` EXPIRE=$((DATE1+$1)) while [ `date +%s` -lt $EXPIRE ]; do sleep $WALL_PERIOD done } # convert a number into 2's complement function conv_2s_comp { # this has since been changed in the kernel so that it returns # a signed value rather than unsigned. which fixes the math # So if its already negative then bail if [ $1 -lt 0 ] then echo $1 return fi if [ $1 -gt 32767 ] then echo $(( 0 - (65535-$1+1) )) return fi echo $1 } CAPACITY=capacity if [ ! -f $B_INFO/$CAPACITY ] then CAPACITY=capacity_level fi function get_acr { local acr_temp acr_temp=$(< $B_INFO/$ACR_PROP ) test $KERNAPI -eq 1 && acr_temp=$(conv_2s_comp ${acr_temp:-0}) echo ${acr_temp:-0} } START_ACR=$(get_acr) while true do CAPLEVEL=$(< $B_INFO/$CAPACITY ) VOLT=$(< $B_INFO/voltage_avg) CURR=$(< $B_INFO/current_avg) TEMP=$(< $B_INFO/temp) STAT=$(< $B_INFO/status) ACR=$(get_acr) ACR_DIFF=$(( ${ACR-0}-${START_ACR-0} )) if [ $KERNAPI -eq 1 ] then MAh=$(( $ACR_DIFF * 625 / 1500 )) else MAh=$ACR_DIFF fi echo `date +%s`",$CAPLEVEL,$VOLT,$CURR,$TEMP,$ACR,$STAT,$MAh" | tee -a $LOGFILE sync # wallclock_delay $DELAY sleep $DELAY done