diff --git a/dragonfly_grasshopper/icon/DF Fourth Generation Thermal Loop.png b/dragonfly_grasshopper/icon/DF Fourth Generation Thermal Loop.png
new file mode 100644
index 0000000..4f9bdea
Binary files /dev/null and b/dragonfly_grasshopper/icon/DF Fourth Generation Thermal Loop.png differ
diff --git a/dragonfly_grasshopper/icon/DF Rejoin to Building.png b/dragonfly_grasshopper/icon/DF Rejoin to Building.png
index dbb19ee..d120300 100644
Binary files a/dragonfly_grasshopper/icon/DF Rejoin to Building.png and b/dragonfly_grasshopper/icon/DF Rejoin to Building.png differ
diff --git a/dragonfly_grasshopper/icon/DF Run Modelica DES.png b/dragonfly_grasshopper/icon/DF Run Modelica DES.png
new file mode 100644
index 0000000..c33c307
Binary files /dev/null and b/dragonfly_grasshopper/icon/DF Run Modelica DES.png differ
diff --git a/dragonfly_grasshopper/json/DF_Fourth_Generation_Thermal_Loop.json b/dragonfly_grasshopper/json/DF_Fourth_Generation_Thermal_Loop.json
new file mode 100644
index 0000000..3509b6b
--- /dev/null
+++ b/dragonfly_grasshopper/json/DF_Fourth_Generation_Thermal_Loop.json
@@ -0,0 +1,43 @@
+{
+ "version": "1.6.0",
+ "nickname": "Gen4Loop",
+ "outputs": [
+ [
+ {
+ "access": "None",
+ "name": "des_loop",
+ "description": "A Dragonfly Thermal Loop object possessing all infrastructure for a\nDistrict Energy Simulation (DES) simulation. This should be connected\nto the loop_ input of the \"DF Model to GeoJSON\" component.",
+ "type": null,
+ "default": null
+ }
+ ]
+ ],
+ "inputs": [
+ {
+ "access": "item",
+ "name": "_chilled_temp_",
+ "description": "A number for the temperature of chilled water in the DES\nin degrees Celsius. (Default: 6).",
+ "type": "double",
+ "default": null
+ },
+ {
+ "access": "item",
+ "name": "_hot_temp_",
+ "description": "A number for the temperature of hot water in the DES in degrees\nCelsius. (Default: 54).",
+ "type": "double",
+ "default": null
+ },
+ {
+ "access": "item",
+ "name": "_name_",
+ "description": "Text to be used for the name and identifier of the Thermal Loop.\nIf no name is provided, it will be \"unnamed\".",
+ "type": "string",
+ "default": null
+ }
+ ],
+ "subcategory": "3 :: Energy",
+ "code": "\ntry: # import the core honeybee dependencies\n from honeybee.typing import clean_ep_string\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee:\\n\\t{}'.format(e))\n\ntry: # import the core dragonfly_energy dependencies\n from dragonfly_energy.des.loop import FourthGenThermalLoop\nexcept ImportError as e:\n raise ImportError('\\nFailed to import dragonfly_energy:\\n\\t{}'.format(e))\n\ntry:\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs, give_warning\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n\nif all_required_inputs(ghenv.Component):\n # set defaults\n name = clean_ep_string(_name_) if _name_ is not None else 'unnamed'\n cwt = 6 if _chilled_temp_ is None else _chilled_temp_\n hwt = 54 if _hot_temp_ is None else _hot_temp_\n\n # create the loop\n des_loop = FourthGenThermalLoop(name, cwt, hwt)\n if _name_ is not None:\n des_loop.display_name = _name_\n",
+ "category": "Dragonfly",
+ "name": "DF Fourth Generation Thermal Loop",
+ "description": "Create an Fourth Generation Thermal Loop, which represents all infrastructure\nfor a District Energy Simulation (DES) simulation.\n_\nThis includes a central hot and chilled water plant for the district.\n-"
+}
\ No newline at end of file
diff --git a/dragonfly_grasshopper/json/DF_Rejoin_to_Building.json b/dragonfly_grasshopper/json/DF_Rejoin_to_Building.json
index e5ff929..642c637 100644
--- a/dragonfly_grasshopper/json/DF_Rejoin_to_Building.json
+++ b/dragonfly_grasshopper/json/DF_Rejoin_to_Building.json
@@ -1,5 +1,5 @@
{
- "version": "1.6.0",
+ "version": "1.6.1",
"nickname": "Rejoin",
"outputs": [
[
@@ -22,7 +22,7 @@
}
],
"subcategory": "0 :: Create",
- "code": "\ntry: # import the core dragonfly dependencies\n from dragonfly.building import Building\n from dragonfly.story import Story\n from dragonfly.room2d import Room2D\n from dragonfly.colorobj import ColorRoom2D\nexcept ImportError as e:\n raise ImportError('\\nFailed to import dragonfly:\\n\\t{}'.format(e))\n\ntry:\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs, give_warning, \\\n document_counter\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n\nif all_required_inputs(ghenv.Component):\n # duplicate the initial objects\n room2ds = []\n for rm in _room2ds:\n assert isinstance(rm, Room2D), 'Expected Room2D. Got {}.'.format(type(rm))\n room2ds.append(rm.duplicate())\n\n # organize the rooms into a nested dictionary by story/building\n orphaned_rooms = []\n org_dict, bldg_dict = {}, {}\n for rm in room2ds:\n if rm.has_parent and rm.parent.has_parent:\n story = rm.parent\n bldg = story.parent\n if bldg.identifier not in bldg_dict:\n bldg_dict[bldg.identifier] = bldg\n org_dict[bldg.identifier] = {}\n try:\n org_dict[bldg.identifier][story.identifier].append(rm)\n except KeyError:\n org_dict[bldg.identifier][story.identifier] = [rm]\n else:\n orphaned_rooms.append(rm)\n\n # re-generate the Buildings and add the new Room2Ds\n buildings = []\n for bldg in bldg_dict.values():\n new_bldg = bldg.duplicate()\n for story in new_bldg:\n try:\n rm_2ds = org_dict[bldg.identifier][story.identifier]\n story._room_2ds = ()\n story.add_room_2ds(rm_2ds)\n except KeyError: # story missing from the input and we'll use the old ones\n pass\n buildings.append(new_bldg)\n\n # if there were orphaned Room2Ds, add them to their own building\n if len(orphaned_rooms) != 0:\n # give a warning about the orphaned Room2Ds\n display_name = 'Building_{}'.format(document_counter('bldg_count'))\n name = clean_and_id_string(display_name)\n msg = '{} of the input Room2Ds were not a part of an original Dragonfly ' \\\n 'Building.\\nThey have been added to a new Building with the auto-generated ' \\\n 'name \"{}\"\\nBetter practice is to add these Room2Ds to new Stories and ' \\\n 'then a Building.'.format(len(orphaned_rooms), display_name)\n give_warning(ghenv.Component, msg)\n # create the stories and the building\n color_obj = ColorRoom2D(orphaned_rooms, 'floor_height')\n story_groups = [[] for val in values]\n values = color_obj.attributes_unique\n for atr, room in zip(color_obj.attributes, in_rooms):\n atr_i = values.index(atr)\n story_groups[atr_i].append(room)\n stories = [Story('{}_Story{}'.format(name, i), r_group)\n for i, r_group in enumerate(story_groups)]\n o_building = Building(name, stories)\n o_building.display_name = display_name\n buildings.append(o_building)\n",
+ "code": "\nfrom collections import OrderedDict\n\ntry: # import the core dragonfly dependencies\n from dragonfly.building import Building\n from dragonfly.story import Story\n from dragonfly.room2d import Room2D\n from dragonfly.colorobj import ColorRoom2D\nexcept ImportError as e:\n raise ImportError('\\nFailed to import dragonfly:\\n\\t{}'.format(e))\n\ntry:\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs, give_warning, \\\n document_counter\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug_{{cad}}:\\n\\t{}'.format(e))\n\n\nif all_required_inputs(ghenv.Component):\n # duplicate the initial objects\n room2ds = []\n for rm in _room2ds:\n assert isinstance(rm, Room2D), 'Expected Room2D. Got {}.'.format(type(rm))\n room2ds.append(rm.duplicate())\n\n # organize the rooms into a nested dictionary by story/building\n orphaned_rooms = []\n org_dict, bldg_dict = OrderedDict(), OrderedDict()\n for rm in room2ds:\n if rm.has_parent and rm.parent.has_parent:\n story = rm.parent\n bldg = story.parent\n if bldg.identifier not in bldg_dict:\n bldg_dict[bldg.identifier] = bldg\n org_dict[bldg.identifier] = OrderedDict()\n try:\n org_dict[bldg.identifier][story.identifier].append(rm)\n except KeyError:\n org_dict[bldg.identifier][story.identifier] = [rm]\n else:\n orphaned_rooms.append(rm)\n\n # re-generate the Buildings and add the new Room2Ds\n buildings = []\n for bldg in bldg_dict.values():\n new_bldg = bldg.duplicate()\n for story in new_bldg:\n try:\n rm_2ds = org_dict[bldg.identifier][story.identifier]\n story._room_2ds = ()\n story.add_room_2ds(rm_2ds)\n except KeyError: # story missing from the input and we'll use the old ones\n pass\n buildings.append(new_bldg)\n\n # if there were orphaned Room2Ds, add them to their own building\n if len(orphaned_rooms) != 0:\n # give a warning about the orphaned Room2Ds\n display_name = 'Building_{}'.format(document_counter('bldg_count'))\n name = clean_and_id_string(display_name)\n msg = '{} of the input Room2Ds were not a part of an original Dragonfly ' \\\n 'Building.\\nThey have been added to a new Building with the auto-generated ' \\\n 'name \"{}\"\\nBetter practice is to add these Room2Ds to new Stories and ' \\\n 'then a Building.'.format(len(orphaned_rooms), display_name)\n give_warning(ghenv.Component, msg)\n # create the stories and the building\n color_obj = ColorRoom2D(orphaned_rooms, 'floor_height')\n story_groups = [[] for val in values]\n values = color_obj.attributes_unique\n for atr, room in zip(color_obj.attributes, in_rooms):\n atr_i = values.index(atr)\n story_groups[atr_i].append(room)\n stories = [Story('{}_Story{}'.format(name, i), r_group)\n for i, r_group in enumerate(story_groups)]\n o_building = Building(name, stories)\n o_building.display_name = display_name\n buildings.append(o_building)\n",
"category": "Dragonfly",
"name": "DF Rejoin to Building",
"description": "Rejoin a list of Room2Ds that were originally a part of a Building back to a new\nBuilding with updated Room2Ds.\n_\nIn the event that the input contains Room2Ds that were not a part of an original\nBuilding, this component can still be used but the stories will be regenerated\nbased on the Room2D floor elevations and a warning will be given.\n-"
diff --git a/dragonfly_grasshopper/json/DF_Run_Modelica_DES.json b/dragonfly_grasshopper/json/DF_Run_Modelica_DES.json
new file mode 100644
index 0000000..3c94ccc
--- /dev/null
+++ b/dragonfly_grasshopper/json/DF_Run_Modelica_DES.json
@@ -0,0 +1,43 @@
+{
+ "version": "1.6.0",
+ "nickname": "RunDES",
+ "outputs": [
+ [
+ {
+ "access": "None",
+ "name": "modelica",
+ "description": "A folder where all of the Modelica files of the District Energy\nSystem (DES) are written.",
+ "type": null,
+ "default": null
+ }
+ ]
+ ],
+ "inputs": [
+ {
+ "access": "item",
+ "name": "_geojson",
+ "description": "The path to an URBANopt-compatible geoJSON file. This geoJSON\nfile can be obtained form the \"DF Model to geoJSON\" component.\nThe geoJSON must have a valid District Energy System (DES) Loop\nassigned to it in order to run correctly through the DES simulation.",
+ "type": "string",
+ "default": null
+ },
+ {
+ "access": "item",
+ "name": "_scenario",
+ "description": "The path to an URBANopt .csv file for the scenario. This CSV\nfile can be obtained form the \"DF Run URBANopt\" component.",
+ "type": "string",
+ "default": null
+ },
+ {
+ "access": "item",
+ "name": "_run",
+ "description": "Set to \"True\" to simulate the Distric Energy System.",
+ "type": "bool",
+ "default": null
+ }
+ ],
+ "subcategory": "3 :: Energy",
+ "code": "\nimport os\nimport subprocess\n\ntry:\n from ladybug.futil import nukedir\n from ladybug.config import folders as lb_folders\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee:\\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: # import the dragonfly_energy dependencies\n from dragonfly_energy.run import run_default_report\nexcept ImportError as e:\n raise ImportError('\\nFailed to import dragonfly_energy:\\n\\t{}'.format(e))\n\ntry:\n from ladybug_{{cad}}.download import download_file_by_name\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\nUO_GMT_VERSION = '0.6.0rc1'\nUO_TN_VERSION = '0.2.1'\nMBL_VERSION = '9.1.1'\n\n\nif all_required_inputs(ghenv.Component) and _run:\n # set clobal values\n ext = '.exe' if os.name == 'nt' else ''\n executor_path = os.path.join(\n lb_folders.ladybug_tools_folder, '{{plugin}}',\n 'ladybug_{{plugin}}_dotnet', 'Ladybug.Executor.exe')\n\n # check to see if the geojson-modelica-translator is installed\n uo_gmt = '{}/uo_des{}'.format(folders.python_scripts_path, ext)\n uo_gmt_pack = '{}/geojson_modelica_translator-{}.dist-info'.format(\n folders.python_package_path, UO_GMT_VERSION)\n if not os.path.isfile(uo_gmt) or not os.path.isdir(uo_gmt_pack):\n #install_cmd = 'pip install geojson-modelica-translator=={}'.format(UO_GMT_VERSION)\n install_cmd = 'pip install git+https://github.com/urbanopt/geojson-modelica-translator@develop'\n if os.name == 'nt' and os.path.isfile(executor_path) and \\\n 'Program Files' in executor_path:\n pip_cmd = [\n executor_path, folders.python_exe_path, '-m {}'.format(install_cmd)\n ]\n else:\n pip_cmd = '\"{py_exe}\" -m {uo_cmd}'.format(\n py_exe=folders.python_exe_path, uo_cmd=install_cmd)\n shell = True if os.name == 'nt' else False\n process = subprocess.Popen(pip_cmd, stderr=subprocess.PIPE, shell=shell)\n stderr = process.communicate()\n\n # check to see if the ThermalNetwork package is installed\n uo_tn = '{}/thermalnetwork{}'.format(folders.python_scripts_path, ext)\n uo_tn_pack = '{}/ThermalNetwork-{}.dist-info'.format(\n folders.python_package_path, UO_TN_VERSION)\n if not os.path.isfile(uo_tn) or not os.path.isdir(uo_tn_pack):\n install_cmd = 'pip install thermalnetwork=={}'.format(UO_TN_VERSION)\n if os.name == 'nt' and os.path.isfile(executor_path) and \\\n 'Program Files' in executor_path:\n pip_cmd = [\n executor_path, folders.python_exe_path, '-m {}'.format(install_cmd)\n ]\n else:\n pip_cmd = '\"{py_exe}\" -m {uo_cmd}'.format(\n py_exe=folders.python_exe_path, uo_cmd=install_cmd)\n shell = True if os.name == 'nt' else False\n process = subprocess.Popen(pip_cmd, stderr=subprocess.PIPE, shell=shell)\n stderr = process.communicate()\n\n # check to see if the Modelica Buildings Library is installed\n install_directory = os.path.join(lb_folders.ladybug_tools_folder, 'resources')\n final_dir = os.path.join(install_directory, 'mbl')\n version_file = os.path.join(final_dir, 'version.txt')\n already_installed = False\n if os.path.isdir(final_dir) and os.path.isfile(version_file):\n with open(version_file, 'r') as vf:\n install_version = vf.read()\n if install_version == MBL_VERSION:\n already_installed = True\n else:\n nukedir(final_dir, True)\n if not already_installed:\n install_cmd = 'dragonfly_energy install mbl --version {}'.format(MBL_VERSION)\n if os.name == 'nt' and os.path.isfile(executor_path) and \\\n 'Program Files' in executor_path:\n pip_cmd = [\n executor_path, folders.python_exe_path, '-m {}'.format(install_cmd)\n ]\n else:\n pip_cmd = '\"{py_exe}\" -m {uo_cmd}'.format(\n py_exe=folders.python_exe_path, uo_cmd=install_cmd)\n shell = True if os.name == 'nt' else False\n process = subprocess.Popen(pip_cmd, stderr=subprocess.PIPE, shell=shell)\n stderr = process.communicate()\n\n \"\"\"\n # delete any existing files in the result folder\n scen_name = os.path.basename(_scenario).replace('.csv', '')\n run_folder = os.path.join(os.path.dirname(_geojson), 'run', scen_name)\n result_folder = os.path.join(run_folder, 'modelica')\n nukedir(result_folder)\n\n # prepare the Modelica-running command\n command = '\"{uo_ditto}\" run-opendss -f \"{feature_file}\" ' \\\n '-s \"{scenario_file}\"'.format(\n uo_ditto=uo_ditto, feature_file=_geojson, scenario_file=_scenario)\n\n # execute the command to run everything through Modelica\n shell = False if os.name == 'nt' else True\n process = subprocess.Popen(command, stderr=subprocess.PIPE, shell=shell)\n stderr = process.communicate()\n\n # gather together all of the result files\n bldg_folder = os.path.join(result_folder, 'results', 'Features')\n \"\"\"\n",
+ "category": "Dragonfly",
+ "name": "DF Run Modelica DES",
+ "description": "Run a an URBANopt geoJSON and scenario through Modelica DES simulation.\n_\nThe geoJSON must have a valid DES Loop assigned to it in order to run correctly\nthrough Modelica DES simulation.\n-"
+}
\ No newline at end of file
diff --git a/dragonfly_grasshopper/src/DF Fourth Generation Thermal Loop.py b/dragonfly_grasshopper/src/DF Fourth Generation Thermal Loop.py
new file mode 100644
index 0000000..2c72997
--- /dev/null
+++ b/dragonfly_grasshopper/src/DF Fourth Generation Thermal Loop.py
@@ -0,0 +1,64 @@
+# Dragonfly: A Plugin for Environmental Analysis (GPL)
+# This file is part of Dragonfly.
+#
+# Copyright (c) 2023, Ladybug Tools.
+# You should have received a copy of the GNU Affero General Public License
+# along with Dragonfly; If not, see .
+#
+# @license AGPL-3.0-or-later
+
+"""
+Create an Fourth Generation Thermal Loop, which represents all infrastructure
+for a District Energy Simulation (DES) simulation.
+_
+This includes a central hot and chilled water plant for the district.
+-
+
+ Args:
+ _chilled_temp_: A number for the temperature of chilled water in the DES
+ in degrees Celsius. (Default: 6).
+ _hot_temp_: A number for the temperature of hot water in the DES in degrees
+ Celsius. (Default: 54).
+ _name_: Text to be used for the name and identifier of the Thermal Loop.
+ If no name is provided, it will be "unnamed".
+
+ Returns:
+ report: Reports, errors, warnings, etc.
+ loop: A Dragonfly Thermal Loop object possessing all infrastructure for a
+ District Energy Simulation (DES) simulation. This should be connected
+ to the loop_ input of the "DF Model to GeoJSON" component.
+"""
+
+ghenv.Component.Name = 'DF Fourth Generation Thermal Loop'
+ghenv.Component.NickName = 'Gen4Loop'
+ghenv.Component.Message = '1.6.0'
+ghenv.Component.Category = 'Dragonfly'
+ghenv.Component.SubCategory = '3 :: Energy'
+ghenv.Component.AdditionalHelpFromDocStrings = '0'
+
+try: # import the core honeybee dependencies
+ from honeybee.typing import clean_ep_string
+except ImportError as e:
+ raise ImportError('\nFailed to import honeybee:\n\t{}'.format(e))
+
+try: # import the core dragonfly_energy dependencies
+ from dragonfly_energy.des.loop import FourthGenThermalLoop
+except ImportError as e:
+ raise ImportError('\nFailed to import dragonfly_energy:\n\t{}'.format(e))
+
+try:
+ from ladybug_rhino.grasshopper import all_required_inputs, give_warning
+except ImportError as e:
+ raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
+
+
+if all_required_inputs(ghenv.Component):
+ # set defaults
+ name = clean_ep_string(_name_) if _name_ is not None else 'unnamed'
+ cwt = 6 if _chilled_temp_ is None else _chilled_temp_
+ hwt = 54 if _hot_temp_ is None else _hot_temp_
+
+ # create the loop
+ des_loop = FourthGenThermalLoop(name, cwt, hwt)
+ if _name_ is not None:
+ des_loop.display_name = _name_
diff --git a/dragonfly_grasshopper/src/DF Rejoin to Building.py b/dragonfly_grasshopper/src/DF Rejoin to Building.py
index 03a46bc..ed5c595 100644
--- a/dragonfly_grasshopper/src/DF Rejoin to Building.py
+++ b/dragonfly_grasshopper/src/DF Rejoin to Building.py
@@ -28,11 +28,13 @@
ghenv.Component.Name = 'DF Rejoin to Building'
ghenv.Component.NickName = 'Rejoin'
-ghenv.Component.Message = '1.6.0'
+ghenv.Component.Message = '1.6.1'
ghenv.Component.Category = 'Dragonfly'
ghenv.Component.SubCategory = '0 :: Create'
ghenv.Component.AdditionalHelpFromDocStrings = '3'
+from collections import OrderedDict
+
try: # import the core dragonfly dependencies
from dragonfly.building import Building
from dragonfly.story import Story
@@ -57,14 +59,14 @@
# organize the rooms into a nested dictionary by story/building
orphaned_rooms = []
- org_dict, bldg_dict = {}, {}
+ org_dict, bldg_dict = OrderedDict(), OrderedDict()
for rm in room2ds:
if rm.has_parent and rm.parent.has_parent:
story = rm.parent
bldg = story.parent
if bldg.identifier not in bldg_dict:
bldg_dict[bldg.identifier] = bldg
- org_dict[bldg.identifier] = {}
+ org_dict[bldg.identifier] = OrderedDict()
try:
org_dict[bldg.identifier][story.identifier].append(rm)
except KeyError:
diff --git a/dragonfly_grasshopper/src/DF Run Modelica DES.py b/dragonfly_grasshopper/src/DF Run Modelica DES.py
new file mode 100644
index 0000000..49ef78c
--- /dev/null
+++ b/dragonfly_grasshopper/src/DF Run Modelica DES.py
@@ -0,0 +1,158 @@
+# Dragonfly: A Plugin for Environmental Analysis (GPL)
+# This file is part of Dragonfly.
+#
+# Copyright (c) 2023, Ladybug Tools.
+# You should have received a copy of the GNU Affero General Public License
+# along with Dragonfly; If not, see .
+#
+# @license AGPL-3.0-or-later
+
+"""
+Run a an URBANopt geoJSON and scenario through Modelica DES simulation.
+_
+The geoJSON must have a valid DES Loop assigned to it in order to run correctly
+through Modelica DES simulation.
+-
+
+ Args:
+ _geojson: The path to an URBANopt-compatible geoJSON file. This geoJSON
+ file can be obtained form the "DF Model to geoJSON" component.
+ The geoJSON must have a valid District Energy System (DES) Loop
+ assigned to it in order to run correctly through the DES simulation.
+ _scenario: The path to an URBANopt .csv file for the scenario. This CSV
+ file can be obtained form the "DF Run URBANopt" component.
+ _run: Set to "True" to simulate the Distric Energy System.
+
+ Returns:
+ report: Reports, errors, warnings, etc.
+ modelica: A folder where all of the Modelica files of the District Energy
+ System (DES) are written.
+"""
+
+ghenv.Component.Name = 'DF Run Modelica DES'
+ghenv.Component.NickName = 'RunDES'
+ghenv.Component.Message = '1.6.0'
+ghenv.Component.Category = 'Dragonfly'
+ghenv.Component.SubCategory = '3 :: Energy'
+ghenv.Component.AdditionalHelpFromDocStrings = '0'
+
+import os
+import subprocess
+
+try:
+ from ladybug.futil import nukedir
+ from ladybug.config import folders as lb_folders
+except ImportError as e:
+ raise ImportError('\nFailed to import honeybee:\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: # import the dragonfly_energy dependencies
+ from dragonfly_energy.run import run_default_report
+except ImportError as e:
+ raise ImportError('\nFailed to import dragonfly_energy:\n\t{}'.format(e))
+
+try:
+ from ladybug_rhino.download import download_file_by_name
+ from ladybug_rhino.grasshopper import all_required_inputs
+except ImportError as e:
+ raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))
+
+UO_GMT_VERSION = '0.6.0rc1'
+UO_TN_VERSION = '0.2.1'
+MBL_VERSION = '9.1.1'
+
+
+if all_required_inputs(ghenv.Component) and _run:
+ # set clobal values
+ ext = '.exe' if os.name == 'nt' else ''
+ executor_path = os.path.join(
+ lb_folders.ladybug_tools_folder, 'grasshopper',
+ 'ladybug_grasshopper_dotnet', 'Ladybug.Executor.exe')
+
+ # check to see if the geojson-modelica-translator is installed
+ uo_gmt = '{}/uo_des{}'.format(folders.python_scripts_path, ext)
+ uo_gmt_pack = '{}/geojson_modelica_translator-{}.dist-info'.format(
+ folders.python_package_path, UO_GMT_VERSION)
+ if not os.path.isfile(uo_gmt) or not os.path.isdir(uo_gmt_pack):
+ #install_cmd = 'pip install geojson-modelica-translator=={}'.format(UO_GMT_VERSION)
+ install_cmd = 'pip install git+https://github.com/urbanopt/geojson-modelica-translator@develop'
+ if os.name == 'nt' and os.path.isfile(executor_path) and \
+ 'Program Files' in executor_path:
+ pip_cmd = [
+ executor_path, folders.python_exe_path, '-m {}'.format(install_cmd)
+ ]
+ else:
+ pip_cmd = '"{py_exe}" -m {uo_cmd}'.format(
+ py_exe=folders.python_exe_path, uo_cmd=install_cmd)
+ shell = True if os.name == 'nt' else False
+ process = subprocess.Popen(pip_cmd, stderr=subprocess.PIPE, shell=shell)
+ stderr = process.communicate()
+
+ # check to see if the ThermalNetwork package is installed
+ uo_tn = '{}/thermalnetwork{}'.format(folders.python_scripts_path, ext)
+ uo_tn_pack = '{}/ThermalNetwork-{}.dist-info'.format(
+ folders.python_package_path, UO_TN_VERSION)
+ if not os.path.isfile(uo_tn) or not os.path.isdir(uo_tn_pack):
+ install_cmd = 'pip install thermalnetwork=={}'.format(UO_TN_VERSION)
+ if os.name == 'nt' and os.path.isfile(executor_path) and \
+ 'Program Files' in executor_path:
+ pip_cmd = [
+ executor_path, folders.python_exe_path, '-m {}'.format(install_cmd)
+ ]
+ else:
+ pip_cmd = '"{py_exe}" -m {uo_cmd}'.format(
+ py_exe=folders.python_exe_path, uo_cmd=install_cmd)
+ shell = True if os.name == 'nt' else False
+ process = subprocess.Popen(pip_cmd, stderr=subprocess.PIPE, shell=shell)
+ stderr = process.communicate()
+
+ # check to see if the Modelica Buildings Library is installed
+ install_directory = os.path.join(lb_folders.ladybug_tools_folder, 'resources')
+ final_dir = os.path.join(install_directory, 'mbl')
+ version_file = os.path.join(final_dir, 'version.txt')
+ already_installed = False
+ if os.path.isdir(final_dir) and os.path.isfile(version_file):
+ with open(version_file, 'r') as vf:
+ install_version = vf.read()
+ if install_version == MBL_VERSION:
+ already_installed = True
+ else:
+ nukedir(final_dir, True)
+ if not already_installed:
+ install_cmd = 'dragonfly_energy install mbl --version {}'.format(MBL_VERSION)
+ if os.name == 'nt' and os.path.isfile(executor_path) and \
+ 'Program Files' in executor_path:
+ pip_cmd = [
+ executor_path, folders.python_exe_path, '-m {}'.format(install_cmd)
+ ]
+ else:
+ pip_cmd = '"{py_exe}" -m {uo_cmd}'.format(
+ py_exe=folders.python_exe_path, uo_cmd=install_cmd)
+ shell = True if os.name == 'nt' else False
+ process = subprocess.Popen(pip_cmd, stderr=subprocess.PIPE, shell=shell)
+ stderr = process.communicate()
+
+ """
+ # delete any existing files in the result folder
+ scen_name = os.path.basename(_scenario).replace('.csv', '')
+ run_folder = os.path.join(os.path.dirname(_geojson), 'run', scen_name)
+ result_folder = os.path.join(run_folder, 'modelica')
+ nukedir(result_folder)
+
+ # prepare the Modelica-running command
+ command = '"{uo_ditto}" run-opendss -f "{feature_file}" ' \
+ '-s "{scenario_file}"'.format(
+ uo_ditto=uo_ditto, feature_file=_geojson, scenario_file=_scenario)
+
+ # execute the command to run everything through Modelica
+ shell = False if os.name == 'nt' else True
+ process = subprocess.Popen(command, stderr=subprocess.PIPE, shell=shell)
+ stderr = process.communicate()
+
+ # gather together all of the result files
+ bldg_folder = os.path.join(result_folder, 'results', 'Features')
+ """
diff --git a/dragonfly_grasshopper/user_objects/DF Fourth Generation Thermal Loop.ghuser b/dragonfly_grasshopper/user_objects/DF Fourth Generation Thermal Loop.ghuser
new file mode 100644
index 0000000..ebf7a7f
Binary files /dev/null and b/dragonfly_grasshopper/user_objects/DF Fourth Generation Thermal Loop.ghuser differ
diff --git a/dragonfly_grasshopper/user_objects/DF Rejoin to Building.ghuser b/dragonfly_grasshopper/user_objects/DF Rejoin to Building.ghuser
index 2921f56..70f1731 100644
Binary files a/dragonfly_grasshopper/user_objects/DF Rejoin to Building.ghuser and b/dragonfly_grasshopper/user_objects/DF Rejoin to Building.ghuser differ
diff --git a/dragonfly_grasshopper/user_objects/DF Run Modelica DES.ghuser b/dragonfly_grasshopper/user_objects/DF Run Modelica DES.ghuser
new file mode 100644
index 0000000..9a4b7fd
Binary files /dev/null and b/dragonfly_grasshopper/user_objects/DF Run Modelica DES.ghuser differ
diff --git a/samples/from_building_footprints.gh b/samples/from_building_footprints.gh
index 92f59bd..1d57cc1 100644
Binary files a/samples/from_building_footprints.gh and b/samples/from_building_footprints.gh differ
diff --git a/samples/ghe_example.gh b/samples/ghe_example.gh
index a07fb93..8db20cb 100644
Binary files a/samples/ghe_example.gh and b/samples/ghe_example.gh differ