Function: Fetch historic and current ambient conditions, from a wunderground weather station.

Note: To make this code work, you have to make a (free) account on wunderground and obtain an API key. A Wunderground cumulus account is free of charge, and supports 500 calls per day, 10 per minute. Request it here: http://api.wunderground.com/members/signup.asp

Then fill in your assigned developer apikey either in script settings below, or store your key in the opengrid.cfg file, with header [Wunderground] (see opengrid.cfg-example)


In [ ]:
import os, sys
import inspect
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.dates import HourLocator, DateFormatter, AutoDateLocator
import datetime as dt
import pytz
import pandas as pd
import pdb


# add the sccript path to opengrid to sys.path
script_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
sys.path.append(os.path.join(script_dir, os.pardir, os.pardir))

from opengrid.library import config
from opengrid.library import wundergroundapi as WGapi

%matplotlib inline
plt.rcParams['figure.figsize']=14,8

Script settings


In [ ]:
c = config.Config()

key = c.get('Wunderground', 'apikey')
#apikey = 'SET_CUSTOM_KEY_HERE'
path_to_data = c.get('data', 'folder')
#path_to_data = 'SET_CUSTOM_PATH_HERE'

if not os.path.exists(path_to_data):
    raise IOError("Provide your path to the data.  This is a folder containing a 'zip' and 'csv' subfolder.")
else:
    path_to_csv = os.path.join(path_to_data, 'csv')

In [ ]:
key # print key to see if it is valid

In [ ]:
reload(WGapi)

Create an object of the Wounderground class and get current weather conditions

We set a small time delay to test the caching. In practice, I think time delays of 15 minutes are fine?


In [ ]:
wg = WGapi.Wunderground(apikey=key, city='Leuven', time_delay=10)

Try running the cell below several times to see how the caching works.


In [ ]:
for prop in ['temp_c', 'solarradiation', 'wind_kph']:
    curr_value , timestamp = wg.get_current(prop)
    print("Current {} in {} is: {} (on {})".format(prop, 
                                                   wg.city,
                                                   curr_value,
                                                   pd.Timestamp(timestamp, unit='s', tz='Europe/Brussels')))

In [ ]:
wg.get_current('wind_kph')

When we ask a property that is not known, a list with know properties is printed and a ValueError is raised


In [ ]:
wg.get_current('relhum')

In [ ]:
#Example for CURRENT weather detail readings

location = 'Leuven'
Some_property_options =[ 'relative_humidity','solarradiation', 'temp_c', 'temp_f','temperature_string','visibility_km','lotsmore']
#(full list: see pprint(parsed_json))
Property ='temp_c'
curr_value , currdate = WGapi.fetch_curr_conditions(key,location, prop= Property)
print "Current %s (on %s) in %s is: %s" % (Property, currdate, location, curr_value)

Property = 'solarradiation'
curr_value2 , currdate = WGapi.fetch_curr_conditions(key,location,prop=Property)
print "Current %s (on %s) in %s is: %s" % (Property, currdate, location, curr_value2)

#Todo: add units to this example

In [ ]:
#Examples for HISTORIC weather detail readings: x days ago
city = 'Leuven'

TempDF = WGapi.details_xdaysago(key,city,5,prop = 'tempm',columnname ='T_out [degC]')
relhum = WGapi.details_xdaysago(key,city,5,prop = 'hum',columnname ='Rel humidity [%]')

df = TempDF.join(relhum)
df.plot(subplots=True)

In [ ]:
#full historic weather details
Tout_h = WGapi.fetch_historic_tempYMD(key,'Leuven',2014,9,8,prop='tempm', columnname = u'T_out [°C]') # for 8th of September, thus YYYYMMDD
hum_h = WGapi.fetch_historic_tempYMD(key,'Leuven',2014,9,8,prop='hum',columnname= 'RelHumidity [%]') # for 8th of September, thus YYYYMMDD
#solrad = WGapi.fetch_historic_tempYMD(key,'Leuven',2014,9,8,prop='solarradiation',columnname= u'Solar radiation [W/m²]') # for 8th of September, thus YYYYMMDD

df = pd.concat([Tout_h, hum_h], axis=1)
df.plot(subplots=True)
df.head()

In [ ]:
#Examples for Historic day-AVERAGE weather fetching
#for more options, uncomment pprint(parsed_json["history"]['dailysummary'])
#just one average temp
out2 =WGapi.fetch_historic_dayaverage(key,'Leuven',2014,8,10, prop ='meantempm',columnname ='T_out') # for 10th of august, thus YYYMMDD
#or some day summaries: 
HDD =WGapi.fetch_historic_dayaverage(key,'Leuven',2014,8,10, prop ='heatingdegreedays',columnname ='HDD') # for 10th of august, thus YYYYMMDD
CDD =WGapi.fetch_historic_dayaverage(key,'Leuven',2014,8,10, prop ='coolingdegreedays',columnname ='CDD') # for 10th of august, thus YYYYMMDD
print out2.join(HDD.join(CDD)) #keep less than 10 calls per min...

In [ ]:
# WIP / Todo
##WIP-part  (WORK IN PROGRESS)
# 0) Add script to give list of possible query options.  
# 1) Add script to find weather station component.  
# 
# A) (low prio) fix figure X-axis in date & make some more fancy graphs (improved date-axis)
# B) (high prio) Multiple calls (such as Average_Temp_Xdaysago could be grouped in single call too. (api call that gets longer list of data).
# C) (high prio) make a usefull example: e.g. Current solar radiation vs PV production , or (historic) HDD vs gas usage.

In [ ]:


In [ ]:
#A)fancy graphs (improved date-axis)
import matplotlib.dates
fig = plt.figure()
ax = fig.gca() 
 
# Plotting stuff here ...
ax.plot_date(dates, temps, 'b.-')
 
# Set major x ticks on Mondays.
ax.xaxis.set_major_locator(
    matplotlib.dates.WeekdayLocator(byweekday=matplotlib.dates.MO)
)
ax.xaxis.set_major_formatter(
    matplotlib.dates.DateFormatter('%a %d\n%b %Y')
)

In [ ]:
#WIP B)
def WGapi.Average_Temp_Xdaysago(key,city,ndays = 5,prop = "temp_c",PDcolumnname ='T_out', averaged =True ,plot_data = True, 
                          startdate = dt.datetime.today()):
    '''
    Gives and/or plots list of (average or detailed) outdoor temperatures over a longer (fixed) number of days, 
    starting from day before today (or startdate).

    Inputs:
    * key: API token
    * city: name of city, string
    * ndays: number of fetched days before startdate . Note: Please set ndays<10 because of nr of calls allowed per minute (==10)!!
    * averaged: True => Daily-averaged, False =>  detailed (20 minute) profile
    * plot: on or off.
    * startdate: defaults to today, but can be used to fetch historic period too.
    '''
    print 'Detailed ambient temperature in ',city,' for last', str(ndays-1),' days'
    
    i = 1 #starting from day before startdate.
    date_i =  startdate- dt.timedelta(days=i)
    if averaged:
        Texdf = WGapi.Fetch_historic_dayaverage_By_date(key,city,date_i,prop,PDcolumnname)
    else:
        Texdf = WGapi.Fetch_historic_temp_ByDate(key,city,date_i,prop,PDcolumnname) 
    
    # one average: Fetch_historic_dayaverage_By_date(key,city,date_i)
    # = pd.DataFrame( data=Tyest['T_out'].values, index= Tyest.index)
    for i in range(2,ndays,1): 
        date_i =  startdate- datetime.timedelta(days=i)
        if averaged:
            new_df = WGapi.Fetch_historic_dayaverage_By_date(key,city,date_i,prop,PDcolumnname)
        else:
            new_df = WGapi.Fetch_historic_temp_ByDate(key,city,date_i,prop,PDcolumnname) 
    
        Texdf = pd.DataFrame.combine_first(Texdf,new_df)


    if plot_data:
    # sorted trough combine_first
        temps = []
        dates = []
        temps = Texdf.values
        dates = Texdf.index
        title = 'Details on subhourly outdoor temperatures over multiple days'
        fig=figure
        f1 = plt.plot(dates,temps)
        x_label = 'Ambient temperature (°C)'
        plt.ylabel([x_label])
        plt.title(title)
    return Texdf
    
#Example:
Temps=WGapi.Average_Temp_Xdaysago(key,'Leuven',ndays = 5, averaged =False,plot_data = True, startdate = dt.datetime.today() )

In [ ]:


In [ ]:


In [ ]: