miner_factory returns a miner of the type intended

This commit is contained in:
UpstreamData
2021-10-07 16:38:05 -06:00
parent 4778aa957b
commit a0e88490c6
7 changed files with 123 additions and 9 deletions

View File

@@ -5,8 +5,6 @@ import asyncio
async def main():
api = BMMinerAPI("192.168.1.1")
print(api.get_commands())
miner_network = MinerNetwork("192.168.1.1")
await miner_network.scan_network_for_miners()

13
miners/bmminer.py Normal file
View 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
View 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
View 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
View 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

View File

@@ -1,6 +1,7 @@
import netifaces
import ipaddress
import asyncio
from miners.miner_factory import MinerFactory
PING_RETRIES: int = 3
PING_TIMEOUT: int = 1
@@ -9,6 +10,7 @@ PING_TIMEOUT: int = 1
class MinerNetwork:
def __init__(self, ip_addr=None):
self.network = None
self.miner_factory = MinerFactory()
self.ip_addr = ip_addr
self.connected_miners = {}
@@ -29,8 +31,15 @@ class MinerNetwork:
scan_tasks = []
for host in local_network.hosts():
scan_tasks.append(self.ping_miner(host))
await asyncio.gather(*scan_tasks)
print(f"Found {len(self.connected_miners)} connected miners...")
miner_ips = await asyncio.gather(*scan_tasks)
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):
for i in range(PING_RETRIES):
@@ -42,10 +51,8 @@ class MinerNetwork:
writer.close()
# make sure the writer is closed
await writer.wait_closed()
# add miner to dict
self.connected_miners[ip] = {}
# ping was successful
return True
return ip
except asyncio.exceptions.TimeoutError:
# ping failed if we time out
continue
@@ -56,4 +63,4 @@ class MinerNetwork:
except Exception as e:
print(e)
continue
return False
return