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

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

c = config.Config()

sys.path.append(c.get('tmpo', 'folder'))
import tmpo
try:
    if os.path.exists(c.get('tmpo', 'data')):
        path_to_tmpo_data = c.get('tmpo', 'data')
except:
    path_to_tmpo_data = None

from opengrid.library.houseprint import houseprint

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

"""
Explanation: This script shows how to use the existing code in opengrid
to create (a) a timeseries plot and (b) a load curve of gas, water or elektricity usage.
Todo:
Change numeric "chosen_type" to a textual choice, with lookupvalue of UtilityType in Utilitytypes.
End of explanation
"""


hp = houseprint.load_houseprint_from_file('new_houseprint.pkl')
hp.init_tmpo(path_to_tmpo_data=path_to_tmpo_data)

"""
Explanation: Script settings
End of explanation
"""


chosen_type = 0
#  0 =water, 1 = gas, 2 = electricity

UtilityTypes = ['water', 'gas','electricity'] # {'water','gas','electricity'} 
utility =  UtilityTypes[chosen_type] # here 'electricity'

#default values:
FL_units = ['l/day', 'm^3/day ~ 10 kWh/day','Ws/day'] #TODO, to be checked!!
Base_Units = ['l/min', 'kW','kW']
Base_Corr = [1/24.0/60.0, 1/100.0/24.0/3.600 , 3.600/1000.0/24 ] #TODO,check validity of conversions!! # water => (l/day) to (l/hr), gas: (l/day) to (kW), elektr Ws/d to kW

tInt_Units = ['l', 'kWh','kWh'] #units after integration
tInt_Corr = [1/60, 3600/60, 3600/60] #TODO, to be checked!! # water => (l/hr) to (l_cumul/min), gas: kW to (kWh/min)

# units for this utility type
bUnit = Base_Units[chosen_type]
bCorr = Base_Corr[chosen_type]
fl_unit = FL_units[chosen_type]
tiUnit = tInt_Units[chosen_type]
tiCorr = tInt_Corr[chosen_type]


"""
Explanation: Fill in here (chosen type [0-2]) what type of data you'd like to plot:
End of explanation
"""


#load data
print 'Loading', utility ,'-data and converting from ',fl_unit ,' to ',bUnit,':'
df = hp.get_data(sensortype=utility)
df = df.diff() #data is cumulative, we need to take the derivative
df = df[df>0] #filter out negative values

# conversion dependent on type of utility (to be checked!!) 
df = df*bCorr

# plot timeseries and load duration for each retained sensor

for sensor in df.columns:
    FL = hp.find_sensor(sensor).device.key
    plt.figure()
    ax1=plt.subplot(121)
    plt.plot_date(df.index, df[sensor], '-', label="{}".format(FL))
    plt.ylabel("{}-usage [{}]".format(utility,bUnit) )
    plt.legend()
    
    ax2=plt.subplot(122)
    plt.plot(np.sort(df[sensor])[::-1], label=sensor)
    plt.ylabel("{}-load curve [{}]".format(utility,bUnit) )
    plt.legend()

#Date/Time library
from arrow import Arrow

#Prepare NVD3.js dependencies
from IPython import display as d
import nvd3
nvd3.ipynb.initialize_javascript(use_remote=True)

#Filter sensors and period
sensorlist = ['b28509eb97137e723995838c393d49df', '2923b75daf93e539e37ce5177c0008c5', 'a926bc966f178fc5d507a569a5bfc3d7']
df_water= df[sensorlist][Arrow(2015, 4, 1).datetime:Arrow(2015, 4, 2).datetime].dropna()

#Prepare chart name and timescale in epoch
chart_name = "{}-usage [{}]".format(utility,bUnit)
df_water["epoch"] = [(Arrow.fromdatetime(o) - Arrow(1970, 1, 1)).total_seconds()*1000 for o in df_water.index]

#Create NVD3 chart
water_chart = nvd3.lineChart(x_is_date=True,name=chart_name,height=450,width=800)
for sensor in sensorlist: # df.columns:
    series_name = name="{}".format(hp.find_sensor(sensor).device.key)
    water_chart.add_serie(name=series_name, x=list(df_water["epoch"]), y=list(df_water[sensor]))

water_chart

"""
Explanation: Available data is loaded in one big dataframe, the columns are the sensors of chosen type.
also, it is rescaled to more "managable" units (to be verified!)
End of explanation
"""


start = pd.Timestamp('20150201')
end = pd.Timestamp('20150301')

dfcum = hp.get_data(sensortype='electricity', head= start, tail = end)

dfcum.shape

dfcum.columns

dfcum.tail()

dfi = dfcum.resample(rule='900s', how='max')
dfi = dfi.interpolate(method='time')
dfi=dfi.diff()*3600/900
dfi.plot()
#dfi.ix['20150701'].plot()

# This works, but is a bad idea if you have multiple sensors for a FLM: you obtain identical column names.
# df.rename(columns = hp.get_flukso_from_sensor, inplace=True)

# Getting a single sensor
dfi['1a1dac9c2ac155f95c58bf1d4f4b7d01'].plot()

"""
Explanation: Tests with the tmpo-based approach
End of explanation
"""


