-
Notifications
You must be signed in to change notification settings - Fork 1
/
hyperweather.py
148 lines (126 loc) · 5.42 KB
/
hyperweather.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
import tkinter as tk
import tkinter.font as tkf
import requests
class HyperWeather:
"""
tkinter window class to display weather for specific location on hyperpixel 4.0 square
"""
_LABEL_CITY = None
_LABEL_TEMPERATURE = None
_LABEL_DESCRIPTION = None
_LABEL_ADDITIONAL = None
def __init__(self, apikey: str,
zipcode: int = 8405,
countrycode: str = 'CH',
measurement: str = 'standard',
fullscreen: bool = False) -> None:
"""
create tkinter window and start loop
:param apikey: set OpenWeather API key as string
:param zipcode: zipcode as int
:param countrycode: 2-letter country code (ISO3166) as string eq. CH, US or etc.
:param measurement: measurement as 'standard', 'metric' or 'imperial'
:param fullscreen: set window fullscreen mode as bool
"""
print(f"[INFO]: zip: {zipcode}, country: {countrycode}, measurement: {measurement}, fullscreen: {fullscreen}")
self.fullscreen = bool(fullscreen)
self.apikey = str(apikey)
self.countrycode = str(countrycode)
self.measurement = str(measurement)
self.zipcode = int(zipcode)
self.count = 1
self.window = tk.Tk()
self._config_window()
self._add_widgets()
self.window.after(10, self.__set_values)
self.window.mainloop()
def _config_window(self) -> None:
"""
configure tkinter window behavior
:return: None
"""
self.window.title('HyperWeather')
self.window.resizable(width=tk.FALSE, height=tk.FALSE)
self.window.geometry("720x720+0+0")
self.window.config(bg='black')
self.window.protocol("WM_DELETE_WINDOW", self._on_closing)
self.window.bind('<Escape>', self._exit)
if self.fullscreen:
self.window.config(cursor='none')
self.window.attributes("-fullscreen", True)
def _add_widgets(self) -> None:
"""
add specific tkinter widgets to window
:return: None
"""
city_font = tkf.Font(family='Technology', size=40, weight='normal')
temp_font = tkf.Font(family='LED Display7', size=55, weight='normal')
desc_font = tkf.Font(family='Technology', size=20, weight='normal')
additional_font = tkf.Font(family='Technology', size=15, weight='normal')
self._LABEL_CITY = tk.Label(self.window, text='unknown', font=city_font, bg='black', fg='#eeeeee')
self._LABEL_TEMPERATURE = tk.Label(self.window, text='unknown', font=temp_font, bg='black', fg='#8ED1FC')
self._LABEL_DESCRIPTION = tk.Label(self.window, text='unknown', font=desc_font, bg='black', fg='#eeeeee')
self._LABEL_ADDITIONAL = tk.Label(self.window, text='unknown', font=additional_font, bg='black', fg='#eeeeee')
self._LABEL_CITY.place(anchor=tk.CENTER, relx=.5, rely=.35)
self._LABEL_TEMPERATURE.place(anchor=tk.CENTER, relx=.5, rely=.5)
self._LABEL_DESCRIPTION.place(anchor=tk.CENTER, relx=.5, rely=.6)
self._LABEL_ADDITIONAL.place(anchor=tk.CENTER, relx=.5, rely=.67)
@staticmethod
def get_measurement_units(measurement: str) -> str:
"""
convert measurement into units
:param measurement: measurement standard, metric or imperial
:return: string of units
"""
if measurement == 'imperial':
unit = u"\N{DEGREE SIGN}" + 'F'
elif measurement == 'metric':
unit = u"\N{DEGREE SIGN}" + 'C'
else:
unit = 'K'
return str(unit)
def __set_values(self) -> None:
"""
call rest api and update tkinter labels
:return: None
"""
city = ''
temp = ''
desc = ''
additional = ''
zip_code = f"{self.zipcode},{self.countrycode}"
api_url = 'https://api.openweathermap.org/data/2.5/weather'
params = dict(zip=zip_code, units=self.measurement, appid=self.apikey)
response = requests.get(api_url, params)
print(f'[INFO]: send {self.count} request to {api_url}')
if response.status_code == 200 and 'application/json' in response.headers.get('Content-Type'):
json_response = response.json()
city = f"{json_response['name']}"
temp = f"{json_response['main']['temp']}{HyperWeather.get_measurement_units(self.measurement)}"
desc = f"{json_response['weather'][0]['description']}"
additional = f"Pressure: {json_response['main']['pressure']} hPa - Humidity: {json_response['main']['humidity']} %"
try:
self.count += 1
self._LABEL_CITY.configure(text=city)
self._LABEL_TEMPERATURE.configure(text=temp)
self._LABEL_DESCRIPTION.configure(text=desc)
self._LABEL_ADDITIONAL.configure(text=additional)
except KeyError as err:
print(f"[ERROR]: {err}")
self.window.after(30000, self.__set_values)
def _on_closing(self) -> None:
"""
catch mouse close window event
:return: None
"""
self._exit('close window by mouse')
def _exit(self, event) -> None:
"""
exit and close tkinter window
:return: None
"""
print(f"[INFO]: {event}")
self.window.destroy()
if __name__ == '__main__':
# get free api key from openweathermap.org
HyperWeather(apikey='', measurement='metric', fullscreen=True)