Title: [ANN] CGMiner Wordpress Widget
Post by: dna2 on September 27, 2013, 10:01:56 PM
Hi everybody, this is my small contribution to the community. Please be easy on me ;) Since I've installed my RPi driving four USB Erupters, I thought I needed a web interface for it. Looking at available projects, I didn't found anything I liked. So I decided to configure my own portal with Wordpress. This is the only first step in integrating CGMiner stats with it but I think is already usable (even if it's really simple). This is the result (look at the bottom left): https://i.imgur.com/zTJv3ZJ.pngThis is the configuration panel visible from Wordpress Dashboard where you can configure IP and Port of your miner: https://i.imgur.com/9dMKTWj.pngAnd this is the widget source code: <?php /** * Plugin Name: Miner Widget * Description: A widget that displays CGMiner stats * Version: 0.1 * Author: dna2 */
ini_set('display_errors', 'On'); add_action( 'widgets_init', 'register_miner_widget' );
function register_miner_widget() { register_widget( 'MinerWidget' ); }
class MinerWidget extends WP_Widget {
function MinerWidget() { $widget_ops = array( 'classname' => 'example', 'description' => __('A widget that displays statistics from CGMiner ', 'example') ); $control_ops = array( 'id_base' => 'miner-widget' ); $this->WP_Widget( 'miner-widget', __('Miner Widget', 'example'), $widget_ops, $control_ops ); } function widget( $args, $instance ) { extract( $args );
$title = apply_filters('widget_title', $instance['title'] ); $ip = $instance['ip']; $port = $instance['port']; $show_info = isset( $instance['show_info'] ) ? $instance['show_info'] : false;
echo $before_widget;
if ( $title ) echo $before_title . $title . $after_title;
$data = $this->requestMiner($ip, $port, 'summary'); if ( $data ) { //printf( 'Version: ' . $data['STATUS']['Description'] . '<BR/>'); printf( 'Uptime: ' . $this->formatTime($data['SUMMARY']['Elapsed']) . '<BR/>'); printf( 'MHS av: ' . $this->formatNumber($data['SUMMARY']['MHS av']) . '<BR/>'); printf( 'Found Blocks: ' . $data['SUMMARY']['Found Blocks'] . '<BR/>'); //printf( 'Getworks: ' . $this->formatNumber($data['SUMMARY']['Getworks']) . '<BR/>'); printf( 'Accepted: ' . $this->formatNumber($data['SUMMARY']['Accepted']) . '<BR/>' ); printf( 'Rejected: ' . $this->formatNumber($data['SUMMARY']['Rejected']) . '<BR/>' ); printf( 'Hardware Errors: ' . $this->formatNumber($data['SUMMARY']['Hardware Errors']) . '<BR/>' ); //printf( 'Utility: ' . $data['SUMMARY']['Utility'] . '<BR/>' ); //printf( 'Discarded: ' . $this->formatNumber($data['SUMMARY']['Discarded']) . '<BR/>' ); //printf( 'Stale: ' . $this->formatNumber($data['SUMMARY']['Stale']) . '<BR/>' ); //printf( 'Get Failures: ' . $this->formatNumber($data['SUMMARY']['Get Failures']) . '<BR/>' ); //printf( 'Local Work: ' . $this->formatNumber($data['SUMMARY']['Local Work']) . '<BR/>' ); //printf( 'Remote Failures: ' . $this->formatNumber($data['SUMMARY']['Remote Failures']) . '<BR/>' ); //printf( 'Network Blocks: ' . $this->formatNumber($data['SUMMARY']['Network Blocks']) . '<BR/>' ); //printf( 'Total MH: ' . $this->formatNumber($data['SUMMARY']['Total MH']) . '<BR/>' ); //printf( 'Work Utility: ' . $data['SUMMARY']['Work Utility'] . '<BR/>' ); //printf( 'Diff. Accepted: ' . $data['SUMMARY']['Difficulty Accepted'] . '<BR/>' ); //printf( 'Diff. Rejected: ' . $data['SUMMARY']['Difficulty Rejected'] . '<BR/>' ); //printf( 'Diff. Stale: ' . $data['SUMMARY']['Difficulty Stale'] . '<BR/>' ); printf( 'Best Share: ' . $this->formatNumber($data['SUMMARY']['Best Share']) . '<BR/>' ); } //if ( $show_info ) // printf( $ip ); echo $after_widget; } private function requestMiner($ip, $port, $cmd) { try { $socket = $this->getsock($ip, $port); if ($socket != null) { socket_write($socket, $cmd, strlen($cmd)); $line = $this->readsockline($socket); socket_close($socket); if (strlen($line) == 0) { //echo "WARN: '$cmd' returned nothing\n"; return $line; } //print "$cmd returned '$line'\n"; if (substr($line,0,1) == '{') return json_decode($line, true); $data = array(); $objs = explode('|', $line); foreach ($objs as $obj) { if (strlen($obj) > 0) { $items = explode(',', $obj); $item = $items[0]; $id = explode('=', $items[0], 2); if (count($id) == 1 or !ctype_digit($id[1])) $name = $id[0]; else $name = $id[0].$id[1]; if (strlen($name) == 0) $name = 'null'; if (isset($data[$name])) { $num = 1; while (isset($data[$name.$num])) $num++; $name .= $num; } $counter = 0; foreach ($items as $item) { $id = explode('=', $item, 2); if (count($id) == 2) $data[$name][$id[0]] = $id[1]; else { $data[$name][$counter] = $id[0]; } $counter++; } } } return $data; } return null;
} catch (Exception $e) { return $e->getMessage(); } } private function getsock($addr, $port) { $socket = null; $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); if ($socket === false || $socket === null) { $error = socket_strerror(socket_last_error()); $msg = "socket create(TCP) failed"; echo "ERR: $msg '$error'\n"; return null; } $res = socket_connect($socket, $addr, $port); if ($res === false) { $error = socket_strerror(socket_last_error()); $msg = "socket connect($addr,$port) failed"; echo "ERR: $msg '$error'\n"; socket_close($socket); return null; } return $socket; } private function readsockline($socket) { $line = ''; while (true) { $byte = socket_read($socket, 1); if ($byte === false || $byte === '') break; if ($byte == "\0") break; $line .= $byte; } return $line; } private function formatTime($value) { $s = $value % 60; $value -= $s; $value /= 60; if ($value == 0) $ret = $s.'s'; else { $m = $value % 60; $value -= $m; $value /= 60; if ($value == 0) $ret = sprintf("%dm $b%02ds", $m, $s); else { $h = $value % 24; $value -= $h; $value /= 24; if ($value == 0) $ret = sprintf("%dh $b%02dm $b%02ds", $h, $m, $s); else { if ($value == 1) $days = ''; else $days = 's'; $ret = sprintf("%dday$days, $b%02dh $b%02dm $b%02ds", $value, $h, $m, $s); } } } return $ret; } private function formatNumber($value) { $parts = explode('.', $value, 2); if (count($parts) == 1) $dec = ''; else $dec = '.'.$this->endzero($parts[1]); $ret = number_format((float)$parts[0]).$dec; return $ret; } private function endzero($num) { $rep = preg_replace('/0*$/', '', $num); if ($rep === '') $rep = '0'; return $rep; } function update( $new_instance, $old_instance ) { $instance = $old_instance;
$instance['title'] = strip_tags( $new_instance['title'] ); $instance['ip'] = strip_tags( $new_instance['ip'] ); $instance['port'] = strip_tags( $new_instance['port'] ); $instance['show_info'] = $new_instance['show_info'];
return $instance; } function form( $instance ) {
$defaults = array( 'title' => __('My Miner', 'example'), 'ip' => __('127.0.0.1', 'example'), 'port' => 4028, 'show_info' => true ); $instance = wp_parse_args( (array) $instance, $defaults ); ?>
<p> <label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php _e('Title:', 'example'); ?></label> <input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo $instance['title']; ?>" style="width:100%;" /> </p>
<p> <label for="<?php echo $this->get_field_id( 'ip' ); ?>"><?php _e('IP Address:', 'example'); ?></label> <input id="<?php echo $this->get_field_id( 'ip' ); ?>" name="<?php echo $this->get_field_name( 'ip' ); ?>" value="<?php echo $instance['ip']; ?>" style="width:100%;" /> </p>
<p> <label for="<?php echo $this->get_field_id( 'port' ); ?>"><?php _e('Port:', 'example'); ?></label> <input id="<?php echo $this->get_field_id( 'port' ); ?>" name="<?php echo $this->get_field_name( 'port' ); ?>" value="<?php echo $instance['port']; ?>" style="width:100%;" /> </p>
<p> <input class="checkbox" type="checkbox" <?php checked( $instance['show_info'], true ); ?> id="<?php echo $this->get_field_id( 'show_info' ); ?>" name="<?php echo $this->get_field_name( 'show_info' ); ?>" /> <label for="<?php echo $this->get_field_id( 'show_info' ); ?>"> <?php _e('Display info publicly?', 'example'); ?></label> </p>
<?php } }
?> Installation: - Copy & Paste source code into a new file MinerWidget.php
- Place the file inside your WordPress installation folder under WORDPRESS_ROOT/wp-content/plugins/MinerWidget/
- Enable the widget from wordpress Plugins page, available in Dashboard
- Place and configure the widget from the widget page wherever you want
Enjoy it :)
|