160 lines
5.1 KiB
Python
160 lines
5.1 KiB
Python
import requests
|
|
from requests.exceptions import ConnectionError
|
|
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
|
|
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:
|
|
return s.json()
|
|
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]
|