started adding the board utility
This commit is contained in:
@@ -1,14 +1 @@
|
|||||||
from cfg_util.cfg_util_sg.miner_factory import miner_factory
|
from cfg_util.cfg_util_sg import main
|
||||||
from cfg_util.cfg_util_sg.ui import ui
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import sys
|
|
||||||
|
|
||||||
# Fix bug with some whatsminers and asyncio because of a socket not being shut down:
|
|
||||||
if sys.version_info[0] == 3 and sys.version_info[1] >= 8 and sys.platform.startswith('win'):
|
|
||||||
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
loop = asyncio.new_event_loop()
|
|
||||||
loop.run_until_complete(ui())
|
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
from cfg_util.cfg_util_sg.miner_factory import miner_factory
|
||||||
|
from cfg_util.cfg_util_sg.ui import ui
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Fix bug with some whatsminers and asyncio because of a socket not being shut down:
|
||||||
|
if sys.version_info[0] == 3 and sys.version_info[1] >= 8 and sys.platform.startswith('win'):
|
||||||
|
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
loop = asyncio.new_event_loop()
|
||||||
|
loop.run_until_complete(ui())
|
||||||
|
|||||||
@@ -172,7 +172,8 @@ async def send_config(ips: list, config):
|
|||||||
async for _config_sender in config_sender_generator:
|
async for _config_sender in config_sender_generator:
|
||||||
progress_bar_len += 1
|
progress_bar_len += 1
|
||||||
asyncio.create_task(update_prog_bar(progress_bar_len))
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
await update_ui_with_data("status", "")
|
await update_ui_with_data("status", "Getting Data")
|
||||||
|
await asyncio.sleep(3)
|
||||||
await refresh_data(ips)
|
await refresh_data(ips)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -10,36 +10,32 @@ class HiveonT9(BMMiner):
|
|||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"HiveonT9: {str(self.ip)}"
|
return f"HiveonT9: {str(self.ip)}"
|
||||||
|
|
||||||
async def get_board_info(self) -> list:
|
async def get_board_info(self) -> dict:
|
||||||
"""Gets data on each board and chain in the miner."""
|
"""Gets data on each board and chain in the miner."""
|
||||||
board_stats = await self.api.stats()
|
board_stats = await self.api.stats()
|
||||||
stats = board_stats['STATS'][1]
|
stats = board_stats['STATS'][1]
|
||||||
boards = []
|
boards = {}
|
||||||
board_chains = {6: [2, 9, 10], 7: [3, 11, 12], 8: [4, 13, 14]}
|
board_chains = {6: [2, 9, 10], 7: [3, 11, 12], 8: [4, 13, 14]}
|
||||||
for idx, board in enumerate(board_chains):
|
for idx, board in enumerate(board_chains):
|
||||||
boards.append({"board": board, "chains": []})
|
boards[board] = []
|
||||||
for chain in board_chains[board]:
|
for chain in board_chains[board]:
|
||||||
count = stats[f"chain_acn{chain}"]
|
count = stats[f"chain_acn{chain}"]
|
||||||
chips = stats[f"chain_acs{chain}"].replace(" ", "")
|
chips = stats[f"chain_acs{chain}"].replace(" ", "")
|
||||||
boards[idx]["chains"].append({
|
boards[board].append({
|
||||||
"chain": chain,
|
"chain": chain,
|
||||||
"chip_count": count,
|
"chip_count": count,
|
||||||
"chip_status": chips
|
"chip_status": chips
|
||||||
})
|
})
|
||||||
return boards
|
return boards
|
||||||
|
|
||||||
async def get_bad_boards(self) -> list:
|
async def get_bad_boards(self) -> dict:
|
||||||
"""Checks for and provides list of non working boards."""
|
"""Checks for and provides list of non working boards."""
|
||||||
boards = await self.get_board_info()
|
boards = await self.get_board_info()
|
||||||
bad_boards = []
|
bad_boards = {}
|
||||||
idx = 0
|
for board in boards.keys():
|
||||||
for board in boards:
|
for chain in boards[board]:
|
||||||
bad_boards.append({"board": board["board"], "chains": []})
|
|
||||||
for chain in board["chains"]:
|
|
||||||
if not chain["chip_count"] == 18 or "x" in chain["chip_status"]:
|
if not chain["chip_count"] == 18 or "x" in chain["chip_status"]:
|
||||||
bad_boards[idx]["chains"].append(chain)
|
if board not in bad_boards.keys():
|
||||||
if not bad_boards[idx]["chains"]:
|
bad_boards[board] = []
|
||||||
del bad_boards[idx]
|
bad_boards[board].append(chain)
|
||||||
idx -= 1
|
return bad_boards
|
||||||
idx += 1
|
|
||||||
return bad_boards
|
|
||||||
@@ -80,3 +80,7 @@ class BMMiner(BaseMiner):
|
|||||||
|
|
||||||
async def get_config(self) -> None:
|
async def get_config(self) -> None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
async def get_board_info(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
|||||||
@@ -109,36 +109,33 @@ class BOSMiner(BaseMiner):
|
|||||||
await file.write(toml_conf)
|
await file.write(toml_conf)
|
||||||
await conn.run("/etc/init.d/bosminer restart")
|
await conn.run("/etc/init.d/bosminer restart")
|
||||||
|
|
||||||
async def get_board_info(self) -> list:
|
async def get_board_info(self) -> dict:
|
||||||
"""Gets data on each board and chain in the miner."""
|
"""Gets data on each board and chain in the miner."""
|
||||||
devdetails = await self.api.devdetails()
|
devdetails = await self.api.devdetails()
|
||||||
devs = devdetails['DEVDETAILS']
|
devs = devdetails['DEVDETAILS']
|
||||||
boards = []
|
boards = {}
|
||||||
for idx, board in enumerate(devs):
|
for board in devs:
|
||||||
boards.append({"board": board["ID"], "chains": []})
|
boards[board["ID"]] = []
|
||||||
boards[idx]["chains"].append({
|
boards[board["ID"]].append({
|
||||||
"chain": board["ID"],
|
"chain": board["ID"],
|
||||||
"chip_count": board['Chips'],
|
"chip_count": board['Chips'],
|
||||||
"chip_status": "o" * board['Chips']
|
"chip_status": "o" * board['Chips']
|
||||||
})
|
})
|
||||||
return boards
|
return boards
|
||||||
|
|
||||||
async def get_bad_boards(self) -> list:
|
async def get_bad_boards(self) -> dict:
|
||||||
"""Checks for and provides list of non working boards."""
|
"""Checks for and provides list of non working boards."""
|
||||||
boards = await self.get_board_info()
|
boards = await self.get_board_info()
|
||||||
bad_boards = []
|
bad_boards = {}
|
||||||
idx = 0
|
for board in boards.keys():
|
||||||
for board in boards:
|
for chain in boards[board]:
|
||||||
bad_boards.append({"board": board["board"], "chains": []})
|
|
||||||
for chain in board["chains"]:
|
|
||||||
if not chain["chip_count"] == 63:
|
if not chain["chip_count"] == 63:
|
||||||
bad_boards[idx]["chains"].append(chain)
|
if board not in bad_boards.keys():
|
||||||
if not bad_boards[idx]["chains"]:
|
bad_boards[board] = []
|
||||||
del bad_boards[idx]
|
bad_boards[board].append(chain)
|
||||||
idx -= 1
|
|
||||||
idx += 1
|
|
||||||
return bad_boards
|
return bad_boards
|
||||||
|
|
||||||
|
|
||||||
async def check_good_boards(self) -> str:
|
async def check_good_boards(self) -> str:
|
||||||
"""Checks for and provides list for working boards."""
|
"""Checks for and provides list for working boards."""
|
||||||
devs = await self.api.devdetails()
|
devs = await self.api.devdetails()
|
||||||
|
|||||||
@@ -40,3 +40,6 @@ class BTMiner(BaseMiner):
|
|||||||
|
|
||||||
async def get_config(self) -> None:
|
async def get_config(self) -> None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
async def get_board_info(self):
|
||||||
|
return None
|
||||||
|
|||||||
@@ -136,3 +136,6 @@ class CGMiner(BaseMiner):
|
|||||||
self._result_handler(result)
|
self._result_handler(result)
|
||||||
self.config = result.stdout
|
self.config = result.stdout
|
||||||
print(str(self.config))
|
print(str(self.config))
|
||||||
|
|
||||||
|
async def get_board_info(self):
|
||||||
|
return None
|
||||||
|
|||||||
@@ -18,3 +18,6 @@ class UnknownMiner(BaseMiner):
|
|||||||
|
|
||||||
async def get_hostname(self):
|
async def get_hostname(self):
|
||||||
return "Unknown"
|
return "Unknown"
|
||||||
|
|
||||||
|
async def get_board_info(self):
|
||||||
|
return None
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
from tools.bad_board_util.miner_factory import miner_factory
|
||||||
|
from tools.bad_board_util.ui import ui
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# Fix bug with some whatsminers and asyncio because of a socket not being shut down:
|
||||||
|
if sys.version_info[0] == 3 and sys.version_info[1] >= 8 and sys.platform.startswith('win'):
|
||||||
|
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
loop = asyncio.new_event_loop()
|
||||||
|
loop.run_until_complete(ui())
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|||||||
68
tools/bad_board_util/func/files.py
Normal file
68
tools/bad_board_util/func/files.py
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
import ipaddress
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import time
|
||||||
|
|
||||||
|
import aiofiles
|
||||||
|
import toml
|
||||||
|
|
||||||
|
from tools.bad_board_util.func.ui import update_ui_with_data
|
||||||
|
from tools.bad_board_util.layout import window
|
||||||
|
from config.bos import bos_config_convert, general_config_convert_bos
|
||||||
|
|
||||||
|
|
||||||
|
async def import_iplist(file_location):
|
||||||
|
await update_ui_with_data("status", "Importing")
|
||||||
|
if not os.path.exists(file_location):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
ip_list = []
|
||||||
|
async with aiofiles.open(file_location, mode='r') as file:
|
||||||
|
async for line in file:
|
||||||
|
ips = [x.group() for x in re.finditer(
|
||||||
|
"^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)", line)]
|
||||||
|
for ip in ips:
|
||||||
|
if ip not in ip_list:
|
||||||
|
ip_list.append(ipaddress.ip_address(ip))
|
||||||
|
ip_list.sort()
|
||||||
|
window["ip_table"].update([[str(ip), "", "", "", ""] for ip in ip_list])
|
||||||
|
await update_ui_with_data("ip_count", str(len(ip_list)))
|
||||||
|
await update_ui_with_data("status", "")
|
||||||
|
|
||||||
|
|
||||||
|
async def export_iplist(file_location, ip_list_selected):
|
||||||
|
await update_ui_with_data("status", "Exporting")
|
||||||
|
if not os.path.exists(file_location):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
if ip_list_selected is not None and not ip_list_selected == []:
|
||||||
|
async with aiofiles.open(file_location, mode='w') as file:
|
||||||
|
for item in ip_list_selected:
|
||||||
|
await file.write(str(item) + "\n")
|
||||||
|
else:
|
||||||
|
async with aiofiles.open(file_location, mode='w') as file:
|
||||||
|
for item in window['ip_table'].Values:
|
||||||
|
await file.write(str(item[0]) + "\n")
|
||||||
|
await update_ui_with_data("status", "")
|
||||||
|
|
||||||
|
|
||||||
|
async def import_config_file(file_location):
|
||||||
|
await update_ui_with_data("status", "Importing")
|
||||||
|
if not os.path.exists(file_location):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
async with aiofiles.open(file_location, mode='r') as file:
|
||||||
|
config = await file.read()
|
||||||
|
await update_ui_with_data("config", await bos_config_convert(toml.loads(config)))
|
||||||
|
await update_ui_with_data("status", "")
|
||||||
|
|
||||||
|
|
||||||
|
async def export_config_file(file_location, config):
|
||||||
|
await update_ui_with_data("status", "Exporting")
|
||||||
|
config = toml.loads(config)
|
||||||
|
config['format']['generator'] = 'upstream_config_util'
|
||||||
|
config['format']['timestamp'] = int(time.time())
|
||||||
|
config = toml.dumps(config)
|
||||||
|
async with aiofiles.open(file_location, mode='w+') as file:
|
||||||
|
await file.write(await general_config_convert_bos(config))
|
||||||
|
await update_ui_with_data("status", "")
|
||||||
171
tools/bad_board_util/func/miners.py
Normal file
171
tools/bad_board_util/func/miners.py
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
import asyncio
|
||||||
|
import ipaddress
|
||||||
|
import warnings
|
||||||
|
|
||||||
|
from tools.bad_board_util.func.ui import update_ui_with_data, update_prog_bar, set_progress_bar_len
|
||||||
|
from tools.bad_board_util.layout import window
|
||||||
|
from tools.bad_board_util.miner_factory import miner_factory
|
||||||
|
|
||||||
|
|
||||||
|
async def scan_network(network):
|
||||||
|
await update_ui_with_data("status", "Scanning")
|
||||||
|
await update_ui_with_data("ip_count", "")
|
||||||
|
window["ip_table"].update([])
|
||||||
|
network_size = len(network)
|
||||||
|
miner_generator = network.scan_network_generator()
|
||||||
|
await set_progress_bar_len(2 * network_size)
|
||||||
|
progress_bar_len = 0
|
||||||
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
|
miners = []
|
||||||
|
async for miner in miner_generator:
|
||||||
|
if miner:
|
||||||
|
miners.append(miner)
|
||||||
|
progress_bar_len += 1
|
||||||
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
|
progress_bar_len += network_size - len(miners)
|
||||||
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
|
get_miner_genenerator = miner_factory.get_miner_generator(miners)
|
||||||
|
all_miners = []
|
||||||
|
async for found_miner in get_miner_genenerator:
|
||||||
|
all_miners.append(found_miner)
|
||||||
|
all_miners.sort(key=lambda x: x.ip)
|
||||||
|
window["ip_table"].update([[str(miner.ip)] for miner in all_miners])
|
||||||
|
progress_bar_len += 1
|
||||||
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
|
await update_ui_with_data("ip_count", str(len(all_miners)))
|
||||||
|
await update_ui_with_data("status", "")
|
||||||
|
|
||||||
|
|
||||||
|
async def miner_light(ips: list):
|
||||||
|
await asyncio.gather(*[flip_light(ip) for ip in ips])
|
||||||
|
|
||||||
|
|
||||||
|
async def flip_light(ip):
|
||||||
|
ip_list = window['ip_table'].Widget
|
||||||
|
miner = await miner_factory.get_miner(ip)
|
||||||
|
index = [item[0] for item in window["ip_table"].Values].index(ip)
|
||||||
|
index_tags = ip_list.item(index)['tags']
|
||||||
|
if "light" not in index_tags:
|
||||||
|
ip_list.item(index, tags=([*index_tags, "light"]))
|
||||||
|
window['ip_table'].update(row_colors=[(index, "white", "red")])
|
||||||
|
await miner.fault_light_on()
|
||||||
|
else:
|
||||||
|
index_tags.remove("light")
|
||||||
|
ip_list.item(index, tags=index_tags)
|
||||||
|
window['ip_table'].update(row_colors=[(index, "black", "white")])
|
||||||
|
await miner.fault_light_off()
|
||||||
|
|
||||||
|
|
||||||
|
async def refresh_data(ip_list: list):
|
||||||
|
await update_ui_with_data("status", "Getting Data")
|
||||||
|
await update_ui_with_data("hr_total", "")
|
||||||
|
ips = [ipaddress.ip_address(ip) for ip in ip_list]
|
||||||
|
if len(ips) == 0:
|
||||||
|
ips = [ipaddress.ip_address(ip) for ip in [item[0] for item in window["ip_table"].Values]]
|
||||||
|
await set_progress_bar_len(len(ips))
|
||||||
|
progress_bar_len = 0
|
||||||
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
|
reset_table_values = []
|
||||||
|
for item in window["ip_table"].Values:
|
||||||
|
if item[0] in ip_list:
|
||||||
|
reset_table_values.append([item[0]])
|
||||||
|
else:
|
||||||
|
reset_table_values.append(item)
|
||||||
|
window["ip_table"].update(reset_table_values)
|
||||||
|
progress_bar_len = 0
|
||||||
|
data_gen = asyncio.as_completed([get_formatted_data(miner) for miner in ips])
|
||||||
|
ip_table_data = window["ip_table"].Values
|
||||||
|
ordered_all_ips = [item[0] for item in ip_table_data]
|
||||||
|
for all_data in data_gen:
|
||||||
|
data_point = await all_data
|
||||||
|
if data_point["IP"] in ordered_all_ips:
|
||||||
|
ip_table_index = ordered_all_ips.index(data_point["IP"])
|
||||||
|
ip_table_data[ip_table_index] = [
|
||||||
|
data_point["IP"], data_point["model"], data_point["host"], str(data_point['TH/s']) + " TH/s",
|
||||||
|
data_point["temp"],
|
||||||
|
data_point['user'], str(data_point['wattage']) + " W"
|
||||||
|
]
|
||||||
|
window["ip_table"].update(ip_table_data)
|
||||||
|
progress_bar_len += 1
|
||||||
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
|
|
||||||
|
hashrate_list = []
|
||||||
|
hr_idx = 3
|
||||||
|
for item, _ in enumerate(window["ip_table"].Values):
|
||||||
|
if len(window["ip_table"].Values[item]) > hr_idx:
|
||||||
|
if not window["ip_table"].Values[item][hr_idx] == '':
|
||||||
|
hashrate_list.append(float(window["ip_table"].Values[item][hr_idx].replace(" TH/s", "")))
|
||||||
|
else:
|
||||||
|
hashrate_list.append(0)
|
||||||
|
else:
|
||||||
|
hashrate_list.append(0)
|
||||||
|
|
||||||
|
total_hr = round(sum(hashrate_list), 2)
|
||||||
|
window["hr_total"].update(f"{total_hr} TH/s")
|
||||||
|
|
||||||
|
await update_ui_with_data("status", "")
|
||||||
|
|
||||||
|
|
||||||
|
async def scan_and_get_data(network):
|
||||||
|
await update_ui_with_data("status", "Scanning")
|
||||||
|
await update_ui_with_data("ip_count", "")
|
||||||
|
await update_ui_with_data("ip_table", [])
|
||||||
|
network_size = len(network)
|
||||||
|
miner_generator = network.scan_network_generator()
|
||||||
|
await set_progress_bar_len(3 * network_size)
|
||||||
|
progress_bar_len = 0
|
||||||
|
miners = []
|
||||||
|
async for miner in miner_generator:
|
||||||
|
if miner:
|
||||||
|
miners.append(miner)
|
||||||
|
# can output "Identifying" for each found item, but it gets a bit cluttered
|
||||||
|
# and could possibly be confusing for the end user because of timing on
|
||||||
|
# adding the IPs
|
||||||
|
# window["ip_table"].update([["Identifying..."] for miner in miners])
|
||||||
|
progress_bar_len += 1
|
||||||
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
|
progress_bar_len += network_size - len(miners)
|
||||||
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
|
get_miner_genenerator = miner_factory.get_miner_generator(miners)
|
||||||
|
all_miners = []
|
||||||
|
async for found_miner in get_miner_genenerator:
|
||||||
|
all_miners.append(found_miner)
|
||||||
|
all_miners.sort(key=lambda x: x.ip)
|
||||||
|
window["ip_table"].update([[str(miner.ip)] for miner in all_miners])
|
||||||
|
progress_bar_len += 1
|
||||||
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
|
await update_ui_with_data("ip_count", str(len(all_miners)))
|
||||||
|
data_gen = asyncio.as_completed([get_formatted_data(miner) for miner in miners])
|
||||||
|
ip_table_data = window["ip_table"].Values
|
||||||
|
ordered_all_ips = [item[0] for item in ip_table_data]
|
||||||
|
progress_bar_len += (network_size - len(miners))
|
||||||
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
|
await update_ui_with_data("status", "Getting Data")
|
||||||
|
for all_data in data_gen:
|
||||||
|
data_point = await all_data
|
||||||
|
if data_point["IP"] in ordered_all_ips:
|
||||||
|
ip_table_index = ordered_all_ips.index(data_point["IP"])
|
||||||
|
board_6 = " ".join([chain["chip_status"] for chain in data_point["data"][6]]).replace("o", "•")
|
||||||
|
board_7 = " ".join([chain["chip_status"] for chain in data_point["data"][7]]).replace("o", "•")
|
||||||
|
board_8 = " ".join([chain["chip_status"] for chain in data_point["data"][8]]).replace("o", "•")
|
||||||
|
data = [
|
||||||
|
data_point["IP"],
|
||||||
|
data_point["model"],
|
||||||
|
board_6,
|
||||||
|
board_7,
|
||||||
|
board_8
|
||||||
|
]
|
||||||
|
ip_table_data[ip_table_index] = data
|
||||||
|
window["ip_table"].update(ip_table_data)
|
||||||
|
progress_bar_len += 1
|
||||||
|
asyncio.create_task(update_prog_bar(progress_bar_len))
|
||||||
|
await update_ui_with_data("status", "")
|
||||||
|
|
||||||
|
|
||||||
|
async def get_formatted_data(ip: ipaddress.ip_address):
|
||||||
|
miner = await miner_factory.get_miner(ip)
|
||||||
|
model = await miner.get_model()
|
||||||
|
warnings.filterwarnings('ignore')
|
||||||
|
board_data = await miner.get_board_info()
|
||||||
|
data = {"IP": str(ip), "model": model, "data": board_data}
|
||||||
|
return data
|
||||||
50
tools/bad_board_util/func/parse_data.py
Normal file
50
tools/bad_board_util/func/parse_data.py
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
from API import APIError
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyPep8
|
||||||
|
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)
|
||||||
|
# has to be == None, or else it fails on 0.0 hashrates
|
||||||
|
# noinspection PyPep8
|
||||||
|
if parsed_data == None:
|
||||||
|
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)
|
||||||
|
# has to be == None, or else it fails on 0.0 hashrates
|
||||||
|
# noinspection PyPep8
|
||||||
|
if parsed_data == None:
|
||||||
|
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
|
||||||
72
tools/bad_board_util/func/ui.py
Normal file
72
tools/bad_board_util/func/ui.py
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import ipaddress
|
||||||
|
import re
|
||||||
|
|
||||||
|
from tools.bad_board_util.layout import window
|
||||||
|
|
||||||
|
import pyperclip
|
||||||
|
|
||||||
|
|
||||||
|
def copy_from_table(table):
|
||||||
|
selection = table.selection()
|
||||||
|
copy_values = []
|
||||||
|
for each in selection:
|
||||||
|
try:
|
||||||
|
value = table.item(each)["values"][0]
|
||||||
|
copy_values.append(str(value))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
copy_string = "\n".join(copy_values)
|
||||||
|
pyperclip.copy(copy_string)
|
||||||
|
|
||||||
|
|
||||||
|
async def update_ui_with_data(key, message, append=False):
|
||||||
|
if append:
|
||||||
|
message = window[key].get_text() + message
|
||||||
|
window[key].update(message)
|
||||||
|
|
||||||
|
|
||||||
|
async def update_prog_bar(amount):
|
||||||
|
window["progress"].Update(amount)
|
||||||
|
percent_done = 100 * (amount / window['progress'].maxlen)
|
||||||
|
window["progress_percent"].Update(f"{round(percent_done, 2)} %")
|
||||||
|
if percent_done == 100:
|
||||||
|
window["progress_percent"].Update("")
|
||||||
|
|
||||||
|
|
||||||
|
async def set_progress_bar_len(amount):
|
||||||
|
window["progress"].Update(0, max=amount)
|
||||||
|
window["progress"].maxlen = amount
|
||||||
|
window["progress_percent"].Update("0.0 %")
|
||||||
|
|
||||||
|
|
||||||
|
async def sort_data(index: int or str):
|
||||||
|
await update_ui_with_data("status", "Sorting Data")
|
||||||
|
data_list = window['ip_table'].Values
|
||||||
|
|
||||||
|
# wattage
|
||||||
|
if re.match("[0-9]* W", str(data_list[0][index])):
|
||||||
|
new_list = sorted(data_list, key=lambda x: int(x[index].replace(" W", "")))
|
||||||
|
if data_list == new_list:
|
||||||
|
new_list = sorted(data_list, reverse=True, key=lambda x: int(x[index].replace(" W", "")))
|
||||||
|
|
||||||
|
# hashrate
|
||||||
|
elif re.match("[0-9]*\.?[0-9]* TH\/s", str(data_list[0][index])):
|
||||||
|
new_list = sorted(data_list, key=lambda x: float(x[index].replace(" TH/s", "")))
|
||||||
|
if data_list == new_list:
|
||||||
|
new_list = sorted(data_list, reverse=True, key=lambda x: float(x[index].replace(" TH/s", "")))
|
||||||
|
|
||||||
|
# ip addresses
|
||||||
|
elif re.match("^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",
|
||||||
|
str(data_list[0][index])):
|
||||||
|
new_list = sorted(data_list, key=lambda x: ipaddress.ip_address(x[index]))
|
||||||
|
if data_list == new_list:
|
||||||
|
new_list = sorted(data_list, reverse=True, key=lambda x: ipaddress.ip_address(x[index]))
|
||||||
|
|
||||||
|
# everything else, hostname, temp, and user
|
||||||
|
else:
|
||||||
|
new_list = sorted(data_list, key=lambda x: x[index])
|
||||||
|
if data_list == new_list:
|
||||||
|
new_list = sorted(data_list, reverse=True, key=lambda x: x[index])
|
||||||
|
|
||||||
|
await update_ui_with_data("ip_table", new_list)
|
||||||
|
await update_ui_with_data("status", "")
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,52 @@
|
|||||||
|
import asyncio
|
||||||
|
import sys
|
||||||
|
import PySimpleGUI as sg
|
||||||
|
|
||||||
|
from tools.bad_board_util.layout import window
|
||||||
|
from tools.bad_board_util.func.miners import refresh_data, scan_and_get_data, miner_light
|
||||||
|
from tools.bad_board_util.func.files import import_iplist, export_iplist
|
||||||
|
from tools.bad_board_util.func.ui import sort_data, copy_from_table
|
||||||
|
|
||||||
|
from network import MinerNetwork
|
||||||
|
|
||||||
|
import webbrowser
|
||||||
|
|
||||||
|
|
||||||
|
async def ui():
|
||||||
|
window.read(timeout=0)
|
||||||
|
table = window["ip_table"].Widget
|
||||||
|
table.bind("<Control-Key-c>", lambda x: copy_from_table(table))
|
||||||
|
while True:
|
||||||
|
event, value = window.read(timeout=0)
|
||||||
|
if event in (None, 'Close', sg.WIN_CLOSED):
|
||||||
|
sys.exit()
|
||||||
|
if isinstance(event, tuple):
|
||||||
|
if len(window["ip_table"].Values) > 0:
|
||||||
|
if event[0] == 'ip_table':
|
||||||
|
if event[2][0] == -1:
|
||||||
|
await sort_data(event[2][1])
|
||||||
|
if event == 'open_in_web':
|
||||||
|
for row in value["ip_table"]:
|
||||||
|
webbrowser.open("http://" + window["ip_table"].Values[row][0])
|
||||||
|
if event == 'scan':
|
||||||
|
if len(value['miner_network'].split("/")) > 1:
|
||||||
|
network = value['miner_network'].split("/")
|
||||||
|
miner_network = MinerNetwork(ip_addr=network[0], mask=network[1])
|
||||||
|
else:
|
||||||
|
miner_network = MinerNetwork(value['miner_network'])
|
||||||
|
asyncio.create_task(scan_and_get_data(miner_network))
|
||||||
|
if event == 'select_all_ips':
|
||||||
|
if len(value["ip_table"]) == len(window["ip_table"].Values):
|
||||||
|
window["ip_table"].update(select_rows=())
|
||||||
|
else:
|
||||||
|
window["ip_table"].update(select_rows=([row for row in range(len(window["ip_table"].Values))]))
|
||||||
|
if event == 'light':
|
||||||
|
asyncio.create_task(miner_light([window['ip_table'].Values[item][0] for item in value['ip_table']]))
|
||||||
|
if event == "import_iplist":
|
||||||
|
asyncio.create_task(import_iplist(value["file_iplist"]))
|
||||||
|
if event == "export_iplist":
|
||||||
|
asyncio.create_task(export_iplist(value["file_iplist"], [window['ip_table'].Values[item][0] for item in value['ip_table']]))
|
||||||
|
if event == "refresh_data":
|
||||||
|
asyncio.create_task(refresh_data([window["ip_table"].Values[item][0] for item in value["ip_table"]]))
|
||||||
|
if event == "__TIMEOUT__":
|
||||||
|
await asyncio.sleep(0)
|
||||||
|
|||||||
Reference in New Issue
Block a user