completed basic recording functionality

This commit is contained in:
UpstreamData
2022-06-02 14:17:08 -06:00
parent e7d269008c
commit 64018cdad8
5 changed files with 216 additions and 32 deletions

View File

@@ -1,21 +1,20 @@
from typing import List
from tools.cfg_util.record.manager import RecordingManager
from tools.cfg_util.record.layout import record_window
import PySimpleGUI as sg
async def start_recording(ips: List[str], file: str, interval: int = 10):
async def start_recording(
ips: List[str], file: str, record_window: sg.Window, interval: int = 10
):
record_window["start_recording"].update(visible=False)
record_window["stop_recording"].update(visible=True)
record_window["pause_recording"].update(visible=True)
record_window["resume_recording"].update(visible=False)
record_window["_placeholder"].update(visible=False)
await RecordingManager().record(
ips,
file,
)
await RecordingManager().record(ips, file, record_window, interval=interval)
async def pause_recording():
async def pause_recording(record_window):
await RecordingManager().pause()
record_window["resume_recording"].update(visible=True)
record_window["start_recording"].update(visible=False)
@@ -23,7 +22,7 @@ async def pause_recording():
record_window["pause_recording"].update(visible=False)
async def stop_recording():
async def stop_recording(record_window):
await RecordingManager().stop()
record_window["start_recording"].update(visible=True)
record_window["stop_recording"].update(visible=False)
@@ -32,7 +31,7 @@ async def stop_recording():
record_window["_placeholder"].update(visible=True)
async def resume_recording():
async def resume_recording(record_window):
await RecordingManager().resume()
record_window["start_recording"].update(visible=False)
record_window["stop_recording"].update(visible=True)

View File

@@ -104,4 +104,5 @@ def record_layout():
return record_layout
record_window = sg.Window("Record Miner Data", record_layout(), modal=True)
def get_record_window():
return sg.Window("Record Miner Data", record_layout(), modal=True)

View File

@@ -1,6 +1,6 @@
import asyncio
from tools.cfg_util.record.layout import record_window
from tools.cfg_util.record.pdf import generate_pdf
from miners.miner_factory import MinerFactory
@@ -27,14 +27,15 @@ class RecordingManager(metaclass=Singleton):
self.miners = []
self.output_file = None
self.interval = 10
self.record_window = None
async def _check_pause(self):
if self.state == PAUSING:
self.state = PAUSED
record_window["record_status"].update("Paused.")
self.record_window["record_status"].update("Paused.")
while not self.state == RESUMING and not self.state == STOPPING:
await asyncio.sleep(0.1)
record_window["record_status"].update("Recording...")
self.record_window["record_status"].update("Recording...")
async def _record_loop(self):
while True:
@@ -58,36 +59,39 @@ class RecordingManager(metaclass=Singleton):
await asyncio.sleep(0.1)
self.state = DONE
record_window["record_status"].update("Writing to file...")
await self.write_output()
record_window["record_status"].update("")
self.record_window["record_status"].update(
"Writing to file (this could take a minute)..."
)
await asyncio.sleep(0.5)
await asyncio.create_task(self.write_output())
self.record_window["record_status"].update("")
async def write_output(self):
from pprint import pprint
await generate_pdf(self.data, self.output_file)
pprint(self.data)
async def record(self, ips: List[str], output_file: str, interval: int = 10):
async def record(
self, ips: List[str], output_file: str, record_window, interval: int = 10
):
self.record_window = record_window
for ip in ips:
self.data[ip] = []
self.output_file = output_file
self.interval = interval
self.state = RECORDING
record_window["record_status"].update("Recording...")
self.record_window["record_status"].update("Recording...")
async for miner in MinerFactory().get_miner_generator(ips):
self.miners.append(miner)
print(miner)
asyncio.create_task(self._record_loop())
async def pause(self):
self.state = PAUSING
record_window["record_status"].update("Pausing...")
self.record_window["record_status"].update("Pausing...")
async def resume(self):
self.state = RESUMING
record_window["record_status"].update("Resuming...")
self.record_window["record_status"].update("Resuming...")
async def stop(self):
self.state = STOPPING
record_window["record_status"].update("Stopping...")
self.record_window["record_status"].update("Stopping...")

View File

@@ -0,0 +1,177 @@
from datetime import datetime, timedelta
from typing import List, Dict
from data import MinerData
import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator
from matplotlib.dates import DateFormatter
import numpy as np
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter, inch
from reportlab.lib.styles import (
ParagraphStyle,
TA_CENTER, # noqa - not declared in __all__
)
from reportlab.lib.utils import ImageReader
from reportlab.platypus import (
SimpleDocTemplate,
KeepInFrame,
Table,
Image,
Paragraph,
TableStyle,
PageBreak,
Spacer,
)
from io import BytesIO
from svglib.svglib import svg2rlg
async def generate_pdf(data: Dict[str, List[MinerData]], file_loc):
doc = SimpleDocTemplate(
file_loc,
pagesize=letter,
topMargin=0.25 * inch,
leftMargin=1 * inch,
rightMargin=1 * inch,
bottomMargin=1 * inch,
title=f"Recorded Data",
)
elements = []
i = 0
for item in data.keys():
i += 1
if not i == 1:
elements.append(PageBreak())
page_elem = await generate_page(data[item])
for elem in page_elem:
elements.append(elem)
doc.build(
elements,
)
async def generate_page(data):
title_style = ParagraphStyle(
"Title",
alignment=TA_CENTER,
fontSize=25,
spaceAfter=40,
spaceBefore=150,
fontName="Helvetica-Bold",
)
hr_graph = create_hr_graph(data)
fan_graph = create_fans_graph(data)
temp_graph = create_temp_graph(data)
title = Paragraph(data[0].ip, style=title_style)
elements = [
title,
await hr_graph,
Spacer(0, 40),
await temp_graph,
Spacer(0, 40),
await fan_graph,
]
return elements
async def create_hr_graph(data):
fig, ax = plt.subplots(figsize=(6, 2))
xpoints = []
ypoints = []
for item in data:
xpoints.append(item.datetime)
ypoints.append(item.hashrate)
for label in ax.get_xticklabels() + ax.get_yticklabels():
label.set_fontsize(6)
ax.plot(xpoints, ypoints)
ax.set_ylim(0, max(ypoints) * 1.4)
date_form = DateFormatter("%H:%M:%S")
ax.xaxis.set_major_formatter(date_form)
ax.yaxis.set_major_formatter("{x:1.1f} TH/s")
ax.set_title("Hashrate", fontsize=15)
ax.yaxis.set_major_locator(MultipleLocator(5))
ax.yaxis.set_minor_locator(MultipleLocator(1))
imgdata = BytesIO()
fig.savefig(imgdata, format="svg")
imgdata.seek(0) # rewind the data
drawing = svg2rlg(imgdata)
imgdata.close()
plt.close("all")
hr_graph = KeepInFrame(375, 375, [Image(drawing)], hAlign="CENTER")
return hr_graph
async def create_fans_graph(data):
fig, ax = plt.subplots(figsize=(6, 2))
xpoints = []
ypoints_f1 = []
ypoints_f2 = []
ypoints_f3 = []
ypoints_f4 = []
for item in data:
xpoints.append(item.datetime)
ypoints_f1.append(item.fan_1)
ypoints_f2.append(item.fan_2)
ypoints_f3.append(item.fan_3)
ypoints_f4.append(item.fan_4)
for label in ax.get_xticklabels() + ax.get_yticklabels():
label.set_fontsize(6)
for ypoints in [ypoints_f1, ypoints_f2, ypoints_f3, ypoints_f4]:
if not ypoints == [-1 for x in range(len(ypoints))]:
ax.plot(xpoints, ypoints)
ax.set_ylim(0, 10000)
date_form = DateFormatter("%H:%M:%S")
ax.xaxis.set_major_formatter(date_form)
ax.yaxis.set_major_formatter("{x:1.0f} RPM")
ax.set_title("Fans", fontsize=15)
imgdata = BytesIO()
fig.savefig(imgdata, format="svg")
imgdata.seek(0) # rewind the data
drawing = svg2rlg(imgdata)
imgdata.close()
plt.close("all")
fans_graph = KeepInFrame(375, 375, [Image(drawing)], hAlign="CENTER")
return fans_graph
async def create_temp_graph(data):
fig, ax = plt.subplots(figsize=(6, 2))
# plt.figure()
xpoints = []
ypoints = []
for item in data:
xpoints.append(item.datetime)
ypoints.append(item.temperature_avg)
for label in ax.get_xticklabels() + ax.get_yticklabels():
label.set_fontsize(6)
ax.plot(xpoints, ypoints)
ax.set_ylim(0, 130)
ax.yaxis.set_major_locator(MultipleLocator(20))
ax.yaxis.set_minor_locator(MultipleLocator(5))
date_form = DateFormatter("%H:%M:%S")
ax.xaxis.set_major_formatter(date_form)
ax.yaxis.set_major_formatter("{x:1.1f} C")
ax.set_title("Temperature", fontsize=15)
imgdata = BytesIO()
fig.savefig(imgdata, format="svg")
imgdata.seek(0) # rewind the data
drawing = svg2rlg(imgdata)
imgdata.close()
plt.close("all")
temp_graph = KeepInFrame(375, 375, [Image(drawing)], hAlign="CENTER")
return temp_graph

View File

@@ -1,7 +1,7 @@
import asyncio
import PySimpleGUI as sg
from tools.cfg_util.record.layout import record_window
from tools.cfg_util.record.layout import get_record_window
from tools.cfg_util.record.func import (
start_recording,
stop_recording,
@@ -11,8 +11,9 @@ from tools.cfg_util.record.func import (
async def record_ui(ips: list):
# if not len(ips) > 0:
# return
if not len(ips) > 0:
return
record_window = get_record_window()
while True:
event, values = record_window.read(0.001)
if event in (None, "Close", sg.WIN_CLOSED):
@@ -20,13 +21,15 @@ async def record_ui(ips: list):
if event == "start_recording":
if values["record_file"]:
asyncio.create_task(start_recording(ips, values["record_file"]))
asyncio.create_task(
start_recording(ips, values["record_file"], record_window)
)
if event == "stop_recording":
asyncio.create_task(stop_recording())
asyncio.create_task(stop_recording(record_window))
if event == "resume_recording":
asyncio.create_task(resume_recording())
asyncio.create_task(resume_recording(record_window))
if event == "pause_recording":
asyncio.create_task(pause_recording())
asyncio.create_task(pause_recording(record_window))
if event == "__TIMEOUT__":
await asyncio.sleep(0.001)