improved api.__init__ formatting and readability

This commit is contained in:
UpstreamData
2021-11-03 12:03:33 -06:00
parent 027423242d
commit 7f0bd87ed1

View File

@@ -18,14 +18,19 @@ class APIError(Exception):
class BaseMinerAPI:
def __init__(self, ip: str, port: int) -> None:
def __init__(self, ip: str, port: int = 4028) -> None:
# api port, should be 4028
self.port = port
# ip address of the miner
self.ip = ipaddress.ip_address(ip)
def get_commands(self) -> list:
return [func for func in
# each function in self
dir(self) if callable(getattr(self, func)) and
# no __ methods
not func.startswith("__") and
# remove all functions that are in this base class
func not in
[func for func in
dir(BaseMinerAPI) if callable(getattr(BaseMinerAPI, func))
@@ -33,11 +38,18 @@ class BaseMinerAPI:
]
async def multicommand(self, *commands: str) -> dict:
# split the commands into a proper list
commands = [*commands]
for item in commands:
# make sure we can actually run the command, otherwise it will fail
if item not in self.get_commands():
print(f"Removing command: {item}")
# if the command isnt allowed, remove it
print(f"Removing incorrect command: {item}")
commands.remove(item)
# standard multicommand format is "command1+command2"
# doesnt work for S19 which is dealt with in the send command function
command = "+".join(commands)
return await self.send_command(command)
@@ -45,6 +57,7 @@ class BaseMinerAPI:
try:
# get reader and writer streams
reader, writer = await asyncio.open_connection(str(self.ip), self.port)
# handle OSError 121
except OSError as e:
if e.winerror == "121":
print("Semaphore Timeout has Expired.")
@@ -72,21 +85,18 @@ class BaseMinerAPI:
except Exception as e:
print(e)
try:
if data.endswith(b"\x00"):
data = json.loads(data.decode('utf-8')[:-1])
else:
data = json.loads(data.decode('utf-8'))
except json.decoder.JSONDecodeError:
raise APIError(f"Decode Error: {data}")
data = self.load_api_data(data)
# close the connection
writer.close()
await writer.wait_closed()
# validate the command suceeded
# also handle for S19 not liking "command1+command2" format
if not self.validate_command_output(data):
try:
data = {}
# S19 handler, try again
for cmd in command.split("+"):
data[cmd] = []
data[cmd].append(await self.send_command(cmd))
@@ -99,7 +109,8 @@ class BaseMinerAPI:
return data
def validate_command_output(self, data):
@staticmethod
def validate_command_output(data):
# 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():
@@ -118,3 +129,17 @@ class BaseMinerAPI:
if data["STATUS"][0]["STATUS"] not in ("S", "I"):
return False
return True
@staticmethod
def load_api_data(data):
try:
# some json from the API returns with a null byte (\x00) on the end
if data.endswith(b"\x00"):
# handle the null byte
data = json.loads(data.decode('utf-8')[:-1])
else:
# no null byte
data = json.loads(data.decode('utf-8'))
# handle bad json
except json.decoder.JSONDecodeError:
raise APIError(f"Decode Error: {data}")