def getminerinfo(miner: Miner): minerid = 'unknown' minertype = 'unknown' if not miner.can_monitor(): raise MinerMonitorException( 'miner {0} cannot be monitored. ip={1} port={2}'.format( miner.name, miner.ipaddress, miner.port)) api = MinerApi(host=miner.ipaddress, port=int(miner.port), timeout=1) jstats = api.stats() #if there was an error then the return is STATUS not STATS! toplevelstatus = jstats['STATUS'][0] if toplevelstatus['STATUS'] == 'error': if not miner.is_disabled(): raise MinerMonitorException(toplevelstatus['description']) else: status = jstats['STATS'][0] details = jstats['STATS'][1] if 'Type' in status: minertype = status['Type'] else: if toplevelstatus['Description'].startswith('cgminer'): minertype = toplevelstatus['Description'] if minertype == 'Antminer S9': minerid = details['miner_id'] minerinfo = MinerInfo(minertype, minerid) return minerinfo
def pools(miner: Miner): '''Gets the current pool for the miner''' def sort_by_priority(j): return j['Priority'] try: api = MinerApi(host=miner.ipaddress, port=int(miner.port)) jstatuspools = api.pools() if jstatuspools['STATUS'][0]['STATUS'] == 'error': if not miner.is_disabled(): raise MinerMonitorException( jstatuspools['STATUS'][0]['description']) else: jpools = jstatuspools["POOLS"] #sort by priority jpools.sort(key=sort_by_priority) #try to do elegant way, but not working #cPool = namedtuple('Pool', 'POOL, URL, Status,Priority,Quota,Getworks,Accepted,Rejected,Long Poll') #colpools = [cPool(**k) for k in jsonpools["POOLS"]] #for pool in colpools: # print(pool.POOL) for pool in jpools: if str(pool["Status"]) == "Alive": currentpool = pool["URL"] currentworker = pool["User"] #print("{0} {1} {2} {3} {4} {5}".format(pool["POOL"],pool["Priority"],pool["URL"],pool["User"],pool["Status"],pool["Stratum Active"])) break minerpool = MinerCurrentPool(miner, currentpool, currentworker, jstatuspools) return minerpool except BaseException as ex: print('Failed to call miner pools api: ' + str(ex)) return None
def stats(miner: Miner): '''returns MinerStatistics, MinerInfo, and MinerApiCall''' if not miner.can_monitor(): raise MinerMonitorException( 'miner {0} cannot be monitored. ip={1} port={2}'.format( miner.name, miner.ipaddress, miner.port)) try: thecall = MinerApiCall(miner) entity = domain.minerstatistics.MinerStatistics( miner, when=datetime.datetime.utcnow()) api = MinerApi(host=miner.ipaddress, port=int(miner.port)) thecall.start() #jstats = api.stats() stats_and_pools = api.command('stats+pools') thecall.stop() if 'stats' in stats_and_pools: jstats = stats_and_pools['stats'][0] else: #if call failed then only one result is returned, so parse it jstats = stats_and_pools entity.rawstats = jstats jstatus = jstats['STATUS'] if jstatus[0]['STATUS'] == 'error': if not miner.is_disabled(): raise MinerMonitorException(jstatus[0]['description']) else: miner_software = parse_miner_software(jstats) if miner_software.startswith('sgminer'): jstats = stats_and_pools['STATS'] jsonstats = jstats status = jstats[0] jstatus = stats_and_pools['STATUS'] minerinfo = helpers.antminerhelper.parse_statistics_inno( entity, jsonstats, status) else: status = jstats['STATS'][0] jsonstats = jstats['STATS'][1] minerinfo = parse_minerinfo(status) #build MinerStatistics from stats parse_statistics(entity, jsonstats, status) minerpool = parse_minerpool(miner, stats_and_pools['pools'][0]) return entity, minerinfo, thecall, minerpool except BaseException as ex: print('Failed to call miner stats api: ' + str(ex)) raise MinerMonitorException(ex) return None, None, None, None
def pools(miner: Miner): '''Gets the current pool for the miner''' try: api = MinerApi(host=miner.ipaddress, port=int(miner.port)) jstatuspools = api.pools() if jstatuspools['STATUS'][0]['STATUS'] == 'error': if not miner.is_disabled(): raise MinerMonitorException( jstatuspools['STATUS'][0]['description']) else: return parse_minerpool(miner, jstatuspools) except BaseException as ex: print('Failed to call miner pools api: ' + str(ex)) return None
def stats(miner: Miner): try: entity = MinerStatistics(miner, when=datetime.datetime.utcnow()) api = MinerApi(host=miner.ipaddress, port=int(miner.port)) jstats = api.stats() if jstats['STATUS'][0]['STATUS'] == 'error': if not miner.is_disabled(): raise MinerMonitorException(jstats['STATUS'][0]['description']) else: status = jstats['STATS'][0] jsonstats = jstats['STATS'][1] entity.minercount = int(jsonstats['miner_count']) entity.elapsed = int(jsonstats['Elapsed']) entity.currenthash = int(float(jsonstats['GHS 5s'])) minertype = status['Type'] entity.controllertemp = None if 'temp_max' in jsonstats: entity.controllertemp = jsonstats['temp_max'] #should be 3 #tempcount = jsonstats['temp_num'] if minertype == 'Antminer S9': entity.tempboard1 = int(jsonstats['temp2_6']) entity.tempboard2 = int(jsonstats['temp2_7']) entity.tempboard3 = int(jsonstats['temp2_8']) entity.boardstatus1 = jsonstats['chain_acs6'] entity.boardstatus2 = jsonstats['chain_acs7'] entity.boardstatus3 = jsonstats['chain_acs8'] entity.fan1 = jsonstats['fan3'] entity.fan2 = jsonstats['fan6'] if minertype == 'Antminer D3': entity.tempboard1 = int(jsonstats['temp2_1']) entity.tempboard2 = int(jsonstats['temp2_2']) entity.tempboard3 = int(jsonstats['temp2_3']) if minertype == 'Antminer A3': entity.tempboard1 = int(jsonstats['temp2_1']) entity.tempboard2 = int(jsonstats['temp2_2']) entity.tempboard3 = int(jsonstats['temp2_3']) return entity except BaseException as ex: print('Failed to call miner stats api: ' + str(ex)) raise MinerMonitorException(ex) return None
def test_miner_is_not_disabled(self): miner = Miner("test", '', '', '', '', '', '', '', '') self.assertFalse(miner.is_disabled())
def test_miner_is_disabled(self): miner = Miner("#test", '', '', '', '', '', '', '', '') self.assertTrue(miner.is_disabled())