Skip to content

Commit

Permalink
derConsumer: Added utility rate API function and fixed utilityProgram…
Browse files Browse the repository at this point in the history
… option in html. \ derUtilityCost: Changed lat/lon to Brighton, CO; minor edits
  • Loading branch information
astronobri committed May 29, 2024
1 parent a5b1572 commit e20b018
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 24 deletions.
6 changes: 3 additions & 3 deletions omf/models/derConsumer.html
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,10 @@
</div>
<hr style="border-style: solid; border-color: #196b12; margin-top: 10px;">
<div class="shortInput">
<label>Consider Utility DER program?</label>
<label>Consider utility DER sharing program?</label>
<select id="utilityProgram" name="utilityProgram" value="{{allInputDataDict.utilityProgram}}">
<option value="True" {{ 'selected' if allInputDataDict.outage == 'Yes' }}>Yes</option>
<option value="False" {{ 'selected' if allInputDataDict.outage == 'No' }}>No</option>
<option value="True" {{ 'selected' if allInputDataDict.utilityProgram == 'Yes' }}>Yes</option>
<option value="False" {{ 'selected' if allInputDataDict.utilityProgram == 'No' }}>No</option>
</select>
</div>
<div class="shortInput">
Expand Down
114 changes: 95 additions & 19 deletions omf/models/derConsumer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import pandas as pd
import plotly.graph_objs as go
import plotly.utils
from numpy_financial import npv
import requests

# OMF imports
from omf.models import __neoMetaModel__
Expand Down Expand Up @@ -214,6 +214,35 @@ def create_REopt_jl_jsonFile(modelDir, inputDict):
json.dump(scenario, jsonFile)
return scenario


def get_tou_rates(modelDir, lat, lon): ## TODO: change lat,lon to inputDict once model is working
api_url = 'https://api.openei.org/utility_rates?parameters'
api_key = '5dFShfSVRt2XJpPYCbzBeLM6nHrOXc0VFPTWxfJJ' ## API key generated by following this website: 'https://openei.org/services/'

params = {
'version': '3',
'format': 'json',
'lat': lat,
'lon': lon,
'api_key': api_key
}
try:
response = requests.get(api_url, params=params)
response.raise_for_status() ## Raise an exception for HTTP errors

data = response.json()

# Save the retrieved data as a JSON file
with open(pJoin(modelDir, 'OEDIrateData.json'), 'w') as json_file:
json.dump(data, json_file)

return data

except requests.exceptions.RequestException as e:
print('Error:', e)
return None


def work(modelDir, inputDict):
''' Run the model in its directory. '''

Expand All @@ -233,7 +262,7 @@ def work(modelDir, inputDict):
# print('Successfully loaded REopt test file. \n')

## Run REopt.jl
reopt_jl.run_reopt_jl(modelDir, "reopt_input_scenario.json", outages=inputDict['outage'])
reopt_jl.run_reopt_jl(modelDir, 'reopt_input_scenario.json', outages=inputDict['outage'])
with open(pJoin(modelDir, 'results.json')) as jsonFile:
reoptResults = json.load(jsonFile)
outData.update(reoptResults) ## Update output file outData with REopt results data
Expand Down Expand Up @@ -386,7 +415,7 @@ def work(modelDir, inputDict):
# showlegend=showlegend))
#fig.update_traces(legendgroup='Demand', visible='legendonly', selector=dict(name='Original Load (kW)')) ## Make demand hidden on plot by default

## PV piece, if enabled
## PV plot, if enabled
if (inputDict['PV'] == 'Yes'):
fig.add_trace(go.Scatter(x=timestamps,
y=PV,
Expand All @@ -402,16 +431,16 @@ def work(modelDir, inputDict):
fig.update_layout(
#title='Residential Data',
xaxis=dict(title='Timestamp'),
yaxis=dict(title="Power (kW)"),
yaxis=dict(title='Power (kW)'),
yaxis2=dict(title='degrees Celsius',
overlaying='y',
side='right'
),
legend=dict(
orientation='h',
yanchor="bottom",
yanchor='bottom',
y=1.02,
xanchor="right",
xanchor='right',
x=1
)
)
Expand Down Expand Up @@ -472,20 +501,20 @@ def makeGridLine(x,y,color,name):
plotData.append(resilience)
plotlyLayout['yaxis'].update(title='Longest Outage survived (Hours)')
plotlyLayout['xaxis'].update(title='Start Hour')
outData["resilienceData"] = json.dumps(plotData, cls=plotly.utils.PlotlyJSONEncoder)
outData["resilienceLayout"] = json.dumps(plotlyLayout, cls=plotly.utils.PlotlyJSONEncoder)
outData['resilienceData'] = json.dumps(plotData, cls=plotly.utils.PlotlyJSONEncoder)
outData['resilienceLayout'] = json.dumps(plotlyLayout, cls=plotly.utils.PlotlyJSONEncoder)

plotData = []
survivalProb = go.Scatter(
x=outData['survivalProbX'],
y=outData['survivalProbY'],
line=dict( color=('red') ),
name="Probability of Surviving Outage of a Given Duration")
name='Probability of Surviving Outage of a Given Duration')
plotData.append(survivalProb)
plotlyLayout['yaxis'].update(title='Probability of meeting critical Load')
plotlyLayout['xaxis'].update(title='Outage Length (Hours)')
outData["resilienceProbData" ] = json.dumps(plotData, cls=plotly.utils.PlotlyJSONEncoder)
outData["resilienceProbLayout"] = json.dumps(plotlyLayout, cls=plotly.utils.PlotlyJSONEncoder)
outData['resilienceProbData' ] = json.dumps(plotData, cls=plotly.utils.PlotlyJSONEncoder)
outData['resilienceProbLayout'] = json.dumps(plotlyLayout, cls=plotly.utils.PlotlyJSONEncoder)


## Create Exported Power plot object
Expand Down Expand Up @@ -545,12 +574,12 @@ def makeGridLine(x,y,color,name):

fig.update_layout(
xaxis=dict(title='Timestamp'),
yaxis=dict(title="Power (kW)"),
yaxis=dict(title='Power (kW)'),
legend=dict(
orientation='h',
yanchor="bottom",
yanchor='bottom',
y=1.02,
xanchor="right",
xanchor='right',
x=1
)
)
Expand All @@ -559,18 +588,65 @@ def makeGridLine(x,y,color,name):
outData['exportedPowerData'] = json.dumps(fig.data, cls=plotly.utils.PlotlyJSONEncoder)
outData['exportedPowerLayout'] = json.dumps(fig.layout, cls=plotly.utils.PlotlyJSONEncoder)

# Model operations typically ends here.
## DER Sharing Program options
if (inputDict['utilityProgram']):
print('Considering utility DER sharing program \n')

## Gather TOU rates
#latitude = float(inputDict['latitude'])
#longitude = float(inputDict['longitude'])
## NOTE: Temporarily use the lat/lon for a utility that has TOU rates specifically
latitude = 39.986771
longitude = -104.812599 ## Brighton, CO
rate_info = get_tou_rates(modelDir, latitude, longitude) ## NOTE: lan/lon will be replaced by inputDict

## Extract "name" keys containing "TOU" or "time of use"
filtered_names = [item['name'] for item in rate_info['items'] if 'TOU' in item['name'] or 'time-of-use' in item['name'] or 'Time of Use' in item['name']]
for name in filtered_names: ## Print the filtered names
print(name)

TOUname = 'Residential Time of Use'
TOUdata = []

for item in rate_info['items']:
if item['name'] == TOUname:
TOUdata.append(item)

print(TOUdata)

'''
rate_info = {
'rate_name': data['items'][0]['name'], ## Rate name
'fixed_monthly_charge': data['items'][0]['fixedmonthlycharge'], ## Fixed monthly charge ($)
'demand_rate_unit': data['items'][0]['demandrateunit'], ## Time of Use Rate Units
'demand_rate_structure': data['items'][0]['demandratestructure'], ## Time of Use Demand Charge Structure
'demand_weekday_schedule': data['items'][0]['demandweekdayschedule'],
'demand_weekend_schedule': data['items'][0]['demandweekendschedule'],
'flat_demand_structure': data['items'][0]['flatdemandstructure'],
'flat_demand_months': data['items'][0]['flatdemandmonths'],
'flat_demand_unit': data['items'][0]['flatdemandunit']
}
'''

## Generate peak shave schedule

## Determine area under the curve

## Apply rate compensations to DERs deployed

## Plot the peak shave schedule?

# Stdout/stderr.
outData["stdout"] = "Success"
outData["stderr"] = ""
outData['stdout'] = 'Success'
outData['stderr'] = ''

return outData

def new(modelDir):
''' Create a new instance of this model. Returns true on success, false on failure. '''
with open(pJoin(__neoMetaModel__._omfDir,"static","testFiles","residential_PV_load.csv")) as f:
with open(pJoin(__neoMetaModel__._omfDir,'static','testFiles','residential_PV_load.csv')) as f:
demand_curve = f.read()
with open(pJoin(__neoMetaModel__._omfDir,"static","testFiles","residential_extended_temperature_data.csv")) as f:
with open(pJoin(__neoMetaModel__._omfDir,'static','testFiles','residential_extended_temperature_data.csv')) as f:
temp_curve = f.read()

defaultInputs = {
Expand Down
4 changes: 2 additions & 2 deletions omf/models/derUtilityCost.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,8 @@ def new(modelDir):
'created': str(datetime.datetime.now()),

## REopt inputs:
'latitude' : '39.7392358',
'longitude' : '-104.990251', ## Brighton, CO
'latitude' : '39.986771 ',
'longitude' : '-104.812599', ## Brighton, CO
'year' : '2018',
'analysis_years' : '25',
'urdbLabel' : '612ff9c15457a3ec18a5f7d3', ## Brighton, CO
Expand Down

0 comments on commit e20b018

Please sign in to comment.