-
Notifications
You must be signed in to change notification settings - Fork 193
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Utility for Generating Alfalfa Metadata to OpenStudio #5236
Merged
Merged
Changes from all commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
9843b0f
Basic structure for Alfalfa OpenStudio integration
TShapinsky 3cd4267
do formatting
TShapinsky 41dbcc9
Add ability to create alfalfa points directly from openstudio objects'
TShapinsky e077c72
consolidate functions and allow for idf and modelobjects to be passed…
TShapinsky eba24de
move to impl pattern for desired functionality and introduce testing …
TShapinsky 8d231c3
fix formatting
TShapinsky e55e00e
consolidate logic and expand testing
TShapinsky 186d31c
formatting
TShapinsky 1cef96b
documentation and testing
TShapinsky 4b5b5a9
formatting
TShapinsky a41f6d8
export correctly to dll
TShapinsky 3dbc86b
add json saving to postprocess workflow step
TShapinsky 134e8a5
fix test building for ubuntu and be more thoughtful about assert vs e…
TShapinsky 7925401
Add example measures for workflow test
TShapinsky 299fa00
include file writing into alfalfaJSON test suite
TShapinsky 30c49e7
fix target name
TShapinsky 5e12354
add check for contents of generated json
TShapinsky f6b9368
change to exposeFromObject and exposeFromComponent. Remove redundant …
TShapinsky d3aed8c
add tests for cases where objects do not have all requsite properties
TShapinsky 10147d1
improve testing and error messages
TShapinsky 280f99c
fix ctest paths
TShapinsky 31820bb
fix ruby bindings
TShapinsky 41abf4a
Raw string litteral and absolute minimal testing for PythonEngine alf…
jmarrec 9ed8e01
Fixup AlfalfaJSON code
jmarrec 578381e
Lint AlfalfaPoint
jmarrec 29f5b9a
Lint up the rest
jmarrec a3f527d
move alfalfa to top level and reimagine Component implementation
TShapinsky 28a9c80
getPoints() to points()
TShapinsky c5c0cb1
formatting
TShapinsky f2c2956
reset utilities cmakelists now that we are not using it
TShapinsky 1677007
commit alfalfajson_gtest
TShapinsky ff2ff6f
move checks for object type into components
TShapinsky 66b50e3
formatting
TShapinsky 3014739
fix dll export
TShapinsky be526c3
undo overzealous clang-format
TShapinsky a221335
undo overzealous clang-format
TShapinsky 3cd641b
undo overzealous clang-format
TShapinsky 662ddbb
use simplified API header
TShapinsky 1de9181
omit clone() from swig
TShapinsky 5fe1207
cleanup imports and clang-tidy
TShapinsky d1f6cff
try using runtime wrapping for make fmt happy on ubuntu 22.04
TShapinsky 5015251
fix alfalfa ctests
TShapinsky f54b39d
fix linking of alfalfa ruby bindings
TShapinsky File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# | ||
# RunCommands.cmake | ||
# | ||
# Run a set of commands in series. | ||
# This is useful for creating tests which consist of more than one command. | ||
# | ||
# Commands are passed as -DCMD<n> as n is between 1 and 9 | ||
# | ||
# Example Usage: | ||
# add_test(test_name COMMAND ${CMAKE_COMMAND} | ||
# "-DCMD1=echo hello" | ||
# "-DCMD2=echo goodbye" | ||
# -P ${CMAKE_SOURCE_DIR}/CMake/RunCommands) | ||
# | ||
# An error will be throw if any command returns a non-zero exit code or if a command cannot be found. | ||
# When an error is thrown no further commands will be executed. | ||
# | ||
# STDOUT and STDERR are untouched and reach output as normal. | ||
# Before running each command is echoed to STDOUT. | ||
|
||
foreach(CMD_IDX RANGE 1 10) | ||
if(DEFINED CMD${CMD_IDX}) | ||
separate_arguments(ARGS NATIVE_COMMAND PROGRAM SEPARATE_ARGS "${CMD${CMD_IDX}}") | ||
if(ARGS) | ||
list(POP_FRONT ARGS CMD) | ||
execute_process(COMMAND ${CMD} ${ARGS} COMMAND_ECHO STDOUT COMMAND_ERROR_IS_FATAL ANY) | ||
else() | ||
message(FATAL_ERROR "Cannot find command to run: '${CMD${CMD_IDX}}'") | ||
endif() | ||
else() | ||
break() | ||
endif() | ||
endforeach() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1038,6 +1038,7 @@ set(project_directories | |
airflow | ||
isomodel | ||
osversion | ||
alfalfa | ||
measure | ||
sdd | ||
lib | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import typing | ||
|
||
import openstudio | ||
|
||
|
||
class AlfalfaMeasure(openstudio.measure.ModelMeasure): | ||
def name(self): | ||
return "Alfalfa Measure" | ||
|
||
def modeler_description(self): | ||
return "The method attempts to build an alfalfa json in the measure" | ||
|
||
|
||
def arguments(self, model: typing.Optional[openstudio.model.Model] = None): | ||
args = openstudio.measure.OSArgumentVector() | ||
|
||
return args | ||
|
||
def run( | ||
self, | ||
model: openstudio.model.Model, | ||
runner: openstudio.measure.OSRunner, | ||
user_arguments: openstudio.measure.OSArgumentMap, | ||
): | ||
""" | ||
define what happens when the measure is run | ||
""" | ||
super().run(model, runner, user_arguments) # Do **NOT** remove this line | ||
|
||
alfalfa = runner.alfalfa() | ||
alfalfa.exposeConstant(10, "safe value") | ||
alfalfa.exposeMeter("Facility:Electricity", "Facility Electricity") | ||
alfalfa.exposeActuator("somehting", "another thing", "key", "example actuator") | ||
alfalfa.exposeOutputVariable("Whole Building", "Facility Total Purchased Electricity Energy", "output variable") | ||
alfalfa.exposeGlobalVariable("global_1", "global variable") | ||
|
||
return True | ||
|
||
AlfalfaMeasure().registerWithApplication() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
<?xml version="1.0"?> | ||
<measure> | ||
<schema_version>3.1</schema_version> | ||
<name>alfalfa_measure</name> | ||
<uid>812d3ebf-c89b-4b93-b400-110ca060b2bb</uid> | ||
<version_id>25ad8ea8-b28b-4f45-93a6-76f056c28ca8</version_id> | ||
<version_modified>2023-11-10T10:47:04Z</version_modified> | ||
<xml_checksum>33A29C78</xml_checksum> | ||
<class_name>AlfalfaMeasure</class_name> | ||
<display_name>Alfalfa Measure</display_name> | ||
<description></description> | ||
<modeler_description>The method attempts to build an alfalfa json in the measure</modeler_description> | ||
<arguments /> | ||
<outputs /> | ||
<provenances /> | ||
<tags> | ||
<tag>Envelope.Opaque</tag> | ||
</tags> | ||
<attributes> | ||
<attribute> | ||
<name>Measure Function</name> | ||
<value>Measure</value> | ||
<datatype>string</datatype> | ||
</attribute> | ||
<attribute> | ||
<name>Requires EnergyPlus Results</name> | ||
<value>false</value> | ||
<datatype>boolean</datatype> | ||
</attribute> | ||
<attribute> | ||
<name>Measure Type</name> | ||
<value>ModelMeasure</value> | ||
<datatype>string</datatype> | ||
</attribute> | ||
<attribute> | ||
<name>Measure Language</name> | ||
<value>Python</value> | ||
<datatype>string</datatype> | ||
</attribute> | ||
<attribute> | ||
<name>Uses SketchUp API</name> | ||
<value>false</value> | ||
<datatype>boolean</datatype> | ||
</attribute> | ||
</attributes> | ||
<files> | ||
<file> | ||
<version> | ||
<software_program>OpenStudio</software_program> | ||
<identifier>3.4.1</identifier> | ||
<min_compatible>3.4.1</min_compatible> | ||
</version> | ||
<filename>measure.py</filename> | ||
<filetype>py</filetype> | ||
<usage_type>script</usage_type> | ||
<checksum>E787E0E0</checksum> | ||
</file> | ||
</files> | ||
</measure> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ | |
from . import openstudioosversion as osversion | ||
from . import openstudioradiance as radiance | ||
from . import openstudiosdd as sdd | ||
from . import openstudioualfalfa as alfalfa | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's that extra "u" in there? I think you meant |
||
from .openstudioutilities import * | ||
from .openstudioutilitiesbcl import * | ||
from .openstudioutilitiescore import * | ||
|
@@ -52,6 +53,7 @@ | |
import openstudioisomodel as isomodel | ||
import openstudiomeasure as measure | ||
import openstudiomodel as model | ||
import openstudioalfalfa as alfalfa | ||
|
||
# These are already included in the `model` namespace via Model.i | ||
# import openstudiomodelcore as modelcore | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"weather_file": "srrl_2013_amy.epw", | ||
"seed_file": "seb.osm", | ||
"steps": [ | ||
{ | ||
"measure_dir_name": "AlfalfaModelPython", | ||
"arguments": {} | ||
}, | ||
{ | ||
"measure_dir_name": "AlfalfaModelRuby", | ||
"arguments": {} | ||
}, | ||
{ | ||
"measure_dir_name": "AlfalfaEPlusPython", | ||
"arguments": {} | ||
}, | ||
{ | ||
"measure_dir_name": "AlfalfaEPlusRuby", | ||
"arguments": {} | ||
}, | ||
] | ||
} |
97 changes: 97 additions & 0 deletions
97
resources/Examples/compact_osw/measures/AlfalfaEPlusPython/measure.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
"""insert your copyright here. | ||
|
||
# see the URL below for information on how to write OpenStudio measures | ||
# http://nrel.github.io/OpenStudio-user-documentation/reference/measure_writing_guide/ | ||
""" | ||
|
||
import openstudio | ||
|
||
|
||
class AlfalfaEPlusPython(openstudio.measure.EnergyPlusMeasure): | ||
"""An EnergyPlusMeasure.""" | ||
|
||
def name(self): | ||
"""Returns the human readable name. | ||
|
||
Measure name should be the title case of the class name. | ||
The measure name is the first contact a user has with the measure; | ||
it is also shared throughout the measure workflow, visible in the OpenStudio Application, | ||
PAT, Server Management Consoles, and in output reports. | ||
As such, measure names should clearly describe the measure's function, | ||
while remaining general in nature | ||
""" | ||
return "AlfalfaEPlusPython" | ||
|
||
def description(self): | ||
"""Human readable description. | ||
|
||
The measure description is intended for a general audience and should not assume | ||
that the reader is familiar with the design and construction practices suggested by the measure. | ||
""" | ||
return "DESCRIPTION_TEXT" | ||
|
||
def modeler_description(self): | ||
"""Human readable description of modeling approach. | ||
|
||
The modeler description is intended for the energy modeler using the measure. | ||
It should explain the measure's intent, and include any requirements about | ||
how the baseline model must be set up, major assumptions made by the measure, | ||
and relevant citations or references to applicable modeling resources | ||
""" | ||
return "MODELER_DESCRIPTION_TEXT" | ||
|
||
def arguments(self, workspace: openstudio.Workspace): | ||
"""Prepares user arguments for the measure. | ||
|
||
Measure arguments define which -- if any -- input parameters the user may set before running the measure. | ||
""" | ||
args = openstudio.measure.OSArgumentVector() | ||
|
||
return args | ||
|
||
def run( | ||
self, | ||
workspace: openstudio.Workspace, | ||
runner: openstudio.measure.OSRunner, | ||
user_arguments: openstudio.measure.OSArgumentMap, | ||
): | ||
"""Defines what happens when the measure is run.""" | ||
super().run(workspace, runner, user_arguments) # Do **NOT** remove this line | ||
TShapinsky marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
if not (runner.validateUserArguments(self.arguments(workspace), user_arguments)): | ||
return False | ||
|
||
alfalfa = runner.alfalfa() | ||
|
||
# Test Meters | ||
alfalfa.exposeMeter("Electricity:Facility", "Electricity Meter String:EPlus:Python") | ||
|
||
meter_object = openstudio.IdfObject.load("Output:Meter, Electricity:Facility;").get() | ||
alfalfa.exposeFromObject(meter_object, "Electricity Meter IDF:Eplus:Python") | ||
TShapinsky marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Test Output Variables | ||
alfalfa.exposeOutputVariable("EMS", "my_var", "Output Variable String:EPlus:Python") | ||
|
||
ems_output_variable_object = openstudio.IdfObject.load("EnergyManagementSystem:OutputVariable,My Var,my_var,,ZoneTimestep,,;").get() | ||
alfalfa.exposeFromObject(ems_output_variable_object, "EMS Output Variable IDF:EPlus:Python") | ||
|
||
output_variable_object = openstudio.IdfObject.load("Output:Variable,EMS,my_var,timstep;").get() | ||
alfalfa.exposeFromObject(output_variable_object, "Output Variable IDF:EPlus:Python") | ||
|
||
# Test Global Variables | ||
alfalfa.exposeGlobalVariable("my_var", "Global Variable String:EPlus:Python") | ||
|
||
global_variable_object = openstudio.IdfObject.load("EnergyManagementSystem:GlobalVariable,my_var;").get() | ||
alfalfa.exposeFromObject(global_variable_object, "Global Variable IDF:EPlus:Python") | ||
|
||
# Test Actuators | ||
alfalfa.exposeActuator("component_name", "componen_type", "control_type", "Actuator String:EPlus:Python") | ||
|
||
actuator_object = openstudio.IdfObject.load("EnergyManagementSystem:Actuator,MyActuator,component_name,component_type,control_type;").get() | ||
alfalfa.exposeFromObject(actuator_object, "Actuator IDF:EPlus:Python") | ||
|
||
return True | ||
|
||
|
||
# register the measure to be used by the application | ||
AlfalfaEPlusPython().registerWithApplication() |
70 changes: 70 additions & 0 deletions
70
resources/Examples/compact_osw/measures/AlfalfaEPlusPython/measure.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
<?xml version="1.0"?> | ||
<measure> | ||
<schema_version>3.1</schema_version> | ||
<name>alfalfa_e_plus_python</name> | ||
<uid>d3160f18-a73e-4470-a574-03bdf39c9ef2</uid> | ||
<version_id>e8e471ba-b61a-47b7-ac7b-162f337d38c2</version_id> | ||
<version_modified>2024-09-09T17:02:46Z</version_modified> | ||
<xml_checksum>00000000</xml_checksum> | ||
<class_name>AlfalfaEPlusPython</class_name> | ||
<display_name>AlfalfaEPlusPython</display_name> | ||
<description>DESCRIPTION_TEXT</description> | ||
<modeler_description>MODELER_DESCRIPTION_TEXT</modeler_description> | ||
<arguments> | ||
<argument> | ||
<name>zone_name</name> | ||
<display_name>New zone name</display_name> | ||
<description>This name will be used as the name of the new zone.</description> | ||
<type>String</type> | ||
<required>true</required> | ||
<model_dependent>false</model_dependent> | ||
</argument> | ||
</arguments> | ||
<outputs /> | ||
<provenances /> | ||
<tags> | ||
<tag>Envelope.Fenestration</tag> | ||
</tags> | ||
<attributes> | ||
<attribute> | ||
<name>Measure Type</name> | ||
<value>EnergyPlusMeasure</value> | ||
<datatype>string</datatype> | ||
</attribute> | ||
<attribute> | ||
<name>Measure Language</name> | ||
<value>Python</value> | ||
<datatype>string</datatype> | ||
</attribute> | ||
</attributes> | ||
<files> | ||
<file> | ||
<filename>LICENSE.md</filename> | ||
<filetype>md</filetype> | ||
<usage_type>license</usage_type> | ||
<checksum>CD7F5672</checksum> | ||
</file> | ||
<file> | ||
<filename>.gitkeep</filename> | ||
<filetype>gitkeep</filetype> | ||
<usage_type>doc</usage_type> | ||
<checksum>00000000</checksum> | ||
</file> | ||
<file> | ||
<version> | ||
<software_program>OpenStudio</software_program> | ||
<identifier>3.8.0</identifier> | ||
</version> | ||
<filename>measure.py</filename> | ||
<filetype>py</filetype> | ||
<usage_type>script</usage_type> | ||
<checksum>88CBEF7D</checksum> | ||
</file> | ||
<file> | ||
<filename>test_alfalfa_e_plus_python.py</filename> | ||
<filetype>py</filetype> | ||
<usage_type>test</usage_type> | ||
<checksum>E636CDC6</checksum> | ||
</file> | ||
</files> | ||
</measure> |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a change? I seem to recall that these originally took ModelObject instances. I think when we @TShapinsky last spoke you were contemplating a change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A risk I can think of is that the final names might not be known at ModelMeasure time.