From 3428882a5629610fc3785a794cde1b65cfb6ad2c Mon Sep 17 00:00:00 2001 From: Chris Mackey Date: Thu, 27 Jul 2023 14:27:13 -0700 Subject: [PATCH] fix(serialize): Ensure that serialization uses UTF-8 --- .../icon/HB Model to OSM.png | Bin 1514 -> 1515 bytes .../json/HB_Model_to_OSM.json | 4 ++-- .../src/HB Model to OSM.py | 16 +++++++++------- .../user_objects/HB Model to OSM.ghuser | Bin 9719 -> 9779 bytes 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/honeybee_grasshopper_energy/icon/HB Model to OSM.png b/honeybee_grasshopper_energy/icon/HB Model to OSM.png index 984a97b5861692137fd63ba7247bd64983f3fc49..ef49fdb391f5208d00526bf837ac0ec9ed97755b 100644 GIT binary patch delta 1447 zcmV;Y1z7s(3+oGzR)2s=L_t(YOU;#gOjBnV#*Y+XB5fTouk$kI#BC;9;*u@yD(Z%E zlgkvRPGusLiwL!}1&S87DT)ZRl}jm5Y$>;v)+&PF01=THP#|8SSAgP((?frnSmgM5qP4rb z`>IM+^}VLH8S46z$kU%hqUJb4_gV2`rUi4-ELbElV^v-Y;#77hYg(bAd1`$VO7;5j zfq{V$@-k0M{C_GVYY!IST*1hdYv>;w!BGDhl$59uD%HR@wgSv1Bbe>2VA6WwAw36g zSudu@`oM^3>}aRwCOjUi#aekO$}1`{dT|g#BUfN)v4X69SpZe=nx=}3)~m5N-GnU% z8&RmMhrw6}ZH)mL#RjZY7%?-Yo=nZ)iyHBYydEh<4Sy)pH^68#qVR|o8|8;EFH(Yl zs5G?OY`4hTlLb%(&+2Mw;hSn@SIMMyf{C}mC$Ry`;0H^nl2hP`tS*3p1q752u@wkcrm)rcMeo66`VPAe zRDXh6wZdi1Y2w!PmaS^adW`~t_cgTQUI-*2Rf30{x{nMKu3K)%bGlf!YREUmHwOo$SKO~q^^EI``DM#K-1!acs30CikM zYZaKWtq@Ni=)^Osb6C=R3;y|?a0^UDo_|IU>P)%IniCOob86ba#2f)XBIiK`8J|EX zZf9fSZPi0nUC#pe(Yb8yK4CIU3rfRWi2(tX!{DvhiGm8F6CiR~bD|qb2W#!rDR%Hf zWzz|VX}5+*AV{cVTU4;A1m5qYP()^^s`?^tVk@e;ISPhxTU*}j*PB90G^<>oEotg zlUJo;bJk&;IDVYk^T#@y&F1`5`fCyWjq#h8do9OWv0B*xCe94c4BE+}7JnA-DgnHr zKE$NA#aOx}8-^w;ZjO$Q(tE)!i+?71A$F**>+_1nRy?0!2%=DT>IYRiG3owzOPYTB`_x14Kk-K!JFPW-*&=`(w+{nX%2S zK6`sk6KA$%i`yT2k}u6U=R42ud!O@uUzz`#yzk$?{}lcDbAOkQrU^8rlhI2w*3nQn z?|pmp+Him0X@}#>>gwuW>?YIL(1osx&fBAnPN!2zb7BE3q4)kAOb-KSVv+Ob@s_Tx zuB&Qw)%Tj(CaBFPq0*m3lIA$V_S*1bmKC$ptXP;~!Aey#;!7P+*0i9M=Bf3KDAVi5 z`uqEb$;&c6{(q~CtUXzPYX!qsuAy&W7=wLhP*S2sm{bG5xC$^EjbOI5fJy6tr}P|r zWIdQH>jfjBvAvC+oA7v?7Hi~3P+n1qk&6Qu9KHf;vkheJ#{#H=*ECgRv`&ph=_YJG z(11dn83tn=v^54~78|faVZ;ovnM^I*iHX0$-@b zIN$HKXXSmWx%sOXW|Y7c}t=ON5K2VtTK{E!T)

-!n;W2D0fFU%Yz4vjo-T7yhTk}uU0_tzJ^xZ17Su73lY3m2*LUSc%+84_m48ML>P)%YniCQ8a%)<_#2yAeGWS6RnV&!? zX=7vJZPBB&+ROs@F?nq6zTq-V4Nk+H3tGI|@9CM^5Hll#NZB$V%rmT{nT+af6 z-PWAwMv$S=4ra3fld~^S?p6rMgdds-pA{kq;`Q)Ic5okgtAec{fbw5Z*v)p5-x_LX zijB7{83uEs3-G$zniHKz^P3v#zke$-wbIHAV0N5_Ku!_uutAvC!hVzA?}LXTic-LX z+H*#DIu7dUVYivb2r$oW{Xi;}YM#@1xB7(LhNKcJ9@}oh#B}%3k=gkNz!TJ#QzG|Z z(#lk9%07e>$B$Ec{#a+X+g*Q3e=VZFF?REEkM&p!Rw?Vj#9QE%Njq88%zpx2C4hJI zhnVoT1WPvOz|d&J&5@B2dN0In@y|pr#0~a#eqPbgg6DS8QN5uK#k3C=$4Vhsoerg1 zkIr_-4>T`_rgKO0BWNmppM9qrO+QJBOem{ufNY-{7Mlak@!M814|LD_cOs+b?|%K6 zb$Dn9*DhVULDy04NB^xxM;}L*(vOh4`a3bqZ?$s5C)&C 0 and not no_report_meas: # everything must run with OS CLI\n if run_ == 1: # simulate everything at once\n osm, idf = run_osw(osw, measures_only=False, silent=silent)\n sql, zsz, rdd, html, err = output_energyplus_files(os.path.dirname(idf))\n else: # remove reporting measure and give a warning\n m_to_remove = [m.identifier for m in measures if m.type == 'ReportingMeasure']\n with open(osw, 'r') as op:\n osw_data = json.load(op)\n s_to_remove = []\n for i, step in enumerate(osw_data['steps']):\n if step['measure_dir_name'] in m_to_remove:\n s_to_remove.append(i)\n for i in reversed(s_to_remove):\n osw_data['steps'].pop(i)\n with open(osw, 'wb') as fp:\n workflow_str = json.dumps(osw_data, indent=4, ensure_ascii=False)\n fp.write(workflow_str.encode('utf-8'))\n msg = 'The following were reporting measures and were not\\n' \\\n 'included in the OSW to avoid running the simulation:\\n{}'.format(\n '\\n'.join(m_to_remove))\n give_warning(ghenv.Component, msg)\n print(msg)\n osm, idf = run_osw(osw, silent=silent)\n elif run_ > 0: # no reporting measure; simulate separately from measure application\n osm, idf = run_osw(osw, silent=silent)\n # process the additional strings\n if len(add_str_) != 0 and add_str_[0] is not None and idf is not None:\n add_str = '\\n'.join(add_str_)\n with open(idf, \"a\") as idf_file:\n idf_file.write(add_str)\n if idf is None: # measures failed to run correctly; parse out.osw\n log_osw = OSW(os.path.join(directory, 'out.osw'))\n errors = []\n for error, tb in zip(log_osw.errors, log_osw.error_tracebacks):\n if 'Cannot create a surface' in error:\n error = 'Your {{Cad}} Model units system is: {}. ' \\\n 'Is this correct?\\n{}'.format(units_system(), error)\n print(tb)\n errors.append(error)\n raise Exception('Failed to run OpenStudio CLI:\\n{}'.format('\\n'.join(errors)))\n elif run_ in (1, 3): # run the resulting idf throught EnergyPlus\n sql, zsz, rdd, html, err = run_idf(idf, _epw_file, silent=silent)\n\n # parse the error log and report any warnings\n if run_ in (1, 3) and err is not None:\n err_obj = Err(err)\n print(err_obj.file_contents)\n for warn in err_obj.severe_errors:\n give_warning(ghenv.Component, warn)\n for error in err_obj.fatal_errors:\n raise Exception(error)\n", + "code": "\nimport sys\nimport os\nimport re\nimport json\n\ntry:\n from ladybug.futil import preparedir, nukedir\n from ladybug.epw import EPW\nexcept ImportError as e:\n raise ImportError('\\nFailed to import ladybug:\\n\\t{}'.format(e))\n\ntry:\n import honeybee.config as hb_config\nexcept ImportError as e:\n raise ImportError('\\nFailed to import honeybee:\\n\\t{}'.format(e))\n\ntry:\n from honeybee_energy.simulation.parameter import SimulationParameter\n from honeybee_energy.run import to_openstudio_osw, run_osw, run_idf, \\\n output_energyplus_files\n from honeybee_energy.result.err import Err\n from honeybee_energy.result.osw import 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, give_warning\n from ladybug_{{cad}}.config import units_system\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 _write:\n # check the presence of openstudio and check that the version is compatible\n check_openstudio_version()\n\n # process the simulation parameters\n if _sim_par_ is None:\n _sim_par_ = SimulationParameter()\n _sim_par_.output.add_zone_energy_use()\n _sim_par_.output.add_hvac_energy_use()\n else:\n _sim_par_ = _sim_par_.duplicate() # ensure input is not edited\n\n # assign design days from the DDY next to the EPW if there are None\n if len(_sim_par_.sizing_parameter.design_days) == 0:\n msg = None\n folder, epw_file_name = os.path.split(_epw_file)\n ddy_file = os.path.join(folder, epw_file_name.replace('.epw', '.ddy'))\n if os.path.isfile(ddy_file):\n try:\n _sim_par_.sizing_parameter.add_from_ddy_996_004(ddy_file)\n except AssertionError:\n msg = 'No ddy_file_ was input into the _sim_par_ sizing ' \\\n 'parameters\\n and no design days were found in the .ddy file '\\\n 'next to the _epw_file.'\n else:\n msg = 'No ddy_file_ was input into the _sim_par_ sizing parameters\\n' \\\n 'and no .ddy file was found next to the _epw_file.'\n if msg is not None:\n epw_obj = EPW(_epw_file)\n des_days = [epw_obj.approximate_design_day('WinterDesignDay'),\n epw_obj.approximate_design_day('SummerDesignDay')]\n _sim_par_.sizing_parameter.design_days = des_days\n msg = msg + '\\nDesign days were generated from the input _epw_file but this ' \\\n '\\nis not as accurate as design days from DDYs distributed with the EPW.'\n give_warning(ghenv.Component, msg)\n print(msg)\n\n # process the simulation folder name and the directory\n _folder_ = hb_config.folders.default_simulation_folder if _folder_ is None else _folder_\n clean_name = re.sub(r'[^.A-Za-z0-9_-]', '_', _model.display_name)\n directory = os.path.join(_folder_, clean_name, 'openstudio')\n\n # duplicate model to avoid mutating it as we edit it for energy simulation\n _model = _model.duplicate()\n # scale the model if the units are not meters\n if _model.units != 'Meters':\n _model.convert_to_units('Meters')\n # remove degenerate geometry within native E+ tolerance of 0.01 meters\n try:\n _model.remove_degenerate_geometry(0.01)\n except ValueError:\n error = 'Failed to remove degenerate Rooms.\\nYour Model units system is: {}. ' \\\n 'Is this correct?'.format(units_system())\n raise ValueError(error)\n\n # auto-assign stories if there are none since most OpenStudio measures need these\n if len(_model.stories) == 0 and len(_model.rooms) != 0:\n _model.assign_stories_by_floor_height()\n\n # delete any existing files in the directory and prepare it for simulation\n nukedir(directory, True)\n preparedir(directory)\n sch_directory = os.path.join(directory, 'schedules')\n preparedir(sch_directory)\n\n # write the model parameter JSONs\n model_dict = _model.to_dict(triangulate_sub_faces=True)\n _model.properties.energy.add_autocal_properties_to_dict(model_dict)\n model_json = os.path.join(directory, '{}.hbjson'.format(clean_name))\n if (sys.version_info < (3, 0)): # we need to manually encode it as UTF-8\n with open(model_json, 'wb') as fp:\n model_str = json.dumps(model_dict, indent=4, ensure_ascii=False)\n fp.write(model_str.encode('utf-8'))\n else:\n with open(model_json, 'w', encoding='utf-8') as fp:\n model_str = json.dump(model_dict, fp, indent=4, ensure_ascii=False)\n\n # write the simulation parameter JSONs\n sim_par_dict = _sim_par_.to_dict()\n sim_par_json = os.path.join(directory, 'simulation_parameter.json')\n with open(sim_par_json, 'w') as fp:\n json.dump(sim_par_dict, fp)\n\n # process any measures input to the component\n measures = None if len(measures_) == 0 or measures_[0] is None else measures_\n no_report_meas = True if measures is None else \\\n all(meas.type != 'ReportingMeasure' for meas in measures)\n str_inject = None if no_report_meas or add_str_ == [] or add_str_[0] is None \\\n else '\\n'.join(add_str_)\n\n # collect the two jsons for output and write out the osw file\n jsons = [model_json, sim_par_json]\n osw = to_openstudio_osw(\n directory, model_json, sim_par_json, additional_measures=measures,\n epw_file=_epw_file, schedule_directory=sch_directory,\n strings_to_inject=str_inject)\n\n # run the measure to translate the model JSON to an openstudio measure\n silent = True if run_ == 3 else False\n if run_ > 0 and not no_report_meas: # everything must run with OS CLI\n if run_ == 1: # simulate everything at once\n osm, idf = run_osw(osw, measures_only=False, silent=silent)\n sql, zsz, rdd, html, err = output_energyplus_files(os.path.dirname(idf))\n else: # remove reporting measure and give a warning\n m_to_remove = [m.identifier for m in measures if m.type == 'ReportingMeasure']\n with open(osw, 'r') as op:\n osw_data = json.load(op)\n s_to_remove = []\n for i, step in enumerate(osw_data['steps']):\n if step['measure_dir_name'] in m_to_remove:\n s_to_remove.append(i)\n for i in reversed(s_to_remove):\n osw_data['steps'].pop(i)\n with open(osw, 'wb') as fp:\n workflow_str = json.dumps(osw_data, indent=4, ensure_ascii=False)\n fp.write(workflow_str.encode('utf-8'))\n msg = 'The following were reporting measures and were not\\n' \\\n 'included in the OSW to avoid running the simulation:\\n{}'.format(\n '\\n'.join(m_to_remove))\n give_warning(ghenv.Component, msg)\n print(msg)\n osm, idf = run_osw(osw, silent=silent)\n elif run_ > 0: # no reporting measure; simulate separately from measure application\n osm, idf = run_osw(osw, silent=silent)\n # process the additional strings\n if len(add_str_) != 0 and add_str_[0] is not None and idf is not None:\n add_str = '\\n'.join(add_str_)\n with open(idf, \"a\") as idf_file:\n idf_file.write(add_str)\n if idf is None: # measures failed to run correctly; parse out.osw\n log_osw = OSW(os.path.join(directory, 'out.osw'))\n errors = []\n for error, tb in zip(log_osw.errors, log_osw.error_tracebacks):\n if 'Cannot create a surface' in error:\n error = 'Your {{Cad}} Model units system is: {}. ' \\\n 'Is this correct?\\n{}'.format(units_system(), error)\n print(tb)\n errors.append(error)\n raise Exception('Failed to run OpenStudio CLI:\\n{}'.format('\\n'.join(errors)))\n elif run_ in (1, 3): # run the resulting idf throught EnergyPlus\n sql, zsz, rdd, html, err = run_idf(idf, _epw_file, silent=silent)\n\n # parse the error log and report any warnings\n if run_ in (1, 3) and err is not None:\n err_obj = Err(err)\n print(err_obj.file_contents)\n for warn in err_obj.severe_errors:\n give_warning(ghenv.Component, warn)\n for error in err_obj.fatal_errors:\n raise Exception(error)\n", "category": "HB-Energy", "name": "HB Model to OSM", "description": "Write a honeybee Model to an OSM file (OpenStudio Model), which can then be translated\nto an IDF file and then run through EnergyPlus.\n-" diff --git a/honeybee_grasshopper_energy/src/HB Model to OSM.py b/honeybee_grasshopper_energy/src/HB Model to OSM.py index 940313c6..9e3baa04 100644 --- a/honeybee_grasshopper_energy/src/HB Model to OSM.py +++ b/honeybee_grasshopper_energy/src/HB Model to OSM.py @@ -74,11 +74,12 @@ ghenv.Component.Name = 'HB Model to OSM' ghenv.Component.NickName = 'ModelToOSM' -ghenv.Component.Message = '1.6.3' +ghenv.Component.Message = '1.6.4' ghenv.Component.Category = 'HB-Energy' ghenv.Component.SubCategory = '5 :: Simulate' ghenv.Component.AdditionalHelpFromDocStrings = '1' +import sys import os import re import json @@ -185,12 +186,13 @@ model_dict = _model.to_dict(triangulate_sub_faces=True) _model.properties.energy.add_autocal_properties_to_dict(model_dict) model_json = os.path.join(directory, '{}.hbjson'.format(clean_name)) - try: - with open(model_json, 'w') as fp: - json.dump(model_dict, fp) - except UnicodeDecodeError: # non-unicode character in display_name - with open(model_json, 'w') as fp: - json.dump(model_dict, fp, ensure_ascii=False) + if (sys.version_info < (3, 0)): # we need to manually encode it as UTF-8 + with open(model_json, 'wb') as fp: + model_str = json.dumps(model_dict, indent=4, ensure_ascii=False) + fp.write(model_str.encode('utf-8')) + else: + with open(model_json, 'w', encoding='utf-8') as fp: + model_str = json.dump(model_dict, fp, indent=4, ensure_ascii=False) # write the simulation parameter JSONs sim_par_dict = _sim_par_.to_dict() diff --git a/honeybee_grasshopper_energy/user_objects/HB Model to OSM.ghuser b/honeybee_grasshopper_energy/user_objects/HB Model to OSM.ghuser index 826c09285610fbd105d79a1ab8ad2e08ff588732..c5ffdf46b13ba96bab6f2b2d7ea22c826f1b7117 100644 GIT binary patch literal 9779 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