Example #1
0
    def initStats(self):
        """Query and parse cgminer device api call."""

        self._statusDict = {}
        for port in self._ports:
            cgminer = CgminerAPI(self._host, int(port))
            self._statusDict[port] = cgminer.command('devs', None)['DEVS']
    def __init__(self):
        # Define supported algo
        self.algos = {}
        self.profitability_log = None
        self.__load_config()
        self.api = TradeMyBitAPI(self.api_key,
                                 'https://pool.trademybit.com/api/')
        self.cgminer = CgminerAPI(self.cgminer_host, self.cgminer_port)

        # We track state in a variable
        self.current_algo = None
Example #3
0
def FindActivePool(miner):
  a=CgminerAPI(miner["hostname"], miner["rpc_port"])
  pools=a.pools()["POOLS"]
  for i in range(0, len(pools)):
    try:
      if (pools[i]["Stratum Active"]==True):
        return pools[i]["Stratum URL"]
    except:
      pass
    # TODO: add checks for non-stratum servers
  return ""
Example #4
0
def CheckMiners(miners, accepted, rejected):  
  rtnval={}
  for i, miner in enumerate(miners):
    try:
      a=CgminerAPI(miners[miner]["hostname"], miners[miner]["rpc_port"])
      summary=a.summary()["SUMMARY"]
      if (accepted[miner]==summary[0]["Accepted"] and rejected[miner]==summary[0]["Rejected"] and accepted[miner]!=-1 and rejected[miner]!=-1):
        rtnval[miner]=FindActivePool(miners[miner])
      accepted[miner]=summary[0]["Accepted"]
      rejected[miner]=summary[0]["Rejected"]
    except:
      pass
  return rtnval
    def __init__(self):
        # Define supported algo
        self.algos = {}
        self.profitability_log = None
        self.__load_config()
        self.api = TradeMyBitAPI(self.api_key, 'https://pool.trademybit.com/api/')
        self.cgminer = CgminerAPI(self.cgminer_host, self.cgminer_port)

        # We track state in a variable
        self.current_algo = None
Example #6
0
def SwitchPool(hostname, port, pool_url, pool_worker, pool_passwd, clear=1):
  a=CgminerAPI(hostname, port)

  # add pool

  a.addpool(pool_url+","+pool_worker+","+pool_passwd)
  time.sleep(1)

  # wait for the connection

  live=0
  while (live==0):
    for i, pool in enumerate(a.pools()["POOLS"]):
      if (pool["URL"]==pool_url and pool["User"]==pool_worker):
        live=1
    if (live==0):
      time.sleep(1)

  # switch to new pool and find it 

  pools=a.pools()["POOLS"]
  delete_list=[]
  found=0
  for i, pool in enumerate(pools):
    if (pool["URL"]==pool_url and pool["User"]==pool_worker and found==0):
      found=1
      a.switchpool(pool["POOL"])
    else:
      delete_list.append(pool["POOL"])

  # remove other pool entries 

  if (clear==1):
    delete_list.sort(reverse=True)
    for i, num in enumerate(delete_list):
      a.removepool(num)
Example #7
0
 def __init__(self):
     self.api = CgminerAPI()
     self.config_path = os.path.dirname(os.path.realpath(__file__)) + '/config/cgminer'
Example #8
0
class Cgminer:

    def __init__(self):
        self.api = CgminerAPI()
        self.config_path = os.path.dirname(os.path.realpath(__file__)) + '/config/cgminer'

    def active(self):
        output = os.popen('ps x | grep cgminer').read()
        if re.search('config/cgminer', output):
            return True

        return False

    def start(self):
        subprocess.Popen(['cgminer', '-c', 'config/cgminer', '-T'], stdout=open('logs', 'w'))

    def stop(self):
        subprocess.Popen(['killall', 'cgminer'], stdout=subprocess.PIPE)

    def restart(self):
        self.stop()
        time.sleep(3)
        self.start()

    def devices(self):
        data = {}

        try:
            data['edevs'] = self.api.edevs()
        except Exception as e:
            raise CgminerError('Problem with API edevs method: ' + e.message)

        try:
            data['estats'] = self.api.estats()
        except Exception as e:
            raise CgminerError('Problem with API estats method: ' + e.message)

        result = []

        try:
            for i in xrange(0, len(data['edevs']['DEVS'])):
                dev = data['edevs']['DEVS'][i]
                stat = data['estats']['STATS'][i]

                result.append({
                    'id': dev['ID'],
                    'name': dev['Name'],
                    'mhs': dev['MHS 1m'],
                    'ghs': dev['MHS 1m'] / 1000,
                    'temperature': dev['Temperature'],
                    'accepted': dev['Accepted'],
                    'rejected': dev['Rejected'],
                    'clockrate': stat['base clockrate'],
                    'fan': stat['fan percent'],
                    'voltage': stat['Asic0 voltage 0']
                })
        except Exception as e:
            raise CgminerError('Problem with devices data preparing: ' + e.message)

        return result

    def summary(self):
        try:
            summary = self.api.summary()
        except Exception as e:
            raise CgminerError('Problem with API summary method: ' + e.message)

        try:
            pools = self.api.pools()
        except Exception as e:
            raise CgminerError('Problem with API pools method: ' + e.message)

        try:
            edevs = self.api.edevs()
        except Exception as e:
            raise CgminerError('Problem with API edevs method: ' + e.message)

        try:
            total = summary['SUMMARY'][0]['Accepted'] + summary['SUMMARY'][0]['Rejected']
            if total == 0:
                accepted_percent = 0
                rejected_percent = 0
            else:
                accepted_percent = int(summary['SUMMARY'][0]['Accepted'] / total * 100)
                rejected_percent = int(summary['SUMMARY'][0]['Rejected'] / total * 100)

            result = {
                'mhs': 0,
                'ghs': 0,
                'accepted': summary['SUMMARY'][0]['Accepted'],
                'rejected': summary['SUMMARY'][0]['Rejected'],
                'accepted_percent': accepted_percent,
                'rejected_percent': rejected_percent,
                'pool': {
                    'url': pools['POOLS'][0]['URL'],
                    'user': pools['POOLS'][0]['User']
                }
            }

            for edev in edevs['DEVS']:
                result['mhs'] += edev['MHS 1m']
                result['ghs'] += edev['MHS 1m'] / 1000
        except Exception as e:
            raise CgminerError('Problem with summary data preparing: ' + e.message)

        return result

    def pools(self):
        with open(self.config_path, 'r') as f:
            return json.loads(f.read())['pools']

    # TODO: catch exceptions
    def update_pools(self, pools):
        ordered_pools = sorted(pools, key=lambda pool: int(pool['priority']))

        with open(self.config_path, 'r') as f:
            config = json.loads(f.read())

        config['pools'] = ordered_pools

        with open(self.config_path, 'w') as f:
            json.dump(config, f)

    def clockrate(self):
        with open(self.config_path, 'r') as f:
            return json.loads(f.read())['hfa-hash-clock']

    def update_clockrate(self, clockrate):
        with open(self.config_path, 'r') as f:
            config = json.loads(f.read())

        config['hfa-hash-clock'] = clockrate

        with open(self.config_path, 'w') as f:
            json.dump(config, f)

    def fan_speed(self):
        with open(self.config_path, 'r') as f:
            config = json.loads(f.read())
            if 'hfa-fan' in config:
                return config['hfa-fan']
            else:
                return 'auto'

    def update_fan_speed(self, fan_speed):
        with open(self.config_path, 'r') as f:
            config = json.loads(f.read())

        if fan_speed == 'auto':
            if 'hfa-fan' in config:
                del config['hfa-fan']
        else:
            config['hfa-fan'] = fan_speed

        with open(self.config_path, 'w') as f:
            json.dump(config, f)

    def overheat(self):
        with open(self.config_path, 'r') as f:
            return json.loads(f.read())['hfa-temp-overheat']

    def update_overheat(self, overheat):
        with open(self.config_path, 'r') as f:
            config = json.loads(f.read())

        config['hfa-temp-overheat'] = overheat

        with open(self.config_path, 'w') as f:
            json.dump(config, f)

    def save(self):
        try:
            print self.api.save(self.config_path)
        except Exception as e:
            raise CgminerError('Problem with API save method: ' + e.message)

        return True

    def latest_hashrate_poins(self):
        points = []

        try:
            for edev in self.api.edevs()['DEVS']:
                points.append(edev['MHS 5m'] / 1000)
        except Exception as e:
            raise CgminerError('Problem with API edevs method: ' + e.message)

        return points
class TradeMyBitSwitcher(object):
    def __init__(self):
        # Define supported algo
        self.algos = {}
        self.algos['scrypt']  =  Algo('Scrypt')
        self.algos['nscrypt'] =  Algo('N-Scrypt')

        self.profitability_log = None
        self.__load_config()
        self.api = TradeMyBitAPI(self.api_key, 'https://pool.trademybit.com/api/')
        self.cgminer = CgminerAPI(self.cgminer_host, self.cgminer_port)

        # We track state in a variable
        self.current_algo = None

    def main(self):
        try:
            # cnt_all = 0
            # main loop
            print '-' * 72

            while True:
                # print header
                # self.logger.info("<<< Round %d >>>" % (cnt_all+1))

                # get data from sources
                self.logger.debug("Fetching data...")
                bestalgo = self.best_algo()

                self.logger.debug("=> Best: %s | Currently mining: %s" % (bestalgo, self.current_algo))

                if bestalgo != self.current_algo and bestalgo != None:
                    # i.e. if we're not already mining the best algo
                    self.switch_algo(bestalgo)

                elif self.current_algo == None:
                    # No miner running and profitability is similar, run the first algo
                    self.logger.warning('No miner running')
                    self.switch_algo(self.algos.keys()[0])

                # sleep
                self.logger.debug('Going to sleep for %dmin...' % self.idletime)
                i = 0
                while i < self.idletime*60:
                    time.sleep(1)
                    i += 1
        except KeyboardInterrupt:
            self.logger.warn('Caught KeyboardInterrupt, terminating...')
            self.cleanup()


    def cleanup(self):
        """Cleanup our mess"""
        if self.profitability_log:
            self.profitability_file.close()

        sys.exit()

    def best_algo(self):
        """Retrieves the "bestalgo" from TMB api"""
        try:
            data = self.api.bestalgo()
            # parse json data into variables
            algo1 = data[0]["algo"]
            score1 = float(data[0]["score"])
            algo2 = data[1]["algo"]
            score2 = float(data[1]["score"])

            self.logger.debug("%s : %f | %s: %f" % (algo1, score1, algo2, score2))

            # return result
            if (score2 - score1) / score1 > self.profitability_threshold:
                best = algo2
            elif (score1 - score2) / score2 > self.profitability_threshold:
                best = algo1
            else:
                best = None

            if self.profitability_log:
                self.profitability_log.writerow({'date': datetime.datetime.now(), algo1: score1, algo2: score2})
                self.profitability_file.flush()

            return best
        except (socket.error, KeyError):
            self.logger.warning('Cannot connect to TMB API...')
            return None

    # # Return scrypt/nscrypt based on the version of the miner running
    # # Temporarly disabled to support sgminer since we can't reliably determine
    # # if sgminer is mining nfactor 10 or 11
    # def current_algo(self):
    #     try:
    #         data = self.cgminer.version()
    #         version = data['STATUS'][0]['Description']
    #         if version.startswith('vertminer'): # vertminer 0.5.4pre1
    #             return 'nscrypt'
    #         elif version.startswith('cgminer'): # cgminer 3.7.2
    #             return 'scrypt'
    #         else:
    #             return None
    #     except:
    #         self.logger.warning('Cannot connect to miner API...')
    #         return None

    def switch_algo(self, algo):
        """Tells the current miner to exit and start the other one"""
        self.logger.info('=> Switching to %s (running %s)' % (algo, self.algos[algo].command))
        self.current_algo = algo
        try:
            self.cgminer.quit()
            time.sleep(self.switchtime) # Wait for it to quit / Or check the process id?
        except socket.error:
            pass # Cgminer not running

        try:
            subprocess.Popen(self.algos[algo].command)
        except OSError:
            self.logger.critical('Cannot execute [%s]!' % self.algos[algo].command)
            self.logger.critical('Make sure your miner startup scripts are executable before continuing.')
            sys.exit()

    def __prepare_logger(self, logging_config={}):
        """Configure the logger"""

        logfile = logging_config.get('logfile')

        # Set console log level based on the config
        if bool(logging_config.get('verbose')):
            log_level = logging.DEBUG
        else:
            log_level = logging.INFO

        # Prepare logger
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)

        ## Console logging
        
        # create console handler
        stream_handler = logging.StreamHandler()
        stream_handler.setLevel(log_level)

        # create formatter and add it to the handler
        formatter = logging.Formatter('%(asctime)s :: %(message)s', "%Y-%m-%d %H:%M:%S")
        stream_handler.setFormatter(formatter)

        # add the handler to the logger
        self.logger.addHandler(stream_handler)

        ## File logging

        if logfile:
            print "Logging to %s" % logfile
            # create file handler
            file_handler = logging.FileHandler(logfile, 'a')
            file_handler.setLevel(logging.DEBUG)

            formatter = logging.Formatter('%(asctime)s :: %(levelname)8s :: %(message)s', "%Y-%m-%d %H:%M:%S")
            file_handler.setFormatter(formatter)

            self.logger.addHandler(file_handler)

        csv_file = logging_config.get('profitability_log')
        if csv_file:
            self.__prepare_profitability_log(csv_file)

    def __prepare_profitability_log(self, csv_file):
        # Check if file is already present to know if we need to write the headers
        write_header = not(os.path.isfile(csv_file))

        self.profitability_file = open(csv_file, 'ab')

        self.profitability_log = csv.DictWriter(self.profitability_file, ['date', 'scrypt', 'nscrypt'])

        if write_header:
            self.profitability_log.writeheader()

    def __load_config(self):
        config_file =  'tmb-switcher.conf'
        #  Check if the config file is present
        if not(os.path.isfile(config_file)):
            print "ERROR: Configuration file not found!"
            print "Make sure the tmb-switcher.conf file is present!"
            sys.exit()

        # Load the config file
        config = ConfigParser.ConfigParser()
        config.read(config_file)

        # Read the logging settings and setup the logger
        logging_config = dict(config.items('Logging'))
        self.__prepare_logger(logging_config)

        # Read the settings or use default values
        try:
            self.api_key = config.get('TradeMyBit', 'apikey')
        except:
            self.logger.critical("Could not read apikey from config file")
            sys.exit()
        try:
            self.idletime = config.getint('Misc','idletime')
        except:
            self.logger.warning("Could not read idletime from config file. Defaulting to 5 min")
            self.idletime = 5
        try:
            self.switchtime = config.getint('Misc', 'switchtime')
        except:
            self.logger.warning("Could not read switchtime from config file. Defaulting to 1s")
            self.switchtime = 1
        try:
            self.profitability_threshold = config.getfloat('Misc','profitability_threshold')
        except:
            self.logger.warning("Could not read profitability_threshold from config file. Defaulting to 10%")
            self.profitability_threshold = 0.1
        try:
            self.cgminer_host = config.get('cgminer', 'host')
        except:
            self.logger.warning("Could not read cgminer host from config file. Defaulting to 127.0.0.1")
            self.cgminer_host = '127.0.0.1'
        try:
            self.cgminer_port = config.getint('cgminer', 'port')
        except:
            self.logger.warning("Could not read cgminer port from config file. Defaulting to 4028")
            self.cgminer_host = 4028

        for key in self.algos:
            try:
                script = config.get('Scripts', key)
                if os.path.isfile(script):
                    self.algos[key].command = script
                else:
                    self.logger.critical('Script for %s not found!' % key)
                    self.cleanup()
            except ConfigParser.NoOptionError :
                self.logger.warning('Script for %s not configured!' % key)
                continue
Example #10
0
import os
import json
from time import sleep

import paho.mqtt.client as mqtt
from pycgminer import CgminerAPI

cgminer = CgminerAPI(host=os.getenv('CGMINER_HOST'),
                     port=int(os.getenv('CGMINER_PORT')))


def on_connect(client, userdata, flags, rc):
    if rc == 0:
        print("Connected to broker " + os.getenv('MQTT_HOST') + ":" +
              os.getenv('MQTT_PORT'))
        global Connected  # Use global variable
        Connected = True  # Signal connection
    else:
        print("Connection failed")


client = mqtt.Client()
# Register connect callback
client.on_connect = on_connect
# Set access token
client.username_pw_set(os.getenv('MQTT_PASS'))
# Connect to ThingsBoard using default MQTT port and 60 seconds keepalive interval
client.connect(os.getenv('MQTT_HOST'), int(os.getenv('MQTT_PORT')), 60)

client.loop_start()  # start the loop
Example #11
0
from pycgminer import CgminerAPI

cgminer = CgminerAPI()

summary = cgminer.summary()

my_gpu0 = cgminer.gpu(0)
my_gpu1 = cgminer.gpu(1)

print my_gpu0

Example #12
0
from datetime import datetime
import requests

from pycgminer import CgminerAPI

from flask import Flask, jsonify
from flask.ext.cache import Cache

from flask_yeoman import flask_yeoman

cgminer = CgminerAPI()

app = Flask(__name__, static_folder='app')
cache = Cache(app, config={'CACHE_TYPE': 'filesystem', 'CACHE_DIR': '/tmp/'})

app.config.update(DEBUG=False)
app.config.from_pyfile('settings.cfg')
app.register_blueprint(flask_yeoman)


def _get_profile():
    """ Retrieve profile data from Slush's Pool API. """
    r = requests.get(
        'https://mining.bitcoin.cz/accounts/profile/json/{0}'.format(
            app.config['SLUSH_TOKEN']),
        verify=False)
    r.raise_for_status()
    profile = r.json()
    profile['total_reward'] = str(
        float(profile['confirmed_reward']) +
        float(profile['unconfirmed_reward']))
class TradeMyBitSwitcher(object):
    def __init__(self):
        # Define supported algo
        self.algos = {}
        self.algos['scrypt'] = Algo('Scrypt')
        self.algos['nscrypt'] = Algo('N-Scrypt')

        self.profitability_log = None
        self.__load_config()
        self.api = TradeMyBitAPI(self.api_key,
                                 'https://pool.trademybit.com/api/')
        self.cgminer = CgminerAPI(self.cgminer_host, self.cgminer_port)

        # We track state in a variable
        self.current_algo = None

    def main(self):
        try:
            # cnt_all = 0
            # main loop
            print '-' * 72

            while True:
                # print header
                # self.logger.info("<<< Round %d >>>" % (cnt_all+1))

                # get data from sources
                self.logger.debug("Fetching data...")
                bestalgo = self.best_algo()

                self.logger.debug("=> Best: %s | Currently mining: %s" %
                                  (bestalgo, self.current_algo))

                if bestalgo != self.current_algo and bestalgo != None:
                    # i.e. if we're not already mining the best algo
                    self.switch_algo(bestalgo)

                elif self.current_algo == None:
                    # No miner running and profitability is similar, run the first algo
                    self.logger.warning('No miner running')
                    self.switch_algo(self.algos.keys()[0])

                # sleep
                self.logger.debug('Going to sleep for %dmin...' %
                                  self.idletime)
                i = 0
                while i < self.idletime * 60:
                    time.sleep(1)
                    i += 1
        except KeyboardInterrupt:
            self.logger.warn('Caught KeyboardInterrupt, terminating...')
            self.cleanup()

    def cleanup(self):
        """Cleanup our mess"""
        if self.profitability_log:
            self.profitability_file.close()

        sys.exit()

    def best_algo(self):
        """Retrieves the "bestalgo" from TMB api"""
        try:
            data = self.api.bestalgo()
            # parse json data into variables
            algo1 = data[0]["algo"]
            score1 = float(data[0]["score"])
            algo2 = data[1]["algo"]
            score2 = float(data[1]["score"])

            self.logger.debug("%s : %f | %s: %f" %
                              (algo1, score1, algo2, score2))

            # return result
            if (score2 - score1) / score1 > self.profitability_threshold:
                best = algo2
            elif (score1 - score2) / score2 > self.profitability_threshold:
                best = algo1
            else:
                best = None

            if self.profitability_log:
                self.profitability_log.writerow({
                    'date': datetime.datetime.now(),
                    algo1: score1,
                    algo2: score2
                })
                self.profitability_file.flush()

            return best
        except (socket.error, KeyError):
            self.logger.warning('Cannot connect to TMB API...')
            return None

    # # Return scrypt/nscrypt based on the version of the miner running
    # # Temporarly disabled to support sgminer since we can't reliably determine
    # # if sgminer is mining nfactor 10 or 11
    # def current_algo(self):
    #     try:
    #         data = self.cgminer.version()
    #         version = data['STATUS'][0]['Description']
    #         if version.startswith('vertminer'): # vertminer 0.5.4pre1
    #             return 'nscrypt'
    #         elif version.startswith('cgminer'): # cgminer 3.7.2
    #             return 'scrypt'
    #         else:
    #             return None
    #     except:
    #         self.logger.warning('Cannot connect to miner API...')
    #         return None

    def switch_algo(self, algo):
        """Tells the current miner to exit and start the other one"""
        self.logger.info('=> Switching to %s (running %s)' %
                         (algo, self.algos[algo].command))
        self.current_algo = algo
        try:
            self.cgminer.quit()
            time.sleep(self.switchtime
                       )  # Wait for it to quit / Or check the process id?
        except socket.error:
            pass  # Cgminer not running

        try:
            subprocess.Popen(self.algos[algo].command)
        except OSError:
            self.logger.critical('Cannot execute [%s]!' %
                                 self.algos[algo].command)
            self.logger.critical(
                'Make sure your miner startup scripts are executable before continuing.'
            )
            sys.exit()

    def __prepare_logger(self, logging_config={}):
        """Configure the logger"""

        logfile = logging_config.get('logfile')

        # Set console log level based on the config
        if bool(logging_config.get('verbose')):
            log_level = logging.DEBUG
        else:
            log_level = logging.INFO

        # Prepare logger
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)

        ## Console logging

        # create console handler
        stream_handler = logging.StreamHandler()
        stream_handler.setLevel(log_level)

        # create formatter and add it to the handler
        formatter = logging.Formatter('%(asctime)s :: %(message)s',
                                      "%Y-%m-%d %H:%M:%S")
        stream_handler.setFormatter(formatter)

        # add the handler to the logger
        self.logger.addHandler(stream_handler)

        ## File logging

        if logfile:
            print "Logging to %s" % logfile
            # create file handler
            file_handler = logging.FileHandler(logfile, 'a')
            file_handler.setLevel(logging.DEBUG)

            formatter = logging.Formatter(
                '%(asctime)s :: %(levelname)8s :: %(message)s',
                "%Y-%m-%d %H:%M:%S")
            file_handler.setFormatter(formatter)

            self.logger.addHandler(file_handler)

        csv_file = logging_config.get('profitability_log')
        if csv_file:
            self.__prepare_profitability_log(csv_file)

    def __prepare_profitability_log(self, csv_file):
        # Check if file is already present to know if we need to write the headers
        write_header = not (os.path.isfile(csv_file))

        self.profitability_file = open(csv_file, 'ab')

        self.profitability_log = csv.DictWriter(self.profitability_file,
                                                ['date', 'scrypt', 'nscrypt'])

        if write_header:
            self.profitability_log.writeheader()

    def __load_config(self):
        config_file = 'tmb-switcher.conf'
        #  Check if the config file is present
        if not (os.path.isfile(config_file)):
            print "ERROR: Configuration file not found!"
            print "Make sure the tmb-switcher.conf file is present!"
            sys.exit()

        # Load the config file
        config = ConfigParser.ConfigParser()
        config.read(config_file)

        # Read the logging settings and setup the logger
        logging_config = dict(config.items('Logging'))
        self.__prepare_logger(logging_config)

        # Read the settings or use default values
        try:
            self.api_key = config.get('TradeMyBit', 'apikey')
        except:
            self.logger.critical("Could not read apikey from config file")
            sys.exit()
        try:
            self.idletime = config.getint('Misc', 'idletime')
        except:
            self.logger.warning(
                "Could not read idletime from config file. Defaulting to 5 min"
            )
            self.idletime = 5
        try:
            self.switchtime = config.getint('Misc', 'switchtime')
        except:
            self.logger.warning(
                "Could not read switchtime from config file. Defaulting to 1s")
            self.switchtime = 1
        try:
            self.profitability_threshold = config.getfloat(
                'Misc', 'profitability_threshold')
        except:
            self.logger.warning(
                "Could not read profitability_threshold from config file. Defaulting to 10%"
            )
            self.profitability_threshold = 0.1
        try:
            self.cgminer_host = config.get('cgminer', 'host')
        except:
            self.logger.warning(
                "Could not read cgminer host from config file. Defaulting to 127.0.0.1"
            )
            self.cgminer_host = '127.0.0.1'
        try:
            self.cgminer_port = config.getint('cgminer', 'port')
        except:
            self.logger.warning(
                "Could not read cgminer port from config file. Defaulting to 4028"
            )
            self.cgminer_host = 4028

        for key in self.algos:
            try:
                script = config.get('Scripts', key)
                if os.path.isfile(script):
                    self.algos[key].command = script
                else:
                    self.logger.critical('Script for %s not found!' % key)
                    self.cleanup()
            except ConfigParser.NoOptionError:
                self.logger.warning('Script for %s not configured!' % key)
                continue
Example #14
0
class Cgminer:
    def __init__(self):
        self.api = CgminerAPI()
        self.config_path = os.path.dirname(
            os.path.realpath(__file__)) + '/config/cgminer'

    def active(self):
        output = os.popen('ps x | grep cgminer').read()
        if re.search('config/cgminer', output):
            return True

        return False

    def start(self):
        subprocess.Popen(['cgminer', '-c', 'config/cgminer', '-T'],
                         stdout=open('logs', 'w'))

    def stop(self):
        subprocess.Popen(['killall', 'cgminer'], stdout=subprocess.PIPE)

    def restart(self):
        self.stop()
        time.sleep(3)
        self.start()

    def devices(self):
        data = {}

        try:
            data['edevs'] = self.api.edevs()
        except Exception as e:
            raise CgminerError('Problem with API edevs method: ' + e.message)

        try:
            data['estats'] = self.api.estats()
        except Exception as e:
            raise CgminerError('Problem with API estats method: ' + e.message)

        result = []

        try:
            for i in xrange(0, len(data['edevs']['DEVS'])):
                dev = data['edevs']['DEVS'][i]
                stat = data['estats']['STATS'][i]

                result.append({
                    'id': dev['ID'],
                    'name': dev['Name'],
                    'mhs': dev['MHS 1m'],
                    'ghs': dev['MHS 1m'] / 1000,
                    'temperature': dev['Temperature'],
                    'accepted': dev['Accepted'],
                    'rejected': dev['Rejected'],
                    'clockrate': stat['base clockrate'],
                    'fan': stat['fan percent'],
                    'voltage': stat['Asic0 voltage 0']
                })
        except Exception as e:
            raise CgminerError('Problem with devices data preparing: ' +
                               e.message)

        return result

    def summary(self):
        try:
            summary = self.api.summary()
        except Exception as e:
            raise CgminerError('Problem with API summary method: ' + e.message)

        try:
            pools = self.api.pools()
        except Exception as e:
            raise CgminerError('Problem with API pools method: ' + e.message)

        try:
            edevs = self.api.edevs()
        except Exception as e:
            raise CgminerError('Problem with API edevs method: ' + e.message)

        try:
            total = summary['SUMMARY'][0]['Accepted'] + summary['SUMMARY'][0][
                'Rejected']
            if total == 0:
                accepted_percent = 0
                rejected_percent = 0
            else:
                accepted_percent = int(summary['SUMMARY'][0]['Accepted'] /
                                       total * 100)
                rejected_percent = int(summary['SUMMARY'][0]['Rejected'] /
                                       total * 100)

            result = {
                'mhs': 0,
                'ghs': 0,
                'accepted': summary['SUMMARY'][0]['Accepted'],
                'rejected': summary['SUMMARY'][0]['Rejected'],
                'accepted_percent': accepted_percent,
                'rejected_percent': rejected_percent,
                'pool': {
                    'url': pools['POOLS'][0]['URL'],
                    'user': pools['POOLS'][0]['User']
                }
            }

            for edev in edevs['DEVS']:
                result['mhs'] += edev['MHS 1m']
                result['ghs'] += edev['MHS 1m'] / 1000
        except Exception as e:
            raise CgminerError('Problem with summary data preparing: ' +
                               e.message)

        return result

    def pools(self):
        with open(self.config_path, 'r') as f:
            return json.loads(f.read())['pools']

    # TODO: catch exceptions
    def update_pools(self, pools):
        ordered_pools = sorted(pools, key=lambda pool: int(pool['priority']))

        with open(self.config_path, 'r') as f:
            config = json.loads(f.read())

        config['pools'] = ordered_pools

        with open(self.config_path, 'w') as f:
            json.dump(config, f)

    def clockrate(self):
        with open(self.config_path, 'r') as f:
            return json.loads(f.read())['hfa-hash-clock']

    def update_clockrate(self, clockrate):
        with open(self.config_path, 'r') as f:
            config = json.loads(f.read())

        config['hfa-hash-clock'] = clockrate

        with open(self.config_path, 'w') as f:
            json.dump(config, f)

    def fan_speed(self):
        with open(self.config_path, 'r') as f:
            config = json.loads(f.read())
            if 'hfa-fan' in config:
                return config['hfa-fan']
            else:
                return 'auto'

    def update_fan_speed(self, fan_speed):
        with open(self.config_path, 'r') as f:
            config = json.loads(f.read())

        if fan_speed == 'auto':
            if 'hfa-fan' in config:
                del config['hfa-fan']
        else:
            config['hfa-fan'] = fan_speed

        with open(self.config_path, 'w') as f:
            json.dump(config, f)

    def overheat(self):
        with open(self.config_path, 'r') as f:
            return json.loads(f.read())['hfa-temp-overheat']

    def update_overheat(self, overheat):
        with open(self.config_path, 'r') as f:
            config = json.loads(f.read())

        config['hfa-temp-overheat'] = overheat

        with open(self.config_path, 'w') as f:
            json.dump(config, f)

    def save(self):
        try:
            print self.api.save(self.config_path)
        except Exception as e:
            raise CgminerError('Problem with API save method: ' + e.message)

        return True

    def latest_hashrate_poins(self):
        points = []

        try:
            for edev in self.api.edevs()['DEVS']:
                points.append(edev['MHS 5m'] / 1000)
        except Exception as e:
            raise CgminerError('Problem with API edevs method: ' + e.message)

        return points
from pycgminer import CgminerAPI
import time,urllib2,json,simplejson,datetime

cgminer = CgminerAPI()

summary = cgminer.summary()

gpu0 = cgminer.gpu(0)
gpu1 = cgminer.gpu(1)

#print summary

#print my_gpu0
#print my_gpu1

gpu0_temp = json.dumps(gpu0)
gpu1_temp = json.dumps(gpu1)

gpu0_parsed_json = json.loads(gpu0_temp)
gpu1_parsed_json = json.loads(gpu1_temp)


#gpu0_temperature = gpu0_parsed_json['GPU']['Temperature']
#gpu0_fan_speed = gpu0_parsed_json['GPU']['Fan_Speed']
gpu0_parsed_json_gpu = gpu0_parsed_json['GPU'][0]
gpu0_temperature = gpu0_parsed_json_gpu[u'Temperature']
gpu0_fan_speed = gpu0_parsed_json_gpu[u'Fan Speed']
gpu0_fan_percent = gpu0_parsed_json_gpu[u'Fan Percent']
gpu0_rejected = gpu0_parsed_json_gpu[u'Rejected']
gpu0_accepted = gpu0_parsed_json_gpu[u'Accepted']
gpu0_hw_errors = gpu0_parsed_json_gpu[u'Hardware Errors']
class TradeMyBitSwitcher(object):
    def __init__(self):
        # Define supported algo
        self.algos = {}
        self.profitability_log = None
        self.__load_config()
        self.api = TradeMyBitAPI(self.api_key, 'https://pool.trademybit.com/api/')
        self.cgminer = CgminerAPI(self.cgminer_host, self.cgminer_port)

        # We track state in a variable
        self.current_algo = None

    def main(self):
        try:
            print '-' * 72
            while True:

                # get data from sources
                self.logger.debug("Fetching data...")
                bestalgo = self.best_algo()

                self.logger.debug("=> Best: %s | Currently mining: %s" % (bestalgo, self.current_algo))

                if bestalgo != self.current_algo and bestalgo != None:
                    # i.e. if we're not already mining the best algo
                    self.switch_algo(bestalgo)

                elif self.current_algo == None:
                    # TODO: useless?
                    # No miner running and profitability is similar, run the first algo
                    self.logger.warning('No miner running')
                    self.switch_algo(self.algos.keys()[0])

                # sleep
                self.logger.debug('Going to sleep for %d min...' % self.idletime)
                i = 0
                while i < self.idletime * 60:
                    time.sleep(1)
                    i += 1
        except KeyboardInterrupt:
            self.logger.warn('Caught KeyboardInterrupt, terminating...')
            self.cleanup()


    def cleanup(self):
        """Cleanup our mess"""
        if self.profitability_log:
            self.profitability_file.close()

        sys.exit()

    def best_algo(self):
        """Retrieves the "bestalgo" from TMB api"""
        
        data_dict = {}            
        algolist = []

        try:
            data = self.api.bestalgo()

            # parse json data into variables
            scores = {}
            logString = []
            for algo in data:
                logString.append("%s : %f" % (algo['algo'], float(algo['score'])))
                if self.algos.has_key(algo['algo']):
                  scores[algo['algo']] = float(algo['score'])

            self.logger.debug(' | '.join(logString))

            # Problem with the API, scores is empty.
            if not bool(scores):
                return None

            # return result
            best_algo = max(scores.iterkeys(), key=(lambda key: scores[key]))

            # Switch if not yet mining or we're crossing the threshold
            if (self.current_algo == None) or \
                (self.current_algo == best_algo) or \
                (((scores[best_algo] - scores[self.current_algo]) / scores[self.current_algo]) > self.profitability_threshold):
                best = best_algo
            else:
                best = None

            if self.profitability_log:
                scores['date'] = datetime.datetime.now()
                self.profitability_log.writerow(scores)
                self.profitability_file.flush()

            return best

        except (socket.error, KeyError):
            self.logger.warning('Cannot connect to TMB API...')
            return None
        except IndexError:
            self.logger.warning('Empty TMB API resultset...')
            return None

    def switch_algo(self, algo):
        """Tells the current miner to exit and start the other one"""
        self.logger.info('=> Switching to %s (running %s)' % (algo, self.algos[algo].command))
        self.current_algo = algo
        try:
            self.cgminer.quit()
            time.sleep(self.switchtime)  # Wait for it to quit / Or check the process id?
        except socket.error:
            pass  # Cgminer not running

        try:
            subprocess.Popen(self.algos[algo].command)
        except OSError:
            self.logger.critical('Cannot execute [%s]!' % self.algos[algo].command)
            self.logger.critical('Make sure your miner startup scripts are executable before continuing.')
            sys.exit()

    def __prepare_logger(self, logging_config={}):
        """Configure the logger"""

        logfile = logging_config.get('logfile')

        # Set console log level based on the config
        if bool(logging_config.get('verbose')):
            log_level = logging.DEBUG
        else:
            log_level = logging.INFO

        # Prepare logger
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)

        ## Console logging

        # create console handler
        stream_handler = logging.StreamHandler()
        stream_handler.setLevel(log_level)

        # create formatter and add it to the handler
        formatter = logging.Formatter('%(asctime)s :: %(message)s', "%Y-%m-%d %H:%M:%S")
        stream_handler.setFormatter(formatter)

        # add the handler to the logger
        self.logger.addHandler(stream_handler)

        # # File logging

        if logfile:
            print "Logging to %s" % logfile
            # create file handler
            file_handler = logging.FileHandler(logfile, 'a')
            file_handler.setLevel(logging.DEBUG)

            formatter = logging.Formatter('%(asctime)s :: %(levelname)8s :: %(message)s', "%Y-%m-%d %H:%M:%S")
            file_handler.setFormatter(formatter)

            self.logger.addHandler(file_handler)

    def __prepare_profitability_log(self, csv_file):
        # Check if file is already present to know if we need to write the headers
        
        if os.path.isfile(csv_file):
            os.rename(csv_file, 'profitability-' + time.strftime("%Y%m%d-%H%M%S") + ".csv")
#         write_header = not(os.path.isfile(csv_file))

        self.profitability_file = open(csv_file, 'ab')
        
        csv_header = ['date']
        for algo in self.algos:
            csv_header.append(algo)

        self.profitability_log = csv.DictWriter(self.profitability_file, ['date'] + self.algos.keys())

#         if write_header:
        self.profitability_log.writeheader()

    def __load_config(self):
        config_file = 'tmb-switcher.conf'
        #  Check if the config file is present
        if not(os.path.isfile(config_file)):
            print "ERROR: Configuration file not found!"
            print "Make sure the tmb-switcher.conf file is present!"
            sys.exit()

        # Load the config file
        config = ConfigParser.ConfigParser()
        config.read(config_file)
        
        # Read the logging settings and setup the logger
        logging_config = dict(config.items('Logging'))
        self.__prepare_logger(logging_config)

        # Read the settings or use default values
        try:
            self.api_key = config.get('TradeMyBit', 'apikey')
        except:
            self.logger.critical("Could not read apikey from config file")
            sys.exit()
        try:
            self.idletime = config.getint('Misc', 'idletime')
        except:
            self.logger.warning("Could not read idletime from config file. Defaulting to 5 min")
            self.idletime = 5
        try:
            self.switchtime = config.getint('Misc', 'switchtime')
        except:
            self.logger.warning("Could not read switchtime from config file. Defaulting to 1s")
            self.switchtime = 1
        try:
            self.profitability_threshold = config.getfloat('Misc', 'profitability_threshold')
        except:
            self.logger.warning("Could not read profitability_threshold from config file. Defaulting to 10%")
            self.profitability_threshold = 0.1
        try:
            self.cgminer_host = config.get('cgminer', 'host')
        except:
            self.logger.warning("Could not read cgminer host from config file. Defaulting to 127.0.0.1")
            self.cgminer_host = '127.0.0.1'
        try:
            self.cgminer_port = config.getint('cgminer', 'port')
        except:
            self.logger.warning("Could not read cgminer port from config file. Defaulting to 4028")
            self.cgminer_host = 4028

        for key in dict(config.items('Scripts')):
            try:
                script = config.get('Scripts', key)
                if os.path.isfile(script):
                    self.algos[key] = Algo(key)
                    self.algos[key].command = script
                else:
                    self.logger.critical('Script for %s not found!' % key)
                    self.cleanup()
            except ConfigParser.NoOptionError :
                self.logger.warning('Script for %s not configured!' % key)
                continue

        self.logger.debug("Enabled algorithms: %s" % ', '.join(self.algos.keys()))
        if not self.algos:
            self.logger.critical('No mining algorithms enabled!')
            sys.exit()

        csv_file = logging_config.get('profitability_log')
        if csv_file:
            self.__prepare_profitability_log(csv_file)
Example #17
0
class Cgminer:

    def __init__(self):
        self.api = CgminerAPI()

    def devices(self):
        data = {}

        try:
            data['edevs'] = self.api.edevs()
        except Exception as e:
            raise CgminerError('Problem with API edevs method: ' + e.message)

        try:
            data['estats'] = self.api.estats()
        except Exception as e:
            raise CgminerError('Problem with API estats method: ' + e.message)

        result = []

        try:
            for i in xrange(0, len(data['edevs']['DEVS'])):
                dev = data['edevs']['DEVS'][i]
                stat = data['estats']['STATS'][i]

                result.append({
                    'id': dev['ID'],
                    'name': dev['Name'],
                    'mhs': dev['MHS 5m'],
                    'ghs': dev['MHS 5m'] / 1000,
                    'temperature': dev['Temperature'],
                    'accepted': dev['Accepted'],
                    'rejected': dev['Rejected'],
                    'clockrate': stat['base clockrate'],
                    'fan': stat['fan percent'],
                    'voltage': stat['Asic0 voltage 0']
                })
        except Exception as e:
            raise CgminerError('Problem with devices data preparing: ' + e.message)

        return result

    def summary(self):
        try:
            summary = self.api.summary()
        except Exception as e:
            raise CgminerError('Problem with API summary method: ' + e.message)

        try:
            pools = self.api.pools()
        except Exception as e:
            raise CgminerError('Problem with API pools method: ' + e.message)

        try:
            total = summary['SUMMARY'][0]['Accepted'] + summary['SUMMARY'][0]['Rejected']
            accepted_percent = int(summary['SUMMARY'][0]['Accepted'] / total * 100)
            rejected_percent = int(summary['SUMMARY'][0]['Rejected'] / total * 100)

            result = {
                'mhs': summary['SUMMARY'][0]['MHS 5m'],
                'ghs': summary['SUMMARY'][0]['MHS 5m'] / 1000,
                'accepted': summary['SUMMARY'][0]['Accepted'],
                'rejected': summary['SUMMARY'][0]['Rejected'],
                'accepted_percent': accepted_percent,
                'rejected_percent': rejected_percent,
                'pool': {
                    'url': pools['POOLS'][0]['URL'],
                    'user': pools['POOLS'][0]['User']
                }
            }
        except Exception as e:
            raise CgminerError('Problem with preparing data: ' + e.message)

        return result

    def save(self, file_path):
        try:
            print self.api.save(file_path)
        except Exception as e:
            raise CgminerError('Problem with API save method: ' + e.message)

        return True

    def latest_hashrate_poins(self):
        points = []

        try:
            for edev in self.api.edevs()['DEVS']:
                points.append(edev['MHS 5m'] / 1000)
        except Exception as e:
            raise CgminerError('Problem with API edevs method: ' + e.message)

        return points
#!/usr/bin/python

import json
import urllib
from pycgminer import CgminerAPI

LTC_TIMEOUT = 10800
TAG_TIMEOUT = 900

cgminer = CgminerAPI()

tag_hash_faster_link = 'http://tag.hashfaster.com/index.php?page=api&action=gettimesincelastblock&api_key=29c14a879e901f304a82fa5b97735b7c0032638cce8e3bd54e6d9e7bf8f8e9e6&id=488'
ltc_hash_faster_link = 'http://ltc.hashfaster.com/index.php?page=api&action=gettimesincelastblock&api_key=40a66486837fd754d275475eefcf6d4bac86e8928cc2312ac34c55cc4e824440&id=1305'

f = urllib.urlopen(tag_hash_faster_link)
tag_hash_faster_json = f.read()
f = urllib.urlopen(ltc_hash_faster_link)
ltc_hash_faster_json = f.read()

decoded_tag = json.loads(tag_hash_faster_json)
decoded_ltc = json.loads(ltc_hash_faster_json)

tag_time = decoded_tag['gettimesincelastblock']['data']
ltc_time = decoded_ltc['gettimesincelastblock']

if ltc_time < LTC_TIMEOUT:
        print cgminer.switchpool(0)
elif tag_time < TAG_TIMEOUT:
        print cgminer.switchpool(5)
else:
        print cgminer.switchpool(1)
Example #19
0
 def __init__(self, config):
     self.config = config
     self.cgminer = CgminerAPI(config['cgminer']['host'], config['cgminer']['port'])
     self.coinwarz = CoinwarzAPI(config['coinwarz'])
     self.cryptsy = CryptsyAPI(config['cryptsy'])
     self.hashrate = self.config['hashrate']
Example #20
0
class CPC(object):
    def __init__(self, config):
        self.config = config
        self.cgminer = CgminerAPI(config['cgminer']['host'], config['cgminer']['port'])
        self.coinwarz = CoinwarzAPI(config['coinwarz'])
        self.cryptsy = CryptsyAPI(config['cryptsy'])
        self.hashrate = self.config['hashrate']

    def restart_cgminer(self):
        logger.info('Restarting CGMiner...')
        try:
            self.cgminer.restart()
        except ValueError:
            pass
        while True:
            try:
                self.cgminer.version()
            except socket.error:
                time.sleep(1)
            else:
                break
        logger.info('CGMiner restarted')

    def cgminer_pools(self):
        pools = []
        for pool in self.cgminer.pools()['POOLS']:
            currency = self.config['pool_currency'].get(pool['URL'])
            if pool['Status'] != 'Alive':
                logger.warning('Pool %s status is %s', pool['URL'], pool['Status'])
            if not currency:
                logger.error('Unknown currency for pool %s', pool['URL'])
                continue
            pool['Currency'] = currency
            pools.append(pool)
        return pools

    def get_currencies(self):
        currencies = {}
        btc_price = None
        price_data = self.cryptsy.get_data()['return']['markets']
        difficulty_data = self.coinwarz.get_data()['Data']

        for label, currency_price_data in price_data.items():
            if currency_price_data['secondarycode'] != 'BTC':
                continue
            currency_data = currencies[currency_price_data['primarycode']] = {}
            currency_data['id'] = currency_price_data['primarycode']
            currency_data['name'] = currency_price_data['primaryname']
            currency_data['price'] = float(currency_price_data['lasttradeprice'])
            currency_data['exchange_volume'] = float(currency_price_data['volume'])

        for currency_difficulty_data in difficulty_data:
            currency = currency_difficulty_data['CoinTag']
            if currency == 'BTC':
                btc_price = currency_difficulty_data['ExchangeRate']
                continue
            if currency not in currencies:
                continue
            currency_data = currencies[currency]
            currency_data['profit_growth'] = currency_difficulty_data['ProfitRatio'] / currency_difficulty_data['AvgProfitRatio']
            currency_data['difficulty'] = currency_difficulty_data['Difficulty']
            currency_data['block_reward'] = currency_difficulty_data['BlockReward']
            currency_data['coins_per_day'] = 86400 * self.hashrate * currency_data['block_reward'] / (currency_data['difficulty'] * 2 ** 32)

        currencies = {k: v for k, v in currencies.iteritems() if 'coins_per_day' in v}

        for currency_data in currencies.values():
            currency_data['usd_per_day'] = currency_data['coins_per_day'] * currency_data['price'] * btc_price
            currency_data['rating'] = RatingCalculator.rate_currency(currency_data)

        return currencies
class TradeMyBitSwitcher(object):
    def __init__(self):
        # Define supported algo
        self.algos = {}
        self.profitability_log = None
        self.__load_config()
        self.api = TradeMyBitAPI(self.api_key,
                                 'https://pool.trademybit.com/api/')
        self.cgminer = CgminerAPI(self.cgminer_host, self.cgminer_port)

        # We track state in a variable
        self.current_algo = None

    def main(self):
        try:
            print '-' * 72
            while True:

                # get data from sources
                self.logger.debug("Fetching data...")
                bestalgo = self.best_algo()

                self.logger.debug("=> Best: %s | Currently mining: %s" %
                                  (bestalgo, self.current_algo))

                if bestalgo != self.current_algo and bestalgo != None:
                    # i.e. if we're not already mining the best algo
                    self.switch_algo(bestalgo)

                elif self.current_algo == None:
                    # TODO: useless?
                    # No miner running and profitability is similar, run the first algo
                    self.logger.warning('No miner running')
                    self.switch_algo(self.algos.keys()[0])

                # sleep
                self.logger.debug('Going to sleep for %d min...' %
                                  self.idletime)
                i = 0
                while i < self.idletime * 60:
                    time.sleep(1)
                    i += 1
        except KeyboardInterrupt:
            self.logger.warn('Caught KeyboardInterrupt, terminating...')
            self.cleanup()

    def cleanup(self):
        """Cleanup our mess"""
        if self.profitability_log:
            self.profitability_file.close()

        sys.exit()

    def best_algo(self):
        """Retrieves the "bestalgo" from TMB api"""

        data_dict = {}
        algolist = []

        try:
            data = self.api.bestalgo()

            # parse json data into variables
            scores = {}
            logString = []
            for algo in data:
                logString.append("%s : %f" %
                                 (algo['algo'], float(algo['score'])))
                if self.algos.has_key(algo['algo']):
                    scores[algo['algo']] = float(algo['score'])

            self.logger.debug(' | '.join(logString))

            # Problem with the API, scores is empty.
            if not bool(scores):
                return None

            # return result
            best_algo = max(scores.iterkeys(), key=(lambda key: scores[key]))

            # Switch if not yet mining or we're crossing the threshold
            if (self.current_algo == None) or \
                (self.current_algo == best_algo) or \
                (((scores[best_algo] - scores[self.current_algo]) / scores[self.current_algo]) > self.profitability_threshold):
                best = best_algo
            else:
                best = None

            if self.profitability_log:
                scores['date'] = datetime.datetime.now()
                self.profitability_log.writerow(scores)
                self.profitability_file.flush()

            return best

        except (socket.error, KeyError):
            self.logger.warning('Cannot connect to TMB API...')
            return None
        except IndexError:
            self.logger.warning('Empty TMB API resultset...')
            return None

    def switch_algo(self, algo):
        """Tells the current miner to exit and start the other one"""
        self.logger.info('=> Switching to %s (running %s)' %
                         (algo, self.algos[algo].command))
        self.current_algo = algo
        try:
            self.cgminer.quit()
            time.sleep(self.switchtime
                       )  # Wait for it to quit / Or check the process id?
        except socket.error:
            pass  # Cgminer not running

        try:
            subprocess.Popen(self.algos[algo].command)
        except OSError:
            self.logger.critical('Cannot execute [%s]!' %
                                 self.algos[algo].command)
            self.logger.critical(
                'Make sure your miner startup scripts are executable before continuing.'
            )
            sys.exit()

    def __prepare_logger(self, logging_config={}):
        """Configure the logger"""

        logfile = logging_config.get('logfile')

        # Set console log level based on the config
        if bool(logging_config.get('verbose')):
            log_level = logging.DEBUG
        else:
            log_level = logging.INFO

        # Prepare logger
        self.logger = logging.getLogger()
        self.logger.setLevel(logging.DEBUG)

        ## Console logging

        # create console handler
        stream_handler = logging.StreamHandler()
        stream_handler.setLevel(log_level)

        # create formatter and add it to the handler
        formatter = logging.Formatter('%(asctime)s :: %(message)s',
                                      "%Y-%m-%d %H:%M:%S")
        stream_handler.setFormatter(formatter)

        # add the handler to the logger
        self.logger.addHandler(stream_handler)

        # # File logging

        if logfile:
            print "Logging to %s" % logfile
            # create file handler
            file_handler = logging.FileHandler(logfile, 'a')
            file_handler.setLevel(logging.DEBUG)

            formatter = logging.Formatter(
                '%(asctime)s :: %(levelname)8s :: %(message)s',
                "%Y-%m-%d %H:%M:%S")
            file_handler.setFormatter(formatter)

            self.logger.addHandler(file_handler)

    def __prepare_profitability_log(self, csv_file):
        # Check if file is already present to know if we need to write the headers

        if os.path.isfile(csv_file):
            os.rename(
                csv_file,
                'profitability-' + time.strftime("%Y%m%d-%H%M%S") + ".csv")


#         write_header = not(os.path.isfile(csv_file))

        self.profitability_file = open(csv_file, 'ab')

        csv_header = ['date']
        for algo in self.algos:
            csv_header.append(algo)

        self.profitability_log = csv.DictWriter(self.profitability_file,
                                                ['date'] + self.algos.keys())

        #         if write_header:
        self.profitability_log.writeheader()

    def __load_config(self):
        config_file = 'tmb-switcher.conf'
        #  Check if the config file is present
        if not (os.path.isfile(config_file)):
            print "ERROR: Configuration file not found!"
            print "Make sure the tmb-switcher.conf file is present!"
            sys.exit()

        # Load the config file
        config = ConfigParser.ConfigParser()
        config.read(config_file)

        # Read the logging settings and setup the logger
        logging_config = dict(config.items('Logging'))
        self.__prepare_logger(logging_config)

        # Read the settings or use default values
        try:
            self.api_key = config.get('TradeMyBit', 'apikey')
        except:
            self.logger.critical("Could not read apikey from config file")
            sys.exit()
        try:
            self.idletime = config.getint('Misc', 'idletime')
        except:
            self.logger.warning(
                "Could not read idletime from config file. Defaulting to 5 min"
            )
            self.idletime = 5
        try:
            self.switchtime = config.getint('Misc', 'switchtime')
        except:
            self.logger.warning(
                "Could not read switchtime from config file. Defaulting to 1s")
            self.switchtime = 1
        try:
            self.profitability_threshold = config.getfloat(
                'Misc', 'profitability_threshold')
        except:
            self.logger.warning(
                "Could not read profitability_threshold from config file. Defaulting to 10%"
            )
            self.profitability_threshold = 0.1
        try:
            self.cgminer_host = config.get('cgminer', 'host')
        except:
            self.logger.warning(
                "Could not read cgminer host from config file. Defaulting to 127.0.0.1"
            )
            self.cgminer_host = '127.0.0.1'
        try:
            self.cgminer_port = config.getint('cgminer', 'port')
        except:
            self.logger.warning(
                "Could not read cgminer port from config file. Defaulting to 4028"
            )
            self.cgminer_host = 4028

        for key in dict(config.items('Scripts')):
            try:
                script = config.get('Scripts', key)
                if os.path.isfile(script):
                    self.algos[key] = Algo(key)
                    self.algos[key].command = script
                else:
                    self.logger.critical('Script for %s not found!' % key)
                    self.cleanup()
            except ConfigParser.NoOptionError:
                self.logger.warning('Script for %s not configured!' % key)
                continue

        self.logger.debug("Enabled algorithms: %s" %
                          ', '.join(self.algos.keys()))
        if not self.algos:
            self.logger.critical('No mining algorithms enabled!')
            sys.exit()

        csv_file = logging_config.get('profitability_log')
        if csv_file:
            self.__prepare_profitability_log(csv_file)
Example #22
0
 def __init__(self):
     self.api = CgminerAPI()
     self.config_path = os.path.dirname(
         os.path.realpath(__file__)) + '/config/cgminer'
Example #23
0
 def __init__(self):
     self.api = CgminerAPI()