text: # -*- coding: utf-8 -*-
  """
  <author>
  <Date>
  
  Functions to fetch (historic, current or prognosed) weather data from wunderground weather stations.
  Required: API key, to be added to opengrid.cfg.
  
  """
  
  # import libraries specific to wunderground script
  import datetime
  import pytz
  import pandas as pd
  import pdb
  
  
  import urllib2 
  import json 
  from pprint import pprint
  import time
  
  
  class Wunderground(object):
      """
      Class to manage api calls to fetch current and historic weather data from
      Wunderground weather stations
      
      This class avoids calling the api again for getting the current conditions
      if they have been obtained within time_delay_min. This is handled by the
      following attributes:
      
      * timestamp_current: timestamp when last call to fetch current conditions
        was succesfully launched
      * json_current : json object returned with the last call
      * time_delay : if timestamp_current is within this time_delay from the
        actual time, use the existing json_current.  Else, call Wunderground to 
        update json_current, and update timestamp_current accordingly.
      """
  
      def __init__(self, apikey, city, time_delay=20*60):
          """
          Parameters
          ----------
          * apikey : String
              Wunderground API key (can be obtained after subscription)
          * city : String
              Location of weather station
          * time_delay: float
              Time delay in seconds for calling api since last call for current conditions
          """
          
          self.apikey = apikey
          self.city = city
          self.time_delay = time_delay
          
          self.json_current = None
          self.timestamp_current = 0
          
      def reset(self):
          """
          Reset json_current and timestam_current
          """
          
          self.json_current = None
          self.timestamp_current = 0
          
      
      def _fetch_current(self):
          """
          Call Wunderground to get current conditions and overwrite
          json_current and timestamp_current
          """
          URL = ''.join(['http://api.wunderground.com/api/',self.apikey,'/geolookup/conditions/q/EU/',self.city,'.json'])
          f = urllib2.urlopen(URL) 
          json_string = f.read() 
          self.json_current = json.loads(json_string)
          self.timestamp_current = time.time()
          
          print("Obtained current conditions and saved json in self.json_current")
          
      def fetch_current(self):
          """
          Call Wunderground to get current conditions IF NEEDED based on current
          time, self.timestamp_current and self.time_delay.  
          If Wunderground is to be called, overwrite json_current and timestamp_current
          """        
          
          if time.time() < (self.timestamp_current + self.time_delay):
              print("No need to call Wunderground, using cached current conditions.")
          else:
              self._fetch_current()
              
      
      def show_properties(self):
          """
          Print all properties that can be obtained from the current conditions
          todo!!
          """
          
          try:
              print("These are the known current properties:\n")
              for prop in self.json_current['current_observation'].keys():
                  print(prop)
          except:
              print("Problem reading self.json_current")
              
  
      def get_current(self, prop):
          """
          Extract current value for prop from self.json_current. 
          Fetch current conditions from Wunderground if needed, depending on 
          current time, self.timestamp_current and self.time_delay. 
          
          Parameters
          ----------
          * prop : String
              Type of weather property to look up.
              
          Returns
          -------
          value, timestamp : value and associated timestamp
          
          Note
          ----
          If prop cannot be found, print all possible properties and raise a 
          ValueError
          """
              
          self.fetch_current()
                  
          try:
              curr_value = float(self.json_current['current_observation'][prop] )
          except:
              print("Property not found.")            
              self.show_properties()
              raise ValueError('Property {} not found.  See show_properties() to get a list with all possibilities'.format(prop))
          
      
          return curr_value, self.timestamp_current
          
  
  #Script to obtain CURRENT weather detail readings
  def fetch_curr_conditions(apikey, city, prop='temp_c'):
      '''
      Generic function for getting current weather conditions in a specified city.
          
      Parameters
      ----------
      * apikey : String
          Wunderground API key (can be obtained after subscription)
      * city : String
          location of weather station
      * prop : String
          Type of weather property to look up.  
          
      Returns
      -------
      
      
      Author: Ryton & comments from Saroele
  
      Output:  double return with value, date/time. If an error occurs, the json response will be printed.
      '''
      #
      
      URL = ''.join(['http://api.wunderground.com/api/',apikey,'/geolookup/conditions/q/EU/',city,'.json'])
      f = urllib2.urlopen(URL) 
      json_string = f.read() 
      parsed_json = json.loads(json_string) 
      #pprint(parsed_json)
      
      try:
          location = parsed_json['location']['city'] 
          curr_value = float(parsed_json['current_observation'][prop] )
          currdate = datetime.date.today()
      except:
          pprint(parsed_json)
          raise
      
      f.close()
  
      return curr_value, currdate
  
  def details_xdaysago(key,city,x_days_ago = 5,prop = "temp_c",columnname ='T_out'):
      """
      Get more subhourly details for a single day, x days ago
      
      todo: complete docstring
      """
      x_days_ago_date =  datetime.datetime.today()- datetime.timedelta(days=x_days_ago)   
      temp_values = fetch_historic_temp_bydate(key,city,x_days_ago_date,prop,columnname)
      return temp_values
  
  
  #some scripts for HISTORIC data fetching
  
  def fetch_historic_tempYMD(key,city,year,month,day, prop = 'tempm',columnname= 'T_out' ):
      """
      Get temp df using year month day.
  
      
      Example URL: http://api.wunderground.com/api/<key>/history_20140808/q/EU/Leuven.json
      
      todo: complete docstring    
      """    
      d = datetime.datetime(year,month,day,0,0)
      datestr = '{:%Y%m%d}'.format(d)
      
      URL = ''.join(['http://api.wunderground.com/api/',key,'/history_',datestr,'/q/BE/',city,'.json'])
      f = urllib2.urlopen(URL) 
      json_string = f.read() 
      parsed_json = json.loads(json_string) 
      #print json_string
      #pprint(parsed_json["history"]['dailysummary'])
      hr = "hour"
      minu = "min"
      time_list=[]
      temp_c_list= []
  
      for  entry in parsed_json["history"]["observations"]:
          #pprint(entry)
          hour_value = entry["date"][hr]
          min_value = entry["date"][minu]
          temp_c = entry[prop]
          temp_c_list.append(float(temp_c))
          concattime = datetime.datetime(year,month, day,int(hour_value),int(min_value))
          time_list.append(concattime)
          
          
          #print concattime, temp_c
      # print shape(temp_c_list), shape(time_list)
      Tout_h = pd.DataFrame(temp_c_list,columns = [columnname],index = time_list)
      return Tout_h
      f.close()
      
  def fetch_historic_temp_bydate(key,city,date_object, prop = 'tempm',columnname= 'T_out' ):
  #same as above, but with dateobject as input. hour / min are ignored
      year = date_object.year
      month = date_object.month
      day = date_object.day
      Tout_h = fetch_historic_tempYMD(key,city,year,month,day, prop ,columnname)
      return Tout_h
  
  #scripts for Historic day-AVERAGE weather fetching
  
  def fetch_historic_dayaverage(key,city,year,month,day,prop = "meantempm",columnname ='T_out'):
      # example URL: http://api.wunderground.com/api/<key>/history_20140808/q/EU/Leuven.json
      # get temp df using year month day.
      #city = 'Geel'   
      d = datetime.datetime(year,month,day,0,0)
      datestr = '{:%Y%m%d}'.format(d)
      
      URL = ''.join(['http://api.wunderground.com/api/',key,'/history_',datestr,'/q/BE/',city,'.json'])
      f = urllib2.urlopen(URL) 
      json_string = f.read() 
      parsed_json = json.loads(json_string) 
      
      #print json_string
      #pprint(parsed_json["history"]['dailysummary'])
      hr = "hour"
      minu = "min"
      
      time_list=[]
      temp_c_list= []
      
      for  entry in parsed_json["history"]['dailysummary']:
          #"pprint(entry)
          hour_value = entry["date"][hr]
          min_value = entry["date"][minu]
          temp_c = entry[prop]
          temp_c_list.append(temp_c)
          concattime = datetime.datetime(year,month, day,int(hour_value),int(min_value))
          time_list.append(concattime)
          #print concattime, temp_c
      #Tout_h = pd.DataFrame([temp_c_list],columns = ['T_out'],index = time_list)
      #parse_dates=['Date'], dayfirst=True, index_col='Date'
      Tout_h = pd.DataFrame([temp_c_list],columns = [columnname], index=time_list)
      #
      
      #Tout_h_T.set_index(time_list)
      f.close()
      return Tout_h
      
      
  def fetch_historic_dayaverage_by_date(key,city,date_object,prop = 'meantempm',columnname ='T_out'):
  #same as above, but with dateobject as input. hour / min are ignored
      year = date_object.year
      month = date_object.month
      day = date_object.day
      Tout_h = fetch_historic_dayaverage(key,city,year,month,day,prop,columnname);
      return Tout_h
  
  def average_temp_xdaysago(key,city,x_days_ago = 5,prop = 'meantempm',columnname ='T_out'):
  #get more subhourly details for a single day, eg. day 5
      x_days_ago_date =  datetime.datetime.today()- datetime.timedelta(days=x_days_ago)   
      temp_values = fetch_historic_dayaverage_by_date(key,city,x_days_ago_date,prop,columnname)
      return temp_values
  
  
  	
  