示例#1
0
 def test_miner_status_change_keeps_original(self):
     miner = Miner('test')
     miner.status = MinerStatus.Offline
     self.assertTrue(miner.laststatuschanged)
     originalstatuschangetime = miner.laststatuschanged
     miner.status = MinerStatus.Offline
     self.assertTrue(miner.laststatuschanged == originalstatuschangetime)
示例#2
0
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
示例#3
0
 def test_miner_monitored_timer(self):
     miner = Miner('test')
     stats = domain.minerstatistics.MinerStatistics(miner)
     apicall = MinerApiCall(miner)
     apicall.start()
     apicall.stop()
     miner.monitored(stats, pool=None, info=None, sec=apicall.elapsed())
     self.assertFalse(miner.lastmonitor is None)
示例#4
0
 def test_miner_monitored_pool(self):
     miner = Miner('test')
     stats = domain.minerstatistics.MinerStatistics(miner)
     miner.monitored(stats,
                     pool=MinerCurrentPool(miner),
                     info=None,
                     sec=None)
     self.assertTrue(miner.minerpool)
示例#5
0
 def putminerandstats(self, miner: Miner, minerstats, minerpool):
     '''put miner and status in cache'''
     self.putminer(miner)
     schema = MinerStatsSchema()
     valstats = schema.dumps(minerstats).data
     self.tryputcache(miner.key() + '.stats', valstats)
     schema = MinerCurrentPoolSchema()
     valpool = schema.dumps(minerpool).data
     self.tryputcache(miner.key() + '.pool', valpool)
示例#6
0
 def test_miner_should_monitor(self):
     miner = Miner("#test", '', '', '', '', '', '', '', '')
     self.assertTrue(miner.should_monitor())
     miner.monitored(domain.minerstatistics.MinerStatistics(miner), None,
                     None, None)
     self.assertFalse(miner.should_monitor())
     miner.name = "test"
     self.assertTrue(miner.should_monitor())
     miner.status = MinerStatus.Disabled
     self.assertTrue(miner.should_monitor())
示例#7
0
 def test_miner_currentpoolname(self):
     miner = Miner('test')
     self.assertTrue(miner.currentpoolname() == '?')
     miner.minerpool = MinerCurrentPool(miner,
                                        'test pool',
                                        'test worker',
                                        allpools={},
                                        poolname='unit test')
     self.assertTrue(miner.currentpoolname() == 'unit test')
     self.assertFalse(
         miner.minerpool.findpoolnumberforpool('test pool', 'test worker'))
示例#8
0
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
示例#9
0
 def test_miner_summary(self):
     miner = Miner("test", '', '', '', '', '', '', '', '')
     self.assertTrue(miner.summary() is not None)
     miner.status = MinerStatus.Online
     self.assertTrue(miner.summary() is not None)
     miner.minerstats = None
     self.assertTrue(miner.summary() is not None)
     miner.minerstats = domain.minerstatistics.MinerStatistics(miner)
     self.assertTrue(miner.summary() is not None)
示例#10
0
 def test_miner_update_port(self):
     miner = Miner('test')
     miner.port = 'port1'
     minerupdate = Miner('test')
     minerupdate.port = 'port2'
     miner.updatefrom(minerupdate)
     self.assertTrue(miner.port == minerupdate.port)
示例#11
0
 def test_miner_no_update(self):
     miner = Miner('test')
     miner.ipaddress = 'ip1'
     minerupdate = Miner('test')
     minerupdate.ipaddress = None
     miner.updatefrom(minerupdate)
     self.assertTrue(miner.ipaddress != minerupdate.ipaddress)
示例#12
0
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
示例#13
0
    def test_miner_status_no_you_cant(self):
        miner = Miner('test')

        def set_status_test():
            miner.status = 'you can be anyting'

        self.assertRaises(ValueError, set_status_test)
示例#14
0
    def setUp(self):
        '''create test miner'''
        self.minerinfo = MinerInfo('Antminer S9', '')
        self.miner = Miner('Test',
                           'Online',
                           'Antminer S9',
                           '',
                           '',
                           '',
                           '',
                           '',
                           '',
                           '',
                           lastmonitor=None,
                           offlinecount=0,
                           defaultpool='',
                           minerinfo=self.minerinfo)

        self.minerstats = MinerStatistics(self.miner,
                                          datetime.datetime.utcnow(),
                                          3,
                                          currenthash=9999,
                                          controllertemp=0,
                                          tempboard1=0,
                                          tempboard2=0,
                                          tempboard3=0)
示例#15
0
 def readminers(self, file_name):
     with open(file_name, encoding='utf-8-sig') as config_file:
         jsonarray = json.loads(config_file.read())
     miners = [Miner(**k) for k in jsonarray]
     #TODO: Remove disabled miners
     #if miner.name.startswith("#"):
     return miners
示例#16
0
 def make_minermessage(self, data):
     '''reconstitute a minermessage'''
     miner = None
     command = None
     minerstats = None
     minerpool = None
     if 'miner' in data:
         #miner comes in as dict instead of entity when there is an error in the schema
         if isinstance(data['miner'], Miner):
             miner = data['miner']
         else:
             miner = Miner(**data['miner'])
     if 'command' in data:
         if isinstance(data['command'], MinerCommand):
             command = data['command']
         else:
             command = MinerCommand(**data['command'])
     if 'minerstats' in data:
         #minerstats = MinerStatistics(Miner=miner,**data['minerstats'])
         minerstats = data['minerstats']
     if 'minerpool' in data:
         #minerpool = MinerCurrentPool(Miner=miner, **data['minerpool'])
         minerpool = data['minerpool']
     entity = MinerMessage(miner, command, minerstats, minerpool)
     return entity
示例#17
0
 def test_miner_can_monitor(self):
     miner = Miner("test", '', '', '', '', '', '', '', '')
     self.assertFalse(miner.can_monitor())
     miner.ipaddress = '123.123.123.123'
     self.assertFalse(miner.can_monitor())
     miner.port = '4028'
     self.assertTrue(miner.can_monitor())
示例#18
0
 def test_miner_pools_available(self):
     miner = Miner('test')
     self.assertTrue(miner.pools_available is None)
     miner.minerpool = MinerCurrentPool(miner,
                                        'test pool',
                                        'test worker',
                                        allpools={})
     self.assertTrue(len(miner.pools_available) == 0)
     miner.minerpool.allpools = {
         "POOLS": [{
             "Pool Stale%": 0,
             "Accepted": 421743,
             "Difficulty Stale": 0,
             "Stratum URL": "test",
             "Rejected": 85,
             "Difficulty Accepted": 6587318272,
             "Best Share": 4019408192,
             "User": "******",
             "Stratum Active": True,
             "Difficulty Rejected": 1343488,
             "Diff": "16.4K",
             "Remote Failures": 3,
             "Discarded": 1094132,
             "Long Poll": "N",
             "Proxy": "",
             "Priority": 0,
             "Has GBT": False,
             "Pool Rejected%": 0.0204,
             "Stale": 63,
             "Last Share Difficulty": 16384,
             "Diff1 Shares": 0,
             "Has Stratum": True,
             "Status": "Alive",
             "URL": "test",
             "Quota": 1,
             "Last Share Time": "0:00:05",
             "Getworks": 70163,
             "Get Failures": 3,
             "POOL": 3,
             "Proxy Type": ""
         }]
     }
     self.assertTrue(len(miner.pools_available) > 0)
     self.assertTrue(miner.minerpool.findpoolnumberforpool('test', 'test'))
     self.assertFalse(miner.minerpool.findpoolnumberforpool('not', 'found'))
示例#19
0
 def test_message_inapp(self):
     app = ApplicationService(component='test')
     values = '{"version":"1.1","sender":"fullcyclereact","type":"configuration","timestamp":"2018-09-16T07:18:34.431Z","body":"{\\"command\\":\\"save\\",\\"parameter\\":\\"\\",\\"id\\":\\"unknown\\",\\"entity\\":\\"miner\\",\\"values\\":[{\\"name\\":\\"S9102\\"},{\\"ipaddress\\":\\"test.com\\"},{\\"port\\":\\"4102\\"},{\\"location\\":\\"222\\"},{\\"in_service_date\\":null}]}"}'
     msg = app.messagedecode_configuration(values)
     self.assertTrue(
         isinstance(msg, messaging.messages.ConfigurationMessage))
     self.assertTrue(msg.entity == 'miner')
     miner = Miner.create(msg.values)
     self.assertTrue(miner.name == "S9102")
示例#20
0
 def getminer(self, miner: Miner):
     '''strategies for getting miner from cache
     originally was key=miner.name but that was not good
     changed to key='miner.'+minerid
     '''
     valu = self.trygetvaluefromcache('miner.{0}'.format(miner.key()))
     if valu is None:
         return None
     minerfromstore = self.deserialize(MinerSchema(), self.safestring(valu))
     minerfromstore.store = 'mem'
     return minerfromstore
示例#21
0
    def test_minerserialization(self):
        sch = MinerSchema()
        miner = Miner('test')
        miner.minerinfo = MinerInfo('Antminer S9', '123')
        miner.minerpool = MinerCurrentPool(miner,
                                           'test pool',
                                           'test worker',
                                           allpools={})
        miner.minerpool.poolname = 'unittest'
        miner.minerstats = MinerStatistics(miner, datetime.datetime.utcnow(),
                                           0, 1, 0, 99, 98, 97, 123, '', '',
                                           '')
        jminer = sch.dumps(miner).data

        #rehydrate miner
        reminer = MinerSchema().loads(jminer).data
        self.assertTrue(isinstance(reminer.minerinfo, MinerInfo))
        self.assertTrue(isinstance(reminer.minerpool, MinerCurrentPool))
        self.assertTrue(reminer.minerpool.poolname == 'unittest')
        self.assertTrue(isinstance(reminer.minerstats, MinerStatistics))
示例#22
0
def main():
    '''main'''
    if COMPONENTDISCOVERED.app.isrunnow:
        miner = Miner('192.168.1.117')
        dodiscovered(miner)
        COMPONENTDISCOVERED.app.shutdown()
    else:
        print('Waiting for messages on {0}. To exit press CTRL+C'.format(QueueName.Q_DISCOVERED))
        COMPONENTDISCOVERED.listeningqueue = COMPONENTDISCOVERED.app.makequeue(QueueName.Q_DISCOVERED)
        COMPONENTDISCOVERED.listeningqueue.subscribe(when_discovered, no_acknowledge=False)
        COMPONENTDISCOVERED.app.listen(COMPONENTDISCOVERED.listeningqueue)
示例#23
0
def findminerbyname(minertofind):
    miners = MinerRepository()
    miner = miners.getminerbyname(minertofind, APP.getconfigfilename('config/miners.conf'))
    if miner is None:
        miner = APP.getknownminerbyname(minertofind)
    if miner is None:
        miner = APP.getminer(Miner(name=minertofind))
    if miner is None:
        print('Miner {0} does not exist'.format(minertofind))
        sys.exit(1)
    return miner
示例#24
0
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
示例#25
0
 def test_miner_create(self):
     values = []
     values.append({"name": "UnitTest"})
     values.append({"minerid": "1"})
     values.append({"ipaddress": "123.123.123.123"})
     values.append({"port": "987"})
     values.append({"location": "rack"})
     values.append({"in_service_date": "2018-01-01T08:00:00.000Z"})
     miner = Miner.create(values)
     self.assertTrue(miner.name == "UnitTest")
     self.assertTrue(miner.minerid == "1")
     self.assertTrue(miner.ipaddress == "123.123.123.123")
     self.assertTrue(miner.port == "987")
     self.assertTrue(miner.location == "rack")
     self.assertTrue(
         miner.in_service_date.date() == datetime.date(2018, 1, 1))
示例#26
0
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
示例#27
0
def doit(args):
    if len(args) < 2:
        print('usage: python runcommand.py nameofcommand [nameofminer] [commandparameter]')
        APP.shutdown(1)

    cmd = args[1]
    if len(args) == 2:
        #single command, no miner specified
        queue_command = Queue(cmd, APP.getservice('rabbit'))
        queue_command.publish('{0} runcommand called on {1}'.format(APP.now(), cmd))
        queue_command.close()
        print('sent command {0}'.format(cmd))
    else:
        minertofind = args[2]
        cmdparam = ''
        if len(args) > 3:
            cmdparam = args[3]
        miners = MinerRepository()
        miner = miners.getminerbyname(minertofind, APP.getconfigfilename('config/miners.conf'))
        if miner is None:
            miner = APP.getknownminerbyname(minertofind)
        if miner is None:
            miner = APP.getminer(Miner(name=minertofind))
        if miner is None:
            print('Miner {0} does not exist'.format(minertofind))
            sys.exit(1)
        qnames = QueueName()
        if not qnames.isvalidqname(cmd):
            print('Queue {0} is not valid'.format(cmd))
            sys.exit(1)
        queue_command = Queue(cmd, APP.getservice('rabbit'))
        #TODO: cleanup logic here. when to call app and when to override with just miner and command
        if cmd:
            qmess = MinerCommand(cmd, cmdparam)
            msg = APP.createmessagecommand(miner, qmess)
            queue_command.publish(msg)
        else:
            queue_command.publish(APP.messageencode(miner))
        queue_command.close()
        print('sent command {0} for miner {1}'.format(cmd, miner.name))
示例#28
0
def dosave(msg):
    entries = QueueEntries()
    if msg.entity == 'miner':
        #add or update miner
        minerid = name = ipaddress = port = None
        for pair in msg.values:
            if 'minerid' in pair:
                minerid = pair['minerid']
            if 'name' in pair:
                name = pair['name']
            if 'ipaddress' in pair:
                ipaddress = pair['ipaddress']
            if 'port' in pair:
                port = pair['port']
        miner = Miner(name, '', '', ipaddress, port, '', '')
        COMPONENTSAVE.app.save_miner(miner)
        entries.add(QueueName.Q_MONITORMINER,
                    COMPONENTSAVE.app.messageencode(miner))
        entries.add(QueueName.Q_PROVISION,
                    COMPONENTSAVE.app.messageencode(miner))

    if msg.entity == 'pool':
        #save the new named pool
        pool_type = name = url = user = priority = None
        for pair in msg.values:
            if 'pool_type' in pair:
                pool_type = pair['pool_type']
            if 'name' in pair:
                name = pair['name']
            if 'url' in pair:
                url = pair['url']
            if 'user' in pair:
                user = pair['user']
            if 'priority' in pair:
                priority = pair['priority']
        pool = Pool(pool_type, name, url, user, priority)
        COMPONENTSAVE.app.save_pool(pool)
    return entries
示例#29
0
 def getknownminer(self, miner: Miner):
     '''get a known miner'''
     return self.getknownminerbykey(miner.key())
示例#30
0
 def putminer(self, miner: Miner):
     '''put miner in cache'''
     if miner and miner.key():
         valu = self.serialize(miner)
         self.tryputcache('miner.{0}'.format(miner.key()), valu)