diff --git a/data.txt b/data.txt index 54f8349..651fc5d 100755 --- a/data.txt +++ b/data.txt @@ -1,4 +1,4 @@ -KSEZ +KFLG 1 60 0 diff --git a/metar_display.py b/metar_display.py index fa33240..eaf17bc 100755 --- a/metar_display.py +++ b/metar_display.py @@ -2,17 +2,20 @@ # Metar Display - Mark Harris # Version 2.1 # UPDATED FAA API 12-2023, https://aviationweather.gov/data/api/ +# Part of Epaper Display project found at; https://github.com/markyharris/metar/ # # Altered from https://github.com/aerodynamics-py/WEATHER_STATION_PI # # Added a number of bold fonts # Added a number of drawing routines for rounded corners, etc. + # Imports from PIL import Image, ImageDraw, ImageFont, ImageOps import requests import urllib.request + # Setup fonts that could be chosen. Default font_choice is #5 # Look in '/usr/share/fonts/truetype/' to see what is installed on # specific system and change as necessary. @@ -63,20 +66,16 @@ class Metar: def __init__(self, airport): self.data = requests.get( -# f"https://api.weather.gov/stations/"+airport+"/observations/latest", timeout=5).json() f"https://aviationweather.gov/api/data/metar?ids="+airport+"&format=json&hours=2.5").json() self.data2 = requests.get( -# f"https://api.weather.gov/stations/"+airport, timeout=5).json() f"https://aviationweather.gov/api/data/metar?ids="+airport+"&format=json&hours=2.5").json() requests.session().close() pass def update(self, airport): self.data = requests.get( -# f"https://api.weather.gov/stations/"+airport+"/observations/latest", timeout=5).json() f"https://aviationweather.gov/api/data/metar?ids="+airport+"&format=json&hours=2.5").json() self.data2 = requests.get( -# f"https://api.weather.gov/stations/"+airport, timeout=5).json() f"https://aviationweather.gov/api/data/metar?ids="+airport+"&format=json&hours=2.5").json() requests.session().close() return self.data, self.data2 diff --git a/metar_layouts.py b/metar_layouts.py index 36c23a0..2808e3e 100755 --- a/metar_layouts.py +++ b/metar_layouts.py @@ -1,6 +1,8 @@ # metar_layouts.py # Layouts for Metar Display - Mark Harris # Version 2.1 +# Part of Epaper Display project found at; https://github.com/markyharris/metar/ +# # UPDATED FAA API 12-2023, https://aviationweather.gov/data/api/ # # Each Layout offers a different look and amount of information. @@ -330,7 +332,7 @@ def layout1(display,metar,remarks,print_table,use_remarks,use_disp_format,interv # Display Wind Speed windsp,dis_unit = get_wspd(metar,wind_speed_units) - if windsp == "Calm" or float(windsp) < 5.0: + if windsp == "Calm" or windsp == "n/a" or float(windsp) < 5.0: display.draw_icon(COL2+ICON_OFFSET, LINE3+5, "r", 50, 50, "windvanelow") elif float(windsp) >= 5.0 and float(windsp) < 15.0: display.draw_icon(COL2+ICON_OFFSET, LINE3+5, "r", 50, 50, "windvanemed") diff --git a/metar_main.py b/metar_main.py index ebbee3f..a0ada05 100755 --- a/metar_main.py +++ b/metar_main.py @@ -1,6 +1,8 @@ # metar_main.py # E-Paper METAR Display - by Mark Harris # Version 2.1 +# Part of Epaper Display project found at; https://github.com/markyharris/metar/ +# # UPDATED to New FAA API 12-2023, https://aviationweather.gov/data/api/ # # Thanks to Aerodynamics for providing a great start for this project diff --git a/metar_routines.py b/metar_routines.py index c42f27b..4933bc6 100755 --- a/metar_routines.py +++ b/metar_routines.py @@ -1,6 +1,8 @@ # metar_routines.py # Metar Decoding Routines - Mark Harris # Version 2.1 +# Part of Epaper Display project found at; https://github.com/markyharris/metar/ +# # UPDATED FAA API 12-2023, https://aviationweather.gov/data/api/ # Imports @@ -134,9 +136,7 @@ def get_visib(metar,visibility_units): # "Visibility in statute miles, 10+ is gr if type(metar.data[0]["visib"]) == int or type(metar.data[0]["visib"]) == float: tmp_vis = float(metar.data[0]["visib"]) else: -# print('metar.data[0]["visib"]',metar.data[0]["visib"]) # debug tmp_vis = metar.data[0]["visib"].strip('+') -# print(tmp_vis) # debug tmp_vis = float(tmp_vis) vis = '{0:.1f}'.format(tmp_vis) if visibility_units == 1: @@ -160,7 +160,6 @@ def get_rawOb(metar): # "Raw text of observation" string rawmetar = metar.data[0]['rawOb'] else: rawmetar = 'n/a' -# print ('rawmetar:',rawmetar) # debug return(rawmetar) def get_wdir(metar): # "Wind direction in degrees or VRB for variable winds" integer @@ -247,7 +246,8 @@ def get_misc(metar): # icaoid,obstime,elev,lat,lon,name = get_misc(metar) lat = metar.data[0]["lat"] # "Latitude of site in degrees" number lon = metar.data[0]["lon"] # "Longitude of site in degrees" number name = metar.data[0]["name"] # "Full name of the site" string - print(icaoid,obstime,elev,lat,lon,name) + + print(icaoid,obstime,elev,lat,lon,name) # debug return(icaoid,obstime,elev,lat,lon,name) @@ -261,14 +261,12 @@ def get_ip_address(): return ip_address - - # Get Flight Categories for Class B and Class C airports def get_flightcat(): - # api url + # api url; the first 2 are old FAA API's that have been sunsetted. Required significant rewrite to accomodate the new system. # url = "https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=2.5&stationString=" - url = "https://aviationweather-cprk.ncep.noaa.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=2.5&stationString=" - +# url = "https://aviationweather-cprk.ncep.noaa.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=2.5&stationString=" + url = "https://aviationweather.gov/api/data/metar?format=xml&hours=2.5&ids=" # Latest API from FAA, https://aviationweather.gov/data/api/ fc_dict = {} vfr_dict = {} mvfr_dict = {} @@ -282,13 +280,10 @@ def get_flightcat(): url = url+ap+"," content = urllib.request.urlopen(url).read() - root = ET.fromstring(content) #Process XML data returned from FAA -# print(root) # debug for data in root.iter('data'): num_results = data.attrib['num_results'] - print(num_results) for metar in root.iter('METAR'): stationId = metar.find('station_id').text @@ -308,6 +303,7 @@ def get_flightcat(): else: vfr_dict[key] = "VFR" +# print(vfr_dict,mvfr_dict,ifr_dict,lifr_dict) # debug return(vfr_dict,mvfr_dict,ifr_dict,lifr_dict) @@ -327,9 +323,9 @@ def flight_category(metar): print("num_clouds layers:",len(metar.data[0]['clouds'])) # debug # Get Cloud Cover - for i in range(len(metar.data[0]['clouds'])): #["properties"]["cloudLayers"])): - sky_condition = metar.data[0]['clouds'][i]['cover'] #["properties"]["cloudLayers"][i]["amount"] - sky_ceiling = metar.data[0]['clouds'][i]['base'] #["properties"]["cloudLayers"][i]["amount"] + for i in range(len(metar.data[0]['clouds'])): + sky_condition = metar.data[0]['clouds'][i]['cover'] + sky_ceiling = metar.data[0]['clouds'][i]['base'] if sky_condition == "OVC" or sky_condition == "BKN" or sky_condition == "OVX" or sky_condition == "VV": if sky_ceiling < 500: @@ -395,9 +391,10 @@ def decode_remarks(rawmessage): # Provides the proper icon to display depending on wind direction def wind_arrow(deg): - if deg == "000" or deg == "VRB": + if deg == "000" or deg == "VRB" or deg == "n/a": arrow = "compass" return arrow + deg = int(deg) if deg < 30 or deg >= 330: arrow = "north" @@ -421,7 +418,6 @@ def wind_arrow(deg): return (arrow) - # decodes raw metar string to grab wind direction wind speed, gusts, temperature and baro # This info is used as backup if the api does not provide this data in its normal response. def decode_rawmessage(airport_name): @@ -439,7 +435,6 @@ def decode_rawmessage(airport_name): # use either live metar or test_metar from above. try: decode = airport_name.split() -# print("***",decode) # debug except: print("*decode try failed") # debug decoded_airport,decoded_time,decoded_wndir,decoded_wnspd,decoded_wngust,decoded_vis,\ @@ -468,7 +463,6 @@ def decode_rawmessage(airport_name): # Get Visibility NEEDS WORK for i in range(len(decode)): -# print("i: ",i) # debug if len(decode[i]) == 1 and i < len(decode): decode[i] = decode[i]+" "+decode[i+1] diff --git a/metar_settings.py b/metar_settings.py index 475ffc2..e638ce5 100755 --- a/metar_settings.py +++ b/metar_settings.py @@ -1,14 +1,16 @@ # metar_settings.py # Metar Display Settings - Mark Harris # Version 2.1 +# Part of Epaper Display project found at; https://github.com/markyharris/metar/ +# # UPDATED FAA API 12-2023, https://aviationweather.gov/data/api/ # # These settings will be used if script is run with no cmd line arguments # Default User Settings airport = "KFLG" # enter default airport identifier to display -use_disp_format = -2 # Choose which display layout to use. -1 = Random layout, -2 = Cycle layouts -interval = 60 # enter default time in seconds between METAR updates - i.e. 3600 = 1 hour +use_disp_format = -2 # Choose which display layout to use. -1 = Random layout, -2 = Cycle layouts +interval = 60 # enter default time in seconds between METAR updates - i.e. 3600 = 1 hour use_remarks = 0 # 0 = display airport information, 1 = display metar remarks info # Display Units @@ -24,5 +26,4 @@ # For randomly selected airports, put more than 12 in list. 12 will randomly be displayed, 13th will be default # If you put less than 12 airports in list, it will pad the missing spots with the default airport above. random_airports = ["KEYW","KFVE","KSEA","KCVG", "KLAS","KCMR","KGRR","KMSN", \ - "KLAX","KNBC","KFVE","KBUF"] #, "KTPA", "KLAS","KGEU","KOLS", \ - # "KSAN", "KPDX", "KBOI", "KMSP", "KSTL", "KBNA", "KTYS"] + "KLAX","KNBC","KFVE","KBUF"] diff --git a/metar_startup.py b/metar_startup.py index 6a78c69..dbecc0d 100644 --- a/metar_startup.py +++ b/metar_startup.py @@ -1,3 +1,14 @@ +# metar_startup.py - Mark Harris +# for E-Paper display +# Version 2.1 +# Part of Epaper Display project found at; https://github.com/markyharris/metar/ +# +# UPDATED FAA API 12-2023, https://aviationweather.gov/data/api/ +# +# This script is run only once upon boot/reboot to display the Admin Page's URL. +# rc.local runs this script, then waits for a bit then runs the 'metar_main.py' script and the 'webapp.py' script + +# imports from metar_layouts import * from metar_routines import * import time diff --git a/templates/metar.html b/templates/metar.html index 4edaf63..2c54ac4 100755 --- a/templates/metar.html +++ b/templates/metar.html @@ -24,6 +24,7 @@ .myDiv span{ text-align: center; background: #ffffff; + background-color: transparent; padding: 6px 6px; display: block; width: 120px; diff --git a/webapp.py b/webapp.py index 8a319ab..3508c16 100755 --- a/webapp.py +++ b/webapp.py @@ -1,6 +1,8 @@ # webapp.py - Mark Harris # for E-Paper display # Version 2.1 +# Part of Epaper Display project found at; https://github.com/markyharris/metar/ +# # UPDATED FAA API 12-2023, https://aviationweather.gov/data/api/ # # This will provide a web interface to control the e-Paper display. @@ -78,7 +80,6 @@ def metar(): else: os.system("ps -ef | grep 'metar_main.py' | awk '{print $2}' | xargs sudo kill") -# os.system('sudo python3 ' + PATH + 'metar_main.py '+ data_field1+' '+data_field2+' '+data_field3+' '+data_field4+' &') os.system('sudo python3 ' + PATH + 'metar_main.py ' + ' ' + data_field1 + ' ' + data_field2 + ' ' + data_field3 + " " + data_field4 \ + " " + data_field5 + ' ' + data_field6 + ' ' + data_field7 + " " + data_field8 + " " + data_field9 + ' &') @@ -138,7 +139,7 @@ def get_data(): # create cmdline command to start the main program using the 'data.txt' variables to kick things off. print('sudo python3 ' + PATH + 'metar_main.py ' + ' ' + data_field1 + ' ' + data_field2 + ' ' + data_field3 + ' ' + data_field4 \ - + ' ' + data_field5 + ' ' + data_field6 + ' ' + data_field7 + " " + data_field8 + ' ' + data_field9 + ' &') # debug + + ' ' + data_field5 + ' ' + data_field6 + ' ' + data_field7 + " " + data_field8 + ' ' + data_field9 + ' &\n') # debug # first run at startup. display web admin ip url for 60 seconds os.system('sudo python3 ' + PATH + 'metar_main.py ' + ' ' + data_field1 + ' ' + data_field2 + ' ' + data_field3 + ' ' + data_field4 \