split out cfg_util into its own module

This commit is contained in:
UpstreamData
2021-11-03 13:38:39 -06:00
parent 7f0bd87ed1
commit 751bc1ee51
6 changed files with 342 additions and 326 deletions

10
cfg_util/__init__.py Normal file
View File

@@ -0,0 +1,10 @@
from cfg_util.miner_factory import miner_factory
from cfg_util.layout import window
from cfg_util.ui import ui
import asyncio
def main():
loop = asyncio.new_event_loop()
loop.run_until_complete(ui())

239
cfg_util/func.py Normal file
View File

@@ -0,0 +1,239 @@
import ipaddress
import os
import re
import time
from operator import itemgetter
import asyncio
import aiofiles
import toml
from cfg_util.miner_factory import miner_factory
from cfg_util.layout import window
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):
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", str(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")
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", 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])
total_hr = round(sum(d.get('TH/s', 0) for d in data), 2)
window["hr_total"].update(f"{total_hr} TH/s")
window["hr_list"].update(disabled=False)
window["hr_list"].update([item['IP'] + " | "
+ item['host'] + " | "
+ str(item['TH/s']) + " TH/s | "
+ item['user'] + " | "
+ str(item['wattage']) + " W"
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):
# TODO: Fix bug with some whatsminers and asyncio:
# Traceback (most recent call last):
# File "C:\Users\upstr\AppData\Local\Programs\Python\Python310\lib\asyncio\events.py", line 80, in _run
# self._context.run(self._callback, *self._args)
# File "C:\Users\upstr\AppData\Local\Programs\Python\Python310\lib\asyncio\proactor_events.py", line 162, in _call_connection_lost
# self._sock.shutdown(socket.SHUT_RDWR)
# OSError: [WinError 10038] An operation was attempted on something that is not a socket
miner = await miner_factory.get_miner(ip)
data = await miner.api.multicommand("summary", "pools", "tunerstatus")
host = await miner.get_hostname()
if "tunerstatus" in data.keys():
wattage = data['tunerstatus'][0]['TUNERSTATUS'][0]['PowerLimit']
else:
wattage = 0
if "summary" in data.keys():
if 'MHS 5s' in data['summary'][0]['SUMMARY'][0].keys():
th5s = round(data['summary'][0]['SUMMARY'][0]['MHS 5s'] / 1000000, 2)
elif 'GHS 5s' in data['summary'][0]['SUMMARY'][0].keys():
if not data['summary'][0]['SUMMARY'][0]['GHS 5s'] == "":
th5s = round(float(data['summary'][0]['SUMMARY'][0]['GHS 5s']) / 1000, 2)
else:
th5s = 0
else:
th5s = 0
else:
th5s = 0
user = data['pools'][0]['POOLS'][0]['User']
return {'TH/s': th5s, 'IP': str(miner.ip), 'host': host, 'user': user, 'wattage': wattage}
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 or str):
await update_ui_with_data("status", "Sorting Data")
data_list = window['hr_list'].Values
new_list = []
indexes = {}
for item in data_list:
item_data = [part.strip() for part in item.split("|")]
for idx, part in enumerate(item_data):
if re.match("[0-9]* W", part):
item_data[idx] = item_data[idx].replace(" W", "")
indexes['wattage'] = idx
elif re.match("[0-9]*\.?[0-9]* TH\/s", part):
item_data[idx] = item_data[idx].replace(" TH/s", "")
indexes['hr'] = idx
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]?)", part):
item_data[idx] = ipaddress.ip_address(item_data[idx])
indexes['ip'] = idx
new_list.append(item_data)
if not isinstance(index, str):
if index == indexes['hr']:
new_data_list = sorted(new_list, key=lambda x: float(x[index]))
else:
new_data_list = sorted(new_list, key=itemgetter(index))
else:
if index.lower() not in indexes.keys():
return
elif index.lower() == 'hr':
new_data_list = sorted(new_list, key=lambda x: float(x[indexes[index]]))
else:
new_data_list = sorted(new_list, key=itemgetter(indexes[index]))
new_ip_list = []
for item in new_data_list:
new_ip_list.append(item[indexes['ip']])
new_data_list = [str(item[indexes['ip']]) + " | "
+ item[1] + " | "
+ item[indexes['hr']] + " TH/s | "
+ item[3] + " | "
+ str(item[indexes['wattage']]) + " W"
for item in new_data_list]
window["hr_list"].update(disabled=False)
window["hr_list"].update(new_data_list)
window['ip_list'].update(new_ip_list)
window["hr_list"].update(disabled=True)
await update_ui_with_data("status", "")

34
cfg_util/layout.py Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
from miners.miner_factory import MinerFactory
miner_factory = MinerFactory()

54
cfg_util/ui.py Normal file
View File

@@ -0,0 +1,54 @@
import asyncio
import sys
from cfg_util.layout import window
from cfg_util.func import scan_network, sort_data, send_config, miner_light, get_data, export_config_file, \
generate_config, import_config, import_iplist, import_config_file
from network import MinerNetwork
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'], 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('ip'))
if event == "sort_data_hr":
asyncio.create_task(sort_data('hr'))
if event == "sort_data_user":
asyncio.create_task(sort_data(3))
if event == "sort_data_w":
asyncio.create_task(sort_data('wattage'))
if event == "__TIMEOUT__":
await asyncio.sleep(0)

File diff suppressed because one or more lines are too long