def get_pool_stats(self, results, miner, worker, algo, pool_id, pool_url): if algo == 'ethash': algo_idx = get_algo_index('daggerhashimoto') else: algo_idx = get_algo_index(algo) if algo_idx is -1: return False coin_idx = get_coin_index(self._DEFAULT_COIN_) # get the cost of the coin # TODO - get the currency from the config, do not assume USD coin_cost = get_coin_cost(self._DEFAULT_COIN_, 'USD') success = False json = self.get_worker_stats(miner, worker) if json: success = self.parse_json(json, results, miner, worker, pool_id, algo, algo_idx, coin_idx, coin_cost) return success
def get_pool_stats(self, results, miner, worker, algo, pool_id, pool_url): # ensure we have an ALGO IDX (i.e. it is known by the system) algo_idx = get_algo_index(algo) if algo_idx is None: # TODO - throw an exception return False coin_idx = get_coin_index(self._DEFAULT_COIN_) # get the cost of the coin # TODO - get the currency from the config, do not assume USD # TODO - cache coin_cost for a period... (or implement REST API result cache) coin_cost = get_coin_cost(self._DEFAULT_COIN_, 'USD') success = False # build the miner URL url = self._MINER_URL.replace("{MINER}", miner.coin_address) # create an API object api = RestAPI(url=url, port=80) # get the data json = api.get_json() if json: success = self.parse_json(json, results, miner, worker, pool_id, algo, algo_idx, coin_idx, coin_cost) return success
def __process_hashrate_calculations(self, miner, hashrate_ghs5s, algo): # it is possible with multi-algo miners and pools to switch the ALGO # let us double check the current algo vs the algo stored in the results # since the hashrate calcs depend on the ALGO try: algo_idx = get_algo_index(algo) algo_idx_from_pool = self.get_result(miner.id, 'algo') if algo_idx == -1 or (algo_idx_from_pool and algo_idx != algo_idx_from_pool): # get the changed algo algo = get_algo_by_index(algo_idx_from_pool) except: pass try: # do all hashrate stuff calculate_hashrates(self, miner, hashrate_ghs5s, algo) except: logger.error("Problem processing hashrate for " "miner '{}' hashrate '{}'".format( miner.id, hashrate_ghs5s))
def parse_json(self, json, results, miner, worker, pool, algo, algo_idx, coin_idx, coin_cost): success = False # get the records records = json['miningRigs'] for record in records: if record.get('stats') is None: pass # TODO - should we log a warning no stats on NiceHash for this Coin / Address ? else: # get the NH algo key nice_algo_key = record['stats'][0]['algorithm']['enumName'] # make sure we are looking at the correct algo nice_algo_idx = get_algo_index(nice_algo_key) # ensure the algo in this record matches the algo that we passed into the parse for this miner if nice_algo_idx == algo_idx: try: # get units suffix for this ALGO / Miner combo speed_suffix = self.get_algo_units( nice_algo_key, results, miner, algo) # get accepted hashrate to use in our profitability calcs # NH is reporting as string (Big decimal scaled to 8 decimal points) speed_accepted = float( record['stats'][0]['speedAccepted']) # profitability is a measure of COIN / speed suffix / per DAY # sometimes the profitability is in the actual stats record stats = record['stats'][0] profitability = stats.get('profitability') if profitability is None: # otherwise it is one level up in the algo record profitability = record['profitability'] # NH is reporting profitability as (COIN / day) and the Results needs (COIN / hashrate / day) # so also divide by the hashrate as our the populate method multiplies it back in later profitability = float(profitability) / speed_accepted except: speed_accepted = 0.0 profitability = 0.0 # finally set the API results into the main results object results.populate_pool_results(miner, worker, pool, algo, algo_idx, coin_idx, coin_cost, profitability, speed_accepted, None, speed_suffix) # break out of the loop success = True break return success
def get_pool_stats(self, results, miner, worker, algo, pool_id, pool_url): # initialize with a 0 hashrate hashrate = 0.0 # profit on MPOS site is measured in BTC/GH/DAY profit_btc_gh_day = 0.0 if self._pool_info is None: # we are SOL logger.error("Cannot get needed POOL DATA from (getminingandprofitsstatistics) API call.") return False # get the API KEY and USER ID api_key, user_id = self._get_api_key_and_user_id() if api_key is None or len(api_key)==0 or user_id is None or user_id == 0: warn_msg = "MINING POOL HUB Needs API_KEY and USER_ID" warn_msg += " in order to retrieve Miner Data. Set using UI or .INI file" logger.warning(warn_msg) return False # Get the pool info, should be a list of potential multialgo pools based on port for pool in self._pool_info: algo = pool['algo'] coin = pool['coin_name'] # profit == BTC / GH / DAY profit_btc_gh_day = pool['profit'] # try to build a URL: url = self._build_api_hashrate_url(api_key, user_id, coin) # create an API object api = RestAPI(url=url, port=80) # get the data json = api.get_json() if json: hashrate = json['getuserhashrate']['data'] if hashrate > 0: # this must be the right pool break # get the algo algo_idx = get_algo_index(algo) if algo_idx == -1: return False # get the index and cost of the coin coin_idx = get_coin_index(coin) coin_cost = get_coin_cost_by_index(coin_idx,'USD') coin_cost_btc = get_coin_cost('BTC', 'USD') coin_cost_ratio = coin_cost_btc/coin_cost # The API is returning a number 1000 times larger than the WEB Dashboard, which is reporting in MH/S # We are going to surmise that the hashrate is reported in KH/s from the API # BUT we want to convert to GH/s to be consistent with profitability here # so force suffix to be GH speed_suffix = "GH" # and divide by 1M to get hashrate expressed in GH hashrate_ghs = (hashrate / 1000000) # We need the profitability to be in: COIN / speed_suffix / day # multiply by ratio of 'COIN' to BTC profit_coin_gh_day = profit_btc_gh_day * coin_cost_ratio # finally set the API results into the main results object results.populate_pool_results(miner, worker, pool_id, algo, algo_idx, coin_idx, coin_cost, profit_coin_gh_day, hashrate_ghs, None, speed_suffix) return True
def get_pool_stats(self, results, miner, worker, algo, pool_id, pool_url): # initialize with a 0 hashrate hashrate = 0.0 # get the coin from the pool URL # should be the format of: "ltc-us.f2pool.com:8888" pool_coin = pool_url.split(".")[0] if "-" in pool_coin: # seems pool location may be inside, remove that pool_coin = pool_coin.split("-")[0] # The F2Pool uses the CURRENCY in the API call but requires currency name # instead of the actual symbol - so we need to translate. # For example: # ltc == litecoin # btc == bitcoin # eth == ethereum # get the coin coin = get_coin_name_by_symbol(pool_coin) if coin is not None: # try to build a URL: url = self._build_api_hashrate_url(miner.coin_address, coin) # create an API object api = RestAPI(url=url, port=80) # get the data json = api.get_json() # hashrate from history - don't need this right now # hashrate = self.get_last_complete_hashrate_from_history(json) workers = json['workers'] for worker_record in workers: if worker_record[0] == worker: # current hashrate per worker hashrate = float(worker_record[1]) break # get the algo algo_idx = get_algo_index(algo) if algo_idx == -1: return False # get the index and cost of the coin coin_idx = get_coin_index(pool_coin) coin_cost = get_coin_cost_by_index(coin_idx, 'USD') coin_cost_btc = get_coin_cost('BTC', 'USD') coin_cost_ratio = coin_cost_btc / coin_cost # profit == BTC / GH / DAY # profit_btc_gh_day = pool['profit'] # BUT we want to convert to GH/s to be consistent with profitability here # so force suffix to be GH speed_suffix = "GH" # must divide by 1G to get hashrate expressed in GH hashrate_ghs = (hashrate / 1000000000) # hack to get profit per day - need to verify with F2Pool support what this means and the units # would be better to get the value earned per worker rather than total value for all miners worker_count = int(json['worker_length']) profit_btc_gh_day = float(json['value_last_day']) / worker_count # We need the profitability to be in: COIN / speed_suffix / day # multiply by ratio of 'COIN' to BTC profit_coin_gh_day = profit_btc_gh_day * coin_cost_ratio # finally set the API results into the main results object results.populate_pool_results(miner, worker, pool_id, algo, algo_idx, coin_idx, coin_cost, profit_coin_gh_day, hashrate_ghs, None, speed_suffix) return True