miner_factory returns a miner of the type intended
This commit is contained in:
2
main.py
2
main.py
@@ -5,8 +5,6 @@ import asyncio
|
|||||||
|
|
||||||
|
|
||||||
async def main():
|
async def main():
|
||||||
api = BMMinerAPI("192.168.1.1")
|
|
||||||
print(api.get_commands())
|
|
||||||
miner_network = MinerNetwork("192.168.1.1")
|
miner_network = MinerNetwork("192.168.1.1")
|
||||||
await miner_network.scan_network_for_miners()
|
await miner_network.scan_network_for_miners()
|
||||||
|
|
||||||
|
|||||||
13
miners/bmminer.py
Normal file
13
miners/bmminer.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
from miners import BaseMiner
|
||||||
|
from API.bosminer import BOSMinerAPI
|
||||||
|
from API.bmminer import BMMinerAPI
|
||||||
|
from API.cgminer import CGMinerAPI
|
||||||
|
|
||||||
|
|
||||||
|
class BMMiner(BaseMiner):
|
||||||
|
def __init__(self, ip: str):
|
||||||
|
api = BMMinerAPI(ip)
|
||||||
|
super().__init__(ip, api)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"BMMiner: {str(self.ip)}"
|
||||||
11
miners/bosminer.py
Normal file
11
miners/bosminer.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
from miners import BaseMiner
|
||||||
|
from API.bosminer import BOSMinerAPI
|
||||||
|
|
||||||
|
|
||||||
|
class BOSminer(BaseMiner):
|
||||||
|
def __init__(self, ip: str):
|
||||||
|
api = BOSMinerAPI(ip)
|
||||||
|
super().__init__(ip, api)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"BOSminer: {str(self.ip)}"
|
||||||
13
miners/cgminer.py
Normal file
13
miners/cgminer.py
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
from miners import BaseMiner
|
||||||
|
from API.bosminer import BOSMinerAPI
|
||||||
|
from API.bmminer import BMMinerAPI
|
||||||
|
from API.cgminer import CGMinerAPI
|
||||||
|
|
||||||
|
|
||||||
|
class CGMiner(BaseMiner):
|
||||||
|
def __init__(self, ip: str):
|
||||||
|
api = CGMinerAPI(ip)
|
||||||
|
super().__init__(ip, api)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"CGMiner: {str(self.ip)}"
|
||||||
72
miners/miner_factory.py
Normal file
72
miners/miner_factory.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
from miners.bosminer import BOSminer
|
||||||
|
from miners.bmminer import BMMiner
|
||||||
|
from miners.cgminer import CGMiner
|
||||||
|
from API import APIError
|
||||||
|
import asyncio
|
||||||
|
import ipaddress
|
||||||
|
import json
|
||||||
|
|
||||||
|
class MinerFactory:
|
||||||
|
async def get_miner(self, ip: ipaddress.ip_address):
|
||||||
|
version_data = await self._get_version_data(ip)
|
||||||
|
version = None
|
||||||
|
if version_data:
|
||||||
|
version = list(version_data['VERSION'][0].keys())[0]
|
||||||
|
if version:
|
||||||
|
if version == "BOSminer":
|
||||||
|
return BOSminer(str(ip))
|
||||||
|
elif version == "CGMiner":
|
||||||
|
return CGMiner(str(ip))
|
||||||
|
elif version == "BMMiner":
|
||||||
|
return BMMiner(str(ip))
|
||||||
|
return f"Unknown: {str(ip)}"
|
||||||
|
|
||||||
|
async def _get_version_data(self, ip: ipaddress.ip_address):
|
||||||
|
try:
|
||||||
|
# get reader and writer streams
|
||||||
|
reader, writer = await asyncio.open_connection(str(ip), 4028)
|
||||||
|
|
||||||
|
# create the command
|
||||||
|
cmd = {"command": "version"}
|
||||||
|
|
||||||
|
# send the command
|
||||||
|
writer.write(json.dumps(cmd).encode('utf-8'))
|
||||||
|
await writer.drain()
|
||||||
|
|
||||||
|
# instantiate data
|
||||||
|
data = b""
|
||||||
|
|
||||||
|
# loop to receive all the data
|
||||||
|
while True:
|
||||||
|
d = await reader.read(4096)
|
||||||
|
if not d:
|
||||||
|
break
|
||||||
|
data += d
|
||||||
|
|
||||||
|
data = json.loads(data.decode('utf-8')[:-1])
|
||||||
|
|
||||||
|
# close the connection
|
||||||
|
writer.close()
|
||||||
|
await writer.wait_closed()
|
||||||
|
|
||||||
|
# check if the data returned is correct or an error
|
||||||
|
# if status isn't a key, it is a multicommand
|
||||||
|
if "STATUS" not in data.keys():
|
||||||
|
for key in data.keys():
|
||||||
|
# make sure not to try to turn id into a dict
|
||||||
|
if not key == "id":
|
||||||
|
# make sure they succeeded
|
||||||
|
if data[key][0]["STATUS"][0]["STATUS"] not in ["S", "I"]:
|
||||||
|
# this is an error
|
||||||
|
raise APIError(data["STATUS"][0]["Msg"])
|
||||||
|
else:
|
||||||
|
# make sure the command succeeded
|
||||||
|
if data["STATUS"][0]["STATUS"] not in ("S", "I"):
|
||||||
|
# this is an error
|
||||||
|
raise APIError(data["STATUS"][0]["Msg"])
|
||||||
|
|
||||||
|
# return the data
|
||||||
|
return data
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
return None
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import netifaces
|
import netifaces
|
||||||
import ipaddress
|
import ipaddress
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from miners.miner_factory import MinerFactory
|
||||||
|
|
||||||
PING_RETRIES: int = 3
|
PING_RETRIES: int = 3
|
||||||
PING_TIMEOUT: int = 1
|
PING_TIMEOUT: int = 1
|
||||||
@@ -9,6 +10,7 @@ PING_TIMEOUT: int = 1
|
|||||||
class MinerNetwork:
|
class MinerNetwork:
|
||||||
def __init__(self, ip_addr=None):
|
def __init__(self, ip_addr=None):
|
||||||
self.network = None
|
self.network = None
|
||||||
|
self.miner_factory = MinerFactory()
|
||||||
self.ip_addr = ip_addr
|
self.ip_addr = ip_addr
|
||||||
self.connected_miners = {}
|
self.connected_miners = {}
|
||||||
|
|
||||||
@@ -29,8 +31,15 @@ class MinerNetwork:
|
|||||||
scan_tasks = []
|
scan_tasks = []
|
||||||
for host in local_network.hosts():
|
for host in local_network.hosts():
|
||||||
scan_tasks.append(self.ping_miner(host))
|
scan_tasks.append(self.ping_miner(host))
|
||||||
await asyncio.gather(*scan_tasks)
|
miner_ips = await asyncio.gather(*scan_tasks)
|
||||||
print(f"Found {len(self.connected_miners)} connected miners...")
|
miner_ips = list(filter(None, miner_ips))
|
||||||
|
print(f"Found {len(miner_ips)} connected miners...")
|
||||||
|
create_miners_tasks = []
|
||||||
|
for miner_ip in miner_ips:
|
||||||
|
create_miners_tasks.append(self.miner_factory.get_miner(miner_ip))
|
||||||
|
miners = await asyncio.gather(*create_miners_tasks)
|
||||||
|
print(miners)
|
||||||
|
|
||||||
|
|
||||||
async def ping_miner(self, ip: ipaddress.ip_address):
|
async def ping_miner(self, ip: ipaddress.ip_address):
|
||||||
for i in range(PING_RETRIES):
|
for i in range(PING_RETRIES):
|
||||||
@@ -42,10 +51,8 @@ class MinerNetwork:
|
|||||||
writer.close()
|
writer.close()
|
||||||
# make sure the writer is closed
|
# make sure the writer is closed
|
||||||
await writer.wait_closed()
|
await writer.wait_closed()
|
||||||
# add miner to dict
|
|
||||||
self.connected_miners[ip] = {}
|
|
||||||
# ping was successful
|
# ping was successful
|
||||||
return True
|
return ip
|
||||||
except asyncio.exceptions.TimeoutError:
|
except asyncio.exceptions.TimeoutError:
|
||||||
# ping failed if we time out
|
# ping failed if we time out
|
||||||
continue
|
continue
|
||||||
@@ -56,4 +63,4 @@ class MinerNetwork:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
continue
|
continue
|
||||||
return False
|
return
|
||||||
|
|||||||
Reference in New Issue
Block a user