Results 1 to 8 of 8
  1. Dolio's Avatar
    48 Posts
    Global Posts
    54 Global Posts
    This project is not nearly mature enough to be called a patch or app but perhaps someday it will be. I have a number of thoughts that would make this more practical for more users...
    • optware appears to have some rrdtool packages available...
    • "Logging" could be done towards the local media drive by a service.
    • Ideally data should go directly into individual .rrd files on media drive.
      [**] Do daily, monthly, yearly .rrds similar to how cacti logs data.
    • Ideally graphs would be rendered on the fly from the .rrds via an app.
    • More data to capture
      [**] Number of running WebOS Apps, versus the current running processes (which are not Apps)
      [**] Somehow represent uptime, perhaps as a simple scaled and rising line of some sort.
    • More Features: Make coffee, toast bread....
    • ...

    Greetings, I've been using a little hack on my Pre which started out as a GPS tracking script and quickly turned into an external logging system which is nothing like true snmp (Simple Network Monitoring Protocol), nor RRDtools, nor cacti, but which none the less results in the ability to produce graphs of a similar nature and quality.

    Let me start at the beginning, as a sysadmin and Linux enthusiast for more than 15 years I obviously first installed optware per Next steps - WebOS Internals in order to be able to open a shell and poke around. Next I loaded Dynamic DNS, highttpd and a tracker.php script, and finally I enabled cron so I could schedule stuff to run.

    So, this "Hack" is made up of two or more scripts. The first is called by cron (linux scheduler) on the Pre which collects various data and "sends it" to a server. When I say "sends it" I mean that it calls a non-existent web page at my webserver, which logs the request in it's error log (Stop laughing!). The second script at the web server pulls the data from the error log(s) and generates a map.kml file which can be imported into google maps or google earth and also generates a temporary .rrd file and then a graph like the one below.

    Only recently after playing around with the various kernel overclocking hacks did I update the the second script so that it could render the graphs. I wanted to be able to see how various speeds and other activities effected temperature and battery loads... My impression so far is that kernel speeds in and of themselves have little effect, other factors have larger impacts.

    From the Top to the Bottom of the graph find:
    The top blue line is the discharge/charge rate, centered on 110 with equals 0mA.
    The next blue line is the SOC (State Of Charge) or battery %, I'm an EV (Electric Vehicle) guy.
    The Red (and later that week) Orange lines are Battery and CPU Temperatures in deg C.
    The various thin blue and red lines are network Tx/Rx on various network interfaces (cell, WiFi)
    The Dark to light green, yellow, and orange fill area below 0 is the relative time spent in various MHz states, I think it's a fairly good way to represent the CPU scaling.
    When the phone is sleeping the load rises sharply and there are fewer counts in any given MHz, thus the pink fill and pink lines representing the 1, 5, and 15 minute load averages.
    Finally because I have the data a dark pink line for the number of running processes.

    An early pair of graphs
    Another graph

    I will post the various scrips in the next two posts and update them as necessary.
    Attached Images Attached Images
    Last edited by Dolio; 05/18/2010 at 07:29 PM. Reason: more ideas for data to log.
  2. Dolio's Avatar
    48 Posts
    Global Posts
    54 Global Posts
    Script 1, the logger, run on Pre by cron, named ""

    # Try `sudo /usr/bin/crontab -e` and add
    # */5 is every 5 minutes, * is every single minute, does not run when sleeping.
    # First option should be YOUR SERVER, second is a unique string identifier.
    # "*/5 * * * * /home/user/ Pre.Track.MyPreName"
    # sudo joe /etc/cron/crontabs/root /var/spool/cron/crontabs/root
    # start cron with `sudo -i initctl start crond`
    # Make sure I am run as root, get date string, get gps location.
    if [ `whoami` != root ] ; then echo must be run as root, try sudo $0 ; exit ; fi
    date=`date +%Y%m%d.%H%M%S`
    # GPS : 
    gps=`/usr/bin/luna-send -n 1 palm://com.palm.location/getCurrentPosition {"responseTime":"1"} 2>&1 \
         | /usr/bin/cut -d\: -f2- | /usr/bin/cut -d, -f4,5,9 | /bin/sed -r 's/[^-\.0-9,]//g'`
    if [ ! $gps ] ; then gps=0,0,0 ; fi
    # Battery : 35%, 29C, -284mA, 3733mV  -> 33,30C,184mA,3796mV
    bat=`grep BATTERY /var/log/messages | grep -v grep | tail -n1 | cut -f2,4,5,6 -d, \
         | /bin/sed -r 's/[^-\.0-9CmAV,]//g'`
    if [ ! $bat ] ; then bat=0,0,0,0 ; fi
    # cpu temp
    cputemp=`luna-send -n 1 palm://org.webosinternals.govnah/get_omap34xx_temp '{}' 2>&1 | cut -f7 -d\ | cut -f1 -d\,`;
    if [ $cputemp -gt -40 ] 2> /dev/null ; then echo -n "" ; else cputemp=0 ; fi
    # LoadAVG : 3.63 3.77 2.97 5/176 2621 -> 3.63,3.77,2.97,5,176,2621
    # CPU and IO for last 1, 5, 10 minutes, running processes, total processes, last process ID used.
    load=`cat /proc/loadavg | /bin/sed -r 's/[^\.0-9]/,/g'`
    if [ ! $load ] ; then load=0,0,0,0,0,0 ; fi
    # uptime : seconds since last boot, time spent idle since last boot.
    uptime=`cat /proc/uptime | /bin/sed -r 's/\ /,/g'`
    if [ ! $uptime ] ; then uptime=0,0 ; fi
    # CPU MHz time in state, collapse into single string and remove whitespace and trailing ;
    MHzScale=`cat /sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state \
              | cut -b1-3,7- | /bin/sed -r 's/\ /:/g' | /bin/sed -r 's/$/;/g'`
    # 800:2930745; 720:3298104; 600:0; 550:0; 500:8719649; 250:0; 125:0;
    MHzScale=`echo $MHzScale | /bin/sed -r 's/ //g' | /bin/sed -r 's/.$//g'`
    # 800:2930845;720:3298304;600:0;550:0;500:8723345;250:0;125:0
    # Current CPU MHz is not as important as it can change rapidly.
    # cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq
    if [ ! $MHzScale ] ; then MHzScale=0 ; fi
    # Network Interfaces NIC:Rx-bytes,Rx-packets,Tx-bytes,Tx-packets
    Net=`cat /proc/net/dev | grep -v Receive | grep -v face | grep -v bsl0 \
         | /bin/sed -r 's/\ +/:/g' | /bin/sed -r 's/::/:/g' | cut -f2,3,4,11,12 -d\: | /bin/sed -r 's/$/;/g'`
    Net=`echo $Net | /bin/sed -r 's/ //g' | /bin/sed -r 's/.$//g'`
    ## Website
    ## Some settings for making a web site request, just look in your site logs file.
    Site=""       # The website for the request?
    if [ "$1" ] ; then Site="$1" ; fi       # First Argument is WebSite.
    Prefix="Pre.Name.Track"     # A Prefix, could be a script?
    if [ "$2" ] ; then Prefix="$2" ; fi     # Second Argument is Prefix.
    if [ $Site == "" ] ; then
    #echo /usr/bin/wget -sqO /dev/null http://$Site/$Prefix,$date,$gps,$bat,$load,$uptime,$MHzScale,$Net 2> /dev/null
    #echo /usr/bin/wget -sqO /dev/null http://$Site/$Prefix,$date,$gps/$bat/$cputemp/$load,$uptime/$MHzScale/$Net 2> /dev/null
    echo /usr/bin/wget -sqO /dev/null http://$Site/$Prefix,$date,$gps,$bat,$cputemp,$load,$uptime,$MHzScale,$Net 2> /dev/null
    #/usr/bin/wget -sqO /dev/null http://$Site/$Prefix,$date,$gps,$bat,$load,$uptime,$MHzScale,$Net 2> /dev/null
    /usr/bin/wget -sqO /dev/null http://$Site/$Prefix,$date,$gps,$bat,$cputemp,$load,$uptime,$MHzScale,$Net 2> /dev/null
    #/usr/bin/wget -sqO /dev/null http://$Site/$Prefix,$date,$gps/$bat/$cputemp/$load,$uptime/$MHzScale/$Net 2> /dev/null
    # We could do other things with the data,
    # like append it into a file on the internal media drive,
    # or inject it into an .rrd (round robin database)
    Last edited by Dolio; 05/18/2010 at 04:11 AM. Reason: Added Script....
  3. Dolio's Avatar
    48 Posts
    Global Posts
    54 Global Posts
    Script 2, the grapher, run on server, named

    This is a little script that strips data from the web servers error log file and then calls the big script to process the data, it's named or something like that.

    d=`date +%Y%m%d --date="Today"`  
    echo "Subject: $f $d Partial"
    zcat -f /var/log/apache2/error.log-*gz /var/log/apache2/error.log-???????? /var/log/apache2/error.log | grep $t | grep -v png | cut -d\/ -f2- \
     | sed -r 's/var\/www\/\///g' | sed -r 's/ failed//g' | grep $d > $fn.pre 
    $h/ $fn.pre > $fn.raw 
    $h/ $fn.raw > $fn.kml 
    p=`grep -c "" $fn.pre` 
    r=`grep -c "" $fn.raw` 
    cp $fn.raw $fn.ral
    $h/ $fn.ral > $fn.line.kml
    rm -f $fn.ral
    $h/ $fn.pre 1> /dev/null 2> /dev/null
    rm -f $h/$f/$
    ln -s $h/$f/$f.$d.pre.png $h/$f/$
    echo Mapped $r of $p Data Points.
    echo ""
    echo ""
    echo ""
    echo ""

    This is the script, it converts data from various types, it began life as a kml map file generator and later evolved to draw graphs. I realize that it is an absolutely disgusting mess...

    use POSIX;
    # See
    # Might eventually want to do something with this...
    if ( not -f $input_file    ) { print "$input_file does not exist.\n"; exit(0); }
    if ( $input_file =~ /\.kml/) {
    # print "Converting $input_file into a .raw format, pipe output to a .raw file and manipulate.\n";
    elsif ( $input_file =~ /\.pre/) {
    # print "Converting $input_file into a .raw format, pipe output to a .raw file and manipulate.\n";
    # Pre.Track.MyPre,20100429.010431,43.2109876,-123.456789,0,95,27C,205mA,4162mV,0.13,0.11,0.25,4,194,5074,2610.02,2335.95,\
    # 800:43365;720:44457;600:0;550:0;500:172745;250:0;125:0
    elsif ( $input_file =~ /\.raw/) {
    # print "Converting $input_file into a .kml format, pipe output to a .kml and edit name.\n";
    # style20100423.140031  blue.png  20100423140031    -123.456789   43.21987654    0.0
    elsif ( $input_file =~ /\.ral/) {
    # print "Converting $input_file into a .kml format, pipe output to a .kml and edit name.\n";
    # style20100423.140031  blue.png  20100423140031    -123.456789   43.219876543    0.0
    else {
     print "Do not know how to process $input_file, should be .kml or .raw\n"
    sub process_kml {
    # Attempts to convert a .kml file into a .raw file
    # Probably can not deal with line elements properly
     @Styles=`grep "Style id" $input_file | sort | uniq | cut -f2 -d\\"`; chomp(@Styles);
     foreach $style (@Styles) {
      $icon=`grep -A6 \\"$style\\" $input_file  | grep \\<href\\>                  | cut -f2 -d\\> | cut -f1 -d\\<`;
      $icon =~ s/$icon_prefix\///;
      $icon =~ s/$icon_prefix2\///;
      $name=`grep -B3 -A4 styleUrl..$style..s $input_file | grep \\<name\\>        | cut -f2 -d\\> | cut -f1 -d\\<`;
      $coor=`grep -B3 -A4 styleUrl..$style..s $input_file | grep \\<coordinates\\> | cut -f2 -d\\> | cut -f1 -d\\<`;
      $coor =~ /(.*),(.*),(.*)/;
      $long=$1; $lat=$2; $alt=$3;
      print sprintf("%-10s", $style) . sprintf("%-25s", $icon) . sprintf("%-20s", $name); # print sprintf("%-20s", $coor);
      print sprintf("%-12s", $long)  . sprintf("%-12s", $lat)  . sprintf("%-12s", $alt) . "\n";
    #  print "$style  \t$icon \t$name\t$coor\n";
    } # End process_kml
    sub process_raw {
     $Map_Name = $input_file; $Map_Name =~ s/\.raw//;$Map_Name =~ s/.*\///;
     @Points=`cat $input_file`; chomp(@Points);
     print <<"_END_";
    <kml xmlns="">
     foreach $point (@Points) {
      $point =~ /(style\d*.\d*)\ *(.*.png)\ *(\w*)\ *(-?\d*.\d*)\ *(-?\d*.\d*)\ *(-?\d*.\d*)/;
      $style=$1; $icon=$2; $name=$3; $long=$4; $lat=$5; $alt=$6;
      print "<Style id=\"style$style_counter\">\n  <IconStyle>\n    <Icon>\n      <href>$icon_prefix/$icon</href>\n    </Icon>\n  </IconStyle>\n</Style>\n";
      print "<Placemark>\n  <name>$name</name>\n  <description><![CDATA[]]></description>\n  <styleUrl>#style$style_counter</styleUrl>\n";
      print "  <Point>\n    <coordinates>$long,$lat,$alt</coordinates>\n  </Point>\n</Placemark>\n";
     print <<"_END_";
    } # End process_raw
    sub process_pre {
    # 0  = Pre.Track.MyPre,20100423.000031,43.21987654,-123.456789,89,37C,-190mA,4060mV,1.38,2.06,1.44,4,184,2506
    # 0e = Pre.Track.MyPre,20100423.000031,,89,37C,-190mA,4060mV,1.38,2.06,1.44,4,184,2506
    # 1 = Pre.Track.MyPre,20100423.000031,43.21987654,-123.456789,0,95,27C,205mA,4162mV,0.13,0.11,0.25,4,194,5074,\
    #     800:43365;720:44457;600:0;550:0;500:172745;250:0;125:0
    # 2 = Pre.Track.MyPre,20100423.000031,43.21987654,-123.456789,0,95,27C,205mA,4162mV,0.13,0.11,0.25,4,194,5074,2610.02,2335.95,\
    #     800:43365;720:44457;600:0;550:0;500:172745;250:0;125:0
    # 3 = Pre.Track.MyPre,20100423.000031,43.21987654,-123.456789,0,95,27C,205mA,4162mV,0.13,0.11,0.25,4,194,5074,2610.02,2335.95,\
    #     800:43365;720:44457;600:0;550:0;500:172745;250:0;125:0,lo:188793600:389417:188793600:389417;ppp0:29263230:34109:2456087:30087;eth0:132781:323:45754:339
    # 4 = Pre.Track.MyPre,20100423.000031,43.21987654,-123.456789,0,95,27C,205mA,4162mV,31,0.13,0.11,0.25,4,194,5074,2610.02,2335.95,\
    #     800:43365;720:44457;600:0;550:0;500:172745;250:0;125:0,lo:188793600:389417:188793600:389417;ppp0:29263230:34109:2456087:30087;eth0:132781:323:45754:339
    # Prefix,date.time,long,lat,alt,soc,temp,draw,volts,load1,load5,load15,running,processes,lastpid,uptime,idletime,mhz:time;mhz:time;etc,NicX:Rxb:Rxp:Txb:Txp;etc
    # Prefix,date.time,long,lat,alt,soc,temp,draw,volts,cputemp,load1,load5,load15,running,processes,lastpid,uptime,idletime,mhz:time;mhz:time,etc,NicX:Rxb:Rxp:Txb:Txp;etc
    # TODO : Use regex to match any of the given lines above in order to
    #        be able to extract and plot any of the old and new data points.
    #        Although this is beginning to get beyond the scope of a "kml parser" script.
    # See
    $v=1;   # Be verbose for debugging...
    @DataSet=`cat $input_file | grep -v ",," | sort | uniq`;
    if ($v) { print "DataSet file $input_file has $#DataSet lines.\n"; }
    if ($v) { print "$DataSet[0]"; }
    $DataSet[0] =~ /^[a-z,A-Z,0-9,\.]*,(\d\d\d\d)(\d\d)(\d\d).(\d\d)(\d\d)(\d\d),.+/;       # Get the date and time of the first line.
    $SecStart=`date -d "$2/$3/$1 $4:$5:$6" +%s`; chomp($SecStart);                          # Convert into seconds since epoc
    $SecStart=`date -d "$2/$3/$1 00:00:00" +%s`; chomp($SecStart);                          # Force to begging of day
    $DateStart=`date -d \@$SecStart`; chomp($DateStart);                                    # 
    $Start=`date -d \@$SecStart +%Y.%m.%d.%H:%M`; chomp($Start);
    if ($v) { print "\tSecStart $2/$3/$1 $4:$5:$6 = $SecStart = $DateStart\n"; }
    if ($v) { print "$DataSet[$#DataSet]"; }
    $DataSet[$#DataSet]=~ /^[a-z,A-Z,0-9,\.]*,(\d\d\d\d)(\d\d)(\d\d).(\d\d)(\d\d)(\d\d),.+/;# Get the date and time of the last line.
    $SecEnd=`date -d "$2/$3/$1 $4:$5:$6" +%s`; chomp($SecEnd);                              # Convert into seconds since epoc
    $SecEnd=`date -d "$2/$3/$1 23:59:59" +%s`; chomp($SecEnd);                              # Force to end of day.
    $DateEnd=`date -d \@$SecEnd`; chomp($DateEnd);                                          # 
    $End=`date -d \@$SecEnd +%Y.%m.%d.%H:%M`; chomp($End);
    if ($v) { print "\tSecEnd $2/$3/$1 $4:$5:$6 = $SecEnd = $DateEnd\n"; }
    $SecLength=$SecEnd-$SecStart;                                                   # Get timspan of dataset
    $RRA_Start  = $SecStart - 5;                                                    # Set start time as an epoc value.
    $DataPoints = 2;                                                                # number of datapoints, just SOC and TEMP at the moment
    $RRA_Length = $DataPoints * $SecLength + 10;                                    # start is -5 seconds, end is +5 seconds
    if ($v) { print "DataSet is $SecLength seconds long, with $DataPoints DataPoints, RRA Length will be $RRA_Length .\n\n"; }
    # Build the command to initialize the .rrd file.
    # Using a step of "1" second is a very high resolution, one month 3 data points and a step of 60 creates a 350M .rrd file.
    # most of our data is going to be at a resolution of 60 seconds or more, using step of 1 just makes the .rrd larger
    $rrdtool_create="rrdtool create $input_file.rrd --start $RRA_Start --step 60 ";
    # DS:Sample_Name:Type(GUAGE, COUNTER, DERIVE or ABSOLUTE):HeardBeat_Timeout:MinValie:MaxValue
    $rrdtool_create .= " DS:TEMP:GAUGE:3600:0:60";
    $rrdtool_create .= " DS:SOC:GAUGE:3600:0:105";
    $rrdtool_create .= " DS:mA:GAUGE:3600:-1500:1500";
    $rrdtool_create .= " DS:mV:GAUGE:3600:2500:4500";
    $rrdtool_create .= " DS:CPUTEMP:GAUGE:3600:0:60";
    $rrdtool_create .= " DS:Load1:GAUGE:3600:0:100";
    $rrdtool_create .= " DS:Load5:GAUGE:3600:0:100";
    $rrdtool_create .= " DS:Load15:GAUGE:3600:0:100";
    $rrdtool_create .= " DS:Running:GAUGE:3600:0:100";
    $rrdtool_create .= " DS:125MHz:DERIVE:3600:0:10000";
    $rrdtool_create .= " DS:250MHz:DERIVE:3600:0:10000";
    $rrdtool_create .= " DS:500MHz:DERIVE:3600:0:10000";
    $rrdtool_create .= " DS:550MHz:DERIVE:3600:0:10000";
    $rrdtool_create .= " DS:600MHz:DERIVE:3600:0:10000";
    $rrdtool_create .= " DS:720MHz:DERIVE:3600:0:10000";
    $rrdtool_create .= " DS:800MHz:DERIVE:3600:0:10000";
    $rrdtool_create .= " DS:loR:DERIVE:3600:0:U";
    $rrdtool_create .= " DS:loT:DERIVE:3600:0:U";
    $rrdtool_create .= " DS:pppR:DERIVE:3600:0:U";
    $rrdtool_create .= " DS:pppT:DERIVE:3600:0:U";
    $rrdtool_create .= " DS:ethR:DERIVE:3600:0:U";
    $rrdtool_create .= " DS:ethT:DERIVE:3600:0:U";
    # RRA:Function(AVERAGE, MIN, MAX or LAST):%allowed to be unknown:number of Samples that make up the record.
    $rrdtool_create .= " RRA:AVERAGE:0.99:1:$RRA_Length";
    $rrdtool_create .= " RRA:MIN:0.99:1:$RRA_Length";
    $rrdtool_create .= " RRA:MAX:0.99:1:$RRA_Length";
    #if ($v) { print "$rrdtool_create\n"; }
    # Build the command to draw the graph and define the graph key.
    # Add each MHz step counter to the previous MHz step counter, negate the result for graphing.
    $rrdtool_key .= " 'DEF:125MHz=$input_file.rrd:125MHz:AVERAGE'                                 'CDEF:125MHza=125MHz,-1,*'";
    $rrdtool_key .= " 'DEF:250MHz=$input_file.rrd:250MHz:AVERAGE' 'CDEF:250MHzb=250MHz,125MHz,+'  'CDEF:250MHza=250MHzb,-1,*'";
    $rrdtool_key .= " 'DEF:500MHz=$input_file.rrd:500MHz:AVERAGE' 'CDEF:500MHzb=500MHz,250MHzb,+' 'CDEF:500MHza=500MHzb,-1,*'";
    $rrdtool_key .= " 'DEF:550MHz=$input_file.rrd:550MHz:AVERAGE' 'CDEF:550MHzb=550MHz,500MHzb,+' 'CDEF:550MHza=550MHzb,-1,*'";
    $rrdtool_key .= " 'DEF:600MHz=$input_file.rrd:600MHz:AVERAGE' 'CDEF:600MHzb=600MHz,550MHzb,+' 'CDEF:600MHza=600MHzb,-1,*'";
    $rrdtool_key .= " 'DEF:720MHz=$input_file.rrd:720MHz:AVERAGE' 'CDEF:720MHzb=720MHz,600MHzb,+' 'CDEF:720MHza=720MHzb,-1,*'";
    $rrdtool_key .= " 'DEF:800MHz=$input_file.rrd:800MHz:AVERAGE' 'CDEF:800MHzb=800MHz,720MHzb,+' 'CDEF:800MHza=800MHzb,-1,*'";
    #$rrdtool_key .= " 'DEF:125MHz=$input_file.rrd:125MHz:AVERAGE'";
    #$rrdtool_key .= " 'DEF:250MHz=$input_file.rrd:250MHz:AVERAGE' 'CDEF:250MHzb=250MHz,125MHz,+'";
    #$rrdtool_key .= " 'DEF:500MHz=$input_file.rrd:500MHz:AVERAGE' 'CDEF:500MHzb=500MHz,250MHzb,+'";
    #$rrdtool_key .= " 'DEF:550MHz=$input_file.rrd:550MHz:AVERAGE' 'CDEF:550MHzb=550MHz,500MHzb,+'";
    #$rrdtool_key .= " 'DEF:600MHz=$input_file.rrd:600MHz:AVERAGE' 'CDEF:600MHzb=600MHz,550MHzb,+'";
    #$rrdtool_key .= " 'DEF:720MHz=$input_file.rrd:720MHz:AVERAGE' 'CDEF:720MHzb=720MHz,600MHzb,+'";
    #$rrdtool_key .= " 'DEF:800MHz=$input_file.rrd:800MHz:AVERAGE' 'CDEF:800MHzb=800MHz,720MHzb,+'";
    #$rrdtool_key .= " 'CDEF:125MHza=125MHz,-1,*' 'CDEF:250MHza=250MHzb,-1,*' 'CDEF:500MHza=500MHzb,-1,*' 'CDEF:550MHza=550MHzb,-1,*' 'CDEF:600MHza=600MHzb,-1,*' 'CDEF:720MHza=720MHzb,-1,*' 'CDEF:800MHza=800MHzb,-1,*'";
    # Print each MHz step counter from fastest to slowest.  Print first so other data is on top of these AREAs.
    #$rrdtool_key .= " 'AREA:800MHza\#00ff00:800MHz\\t' 'AREA:720MHza\#00cc00:720MHz\\t' 'AREA:600MHza\#009900:600MHz\\t' 'AREA:550MHza\#006600:550MHz\\t'";
    #$rrdtool_key .= " 'AREA:500MHza\#004400:500MHz\\t' 'AREA:250MHza\#002200:250MHz\\t' 'AREA:125MHz\#000000:125MHz (time in state)'";
    $rrdtool_key .= " 'AREA:800MHza\#FF8000:800MHz' 'AREA:720MHza\#FFFF00:720MHz' 'AREA:600MHza\#C0FF00:600MHz' 'AREA:550MHza\#80FF00:550MHz'";
    $rrdtool_key .= " 'AREA:500MHza\#00FF00:500MHz' 'AREA:250MHza\#088A08:250MHz' 'AREA:125MHza\#0B3B0B:125MHz (relative time in state)'";
    # Network, don't bother graphing the looback adapter, find different colors for ppp0 and eth0
    $rrdtool_key .= " 'DEF:loR=$input_file.rrd:loR:AVERAGE'  'LINE1:loR\#8181F7:lo   Kbytes/sec Rx\\t\\t\\t  '";
    $rrdtool_key .= " 'GPRINT:loR:AVERAGE:Ave \%7.2lf\\t'  'GPRINT:loR:MAX:Max \%7.2lf '";
    $rrdtool_key .= " 'DEF:loT=$input_file.rrd:loT:AVERAGE'  'LINE1:loT\#F78181:Tx\\t'";
    $rrdtool_key .= " 'GPRINT:loT:AVERAGE:Ave \%7.2lf\\t'  'GPRINT:loT:MAX:Max \%7.2lf \\n'";
    $rrdtool_key .= " 'DEF:pppR=$input_file.rrd:pppR:AVERAGE' 'LINE1:pppR\#2E2EFE:ppp0 Kbytes/sec Rx\\t\\t\\t  '";
    $rrdtool_key .= " 'GPRINT:pppR:AVERAGE:Ave \%7.2lf\\t' 'GPRINT:pppR:MAX:Max \%7.2lf '";
    $rrdtool_key .= " 'DEF:pppT=$input_file.rrd:pppT:AVERAGE' 'LINE1:pppT\#FE2E2E:Tx\\t'";
    $rrdtool_key .= " 'GPRINT:pppT:AVERAGE:Ave \%7.2lf\\t' 'GPRINT:pppT:MAX:Max \%7.2lf \\n'";
    $rrdtool_key .= " 'DEF:ethR=$input_file.rrd:ethR:AVERAGE' 'LINE1:ethR\#0404B4:eth0 Kbytes/sec Rx\\t\\t\\t  '";
    $rrdtool_key .= " 'GPRINT:ethR:AVERAGE:Ave \%7.2lf\\t' 'GPRINT:ethR:MAX:Max \%7.2lf '";
    $rrdtool_key .= " 'DEF:ethT=$input_file.rrd:ethT:AVERAGE' 'LINE1:ethT\#B40404:Tx\\t'";
    $rrdtool_key .= " 'GPRINT:ethT:AVERAGE:Ave \%7.2lf\\t' 'GPRINT:ethT:MAX:Max \%7.2lf \\n'";
    # Print Temp, SOC, and mA lines.
    $rrdtool_key .= " 'DEF:mV=$input_file.rrd:mV:AVERAGE' 'CDEF:mVa=mV,1000,/' 'CDEF:mVb=mVa,100,+' 'LINE1:mVb\#81F7F3:Battery mV\\t'";
    $rrdtool_key .= " 'GPRINT:mV:MIN:Min \%4.0lf \\t' 'GPRINT:mV:AVERAGE:Ave \%4.0lf \\t' 'GPRINT:mV:MAX:Max \%4.0lf \\tmV/1000+100 (Volts -100 on graph)\\n'";
    $rrdtool_key .= " 'DEF:mA=$input_file.rrd:mA:AVERAGE' 'CDEF:mAa=mA,50,/' 'CDEF:mAb=mAa,110,+' 'LINE2:mAb\#2EFEF7:Battery mA\\t'";
    $rrdtool_key .= " 'GPRINT:mA:MIN:Min \%4.0lf \\t' 'GPRINT:mA:AVERAGE:Ave \%4.0lf \\t' 'GPRINT:mA:MAX:Max \%4.0lf \\tmA/50+110 (-1000 to 1000mA is 90 to 130 on graph)\\n'";
    $rrdtool_key .= " 'DEF:SOC=$input_file.rrd:SOC:AVERAGE' 'LINE2:SOC\#04B4AE:Battery SOC\\t'";
    $rrdtool_key .= " 'GPRINT:SOC:MIN:Min \%4.0lf \\t' 'GPRINT:SOC:AVERAGE:Ave \%4.0lf \\t' 'GPRINT:SOC:MAX:Max \%4.0lf \t \\n'";
    $rrdtool_key .= " 'DEF:TEMP=$input_file.rrd:TEMP:AVERAGE' 'LINE2:TEMP\#ff0000:Battery TEMP\\t'";
    $rrdtool_key .= " 'GPRINT:TEMP:MIN:Min \%4.0lf \\t' 'GPRINT:TEMP:AVERAGE:Ave \%4.0lf \\t' 'GPRINT:TEMP:MAX:Max \%4.0lf \t(deg C)\\n'";
    $rrdtool_key .= " 'DEF:CPUTEMP=$input_file.rrd:CPUTEMP:AVERAGE' 'LINE2:CPUTEMP\#ffaa00:CPU TEMP\\t\\t'";
    $rrdtool_key .= " 'GPRINT:CPUTEMP:MIN:Min \%4.0lf \\t' 'GPRINT:CPUTEMP:AVERAGE:Ave \%4.0lf \\t' 'GPRINT:CPUTEMP:MAX:Max \%4.0lf \t(deg C)\\n'";
    # 1 minute load average goes to high when the device is sleeping so don't bother graphing it.
    $rrdtool_key .= " 'DEF:Load1=$input_file.rrd:Load1:AVERAGE'   'CDEF:Load1b=Load1,-1,*'      'LINE1:Load1b\#8A0886:Load  1 min avg\\t'";
    $rrdtool_key .= " 'GPRINT:Load1:MIN:Min \%4.0lf \\t' 'GPRINT:Load1:AVERAGE:Ave \%4.0lf \\t' 'GPRINT:Load1:MAX:Max \%4.0lf \\t(inverted)\\n'";
    $rrdtool_key .= " 'DEF:Load5=$input_file.rrd:Load5:AVERAGE'     'CDEF:Load5b=Load5,-1,*'     'LINE1:Load5b\#FF00FF:Load  5 min avg\\t'";
    $rrdtool_key .= " 'GPRINT:Load5:MIN:Min \%4.0lf \\t' 'GPRINT:Load5:AVERAGE:Ave \%4.0lf \\t' 'GPRINT:Load5:MAX:Max \%4.0lf \\t(inverted)\\n'";
    $rrdtool_key .= " 'DEF:Load15=$input_file.rrd:Load15:AVERAGE'   'CDEF:Load15b=Load15,-1,*'   'AREA:Load15b\#F5A9F2:Load 15 min avg\\t'";
    $rrdtool_key .= " 'GPRINT:Load15:MIN:Min \%4.0lf \\t' 'GPRINT:Load15:AVERAGE:Ave \%4.0lf \\t' 'GPRINT:Load15:MAX:Max \%4.0lf \\t(inverted)\\n'";
    $rrdtool_key .= " 'DEF:Running=$input_file.rrd:Running:AVERAGE' 'CDEF:Runningb=Running,-1,*' 'LINE2:Runningb\#610B5E:Running Procs\\t'";
    $rrdtool_key .= " 'GPRINT:Running:MIN:Min \%4.0lf \\t' 'GPRINT:Running:AVERAGE:Ave \%4.0lf \\t' 'GPRINT:Running:MAX:Max \%4.0lf \\t(inverted)\\n'";
    if ($v) { print "Gathering DataPoints : "; }
    foreach $Sample (@DataSet) {
     chomp($Sample); $SampleTime="";
    # Prefix,date.time,long,lat,alt,soc,temp,draw,volts,load1,load5,load15,running,processes,lastpid,uptime,idletime,mhz:time;mhz:time;etc,NicX:Rxb:Rxp:Txb:Txp;etc
    # Prefix,date.time,long,lat,alt,soc,temp,draw,volts,cputemp,load1,load5,load15,running,processes,lastpid,uptime,idletime,mhz:time;mhz:time,etc,NicX:Rxb:Rxp:Txb:Txp;etc
    # $DataSet[$#DataSet]=~ /^[a-z,A-Z,0-9,\.]*,(....)(..)(..).(..)(..)(..),.+/;    # Get the date and time of the last line.
    # if ($v) { print "$Sample\n"; }
    # $Sample =~ /^[^,,a-z,A-Z,0-9,\.]*,(\d\d\d\d)(\d\d)(\d\d).(\d\d)(\d\d)(\d\d),([0-9,\-,\.]*),([[0-9,\-,\.]*),([[0-9,\-,\.]*),?0?,([0-9]*),([0-9]*C),.*/;
     if ( $Sample =~ /^[a-z,A-Z,0-9,\.]*,(\d\d\d\d)(\d\d)(\d\d).(\d\d)(\d\d)(\d\d),([^,]+),([^,]+),([^,]+)?,([^,]+),([^,]+)C,([^,]+)mA,([^,]+)mV,([^,C]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+;[^,]+),([^,]+;[^,]+)/ ||
          $Sample =~ /^[a-z,A-Z,0-9,\.]*,(\d\d\d\d)(\d\d)(\d\d).(\d\d)(\d\d)(\d\d),([^,]+),([^,]+),([^,]+)?,([^,]+),([^,]+)C,([^,]+)mA,([^,]+)mV,([^,C]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+;[^,]+)/ ||
          $Sample =~ /^[a-z,A-Z,0-9,\.]*,(\d\d\d\d)(\d\d)(\d\d).(\d\d)(\d\d)(\d\d),([^,]+),([^,]+),?([^,]+)?,([^,]+),([^,]+)C,([^,]+)mA,([^,]+)mV,([^,C]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),?.+?/ ) {
      $SampleTime=`date -d "$2/$3/$1 $4:$5:$6" +%s`; chomp($SampleTime);
      $SampleLong=$8;   $SampleLat=$7;    $SampleAlt=$9; $SampleSOC=$10;   $SampleTemp=$11; $SamplemA=$12;    $SamplemV=$13;
      $SampleLoad1=$14; $SampleLoad5=$15; $SampleLoad15=$16;
      $SampleRun=$17;   $SampleProcs=$18; $SampleLastPid=$19;
      $SampleUp=$20;    $SampleIdle=$21;  $SampleMHz=$22;     $SampleNet=$23;
    #  if ($v) { print "=1="; }
     } elsif ( $Sample =~ /^[a-z,A-Z,0-9,\.]*,(\d\d\d\d)(\d\d)(\d\d).(\d\d)(\d\d)(\d\d),([^,]+),([^,]+),([^,]+)?,([^,]+),([^,]+)C,([^,]+)mA,([^,]+)mV,([^,]+)C,([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+),([^,]+;[^,]+),([^,]+;[^,]+)/ ) {
      $SampleTime=`date -d "$2/$3/$1 $4:$5:$6" +%s`; chomp($SampleTime);
      $SampleLong=$8;   $SampleLat=$7;    $SampleAlt=$9; $SampleSOC=$10;   $SampleTemp=$11; $SamplemA=$12;    $SamplemV=$13;
      $SampleLoad1=$15; $SampleLoad5=$16; $SampleLoad15=$17;
      $SampleRun=$18;   $SampleProcs=$19; $SampleLastPid=$20;
      $SampleUp=$21;    $SampleIdle=$22;  $SampleMHz=$23;     $SampleNet=$24;
    #  if ($v) { print "=2="; }
     if ($SampleTime) {
    #  if ($v) { print "$SampleTime, ($SampleLong,$SampleLat,$SampleAlt), ($SampleSOC,$SampleTemp,$SamplemA,$SamplemV,$SampleCPUTemp), $SampleMHz, $SampleNet\n"; }
    #  mA will be -1000 to +1000, scale to 1/50th (-20 tp +20) and raise by 110 (90 to 130)
    #  $SamplemA=( ( $SamplemA / 50 ) + 110 );
    # mV will be 3500 to 4200, scale by 1/1000th for volts and raise by 100 for 103.5 to 104.2
    #  $SamplemV=( ( $SamplemV / 1000 ) + 100 );
    # Break apart the Network samples into each Net Adapter and it's counters nicX:Rxbytes:Rxpackets:Txbytes:Txpackets
      while ($SampleNet) {
       ($Step,$SampleNet)=split (/\;/,$SampleNet,2);
       ($Net,$Rb,$Rp,$Tb,$Tp)=split (/\:/,$Step,5);
    #   @$Net[0]=ceil$Rb; @$Net[1]=$Rp; @$Net[2]=$Tb; @$Net[3]=$Tp; # bytes
       @$Net[0]=ceil($Rb/1024); @$Net[1]=ceil($Rp/1024); @$Net[2]=ceil($Tb/1024); @$Net[3]=ceil($Tp/1024); # Kbytes
    #   @$Net[0]=ceil($Rb/1048576); @$Net[1]=ceil($Rp/1048576); @$Net[2]=ceil($Tb/1048576); @$Net[3]=ceil($Tp/1048576); # Mbytes
    #   @$Net[0]=ceil($Rb/1073741824); @$Net[1]=ceil($Rp/1073741824); @$Net[2]=ceil($Tb/1073741824); @$Net[3]=ceil($Tp/1073741824); # Gbytes
    #   print "$Step  -  $SampleNet  -  $Net  -  @$Net\n\n";
    #   print "$Net : @$Net\t";
      }#  print "\n";
    ## Bunch of MHz processing junk...  Using rrd data type of counter, so not using the difference and total stuff here.
    ## Store the last samples MHz speeds and values and reset for next sample.
      @LMHzs=@MHzs; @MHzs="";       # store LastMHz's, reset MHz's
      $LSMHzT=$SMHzT; $SMHzT=0;     # store LastSampleMHzTotal, reset
      foreach $MHz (@LMHzs) { $LMHz="L$MHz"; @$LMHz=@$MHz; }
    ## Break apart this samples into MHz's and each ones values, and sum the values.
      while ($SampleMHz) {
       ($Step,$SampleMHz)=split (/\;/,$SampleMHz,2);
    #   ($MHz,$MHzt)=split (/\:/,$Step,2); @$MHz=$MHzt; # Use raw unmodified values in the .rrd
       ($MHz,$MHzt)=split (/\:/,$Step,2); @$MHz=ceil( $MHzt / 4.5 ); # Scale down by 10, need to round or drop decimles. use ceil or floor
    #   ($MHz,$MHzt)=split (/\:/,$Step,2); @$MHz=ceil( ( $MHzt / 10 ) - 10 ); # Scale down by 10, subtract 10 and "round".
    #   $SMHzT=( $SMHzT + $MHzt );  # Total counts? We are not using this value for now.
    #   print "$Step  -  $SampleMHz  -  $MHz  -  @$MHz\n";
    # print "@MHzs\n";
    if ($d) { print "$2/$3/$1 $4:$5:$6 - "; }
    # Subtract this samples value from the Last one for each MHz's and sum the total of all values.
    # foreach $MHz (@MHzs) { $LMHz="L$MHz"; $SMHz="S$MHz"; @$SMHz=( @$MHz[0] - @$LMHz[0] ); $SMHzT=( $SMHzT + @$SMHz[0] ); }
    # Print what we have.
    # foreach $MHz (@MHzs) { $LMHz="L$MHz"; $SMHz="S$MHz"; print "$MHz:@$MHz-@$LMHz=@$SMHz/$SMHzT - "; }    # print more
    # foreach $MHz (@MHzs) { $LMHz="L$MHz"; $SMHz="S$MHz"; print "$MHz:@$SMHz - "; } print "$SMHzT";        # print cleaner
    ## Get the Percentage of time spent at each MHz's
    #  foreach $MHz (@MHzs) { $LMHz="L$MHz"; $SMHz="S$MHz"; $PMHz="P$MHz"; if ($SMHzT) { @$PMHz=( @$SMHz[0] / $SMHzT ); } }
    ## Print what we have.
    #  foreach $MHz (@MHzs) { $LMHz="L$MHz"; $SMHz="S$MHz"; $PMHz="P$MHz"; print "$MHz:@$PMHz - "; }
    if ($d) { print "\n"; }
    ## How the flip can we graph with one or multiple lines the time spent at each MHz's?
    ## How about a stacked filled RRD set, won't need much of the above bull junk.
    ## figured it out I think...
      if ($v) { print "."; }
    #  $rrdtool_update = "rrdtool update $input_file.rrd $SampleTime:$SampleTemp:$SampleSOC:$SamplemA:";
      $rrdtool_update = "rrdtool update $input_file.rrd $SampleTime:$SampleTemp:$SampleSOC:$SamplemA:$SamplemV:$SampleCPUTemp:$SampleLoad1:$SampleLoad5:$SampleLoad15:$SampleRun:@125[0]:@250[0]:@500[0]:@550[0]:@600[0]:@720[0]:@800[0]:@lo[0]:@lo[2]:@ppp0[0]:@ppp0[2]:@eth0[0]:@eth0[2]";
    #  if ($v) { print "$rrdtool_update\n"; }
      push (@rrdtool_update,"$rrdtool_update\n");
    if ($v) { print " done.\n\n"; }
    # Finally execute the $rrdtool_create command and each of the @rrdtool_update commands
    if ($v) { print "Creating .rrd"; }
    print `$rrdtool_create`;
    if ($v) { print ", adding data to .rrd : "; }
    foreach (@rrdtool_update) {
     print `$_ 1> /dev/null 2> /dev/null`;
     if ($v) { print "."; }
    # if ($v) { print "$_\n"; }
    if ($v) { print " done.\n\n"; }
    # Now, Finally, Graph the .rrd data
    if ($v) { print "Creating graph$input_file.png "; }
    $rrdtool_graph = "rrdtool graph $input_file.png -a PNG --color BACK#eeffee --color CANVAS#f5fff5 --title=\"Palm Pre ($Start-$End) $#DataSet Samples.\"";
    $rrdtool_graph .= " --vertical-label \"MHz, Load, Processes, Temp, SOC, mA, and Stuff\"";
    $rrdtool_graph .= " 'HRULE:110#2EFEF7' 'HRULE:100#04B4AE' 'HRULE:50#ff0000' 'HRULE:45#cc9900' 'HRULE:40#cccc00'";
    #$rrdtool_graph .= " 'HRULE:100#00ccff' 'HRULE:102#00ccff' 'HRULE:104#00ccff' 'HRULE:106#00ccff' 'HRULE:108#00ccff' 'HRULE:110#00ccff' 'HRULE:112#00ccff' 'HRULE:114#00ccff' 'HRULE:116#00ccff' 'HRULE:118#00ccff' 'HRULE:120#00ccff'";
    $rrdtool_graph .= " $rrdtool_key";
    $rrdtool_graph .= " --lower-limit -25 --upper-limit 125 --rigid";
    #$rrdtool_graph .= " --no-legend";
    $rrdtool_graph .= " --alt-autoscale --units-exponent -0 --units-length 3";
    $rrdtool_graph .= " --start $SecStart-60 --end $SecEnd+60 --step 1 --height 480 --width 720 --slope-mode --interlaced";
    #$rrdtool_graph .= " --start 1273033333+1800 --end $SecEnd+60 --step 1 --height 480 --width 720 --slope-mode --interlaced";
    # 320x480 screen (x2 640x960) (1.5x 480x720)
    print `$rrdtool_graph`;
    # Now, remove the large .rrd file.
    print `ls -lah $input_file.rrd ; rm -f $input_file.rrd`;
    # Make a map kml file using a single line instead of push pins.
    sub process_ral {
     $Map_Name = $input_file; $Map_Name =~ s/\.ral//;$Map_Name =~ s/.*\///;
     @Points=`cat $input_file`; chomp(@Points);
     print <<"_END_";
    <kml xmlns="">
      <Style id="style00">
     foreach $point (@Points) {
      $point =~ /(style\d*.\d*)\ *(.*.png)\ *(\w*)\ *(-?\d*.\d*)\ *(-?\d*.\d*)\ *(-?\d*.\d*)/;
      $style=$1; $icon=$2; $name=$3; $long=$4; $lat=$5; $alt=$6;
    #  print "<Style id=\"style$style_counter\">\n  <IconStyle>\n    <Icon>\n      <href>$icon_prefix/$icon</href>\n    </Icon>\n  </IconStyle>\n</Style>\n";
    #  print "<Placemark>\n  <name>$name</name>\n  <description><![CDATA[]]></description>\n  <styleUrl>#style$style_counter</styleUrl>\n";
    #  print "  <Point>\n    <coordinates>$long,$lat,$alt</coordinates>\n  </Point>\n</Placemark>\n";
      print "      $long,$lat,$alt\n";
     print <<"_END_";
    } # End process_raw
    Last edited by Dolio; 05/18/2010 at 04:36 AM. Reason: Added Script....
  4. #4  
    This is some impressive work. It's interesting that the phone running at 800mhz doesn't have much effect on the temperature, even when running multiple apps (if I read that correctly).

    What accounts for the sharp decline in battery on Saturday and Sunday afternoon?
  5. Dolio's Avatar
    48 Posts
    Global Posts
    54 Global Posts
    Quote Originally Posted by Jahooba View Post
    This is some impressive work. It's interesting that the phone running at 800mhz doesn't have much effect on the temperature, even when running multiple apps (if I read that correctly).

    What accounts for the sharp decline in battery on Saturday and Sunday afternoon?
    That is what I've concluded, the CPU speed doesn't seem to have much effect on the temperature. The radio activity appears to have much more effect on temperature. For example, running tethering (both 3G and WiFi radios on) is the activity that results in the most heat and battery drain. I have tighter (1 day) graphs of tethering events where the temperature rises sharply, during those times the CPU might be at only 500MHz and the screen may be off to try and keep things cooler. I think it's been pointed out elsewhere that the radio load seems to produce a lot of heat.

    Regarding the number of "Running Apps", there are always going to be a few "Running Procs" or Processes, such as Java, Luna, my cron script, etc. But these processes do not equate to running apps. In fact running WebOS apps might not even appear as running processes, since they are all sub-luna-java processes handled by those two processes. This brings up a very good point in that it would be nice to have some way of logging the number of running WebOS apps, rather than system processes.

    The sharp decline in SOC on Saturday and Sunday was me listening to three PalmCast Episodes each day (3 to 4 hours of listening) via my blue tooth earbud as I worked outside in the garden...
  6. Dolio's Avatar
    48 Posts
    Global Posts
    54 Global Posts
    Alright, it's been a while, and I've been working on a "local" version that uses the rrdtool command to collect, store, and render graphs entirely on the device. But the local version seems to be much heavier than offloading the data to an external server for processing...

    Anyway, I've also turned my personal graphs into an image gallery that you are welcome to check out via Viewing /Pre.Track/Pre.Track.Dolio.lastweek.png at 799 x 727 . The Previous image will be for yesterday and the Next image for today. You can also go up to the parent folder for thumbnails of all the monthly (top of the list) and daily graphs.

    Also added 1000MHz to the CPU speed portion of the graph. One quark, "WarthogKernel" v1.4.1-58 appears to have added 1000MHz but removed 800MHz from the available steps. The Previous v1.4.1-52(I think) had both 800 and 1005 which I think I preferred. Consider this a note to self to update the script above to render the new 1GHz clock rate, and deal with missing steps.
    Last edited by Dolio; 06/29/2010 at 09:18 PM. Reason: Noticed the missing 800MHz step from the latest kernel...
  7. #7  
    That chart is nearly impossible to understand... but i like the concept. I've always wanted a way to log the on/off of the data radios.

    Could you display the relationship between battery and data radios?

    If I helped you or you have downloaded one of my files,
    then least you could do is click the "Thanks" button.
  8. Dolio's Avatar
    48 Posts
    Global Posts
    54 Global Posts
    Quote Originally Posted by Abyssul View Post
    That chart is nearly impossible to understand... but i like the concept. I've always wanted a way to log the on/off of the data radios.

    Could you display the relationship between battery and data radios?
    The link above is for the weekly graph, which is fairly condensed and more difficult to interpret than the daily ones. Clicking through to the individual day graphs which should give a more detailed view and be easier to understand.

    Here is an example of an idle discharge.
    * Viewing /Pre.Track/Pre.Track.Dolio.20100627.pre.png at 799 x 727

    Here is an example of streaming a few PodCasts over EVDO.
    * Viewing /Pre.Track/Pre.Track.Dolio.20100529.pre.png at 799 x 727
    * Viewing /Pre.Track/Pre.Track.Dolio.20100529..pre.png at 799 x 727
    * Viewing /Pre.Track/Pre.Track.Dolio.20100529...pre.png at 799 x 727
    The last shows Discharges of 165 to 545mA with an average of 369mA

    Here's another day with similar PodCasting activities.
    * Viewing /Pre.Track/Pre.Track.Dolio.20100523.pre.png at 799 x 727

Tags for this Thread

Posting Permissions