From 4d0728a4489f12f9450a4a1f0064903489e045ff Mon Sep 17 00:00:00 2001 From: Chris Mackey Date: Thu, 14 Sep 2023 17:32:38 -0700 Subject: [PATCH] fix(thermal_map): Expose comfort parameters on UTCI map --- .../json/HB_UTCI_Comfort_Map.json | 11 +++++++++-- .../src/HB UTCI Comfort Map.py | 7 ++++++- .../user_objects/HB UTCI Comfort Map.ghuser | Bin 9747 -> 9910 bytes 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/honeybee_grasshopper_energy/json/HB_UTCI_Comfort_Map.json b/honeybee_grasshopper_energy/json/HB_UTCI_Comfort_Map.json index 705046b2..5bcb2f16 100644 --- a/honeybee_grasshopper_energy/json/HB_UTCI_Comfort_Map.json +++ b/honeybee_grasshopper_energy/json/HB_UTCI_Comfort_Map.json @@ -1,5 +1,5 @@ { - "version": "1.6.0", + "version": "1.6.1", "nickname": "UTCIMap", "outputs": [ [ @@ -104,6 +104,13 @@ "type": "System.Object", "default": null }, + { + "access": "item", + "name": "comfort_par_", + "description": "Optional comfort parameters from the \"LB UTCI Comfort Parameters\"\ncomponent to specify the temperatures (in Celcius) that are\nconsidered acceptable/comfortable. The default will assume a that\nthe comfort range is between 9C and 26C.", + "type": "string", + "default": null + }, { "access": "item", "name": "solar_body_par_", @@ -134,7 +141,7 @@ } ], "subcategory": "7 :: Thermal Map", - "code": "\nimport os\n\ntry:\n from lbt_recipes.recipe import Recipe\n from honeybee.model import Model\nexcept ImportError as e:\n raise ImportError('\\nFailed to import lbt_recipes:\\n\\t{}'.format(e))\n\ntry:\n from ladybug_{{cad}}.config import units_system\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs, recipe_result\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 # create the recipe and set the input arguments\n recipe = Recipe('utci_comfort_map')\n recipe.input_value_by_name('model', _model)\n recipe.input_value_by_name('epw', _epw)\n recipe.input_value_by_name('ddy', ddy_)\n recipe.input_value_by_name('north', north_)\n recipe.input_value_by_name('run-period', run_period_)\n if isinstance(_wind_speed_, str) and os.path.isdir(_wind_speed_):\n recipe.input_value_by_name('air-speed-matrices', _wind_speed_)\n else:\n recipe.input_value_by_name('wind-speed', _wind_speed_)\n recipe.input_value_by_name('schedule', schedule_)\n recipe.input_value_by_name('solarcal-parameters', solar_body_par_)\n recipe.input_value_by_name('radiance-parameters', radiance_par_)\n\n # perform an extra check for units because many people forget to check them\n if isinstance(_model, Model):\n check_model = _model\n if check_model.units != 'Meters':\n check_model = _model.duplicate()\n check_model.convert_to_units('Meters')\n # remove degenerate geometry within native E+ tolerance of 0.01 meters\n for room in check_model.rooms:\n try:\n room.remove_colinear_vertices_envelope(\n tolerance=0.01, delete_degenerate=True)\n except AssertionError as e: # room removed; likely wrong units\n error = 'Your Model units system is: {}. ' \\\n 'Is this correct?\\n{}'.format(_model.units, e)\n raise ValueError(error)\n\n # run the recipe\n silent = True if _run > 1 else False\n project_folder = recipe.run(\n run_settings_, radiance_check=True, openstudio_check=True, silent=silent)\n\n # load the results\n try:\n env_conds = recipe_result(recipe.output_value_by_name('environmental-conditions', project_folder))\n utci = recipe_result(recipe.output_value_by_name('utci', project_folder))\n condition = recipe_result(recipe.output_value_by_name('condition', project_folder))\n category = recipe_result(recipe.output_value_by_name('category', project_folder))\n TCP = recipe_result(recipe.output_value_by_name('tcp', project_folder))\n HSP = recipe_result(recipe.output_value_by_name('hsp', project_folder))\n CSP = recipe_result(recipe.output_value_by_name('csp', project_folder))\n except Exception:\n raise Exception(recipe.failure_message(project_folder))\n", + "code": "\nimport os\n\ntry:\n from lbt_recipes.recipe import Recipe\n from honeybee.model import Model\nexcept ImportError as e:\n raise ImportError('\\nFailed to import lbt_recipes:\\n\\t{}'.format(e))\n\ntry:\n from ladybug_{{cad}}.config import units_system\n from ladybug_{{cad}}.{{plugin}} import all_required_inputs, recipe_result\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 # create the recipe and set the input arguments\n recipe = Recipe('utci_comfort_map')\n recipe.input_value_by_name('model', _model)\n recipe.input_value_by_name('epw', _epw)\n recipe.input_value_by_name('ddy', ddy_)\n recipe.input_value_by_name('north', north_)\n recipe.input_value_by_name('run-period', run_period_)\n if isinstance(_wind_speed_, str) and os.path.isdir(_wind_speed_):\n recipe.input_value_by_name('air-speed-matrices', _wind_speed_)\n else:\n recipe.input_value_by_name('wind-speed', _wind_speed_)\n recipe.input_value_by_name('schedule', schedule_)\n recipe.input_value_by_name('comfort-parameters', comfort_par_)\n recipe.input_value_by_name('solarcal-parameters', solar_body_par_)\n recipe.input_value_by_name('radiance-parameters', radiance_par_)\n\n # perform an extra check for units because many people forget to check them\n if isinstance(_model, Model):\n check_model = _model\n if check_model.units != 'Meters':\n check_model = _model.duplicate()\n check_model.convert_to_units('Meters')\n # remove degenerate geometry within native E+ tolerance of 0.01 meters\n for room in check_model.rooms:\n try:\n room.remove_colinear_vertices_envelope(\n tolerance=0.01, delete_degenerate=True)\n except AssertionError as e: # room removed; likely wrong units\n error = 'Your Model units system is: {}. ' \\\n 'Is this correct?\\n{}'.format(_model.units, e)\n raise ValueError(error)\n\n # run the recipe\n silent = True if _run > 1 else False\n project_folder = recipe.run(\n run_settings_, radiance_check=True, openstudio_check=True, silent=silent)\n\n # load the results\n try:\n env_conds = recipe_result(recipe.output_value_by_name('environmental-conditions', project_folder))\n utci = recipe_result(recipe.output_value_by_name('utci', project_folder))\n condition = recipe_result(recipe.output_value_by_name('condition', project_folder))\n category = recipe_result(recipe.output_value_by_name('category', project_folder))\n TCP = recipe_result(recipe.output_value_by_name('tcp', project_folder))\n HSP = recipe_result(recipe.output_value_by_name('hsp', project_folder))\n CSP = recipe_result(recipe.output_value_by_name('csp', project_folder))\n except Exception:\n raise Exception(recipe.failure_message(project_folder))\n", "category": "HB-Energy", "name": "HB UTCI Comfort Map", "description": "Compute spatially-resolved Universal Thermal Climate Index (UTCI) and heat/cold\nstress conditions an EPW and Honeybee model.\n_\nThis recipe uses EnergyPlus to obtain surface temperatures and indoor air\ntemperatures + humidities. Outdoor air temperatures, relative humidities, and\nair speeds are taken directly from the EPW. The energy properties of the model\ngeometry are what determine the outcome of the simulation, though the model's\nRadiance sensor grids are what determine where the comfort mapping occurs.\n_\nLongwave radiant temperatures are obtained by computing spherical view factors\nfrom each sensor to the Room surfaces of the model using Radiance. These view factors\nare then multiplied by the surface temperatures output by EnergyPlus to yield\nlongwave MRT at each sensor. For outdoor sensors, each sensor's sky view is multiplied\nby the EPW sky temperature to account for longwave radiant exchange with the sky.\nAll outdoor context shades and the ground are assumed to be at the EPW air\ntemperature unless they have been modeled as Honeybee rooms.\n_\nA Radiance-based enhanced 2-phase method is used for all shortwave MRT calculations,\nwhich precisely represents direct sun by tracing a ray from each sensor to the\nsolar position. To determine Thermal Comfort Percent (TCP), the occupancy schedules\nof the energy model are used for indoor sensors if no schedule_ is input. Any\nhour of the energy model occupancy schedule that is 0.1 or greater will be\nconsidered occupied. If no schedule_ is input, all hours of the outdoors are\nconsidered occupied.\n-" diff --git a/honeybee_grasshopper_energy/src/HB UTCI Comfort Map.py b/honeybee_grasshopper_energy/src/HB UTCI Comfort Map.py index b23b056b..d962fe89 100644 --- a/honeybee_grasshopper_energy/src/HB UTCI Comfort Map.py +++ b/honeybee_grasshopper_energy/src/HB UTCI Comfort Map.py @@ -72,6 +72,10 @@ If unspecified, it will be assumed that all times are relevant for outdoor sensors and the energy model occupancy schedules will be used for indoor sensors. + comfort_par_: Optional comfort parameters from the "LB UTCI Comfort Parameters" + component to specify the temperatures (in Celcius) that are + considered acceptable/comfortable. The default will assume a that + the comfort range is between 9C and 26C. solar_body_par_: Optional solar body parameters from the "LB Solar Body Parameters" object to specify the properties of the human geometry assumed in the shortwave MRT calculation. The default assumes average skin/clothing @@ -154,7 +158,7 @@ ghenv.Component.Name = 'HB UTCI Comfort Map' ghenv.Component.NickName = 'UTCIMap' -ghenv.Component.Message = '1.6.0' +ghenv.Component.Message = '1.6.1' ghenv.Component.Category = 'HB-Energy' ghenv.Component.SubCategory = '7 :: Thermal Map' ghenv.Component.AdditionalHelpFromDocStrings = '1' @@ -187,6 +191,7 @@ else: recipe.input_value_by_name('wind-speed', _wind_speed_) recipe.input_value_by_name('schedule', schedule_) + recipe.input_value_by_name('comfort-parameters', comfort_par_) recipe.input_value_by_name('solarcal-parameters', solar_body_par_) recipe.input_value_by_name('radiance-parameters', radiance_par_) diff --git a/honeybee_grasshopper_energy/user_objects/HB UTCI Comfort Map.ghuser b/honeybee_grasshopper_energy/user_objects/HB UTCI Comfort Map.ghuser index 275f78df54ccac224d56939e9d24d015fe5b996b..e50bf5423affe2e0e85497607e069e0f45ee8658 100644 GIT binary patch literal 9910 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