-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(simulate): Add a component to create an OSM from a Measure
- Loading branch information
1 parent
19e7dd7
commit 4963f7a
Showing
4 changed files
with
203 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 64 additions & 0 deletions
64
honeybee_grasshopper_energy/json/HB_Create_OSM_Measure.json
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,64 @@ | ||
{ | ||
"version": "1.7.0", | ||
"nickname": "OSMMeasure", | ||
"outputs": [ | ||
[ | ||
{ | ||
"access": "None", | ||
"name": "osw", | ||
"description": "File path to the OpenStudio Workflow JSON on this machine. This workflow\nis executed using the OpenStudio command line interface (CLI) and\nit includes measures to create the OSM from the measure", | ||
"type": null, | ||
"default": null | ||
}, | ||
{ | ||
"access": "None", | ||
"name": "osm", | ||
"description": "The file path to the OpenStudio Model (OSM) that has been generated\non this computer.", | ||
"type": null, | ||
"default": null | ||
}, | ||
{ | ||
"access": "None", | ||
"name": "idf", | ||
"description": "The file path of the EnergyPlus Input Data File (IDF) that has been\ngenerated on this computer.", | ||
"type": null, | ||
"default": null | ||
} | ||
] | ||
], | ||
"inputs": [ | ||
{ | ||
"access": "item", | ||
"name": "_measure", | ||
"description": "A Measure from the \"HB Load Measure\" component that is intended to\ngenerate an OSM from input arguments. Measures can be downloaded\nfrom the NREL Building Components Library (BCL) at (https://bcl.nrel.gov/).", | ||
"type": "System.Object", | ||
"default": null | ||
}, | ||
{ | ||
"access": "list", | ||
"name": "add_str_", | ||
"description": "Optional additional text strings here to be written into the IDF.\nThe input here should be complete EnergyPlus objects as a single\nstring following the IDF format. This can be used to add addition\nEnergyPlus outputs in the resulting IDF among other features.", | ||
"type": "System.Object", | ||
"default": null | ||
}, | ||
{ | ||
"access": "item", | ||
"name": "_folder_", | ||
"description": "An optional folder on this computer, into which the IDF and OSM\nfiles will be written. If none, a sub-folder within the default\nsimulation folder will be used.", | ||
"type": "string", | ||
"default": null | ||
}, | ||
{ | ||
"access": "item", | ||
"name": "_run", | ||
"description": "Script variable Python", | ||
"type": "bool", | ||
"default": null | ||
} | ||
], | ||
"subcategory": "5 :: Simulate", | ||
"code": "\nimport sys\nimport re\nimport os\nimport json\n\ntry:\n from ladybug.futil import preparedir, nukedir\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug:\\n\\t{}'.format(e))\n\ntry:\n from honeybee.config import folders\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee:\\n\\t{}'.format(e))\n\ntry:\n from honeybee_energy.measure import Measure\n from honeybee_energy.run import run_osw\n from honeybee_energy.config import folders as energy_folders\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee_energy:\\n\\t{}'.format(e))\n\ntry:\n from lbt_recipes.version import check_openstudio_version\nexcept ImportError as e:\n raise ImportError('\\nFailed to import lbt_recipes:\\n\\t{}'.format(e))\n\ntry:\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n\nif all_required_inputs(ghenv.Component) and _run:\n # check the presence of openstudio and check that the version is compatible\n check_openstudio_version()\n\n # process the simulation folder name and the directory\n _folder_ = folders.default_simulation_folder if _folder_ is None else _folder_\n clean_name = re.sub(r'[^.A-Za-z0-9_-]', '_', _measure.display_name)\n directory = os.path.join(_folder_, clean_name, 'openstudio')\n\n # delete any existing files in the directory and prepare it for simulation\n nukedir(directory, True)\n preparedir(directory)\n\n # create a dictionary representation of the .osw with steps to run\n # the model measure and the simulation parameter measure\n osw_dict = {'steps': []}\n # assign the measure_paths to the osw_dict\n if 'measure_paths' not in osw_dict:\n osw_dict['measure_paths'] = []\n if energy_folders.honeybee_openstudio_gem_path: # include honeybee-openstudio measure path\n measure_dir = os.path.join(energy_folders.honeybee_openstudio_gem_path, 'measures')\n osw_dict['measure_paths'].append(measure_dir)\n\n # add the measure to the OSW\n measure_paths = set() # set of all unique measure paths\n _measure.validate() # ensure that all required arguments have values\n measure_paths.add(os.path.dirname(_measure.folder))\n osw_dict['steps'].append(_measure.to_osw_dict()) # add measure to workflow\n\n # load the inject IDF measure if strings_to_inject have bee specified\n str_inject = None if add_str_ == [] or add_str_[0] is None \\\n else '\\n'.join(add_str_)\n if str_inject is not None and str_inject != '':\n assert energy_folders.inject_idf_measure_path is not None, \\\n 'Additional IDF strings input but the inject_idf measure is not installed.'\n idf_measure = Measure(energy_folders.inject_idf_measure_path)\n inject_idf = os.path.join(directory, 'inject.idf')\n with open(inject_idf, \"w\") as idf_file:\n idf_file.write(str_inject)\n units_arg = idf_measure.arguments[0]\n units_arg.value = inject_idf\n measure_paths.add(os.path.dirname(idf_measure.folder))\n osw_dict['steps'].append(idf_measure.to_osw_dict()) # add measure to workflow\n\n # write the dictionary to a workflow.osw\n for m_path in measure_paths:\n osw_dict['measure_paths'].append(m_path)\n osw_json = os.path.join(directory, 'workflow.osw')\n if (sys.version_info < (3, 0)): # we need to manually encode it as UTF-8\n with open(osw_json, 'w') as fp:\n workflow_str = json.dumps(osw_dict, indent=4, ensure_ascii=False)\n fp.write(workflow_str.encode('utf-8'))\n else:\n with open(osw_json, 'wb', encoding='utf-8') as fp:\n workflow_str = json.dump(osw_dict, fp, indent=4, ensure_ascii=False)\n osw = os.path.abspath(osw_json)\n osm, idf = run_osw(osw, silent=False)\n", | ||
"category": "HB-Energy", | ||
"name": "HB Create OSM Measure", | ||
"description": "Run an OpenStudio Meausre that is intended to create an entire OSM file\n(OpenStudio Model). Examples of such measures include the \"Create DOE\nPrototype Building\" measure such as that wich can be downloaded here:\n_\nhttps://github.com/NREL/openstudio-model-articulation-gem/tree/develop/lib/\nmeasures/create_DOE_prototype_building\n-" | ||
} |
139 changes: 139 additions & 0 deletions
139
honeybee_grasshopper_energy/src/HB Create OSM 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,139 @@ | ||
# Honeybee: A Plugin for Environmental Analysis (GPL) | ||
# This file is part of Honeybee. | ||
# | ||
# Copyright (c) 2023, Ladybug Tools. | ||
# You should have received a copy of the GNU Affero General Public License | ||
# along with Honeybee; If not, see <http://www.gnu.org/licenses/>. | ||
# | ||
# @license AGPL-3.0-or-later <https://spdx.org/licenses/AGPL-3.0-or-later> | ||
|
||
""" | ||
Run an OpenStudio Meausre that is intended to create an entire OSM file | ||
(OpenStudio Model). Examples of such measures include the "Create DOE | ||
Prototype Building" measure such as that wich can be downloaded here: | ||
_ | ||
https://github.com/NREL/openstudio-model-articulation-gem/tree/develop/lib/ | ||
measures/create_DOE_prototype_building | ||
- | ||
Args: | ||
_measure: A Measure from the "HB Load Measure" component that is intended to | ||
generate an OSM from input arguments. Measures can be downloaded | ||
from the NREL Building Components Library (BCL) at (https://bcl.nrel.gov/). | ||
add_str_: Optional additional text strings here to be written into the IDF. | ||
The input here should be complete EnergyPlus objects as a single | ||
string following the IDF format. This can be used to add addition | ||
EnergyPlus outputs in the resulting IDF among other features. | ||
_folder_: An optional folder on this computer, into which the IDF and OSM | ||
files will be written. If none, a sub-folder within the default | ||
simulation folder will be used. | ||
run_: Set to "True" to run the measure and generate the OSM. | ||
Returns: | ||
report: Reports, errors, warnings. | ||
osw: File path to the OpenStudio Workflow JSON on this machine. This workflow | ||
is executed using the OpenStudio command line interface (CLI) and | ||
it includes measures to create the OSM from the measure | ||
osm: The file path to the OpenStudio Model (OSM) that has been generated | ||
on this computer. | ||
idf: The file path of the EnergyPlus Input Data File (IDF) that has been | ||
generated on this computer. | ||
""" | ||
|
||
ghenv.Component.Name = 'HB Create OSM Measure' | ||
ghenv.Component.NickName = 'OSMMeasure' | ||
ghenv.Component.Message = '1.7.0' | ||
ghenv.Component.Category = 'HB-Energy' | ||
ghenv.Component.SubCategory = '5 :: Simulate' | ||
ghenv.Component.AdditionalHelpFromDocStrings = '0' | ||
|
||
import sys | ||
import re | ||
import os | ||
import json | ||
|
||
try: | ||
from ladybug.futil import preparedir, nukedir | ||
except ImportError as e: | ||
raise ImportError('\nFailed to import ladybug:\n\t{}'.format(e)) | ||
|
||
try: | ||
from honeybee.config import folders | ||
except ImportError as e: | ||
raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e)) | ||
|
||
try: | ||
from honeybee_energy.measure import Measure | ||
from honeybee_energy.run import run_osw | ||
from honeybee_energy.config import folders as energy_folders | ||
except ImportError as e: | ||
raise ImportError('\nFailed to import honeybee_energy:\n\t{}'.format(e)) | ||
|
||
try: | ||
from lbt_recipes.version import check_openstudio_version | ||
except ImportError as e: | ||
raise ImportError('\nFailed to import lbt_recipes:\n\t{}'.format(e)) | ||
|
||
try: | ||
from ladybug_rhino.grasshopper import all_required_inputs | ||
except ImportError as e: | ||
raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e)) | ||
|
||
|
||
if all_required_inputs(ghenv.Component) and _run: | ||
# check the presence of openstudio and check that the version is compatible | ||
check_openstudio_version() | ||
|
||
# process the simulation folder name and the directory | ||
_folder_ = folders.default_simulation_folder if _folder_ is None else _folder_ | ||
clean_name = re.sub(r'[^.A-Za-z0-9_-]', '_', _measure.display_name) | ||
directory = os.path.join(_folder_, clean_name, 'openstudio') | ||
|
||
# delete any existing files in the directory and prepare it for simulation | ||
nukedir(directory, True) | ||
preparedir(directory) | ||
|
||
# create a dictionary representation of the .osw with steps to run | ||
# the model measure and the simulation parameter measure | ||
osw_dict = {'steps': []} | ||
# assign the measure_paths to the osw_dict | ||
if 'measure_paths' not in osw_dict: | ||
osw_dict['measure_paths'] = [] | ||
if energy_folders.honeybee_openstudio_gem_path: # include honeybee-openstudio measure path | ||
measure_dir = os.path.join(energy_folders.honeybee_openstudio_gem_path, 'measures') | ||
osw_dict['measure_paths'].append(measure_dir) | ||
|
||
# add the measure to the OSW | ||
measure_paths = set() # set of all unique measure paths | ||
_measure.validate() # ensure that all required arguments have values | ||
measure_paths.add(os.path.dirname(_measure.folder)) | ||
osw_dict['steps'].append(_measure.to_osw_dict()) # add measure to workflow | ||
|
||
# load the inject IDF measure if strings_to_inject have bee specified | ||
str_inject = None if add_str_ == [] or add_str_[0] is None \ | ||
else '\n'.join(add_str_) | ||
if str_inject is not None and str_inject != '': | ||
assert energy_folders.inject_idf_measure_path is not None, \ | ||
'Additional IDF strings input but the inject_idf measure is not installed.' | ||
idf_measure = Measure(energy_folders.inject_idf_measure_path) | ||
inject_idf = os.path.join(directory, 'inject.idf') | ||
with open(inject_idf, "w") as idf_file: | ||
idf_file.write(str_inject) | ||
units_arg = idf_measure.arguments[0] | ||
units_arg.value = inject_idf | ||
measure_paths.add(os.path.dirname(idf_measure.folder)) | ||
osw_dict['steps'].append(idf_measure.to_osw_dict()) # add measure to workflow | ||
|
||
# write the dictionary to a workflow.osw | ||
for m_path in measure_paths: | ||
osw_dict['measure_paths'].append(m_path) | ||
osw_json = os.path.join(directory, 'workflow.osw') | ||
if (sys.version_info < (3, 0)): # we need to manually encode it as UTF-8 | ||
with open(osw_json, 'w') as fp: | ||
workflow_str = json.dumps(osw_dict, indent=4, ensure_ascii=False) | ||
fp.write(workflow_str.encode('utf-8')) | ||
else: | ||
with open(osw_json, 'wb', encoding='utf-8') as fp: | ||
workflow_str = json.dump(osw_dict, fp, indent=4, ensure_ascii=False) | ||
osw = os.path.abspath(osw_json) | ||
osm, idf = run_osw(osw, silent=False) |
Binary file added
BIN
+6.96 KB
honeybee_grasshopper_energy/user_objects/HB Create OSM Measure.ghuser
Binary file not shown.