|
|
<?php |
|
|
/* ccminer API sample UI (API 1.7) */ |
|
|
|
|
|
$host = 'http://localhost/api/'; // 'http://'.$_SERVER['SERVER_NAME'].'/api/'; |
|
|
$configs = array( |
|
|
'LOCAL'=>'local-sample.php', |
|
|
//'EPSYTOUR'=>'epsytour.php', /* copy local.php file and edit target IP:PORT */ |
|
|
); |
|
|
|
|
|
// 3 seconds max. |
|
|
set_time_limit(3); |
|
|
error_reporting(0); |
|
|
|
|
|
function getdataFromPeers() |
|
|
{ |
|
|
global $host, $configs; |
|
|
$data = array(); |
|
|
foreach ($configs as $name => $conf) { |
|
|
|
|
|
$json = file_get_contents($host.$conf); |
|
|
|
|
|
$data[$name] = json_decode($json, TRUE); |
|
|
} |
|
|
return $data; |
|
|
} |
|
|
|
|
|
function ignoreField($key) |
|
|
{ |
|
|
$ignored = array( |
|
|
'API','VER','GPU','BUS','POOLS', |
|
|
'CARD','GPUS','CPU','TS', |
|
|
); |
|
|
return in_array($key, $ignored); |
|
|
} |
|
|
|
|
|
function translateField($key) |
|
|
{ |
|
|
$intl = array(); |
|
|
$intl['NAME'] = 'Software'; |
|
|
$intl['VER'] = 'Version'; |
|
|
|
|
|
$intl['ALGO'] = 'Algorithm'; |
|
|
$intl['GPUS'] = 'GPUs'; |
|
|
$intl['CPUS'] = 'Threads'; |
|
|
$intl['KHS'] = 'Hash rate'; |
|
|
$intl['ACC'] = 'Accepted shares'; |
|
|
$intl['ACCMN'] = 'Accepted / mn'; |
|
|
$intl['REJ'] = 'Rejected'; |
|
|
$intl['SOLV'] = 'Solved'; |
|
|
$intl['DIFF'] = 'Difficulty'; |
|
|
$intl['NETKHS'] = 'Net Rate'; |
|
|
$intl['UPTIME'] = 'Miner up time'; |
|
|
$intl['TS'] = 'Last update'; |
|
|
$intl['THR'] = 'Throughput'; |
|
|
$intl['WAIT'] = 'Wait time'; |
|
|
|
|
|
|
|
|
$intl['H'] = 'Bloc height'; |
|
|
$intl['I'] = 'Intensity'; |
|
|
$intl['HWF'] = 'Failures'; |
|
|
$intl['POOLS'] = 'Pools'; |
|
|
|
|
|
$intl['TEMP'] = 'T°c'; |
|
|
$intl['FAN'] = 'Fan %'; |
|
|
$intl['FREQ'] = 'Freq.'; |
|
|
$intl['POWER'] = 'Power'; |
|
|
$intl['PST'] = 'P-State'; |
|
|
|
|
|
// pool infos |
|
|
$intl['POOL'] = 'Pool'; |
|
|
$intl['PING'] = 'Ping (ms)'; |
|
|
$intl['DISCO'] = 'Disconnects'; |
|
|
$intl['USER'] = 'User'; |
|
|
|
|
|
if (isset($intl[$key])) |
|
|
return $intl[$key]; |
|
|
else |
|
|
return $key; |
|
|
} |
|
|
|
|
|
function translateValue($key,$val,$data=array()) |
|
|
{ |
|
|
switch ($key) { |
|
|
case 'UPTIME': |
|
|
case 'WAIT': |
|
|
$min = floor(intval($val) / 60); |
|
|
$sec = intval($val) % 60; |
|
|
$val = "${min}mn${sec}s"; |
|
|
if ($min > 180) { |
|
|
$hrs = floor($min / 60); |
|
|
$min = $min % 60; |
|
|
$val = "${hrs}h${min}mn"; |
|
|
} |
|
|
break; |
|
|
case 'NAME': |
|
|
$val = $data['NAME'].' '.$data['VER']; |
|
|
break; |
|
|
case 'FREQ': |
|
|
$val = sprintf("%d MHz", round(floatval($val)/1000.0)); |
|
|
break; |
|
|
case 'POWER': |
|
|
$val = sprintf("%d W", round(floatval($val)/1000.0)); |
|
|
break; |
|
|
case 'TS': |
|
|
$val = strftime("%H:%M:%S", (int) $val); |
|
|
break; |
|
|
case 'KHS': |
|
|
case 'NETKHS': |
|
|
$val = '<span class="bold">'.$val.'</span> kH/s'; |
|
|
break; |
|
|
case 'NAME': |
|
|
case 'POOL'; |
|
|
case 'USER': |
|
|
// long fields |
|
|
$val = '<span class="elipsis">'.$val.'</span>'; |
|
|
break; |
|
|
} |
|
|
return $val; |
|
|
} |
|
|
|
|
|
function filterPoolInfos($stats) |
|
|
{ |
|
|
$keys = array('USER','H','PING','DISCO'); |
|
|
$data = array(); |
|
|
$pool = array_pop($stats); |
|
|
// simplify URL to host only |
|
|
$data['POOL'] = $pool['URL']; |
|
|
if (strstr($pool['URL'],'://')) { |
|
|
$parts = explode(':', $pool['URL']); |
|
|
$data['POOL'] = substr($parts[1],2); |
|
|
} |
|
|
foreach ($pool as $key=>$val) { |
|
|
if (in_array($key, $keys)) |
|
|
$data[$key] = $val; |
|
|
} |
|
|
return $data; |
|
|
} |
|
|
|
|
|
function displayData($data) |
|
|
{ |
|
|
$htm = ''; |
|
|
$totals = array(); |
|
|
foreach ($data as $name => $stats) { |
|
|
if (!isset($stats['summary'])) |
|
|
continue; |
|
|
$htm .= '<table id="tb_'.$name.'" class="stats">'."\n"; |
|
|
$htm .= '<tr><th class="machine" colspan="2">'.$name."</th></tr>\n"; |
|
|
if (!empty($stats)) { |
|
|
$summary = (array) $stats['summary']; |
|
|
foreach ($summary as $key=>$val) { |
|
|
if (!empty($val) && !ignoreField($key)) |
|
|
$htm .= '<tr><td class="key">'.translateField($key).'</td>'. |
|
|
'<td class="val">'.translateValue($key, $val, $summary)."</td></tr>\n"; |
|
|
} |
|
|
if (isset($summary['KHS'])) |
|
|
@ $totals[$summary['ALGO']] += floatval($summary['KHS']); |
|
|
|
|
|
if (isset($stats['pool']) && !empty($stats['pool']) ) { |
|
|
$pool = filterPoolInfos($stats['pool']); |
|
|
$htm .= '<tr><th class="gpu" colspan="2">POOL</th></tr>'."\n"; |
|
|
foreach ($pool as $key=>$val) { |
|
|
if (!empty($val) && !ignoreField($key)) |
|
|
$htm .= '<tr><td class="key">'.translateField($key).'</td>'. |
|
|
'<td class="val">'.translateValue($key, $val)."</td></tr>\n"; |
|
|
} |
|
|
} |
|
|
|
|
|
foreach ($stats['threads'] as $g=>$gpu) { |
|
|
$card = isset($gpu['CARD']) ? $gpu['CARD'] : ''; |
|
|
$htm .= '<tr><th class="gpu" colspan="2">'.$g." $card</th></tr>\n"; |
|
|
foreach ($gpu as $key=>$val) { |
|
|
if (!empty($val) && !ignoreField($key)) |
|
|
$htm .= '<tr><td class="key">'.translateField($key).'</td>'. |
|
|
'<td class="val">'.translateValue($key, $val)."</td></tr>\n"; |
|
|
} |
|
|
} |
|
|
} |
|
|
$htm .= "</table>\n"; |
|
|
} |
|
|
// totals |
|
|
if (!empty($totals)) { |
|
|
$htm .= '<div class="totals"><h2>Total Hash rate</h2>'."\n"; |
|
|
foreach ($totals as $algo => $hashrate) { |
|
|
$htm .= '<li><span class="algo">'.$algo.":</span>$hashrate kH/s</li>\n"; |
|
|
} |
|
|
$htm .= '</div>'; |
|
|
} |
|
|
return $htm; |
|
|
} |
|
|
|
|
|
$data = getdataFromPeers(); |
|
|
|
|
|
?> |
|
|
<html> |
|
|
<head> |
|
|
<title>ccminer rig api sample</title> |
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
|
|
<meta http-equiv="refresh" content="10"> |
|
|
<style type="text/css"> |
|
|
body { |
|
|
color:#cccccc; background:#1d1d1d; margin:30px 30px 0px 30px; padding:0px; |
|
|
font-size:.8em; font-family:Arial,Helvetica,sans-serif; |
|
|
} |
|
|
a { color:#aaaaaa; text-decoration: none; } |
|
|
a:focus { outline-style:none; } |
|
|
.clear { clear: both; } |
|
|
|
|
|
div#page, div#header, div#footer { |
|
|
margin: auto; |
|
|
width: 950px; |
|
|
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15); |
|
|
} |
|
|
div#page { |
|
|
padding-top: 8px; |
|
|
background: #252525; |
|
|
min-height: 820px; |
|
|
} |
|
|
div#header { |
|
|
background: rgba(65, 65, 65, 0.85); |
|
|
height: 50px; |
|
|
margin-bottom: 24px; |
|
|
padding-left: 8px; |
|
|
} |
|
|
div#footer { |
|
|
background: rgba(25, 25, 25, 0.85); |
|
|
height: 0px; |
|
|
margin-bottom: 40px; |
|
|
text-align: center; |
|
|
color: #666666; |
|
|
text-shadow: rgba(0, 0, 0, 0.8) 0px 1px 0px; |
|
|
} |
|
|
#header h1 { padding: 12px; font-size: 20px; } |
|
|
#footer p { margin: 12px 24px; } |
|
|
|
|
|
table.stats { width: 280px; margin: 4px 16px; display: inline-block; } |
|
|
th.machine { color: darkcyan; padding: 16px 0px 0px 0px; text-align: left; border-bottom: 1px solid gray; } |
|
|
th.gpu { color: white; padding: 3px 3px; font: bolder; text-align: left; background: rgba(65, 65, 65, 0.85); } |
|
|
td.key { width: 99px; max-width: 180px; } |
|
|
td.val { width: 40px; max-width: 100px; color: white; } |
|
|
|
|
|
div.totals { margin: 16px; padding-bottom: 16px; } |
|
|
div.totals h2 { color: darkcyan; font-size: 16px; margin-bottom: 4px; } |
|
|
div.totals li { list-style-type: none; font-size: 16px; margin-left: 4px; margin-bottom: 8px; } |
|
|
li span.algo { display: inline-block; width: 100px; max-width: 180px; } |
|
|
|
|
|
span.bold { color: #bb99aa; } |
|
|
span.elipsis { display: inline-block; max-width: 130px; overflow: hidden; } |
|
|
</style> |
|
|
</head> |
|
|
<body> |
|
|
<div id="header"> |
|
|
<h1>ccminer monitoring API RIG sample</h1> |
|
|
</div> |
|
|
|
|
|
<div id="page"> |
|
|
<?=displayData($data)?> |
|
|
</div> |
|
|
|
|
|
<div id="footer"> |
|
|
<p>© 2014-2015 <a href="http://github.com/tpruvot/ccminer">tpruvot@github</a></p> |
|
|
</div> |
|
|
|
|
|
</body> |
|
|
</html>
|
|
|
|