10/18/2023 Map Stopped Working?
Visit this post for the fix
Hello,
I am working on an 1850 pixel map. But the API request for all of those is too big and the aviationweather.gov server returns an error.
So I modified the code so it will only send a certain amount (300 at the time). It looks like it works but some airports are shown as Undefinded.
Maybe someone can help with this?
Here is the code I changed in the webapp.py
I added this lib at #60
from itertools import islice
This var at #139
max_api_airports = 300 # The max amount of airports from api with one request
I also changed this value LED_COUNT = 2000
And these are my edits from #1533 to #1702
# routine to capture airport information and pass along to web pages. def get_led_map_info(): logger.debug('In get_led_map_info Routine') global led_map_url global led_map_dict global lat_list global lon_list global max_lat global min_lat global max_lon global min_lon airports_count = len(airports) lmu_tmp = led_map_url print ("Number of airports in the list: ", airports_count) tmp_ap = airports_count tmp_start = 0 tmp_end = max_api_airports while (tmp_ap >= 0): print ("tmp_start: ", tmp_start) print ("tmp_ap: ", tmp_ap) print ("tmp_end: ", tmp_end) for airportcode in islice(airports, tmp_start, tmp_end): lmu_tmp = lmu_tmp + airportcode + "," #led_map_url = led_map_url[:-1] logger.debug(lmu_tmp) # debug url if neccessary while True: # check internet availability and retry if necessary. If house power outage, map may boot quicker than router. try: content = urllib.request.urlopen(lmu_tmp).read() logger.info('Internet Available') logger.info(lmu_tmp) break except: logger.warning('FAA Data Not Available') logger.warning(lmu_tmp) time.sleep(delay_time) content = '' pass if content == '': # if FAA data not available bypass getting apinfo return root = ET.fromstring(content) # Process XML data returned from FAA for led_map_info in root.iter('METAR'): stationId = led_map_info.find('station_id').text try: lat = led_map_info.find('latitude').text lon = led_map_info.find('longitude').text except: lat = '0' lon = '0' lat_list.append(lat) lon_list.append(lon) if led_map_info.find('flight_category') is None: fl_cat = 'Not Reported' else: fl_cat = led_map_info.find('flight_category').text led_map_dict[stationId] = [lat,lon,fl_cat] tmp_ap = tmp_ap - max_api_airports tmp_start = tmp_start + max_api_airports tmp_end = tmp_end + max_api_airports lmu_tmp = led_map_url max_lat = max(lat_list) min_lat = min(lat_list) max_lon = max(lon_list) min_lon = min(lon_list) # routine to capture airport information and pass along to web pages. def get_apinfo(): logger.debug('In Get_Apinfo Routine') global orig_apurl global apinfo_dict #print (max_api_airports) airports_count = len(airports) print ("Number of airports in the list: ", airports_count) apurl = orig_apurl # Assign base FAA url to temp variable tmp_ap = airports_count tmp_start = 0 tmp_end = max_api_airports while (tmp_ap >= 0): print ("tmp_start: ", tmp_start) print ("tmp_ap: ", tmp_ap) print ("tmp_end: ", tmp_end) for airportcode in islice(airports, tmp_start, tmp_end): apurl = apurl + airportcode + "," #apurl = apurl[:-1] print ("URL string: ", apurl) while True: # check internet availability and retry if necessary. If house power outage, map may boot quicker than router. try: # s.connect(("8.8.8.8", 80)) content = urllib.request.urlopen(apurl).read() logger.info('Internet Available') logger.info(apurl) break except: logger.warning('FAA Data Not Available') logger.warning(apurl) time.sleep(delay_time) content = '' pass if content == '': # if FAA data not available bypass getting apinfo return root = ET.fromstring(content) # Process XML data returned from FAA for apinfo in root.iter('Station'): stationId = apinfo.find('station_id').text if stationId[0] != 'K': site = apinfo.find('site').text country = apinfo.find('country').text apinfo_dict[stationId] = [site,country] else: site = apinfo.find('site').text state = apinfo.find('state').text apinfo_dict[stationId] = [site,state] tmp_ap = tmp_ap - max_api_airports tmp_start = tmp_start + max_api_airports tmp_end = tmp_end + max_api_airports apurl = orig_apurl #print (content) #content2 = content.decode() #file = open("temp123.xml", "w") #file.write(content2) #file.close() """ root = ET.fromstring(content) # Process XML data returned from FAA for apinfo in root.iter('Station'): stationId = apinfo.find('station_id').text if stationId[0] != 'K': site = apinfo.find('site').text country = apinfo.find('country').text apinfo_dict[stationId] = [site,country] else: site = apinfo.find('site').text state = apinfo.find('state').text apinfo_dict[stationId] = [site,state] """
Marty, all I can say is "Wow". This will be an awesome map. I can't wait to see a picture.
If I understand your question properly, the undefined nature of an airport (as listed in the airport editor) does not necessarily correlate to an error, or missing metar from that airport.
There are a number of weather data products at work on this project. The Airport editor uses an API from weather.gov while the LED's uses XML data returned from https://www.aviationweather.gov/dataserver. For some reason, there are often inconsistencies between these 2 weather products that I can't explain.
So as long as you know that each airport you are using publishes a METAR your LED's should perform properly. This URL will list all the airports and will tell you if it reports a METAR or not;
https://www.aviationweather.gov/docs/metar/stations.txt
Mark
Hi Mark,
thanks for your fast reply. So the API URL used in both functions is just for the LEDs.
They both start with: www.aviationweather.gov
This is how it looks like on the webapp:
When I look up those airports directly on the aviationweather.gov, all of those UNDF ones reporting METARs
Thanks,
Daniel
Yes, that's what has confounded me all this time.
Try this in your browser;
https://api.weather.gov/stations/KPZZ/observations/latest
Then try this;
https://api.weather.gov/stations/KGHB/observations/latest
I have no idea why there is a discrepancy. I've often wondered if I should remove the weather report from the airports editor for this very reason. BTW: The reason for using this api, is that I can use Jquery and Ajax to update the html on the page on the fly.
Hope this helps explain it. - Mark
@markyharris Thanks for the links. I also have an issue when I click on map layout.
I get this error,
builtins.KeyError KeyError: 'KXER' Traceback (most recent call last) File "/usr/lib/python3/dist-packages/flask/app.py", line 2309, in __call__ return self.wsgi_app(environ, start_response) File "/usr/lib/python3/dist-packages/flask/app.py", line 2295, in wsgi_app response = self.handle_exception(e) File "/usr/lib/python3/dist-packages/flask/app.py", line 1741, in handle_exception reraise(exc_type, exc_value, tb) File "/usr/lib/python3/dist-packages/flask/_compat.py", line 35, in reraise raise value File "/usr/lib/python3/dist-packages/flask/app.py", line 2292, in wsgi_app response = self.full_dispatch_request() File "/usr/lib/python3/dist-packages/flask/app.py", line 1815, in full_dispatch_request rv = self.handle_user_exception(e) File "/usr/lib/python3/dist-packages/flask/app.py", line 1718, in handle_user_exception reraise(exc_type, exc_value, tb) File "/usr/lib/python3/dist-packages/flask/_compat.py", line 35, in reraise raise value File "/usr/lib/python3/dist-packages/flask/app.py", line 1813, in full_dispatch_request rv = self.dispatch_request() File "/usr/lib/python3/dist-packages/flask/app.py", line 1799, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/NeoSectional/webapp.py", line 359, in led_map +"</a><br>Pin Number = "+str(pin_num)+"<br><b><font size=+2 color="+color+">"+led_map_dict[led_ap][2]+"</font></b>" KeyError: 'KXER' The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error. To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.
KXER is not a recognized airport ID. Could it be mis-spelled?
Try this search on FAA's lookup site;
https://nfdc.faa.gov/nfdcApps/services/ajv5/airportDisplay.jsp?airportId=KXER
When you put a recognizable airport id in you won't get this error. - Mark
Hi Mark,
it's an offshore something, it reports the weather to aviationweather.gov and foreflight but maybe not to weather.gov
Thanks for all the help with this.
You are right. Here's the URL that the LED's use to display the proper flight category;
https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&mostRecentForEachStation=constraint&hoursBeforeNow=2.5&stationString=KXER
And it does in fact show the METAR data for KXER. It's a shame that all the weather products could not be synced up. - Mark