Skip to content

Commit

Permalink
fix(subprocess): Update components for Rhino 8 compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
chriswmackey authored and Chris Mackey committed Nov 8, 2023
1 parent edbd8af commit e4f7801
Show file tree
Hide file tree
Showing 12 changed files with 64 additions and 54 deletions.
Binary file modified honeybee_grasshopper_core/icon/HB Load gbXML OSM IDF.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified honeybee_grasshopper_core/icon/HB Update HBJSON.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified honeybee_grasshopper_core/icon/HB Visualize Recipe Execution.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 14 additions & 14 deletions honeybee_grasshopper_core/json/HB_Load_gbXML_OSM_IDF.json
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
{
"version": "1.7.0",
"nickname": "LoadEModel",
"name": "HB Load gbXML OSM IDF",
"subcategory": "3 :: Serialize",
"version": "1.7.1",
"description": "Load a gbXML, OSM, or IDF file as a Honeybee Model.\n_\nThe reverse translators within the OpenStudio SDK are used to import all geometry\nand boundary conditions (including adjacencies) to a Honeybee format.\n_\nNote that, while all geometry will be imported, it is possible that not all of the\nproperties assigned to this geometry will be imported, particularly if a certain\nproperty is not supported in the OpenStudio SDK. Honeybee will assign defaults\nfor missing properites and, the HBJSON format should be used whenever lossless\nfile transfer is needed.\n-",
"code": "\nimport os\nimport subprocess\nimport re\nimport json\n\ntry: # import the ladybug_geometry dependencies\n from ladybug_geometry.geometry3d.pointvector import Vector3D\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_geometry:\\n\\t{}'.format(e))\n\ntry: # import the core honeybee dependencies\n from honeybee.model import Model\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.config import folders as e_folders\n from honeybee_energy.result.osw import OSW\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: # import the core ladybug_{{cad}} dependencies\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs, give_warning\n from ladybug_{{cad}}.config import conversion_to_meters, units_system, \\\n tolerance, angle_tolerance\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n\ndef model_units_tolerance_check(model):\n \"\"\"Convert a model to the current {{Cad}} units and check the tolerance.\n\n Args:\n model: A honeybee Model, which will have its units checked.\n \"\"\"\n # check the model units\n if model.units != units_system():\n print('Imported model units \"{}\" do not match that of the current {{Cad}} '\n 'model units \"{}\"\\nThe model is being automatically converted '\n 'to the {{Cad}} doc units.'.format(model.units, units_system()))\n model.convert_to_units(units_system())\n\n # check that the model tolerance is not too far from the {{Cad}} tolerance\n if model.tolerance / tolerance >= 100:\n msg = 'Imported Model tolerance \"{}\" is significantly coarser than the ' \\\n 'current {{Cad}} model tolerance \"{}\".\\nIt is recommended that the ' \\\n '{{Cad}} document tolerance be changed to be coarser and this ' \\\n 'component is re-run.'.format(model.tolerance, tolerance)\n print msg\n give_warning(ghenv.Component, msg)\n\n\nif all_required_inputs(ghenv.Component) and _load:\n # check the presence of openstudio and check that the version is compatible\n check_openstudio_version()\n\n # sense the type of file we are loading\n lower_fname = os.path.basename(_model_file).lower()\n if lower_fname.endswith('.xml') or lower_fname.endswith('.gbxml'):\n cmd_name = 'model-from-gbxml'\n f_name = lower_fname.replace('.gbxml', '.hbjson').replace('.xml', '.hbjson')\n elif lower_fname.endswith('.osm'):\n cmd_name = 'model-from-osm'\n f_name = lower_fname.replace('.osm', '.hbjson')\n elif lower_fname.endswith('.idf'):\n cmd_name = 'model-from-idf'\n f_name = lower_fname.replace('.idf', '.hbjson')\n else:\n raise ValueError('Failed to recongize the input _model_file file type.\\n'\n 'Make sure that it has an appropriate file extension.')\n\n # Execute the honybee CLI to obtain the model JSON via CPython\n out_path = os.path.join(folders.default_simulation_folder, f_name)\n if os.path.isfile(out_path):\n os.remove(out_path)\n cmds = [folders.python_exe_path, '-m', 'honeybee_energy', 'translate',\n cmd_name, _model_file, '--output-file', out_path]\n shell = True if os.name == 'nt' else False\n custom_env = os.environ.copy()\n custom_env['PYTHONHOME'] = ''\n process = subprocess.Popen(\n cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE,\n shell=shell, env=custom_env)\n result = process.communicate()\n\n # check to see if the file was successfully output and, if not, report the error\n if not os.path.isfile(out_path):\n if lower_fname.endswith('.idf'):\n # check the version of the IDF since, most of the time, people don't check this\n try:\n ver_regex = r'[V|v][E|e][R|r][S|s][I|i][O|o][N|n],\\s*(\\d*\\.\\d*)[;|.]'\n ver_pattern = re.compile(ver_regex)\n with open(_model_file, 'r') as mf:\n ver_val = re.search(ver_pattern, mf.read())\n ver_tup = tuple(int(v) for v in ver_val.groups()[0].split('.'))\n if e_folders.energyplus_version[:2] != ver_tup:\n msg = 'The IDF is from EnergyPlus version {}.\\nThis must be changed ' \\\n 'to {} with the IDFVersionUpdater\\nin order to import ' \\\n 'it with this Ladybug Tools installation.'.format(\n '.'.join((str(v) for v in ver_tup)),\n '.'.join((str(v) for v in e_folders.energyplus_version[:2]))\n )\n print(msg)\n give_warning(ghenv.Component, msg)\n except Exception:\n pass # failed to parse the version; it may not be in the IDF\n # parse any of the errors that came with the output OSW\n osw_path = os.path.join(folders.default_simulation_folder, 'temp_translate', 'out.osw')\n if os.path.isfile(osw_path):\n log_osw = OSW(osw_path)\n print(log_osw.stdout[0])\n errors = []\n for error, tb in zip(log_osw.errors, log_osw.error_tracebacks):\n print(tb)\n errors.append(error)\n raise Exception('Failed to run OpenStudio CLI:\\n{}'.format('\\n'.join(errors)))\n \n # if it's all good, load the model and convert it to {{Cad}} model units\n with open(out_path) as json_file:\n model_dict = json.load(json_file)\n model = Model.from_dict(model_dict)\n model_units_tolerance_check(model)\n\n # given that most other software lets doors go to the edge, move them slightly for HB\n move_vec = Vector3D(0, 0, 0.02 / conversion_to_meters())\n for room in model.rooms:\n for face in room.faces:\n doors = face.doors\n for door in doors:\n if not face.geometry.is_sub_face(door.geometry, tolerance, angle_tolerance):\n door.move(move_vec)\n if len(doors) != 0:\n face._punched_geometry = None\n",
"outputs": [
[
{
"access": "None",
"name": "model",
"description": "A honeybee Model objects that has been re-serialized from the input file.",
"access": "None",
"type": null,
"description": "A honeybee Model objects that has been re-serialized from the input file.",
"default": null
}
]
],
"category": "Honeybee",
"nickname": "LoadEModel",
"inputs": [
{
"access": "item",
"name": "_model_file",
"description": "A file path to a gbXML, OSM or IDF file from which a Honeybee Model\nwill be loaded",
"access": "item",
"type": "string",
"description": "A file path to a gbXML, OSM or IDF file from which a Honeybee Model\nwill be loaded",
"default": null
},
{
"access": "item",
"name": "_load",
"description": "Set to \"True\" to load the Model from the input file.",
"access": "item",
"type": "bool",
"description": "Set to \"True\" to load the Model from the input file.",
"default": null
}
],
"subcategory": "3 :: Serialize",
"code": "\nimport os\nimport subprocess\nimport re\nimport json\n\ntry: # import the ladybug_geometry dependencies\n from ladybug_geometry.geometry3d.pointvector import Vector3D\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_geometry:\\n\\t{}'.format(e))\n\ntry: # import the core honeybee dependencies\n from honeybee.model import Model\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.config import folders as e_folders\n from honeybee_energy.result.osw import OSW\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: # import the core ladybug_{{cad}} dependencies\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs, give_warning\n from ladybug_{{cad}}.config import conversion_to_meters, units_system, \\\n tolerance, angle_tolerance\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n\ndef model_units_tolerance_check(model):\n \"\"\"Convert a model to the current {{Cad}} units and check the tolerance.\n\n Args:\n model: A honeybee Model, which will have its units checked.\n \"\"\"\n # check the model units\n if model.units != units_system():\n print('Imported model units \"{}\" do not match that of the current {{Cad}} '\n 'model units \"{}\"\\nThe model is being automatically converted '\n 'to the {{Cad}} doc units.'.format(model.units, units_system()))\n model.convert_to_units(units_system())\n\n # check that the model tolerance is not too far from the {{Cad}} tolerance\n if model.tolerance / tolerance >= 100:\n msg = 'Imported Model tolerance \"{}\" is significantly coarser than the ' \\\n 'current {{Cad}} model tolerance \"{}\".\\nIt is recommended that the ' \\\n '{{Cad}} document tolerance be changed to be coarser and this ' \\\n 'component is re-run.'.format(model.tolerance, tolerance)\n print msg\n give_warning(ghenv.Component, msg)\n\n\nif all_required_inputs(ghenv.Component) and _load:\n # check the presence of openstudio and check that the version is compatible\n check_openstudio_version()\n\n # sense the type of file we are loading\n lower_fname = os.path.basename(_model_file).lower()\n if lower_fname.endswith('.xml') or lower_fname.endswith('.gbxml'):\n cmd_name = 'model-from-gbxml'\n f_name = lower_fname.replace('.gbxml', '.hbjson').replace('.xml', '.hbjson')\n elif lower_fname.endswith('.osm'):\n cmd_name = 'model-from-osm'\n f_name = lower_fname.replace('.osm', '.hbjson')\n elif lower_fname.endswith('.idf'):\n cmd_name = 'model-from-idf'\n f_name = lower_fname.replace('.idf', '.hbjson')\n else:\n raise ValueError('Failed to recongize the input _model_file file type.\\n'\n 'Make sure that it has an appropriate file extension.')\n\n # Execute the honybee CLI to obtain the model JSON via CPython\n out_path = os.path.join(folders.default_simulation_folder, f_name)\n if os.path.isfile(out_path):\n os.remove(out_path)\n cmds = [folders.python_exe_path, '-m', 'honeybee_energy', 'translate',\n cmd_name, _model_file, '--output-file', out_path]\n shell = True if os.name == 'nt' else False\n process = subprocess.Popen(cmds, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=shell)\n result = process.communicate()\n\n # check to see if the file was successfully output and, if not, report the error\n if not os.path.isfile(out_path):\n if lower_fname.endswith('.idf'):\n # check the version of the IDF since, most of the time, people don't check this\n try:\n ver_regex = r'[V|v][E|e][R|r][S|s][I|i][O|o][N|n],\\s*(\\d*\\.\\d*)[;|.]'\n ver_pattern = re.compile(ver_regex)\n with open(_model_file, 'r') as mf:\n ver_val = re.search(ver_pattern, mf.read())\n ver_tup = tuple(int(v) for v in ver_val.groups()[0].split('.'))\n if e_folders.energyplus_version[:2] != ver_tup:\n msg = 'The IDF is from EnergyPlus version {}.\\nThis must be changed ' \\\n 'to {} with the IDFVersionUpdater\\nin order to import ' \\\n 'it with this Ladybug Tools installation.'.format(\n '.'.join((str(v) for v in ver_tup)),\n '.'.join((str(v) for v in e_folders.energyplus_version[:2]))\n )\n print(msg)\n give_warning(ghenv.Component, msg)\n except Exception:\n pass # failed to parse the version; it may not be in the IDF\n # parse any of the errors that came with the output OSW\n osw_path = os.path.join(folders.default_simulation_folder, 'temp_translate', 'out.osw')\n if os.path.isfile(osw_path):\n log_osw = OSW(osw_path)\n print(log_osw.stdout[0])\n errors = []\n for error, tb in zip(log_osw.errors, log_osw.error_tracebacks):\n print(tb)\n errors.append(error)\n raise Exception('Failed to run OpenStudio CLI:\\n{}'.format('\\n'.join(errors)))\n \n # if it's all good, load the model and convert it to {{Cad}} model units\n with open(out_path) as json_file:\n model_dict = json.load(json_file)\n model = Model.from_dict(model_dict)\n model_units_tolerance_check(model)\n\n # given that most other software lets doors go to the edge, move them slightly for HB\n move_vec = Vector3D(0, 0, 0.02 / conversion_to_meters())\n for room in model.rooms:\n for face in room.faces:\n doors = face.doors\n for door in doors:\n if not face.geometry.is_sub_face(door.geometry, tolerance, angle_tolerance):\n door.move(move_vec)\n if len(doors) != 0:\n face._punched_geometry = None\n",
"category": "Honeybee",
"name": "HB Load gbXML OSM IDF",
"description": "Load a gbXML, OSM, or IDF file as a Honeybee Model.\n_\nThe reverse translators within the OpenStudio SDK are used to import all geometry\nand boundary conditions (including adjacencies) to a Honeybee format.\n_\nNote that, while all geometry will be imported, it is possible that not all of the\nproperties assigned to this geometry will be imported, particularly if a certain\nproperty is not supported in the OpenStudio SDK. Honeybee will assign defaults\nfor missing properites and, the HBJSON format should be used whenever lossless\nfile transfer is needed.\n-"
]
}
Loading

0 comments on commit e4f7801

Please sign in to comment.