Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/dpinney/omf
Browse files Browse the repository at this point in the history
  • Loading branch information
SaeedRazavi committed Jun 7, 2024
2 parents 0d18713 + f1b5246 commit 2a7abdc
Show file tree
Hide file tree
Showing 37 changed files with 4,042 additions and 1,044 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ omf/solvers/PowerModelsONM/PowerModelsONM*
omf/solvers/PowerModelsONM/Manifest.toml
omf/solvers/PowerModelsONM/Project.toml
omf/solvers/PowerModelsONM/build/*
omf/solvers/PowerModelsONM/instantiated.txt
gridlabd.dmg
omf/omf.error.log
omf/omf.access.log
Expand Down Expand Up @@ -65,4 +64,4 @@ omf/solvers/reopt_jl/testFiles/resultsResilience.json
omf/solvers/reopt_jl/testFiles/results.json
omf/solvers/reopt_jl/testFiles/REoptInputs.json
omf/solvers/reopt_jl/reopt_jl.so
omf/solvers/reopt_jl/instantiated.txt
instantiated.txt
28 changes: 28 additions & 0 deletions omf.novol.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# A Dockerfile for running the Open Modeling Framework
FROM ubuntu:18.04

# Install and setup OMF reqs
RUN apt-get -y update && apt-get install -y git python3 sudo
RUN cd home; git clone --depth 1 https://github.com/dpinney/omf
RUN cd /home/omf; python3 install.py

# Run the OMF
EXPOSE 5000
WORKDIR /home/omf/omf
ENTRYPOINT ["python3"]
CMD ["web.py"]

# INSTRUCTIONS
# ============
# - Navigate to this directory
# - Build image with command `docker build -f newomf.dockerfile -t omfim .`
# - Run image in background with `docker run -d -p 5000:5000 --name omfcon omfim`
# - View at http://127.0.0.1:5000
# - Stop it with `docker stop omfcon` and remove it with `docker rm omfcon`.
# - Delete the images with `docker rmi omfim`
#
# FEATURE IDEAS
# =============
# - Switch to install.py instead of manual apt commands
# - Python "build" script to create, start and exit the image
# - Modify Dockerfile to use a network drive containing the omf repo instead of doing a fresh git pull
File renamed without changes.
1 change: 1 addition & 0 deletions omf/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,4 @@
from omf.models import transformerPairing
from omf.models import derConsumer
from omf.models import derUtilityCost
#from omf.models import microgridPlan
141 changes: 116 additions & 25 deletions omf/models/derConsumer.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
<script src="https://cdn.plot.ly/plotly-1.50.1.min.js"></script>
<script type="text/javascript">
$(window).on('pageshow',function(){
Plotly.newPlot('plotlyPlot', JSON.parse(allOutputData['plotlyPlot']),JSON.parse(allOutputData['plotlyLayout']));
Plotly.newPlot('derOverviewData', JSON.parse(allOutputData['derOverviewData']),JSON.parse(allOutputData['derOverviewLayout']));
Plotly.newPlot('exportedPowerData', JSON.parse(allOutputData['exportedPowerData']),JSON.parse(allOutputData['exportedPowerLayout']));
Plotly.newPlot('resiliencePlotly', JSON.parse(allOutputData['resilienceData']), JSON.parse(allOutputData['resilienceLayout']) || {});
Plotly.newPlot('resilienceProbPlotly', JSON.parse(allOutputData['resilienceProbData']), JSON.parse(allOutputData['resilienceProbLayout']) || {});

});
</script>
</head>
Expand All @@ -20,7 +20,7 @@
<form name="inputForm" action="/runModel/" onsubmit="event.preventDefault(); return isFormValid();" method="post">
<!-- Required Inputs -->
<div class="shortInput">
<label>Model Type <a href="https://github.com/dpinney/omf/wiki/Models:-derConsumer" target="blank">Help?</a></label>
<label>Model Type <a href="https://github.com/dpinney/omf/wiki/Models-~-derConsumer" target="blank">Help?</a></label>
<input type="text" id="modelType" name="modelType" value="{{modelName}}" readonly/>
</div>
<div class="shortInput">
Expand All @@ -41,7 +41,7 @@
</div>
<!-- Model Specific Inputs -->
<div class="wideInput">
<p class="inputSectionHeader">Specific REopt Model Inputs</p>
<p class="inputSectionHeader">General Model Inputs</p>
</div>
<hr style="border-style: solid; border-color: #196b12; margin-top: 10px;">
<div class="shortInput">
Expand Down Expand Up @@ -80,28 +80,24 @@
</div>
<div class="shortInput">
<label class="tooltip">Analysis Period (years)<span class="classic">Specify the length of financial analysis in years.</span></label>
<input type="number" id="analysisYears" name="analysisYears" value="{{allInputDataDict.analysisYears}}" step="1" min="2" max="75" required="required"/>
</div>
<hr>
<div class="wideInput"> <!-- REopt technologies-->
<p class="inputSectionHeader" style="font-size: medium;">Model DER technologies</p>
<input type="number" id="analysis_years" name="analysis_years" value="{{allInputDataDict.analysis_years}}" step="1" min="2" max="75" required="required"/>
</div>
<div class="shortInput">
<label class="tooltip">PV<span class="classic">Include PV in DER analysis.</span></label>
<label class="tooltip">Photovoltaic<span class="classic">Include PV in DER analysis?</span></label>
<select id="PV" name="PV" value="{{allInputDataDict.PV}}"/>
<option value="Yes" {{ 'selected' if allInputDataDict.solar == 'Yes' }}>Yes</option>
<option value="No" {{ 'selected' if allInputDataDict.solar == 'No' }}>No</option>
</select>
</div>
<div class="shortInput">
<label class="tooltip">Battery<span class="classic">Include battery energy storage in DER analysis.</span></label>
<select id="battery" name="battery" value="{{allInputDataDict.BESS}}"/>
<label class="tooltip">Battery<span class="classic">Include battery energy storage in DER analysis?</span></label>
<select id="BESS" name="BESS" value="{{allInputDataDict.BESS}}"/>
<option value="Yes" {{ 'selected' if allInputDataDict.BESS == 'Yes' }}>Yes</option>
<option value="No" {{ 'selected' if allInputDataDict.BESS == 'No' }}>No</option>
</select>
</div>
<div class="shortInput">
<label class="tooltip">Diesel Generator<span class="classic">Include diesel generator in DER analysis.</span></label>
<label class="tooltip">Diesel Generator<span class="classic">Include diesel generator in DER analysis?</span></label>
<select id="generator" name="generator" value="{{allInputDataDict.generator}}"/>
<option value="Yes" {{ 'selected' if allInputDataDict.generator == 'Yes' }}>Yes</option>
<option value="No" {{ 'selected' if allInputDataDict.generator == 'No' }}>No</option>
Expand All @@ -111,8 +107,8 @@
<div class="shortInput">
<label>Simulate Outage</label>
<select id="outage" name="outage" value="{{allInputDataDict.outage}}">
<option value="True" {{ 'selected' if allInputDataDict.outage == 'True' }}>On</option>
<option value="False" {{ 'selected' if allInputDataDict.outage == 'False' }}>Off</option>
<option value="True" {{ 'selected' if allInputDataDict.outage == 'Yes' }}>Yes</option>
<option value="False" {{ 'selected' if allInputDataDict.outage == 'No' }}>No</option>
</select>
</div>
<div class="shortInput">
Expand All @@ -124,7 +120,7 @@
<input type="number" id="outage_duration" name="outage_duration" value="{{allInputDataDict.outage_duration}}" min="1" max="8760" required="required"/>
</div>
<div class="wideInput"> <!-- vbatDispatch Specific Inputs -->
<p class="inputSectionHeader">Specific vbatDispatch Model Inputs</p>
<p class="inputSectionHeader"> Thermal Model Inputs</p>
</div>
<hr style="border-style: solid; border-color: #196b12; margin-top: 10px;">
<div class="shortInput">
Expand Down Expand Up @@ -164,6 +160,7 @@
}
}
</script>
<option value="0" {{ 'selected' if allInputDataDict.load_type == '0' }}>None</option>
<option value="1" {{ 'selected' if allInputDataDict.load_type == '1' }}>Air Conditioner</option>
<option value="2" {{ 'selected' if allInputDataDict.load_type == '2' }}>Heat Pump</option>
<option value="3" {{ 'selected' if allInputDataDict.load_type == '3' }}>Refrigerator</option>
Expand Down Expand Up @@ -222,6 +219,27 @@
<label class="tooltip">Discount Rate (%)<span class="classic">Discount rate used in financial analysis.</span></label>
<input type="text" id="discountRate" name="discountRate" value="{{allInputDataDict.discountRate}}" pattern="[1-9][0-9]{0,2}" required="required">
</div>
<div class="wideInput">
<p class="inputSectionHeader">Distributed Energy Resource (DER) Program Design inputs</p>
</div>
<hr style="border-style: solid; border-color: #196b12; margin-top: 10px;">
<div class="shortInput">
<label>Consider utility DER sharing program?</label>
<select id="utilityProgram" name="utilityProgram" value="{{allInputDataDict.utilityProgram}}">
<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">
<label class="tooltip">Energy Compensation Rate ($/kWh)<span class="classic">The dollar amount per kWh compensated to the member-consumer.</span></label>
<input type="text" id="rateCompensation" name="rateCompensation" value="{{allInputDataDict.rateCompensation}}" pattern="^\d+\.?\d*?$" min="0" required="required"/>
</div>
<div class="shortInput">
<label class="tooltip">Maximum BESS discharge (%)<span class="classic">The maximum percentage of BESS total charge used for discharging. Most programs designate up to 80% of total charge, leaving the member with at least 20% charge.</span></label>
<input type="text" id="maxBESSDischarge" name="maxBESSDischarge" value="{{allInputDataDict.maxBESSDischarge}}" pattern="^\d+\.?\d*?$" min="0" max="1" required="required"/>
</div>


{{ omfModelButtons }}
</form>

Expand All @@ -230,18 +248,91 @@
{{ omfRunDebugBlock }}
{% if modelStatus == 'finished' %}
<!-- Output tables, graphs, etc -->
<div id="output">
<p class="reportTitle" style="page-break-before:always">DER Serving Load Overview</p>
<div id="derOverviewData" class="tightContent" style="width: 1000px; height: 600px;"></div>

<p class="reportTitle" style="page-break-before:always">Plotly Test Plot</p>
<div id="plotlyPlot" class="tightContent" style="width: 1000px; height: 600px;"></div>
<p class="reportTitle" style="page-break-before:always">Exported Power Overview</p>
<div id="exportedPowerData" class="tightContent" style="width: 1000px; height: 600px;"></div>

<p class="reportTitle" style="page-break-before:always">Resilience Overview</p>
<div id="resiliencePlotly" class="tightContent"></div>

<p class="reportTitle" style="page-break-before:always">Outage Survival Probability</p>
<div id="resilienceProbPlotly" class="tightContent"></div>
<p class="reportTitle" style="page-break-before:always">Resilience Overview</p>
<div id="resiliencePlotly" class="tightContent"></div>
<p class="reportTitle" style="page-break-before:always">Outage Survival Probability</p>
<div id="resilienceProbPlotly" class="tightContent"></div>

<div id="output">
{{ rawOutputFiles }}
<p class="reportTitle">Monthly Cost Comparison</p>
<div id="levelizedCostReport" class="tightContent">
<div id="levelizedCostTableDiv" style="display:inline-block; width:1000px">
<table id="monthlySummaryTable" style="margin:5px;width:990px">
<style>td, th {padding:7 0 5 20;text-align: left;font-size:0.7em;}</style>
<div id="tableHead">
<thead>
<th></th>
<th>Jan</th>
<th>Feb</th>
<th>Mar</th>
<th>Apr</th>
<th>May</th>
<th>Jun</th>
<th>Jul</th>
<th>Aug</th>
<th>Sep</th>
<th>Oct</th>
<th>Nov</th>
<th>Dec</th>
</thead>
</div>
</table>
<script id="globalOutputScripting">
function insertMetric(tableId, name, vector) {
// Add a vector to a table as a row.
table = gebi(tableId)
newRow = table.insertRow()
newRow.insertCell().innerHTML = "<div id=\"metric\">" + name + "</div>"
for (i=0; i<vector.length; i++) {
cell = newRow.insertCell()
cell.innerHTML = delimitNumbers(vector[i].toFixed(0))
}
}
</script>
<script>
insertMetric("monthlySummaryTable","Peak Demand (kW)", allOutputData.peakDemand)
insertMetric("monthlySummaryTable","Adjusted Peak Demand (kW)", allOutputData.peakAdjustedDemand)
insertMetric("monthlySummaryTable","Energy (kWh)", allOutputData.energyMonthly)
insertMetric("monthlySummaryTable","Adjusted Energy (kWh)", allOutputData.energyAdjustedMonthly)
insertMetric("monthlySummaryTable","Energy Cost ($)", allOutputData.energyCost)
insertMetric("monthlySummaryTable","Energy Cost using VBAT ($)", allOutputData.energyCostAdjusted)
insertMetric("monthlySummaryTable","Demand Charge ($)", allOutputData.demandCharge)
insertMetric("monthlySummaryTable","Demand Charge using VBAT ($)", allOutputData.demandChargeAdjusted)
insertMetric("monthlySummaryTable","Total Cost ($)", allOutputData.totalCost)
insertMetric("monthlySummaryTable","Total Cost using VBAT ($)", allOutputData.totalCostAdjusted)
insertMetric("monthlySummaryTable","Savings ($)", allOutputData.savings)
</script>
</div>
</div>

<p class="reportTitle" style="page-break-before:always">Cash Flow Projection</p>
<div id="cashFlowReport" class="tightContent">
<div id="cashFlowChartDiv"></div>
<script>
new Highcharts.Chart({"credits":{"enabled":false},
"plotOptions":{"column":{"stacking":'normal'},"series":{"animation":false,"shadow":false},"spline":{"animation":false,"shadow":false}},
"xAxis":{"title":{"text":"Year After Installation","style":{"color":"gray"}},"type":"linear","tickColor":"gray","tickInterval":1,"lineColor":"gray","minorTickColor":"gray", "minorTickInterval":5},
"title":{"text":"NPV:$" + allOutputData.NPV.toFixed(0) + " ; SPP:" + allOutputData.SPP.toFixed(3), "verticalAlign":"bottom", "align":"right", "y":-50, "x":-10, "style":{"color":"#333333", "fontSize":"12px"}},
//"title":{"text":""},
"series":[{"name":"Net Benefits", "data":allOutputData.netCashflow},
{"name":"Cumulative Return", "type":"spline", "data":allOutputData.cumulativeCashflow}
],
"yAxis":{"title":{"text":"Income ($)","style":{"color":"gray"}}},
"chart":{"marginBottom":55,"zoomType":"x","renderTo":"cashFlowChartDiv","type":"column","marginRight":20, "height":250,"width":1000},
"tooltip":{"valueDecimals":1},
"legend":{"verticalAlign":"top","align":"top","borderWidth":0,"x":50,"y":-10,"layout":"horizontal"}})
</script>
</div>
</div>

<!-- Raw Input and Output Files -->
{{ rawOutputFiles }}
{% endif %}
</body>
Loading

0 comments on commit 2a7abdc

Please sign in to comment.