Fetch and display weather data.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
4.3 KiB
Raw

from datetime import datetime, timedelta
import json
import os.path
import requests
import time
class HandleWeatherFile:
"""
Fetch weather data from the infoclimat.fr public API.
Save the data into JSON file for future use so as to not overload the
free API.
Provide helper function to retrieve information from the JSON file.
@param latitude Latitude of the point in space to gather weather data from.
@param longitude Latitude of the point in space to gather weather data from.
@param filename Name of the JSON file that host weather data.
"""
def __init__(self,latitude=48.85341,longitude=2.3488,filename="WeatherReport.json"):
self.latitude=latitude
self.longitude=longitude
self.filename=filename
def fetchWeatherFile(self,fileValidityInSecond=3600):
"""
Fetch the JSON weather report file from the web
Use self.filename file to store the data. If this file already
exist and it's creation date is less than "fileValidityInSecond"
then its content is used instead of an API request.
The self.filename file will be saved/overrode automatically.
@param fileValidityInSecond Maximum time in second for an old file to be valid.
"""
fetchNewFile=True
jsonData=None
if(os.path.exists(self.filename)):
f=open(self.filename)
try:
jsonData=json.load(f)
if jsonData.get("fetchTime")!=None:
if (jsonData["fetchTime"]+fileValidityInSecond)>time.time():
fetchNewFile=False
except Exception:
pass
f.close()
if fetchNewFile:
try:
request=requests.get("https://www.infoclimat.fr/public-api/gfs/json?_ll="+str(self.latitude)+","+str(self.longitude)+"&_auth=VkxeSQ5wVnRQfQQzVCJXflE5ADUNe1dwB3tRMgBlAH1UPwRlBGRUMlI8WyZTfFJkAy5XNAE6BzcEbwZ%2BXS8AYVY8XjIOZVYxUD8EYVR7V3xRfwBhDS1XcAdlUTYAZAB9VDYEaQRnVChSPlsnU2JSbwM2VygBIQc%2BBGEGYl05AGBWPF44Dm5WMlA%2BBHlUe1dlUWMAMg01V20HYFEwAGQAYVQxBGkEYlQxUj1bJ1NqUmcDNFc3ATsHNwRiBmldLwB8VkxeSQ5wVnRQfQQzVCJXflE3AD4NZg%3D%3D&_c=8f0f822a713fe1e38891d301396859ea");
if(request.status_code==200):
jsonData=request.json()
jsonData["fetchTime"]=time.time()
f=open(self.filename, "w")
f.write(json.dumps(jsonData))
f.close()
else:
jsonData=request.status_code
except Exception:
pass
return jsonData
def getFormattedDateTimeArray(self,dayCount,includeToday=False,hour=[]):
"""
Return an array composed of string representing dates and times formatted like the weather JSON file
@param dayCount Number of days of measure (counting up from today)
@param includeToday Indicate if dayCount include today or not
@param hour Hours to include, can be empty: then all possible hour will be returned.
"""
dayDateTime=[]
currentDateTime=datetime.now()
for i in range(dayCount):
if includeToday:
if i==0:
iDateTime=currentDateTime
else:
iDateTime=currentDateTime+timedelta(days=i)
else:
iDateTime=currentDateTime+timedelta(days=i+1)
if len(hour)==0:
for h in range(0,24):
dayDateTime.append(self._getFormattedDateTime(iDateTime,h))
else:
for h in hour:
dayDateTime.append(self._getFormattedDateTime(iDateTime,h))
return dayDateTime
def _getFormattedDateTime(self,dateTimeObj,hour):
"""
Return a dateTime string formatted like the weather JSON file
@param dateTimeObj dateTime object used to get year/month and day.
@param hour Hour to be used instead of the dateTimeObj value
"""
return(
str(dateTimeObj.year)
+"-"+str(dateTimeObj.month).rjust(2,"0")
+"-"+str(dateTimeObj.day).rjust(2,"0")
+" "+str(hour).rjust(2,"0")
+":00:00"
)
def getWeatherFileMeasureHours(self,integerValue=False):
"""
Return an array with all the possible measured hours within the weather report file.
Return empty array if file empty or fail to open.
@param integerValue Return only the integer value of the hour instead of "HH:MM:SS" by default.
"""
validHours=[]
measureDateTime=datetime.now()+timedelta(days=1)
measureDay=self._getFormattedDateTime(measureDateTime,0)[:-9]
if(os.path.exists(self.filename)):
f=open(self.filename)
try:
jsonData=json.load(f)
for k in jsonData.keys():
if k.__contains__(measureDay):
validHours.append(k.replace(measureDay+" ",""))
except Exception:
pass
f.close()
if(integerValue):
for i in range(0,len(validHours)):
validHours[i]=int(validHours[i].replace(":00:00",""))
return validHours