Private
Public Access
1
0
Files
rowsandall/rowers/weather.py
Sander Roosendaal 764044899a fix errors
2023-04-10 13:32:10 +02:00

163 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:
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]