Add logic to the forecast screen
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -7,5 +7,6 @@ csv_info.txt
|
|||||||
pyinstaller_cmd.txt
|
pyinstaller_cmd.txt
|
||||||
themes/.current_theme
|
themes/.current_theme
|
||||||
launch.bat
|
launch.bat
|
||||||
|
designer.bat
|
||||||
*.sh
|
*.sh
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|||||||
43
artemis.py
43
artemis.py
@@ -22,8 +22,7 @@ from PyQt5.QtCore import (QFileInfo,
|
|||||||
pyqtSlot,)
|
pyqtSlot,)
|
||||||
|
|
||||||
from audio_player import AudioPlayer
|
from audio_player import AudioPlayer
|
||||||
from space_weather_data import SpaceWeatherData
|
from weatherdata import SpaceWeatherData, ForecastData
|
||||||
from forecastdata import ForecastData
|
|
||||||
from download_window import DownloadWindow
|
from download_window import DownloadWindow
|
||||||
from switchable_label import SwitchableLabelsIterable
|
from switchable_label import SwitchableLabelsIterable
|
||||||
from constants import (Constants,
|
from constants import (Constants,
|
||||||
@@ -525,30 +524,10 @@ class Artemis(QMainWindow, Ui_MainWindow):
|
|||||||
self.forecast_info_btn.clicked.connect(
|
self.forecast_info_btn.clicked.connect(
|
||||||
lambda: webbrowser.open(Constants.SPACE_WEATHER_INFO)
|
lambda: webbrowser.open(Constants.SPACE_WEATHER_INFO)
|
||||||
)
|
)
|
||||||
|
self.forecast_data = ForecastData(self)
|
||||||
self.update_forecast_bar.clicked.connect(self.start_update_forecast)
|
self.update_forecast_bar.clicked.connect(self.start_update_forecast)
|
||||||
self.update_forecast_bar.set_idle()
|
self.update_forecast_bar.set_idle()
|
||||||
self.forecast_data = ForecastData()
|
self.forecast_data.update_complete.connect(self.update_forecast)
|
||||||
self.today_forecast_labels = []
|
|
||||||
self.today_p1_forecast_labels = []
|
|
||||||
self.today_p2_forecast_labels = []
|
|
||||||
self.all_forecast_labels = []
|
|
||||||
flags = ['', 'p1_', 'p2_']
|
|
||||||
for flag in flags:
|
|
||||||
title_lbl = getattr(self, "today_" + flag + "lbl")
|
|
||||||
title_lbl.setText("-")
|
|
||||||
for index in range(20):
|
|
||||||
label = getattr(
|
|
||||||
self,
|
|
||||||
"forecast_today_" + flag + str(index) + "_lbl"
|
|
||||||
)
|
|
||||||
label.setText(Constants.UNKNOWN)
|
|
||||||
self.all_forecast_labels.append(label)
|
|
||||||
if flag == flags[0]:
|
|
||||||
self.today_forecast_labels.append(label)
|
|
||||||
if flag == flags[1]:
|
|
||||||
self.today_p1_forecast_labels.append(label)
|
|
||||||
if flag == flags[2]:
|
|
||||||
self.today_p2_forecast_labels.append(label)
|
|
||||||
|
|
||||||
|
|
||||||
# Final operations.
|
# Final operations.
|
||||||
@@ -558,7 +537,9 @@ class Artemis(QMainWindow, Ui_MainWindow):
|
|||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def start_update_forecast(self):
|
def start_update_forecast(self):
|
||||||
pass
|
if not self.forecast_data.is_updating:
|
||||||
|
self.update_forecast_bar.set_updating()
|
||||||
|
self.forecast_data.update()
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def start_update_space_weather(self):
|
def start_update_space_weather(self):
|
||||||
@@ -566,6 +547,16 @@ class Artemis(QMainWindow, Ui_MainWindow):
|
|||||||
self.update_now_bar.set_updating()
|
self.update_now_bar.set_updating()
|
||||||
self.space_weather_data.update()
|
self.space_weather_data.update()
|
||||||
|
|
||||||
|
@pyqtSlot(bool)
|
||||||
|
def update_forecast(self, status_ok):
|
||||||
|
self.update_forecast_bar.set_idle()
|
||||||
|
if status_ok:
|
||||||
|
self.forecast_data.update_all_labels()
|
||||||
|
elif not self.closing:
|
||||||
|
pop_up(self, title=Messages.BAD_DOWNLOAD,
|
||||||
|
text=Messages.BAD_DOWNLOAD_MSG).show()
|
||||||
|
self.forecast_data.remove_data()
|
||||||
|
|
||||||
@pyqtSlot(bool)
|
@pyqtSlot(bool)
|
||||||
def update_space_weather(self, status_ok):
|
def update_space_weather(self, status_ok):
|
||||||
self.update_now_bar.set_idle()
|
self.update_now_bar.set_idle()
|
||||||
@@ -1421,6 +1412,8 @@ class Artemis(QMainWindow, Ui_MainWindow):
|
|||||||
self.download_window.close()
|
self.download_window.close()
|
||||||
if self.space_weather_data.is_updating:
|
if self.space_weather_data.is_updating:
|
||||||
self.space_weather_data.shutdown_thread()
|
self.space_weather_data.shutdown_thread()
|
||||||
|
if self.forecast_data.is_updating:
|
||||||
|
self.forecast_data.shutdown_thread()
|
||||||
super().closeEvent(event)
|
super().closeEvent(event)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
1808
artemis.ui
1808
artemis.ui
File diff suppressed because it is too large
Load Diff
@@ -91,6 +91,7 @@ class Constants:
|
|||||||
RTL_SDL_LINK = "https://www.rtl-sdr.com/"
|
RTL_SDL_LINK = "https://www.rtl-sdr.com/"
|
||||||
UPDATING_STR = "Updating..."
|
UPDATING_STR = "Updating..."
|
||||||
ACF_DOCS = "https://aresvalley.com/documentation/"
|
ACF_DOCS = "https://aresvalley.com/documentation/"
|
||||||
|
FORECAST_PROBABILITIES = "https://services.swpc.noaa.gov/text/sgarf.txt"
|
||||||
SPACE_WEATHER_XRAY = "https://services.swpc.noaa.gov/text/goes-xray-flux-primary.txt"
|
SPACE_WEATHER_XRAY = "https://services.swpc.noaa.gov/text/goes-xray-flux-primary.txt"
|
||||||
SPACE_WEATHER_PROT_EL = "https://services.swpc.noaa.gov/text/goes-particle-flux-primary.txt"
|
SPACE_WEATHER_PROT_EL = "https://services.swpc.noaa.gov/text/goes-particle-flux-primary.txt"
|
||||||
SPACE_WEATHER_AK_INDEX = "https://services.swpc.noaa.gov/text/wwv.txt"
|
SPACE_WEATHER_AK_INDEX = "https://services.swpc.noaa.gov/text/wwv.txt"
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
class ForecastData:
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
from PyQt5.QtGui import QPixmap
|
|
||||||
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
|
|
||||||
from threads import UpdateSpaceWeatherThread, ThreadStatus
|
|
||||||
|
|
||||||
|
|
||||||
class SpaceWeatherData(QObject):
|
|
||||||
update_complete = pyqtSignal(bool)
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
self.xray = ''
|
|
||||||
self.prot_el = ''
|
|
||||||
self.ak_index = ''
|
|
||||||
self.sgas = ''
|
|
||||||
self.geo_storm = ''
|
|
||||||
self.images = [
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap()
|
|
||||||
]
|
|
||||||
self.__update_thread = UpdateSpaceWeatherThread(self)
|
|
||||||
self.__update_thread.finished.connect(self.__parse_and_emit_signal)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def is_updating(self):
|
|
||||||
return self.__update_thread.isRunning()
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def update(self):
|
|
||||||
self.__update_thread.start()
|
|
||||||
|
|
||||||
def __parse_data(self):
|
|
||||||
double_split = lambda string: [i.split() for i in string.splitlines()]
|
|
||||||
self.xray = double_split(self.xray)
|
|
||||||
self.prot_el = double_split(self.prot_el)
|
|
||||||
self.ak_index = double_split(self.ak_index)
|
|
||||||
self.sgas = double_split(self.sgas)
|
|
||||||
self.geo_storm = double_split(self.geo_storm)
|
|
||||||
|
|
||||||
def remove_data(self):
|
|
||||||
self.xray = ''
|
|
||||||
self.prot_el = ''
|
|
||||||
self.ak_index = ''
|
|
||||||
self.sgas = ''
|
|
||||||
self.geo_storm = ''
|
|
||||||
self.images = [
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap(),
|
|
||||||
QPixmap()
|
|
||||||
]
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def __parse_and_emit_signal(self):
|
|
||||||
status_ok = False
|
|
||||||
if self.__update_thread.status is ThreadStatus.OK:
|
|
||||||
status_ok = True
|
|
||||||
self.__parse_data()
|
|
||||||
self.update_complete.emit(status_ok)
|
|
||||||
|
|
||||||
def shutdown_thread(self):
|
|
||||||
self.__update_thread.terminate()
|
|
||||||
self.__update_thread.wait()
|
|
||||||
@@ -6,6 +6,7 @@ class _BaseSwitchableLabel(QLabel):
|
|||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.is_on = False
|
self.is_on = False
|
||||||
|
self.level = 0
|
||||||
|
|
||||||
def switch_on(self):
|
def switch_on(self):
|
||||||
self.is_on = True
|
self.is_on = True
|
||||||
@@ -44,12 +45,17 @@ class SingleColorSwitchableLabel(_BaseSwitchableLabel):
|
|||||||
self.active_color = ForecastColors.WARNING_COLOR
|
self.active_color = ForecastColors.WARNING_COLOR
|
||||||
|
|
||||||
def switch_on(self):
|
def switch_on(self):
|
||||||
super().switch_on()
|
if self.level >= 30:
|
||||||
self.setStyleSheet(f"background-color: {self.active_color};")
|
super().switch_on()
|
||||||
|
self.setStyleSheet(f"color: {self.active_color}"
|
||||||
|
# f"""background-color: {self.active_color};
|
||||||
|
# color: #000000;"""
|
||||||
|
)
|
||||||
|
|
||||||
def switch_off(self):
|
def switch_off(self):
|
||||||
super().switch_off()
|
super().switch_off()
|
||||||
self.setStyleSheet("background-color: transparent;")
|
# self.setStyleSheet("""background-color: transparent;""")
|
||||||
|
self.setStyleSheet("")
|
||||||
|
|
||||||
|
|
||||||
class MultiColorSwitchableLabel(_BaseSwitchableLabel):
|
class MultiColorSwitchableLabel(_BaseSwitchableLabel):
|
||||||
@@ -64,18 +70,20 @@ class MultiColorSwitchableLabel(_BaseSwitchableLabel):
|
|||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.level = 0
|
|
||||||
|
|
||||||
def switch_on(self):
|
def switch_on(self):
|
||||||
if 5 <= self.level <= 9:
|
if 5 <= self.level <= 9:
|
||||||
super().switch_on()
|
super().switch_on()
|
||||||
self.setStyleSheet(f"""
|
self.setStyleSheet(f"color: {self.LEVEL_COLORS[self.level]}"
|
||||||
background-color: {self.LEVEL_COLORS[self.level]};
|
# f"""background-color: {self.LEVEL_COLORS[self.level]};
|
||||||
""")
|
# color: #000000;
|
||||||
|
# """
|
||||||
|
)
|
||||||
|
|
||||||
def switch_off(self):
|
def switch_off(self):
|
||||||
super().switch_off()
|
super().switch_off()
|
||||||
self.setStyleSheet("background-color: transparent;")
|
# self.setStyleSheet("background-color: transparent;")
|
||||||
|
self.setStyleSheet("")
|
||||||
|
|
||||||
|
|
||||||
class SwitchableLabelsIterable:
|
class SwitchableLabelsIterable:
|
||||||
|
|||||||
73
threads.py
73
threads.py
@@ -19,7 +19,7 @@ class ThreadStatus(Enum):
|
|||||||
UNDEFINED = auto()
|
UNDEFINED = auto()
|
||||||
|
|
||||||
|
|
||||||
class _BaseDownloadThread(QThread):
|
class BaseDownloadThread(QThread):
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.status = ThreadStatus.UNDEFINED
|
self.status = ThreadStatus.UNDEFINED
|
||||||
@@ -29,7 +29,7 @@ class _BaseDownloadThread(QThread):
|
|||||||
self.wait()
|
self.wait()
|
||||||
|
|
||||||
|
|
||||||
class DownloadThread(_BaseDownloadThread):
|
class DownloadThread(BaseDownloadThread):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.reason = 0
|
self.reason = 0
|
||||||
@@ -65,7 +65,13 @@ class DownloadThread(_BaseDownloadThread):
|
|||||||
self.status = ThreadStatus.OK
|
self.status = ThreadStatus.OK
|
||||||
|
|
||||||
|
|
||||||
class UpdateSpaceWeatherThread(_BaseDownloadThread):
|
class _AsyncDownloader:
|
||||||
|
async def _download_resource(self, session, link):
|
||||||
|
resp = await session.get(link)
|
||||||
|
return await resp.read()
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateSpaceWeatherThread(BaseDownloadThread, _AsyncDownloader):
|
||||||
|
|
||||||
__properties = ("xray", "prot_el", "ak_index", "sgas", "geo_storm")
|
__properties = ("xray", "prot_el", "ak_index", "sgas", "geo_storm")
|
||||||
|
|
||||||
@@ -73,20 +79,16 @@ class UpdateSpaceWeatherThread(_BaseDownloadThread):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
self.__space_weather_data = space_weather_data
|
self.__space_weather_data = space_weather_data
|
||||||
|
|
||||||
async def __download_resource(self, session, link):
|
|
||||||
resp = await session.get(link)
|
|
||||||
return await resp.read()
|
|
||||||
|
|
||||||
async def __download_property(self, session, property_name):
|
async def __download_property(self, session, property_name):
|
||||||
link = getattr(Constants, "SPACE_WEATHER_" + property_name.upper())
|
link = getattr(Constants, "SPACE_WEATHER_" + property_name.upper())
|
||||||
data = await self.__download_resource(session, link)
|
data = await self._download_resource(session, link)
|
||||||
setattr(self.__space_weather_data, property_name, str(data, 'utf-8'))
|
setattr(self.__space_weather_data, property_name, str(data, 'utf-8'))
|
||||||
|
|
||||||
async def __download_image(self, session, n):
|
async def __download_image(self, session, n):
|
||||||
im = await self.__download_resource(session, Constants.SPACE_WEATHER_IMGS[n])
|
im = await self._download_resource(session, Constants.SPACE_WEATHER_IMGS[n])
|
||||||
self.__space_weather_data.images[n].loadFromData(im)
|
self.__space_weather_data.images[n].loadFromData(im)
|
||||||
|
|
||||||
async def __download_resources(self, *links):
|
async def _download_resources(self):
|
||||||
session = aiohttp.ClientSession()
|
session = aiohttp.ClientSession()
|
||||||
try:
|
try:
|
||||||
t = []
|
t = []
|
||||||
@@ -111,4 +113,53 @@ class UpdateSpaceWeatherThread(_BaseDownloadThread):
|
|||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.status = ThreadStatus.UNDEFINED
|
self.status = ThreadStatus.UNDEFINED
|
||||||
asyncio.run(self.__download_resources())
|
asyncio.run(self._download_resources())
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateForecastThread(BaseDownloadThread, _AsyncDownloader):
|
||||||
|
|
||||||
|
class _PropertyName(Enum):
|
||||||
|
FORECAST = auto()
|
||||||
|
PROBABILITIES = auto()
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
|
super().__init__()
|
||||||
|
self.parent = parent
|
||||||
|
|
||||||
|
async def __download_property(self, session, link, prop_name):
|
||||||
|
resp = await self._download_resource(session, link)
|
||||||
|
resp = str(resp, 'utf-8')
|
||||||
|
if prop_name is self._PropertyName.FORECAST:
|
||||||
|
self.parent.forecast = resp
|
||||||
|
if prop_name is self._PropertyName.PROBABILITIES:
|
||||||
|
self.parent.probabilities = resp
|
||||||
|
|
||||||
|
async def _download_resources(self):
|
||||||
|
session = aiohttp.ClientSession()
|
||||||
|
try:
|
||||||
|
await asyncio.gather(
|
||||||
|
asyncio.create_task(
|
||||||
|
self.__download_property(
|
||||||
|
session,
|
||||||
|
Constants.SPACE_WEATHER_GEO_STORM,
|
||||||
|
self._PropertyName.FORECAST
|
||||||
|
)
|
||||||
|
),
|
||||||
|
asyncio.create_task(
|
||||||
|
self.__download_property(
|
||||||
|
session,
|
||||||
|
Constants.FORECAST_PROBABILITIES,
|
||||||
|
self._PropertyName.PROBABILITIES
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
self.status = ThreadStatus.UNKNOWN_ERR
|
||||||
|
else:
|
||||||
|
self.status = ThreadStatus.OK
|
||||||
|
finally:
|
||||||
|
await session.close()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.status = ThreadStatus.UNDEFINED
|
||||||
|
asyncio.run(self._download_resources())
|
||||||
|
|||||||
314
weatherdata.py
Normal file
314
weatherdata.py
Normal file
@@ -0,0 +1,314 @@
|
|||||||
|
import re
|
||||||
|
from PyQt5.QtGui import QPixmap
|
||||||
|
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
|
||||||
|
from threads import (BaseDownloadThread,
|
||||||
|
UpdateSpaceWeatherThread,
|
||||||
|
ThreadStatus,
|
||||||
|
UpdateForecastThread)
|
||||||
|
from constants import Constants
|
||||||
|
from switchable_label import MultiColorSwitchableLabel
|
||||||
|
|
||||||
|
|
||||||
|
class _BaseWeatherData(QObject):
|
||||||
|
update_complete = pyqtSignal(bool)
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self._update_thread = BaseDownloadThread()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_updating(self):
|
||||||
|
return self._update_thread.isRunning()
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
self._update_thread.start()
|
||||||
|
|
||||||
|
def _parse_data(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@pyqtSlot()
|
||||||
|
def _parse_and_emit_signal(self):
|
||||||
|
status_ok = False
|
||||||
|
if self._update_thread.status is ThreadStatus.OK:
|
||||||
|
status_ok = True
|
||||||
|
self._parse_data()
|
||||||
|
self.update_complete.emit(status_ok)
|
||||||
|
|
||||||
|
def _double_split(self, string):
|
||||||
|
return [i.split() for i in string.splitlines()]
|
||||||
|
|
||||||
|
def shutdown_thread(self):
|
||||||
|
self._update_thread.terminate()
|
||||||
|
self._update_thread.wait()
|
||||||
|
|
||||||
|
|
||||||
|
class SpaceWeatherData(_BaseWeatherData):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.xray = ''
|
||||||
|
self.prot_el = ''
|
||||||
|
self.ak_index = ''
|
||||||
|
self.sgas = ''
|
||||||
|
self.geo_storm = ''
|
||||||
|
self.images = [
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap()
|
||||||
|
]
|
||||||
|
self._update_thread = UpdateSpaceWeatherThread(self)
|
||||||
|
self._update_thread.finished.connect(self._parse_and_emit_signal)
|
||||||
|
|
||||||
|
def _parse_data(self):
|
||||||
|
self.xray = self._double_split(self.xray)
|
||||||
|
self.prot_el = self._double_split(self.prot_el)
|
||||||
|
self.ak_index = self._double_split(self.ak_index)
|
||||||
|
self.sgas = self._double_split(self.sgas)
|
||||||
|
self.geo_storm = self._double_split(self.geo_storm)
|
||||||
|
|
||||||
|
def remove_data(self):
|
||||||
|
self.xray = ''
|
||||||
|
self.prot_el = ''
|
||||||
|
self.ak_index = ''
|
||||||
|
self.sgas = ''
|
||||||
|
self.geo_storm = ''
|
||||||
|
self.images = [
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap(),
|
||||||
|
QPixmap()
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class ForecastData(_BaseWeatherData):
|
||||||
|
|
||||||
|
ROW_KEYWORDS = {
|
||||||
|
"solar_row": "S1 or greater",
|
||||||
|
"event_row": "III. Event probabilities",
|
||||||
|
"rb_now_row": "R1-R2",
|
||||||
|
"ga_now_row": "Geomagnetic Activity Probabilities",
|
||||||
|
"kp_index_row": "NOAA Kp index breakdown"
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, parent):
|
||||||
|
super().__init__()
|
||||||
|
self.forecast = ''
|
||||||
|
self.probabilities = ''
|
||||||
|
self.labels_table = []
|
||||||
|
self.solar_row = None
|
||||||
|
self.event_row = None
|
||||||
|
self.rb_now_row = None
|
||||||
|
self.ga_now_row = None
|
||||||
|
self.kp_index_row = None
|
||||||
|
self._update_thread = UpdateForecastThread(self)
|
||||||
|
self._update_thread.finished.connect(self._parse_and_emit_signal)
|
||||||
|
self.today_lbl = parent.today_lbl
|
||||||
|
self.today_p1_lbl = parent.today_p1_lbl
|
||||||
|
self.today_p2_lbl = parent.today_p2_lbl
|
||||||
|
self.__today_lbls = []
|
||||||
|
self.__today_p1_lbls = []
|
||||||
|
self.__today_p2_lbls = []
|
||||||
|
self.__all_lbls = []
|
||||||
|
flags = ['', 'p1_', 'p2_']
|
||||||
|
for flag in flags:
|
||||||
|
title_lbl = getattr(self, "today_" + flag + "lbl")
|
||||||
|
title_lbl.setText("-")
|
||||||
|
for index in range(20):
|
||||||
|
label = getattr(
|
||||||
|
parent,
|
||||||
|
"forecast_today_" + flag + str(index) + "_lbl"
|
||||||
|
)
|
||||||
|
label.setText(Constants.UNKNOWN)
|
||||||
|
if flag == flags[0]:
|
||||||
|
self.__today_lbls.append(label)
|
||||||
|
if flag == flags[1]:
|
||||||
|
self.__today_p1_lbls.append(label)
|
||||||
|
if flag == flags[2]:
|
||||||
|
self.__today_p2_lbls.append(label)
|
||||||
|
|
||||||
|
self.__all_lbls = [
|
||||||
|
self.__today_lbls,
|
||||||
|
self.__today_p1_lbls,
|
||||||
|
self.__today_p2_lbls
|
||||||
|
]
|
||||||
|
|
||||||
|
def _parse_data(self):
|
||||||
|
self.forecast = self.forecast.splitlines()
|
||||||
|
# Remove possible '(G\d)' from the kp_index table
|
||||||
|
self.probabilities = re.sub('(G\d)', lambda obj: '', self.probabilities)
|
||||||
|
self.probabilities = self.probabilities.splitlines()
|
||||||
|
|
||||||
|
def __split_lists(self):
|
||||||
|
self.forecast = [i.split() for i in self.forecast]
|
||||||
|
self.probabilities = [i.split() for i in self.probabilities]
|
||||||
|
|
||||||
|
def __find_row_with(self, data, text):
|
||||||
|
for i, row in enumerate(data):
|
||||||
|
if text in row:
|
||||||
|
return i
|
||||||
|
return None
|
||||||
|
|
||||||
|
def __get_rows(self):
|
||||||
|
self.solar_row = self.__find_row_with(
|
||||||
|
self.forecast,
|
||||||
|
self.ROW_KEYWORDS["solar_row"]
|
||||||
|
)
|
||||||
|
self.event_row = self.__find_row_with(
|
||||||
|
self.probabilities,
|
||||||
|
self.ROW_KEYWORDS["event_row"]
|
||||||
|
)
|
||||||
|
self.rb_now_row = self.__find_row_with(
|
||||||
|
self.forecast,
|
||||||
|
self.ROW_KEYWORDS["rb_now_row"]
|
||||||
|
)
|
||||||
|
self.ga_now_row = self.__find_row_with(
|
||||||
|
self.probabilities,
|
||||||
|
self.ROW_KEYWORDS["ga_now_row"]
|
||||||
|
)
|
||||||
|
self.kp_index_row = self.__find_row_with(
|
||||||
|
self.forecast,
|
||||||
|
self.ROW_KEYWORDS["kp_index_row"]
|
||||||
|
)
|
||||||
|
|
||||||
|
is_none = lambda x: x is None
|
||||||
|
if any([
|
||||||
|
is_none(self.solar_row),
|
||||||
|
is_none(self.event_row),
|
||||||
|
is_none(self.rb_now_row),
|
||||||
|
is_none(self.ga_now_row),
|
||||||
|
is_none(self.kp_index_row)
|
||||||
|
]):
|
||||||
|
raise Exception
|
||||||
|
|
||||||
|
def __set_dates(self):
|
||||||
|
month = self.forecast[self.solar_row - 1][0]
|
||||||
|
today = self.forecast[self.solar_row - 1][1]
|
||||||
|
today_p1 = self.forecast[self.solar_row - 1][3]
|
||||||
|
today_p2 = self.forecast[self.solar_row - 1][5]
|
||||||
|
self.today_lbl.setText(month + ' ' + today)
|
||||||
|
self.today_p1_lbl.setText(month + ' ' + today_p1)
|
||||||
|
self.today_p2_lbl.setText(month + ' ' + today_p2)
|
||||||
|
|
||||||
|
def __make_labels_table(self):
|
||||||
|
get_first_split = lambda x: x.split("/")[0]
|
||||||
|
get_second_split = lambda x: x.split("/")[1]
|
||||||
|
get_third_split = lambda x: x.split("/")[2]
|
||||||
|
self.labels_table = [
|
||||||
|
[
|
||||||
|
[self.forecast, self.solar_row, 3, None],
|
||||||
|
[self.probabilities, self.event_row + 1, 2, get_first_split],
|
||||||
|
[self.probabilities, self.event_row + 2, 2, get_first_split],
|
||||||
|
[self.probabilities, self.event_row + 3, 1, get_first_split],
|
||||||
|
[self.forecast, self.rb_now_row, 1, None],
|
||||||
|
[self.forecast, self.rb_now_row + 1, 3, None],
|
||||||
|
[self.probabilities, self.ga_now_row + 2, 1, get_first_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 3, 2, get_first_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 4, 2, get_first_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 6, 1, get_first_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 7, 2, get_first_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 8, 2, get_first_split],
|
||||||
|
[self.forecast, self.kp_index_row + 3, 1, None],
|
||||||
|
[self.forecast, self.kp_index_row + 4, 1, None],
|
||||||
|
[self.forecast, self.kp_index_row + 5, 1, None],
|
||||||
|
[self.forecast, self.kp_index_row + 6, 1, None],
|
||||||
|
[self.forecast, self.kp_index_row + 7, 1, None],
|
||||||
|
[self.forecast, self.kp_index_row + 8, 1, None],
|
||||||
|
[self.forecast, self.kp_index_row + 9, 1, None],
|
||||||
|
[self.forecast, self.kp_index_row + 10, 1, None]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[self.forecast, self.solar_row, 4, None],
|
||||||
|
[self.probabilities, self.event_row + 1, 2, get_second_split],
|
||||||
|
[self.probabilities, self.event_row + 2, 2, get_second_split],
|
||||||
|
[self.probabilities, self.event_row + 3, 1, get_second_split],
|
||||||
|
[self.forecast, self.rb_now_row, 2, None],
|
||||||
|
[self.forecast, self.rb_now_row + 1, 4, None],
|
||||||
|
[self.probabilities, self.ga_now_row + 2, 1, get_second_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 3, 2, get_second_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 4, 2, get_second_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 6, 1, get_second_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 7, 2, get_second_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 8, 2, get_second_split],
|
||||||
|
[self.forecast, self.kp_index_row + 3, 2, None],
|
||||||
|
[self.forecast, self.kp_index_row + 4, 2, None],
|
||||||
|
[self.forecast, self.kp_index_row + 5, 2, None],
|
||||||
|
[self.forecast, self.kp_index_row + 6, 2, None],
|
||||||
|
[self.forecast, self.kp_index_row + 7, 2, None],
|
||||||
|
[self.forecast, self.kp_index_row + 8, 2, None],
|
||||||
|
[self.forecast, self.kp_index_row + 9, 2, None],
|
||||||
|
[self.forecast, self.kp_index_row + 10, 2, None]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
[self.forecast, self.solar_row, 5, None],
|
||||||
|
[self.probabilities, self.event_row + 1, 2, get_third_split],
|
||||||
|
[self.probabilities, self.event_row + 2, 2, get_third_split],
|
||||||
|
[self.probabilities, self.event_row + 3, 1, get_third_split],
|
||||||
|
[self.forecast, self.rb_now_row, 3, None],
|
||||||
|
[self.forecast, self.rb_now_row + 1, 5, None],
|
||||||
|
[self.probabilities, self.ga_now_row + 2, 1, get_third_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 3, 2, get_third_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 4, 2, get_third_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 6, 1, get_third_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 7, 2, get_third_split],
|
||||||
|
[self.probabilities, self.ga_now_row + 8, 2, get_third_split],
|
||||||
|
[self.forecast, self.kp_index_row + 3, 3, None],
|
||||||
|
[self.forecast, self.kp_index_row + 4, 3, None],
|
||||||
|
[self.forecast, self.kp_index_row + 5, 3, None],
|
||||||
|
[self.forecast, self.kp_index_row + 6, 3, None],
|
||||||
|
[self.forecast, self.kp_index_row + 7, 3, None],
|
||||||
|
[self.forecast, self.kp_index_row + 8, 3, None],
|
||||||
|
[self.forecast, self.kp_index_row + 9, 3, None],
|
||||||
|
[self.forecast, self.kp_index_row + 10, 3, None]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
def __get_lbl_value(self, data, row, col, f = None):
|
||||||
|
val = data[row][col]
|
||||||
|
if f is not None:
|
||||||
|
val = f(val)
|
||||||
|
val = val.lstrip('0').rstrip('%')
|
||||||
|
return val
|
||||||
|
|
||||||
|
def __is_integer(self, s):
|
||||||
|
try:
|
||||||
|
int(s)
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def __set_labels_values(self):
|
||||||
|
for lbl_list, table in zip(self.__all_lbls, self.labels_table):
|
||||||
|
for lbl, row in zip(lbl_list, table):
|
||||||
|
lbl.switch_off()
|
||||||
|
value = self.__get_lbl_value(*row)
|
||||||
|
if self.__is_integer(value):
|
||||||
|
lbl.level = int(value)
|
||||||
|
if not isinstance(lbl, MultiColorSwitchableLabel):
|
||||||
|
value += '%'
|
||||||
|
lbl.setText(value)
|
||||||
|
lbl.switch_on()
|
||||||
|
|
||||||
|
def update_all_labels(self):
|
||||||
|
try:
|
||||||
|
self.__get_rows()
|
||||||
|
self.__split_lists()
|
||||||
|
self.__make_labels_table()
|
||||||
|
self.__set_dates()
|
||||||
|
self.__set_labels_values()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def remove_data(self):
|
||||||
|
self.forecast = ''
|
||||||
|
self.probabilities = ''
|
||||||
Reference in New Issue
Block a user