import requests from requests.exceptions import ConnectionError import json from lxml import objectify, etree #import xml.etree.ElementTree as ET from defusedxml import ElementTree as ET import time from datetime import datetime from rowingdata import rowingdata, geo_distance import arrow import pandas as pd from rowers.models import Rower, Workout from rowsandall_app.settings import FORECAST_IO_KEY # Find closest airport def get_airport_code(lat, lon): metardata = pd.read_csv('rowers/data/metarlatlon.csv') deltasq = (lat-metardata.lat)**2+(lon-metardata.lon)**2 a = metardata[deltasq == deltasq.min()] airport_code = a.iloc[0]['icao'] newlat = a.iloc[0]['lat'] newlon = a.iloc[0]['lon'] distance = geo_distance(lat, lon, newlat, newlon) return airport_code, newlat, newlon, distance # Get weather data from the DarkSky API def get_weather_data(long, lat, unixtime): url = "https://api.darksky.net/forecast/"+FORECAST_IO_KEY+"/" url += str(long)+","+str(lat)+","+str(unixtime) try: s = requests.get(url) except ConnectionError: # pragma: no cover return 0 if s.ok: try: return s.json() except: return 0 else: # pragma: no cover return 0 # Get Metar data def get_metar_data(airportcode, unixtime): timestamp = arrow.get(unixtime).isoformat() 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 try: s = requests.get(url) except: # pragma: no cover message = 'Failed to download METAR data' return [0, 0, message, '', ''] if s.ok: # pragma: no cover try: doc = etree.fromstring(s.content) except AttributeError: message = 'METAR data content error' return [0, 0, message, '', 0] lengte = len(doc.xpath('data/METAR/station_id')) idnr = int(lengte/2) try: _ = doc.xpath('data/METAR/station_id')[idnr].text temp_c = doc.xpath('data/METAR/temp_c')[idnr].text wind_dir = doc.xpath('data/METAR/wind_dir_degrees')[idnr].text wind_speed = doc.xpath('data/METAR/wind_speed_kt')[idnr].text timestamp = doc.xpath('data/METAR/observation_time')[idnr].text rawtext = doc.xpath('data/METAR/raw_text')[idnr].text except IndexError: message = 'Failed to download METAR data' return [0, 0, message, '', timestamp] 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' # pragma: no cover return [0, 0, message, '', timestamp] # pragma: no cover # Get wind data (and translate from knots to m/s) def get_wind_data(lat, long, unixtime): data = get_weather_data(lat, long, unixtime) summary = '' temperature = 20 if data: # pragma: no cover try: # we are getting wind in mph windspeed = data['currently']['windSpeed']*0.44704 windbearing = data['currently']['windBearing'] except KeyError: windspeed = 0 windbearing = 0 try: airports = data['flags']['madis-stations'] except KeyError: airports = ['unknown'] try: temperature = data['currently']['temperature'] # Temp is given in Fahrenheit, so convert to Celsius for Europeans temperaturec = (temperature-32.)*(5./9.) temperaturec = int(10*temperaturec)/10. except KeyError: temperature = 'unknown' temperaturec = 'unknown' try: summary = data['currently']['summary'] except KeyError: summary = 'unknown' else: windspeed = 0 windbearing = 0 summary = 'unknown' airports = ['unknown'] temperature = 'unknown' temperaturec = 'unknown' message = 'Not able to get weather data' # apply Hellman's coefficient for neutral air above human # inhabitated areas windspeed = windspeed*(0.1)**0.34 windspeed = 0.01*int(100*windspeed) timestamp = arrow.get(unixtime).isoformat() message = 'Summary for your location at '+timestamp+': '+summary message += '. Temperature '+str(temperature)+'F/'+str(temperaturec)+'C' if data: # pragma: no cover message += '. Wind: ' + \ str(windspeed)+' m/s. Wind Bearing: '+str(windbearing)+' degrees' return [windspeed, windbearing, message, airports, timestamp]