Skip to content

Commit

Permalink
Merge branch 'master' into gh-pages-custom
Browse files Browse the repository at this point in the history
  • Loading branch information
dhblum committed Apr 3, 2024
2 parents 701f628 + 7866550 commit 74a0e24
Show file tree
Hide file tree
Showing 27 changed files with 617 additions and 246 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Building Optimization Performance Tests
Visit the [BOPTEST Home Page](https://ibpsa.github.io/project1-boptest/) for more information about the project, software, and documentation.

This repository contains code for the Building Optimization Performance Test framework (BOPTEST)
that is being developed as part of the [IBPSA Project 1](https://ibpsa.github.io/project1/).
that is being developed as part of the [IBPSA Project 2](https://ibpsa.github.io/project1-boptest/ibpsa/index.html) and was previously developed as part of the [IBPSA Project 1](https://ibpsa.github.io/project1/).


## Structure
Expand Down Expand Up @@ -68,7 +68,7 @@ Example RESTful interaction:

| Interaction | Request |
|-----------------------------------------------------------------------|-----------------------------------------------------------|
| Advance simulation with control input and receive measurements. | POST ``advance`` with optional json data "{<input_name>:<value>}" |
| Advance simulation with control input and receive measurements. | POST ``advance`` with optional arguments ``<input_name_u>:<value>``, and corresponding ``<input_name_activate>:<0 or 1>``, where 1 enables value overwrite and 0 disables (0 is default) |
| Initialize simulation to a start time using a warmup period in seconds. Also resets point data history and KPI calculations. | PUT ``initialize`` with required arguments ``start_time=<value>``, ``warmup_period=<value>``|
| Receive communication step in seconds. | GET ``step`` |
| Set communication step in seconds. | PUT ``step`` with required argument ``step=<value>`` |
Expand Down
29 changes: 22 additions & 7 deletions data/get_html_IO.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
2. Run BOPTEST test case on localhost:5000
3. Run this script
Outputs:
"inputs.txt": html code documenting the inputs
"measurements.txt": html code documenting the outputs
Output:
"inputs_measurements_forecasts.html" html code documenting inputs, outputs and
forecasts together
"""

# GENERAL PACKAGE IMPORT
Expand Down Expand Up @@ -40,24 +39,40 @@ def run():

# GET TEST INFORMATION
# --------------------
# Create single I/O file
# Inputs available
inputs = requests.get('{0}/inputs'.format(url)).json()['payload']
with open('inputs.txt', 'w') as f:
with open('inputs_measurements_forecasts.html', 'w') as f:
f.write('<h3>Model IO\'s</h3>\n')
f.write('<h4>Inputs</h4>\n')
f.write('The model inputs are:\n')
f.write('<ul>\n')
for i in sorted(inputs.keys()):
if 'activate' not in i:
f.write('<li>\n<code>{0}</code> [{1}] [min={2}, max={3}]: {4}\n</li>\n'.format(i,inputs[i]['Unit'],inputs[i]['Minimum'], inputs[i]['Maximum'], inputs[i]['Description']))
else:
f.write('<li>\n<code>{0}</code> [1] [min=0, max=1]: Activation signal to overwrite input {1} where 1 activates, 0 deactivates (default value)\n</li>\n'.format(i,i.replace('activate','')+'u'))
f.write('</ul>\n')
# Measurements available
measurements = requests.get('{0}/measurements'.format(url)).json()['payload']
with open('measurements.txt', 'w') as f:
with open('inputs_measurements_forecasts.html', 'a') as f:
f.write('<h4>Outputs</h4>\n')
f.write('The model outputs are:\n')
f.write('<ul>\n')
for i in sorted(measurements.keys()):
if 'activate' not in i:
f.write('<li>\n<code>{0}</code> [{1}] [min={2}, max={3}]: {4}\n</li>\n'.format(i,measurements[i]['Unit'],measurements[i]['Minimum'], measurements[i]['Maximum'], measurements[i]['Description']))
f.write('</ul>\n')
# Forecasts available
forecast_points = requests.get('{0}/forecast_points'.format(url)).json()['payload']
with open('forecast_points.txt', 'w') as f:
with open('inputs_measurements_forecasts.html', 'a') as f:
f.write('<h4>Forecasts</h4>\n')
f.write('The model forecasts are:\n')
f.write('<ul>\n')
for i in sorted(forecast_points.keys()):
if 'activate' not in i:
f.write('<li>\n<code>{0}</code> [{1}]: {2}\n</li>\n'.format(i,forecast_points[i]['Unit'],forecast_points[i]['Description']))
f.write('</ul>\n')
# --------------------

if __name__ == "__main__":
Expand Down
6 changes: 4 additions & 2 deletions releasenotes.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Release Notes

## BOPTEST v0.5.0-dev
## BOPTEST v0.6.0

Released on xx/xx/xxxx.
Released on 04/03/2024.

**The following changes are backwards-compatible and do not significantly change benchmark results:**

Expand All @@ -16,6 +16,8 @@ Released on xx/xx/xxxx.
- Correct typo in documentation for ``multizone_office_simple_air``, cooling setback temperature changed from 12 to 30. This is for [#605](https://github.com/ibpsa/project1-boptest/issues/605).
- Modify unit tests for test case scenarios to only simulate two days after warmup instead of the whole two-week scenario. This is for [#576](https://github.com/ibpsa/project1-boptest/issues/576).
- Fix unit tests for possible false passes in certain test cases. This is for [#620](https://github.com/ibpsa/project1-boptest/issues/620).
- Add ``activate`` control inputs to all test case documentation and update ``get_html_IO.py`` to print one file with all inputs, outputs, and forecasts. This is for [#555](https://github.com/ibpsa/project1-boptest/issues/555).
- Add storing of scenario result trajectories, kpis, and test information to simulation directory within test case docker container. This is for [#626](https://github.com/ibpsa/project1-boptest/issues/626).


## BOPTEST v0.5.0
Expand Down
83 changes: 64 additions & 19 deletions testcase.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import os
import json
import array as a
import pandas as pd

class TestCase(object):
'''Class that implements the test case.
Expand Down Expand Up @@ -359,6 +360,8 @@ def advance(self, u):
# Check if scenario is over
if self.start_time >= self.end_time:
self.scenario_end = True
# store results
self.store_results()
# Log and return
logging.info(message)
return status, message, payload
Expand Down Expand Up @@ -1142,27 +1145,17 @@ def post_results_to_dashboard(self, api_key, tags, unit_test=False):
dash_server = os.environ['BOPTEST_DASHBOARD_SERVER']
# Create payload
uid = str(uuid.uuid4())
payload = {
"results": [
{
"uid": uid,
"dateRun": str(datetime.now(tz=pytz.UTC)),
"boptestVersion": self.version,
"isShared": True,
"controlStep": str(self.get_step()[2]),
"account": {
test_results = self._get_test_results()
api_parameters = {
"uid": uid,
"isShared": True,
"account": {
"apiKey": api_key
},
"forecastParameters":{},
"tags": tags,
"kpis": self.get_kpis()[2],
"scenario": self.add_forecast_uncertainty(self.keys_to_camel_case(self.get_scenario()[2])),
"buildingType": {
"uid": self.get_name()[2]['name']
}
}
]
},
"tags": tags,
}
test_results.update(api_parameters)
payload = {"results":[test_results]}
dash_url = "%s/api/results" % dash_server
# Post to dashboard
if not unit_test:
Expand Down Expand Up @@ -1327,6 +1320,58 @@ def _get_full_current_state(self):

return z

def _get_test_results(self):
'''Collect test results and information into a dictionary.
Returns
-------
results: dict
Dictionary of test specific results and information.
'''

results = {
"dateRun": str(datetime.now(tz=pytz.UTC)),
"boptestVersion": self.version,
"controlStep": str(self.get_step()[2]),
"forecastParameters":{},
"kpis": self.get_kpis()[2],
"scenario": self.add_forecast_uncertainty(self.keys_to_camel_case(self.get_scenario()[2])),
"buildingType": {
"uid": self.get_name()[2]['name'],
}
}

return results

def store_results(self):
'''Stores results from scenario in working directory as json and csv.
When run with Service, the result will be packed in the result tarball and
be retrieveable with the test_id.
Returns
-------
None
'''

file_name = "results"
# get results_json
results_json = self._get_test_results()
# store results_json
with open(file_name + ".json", "w") as outfile:
json.dump(results_json, outfile)
# get list of results, need to use output metadata so duplicate inputs are removed
result_list = self.input_names + list(self.outputs_metadata.keys())
# get results trajectories
results = self.get_results(result_list, self.initial_time, self.end_time)[2]
# convert to dataframe with time as index
results_df = pd.DataFrame.from_dict(results)
results_df.index = results_df['time']
# store results csv
results_df.to_csv(file_name + ".csv")

def to_camel_case(self, snake_str):
components = snake_str.split('_')
# We capitalize the first letter of each component except the first one
Expand Down
23 changes: 20 additions & 3 deletions testcases/bestest_air/doc/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -263,16 +263,28 @@ <h4>Inputs</h4>
The model inputs are:
<ul>
<li>
<code>fcu_oveTSup_u</code> [K] [min=285.15, max=313.15]: Supply air temperature setpoint
<code>con_oveTSetCoo_activate</code> [1] [min=0, max=1]: Activation signal to overwrite input con_oveTSetCoo_u where 1 activates, 0 deactivates (default value)
</li>
<li>
<code>fcu_oveFan_u</code> [1] [min=0.0, max=1.0]: Fan control signal as air mass flow rate normalized to the design air mass flow rate
<code>con_oveTSetCoo_u</code> [K] [min=296.15, max=303.15]: Zone temperature setpoint for cooling
</li>
<li>
<code>con_oveTSetHea_activate</code> [1] [min=0, max=1]: Activation signal to overwrite input con_oveTSetHea_u where 1 activates, 0 deactivates (default value)
</li>
<li>
<code>con_oveTSetHea_u</code> [K] [min=288.15, max=296.15]: Zone temperature setpoint for heating
</li>
<li>
<code>con_oveTSetCoo_u</code> [K] [min=296.15, max=303.15]: Zone temperature setpoint for cooling
<code>fcu_oveFan_activate</code> [1] [min=0, max=1]: Activation signal to overwrite input fcu_oveFan_u where 1 activates, 0 deactivates (default value)
</li>
<li>
<code>fcu_oveFan_u</code> [1] [min=0.0, max=1.0]: Fan control signal as air mass flow rate normalized to the design air mass flow rate
</li>
<li>
<code>fcu_oveTSup_activate</code> [1] [min=0, max=1]: Activation signal to overwrite input fcu_oveTSup_u where 1 activates, 0 deactivates (default value)
</li>
<li>
<code>fcu_oveTSup_u</code> [K] [min=285.15, max=313.15]: Supply air temperature setpoint
</li>
</ul>
<h4>Outputs</h4>
Expand Down Expand Up @@ -367,9 +379,14 @@ <h4>Outputs</h4>
</li>
<li>
<code>zon_weaSta_reaWeaWinDir_y</code> [rad] [min=None, max=None]: Wind direction measurement
</li>
<li>
<code>zon_weaSta_reaWeaWinSpe_y</code> [m/s] [min=None, max=None]: Wind speed measurement
</li>
</ul>
<h4>Forecasts</h4>
The model forecasts are:
<ul>
<li>
<code>EmissionsElectricPower</code> [kgCO2/kWh]: Kilograms of carbon dioxide to produce 1 kWh of electricity
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,16 +291,28 @@ temperature setpoint.
The model inputs are:
<ul>
<li>
<code>fcu_oveTSup_u</code> [K] [min=285.15, max=313.15]: Supply air temperature setpoint
<code>con_oveTSetCoo_activate</code> [1] [min=0, max=1]: Activation signal to overwrite input con_oveTSetCoo_u where 1 activates, 0 deactivates (default value)
</li>
<li>
<code>fcu_oveFan_u</code> [1] [min=0.0, max=1.0]: Fan control signal as air mass flow rate normalized to the design air mass flow rate
<code>con_oveTSetCoo_u</code> [K] [min=296.15, max=303.15]: Zone temperature setpoint for cooling
</li>
<li>
<code>con_oveTSetHea_activate</code> [1] [min=0, max=1]: Activation signal to overwrite input con_oveTSetHea_u where 1 activates, 0 deactivates (default value)
</li>
<li>
<code>con_oveTSetHea_u</code> [K] [min=288.15, max=296.15]: Zone temperature setpoint for heating
</li>
<li>
<code>con_oveTSetCoo_u</code> [K] [min=296.15, max=303.15]: Zone temperature setpoint for cooling
<code>fcu_oveFan_activate</code> [1] [min=0, max=1]: Activation signal to overwrite input fcu_oveFan_u where 1 activates, 0 deactivates (default value)
</li>
<li>
<code>fcu_oveFan_u</code> [1] [min=0.0, max=1.0]: Fan control signal as air mass flow rate normalized to the design air mass flow rate
</li>
<li>
<code>fcu_oveTSup_activate</code> [1] [min=0, max=1]: Activation signal to overwrite input fcu_oveTSup_u where 1 activates, 0 deactivates (default value)
</li>
<li>
<code>fcu_oveTSup_u</code> [K] [min=285.15, max=313.15]: Supply air temperature setpoint
</li>
</ul>
<h4>Outputs</h4>
Expand Down Expand Up @@ -395,6 +407,10 @@ The model outputs are:
</li>
<li>
<code>zon_weaSta_reaWeaWinDir_y</code> [rad] [min=None, max=None]: Wind direction measurement
</li>
<li>
<code>zon_weaSta_reaWeaWinSpe_y</code> [m/s] [min=None, max=None]: Wind speed measurement
</li>
</ul>
<h4>Forecasts</h4>
The model forecasts are:
Expand Down
Loading

0 comments on commit 74a0e24

Please sign in to comment.