Skip to content

Instantly share code, notes, and snippets.

@nedgonaes
Created September 4, 2019 02:29
Show Gist options
  • Save nedgonaes/022b9320ed43706b58dd314af4625a53 to your computer and use it in GitHub Desktop.
Save nedgonaes/022b9320ed43706b58dd314af4625a53 to your computer and use it in GitHub Desktop.
very rough cut at finding airports in a list that have better than 1000/2 weather.
#!/usr/bin/env python3
import urllib.request
import xml.etree.ElementTree as ET
from datetime import datetime,timedelta
from collections import namedtuple
import math
#NOTE: TAKE THIS AS AN INPUT
targetTime = datetime.strptime("2019-09-04T15:01:00Z","%Y-%m-%dT%H:%M:%SZ")
minus_one_hour = targetTime - timedelta(hours=1)
plus_one_hour = targetTime + timedelta(hours=1)
# Read the airports file to retrieve list of airports and use as order for LEDs
with open("airports") as f:
airports = f.readlines()
airports = [x.strip() for x in airports]
# Retrieve TAF from aviationweather.gov data server
# Details about parameters can be found here: https://www.aviationweather.gov/dataserver/example?datatype=metar
url = "https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=tafs&requestType=retrieve&format=xml&hoursBeforeNow=5&mostRecentForEachStation=true&stationString=" + ",".join(
[item for item in airports if item != "NULL"])
print(url)
content = urllib.request.urlopen(url).read()
root = ET.fromstring(content)
conditionDict = {"": ""}
for taf in root.iter('TAF'):
stationId = taf.find('station_id').text
print(stationId)
qualifies = True
for forecast in taf.findall('forecast'):
if forecast.find('fcst_time_from') is None:
continue
if forecast.find('fcst_time_to') is None:
continue
fcst_time_from = datetime.strptime(forecast.find('fcst_time_from').text,"%Y-%m-%dT%H:%M:%SZ")
fcst_time_to = datetime.strptime(forecast.find('fcst_time_to').text,"%Y-%m-%dT%H:%M:%SZ")
latest_start = max(fcst_time_from, minus_one_hour)
earliest_end = min(fcst_time_to, plus_one_hour)
if latest_start <= earliest_end:
#get ceiling, assumes always listed in ascending order
ceiling = math.inf
vis = math.inf
if forecast.findall('sky_condition') is not None:
for sky_condition in reversed(forecast.findall('sky_condition')):
if sky_condition.get('sky_cover') in ['BKN','OVC']:
ceiling = int(sky_condition.get('cloud_base_ft_agl'))
#print(sky_condition.get('sky_cover'), sky_condition.get('cloud_base_ft_agl'))
if ceiling < 1000:
qualifies = False
print("disqualified, ceiling", fcst_time_from,fcst_time_to)
#get vis
if forecast.find('visibility_statute_mi') is not None:
visibility_statute_mi = float(forecast.find('visibility_statute_mi').text)
if visibility_statute_mi < 2.0:
qualifies = False
print("disqualified, vis", fcst_time_from,fcst_time_to)
conditionDict[stationId] = qualifies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment