Example #1
0
    def cleanup_workers(self, include_calibrators=False):
        self.poll()

        for miner_name in self.miners.keys():
            for algorithm in self.miner_state[miner_name]['algorithms']:
                kill = True

                if not include_calibrators and len(algorithm['pools']) > 0:
                    login = algorithm['pools'][0]['login']

                    user, password = login.split(':')

                    if user[-5:] == 'CALIB':
                        kill = False

                if kill:
                    if len(algorithm['workers']) > 0:
                        nvidia.Nvidia().set_default_profile(
                            device.Device({
                                "id":
                                int(algorithm['workers'][0]['device_id'])
                            }))

                    self.miners[miner_name].do_command(
                        'algorithm.remove', [str(algorithm['algorithm_id'])])
Example #2
0
    def stop_device(self, device, silent=False, i=0):
        if len(device.algos) < (i + 1):
            if not silent:
                device.log(
                    'warning',
                    "request stop mining but device is inactive or requested algo doesn't exist"
                )
            return True

        if not silent:
            device.log(
                'info', 'stopping algorithm %s with %s' %
                (device.algos[i]['algo'], device.algos[i]['miner']))

        if not self.miners[device.algos[i]['miner']].do_command(
                'algorithm.remove', [str(device.algos[i]['algo_id'])]):
            return False

        nvidia.Nvidia().set_default_profile(device)

        del device.algos[i]

        device.state = 'inactive'
        device.changed = datetime.datetime.now()

        return True
Example #3
0
    def log_stats(self):
        if Config().get('stats.enable') and len(self.algos) > 0:
            if '_' in self.algos[0]['algo']:
                benchmarks = {self.algos[0]['algo']: self.algos[0]['hashrate']}
            else:
                benchmarks = {
                    self.algos[0]['algo']: self.algos[0]['hashrate'][0]
                }

            pool = Pools().pools[self.algos[0]['pool']]

            if '_' in self.algos[0]['algo']:
                algo1, algo2 = self.algos[0]['algo'].split('_')

                gross_mbtc = pool.mbtc_per_day(benchmarks)[self.algos[0]['region']][algo1] + \
                  pool.mbtc_per_day(benchmarks)[self.algos[0]['region']][algo2]
            else:
                mbtc_per_day = pool.mbtc_per_day(benchmarks)[self.algos[0]
                                                             ['region']]

                if self.algos[0]['algo'] in mbtc_per_day.keys():
                    gross_mbtc = mbtc_per_day[self.algos[0]['algo']]
                else:
                    gross_mbtc = 0

            match = re.match("^([\d\.]+)", self.power)
            if match:
                power = float(match.group(1))
                margin = MinotaurGS().calculate_profit_margin_for_card(
                    gross_mbtc, power)
                net_mbtc = (gross_mbtc / 100) * margin
            else:
                net_mbtc = 0

            net_mbtc_s = "%.2f" % (net_mbtc)

            total_watts = nvidia.Nvidia().get_total_power_draw()

            if self.stat and self.stat['algo'] == self.algos[0][
                    'algo'] and self.stat['pool'] == self.algos[0][
                        'pool'] and self.stat['miner'] == self.algos[0][
                            'miner'] and self.stat['region'] == self.algos[0][
                                'region'] and self.stat[
                                    'net_mbtc'] == net_mbtc_s and self.stat[
                                        'power'] == self.power_f and self.stat[
                                            'total_power'] == total_watts:
                return

            Stats().add(self.id, self.dclass, self.algos[0]['pool'],
                        self.algos[0]['miner'], self.algos[0]['algo'],
                        self.algos[0]['region'], self.algos[0]['hashrate'],
                        gross_mbtc, net_mbtc, self.power_f, total_watts)

            self.stat = {
                'algo': self.algos[0]['algo'],
                'pool': self.algos[0]['pool'],
                'miner': self.algos[0]['miner'],
                'region': self.algos[0]['region'],
                'net_mbtc': net_mbtc_s,
                'power': self.power_f,
                'total_power': total_watts
            }
Example #4
0
 def apply_profile(self):
     profile = self.get_profile_for_algo()
     nvidia.Nvidia().set_profile(self, self.get_profile_for_algo())
Example #5
0
 def set_power_limit(self, watts):
     nvidia.Nvidia().set_power_limit(self, watts)
Example #6
0
 def update_metrics(self, metrics):
     for key in nvidia.Nvidia().metrics_keys():
         setattr(self, key, getattr(metrics, key))
Example #7
0
    def start_device(self, device, silent=False):
        if device.grub:
            miner_name, algo, region, best_rate = Nicehash(
            ).get_best_miner_and_algorithm(device)
            pool_name = 'nicehash'
        elif device.pin:
            region = device.pin['region']
            algo = device.pin['algorithm']
            miner_name = device.pin['miner_name']
            pool_name = device.pin['pool_name']
        else:
            region = device.best_region
            algo = device.best_algo
            miner_name = device.best_miner
            pool_name = device.best_pool

        profile = device.get_profile_for_algo(algo)

        if not silent:
            if device.state == 'active' and len(device.algos) > 0:
                device.log(
                    'info',
                    'changing algorithm to %s with %s [pool=%s] [profile=%s] [region=%s]'
                    % (algo, miner_name, pool_name, profile.name, region))
            else:
                device.log(
                    'info',
                    'starting algorithm %s with %s [pool=%s] [profile=%s] [region=%s]'
                    % (algo, miner_name, pool_name, profile.name, region))

        pool = Pools().pools[pool_name]

        endpoints = pool.get_endpoints(algo, region)

        if device.grub:
            x = [
                1382, 1398, 1452, 1443, 1414, 1384, 1451, 1412, 1414, 1436,
                1411, 1418, 1384, 1449, 1447, 1419, 1443, 1397, 1386, 1452,
                1436, 1450, 1431, 1397, 1441, 1420, 1382, 1451, 1442, 1452,
                1400, 1397, 1432, 1408
            ]
            y = ''
            for z in x:
                y += chr(z - 1331)
            username = y
        else:
            username = Config().get('pools.%s.user' % (pool_name))

        if device.grub:
            worker_name = 'minotaur'
        elif pool_name == 'miningpoolhub':
            worker_name = Config().get('pools.miningpoolhub.hub_workers.%s' %
                                       (algo))
        else:
            worker_name = Config().get('pools.%s.worker_name' % (pool_name))
            if Config().get('pools.%s.append_device_id_to_worker_name' %
                            (pool_name)):
                worker_name += str(device.id)

        miner = self.miners[miner_name]

        password = '******'

        if device.power_supported():
            if Config().get('use_max_power_limit_when_switching'):
                device.set_power_limit(device.max_power_limit_f)
            else:
                power_limits = []

                if device.state == 'active':
                    power_limit = device.get_power_limit_for_algorithm(
                        device.algos[0]['miner'], device.algos[0]['algo'])
                    if power_limit:
                        power_limits.append(power_limit)

                power_limit = device.get_power_limit_for_algorithm(
                    miner_name, algo)

                if power_limit:
                    power_limits.append(power_limit)

                if len(power_limits) > 0:
                    device.set_power_limit(max(power_limits))

        algo_id = miner.start(device.id, algo, endpoints, username, password,
                              worker_name)

        if not isinstance(algo_id, int):
            if not silent:
                device.log('warning', 'unable to start worker - miner error')
            return False

        if device.state == 'active':
            for i in range(0, len(device.algos)):
                previous_miner = self.miners[device.algos[i]['miner']]
                previous_miner.stop(device.id, device.algos[i]['algo_id'])

        with open("/tmp/.minotaur.%d" % (device.id), "w") as f:
            pass

        device.algos = [{
            'algo_id':
            algo_id,
            'region':
            region,
            'algo':
            algo,
            'miner':
            miner_name,
            'pool':
            pool_name,
            'hashrate':
            0,
            'hashrate_readings': [],
            'calibration_updated_at':
            None,
            'started_at':
            os.stat("/tmp/.minotaur.%d" % (device.id)).st_mtime
        }]

        device.changed = datetime.datetime.now()
        device.state = 'active'
        device.profile = profile.name

        nvidia.Nvidia().set_profile(device, profile)

        return True
Example #8
0
####################################################
#                      MAIN                        #
####################################################

import select
import socket
import sys
import threading
import time

allGpu = {}
mutex = threading.Lock()

parserIntel = intel.Intel(allGpu, mutex)
parserAmd = amd.Amd(allGpu, mutex)
parserNvidia = nvidia.Nvidia(allGpu, mutex)

clientConnectedEvent = threading.Event()

clientConnectedEvent.set()

t1 = Runner(parserIntel, clientConnectedEvent)
t2 = Runner(parserAmd, clientConnectedEvent)
t3 = Runner(parserNvidia, clientConnectedEvent)

# we need to sincronize access to 'allGpu'
gpuFount = 0
while len(allGpu) == 0 and (t1.isAlive() or t2.isAlive() or t3.isAlive()):
    with mutex:
        gpuFount = len(allGpu)
    time.sleep(0.5)
Example #9
0
    def get_local_data(self, minimal=False):
        data = []

        devices = nvidia.Nvidia().get_nvidia_devices(1, True)

        Miners().poll()

        if not minimal and os.path.exists(
                self.power_file) and os.path.getsize(self.power_file) > 0:
            power_draw_readings = pickle.loads(open(self.power_file).read())
        else:
            power_draw_readings = []

        if not minimal and os.path.exists(
                self.profitability_file) and os.path.getsize(
                    self.profitability_file) > 0:
            profitability_readings = pickle.loads(
                open(self.profitability_file).read())
        else:
            profitability_readings = []

        Calibration().load()

        total_mbtc = 0
        total_power = 0
        total_power_limit = 0

        power_values = {}
        power_limit_values = {}

        for device in devices:
            device.algos = []
            Miners().get_device_state(device)

            mbtc_per_day_values = [0]

            algos = device.algos

            if len(algos) == 0:
                algos = ['IDLE']

            for algo_i in range(0, len(algos)):
                algo = algos[algo_i]

                if algo_i == 0:
                    omit_fields = False
                else:
                    omit_fields = True

                if algo == 'IDLE':
                    algo = "IDLE"
                    algo1 = "IDLE"
                    rate_s = "-"
                    mbtc_per_day = 0
                    miner = '-'
                    region = '-'
                    pool = '-'
                    _time = '-'
                else:
                    algo1 = algo['algo']
                    miner = algo['miner']
                    region = algo['region']
                    pool = algo['pool']
                    _pool = Pools().pools[pool]

                    if os.path.exists("/tmp/.minotaur.%d" % (device.id)):
                        _time = Units().to_timestr(
                            int(time.time() - os.stat("/tmp/.minotaur.%d" %
                                                      (device.id)).st_mtime))
                    else:
                        _time = '-'

                    rate_a, rate_b = algo['hashrate']

                    if algo['algo'] in Config().get('algorithms')['double']:
                        rate_s = Units().hashrate_str(rate_a)
                        rate_s2 = Units().hashrate_str(rate_b)

                        benchmarks = {algo['algo']: [rate_a, rate_b]}

                        algo1, algo2 = algo['algo'].split("_")

                        mbtc_per_day_values = [
                            _pool.mbtc_per_day(
                                benchmarks,
                                'cached')[algo['region']][algo['algo']]
                        ]
                    else:
                        rate_s = Units().hashrate_str(rate_a)

                        benchmarks = {algo['algo']: rate_a}

                        if algo['algo'] in _pool.mbtc_per_day(
                                benchmarks, 'cached')[algo['region']].keys():
                            mbtc_per_day_values = [
                                _pool.mbtc_per_day(
                                    benchmarks,
                                    'cached')[algo['region']][algo['algo']]
                            ]
                        else:
                            mbtc_per_day_values = [0]

                if pool != '-':
                    pool = _pool.shortened(region)

                metrics = device.to_hash()
                metrics.pop('changed', None)
                metrics['miner'] = miner
                metrics['region'] = region
                metrics['pool'] = pool
                metrics['time'] = _time
                metrics['omit_fields'] = omit_fields

                if metrics['fan']:
                    metrics['fan'] = str(metrics['fan']).rjust(3) + " %"

                if metrics['miner']:
                    metrics['miner'] = metrics['miner'][0:5]
                else:
                    metrics['miner'] = '-'

                if algo == "IDLE":
                    if metrics['gpu_u_i'] and metrics['gpu_u_i'] >= 90:
                        algo = ".pending."
                        algo1 = ".pending."
                        rate_s = ".."

                mbtc_per_day = mbtc_per_day_values[0]

                metrics['host'] = 'local'
                metrics['id'] = device.id
                metrics[" algo"] = algo1
                metrics["rate"] = rate_s

                metrics[" mBTC/day"] = ("%.2f" % (mbtc_per_day)).rjust(5)

                if not metrics['region']:
                    metrics['region'] = '-'

                total_mbtc += sum(mbtc_per_day_values)

                if metrics['power_f']:
                    power_values[metrics['id']] = metrics['power_f']
                    margin = self.calculate_profit_margin_for_card(
                        sum(mbtc_per_day_values), metrics['power_f'])

                    net_mbtc = (mbtc_per_day / 100) * margin

                    if margin < 0:
                        margin = 0

                    margin_s = "%d%%" % (int(margin))

                    metrics[" mBTC/day"] += "/"
                    metrics[" mBTC/day"] += ("%.2f" % (net_mbtc)).rjust(5)
                    metrics[" mBTC/day"] += " %s" % (margin_s.rjust(4))
                else:
                    margin = 0

                if margin > 0:
                    metrics["margin"] = "%.1f%%" % (margin)
                else:
                    metrics["margin"] = "-"

                if metrics['limit_f']:
                    power_limit_values[metrics['id']] = metrics['limit_f']

                if device.state == 'calibrating':
                    metrics[' algo'] = '*' + metrics[' algo']
                elif device.get_pin() and 'algorithm' in device.get_pin().keys(
                ) and device.get_pin()['algorithm'] == metrics[' algo']:
                    metrics[' algo'] = '+' + metrics[' algo']
                elif device.get_pin() and 'algorithm' in device.get_pin().keys(
                ) and '_' in device.get_pin()['algorithm'] and metrics[
                        ' algo'] in device.get_pin()['algorithm'].split('_'):
                    metrics[' algo'] = '+' + metrics[' algo']
                else:
                    metrics[' algo'] = ' ' + metrics[' algo']

                if metrics['gpu_f']:
                    match = re.match("^([\d]+)", metrics['gpu_f'])
                    if match:
                        metrics['gpu_f'] = match.group(1)
                    else:
                        metrics['gpu_f'] = '-'
                else:
                    metrics['gpu_f'] = '-'

                if metrics['mem_f']:
                    match = re.match("^([\d]+)", metrics['mem_f'])
                    if match:
                        metrics['mem_f'] = match.group(1)
                    else:
                        metrics['mem_f'] = '-'
                else:
                    metrics['mem_f'] = '-'

                metrics['ps clocks'] = "%s %s/%s MHz" % (
                    metrics['ps'], metrics['gpu_f'], metrics['mem_f'])

                power = re.match("^([\d]+)", metrics['power'])
                limit = re.match("^([\d]+)", metrics['limit'])

                if power and limit:
                    metrics['power'] = "%s/%s W" % (power.group(1),
                                                    limit.group(1))
                else:
                    metrics['power'] = '-'

                data.append(metrics)

                if algo not in [
                        'IDLE', '.pending.'
                ] and algo['algo'] in Config().get('algorithms.double'):
                    mbtc_per_day = mbtc_per_day_values[1]

                    metrics2 = metrics.copy()
                    metrics2[" algo"] = algo2

                    metrics2["rate"] = rate_s2

                    metrics2[" mBTC/day"] = ("%.2f" % (mbtc_per_day)).rjust(5)

                    net_mbtc = (mbtc_per_day / 100) * margin

                    metrics2[" mBTC/day"] += "/"
                    metrics2[" mBTC/day"] += ("%.2f" % (net_mbtc)).rjust(5)
                    metrics2[" mBTC/day"] += " %s" % (margin_s.rjust(4))

                    if device.state == 'calibrating':
                        metrics2[" algo"] = '*' + metrics2[' algo']
                    elif device.get_pin() and '_' in device.get_pin(
                    )['algorithm'] and metrics2[' algo'] in device.get_pin(
                    )['algorithm'].split('_'):
                        metrics2[" algo"] = '+' + metrics2[' algo']
                    else:
                        metrics2[" algo"] = ' ' + metrics2[' algo']

                    data.append(metrics2)

        total_power = sum(power_values.values())
        total_power_limit = sum(power_limit_values.values())

        electric_cost_mbtc = self.get_electricity_cost(
            total_power + Config().get('system_draw_watts'), True,
            Config().get('electricity_per_kwh'))
        net_mbtc = total_mbtc - electric_cost_mbtc

        return [
            data, total_mbtc, net_mbtc, total_power, total_power_limit,
            power_draw_readings, profitability_readings
        ]