Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update documentation for version 0.6.0 #592

Merged
merged 11 commits into from
Jan 4, 2024
3 changes: 3 additions & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"language": "en",
"words": [
"autoload",
"borefield",
"buildingspy",
"Combi",
"cvrmsd",
Expand All @@ -12,8 +13,10 @@
"endraw",
"energyplus",
"GDHC",
"gfunction",
"HVAC",
"IBPSA",
"interconnectivity",
"Jing",
"levelname",
"libfortran",
Expand Down
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<!--Fill in the following information detailing the issue. Make sure to not disclose protected data (e.g. passwords). Screenshots are helpful.-->
<!--Fill in the following information detailing the issue. Make sure to not disclose protected data (e.g., passwords). Screenshots are helpful.-->

### Expected Behavior

Expand Down
2 changes: 1 addition & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ Version 0.5.0
Version 0.4.1
-------------
## What's Changed
* Cli bugfixing
* Cli bug fixes
* Detailed models
* End-of-year updates to GMT docs
* Remove support for 3.7 in development, update development dependencies
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
URBANopt™, Copyright (c) 2019, 2023 Alliance for Sustainable Energy, LLC, and other contributors.
URBANopt™, Copyright (c) 2019, 2024 Alliance for Sustainable Energy, LLC, and other contributors.
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted
Expand Down
84 changes: 18 additions & 66 deletions docs/developer_resources.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ GMT has "building blocks" that it uses to define and connect models, which curre

Each block type is a collection of models, e.g. the Loads includes time series and spawn models. A model in GMT refers to an abstracted Modelica model. It generates Modelica code (the Modelica model) and is used to define connections to other models.

Each block type can "connect" (note this "connect" does not refer to Modelica's concept of "connect") to other specific block types. For example, you can connect a load to an ETS, but you cannot connect a load to a network.
Each block type can "connect" (note this "connect" does not refer to Modelica's concept of "connect") to other specific block types. For example, you can connect a load to an ETS, but you cannot connect a load to a network. However, some models (i.e. 5G) have an ETS embedded in them.

Each block type has a corresponding directory inside of :code:`geojson_modelica_translator/model_connectors`, which contains its different model types (e.g. for Loads it contains the Time Series model and others).

Expand All @@ -58,44 +58,42 @@ to follow the detailed instructions for :ref:`Docker Installation` in the Gettin

Follow the instructions below in order to configure your local environment:

* If you need a custom Modelica Buildings Library:
* Clone the `MBL <https://github.com/lbl-srg/modelica-buildings>`_ into a working directory outside of the GMT directory
* Ensure your MODELICAPATH env var is set to the MBL you want to use! See the documentation at :ref:`MBL Installation`
* Change to the directory inside the modelica-buildings repo you just checked out. (:code:`cd modelica-buildings`)
* Install git-lfs
* Mac: :code:`brew install git-lfs; git lfs install`
* Ubuntu: :code:`sudo apt install git-lfs; git lfs install`
* The current GMT code works with the :code:`maint_9.1.x` branch of the MBL. GMT version :code:`0.2.3`, which uses JModelica, requires the :code:`issue2204_gmt_mbl` branch of the MBL.
* Get the Modelica Buildings Library. See the documentation at :ref:`MBL Installation`

* Clone `the GMT repo <https://github.com/urbanopt/geojson-modelica-translator>`_ into a working directory
* (optional/as-needed) Add Python 3 to the environment variables
* For developers, dependency management is through `Poetry`_. Installation is accomplished by running :code:`pip install poetry`.
* Return to the GMT root directory and run :code:`poetry install`
* Test if everything is installed correctly by running :code:`poetry run pytest -m 'not compilation and not simulation'`. This will run all the unit and integration tests.
* (optional/as-needed) Add Python 3 to the environment variables
* As general guidance, we recommend using virtual environments to avoid dependencies colliding between your Python projects. `venv <https://docs.python.org/3/library/venv.html>`_ is the Python native solution that will work everywhere, though other options may be more user-friendly.
* Some popular alternatives are:
* `pyenv <https://github.com/pyenv/pyenv>`_ and `the virtualenv plugin <https://github.com/pyenv/pyenv-virtualenv>`_ work together nicely for Linux/Mac machines
* `virtualenv <https://virtualenv.pypa.io/en/latest/>`_
* `miniconda <https://docs.conda.io/projects/miniconda/en/latest/>`_
* For developers, dependency management is through `Poetry`_. Poetry can be acquired by running :code:`pip install poetry`.
* If you haven't already installed a virtual environment, Poetry will automatically create a simplified environment for your project.
* Move to the GMT root directory and run :code:`poetry install` to install the dependencies.
* Verify that everything is installed correctly by running :code:`poetry run pytest -m 'not compilation and not simulation and not dymola'`. This will run all the unit and integration tests.
* Follow the instructions below to install pre-commit.
* To test pre-commit and building the documentation, you can run

.. code-block::

poetry install
poetry run pytest -m 'not compilation and not simulation' --doctest-modules -v --cov-report term-missing --cov .
poetry run pytest -m 'not compilation and not simulation and not dymola' --doctest-modules -v --cov-report term-missing --cov .
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sweet... now it is just simulation!


The tests should all pass assuming the libraries are installed correctly on your computer. Also, there will be a set
of Modelica models that are created and persisted into the :code:`tests/output` folder and the
The tests should all pass assuming the libraries, Docker, and all dependencies are installed correctly on your computer. Also, there will be a set
of Modelica models that are created and persisted into the :code:`tests/GMT_Lib/output` folder and the
:code:`tests/model_connectors/output` folder. These files can be inspected in your favorite Modelica editor.

Pre-commit
**********

This project uses `pre-commit <https://pre-commit.com/>`_ to ensure code consistency.
To enable pre-commit on every commit run the following from the command line from within the git checkout of the
To enable pre-commit for your local development process, run the following from the command line from within the git checkout of the
GMT:

.. code-block:: bash

pre-commit install

To run pre-commit against the files without calling git commit, then run the following. This is useful when cleaning up the repo before committing.
To run pre-commit against the files without calling git commit, then run the following. This is useful when cleaning up the repo before committing. CI will fail if pre-commit hasn't been run locally.

.. code-block:: bash

Expand Down Expand Up @@ -217,53 +215,7 @@ simulation mapper class from existing at that level.
Running Simulations
-------------------

The GeoJSON to Modelica Translator contains a :code:`ModelicaRunner.run_in_docker(...)` method. It is recommended
to use this method in a python script as it will copy the required files into the correct location. If
desired, a user can run the simulations manually using JModelica (via Docker). Follow the steps below to configure
the runner to work locally.

* Make sure jm_ipython.sh is in your local path.
* After running the :code:`pytest`, go into the :code:`geojson_modelica_translator/modelica/lib/runner/` directory.
* Copy :code:`jmodelica.py` to the :code:`tests/model_connectors/output` directory.
* From the :code:`tests/model_connectors/output` directory, run examples using either of the the following:
* :code:`jm_ipython.sh jmodelica.py spawn_single.Loads.B5a6b99ec37f4de7f94020090.coupling`
* :code:`jm_ipython.sh jmodelica.py spawn_single/Loads/B5a6b99ec37f4de7f94020090/coupling.mo`
* The warnings from the simulations can be ignored. A successful simulation will return Final Run Statistics.
* Install matplotlib package. :code:`pip install matplotlib`
* Visualize the results by inspecting the resulting mat file using BuildingsPy. Run this from the root directory of the GMT.

.. code-block:: python
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i will miss this code, but it needs to go...


%matplotlib inline
import os
import matplotlib.pyplot as plt

from buildingspy.io.outputfile import Reader

mat = Reader(os.path.join(
"tests", "model_connectors", "output", "spawn_single_Loads_B5a6b99ec37f4de7f94020090_coupling_result.mat"),
"dymola"
)
# List off all the variables
for var in mat.varNames():
print(var)

(time1, zn_1_temp) = mat.values("bui.znPerimeter_ZN_3.TAir")
(_time1, zn_4_temp) = mat.values("bui.znPerimeter_ZN_4.TAir")
plt.style.use('seaborn-whitegrid')

fig = plt.figure(figsize=(16, 8))
ax = fig.add_subplot(211)
ax.plot(time1 / 3600, zn_1_temp - 273.15, 'r', label='$T_1$')
ax.plot(time1 / 3600, zn_4_temp - 273.15, 'b', label='$T_4$')
ax.set_xlabel('time [h]')
ax.set_ylabel(r'temperature [$^\circ$C]')
# Simulation is only for 168 hours?
ax.set_xlim([0, 168])
ax.legend()
ax.grid(True)
fig.savefig('indoor_temp_example.png')

The GeoJSON to Modelica Translator contains a :code:`ModelicaRunner.run_in_docker(...)` method. The test suite uses this to run most of our models with OpenModelica.

Release Instructions
--------------------
Expand Down
31 changes: 17 additions & 14 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ There are three major steps to running the GeoJSON to Modelica Translator (GMT):
Depending on the use case, the need to run all the steps above may not be needed. For example:
it may be desirable to only generate the Modelica package and then open and run the model
in a Modelica user interface such as Dymola. Or, there may be a case to simply generate the
GeoJSON and System Parameter file from results of an URBANopt SDK simulation result set.
System Parameter file from results of an URBANopt SDK simulation. These files can then be
customized by hand to build a district system to meet your needs.

This Getting Started guide is broken up into three major setup steps:
Therefore, this Getting Started guide is broken up into three major setup steps. Each one requires all previous steps to be completed first.

#. Installing the GMT from PyPi
#. Installing and configuring the Modelica Buildings Library (MBL)
Expand All @@ -23,7 +24,7 @@ This Getting Started guide is broken up into three major setup steps:
GMT Installation
----------------

You must have PIP and Python 3.7 or later installed (run :code:`python --version` to see what version you're using). After installing Python and PIP run the following in a terminal (requires Python 3):
You must have PIP and Python 3.9 or later installed (run :code:`python --version` to see what version you're using). After installing Python and PIP run the following in a terminal:

.. code-block:: bash

Expand All @@ -43,10 +44,13 @@ After installation of the GMT, a new command line interface (called the URBANopt
MBL Installation
----------------

The Modelica Buildings Library contains many models that are needed to assemble the district systems. Installation of the MBL is done through Git and GitHub. Follow the instructions below to install the MBL needed for the GMT:
The Modelica Buildings Library contains many models that are needed to assemble the district systems. Follow the instructions below to install the MBL needed for the GMT:

* Download and extract the newest 9.1 version of the MBL from `<https://simulationresearch.lbl.gov/modelica/downloads/archive/modelica-buildings.html>`_
* Add the Modelica Buildings Library path to your MODELICAPATH environment variable (e.g., export MODELICAPATH=${MODELICAPATH}:$HOME/path/to/modelica-buildings). Restart your terminal to ensure that the MBL library is exported correctly.
* Download and extract the appropriate version of the MBL from `<https://simulationresearch.lbl.gov/modelica/downloads/archive/modelica-buildings.html>`_
* The appropriate version can be found in the right-hand column of the `installer matrix <https://docs.urbanopt.net/developer_resources/compatibility_matrix.html#urbanopt-installer-matrix>`_.
* Add the Modelica Buildings Library path to your MODELICAPATH environment variable (e.g., :code:`export MODELICAPATH=${MODELICAPATH}:$HOME/path/to/modelica-buildings`).
* For help setting env vars on Windows, this documentation may help: `<https://www.howtogeek.com/787217/how-to-edit-environment-variables-on-windows-10-or-11/>`_
* Restart your terminal to ensure that the environment variable for the MBL library is exported correctly.

Once the MBL is installed, then the CLI can be used to create the model with the following command:

Expand All @@ -61,22 +65,21 @@ Once the MBL is installed, then the CLI can be used to create the model with the
The resulting Modelica package will be created and can be opened in a Modelica editor. Open the :code:`package.mo` file in the root directory of the generated package. You will also need to
load the MBL into your Modelica editor.

The latest version of this repository uses MBL v9.0.0. This version does not support running JModelica due to the upgrade to Modelica Standard Library (MSL) version 4. For this reason, the unit tests no longer run the models; therefore, you will need to mark the pytest to not run the simulations with :code:`poetry run pytest -m 'not simulation'`.
Most models can be simulated for free using OpenModelica, which is included via Docker.

Test running the models with Dymola or OpenModelica. Dymola is used to test these models during development.
Dymola is a more full-featured alternative to OpenModelica and is not free.


Docker Installation
-------------------

The preferred method of running the simulations would be within Dymola; however, that is not a
practical solution for many based on the license requirement. Version 0.2.3 of the GMT enables the running of the
models using JModelica which requires the installation of `Docker`_. To configure Docker, do the
following:
Version 0.5.0+ of the GMT enables running the models using OpenModelica which requires the installation of `Docker`_.
To configure Docker, do the following:

* Install `Docker <https://docs.docker.com/get-docker/>`_ for your system.
* Configure Docker Desktop to have at least 4 GB Ram and 2 cores. This is configured under the Docker Preferences.
* It is recommended to test the installation of Docker by simply running :code:`docker run hello-world` in a terminal.
* Larger models (more buildings) may require more resources in Docker.
* We recommend testing the Docker installation by simply running :code:`docker run hello-world` in a terminal to confirm it is working as intended.

After Docker is installed and configured, you can use the CLI to run the model using the following
command:
Expand All @@ -90,6 +93,6 @@ command:
uo_des run-model model_from_sdk


.. _MBL: https://github.com/lbl-srg/modelica-buildings/
.. _MBL: https://simulationresearch.lbl.gov/modelica/index.html
.. _Poetry: https://python-poetry.org/docs/
.. _Docker: https://docs.docker.com/get-docker/
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@


class Coupling(object):
"""A Coupling represents a connection/relationship between two models (e.g. a load and ets).
"""A Coupling represents a connection/relationship between two models (e.g., a load and ets).
More specifically, is used to create the required components and connections between two models.
"""
_template_component_definitions = 'ComponentDefinitions.mopt'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
class DiagramNode:
def __init__(self, context_id, model_name, model_type):
"""
:param context_id: str, used for "grouping" nodes. E.g. this would be
:param context_id: str, used for "grouping" nodes, e.g., this would be
either the coupling id or the model id (depending on where the icon is declared)
:param model_name: str
:param model_type: str, general type of the component (e.g. load, network, etc)
:param model_type: str, general type of the component (e.g., load, network, etc)
"""
self.context_id = context_id
self.model_name = model_name
Expand Down Expand Up @@ -134,7 +134,7 @@ def to_dict(self, context_id, is_coupling):
line_template = Template('Line(points={$points},color={0,0,127})')

# add transformations defined within this id's context
# e.g. if id is for a model, add all transformations defined in the model instance template
# e.g., if id is for a model, add all transformations defined in the model instance template
for component_name, diagram_node in self._initial_diagram_graph.get(context_id, {}).items():
# x1, y1 is lower left of icon, x2, y2 is upper right
x_pos, y_pos = self._grid_to_coord(diagram_node.grid_col, diagram_node.grid_row)
Expand All @@ -160,7 +160,7 @@ def to_dict(self, context_id, is_coupling):
# include this connection if either:
# - we're working on the coupling lines
# - this connects to another model we might be interested in
# (e.g. model a instance connecting to model b instance)
# (e.g., model a instance connecting to model b instance)
include_line = this_context_id == context_id or other_node.context_id in diagram_ids
if include_line:
points = self._calculate_connector_line(
Expand Down Expand Up @@ -339,7 +339,7 @@ def _parse_coupling_graph(cls, coupling_graph):
{
'<model instance or coupling id>' : {
'<component name>': {
'type': '<component type e.g. load>',
'type': '<component type, e.g., load>',
'edges': {
'<component port name>': [
('<other model instance or coupling id>', '<other component name>', '<other component port>'), ...
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def get_param_by_id(self, id, jsonpath):
:return: variant, the value from the data
"""

# TODO: check that ids are unique in the system parameters file, i.e. a building_id doesn't match a ghe_id
# TODO: check that ids are unique in the system parameters file, i.e., a building_id doesn't match a ghe_id
for b in self.param_template.get("buildings", []):
if b.get("geojson_id") == id:
return self.get_param(jsonpath, data=b)
Expand Down