{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tutorial - The Preamble" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Author(s):** Santosh Philip" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We am using this tutorial/documentation as a way of identifying alformed API and gaps in the software. When eppy was developed, writing the user documentation forced us to rewrite the software. This documentation is written with the same intent. It is a little easier in the case of `eppy3000`, since we are trying to mimic `eppy` using it as a starting point.\n", "\n", "Any places where the word `TODO` occurs is where we find some recoding has to be done. An issue has to be opened and then resolved." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Start with Eppy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We are now at E+ version 9.3. If you install E+ version 9.3, you will find only one epJSON file in the installation. All the files are IDF files. So how do we work with and explore eppy300 and epJSON ?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We will have to read the IDF file, convert it to epJSON and then work with it. The key is to do the conversion from IDF to epJSON. There are two ways of doing this:\n", "\n", "1. import eppy. Read the IDF using eppy and then do the conversion\n", "2. Use eppy3000 to directly convert IDF to epJSON. Don't use eppy at all" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Convert to epJSON *with* eppy" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# you would normaly install eppy by doing\n", "# python setup.py install\n", "# or\n", "# pip install eppy\n", "# or\n", "# easy_install eppy\n", "\n", "# if you have not done so, uncomment the following three lines\n", "import sys\n", "# pathnameto_eppy = 'c:/eppy3000'\n", "pathnameto_eppy3000 = '../'\n", "sys.path.append(pathnameto_eppy3000)\n", "\n", "import eppy" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "VERSION,\n", " 9.3; !- Version Identifier\n", "\n", "SIMULATIONCONTROL,\n", " Yes, !- Do Zone Sizing Calculation\n", " Yes, !- Do System Sizing Calculation\n", " Yes, !- Do Plant Sizing Calculation\n", " No, !- Run Simulation for Sizing Periods\n", " Yes; !- Run Simulation for Weather File Run Periods\n", "\n", "BUILDING,\n", " Empire State Building, !- Name\n", " 30, !- North Axis\n", " City, !- Terrain\n", " 0.04, !- Loads Convergence Tolerance Value\n", " 0.4, !- Temperature Convergence Tolerance Value\n", " FullExterior, !- Solar Distribution\n", " 25, !- Maximum Number of Warmup Days\n", " 6; !- Minimum Number of Warmup Days\n", "\n", "SITE:LOCATION,\n", " CHICAGO_IL_USA TMY2-94846, !- Name\n", " 41.78, !- Latitude\n", " -87.75, !- Longitude\n", " -6, !- Time Zone\n", " 190; !- Elevation\n", "\n" ] } ], "source": [ "fname = \"../eppy3000/resources/snippets/V9_3/smallfile.idf\"\n", "weatherfile = \"../eppy3000/resources/weatherfiles/USA_CA_San.Francisco.Intl.AP.724940_TMY3.epw\"\n", "idf = eppy.openidf(fname, epw=weatherfile) # needs a weather file to work. TODO: open an issue and fix this\n", "idf.printidf()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Looks good. Now we need to convert it" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "import eppy3000.oldeppy as oldeppy\n", "epschema = '../eppy3000/resources/schema/V9_3/Energy+.schema.epJSON'\n", "epj = oldeppy.idf2epj(idf, open(epschema, 'r'))\n", "\n", "#TODO: would be nice to have the code find the schema file in the E+ installation.\n", "# Like how eppy2000.openidf() does" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us print this `epj` and see what it looks like" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Version !- EP_KEY # use .eppykey\n", " Version 1 !- EPJOBJECT_NAME # use .eppyname\n", " 9.3 !- version_identifier\n", " 1 !- idf_order\n", "\n", "SimulationControl !- EP_KEY # use .eppykey\n", " SimulationControl 1 !- EPJOBJECT_NAME # use .eppyname\n", " Yes !- do_zone_sizing_calculation\n", " Yes !- do_system_sizing_calculation\n", " Yes !- do_plant_sizing_calculation\n", " No !- run_simulation_for_sizing_periods\n", " Yes !- run_simulation_for_weather_file_run_periods\n", " 2 !- idf_order\n", "\n", "Building !- EP_KEY # use .eppykey\n", " Empire State Building !- EPJOBJECT_NAME # use .eppyname\n", " 30 !- north_axis\n", " City !- terrain\n", " 0.04 !- loads_convergence_tolerance_value\n", " 0.4 !- temperature_convergence_tolerance_value\n", " FullExterior !- solar_distribution\n", " 25 !- maximum_number_of_warmup_days\n", " 6 !- minimum_number_of_warmup_days\n", " 3 !- idf_order\n", "\n", "Site:Location !- EP_KEY # use .eppykey\n", " CHICAGO_IL_USA TMY2-94846 !- EPJOBJECT_NAME # use .eppyname\n", " 41.78 !- latitude\n", " -87.75 !- longitude\n", " -6 !- time_zone\n", " 190 !- elevation\n", " 4 !- idf_order\n" ] } ], "source": [ "print(epj)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Thats weird . I looks like the idf file. Shouldn't it look like the JSON ?\n", "\n", "Good point. The actual JSON in `epj` looks different. Let us take a look at that" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"Version\": {\n", " \"Version 1\": {\n", " \"version_identifier\": \"9.3\",\n", " \"idf_order\": 1\n", " }\n", " },\n", " \"SimulationControl\": {\n", " \"SimulationControl 1\": {\n", " \"do_zone_sizing_calculation\": \"Yes\",\n", " \"do_system_sizing_calculation\": \"Yes\",\n", " \"do_plant_sizing_calculation\": \"Yes\",\n", " \"run_simulation_for_sizing_periods\": \"No\",\n", " \"run_simulation_for_weather_file_run_periods\": \"Yes\",\n", " \"idf_order\": 2\n", " }\n", " },\n", " \"Building\": {\n", " \"Empire State Building\": {\n", " \"north_axis\": 30,\n", " \"terrain\": \"City\",\n", " \"loads_convergence_tolerance_value\": 0.04,\n", " \"temperature_convergence_tolerance_value\": 0.4,\n", " \"solar_distribution\": \"FullExterior\",\n", " \"maximum_number_of_warmup_days\": 25,\n", " \"minimum_number_of_warmup_days\": 6,\n", " \"idf_order\": 3\n", " }\n", " },\n", " \"Site:Location\": {\n", " \"CHICAGO_IL_USA TMY2-94846\": {\n", " \"latitude\": 41.78,\n", " \"longitude\": -87.75,\n", " \"time_zone\": -6,\n", " \"elevation\": 190,\n", " \"idf_order\": 4\n", " }\n", " }\n", "}\n" ] } ], "source": [ " print(epj.jsonstr())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So why are you printing it to look like an IDF file. \n", "\n", "Couple of reasons:\n", "\n", "1. It is was easier to do the development with epj expressed in the IDF format.\n", " - Note that there are some extra fields in the idf format that are not there in the JSON format.\n", " - One of them is `EP_KEY`\n", " - the other is `EPJOBJECT_NAME`\n", " - These fields are used internally by eppy3000\n", " - epJSON allows you to add your own fields. A very useful attribute\n", " - Any field name that starts with `EP` will be used internally by eppy3000 and will be displayed\n", " - Any field name that starts with `eppy_` will be used internally by eppy3000, but will not be displayed in the print (these are hidden fields, that the user does not need to see)\n", "2. The second reason, is that the JSON fromat is not as **human readable** as it claims to be. At least not for most humans :-). \n", " - as an example see this link https://marianoguerra.github.io/json.human.js/\n", " - Presenting it in the IDF fromat makes it clearer\n", " \n", "It is not clear if this is the best pathway to take. But it is useful for the moment. So we are going to stick with it until something better comes along" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### EPJ schema" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With the IDF file, we also have the IDD file that holds the structure of the IDF file. In eppy we can access IDD file. What happens in epJSON file in EPJ\n", "\n", "Let us get to the fieldnames of `Building` object as seen by the schema" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# building_fieldnames = epj.epschema.epschemaobjects['Building'].fieldnames()\n", "#\n", "# There is bug that does not capture the epschema \n", "# happens when idf2epj is used \n", "# this is a TODO: open an issue on it\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Convert to epJSON *with* eppy (in one line)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Version !- EP_KEY # use .eppykey\n", " Version 1 !- EPJOBJECT_NAME # use .eppyname\n", " 9.3 !- version_identifier\n", " 1 !- idf_order\n", "\n", "SimulationControl !- EP_KEY # use .eppykey\n", " SimulationControl 1 !- EPJOBJECT_NAME # use .eppyname\n", " Yes !- do_zone_sizing_calculation\n", " Yes !- do_system_sizing_calculation\n", " Yes !- do_plant_sizing_calculation\n", " No !- run_simulation_for_sizing_periods\n", " Yes !- run_simulation_for_weather_file_run_periods\n", " 2 !- idf_order\n", "\n", "Building !- EP_KEY # use .eppykey\n", " Empire State Building !- EPJOBJECT_NAME # use .eppyname\n", " 30 !- north_axis\n", " City !- terrain\n", " 0.04 !- loads_convergence_tolerance_value\n", " 0.4 !- temperature_convergence_tolerance_value\n", " FullExterior !- solar_distribution\n", " 25 !- maximum_number_of_warmup_days\n", " 6 !- minimum_number_of_warmup_days\n", " 3 !- idf_order\n", "\n", "Site:Location !- EP_KEY # use .eppykey\n", " CHICAGO_IL_USA TMY2-94846 !- EPJOBJECT_NAME # use .eppyname\n", " 41.78 !- latitude\n", " -87.75 !- longitude\n", " -6 !- time_zone\n", " 190 !- elevation\n", " 4 !- idf_order\n" ] } ], "source": [ "import eppy3000.experimental.openidf\n", "\n", "fname = \"../eppy3000/resources/snippets/V9_3/smallfile.idf\"\n", "wfile = \"../eppy3000/resources/weatherfiles/USA_CA_San.Francisco.Intl.AP.724940_TMY3.epw\"\n", "epj = eppy3000.experimental.openidf.openidf(fname, wfile)\n", "\n", "print(epj)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Convert to epJSON *without* eppy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you simply want to convert a file" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The epj file is saved at: ../eppy3000/resources/snippets/V9_3/smallfile.epJSON\n" ] } ], "source": [ "import eppy3000.idfjsonconverter as idfjsonconverter\n", "\n", "idffilename = \"../eppy3000/resources/snippets/V9_3/smallfile.idf\"\n", "schemapath = \"../eppy3000/resources/schema/V9_3/Energy+.schema.epJSON\"\n", "\n", "epjfilename = idfjsonconverter.idffile2epjfile(idffilename, schemapath=schemapath)\n", "print(f'The epj file is saved at: {epjfilename}')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Usually you can call it by ``idfjsonconverter.idffile2epjfile(idffilename(idffilename)``\n", "You don't need to give it the schema name. It will find the schema file by searching in the usual install locations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us read the epJSON file and see if it actually happened. Yes! It worked - the file looks good" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{\n", " \"Version\": {\n", " \"Version 1\": {\n", " \"version_identifier\": \"9.3\",\n", " \"idf_order\": 1\n", " }\n", " },\n", " \"SimulationControl\": {\n", " \"SimulationControl 1\": {\n", " \"do_zone_sizing_calculation\": \"Yes\",\n", " \"do_system_sizing_calculation\": \"Yes\",\n", " \"do_plant_sizing_calculation\": \"Yes\",\n", " \"run_simulation_for_sizing_periods\": \"No\",\n", " \"run_simulation_for_weather_file_run_periods\": \"Yes\",\n", " \"idf_order\": 2\n", " }\n", " },\n", " \"Building\": {\n", " \"Empire State Building\": {\n", " \"north_axis\": 30,\n", " \"terrain\": \"City\",\n", " \"loads_convergence_tolerance_value\": 0.04,\n", " \"temperature_convergence_tolerance_value\": 0.4,\n", " \"solar_distribution\": \"FullExterior\",\n", " \"maximum_number_of_warmup_days\": 25,\n", " \"minimum_number_of_warmup_days\": 6,\n", " \"idf_order\": 3\n", " }\n", " },\n", " \"Site:Location\": {\n", " \"CHICAGO_IL_USA TMY2-94846\": {\n", " \"latitude\": 41.78,\n", " \"longitude\": -87.75,\n", " \"time_zone\": -6,\n", " \"elevation\": 190,\n", " \"idf_order\": 4\n", " }\n", " }\n", "}\n" ] } ], "source": [ "print(open(epjfilename, 'r').read())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that we have the epJSON file, Let us open it using eppy3000 and look at it." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from eppy3000.modelmaker import EPJ\n", "epj = EPJ(epjfilename)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Version !- EP_KEY # use .eppykey\n", " Version 1 !- EPJOBJECT_NAME # use .eppyname\n", " 9.3 !- version_identifier\n", " 1 !- idf_order\n", "\n", "SimulationControl !- EP_KEY # use .eppykey\n", " SimulationControl 1 !- EPJOBJECT_NAME # use .eppyname\n", " Yes !- do_zone_sizing_calculation\n", " Yes !- do_system_sizing_calculation\n", " Yes !- do_plant_sizing_calculation\n", " No !- run_simulation_for_sizing_periods\n", " Yes !- run_simulation_for_weather_file_run_periods\n", " 2 !- idf_order\n", "\n", "Building !- EP_KEY # use .eppykey\n", " Empire State Building !- EPJOBJECT_NAME # use .eppyname\n", " 30 !- north_axis\n", " City !- terrain\n", " 0.04 !- loads_convergence_tolerance_value\n", " 0.4 !- temperature_convergence_tolerance_value\n", " FullExterior !- solar_distribution\n", " 25 !- maximum_number_of_warmup_days\n", " 6 !- minimum_number_of_warmup_days\n", " 3 !- idf_order\n", "\n", "Site:Location !- EP_KEY # use .eppykey\n", " CHICAGO_IL_USA TMY2-94846 !- EPJOBJECT_NAME # use .eppyname\n", " 41.78 !- latitude\n", " -87.75 !- longitude\n", " -6 !- time_zone\n", " 190 !- elevation\n", " 4 !- idf_order\n" ] } ], "source": [ "print(epj)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Convert all IDF files in a folder to epJSON" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sometimes you want to convert all the idf files in a folder. You can use ``idffolder2epjfolder`` to do that" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "import eppy3000.idfjsonconverter as idfjsonconverter\n", "\n", "startfolder = \"./eppy3000/resources/snippets/V9_3\"\n", "schemapath = \"../eppy3000/resources/schema/V9_3/Energy+.schema.epJSON\"\n", "\n", "idfjsonconverter.idffolder2epjfolder(startfolder, schemapath=schemapath) \n", "# You don't need to use schemapath if you have Energyplus installed" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The files are saved in the same folder as the IDF files. You can also save them in a different folder. See the documentation of ``idffolder2epjfolder`` below" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Convert all the idf files in idffolder into epj files and save them in epjfolder\n", "\n", " The function finds the idf files by searching for the all files in the idffolder that have the extension 'idf'. This extension can be overridden by giving a value to idfext\n", "\n", " Parameters\n", " ----------\n", " idffolder: str, pathlib.Path\n", " This is the folder with the idf files\n", " epjfolder: str, pathlib.Path\n", " This is the folder where you want to store the generated epj files. When epjfolder=None, the epj files are saved in the idffolder\n", " idfext: str\n", " This is the extension of the idf files. Default value is `idf`\n", " epjext: str\n", " This is the extension of the epj files. Default value is `epJSON`\n", " schemapath: str, pathlib.Path\n", " path to Energy+.schema.epJSON usuallty found in the install location of EnergyPlus. If schemapah=None, the function will attempt to find the schema path in the standard install locations\n", " verbose: Boolean\n", " When verbose=True, it will print file names on screen. The default for verbose is False\n", "\n", " Returns\n", " -------\n", " None\n", " \n", "\n" ] } ], "source": [ "# def idffolder2epjfolder(\n", "# idffolder, epjfolder=None, idfext=None, epjext=None, schemapath=None, verbose=False\n", "# ):\n", "print(idfjsonconverter.idffolder2epjfolder.__doc__)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Opening a file without the schema (IDD)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Eppy3000 lets you open the `epJSON` as `EPJ` file without refering to the `schema.epJSON`. The code in the previous section does exactly that. A lot of functionality is avaliable without the schema. There are use cases for this, where you you want to quickly make some changes to `epj` and don't have access to the schema.\n", "\n", "TODO: It is not explicit in the API whether the schema is read or not. One way to make it explicit is to force the user to enter the arg for the schema. If the arg is None: no schema is read; else: the schema is read" ] } ], "metadata": { "celltoolbar": "Raw Cell Format", "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.8" } }, "nbformat": 4, "nbformat_minor": 4 }