added safe_parse_api_data, recursive function to make sure the api data is parsed safely
This commit is contained in:
@@ -10,6 +10,7 @@ import toml
|
|||||||
|
|
||||||
from cfg_util.miner_factory import miner_factory
|
from cfg_util.miner_factory import miner_factory
|
||||||
from cfg_util.layout import window
|
from cfg_util.layout import window
|
||||||
|
from cfg_util.func.data import safe_parse_api_data
|
||||||
|
|
||||||
from config.bos import bos_config_convert, general_config_convert_bos
|
from config.bos import bos_config_convert, general_config_convert_bos
|
||||||
|
|
||||||
@@ -131,23 +132,26 @@ async def get_formatted_data(ip: ipaddress.ip_address):
|
|||||||
data = await miner.api.multicommand("summary", "pools", "tunerstatus")
|
data = await miner.api.multicommand("summary", "pools", "tunerstatus")
|
||||||
host = await miner.get_hostname()
|
host = await miner.get_hostname()
|
||||||
if "tunerstatus" in data.keys():
|
if "tunerstatus" in data.keys():
|
||||||
wattage = data['tunerstatus'][0]['TUNERSTATUS'][0]['PowerLimit']
|
wattage = await safe_parse_api_data(data, "tunerstatus", 0, 'TUNERSTATUS', 0, "PowerLimit")
|
||||||
|
# data['tunerstatus'][0]['TUNERSTATUS'][0]['PowerLimit']
|
||||||
else:
|
else:
|
||||||
wattage = 0
|
wattage = 0
|
||||||
if "summary" in data.keys():
|
if "summary" in data.keys():
|
||||||
if 'MHS 5s' in data['summary'][0]['SUMMARY'][0].keys():
|
if 'MHS 5s' in data['summary'][0]['SUMMARY'][0].keys():
|
||||||
th5s = round(data['summary'][0]['SUMMARY'][0]['MHS 5s'] / 1000000, 2)
|
th5s = round(await safe_parse_api_data(data, 'summary', 0, 'SUMMARY', 0, 'MHS 5s') / 1000000, 2)
|
||||||
elif 'GHS 5s' in data['summary'][0]['SUMMARY'][0].keys():
|
elif 'GHS 5s' in data['summary'][0]['SUMMARY'][0].keys():
|
||||||
if not data['summary'][0]['SUMMARY'][0]['GHS 5s'] == "":
|
if not data['summary'][0]['SUMMARY'][0]['GHS 5s'] == "":
|
||||||
th5s = round(float(data['summary'][0]['SUMMARY'][0]['GHS 5s']) / 1000, 2)
|
th5s = round(float(await safe_parse_api_data(data, 'summary', 0, 'SUMMARY', 0, 'GHS 5s')) / 1000, 2)
|
||||||
else:
|
else:
|
||||||
th5s = 0
|
th5s = 0
|
||||||
else:
|
else:
|
||||||
th5s = 0
|
th5s = 0
|
||||||
else:
|
else:
|
||||||
th5s = 0
|
th5s = 0
|
||||||
if not data['pools'][0]['POOLS'] == []:
|
if "pools" not in data.keys():
|
||||||
user = data['pools'][0]['POOLS'][0]['User']
|
user = "?"
|
||||||
|
elif not data['pools'][0]['POOLS'] == []:
|
||||||
|
user = await safe_parse_api_data(data, 'pools', 0, 'POOLS', 0, 'User')
|
||||||
else:
|
else:
|
||||||
user = "Blank"
|
user = "Blank"
|
||||||
return {'TH/s': th5s, 'IP': str(miner.ip), 'host': host, 'user': user, 'wattage': wattage}
|
return {'TH/s': th5s, 'IP': str(miner.ip), 'host': host, 'user': user, 'wattage': wattage}
|
||||||
45
cfg_util/func/data.py
Normal file
45
cfg_util/func/data.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
from API import APIError
|
||||||
|
|
||||||
|
|
||||||
|
async def safe_parse_api_data(data: dict or list, *path: str or int, idx: int = 0):
|
||||||
|
path = [*path]
|
||||||
|
if len(path) == idx+1:
|
||||||
|
if isinstance(path[idx], str):
|
||||||
|
if isinstance(data, dict):
|
||||||
|
if path[idx] in data.keys():
|
||||||
|
return data[path[idx]]
|
||||||
|
elif isinstance(path[idx], int):
|
||||||
|
if isinstance(data, list):
|
||||||
|
if len(data) > path[idx]:
|
||||||
|
return data[path[idx]]
|
||||||
|
else:
|
||||||
|
if isinstance(path[idx], str):
|
||||||
|
if isinstance(data, dict):
|
||||||
|
if path[idx] in data.keys():
|
||||||
|
parsed_data = await safe_parse_api_data(data[path[idx]], idx=idx+1, *path)
|
||||||
|
if not parsed_data:
|
||||||
|
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
|
||||||
|
return parsed_data
|
||||||
|
else:
|
||||||
|
if idx == 0:
|
||||||
|
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
if idx == 0:
|
||||||
|
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
|
||||||
|
return False
|
||||||
|
elif isinstance(path[idx], int):
|
||||||
|
if isinstance(data, list):
|
||||||
|
if len(data) > path[idx]:
|
||||||
|
parsed_data = await safe_parse_api_data(data[path[idx]], idx=idx+1, *path)
|
||||||
|
if not parsed_data:
|
||||||
|
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
|
||||||
|
return parsed_data
|
||||||
|
else:
|
||||||
|
if idx == 0:
|
||||||
|
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
if idx == 0:
|
||||||
|
raise APIError(f"Data parsing failed on path index {idx} - \nKey: {path[idx]} \nData: {data}")
|
||||||
|
return False
|
||||||
11
main.py
11
main.py
@@ -4,6 +4,7 @@ import asyncio
|
|||||||
from API.bosminer import BOSMinerAPI
|
from API.bosminer import BOSMinerAPI
|
||||||
from API.cgminer import CGMinerAPI
|
from API.cgminer import CGMinerAPI
|
||||||
import sys
|
import sys
|
||||||
|
from cfg_util.func.data import safe_parse_api_data
|
||||||
|
|
||||||
|
|
||||||
# Fix bug with some whatsminers and asyncio because of a socket not being shut down:
|
# Fix bug with some whatsminers and asyncio because of a socket not being shut down:
|
||||||
@@ -42,8 +43,12 @@ async def braiins_update():
|
|||||||
async def test_command():
|
async def test_command():
|
||||||
miner_network = MinerNetwork('192.168.1.1')
|
miner_network = MinerNetwork('192.168.1.1')
|
||||||
miners = await miner_network.scan_network_for_miners()
|
miners = await miner_network.scan_network_for_miners()
|
||||||
tasks = miners[0].api.multicommand("summary", "pools", "tunerstatus")
|
tasks = [miner.api.summary() for miner in miners]
|
||||||
data = await asyncio.gather(tasks)
|
data = await asyncio.gather(*tasks)
|
||||||
|
parse_tasks = []
|
||||||
|
for item in data:
|
||||||
|
parse_tasks.append(safe_parse_api_data(item, 'SUMMARY', 0, 'MHS 5s'))
|
||||||
|
data = await asyncio.gather(*parse_tasks)
|
||||||
print(data)
|
print(data)
|
||||||
|
|
||||||
async def get_commands_from_miner_api():
|
async def get_commands_from_miner_api():
|
||||||
@@ -54,4 +59,4 @@ async def get_commands_from_miner_api():
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
asyncio.new_event_loop().run_until_complete(get_commands_from_miner_api())
|
asyncio.new_event_loop().run_until_complete(test_command())
|
||||||
|
|||||||
Reference in New Issue
Block a user