From e49a4e8f0e4682806fbb3d5cbc5a6d58bb496c17 Mon Sep 17 00:00:00 2001 From: Sander Roosendaal Date: Mon, 20 Feb 2017 20:38:12 +0100 Subject: [PATCH] added METAR --- rowers/templates/windedit.html | 4 +- rowers/urls.py | 2 +- rowers/views.py | 67 +++++++++++++++++++++++++++++++++- rowers/weather.py | 48 ++++++++++++++++++++++++ 4 files changed, 118 insertions(+), 3 deletions(-) diff --git a/rowers/templates/windedit.html b/rowers/templates/windedit.html index 5d9ea3e0..0d98cce7 100644 --- a/rowers/templates/windedit.html +++ b/rowers/templates/windedit.html @@ -53,7 +53,9 @@

Closest Airport Weather: {{ airport }} - ({{ airportdistance | floatformat:-1 }} km)

+ ({{ airportdistance | floatformat:-1 }} km) + Airport Data

+

Dark Sky Data

Download wind speed and bearing from The Dark Sky diff --git a/rowers/urls.py b/rowers/urls.py index 5a91bfd5..c756414f 100644 --- a/rowers/urls.py +++ b/rowers/urls.py @@ -178,7 +178,7 @@ urlpatterns = [ url(r'^workout/(?P\d+)/wind/c/(?P\w+.*)$',views.workout_wind_view), url(r'^workout/(?P\d+)/wind/s/(?P\w+.*)$',views.workout_wind_view), url(r'^workout/(?P\d+)/darkskywind$',views.workout_downloadwind_view), - url(r'^workout/(?P\d+)/darkskywind/airport/(?P\w+)$',views.workout_downloadwind_view), + url(r'^workout/(?P\d+)/metar/(?P\w+)$',views.workout_downloadmetar_view), url(r'^workout/(\d+)/stream$',views.workout_stream_view), url(r'^workout/(?P\d+)/stream/c/(?P\w+.*)$',views.workout_stream_view), url(r'^workout/(\d+)/crewnerdsummary$',views.workout_crewnerd_summary_view), diff --git a/rowers/views.py b/rowers/views.py index f3f4e266..7ac02cb7 100644 --- a/rowers/views.py +++ b/rowers/views.py @@ -82,7 +82,7 @@ import mpld3 from mpld3 import plugins import stravalib from stravalib.exc import ActivityUploadFailed,TimeoutExceeded -from weather import get_wind_data,get_airport_code +from weather import get_wind_data,get_airport_code,get_metar_data from oauth2_provider.models import Application,Grant,AccessToken @@ -2495,7 +2495,72 @@ def workout_downloadwind_view(request,id=0, return response + +# Get weather for given location and date/time +@user_passes_test(ispromember,login_url="/",redirect_field_name=None) +def workout_downloadmetar_view(request,id=0, + airportcode=None, + message="",successmessage=""): + try: + row = Workout.objects.get(id=id) + except Workout.DoesNotExist: + raise Http404("Workout doesn't exist") + + f1 = row.csvfilename + if (checkworkoutuser(request.user,row)==False): + message = "You are not allowed to edit this workout" + url = reverse(workouts_view,args=[str(message)]) + + return HttpResponseRedirect(url) + + # create bearing + rowdata = rdata(f1) + if rowdata == 0: + return HttpResponse("Error: CSV Data File Not Found") + + try: + bearing = rowdata.df.ix[:,'bearing'].values + except KeyError: + rowdata.add_bearing() + rowdata.write_csv(f1,gzip=True) + + # get wind + try: + avglat = rowdata.df[' latitude'].mean() + avglon = rowdata.df[' longitude'].mean() + airportcode = get_airport_code(avglat,avglon)[0] + avgtime = int(rowdata.df['TimeStamp (sec)'].mean()-rowdata.df.ix[0,'TimeStamp (sec)']) + startdatetime = dateutil.parser.parse("{}, {}".format(row.date, + row.starttime)) + starttimeunix = int(mktime(startdatetime.timetuple())) + avgtime = starttimeunix+avgtime + winddata = get_metar_data(airportcode,avgtime) + windspeed = winddata[0] + windbearing = winddata[1] + message = winddata[2] + row.notes += "\n"+message + row.save() + rowdata.add_wind(windspeed,windbearing) + rowdata.write_csv(f1,gzip=True) + + kwargs = {'successmessage':str(message), + 'id':str(id)} + + url = reverse(workout_wind_view,kwargs=kwargs) + response = HttpResponseRedirect(url) + except KeyError: + message = "No latitude/longitude data" + kwargs = {'message':str(message), + 'id':str(id)} + url = reverse(workout_wind_view,kwargs=kwargs) + response = HttpResponseRedirect(url) + + + + return response + + # Show form to update wind data @user_passes_test(ispromember,login_url="/",redirect_field_name=None) def workout_wind_view(request,id=0,message="",successmessage=""): diff --git a/rowers/weather.py b/rowers/weather.py index 88022af0..4e9a74fd 100644 --- a/rowers/weather.py +++ b/rowers/weather.py @@ -1,5 +1,7 @@ import requests import json +from lxml import objectify,etree +import xml.etree.ElementTree as ET import time from datetime import datetime from rowingdata import rowingdata,geo_distance @@ -31,6 +33,52 @@ def get_weather_data(long,lat,unixtime): else: return 0 +# Get Metar data +def get_metar_data(airportcode,unixtime): + + timestamp = datetime.utcfromtimestamp(unixtime).isoformat()+'Z' + + url = "https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&startTime=" + url += str(unixtime-3600) + url += "&endTime=" + url += str(unixtime+3600) + url += "&stationString="+airportcode + + s = requests.get(url) + + if s.ok: + doc = etree.fromstring(s.content) + id = doc.xpath('data/METAR/station_id')[0].text + temp_c = doc.xpath('data/METAR/temp_c')[0].text + wind_dir = doc.xpath('data/METAR/wind_dir_degrees')[0].text + wind_speed = doc.xpath('data/METAR/wind_speed_kt')[0].text + timestamp = doc.xpath('data/METAR/observation_time')[0].text + rawtext = doc.xpath('data/METAR/raw_text')[0].text + + print temp_c,wind_dir,wind_speed + + windbearing = float(wind_dir) + wind_knots = float(wind_speed) + wind_ms = 0.514444*wind_knots + wind_ms = int(10*wind_ms)/10. + + temperaturec = float(temp_c) + temp_f = 32.+(9./5.)*temperaturec + temp_f = str(int(10*temp_f)/10.) + + message = 'Summary for your location at '+timestamp+': ' + message += 'Temperature '+temp_c+'C/'+temp_f+'F' + message += '. Wind: '+str(wind_ms)+' m/s ('+str(wind_knots)+' kt)' + message +='. Wind Bearing: '+str(windbearing)+' degrees' +# message +='\n'+rawtext + + return [wind_ms,windbearing,message,rawtext,timestamp] + + + message = 'Failed to download METAR data' + return [0,0,message,'',timestamp] + + # Get wind data (and translate from knots to m/s) def get_wind_data(lat,long,unixtime): data = get_weather_data(lat,long,unixtime)