Files
pyasic/config_tool.py
2021-10-19 16:48:55 -06:00

266 lines
9.9 KiB
Python

import asyncio
import ipaddress
import os
import re
import sys
import time
from operator import itemgetter
import PySimpleGUI as sg
import aiofiles
import toml
from miners.miner_factory import MinerFactory
from network import MinerNetwork
layout = [
[sg.Text('Network IP: '), sg.InputText(key='miner_network', do_not_clear=True, size=(90, 1)),
sg.Button('Scan', key='scan'),
sg.Text("", key="status")],
[sg.Text('IP List File: '), sg.Input(key="file_iplist", do_not_clear=True, size=(90, 1)), sg.FileBrowse(),
sg.Button('Import', key="import_iplist")],
[sg.Text('Config File: '), sg.Input(key="file_config", do_not_clear=True, size=(90, 1)), sg.FileBrowse(),
sg.Button('Import', key="import_file_config"), sg.Button('Export', key="export_file_config")],
[
sg.Column([
[sg.Text("IP List:", pad=(0, 0)), sg.Text("", key="ip_count", pad=(1, 0), size=(3, 1)),
sg.Button('ALL', key="select_all_ips")],
[sg.Listbox([], size=(20, 32), key="ip_list", select_mode='extended')]
]),
sg.Column([
[sg.Text("Data: ", pad=(0, 0)), sg.Button('GET', key="get_data"), sg.Button('SORT IP', key="sort_data_ip"), sg.Button('SORT HR', key="sort_data_hr"), sg.Button('SORT USER', key="sort_data_user")],
[sg.Listbox([], size=(50, 32), key="hr_list")]
]),
sg.Column([
[sg.Text("Config"), sg.Button("IMPORT", key="import_config"), sg.Button("CONFIG", key="send_config"),
sg.Button("LIGHT", key="light"), sg.Button("GENERATE", key="generate_config")],
[sg.Multiline(size=(50, 34), key="config", do_not_clear=True)],
])
],
]
window = sg.Window('Upstream Config Util', layout)
miner_factory = MinerFactory()
async def update_ui_with_data(key, data, append=False):
if append:
data = window[key].get_text() + data
window[key].update(data)
async def scan_network(network):
global window
await update_ui_with_data("status", "Scanning")
miners = await network.scan_network_for_miners()
window["ip_list"].update([str(miner.ip) for miner in miners])
await update_ui_with_data("ip_count", str(len(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):
listbox = window['ip_list'].Widget
miner = await miner_factory.get_miner(ip)
if ip in window["ip_list"].Values:
index = window["ip_list"].Values.index(ip)
if listbox.itemcget(index, "background") == 'red':
listbox.itemconfigure(index, bg='#f0f3f7', fg='#000000')
await miner.fault_light_off()
else:
listbox.itemconfigure(index, bg='red', fg='white')
await miner.fault_light_on()
async def import_config(ip):
await update_ui_with_data("status", "Importing")
miner = await miner_factory.get_miner(ipaddress.ip_address(*ip))
await miner.get_config()
config = miner.config
await update_ui_with_data("config", toml.dumps(config))
await update_ui_with_data("status", "")
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_list"].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 send_config(ips: list, config):
await update_ui_with_data("status", "Configuring")
config['format']['generator'] = 'upstream_config_util'
config['format']['timestamp'] = int(time.time())
tasks = []
for ip in ips:
tasks.append(miner_factory.get_miner(ip))
miners = await asyncio.gather(*tasks)
tasks = []
for miner in miners:
tasks.append(miner.send_config(config))
await asyncio.gather(*tasks)
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", str(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(config)
await update_ui_with_data("status", "")
async def get_data(ip_list: list):
await update_ui_with_data("status", "Getting Data")
ips = [ipaddress.ip_address(ip) for ip in ip_list]
ips.sort()
data = await asyncio.gather(*[get_formatted_data(miner) for miner in ips])
window["hr_list"].update(disabled=False)
window["hr_list"].update([item['IP'] + " | " + str(item['TH/s']) + " TH/s | " + item['user'] for item in data])
window["hr_list"].update(disabled=True)
await update_ui_with_data("status", "")
async def get_formatted_data(ip: ipaddress.ip_address):
miner = await miner_factory.get_miner(ip)
data = await miner.api.multicommand("summary", "pools")
mh5s = round(data['summary'][0]['SUMMARY'][0]['MHS 5s'] / 1000000, 2)
user = data['pools'][0]['POOLS'][0]['User']
return {'TH/s': mh5s, 'IP': str(miner.ip), 'user': user}
async def generate_config():
config = {'group': [{
'name': 'group',
'quota': 1,
'pool': [{
'url': 'stratum2+tcp://us-east.stratum.slushpool.com/u95GEReVMjK6k5YqiSFNqqTnKU4ypU2Wm8awa6tmbmDmk1bWt',
'user': 'UpstreamDataInc.test',
'password': '123'
}, {
'url': 'stratum2+tcp://stratum.slushpool.com/u95GEReVMjK6k5YqiSFNqqTnKU4ypU2Wm8awa6tmbmDmk1bWt',
'user': 'UpstreamDataInc.test',
'password': '123'
}, {
'url': 'stratum+tcp://stratum.slushpool.com:3333',
'user': 'UpstreamDataInc.test',
'password': '123'
}]
}],
'format': {
'version': '1.2+',
'model': 'Antminer S9',
'generator': 'upstream_config_util',
'timestamp': int(time.time())
},
'temp_control': {
'target_temp': 80.0,
'hot_temp': 90.0,
'dangerous_temp': 120.0
},
'autotuning': {
'enabled': True,
'psu_power_limit': 900
}
}
window['config'].update(toml.dumps(config))
async def sort_data(index: int):
await update_ui_with_data("status", "Sorting Data")
data_list = window['hr_list'].Values
new_list = []
for item in data_list:
item_data = [part.strip() for part in item.split("|")]
item_data[1] = item_data[1].replace(" TH/s", "")
item_data[0] = ipaddress.ip_address(item_data[0])
new_list.append(item_data)
if index == 1:
new_data_list = sorted(new_list, key=lambda x: float(x[index]))
else:
new_data_list = sorted(new_list, key=itemgetter(index))
new_data_list = [str(item[0]) + " | " + item[1] + " TH/s | " + item[2] for item in new_data_list]
window["hr_list"].update(disabled=False)
window["hr_list"].update(new_data_list)
window["hr_list"].update(disabled=True)
await update_ui_with_data("status", "")
async def ui():
while True:
event, value = window.read(timeout=10)
if event in (None, 'Close'):
sys.exit()
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_network(miner_network))
if event == 'select_all_ips':
if value['ip_list'] == window['ip_list'].Values:
window['ip_list'].set_value([])
else:
window['ip_list'].set_value(window['ip_list'].Values)
if event == 'import_config':
if 2 > len(value['ip_list']) > 0:
asyncio.create_task(import_config(value['ip_list']))
if event == 'light':
asyncio.create_task(miner_light(value['ip_list']))
if event == "import_iplist":
asyncio.create_task(import_iplist(value["file_iplist"]))
if event == "send_config":
asyncio.create_task(send_config(value['ip_list'], toml.loads(value['config'])))
if event == "import_file_config":
asyncio.create_task(import_config_file(value['file_config']))
if event == "export_file_config":
asyncio.create_task(export_config_file(value['file_config'], value["config"]))
if event == "get_data":
asyncio.create_task(get_data(value['ip_list']))
if event == "generate_config":
asyncio.create_task(generate_config())
if event == "sort_data_ip":
asyncio.create_task(sort_data(0))
if event == "sort_data_hr":
asyncio.create_task(sort_data(1))
if event == "sort_data_user":
print()
asyncio.create_task(sort_data(2))
if event == "__TIMEOUT__":
await asyncio.sleep(0)
if __name__ == '__main__':
loop = asyncio.new_event_loop()
loop.run_until_complete(ui())