Mar 11
1 Star2 Stars3 Stars4 Stars5 Stars (3 votes, average: 4.67 out of 5)
Loading ... Loading ...

BOINC Statistics output to ConkySince my previous article about Conky, Conky on Ubunty 64 Bit - .conkyrc, I’ve been playing around with trying to get Conky to output some BOINC (SETI@Home data), and through a little digging, found a couple of very useful resources. The first being BOINC’s own client_status.xml file, located on Ubunutu in /var/lib/boinc-client/client_status.xml, which contains a lot of information about BOINC projects, Work Units, Status and so on. The second being a command line application, again built into BOINC - boinc_cmd. boinc_cmd can be executed with a bunch of parameters, such as –get_simple_gui_info and –get_project_status which output to the Terminal a lot of information about Projects and Work Units.

To output BOINC data via Conky, it’s possible to call the boinc_cmd in .conkyrc and strip down the information with grep and sed etc:

${execi 10 boinc_cmd --get_simple_gui_info | grep -m 1 "fraction done:" | tail -n 1 - | sed -e 's/ fraction done: //'}
${execi 10 boinc_cmd --get_simple_gui_info | grep -m 2 "fraction done:" | tail -n 1 - | sed -e 's/ fraction done: //'}

…and so on for each piece of data required for output, but this is pretty labourious, and makes for a rather ugly .conkyrc, so I’ve written a really quick and dirty Perl Script (it’s not pleasant to look at, and needs a LOT of work, so it’s more of a pre Alpha-Alpha! I’m not sure how, or if it will work with multiple projects, since I only have SETI@HOME installed…) - which actually retrieves all the data from the client_status.xml file. The (archived) script, boinc.pl can be downloaded here (and viewed below - just copy and paste the text into a file, and save it as “boinc.pl” if the download doesn’t work for you). It’s also posted over at the Ubuntu Forums. I’ve called it in .conkyrc by adding one simple line:

BOINC:
${color lightgrey}${execi 10 perl ~/ConkyScripts/boinc/boinc.pl}

OK, so that’s actually two lines, but the first line doesn’t really do anything except output the text “BOINC:” to Conky, so it doesn’t count - but it’s much cleaner than potentially dozens of lines, right? The script itself is in my ~/ConkyScripts/boinc directory and has been made executable:

sudo chmod a+x boinc.pl

Here’s the script so far - it’s VERY much Work In Progress, but it outputs the data as shown in the image above:

Edit 15/03/08: I’ve updated the code, so hopefully it’ll work with multiple projects:

#!/usr/bin/perl

$BoincStatePath="/var/lib/boinc-client";
$BoincClientStateFile="client_state.xml";
$StateFile="$BoincStatePath/$BoincClientStateFile";

open(INFO, $StateFile);
@lines = <INFO>;
close(INFO);
sub strip_tags($);

sub convert_time_to_string($);
sub estimate_time_remaining;
$projectCount = 0;
$wuCount = 0;
$wuActive = 0;
$wuActiveTask = 0;

foreach $line (@lines) {

   if ($line =~ /<master_url>/) {
      $projectMasterURL[$projectCount] = strip_tags($line);
   }

   if ($line =~ /<project_name>/) {
      $projectName[$projectCount] = strip_tags($line);
      $projectCount++;
   }

   if ($line =~ /<workunit>/) {
      $wuCount++;
   }

   if ($line =~ /<active_task_state>1/) {
      $wuActive++;
   }

   if ($line =~ /<active_task>/) {
      $wuActiveTask++;
   }

   if ($line =~ /<result_name>/) {
      $wuName[$wuActiveTask] = strip_tags($line);
   }

   if ($line =~ /<fraction_done>/) {
      $wuPercent[$wuActiveTask] = strip_tags($line) * 100;
   }

   if ($line =~ /<project_master_url>/) {
      $wuMasterURL[$wuActiveTask] = strip_tags($line);
   }

   if ($line =~ /<current_cpu_time>/) {
      $wuCPUTime[$wuActiveTask] = convert_time_to_string(strip_tags($line));
      $wuCPUTimeRaw[$wuActiveTask] = strip_tags($line);
   }

}

print "No. Work Units: ".$wuCount.", Active WU: ".$wuActive."\n";

for($i = 0; $i <= $projectCount; ++$i) {
   print $projectName[$i];
   for ($j = 1; $j <= $wuActiveTask; ++$j) {
      if($projectMasterURL[$i] eq $wuMasterURL[$j]) {
         print "WU ".$j.": ".$wuName[$j];
         $estTime = convert_time_to_string(estimate_time_remaining($wuCPUTimeRaw[$j],$wuPercent[$j]));
         print "CPU Time: ".$wuCPUTime[$j]." Time Remaining: ".$estTime."\n";
         print $wuPercent[$j]."% Complete\n";
      }
   }
}

sub strip_tags($) {
   my $string = shift;
   $string =~ s/<(.*?)>//gi;
   $string =~ s/ //gi;
   return $string;
}

sub convert_time_to_string($) {
   $cpuTime = int($_[0]);
   #Calculate the number of days
   if ($cpuTime > 86400) {
      $timeDays = $cpuTime/(24*60*60).":";
   } else {
      $timeDays = "";
   }

   #Calculate the number of hours and minutes
   $timeHours = ($cpuTime/(60*60))%24;
   $timeMinutes = ($cpuTime/60)%60;
   $timeSeconds = $cpuTime%60;
   $cpuTimeString = $timeDays.$timeHours.":".$timeMinutes.":".$timeSeconds;

   return $cpuTimeString;
}

sub estimate_time_remaining {
   $cpuTime = $_[0];
   $currentPercent = $_[1];
   $onePercentTime = $cpuTime/$currentPercent;
   $totalTime = $onePercentTime * 100;
   $estimatedTimeReminaing = $totalTime - $cpuTime;
   return $estimatedTimeReminaing;
}

written by Hodge \\ tags: , , , , ,

Webloogle Blog Directory