->
Since 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;
}

(3 votes, average: 4.67 out of 5)
Twitter
Facebook










Recent Comments