Update left half of space weather with colored labels. Also apply minor modifications

This commit is contained in:
alessandro90
2019-04-01 22:53:54 +02:00
parent f04aec4926
commit 5b95d19d7c
9 changed files with 854 additions and 393 deletions

View File

@@ -1,4 +1,5 @@
from collections import namedtuple from collections import namedtuple
from itertools import chain
from functools import partial from functools import partial
from glob import glob from glob import glob
import webbrowser import webbrowser
@@ -26,14 +27,15 @@ from audio_player import AudioPlayer
from space_weather_data import SpaceWeatherData from space_weather_data import SpaceWeatherData
from double_text_button import DoubleTextButton from double_text_button import DoubleTextButton
from download_window import DownloadWindow from download_window import DownloadWindow
from switchable_label import SwitchableLabel, SwitchableLabelIterable from switchable_label import SwitchableLabel, SwitchableLabelsIterable
from constants import (Constants, from constants import (Constants,
Ftype, Ftype,
GfdType, GfdType,
Database, Database,
ChecksumWhat, ChecksumWhat,
Messages, Messages,
Signal,) Signal,
Colors,)
from themes import Theme from themes import Theme
from utilities import (checksum_ok, from utilities import (checksum_ok,
uncheck_and_emit, uncheck_and_emit,
@@ -377,6 +379,81 @@ class Artemis(QMainWindow, Ui_MainWindow):
self.update_now_btn.clicked.connect(self.start_update_space_weather) self.update_now_btn.clicked.connect(self.start_update_space_weather)
self.space_weather_data = SpaceWeatherData() self.space_weather_data = SpaceWeatherData()
self.space_weather_data.update_complete.connect(self.update_space_weather) self.space_weather_data.update_complete.connect(self.update_space_weather)
self.switchable_r_labels = SwitchableLabelsIterable(self.r0_now_lbl,
self.r1_now_lbl,
self.r2_now_lbl,
self.r3_now_lbl,
self.r4_now_lbl,
self.r5_now_lbl,)
self.switchable_s_labels = SwitchableLabelsIterable(self.s0_now_lbl,
self.s1_now_lbl,
self.s2_now_lbl,
self.s3_now_lbl,
self.s4_now_lbl,
self.s5_now_lbl,)
self.switchable_g_now_labels = SwitchableLabelsIterable(self.g0_now_lbl,
self.g1_now_lbl,
self.g2_now_lbl,
self.g3_now_lbl,
self.g4_now_lbl,
self.g5_now_lbl)
self.switchable_g_today_labels = SwitchableLabelsIterable(self.g0_today_lbl,
self.g1_today_lbl,
self.g2_today_lbl,
self.g3_today_lbl,
self.g4_today_lbl,
self.g5_today_lbl)
colors_array = [[Colors.WHITE_LIGHT, Colors.WHITE_DARK],
[Colors.BLUE_LIGHT, Colors.BLUE_DARK],
[Colors.GREEN_LIGHT, Colors.GREEN_DARK],
[Colors.YELLOW_LIGHT, Colors.YELLOW_DARK],
[Colors.ORANGE_LIGHT, Colors.ORANGE_DARK],
[Colors.RED_LIGHT, Colors.RED_DARK]]
for lab, [light_color, dark_color] in zip(chain(self.switchable_r_labels,
self.switchable_s_labels,
self.switchable_g_now_labels,
self.switchable_g_today_labels),
colors_array * 4):
lab.set_colors(light_color, dark_color)
k_storms_colors = [[Colors.RED_LIGHT, Colors.RED_DARK],
[Colors.RED2_LIGHT, Colors.RED2_DARK],
[Colors.RED3_LIGHT, Colors.RED3_DARK],
[Colors.ORANGE_LIGHT, Colors.ORANGE_DARK],
[Colors.ORANGE2_LIGHT, Colors.ORANGE2_DARK],
[Colors.YELLOW_LIGHT, Colors.YELLOW_DARK],
[Colors.GREEN3_LIGHT, Colors.GREEN3_DARK],
[Colors.GREEN2_LIGHT, Colors.GREEN2_DARK],
[Colors.GREEN_LIGHT, Colors.GREEN_DARK],
[Colors.BLUE_LIGHT, Colors.BLUE_DARK]]
a_storm_colors = [[Colors.RED_LIGHT, Colors.RED_DARK],
[Colors.ORANGE_LIGHT, Colors.ORANGE_DARK],
[Colors.ORANGE2_LIGHT, Colors.ORANGE2_DARK],
[Colors.YELLOW_LIGHT, Colors.YELLOW_DARK],
[Colors.GREEN_LIGHT, Colors.GREEN_DARK],
[Colors.BLUE_LIGHT, Colors.BLUE_DARK]]
self.k_storm_labels = SwitchableLabelsIterable(self.k_ex_sev_storm_lbl,
self.k_very_sev_storm_lbl,
self.k_sev_storm_lbl,
self.k_maj_storm_lbl,
self.k_min_storm_lbl,
self.k_active_lbl,
self.k_unsettled_lbl,
self.k_quiet_lbl,
self.k_very_quiet_lbl,
self.k_inactive_lbl)
self.a_storm_labels = SwitchableLabelsIterable(self.a_sev_storm_lbl,
self.a_maj_storm_lbl,
self.a_min_storm_lbl,
self.a_active_lbl,
self.a_unsettled_lbl,
self.a_quiet_lbl)
for lab, [light_color, dark_color] in zip(chain(self.k_storm_labels, self.a_storm_labels),
chain(k_storms_colors, a_storm_colors)):
lab.set_colors(light_color, dark_color)
# Final operations. # Final operations.
self.theme.initialize() self.theme.initialize()
@@ -393,7 +470,129 @@ class Artemis(QMainWindow, Ui_MainWindow):
def update_space_weather(self, status_ok): def update_space_weather(self, status_ok):
self.update_now_bar.setMaximum(self.update_now_bar.minimum() + 1) self.update_now_bar.setMaximum(self.update_now_bar.minimum() + 1)
if status_ok: if status_ok:
print('ok') # Insert labels values and colors here. xray_long = float(self.space_weather_data.xray[-1][7])
format_text = lambda letter, power : letter + f"{xray_long * 10**power:.1f}"
if xray_long < 1e-8 and xray_long != -1.00e+05:
self.peak_flux_lbl.setText(format_text("<A", 8))
elif xray_long >= 1e-8 and xray_long < 1e-7:
self.peak_flux_lbl.setText(format_text("A", 8))
elif xray_long >= 1e-7 and xray_long < 1e-6:
self.peak_flux_lbl.setText(format_text("B", 7))
elif xray_long >= 1e-6 and xray_long < 1e-5:
self.peak_flux_lbl.setText(format_text("C", 6))
elif xray_long >= 1e-5 and xray_long < 1e-4:
self.peak_flux_lbl.setText(format_text("M", 5))
elif xray_long >= 1e-4:
self.peak_flux_lbl.setText(format_text("X", 4))
elif xray_long == -1.00e+05:
self.peak_flux_lbl.setText("No Data")
if xray_long < 1e-5 and xray_long != -1.00e+05:
self.switchable_r_labels.switch_on(self.r0_now_lbl)
elif xray_long >= 1e-5 and xray_long < 5e-5:
self.switchable_r_labels.switch_on(self.r1_now_lbl)
elif xray_long >= 5e-5 and xray_long < 1e-4:
self.switchable_r_labels.switch_on(self.r2_now_lbl)
elif xray_long >= 1e-4 and xray_long < 1e-3:
self.switchable_r_labels.switch_on(self.r3_now_lbl)
elif xray_long >= 1e-3 and xray_long < 2e-3:
self.switchable_r_labels.switch_on(self.r4_now_lbl)
elif xray_long >= 2e-3:
self.switchable_r_labels.switch_on(self.r5_now_lbl)
elif xray_long == -1.00e+05:
self.switchable_r_labels.switch_off_all()
pro10 = float(self.space_weather_data.prot_el[-1][8])
if pro10 < 10 and pro10 != -1.00e+05:
self.switchable_s_labels.switch_on(self.s0_now_lbl)
elif pro10 >= 10 and pro10 < 100:
self.switchable_s_labels.switch_on(self.s1_now_lbl)
elif pro10 >= 100 and pro10 < 1000:
self.switchable_s_labels.switch_on(self.s2_now_lbl)
elif pro10 >= 1000 and pro10 < 10000:
self.switchable_s_labels.switch_on(self.s3_now_lbl)
elif pro10 >= 10000 and pro10 < 100000:
self.switchable_s_labels.switch_on(self.s4_now_lbl)
elif pro10 >= 100000:
self.switchable_s_labels.switch_on(self.s5_now_lbl)
elif pro10 == -1.00e+05:
self.switchable_s_labels.switch_off_all()
k_index = int(self.space_weather_data.ak_index[8][11].replace('.', ''))
self.k_index_lbl.setText(str(k_index))
a_index = int(self.space_weather_data.ak_index[7][7].replace('.', ''))
self.a_index_lbl.setText(str(a_index))
if k_index == 0:
self.switchable_g_now_labels.switch_on(self.g0_now_lbl)
self.k_storm_labels.switch_on(self.k_inactive_lbl)
elif k_index == 1:
self.switchable_g_now_labels.switch_on(self.g0_now_lbl)
self.k_storm_labels.switch_on(self.k_very_quiet_lbl)
elif k_index == 2:
self.switchable_g_now_labels.switch_on(self.g0_now_lbl)
self.k_storm_labels.switch_on(self.k_quiet_lbl)
elif k_index == 3:
self.switchable_g_now_labels.switch_on(self.g0_now_lbl)
self.k_storm_labels.switch_on(self.k_unsettled_lbl)
elif k_index == 4:
self.switchable_g_now_labels.switch_on(self.g0_now_lbl)
self.k_storm_labels.switch_on(self.k_active_lbl)
elif k_index == 5:
self.switchable_g_now_labels.switch_on(self.g1_now_lbl)
self.k_storm_labels.switch_on(self.k_min_storm_lbl)
elif k_index == 6:
self.switchable_g_now_labels.switch_on(self.g2_now_lbl)
self.k_storm_labels.switch_on(self.k_maj_storm_lbl)
elif k_index == 7:
self.switchable_g_now_labels.switch_on(self.g3_now_lbl)
self.k_storm_labels.switch_on(self.k_sev_storm_lbl)
elif k_index == 8:
self.switchable_g_now_labels.switch_on(self.g4_now_lbl)
self.k_storm_labels.switch_on(self.k_very_sev_storm_lbl)
elif k_index == 9:
self.switchable_g_now_labels.switch_on(self.g5_now_lbl)
self.k_storm_labels.switch_on(self.k_ex_sev_storm_lbl)
if a_index >= 0 and a_index < 8:
self.a_storm_labels.switch_on(self.a_quiet_lbl)
elif a_index >= 8 and a_index < 16:
self.a_storm_labels.switch_on(self.a_unsettled_lbl)
elif a_index >= 16 and a_index < 30:
self.a_storm_labels.switch_on(self.a_active_lbl)
elif a_index >= 30 and a_index < 50:
self.a_storm_labels.switch_on(self.a_min_storm_lbl)
elif a_index >= 50 and a_index < 100:
self.a_storm_labels.switch_on(self.a_maj_storm_lbl)
elif a_index >= 100 and a_index < 400:
self.a_storm_labels.switch_on(self.a_sev_storm_lbl)
index = self.space_weather_data.geo_storm[6].index("was") + 1
k_index_24_hmax = int(self.space_weather_data.geo_storm[6][index])
if k_index_24_hmax == 0:
self.switchable_g_today_labels.switch_on(self.g0_today_lbl)
elif k_index_24_hmax == 1:
self.switchable_g_today_labels.switch_on(self.g0_today_lbl)
elif k_index_24_hmax == 2:
self.switchable_g_today_labels.switch_on(self.g0_today_lbl)
elif k_index_24_hmax == 3:
self.switchable_g_today_labels.switch_on(self.g0_today_lbl)
elif k_index_24_hmax == 4:
self.switchable_g_today_labels.switch_on(self.g0_today_lbl)
elif k_index_24_hmax == 5:
self.switchable_g_today_labels.switch_on(self.g1_today_lbl)
elif k_index_24_hmax == 6:
self.switchable_g_today_labels.switch_on(self.g2_today_lbl)
elif k_index_24_hmax == 7:
self.switchable_g_today_labels.switch_on(self.g3_today_lbl)
elif k_index_24_hmax == 8:
self.switchable_g_today_labels.switch_on(self.g4_today_lbl)
elif k_index_24_hmax == 9:
self.switchable_g_today_labels.switch_on(self.g5_today_lbl)
self.sfi_lbl.setText(self.space_weather_data.ak_index[7][2].replace('.', '').lstrip('0'))
self.sn_lbl.setText([x[4] for i, x in enumerate(self.space_weather_data.sgas) if "SSN" in x][0].lstrip('0'))
else: else:
pop_up(self, title = Messages.BAD_DOWNLOAD, pop_up(self, title = Messages.BAD_DOWNLOAD,
text = Messages.BAD_DOWNLOAD_MSG).show() text = Messages.BAD_DOWNLOAD_MSG).show()
@@ -402,10 +601,10 @@ class Artemis(QMainWindow, Ui_MainWindow):
@pyqtSlot() @pyqtSlot()
def go_to_gfd(self, by): def go_to_gfd(self, by):
query = "/?q=" query = "/?q="
if by == GfdType.FREQ: if by is GfdType.FREQ:
value_in_mhz = self.freq_gfd.value() * Constants.CONVERSION_FACTORS[self.unit_freq_gfd.currentText()] / Constants.CONVERSION_FACTORS["MHz"] value_in_mhz = self.freq_gfd.value() * Constants.CONVERSION_FACTORS[self.unit_freq_gfd.currentText()] / Constants.CONVERSION_FACTORS["MHz"]
query += str(value_in_mhz) query += str(value_in_mhz)
elif by == GfdType.LOC: elif by is GfdType.LOC:
query += self.gfd_line_edit.text() query += self.gfd_line_edit.text()
try: try:
webbrowser.open(Constants.GFD_SITE + query.lower()) webbrowser.open(Constants.GFD_SITE + query.lower())
@@ -1060,9 +1259,9 @@ if __name__ == '__main__':
my_app = QApplication(sys.argv) my_app = QApplication(sys.argv)
img = QPixmap(":/icons/Artemis3.500px.png") img = QPixmap(":/icons/Artemis3.500px.png")
# img = img.scaled(600, 600, aspectRatioMode = Qt.KeepAspectRatio) # img = img.scaled(600, 600, aspectRatioMode = Qt.KeepAspectRatio)
splash = QSplashScreen(img) # splash = QSplashScreen(img)
splash.show() # splash.show()
sleep(2) # sleep(2)
w = Artemis() w = Artemis()
splash.finish(w) # splash.finish(w)
sys.exit(my_app.exec_()) sys.exit(my_app.exec_())

File diff suppressed because it is too large Load Diff

View File

@@ -66,6 +66,30 @@ class Database(object):
Signal.SUP_BAND, Signal.SUP_BAND,
Signal.CATEGORY_CODE,) Signal.CATEGORY_CODE,)
class Colors(object):
RED_DARK = "#4d0000"
RED_LIGHT = "#ff0000"
RED2_DARK = "#4c0c00"
RED2_LIGHT = "#ff2700"
RED3_DARK = "#4b1100"
RED3_LIGHT = "#ff3a00"
ORANGE_DARK = "#4d2e00"
ORANGE_LIGHT = "#ffad33"
ORANGE2_DARK = "#4c2000"
ORANGE2_LIGHT = "#ff6c00"
GREEN_DARK = "#003300"
GREEN_LIGHT = "#33ff33"
GREEN2_DARK = "#424d00"
GREEN2_LIGHT = "#dcff00"
GREEN3_DARK = "#344d00"
GREEN3_LIGHT = "#aeff00"
BLUE_DARK = "#000033"
BLUE_LIGHT = "#3333ff"
WHITE_DARK = "#333333"
WHITE_LIGHT = "#d9b3ff"
YELLOW_DARK = "#333300"
YELLOW_LIGHT = "#ffff33"
class Constants(object): class Constants(object):
ACF_DOCS = "https://aresvalley.com/documentation/" ACF_DOCS = "https://aresvalley.com/documentation/"
FORECAST_XRAY = "https://services.swpc.noaa.gov/text/goes-xray-flux-primary.txt" FORECAST_XRAY = "https://services.swpc.noaa.gov/text/goes-xray-flux-primary.txt"

View File

@@ -50,11 +50,11 @@ class DownloadWindow(QWidget, Ui_Download_window):
@pyqtSlot() @pyqtSlot()
def wait_close(self): def wait_close(self):
if self.download_thread.status == ThreadStatus.OK: if self.download_thread.status is ThreadStatus.OK:
self.close() self.close()
elif self.download_thread.status == ThreadStatus.NO_CONNECTION_ERR: elif self.download_thread.status is ThreadStatus.NO_CONNECTION_ERR:
self.show_no_connection_warning() self.show_no_connection_warning()
elif self.download_thread.status == ThreadStatus.BAD_DOWNLOAD_ERR: elif self.download_thread.status is ThreadStatus.BAD_DOWNLOAD_ERR:
self.show_bad_download_warning() self.show_bad_download_warning()
else: else:
self.close() self.close()

View File

@@ -1,7 +1,6 @@
from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject from PyQt5.QtCore import pyqtSlot, pyqtSignal, QObject
from threads import UpadteSpaceWeatherThread, ThreadStatus from threads import UpadteSpaceWeatherThread, ThreadStatus
from utilities import double_split
class SpaceWeatherData(QObject): class SpaceWeatherData(QObject):
update_complete = pyqtSignal(bool) update_complete = pyqtSignal(bool)
@@ -21,6 +20,7 @@ class SpaceWeatherData(QObject):
self.__update_thread.start() self.__update_thread.start()
def __parse_data(self): def __parse_data(self):
double_split = lambda string : [i.split() for i in string.splitlines()]
self.xray = double_split(self.xray) self.xray = double_split(self.xray)
self.prot_el = double_split(self.prot_el) self.prot_el = double_split(self.prot_el)
self.ak_index = double_split(self.ak_index) self.ak_index = double_split(self.ak_index)
@@ -36,7 +36,7 @@ class SpaceWeatherData(QObject):
@pyqtSlot() @pyqtSlot()
def __parse_and_emit_signal(self): def __parse_and_emit_signal(self):
if self.__update_thread.status != ThreadStatus.OK: if self.__update_thread.status is not ThreadStatus.OK:
status_ok = False status_ok = False
else: else:
status_ok = True status_ok = True

View File

@@ -11,13 +11,15 @@ class SwitchableLabel(QLabel):
self.switch_off_color = off self.switch_off_color = off
def switch_on(self): def switch_on(self):
self.setStyleSheet(f"background-color: {self.switch_on_color}") self.setStyleSheet(f"""background-color: {self.switch_on_color};
color:#000000;""")
def switch_off(self): def switch_off(self):
self.setStyleSheet(f"background-color: {self.switch_off_color}") self.setStyleSheet(f"""background-color: {self.switch_off_color};
color:#000000;""")
class SwitchableLabelIterable(object): class SwitchableLabelsIterable(object):
def __init__(self, *labels): def __init__(self, *labels):
self.labels = labels self.labels = labels
@@ -25,9 +27,9 @@ class SwitchableLabelIterable(object):
for lab in self.labels: for lab in self.labels:
yield lab yield lab
def switch_on(label): def switch_on(self, label):
for lab in self.labels: for lab in self.labels:
if lab == label: if lab is label:
lab.switch_on() lab.switch_on()
else: else:
lab.switch_off() lab.switch_off()

View File

@@ -1,10 +1,11 @@
from functools import partial from functools import partial
import os import os
import re
from PyQt5.QtWidgets import QAction from PyQt5.QtWidgets import QAction
from PyQt5.QtCore import pyqtSlot from PyQt5.QtCore import pyqtSlot
from PyQt5.QtGui import QPixmap from PyQt5.QtGui import QPixmap
from constants import Constants from constants import Constants
from utilities import pop_up, is_valid_html_color from utilities import pop_up
class ThemeConstants(object): class ThemeConstants(object):
FOLDER = "themes" FOLDER = "themes"
@@ -138,6 +139,7 @@ class Theme(object):
valid_format = True valid_format = True
quality, color = line.split(ThemeConstants.COLOR_SEPARATOR) quality, color = line.split(ThemeConstants.COLOR_SEPARATOR)
color = color.rstrip() color = color.rstrip()
is_valid_html_color = lambda color : bool(re.match("#([a-zA-Z0-9]){6}", color))
if quality.lower() == Constants.ACTIVE and is_valid_html_color(color): if quality.lower() == Constants.ACTIVE and is_valid_html_color(color):
self.__parent.active_color = color self.__parent.active_color = color
active_color_ok = True active_color_ok = True

View File

@@ -73,10 +73,10 @@ class UpadteSpaceWeatherThread(QThread):
def run(self): def run(self):
try: try:
self.__space_weather_data.xray = str(urllib3.PoolManager().request('GET', Constants.FORECAST_XRAY).data) self.__space_weather_data.xray = str(urllib3.PoolManager().request('GET', Constants.FORECAST_XRAY).data, 'utf-8')
self.__space_weather_data.prot_el = str(urllib3.PoolManager().request('GET', Constants.FORECAST_PROT).data) self.__space_weather_data.prot_el = str(urllib3.PoolManager().request('GET', Constants.FORECAST_PROT).data, 'utf-8')
self.__space_weather_data.ak_index = str(urllib3.PoolManager().request('GET', Constants.FORECAST_AK_IND).data) self.__space_weather_data.ak_index = str(urllib3.PoolManager().request('GET', Constants.FORECAST_AK_IND).data, 'utf-8')
self.__space_weather_data.sgas = str(urllib3.PoolManager().request('GET', Constants.FORECAST_SGAS).data) self.__space_weather_data.sgas = str(urllib3.PoolManager().request('GET', Constants.FORECAST_SGAS).data, 'utf-8')
self.__space_weather_data.geo_storm = str(urllib3.PoolManager().request('GET', Constants.FORECAST_G).data) self.__space_weather_data.geo_storm = str(urllib3.PoolManager().request('GET', Constants.FORECAST_G).data, 'utf-8')
except: except:
self.__status = ThreadStatus.UNKNOWN_ERR self.__status = ThreadStatus.UNKNOWN_ERR

View File

@@ -1,6 +1,5 @@
from functools import partial from functools import partial
import hashlib import hashlib
import re
import sys import sys
import os import os
from pandas import read_csv from pandas import read_csv
@@ -42,9 +41,9 @@ def pop_up(cls, title, text,
def checksum_ok(data, what): def checksum_ok(data, what):
code = hashlib.sha256() code = hashlib.sha256()
code.update(data) code.update(data)
if what == ChecksumWhat.FOLDER: if what is ChecksumWhat.FOLDER:
n = 0 n = 0
elif what == ChecksumWhat.DB: elif what is ChecksumWhat.DB:
n = 1 n = 1
else: else:
raise ValueError("Wrong entry name.") raise ValueError("Wrong entry name.")
@@ -55,9 +54,6 @@ def checksum_ok(data, what):
raise raise
return code.hexdigest() == reference return code.hexdigest() == reference
def is_valid_html_color(color):
return bool(re.match("#([a-zA-Z0-9]){6}", color))
def connect_to(events_to_connect, fun_to_connect, fun_args): def connect_to(events_to_connect, fun_to_connect, fun_args):
if fun_args: if fun_args:
for event in events_to_connect: for event in events_to_connect:
@@ -107,6 +103,3 @@ def format_numbers(lower, upper):
return f"{lower:,} {units[lower_factor]} - {upper:,} {units[upper_factor]}" return f"{lower:,} {units[lower_factor]} - {upper:,} {units[upper_factor]}"
else: else:
return f"{lower:,} {units[lower_factor]}" return f"{lower:,} {units[lower_factor]}"
def double_split(string):
return [i.split() for i in string.splitlines()]