-
Notifications
You must be signed in to change notification settings - Fork 0
/
example.py
executable file
·124 lines (107 loc) · 3.18 KB
/
example.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
#!/usr/bin/python3
# Example script for displaying local airport weather METARs on the LED board.
#
# Written by Calvin Owens <jcalvinowens@gmail.com>
#
# To the extent possible under law, I waive all copyright and related or
# neighboring rights. You should have received a copy of the CC0 license along
# with this work. If not, see http://creativecommons.org/publicdomain/zero/1.0
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
import subprocess
from datetime import datetime, timezone
import http.client
AIRPORTS = [
"PAO",
"NUQ",
"HWD",
"LVK",
"C83",
"TCY",
"CCR",
"OAK",
"DVO",
"O69",
"APC",
"STS",
"HAF",
"SFO",
"RHV",
"SJC",
"E16",
"CVH",
"WVI",
"OAR",
"MRY",
]
# The HTTP API requires you to provide a "KILO" prefix, even for airports that
# don't actually have one (like C83)...
def airports():
return ",".join("K" + aid for aid in AIRPORTS)
def get_metars():
try:
c = http.client.HTTPSConnection("aviationweather.gov")
c.request("GET", f"/cgi-bin/data/metar.php?ids={airports()}&hours=0&format=raw", "", {})
metars = c.getresponse().read().decode("ascii", "ignore").splitlines()
except:
metars = []
finally:
c.close()
metarsout = []
metarsout.append(" " * 16 + "LOCAL METARS...")
now = datetime.now(timezone.utc)
for metar in metars:
metarsplit = metar.split(' ')
# Delete remarks
if "RMK" in metarsplit:
del metarsplit[metarsplit.index("RMK"):]
# Show the airport ID again at the end
metarsplit.append(metarsplit[0])
# Decode METAR timestamp (DDHHMM)
# FIXME: Wrong crossing midnight last day of month
mtime = datetime(
year=now.year,
month=now.month,
day=int(metarsplit[1][0:2]),
hour=int(metarsplit[1][2:4]),
minute=int(metarsplit[1][4:6]),
tzinfo=timezone.utc,
)
delta = now - mtime
# Convert the UTC timestamp to the local timezone
#metarsplit[1] = mtime.astimezone().strftime("%H%M%Z")
# Convert the UTC timestamp to a relative one
if delta.seconds >= 3600:
metarsplit[1] = "%.1f HOURS AGO" % (delta.seconds / 3600)
else:
metarsplit[1] = "%02d MINUTES AGO" % (delta.seconds // 60)
# Convert C to F and append it
for f in filter(lambda x: "/" in x, (x for x in metarsplit)):
try:
t, d = f.split("/")
t = t.replace("M", "-")
d = d.replace("M", "-")
temp = int(t)
dew = int(d)
faren = "%s%02dF/%s%02dF" % (
"M" if temp < 0 else "", abs(temp * 1.8 + 32),
"M" if dew < 0 else "", abs(dew * 1.8 + 32),
)
metarsplit[metarsplit.index(f)] += " " + faren
except:
continue
metarsout.append(" ".join(metarsplit))
if len(metarsout) == 1:
return ["HELP I AM BROKEN"]
return [(" " * 8).join(metarsout) + " " * 16]
def run_client(*args):
cmd = ["./driver.py"]
cmd.extend(args)
subprocess.check_call(cmd)
while True:
run_client(*(["--col-shift", "0.0375"] + get_metars()))