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

Issue669 buildingspy #672

Merged
merged 20 commits into from
Dec 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ double tab1(8760,30)
#TYPICAL/EXTREME PERIODS,6,Summer - Week Nearest Max Temperature For Period,Extreme,7/13,7/19,Summer - Week Nearest Average Temperature For Period,Typical,8/ 3,8/ 9,Winter - Week Nearest Min Temperature For Period,Extreme,12/ 8,12/14,Winter - Week Nearest Average Temperature For Period,Typical,12/15,12/21,Autumn - Week Nearest Average Temperature For Period,Typical,10/20,10/26,Spring - Week Nearest Average Temperature For Period,Typical,4/19,4/25
#GROUND TEMPERATURES,3,.5,,,,3.79,3.08,4.35,6.34,11.55,15.57,18.29,19.11,17.71,14.58,10.41,6.54,2,,,,6.44,5.16,5.42,6.48,9.96,13.11,15.64,16.99,16.70,14.93,12.06,9.01,4,,,,8.62,7.31,7.02,7.42,9.39,11.52,13.46,14.82,15.14,14.37,12.68,10.62
#HOLIDAYS/DAYLIGHT SAVINGS,No,0,0,0
#COMMENTS 1,"Custom/User Format -- WMO#107290; Bundesinstitut f�r Bau-, Stadt- und Raumforschung im Bundesamt f�r Bauwesen und Raumordnung. 1) DWD are the original author of the DTRY dataset on which these EPWs are based. 2) The EPWs were converted by Climate.OneBuilding.Org. Neither the DWD nor the BBSR were responsible for the conversion, and they disclaim all liability associated with the use of the converted DTRY EPW data set."
#COMMENTS 1,"Custom/User Format -- WMO#107290; Bundesinstitut fuer Bau-, Stadt- und Raumforschung im Bundesamt fuer Bauwesen und Raumordnung. 1) DWD are the original author of the DTRY dataset on which these EPWs are based. 2) The EPWs were converted by Climate.OneBuilding.Org. Neither the DWD nor the BBSR were responsible for the conversion, and they disclaim all liability associated with the use of the converted DTRY EPW data set."
#COMMENTS 2,"Downloaded from Climate.OneBuilding.Org -- Ground temps represent undisturbed earth temperatures - calculated from this weather data."
#DATA PERIODS,1,1,Data,Monday, 1/ 1,12/31
#C1 Time in seconds. Beginning of a year is 0s.
Expand Down
94 changes: 94 additions & 0 deletions teaser/data/output/aixlib_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ def export_multizone(buildings, prj, path=None):
filename=utilities.get_full_path(
"data/output/modelicatemplate/AixLib/AixLib_Multizone"),
lookup=lookup)
test_script_template = Template(
filename=utilities.get_full_path(
"data/output/modelicatemplate/modelica_test_script"),
lookup=lookup)

uses = [
'Modelica(version="' + prj.modelica_info.version + '")',
Expand Down Expand Up @@ -146,6 +150,17 @@ def export_multizone(buildings, prj, path=None):
modelica_info=bldg.parent.modelica_info))
out_file.close()

dir_resources = os.path.join(path, "Resources")
if not os.path.exists(dir_resources):
os.mkdir(dir_resources)
dir_scripts = os.path.join(dir_resources, "Scripts")
if not os.path.exists(dir_scripts):
os.mkdir(dir_scripts)
dir_dymola = os.path.join(dir_scripts, "Dymola")
if not os.path.exists(dir_dymola):
os.mkdir(dir_dymola)
_help_test_script(bldg, dir_dymola, test_script_template)

zone_path = os.path.join(bldg_path, bldg.name + "_DataBase")

for zone in bldg.thermal_zones:
Expand Down Expand Up @@ -173,10 +188,76 @@ def export_multizone(buildings, prj, path=None):
addition=bldg.name + "_",
extra=None)

_copy_script_unit_tests(os.path.join(dir_scripts, "runUnitTests.py"))
_copy_reference_results(dir_resources, prj)

print("Exports can be found here:")
print(path)


def _copy_reference_results(dir_resources, prj):
"""Copy reference results to modelica output.

Parameters
----------
dir_resources : str
Resources directory of the modelica output
prj : teaser.project.Project
Project to be exported
"""

if prj.dir_reference_results is not None:
dir_ref_out = os.path.join(dir_resources, "ReferenceResults")
if not os.path.exists(dir_ref_out):
os.mkdir(dir_ref_out)
dir_ref_out_dymola = os.path.join(dir_ref_out, "Dymola")
if not os.path.exists(dir_ref_out_dymola):
os.mkdir(dir_ref_out_dymola)
for filename in os.listdir(prj.dir_reference_results):
if filename.endswith(".txt"):
shutil.copy2(
os.path.join(prj.dir_reference_results, filename),
os.path.join(dir_ref_out_dymola, filename)
)


def _help_test_script(bldg, dir_dymola, test_script_template):
"""Create a test script for regression testing with BuildingsPy

Parameters
----------
bldg : teaser.logic.buildingobjects.building.Building
Building for which test script is created
dir_dymola : str
Output directory for Dymola scripts
test_script_template : mako.template.Template
Template for the test script

Returns
-------
dir_scripts : str
Path to the scripts directory
"""

dir_building = os.path.join(dir_dymola, bldg.name)
if not os.path.exists(dir_building):
os.mkdir(dir_building)
out_file = open(utilities.get_full_path
(os.path.join(dir_building, bldg.name + ".mos")), 'w')
names_variables = []
for i, zone in enumerate(bldg.thermal_zones):
names_variables.append(f"multizone.PHeater[{i+1}]")
names_variables.append(f"multizone.PCooler[{i+1}]")
names_variables.append(f"multizone.TAir[{i+1}]")
out_file.write(test_script_template.render_unicode(
project=bldg.parent,
bldg=bldg,
stop_time=3600 * 24 * 365,
names_variables=names_variables,
))
out_file.close()


def _help_package(path, name, uses=None, within=None):
"""creates a package.mo file

Expand Down Expand Up @@ -248,3 +329,16 @@ def _copy_weather_data(source_path, destination_path):
"""

shutil.copy2(source_path, destination_path)


def _copy_script_unit_tests(destination_path):
"""Copies the script to run the unit tests.

Parameters
----------
destination_path : str
path of where the weather file should be placed
"""

source_path = utilities.get_full_path("data/output/runUnitTests.py")
shutil.copy2(source_path, destination_path)
4 changes: 4 additions & 0 deletions teaser/data/output/modelicatemplate/AixLib/AixLib_Multizone
Original file line number Diff line number Diff line change
Expand Up @@ -140,9 +140,13 @@ equation
StartTime=${str(zone.parent.parent.modelica_info.start_time)},
StopTime=${str(zone.parent.parent.modelica_info.stop_time)},
Interval=${modelica_info.interval_output},
Tolerance=0.0001,
__Dymola_Algorithm="${modelica_info.current_solver}"),
__Dymola_experimentSetupOutput(equidistant=${get_true_false(modelica_info.equidistant_output)},
events=${get_true_false(modelica_info.results_at_events)}),
__Dymola_Commands(file=
"Resources/Scripts/Dymola/${bldg.name}/${bldg.name}.mos"
"Simulate and Plot"),
Icon(coordinateSystem(preserveAspectRatio=false, extent={{-100,-100},{100,100}}),
graphics={
Line(points={{80,-82}}, color={28,108,200}),
Expand Down
5 changes: 5 additions & 0 deletions teaser/data/output/modelicatemplate/modelica_test_script
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
simulateModel("${project.name}.${bldg.name}.${bldg.name}", method="Dassl", tolerance=0.0001, stopTime=${stop_time}, resultFile="${bldg.name}");
% for name_variable in names_variables:
createPlot(id=${loop.index + 1}, y={"${name_variable}"});
% endfor

228 changes: 228 additions & 0 deletions teaser/data/output/runUnitTests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,228 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#######################################################
# Script that runs all unit tests or, optionally,
# only checks the html syntax or the validity of
# the simulation parameters of the models
#
# To run the unit tests, this script
# - creates temporary directories for each processor,
# - copies the library directory into these
# temporary directories,
# - creates run scripts that run all unit tests,
# - runs these unit tests,
# - collects the dymola log files from each process,
# - writes the combined log file 'unitTests.log'
# in the current directory,
# - checks whether all unit tests run successfully,
# and produced the same results as the reference
# results, and
# - exits with the message
# 'Unit tests completed successfully.' or with
# an error message.
#
# If no errors occurred during the unit tests, then
# this script returns 0. Otherwise, it returns a
# non-zero exit value.
#
# MWetter@lbl.gov 2011-02-23
# TSNouidui@lbl.gov 2017-04-11
#######################################################
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function


def _validate_experiment_setup(path):
import buildingspy.development.validator as v

val = v.Validator()
retVal = val.validateExperimentSetup(path)

return retVal


def _validate_html(path):
import buildingspy.development.validator as v

val = v.Validator()
errMsg = val.validateHTMLInPackage(path)
n_msg = len(errMsg)
for i in range(n_msg):
if i == 0:
print(
"The following malformed html syntax has been found:\n{}".format(
errMsg[i]
)
)
else:
print(errMsg[i])

if n_msg == 0:
return 0
else:
return 1


def _setEnvironmentVariables(var, value):
""" Add to the environment variable `var` the value `value`
"""
import os
import platform

if var in os.environ:
if platform.system() == "Windows":
os.environ[var] = value + ";" + os.environ[var]
else:
os.environ[var] = value + ":" + os.environ[var]
else:
os.environ[var] = value


def _runUnitTests(batch, tool, package, path, n_pro, show_gui, skip_verification):
import buildingspy.development.regressiontest as u

ut = u.Tester(tool=tool, skip_verification=skip_verification)
ut.batchMode(batch)
ut.setLibraryRoot(path)
if package is not None:
ut.setSinglePackage(package)
ut.setNumberOfThreads(n_pro)
ut.pedanticModelica(False)
ut.showGUI(show_gui)
# Below are some option that may occassionally be used.
# These are currently not exposed as command line arguments.
# ut.setNumberOfThreads(1)
# ut.deleteTemporaryDirectories(False)
# ut.useExistingResults(['/tmp/tmp-Buildings-0-fagmeZ'])

# ut.writeOpenModelicaResultDictionary()
# Run the regression tests

retVal = ut.run()

# Display HTML report if not run in batch mode.
# (For buildingspy.__version__ >= 2)
if not batch:
try:
if not skip_verification:
ut.report()
except AttributeError:
pass

return retVal


if __name__ == "__main__":
import multiprocessing
import platform
import argparse
import os
import sys

# Configure the argument parser
parser = argparse.ArgumentParser(
description="Run the unit tests or the html validation only."
)
unit_test_group = parser.add_argument_group("arguments to run unit tests")

unit_test_group.add_argument(
"-b",
"--batch",
action="store_true",
help="Run in batch mode without user interaction",
)
unit_test_group.add_argument(
"-t",
"--tool",
metavar="dymola",
default="dymola",
help="Tool for the regression tests. Set to dymola or jmodelica",
)
unit_test_group.add_argument(
"-s",
"--single-package",
metavar="Modelica.Package",
help="Test only the Modelica package Modelica.Package",
)
unit_test_group.add_argument(
"-p",
"--path",
default=".",
help="Path where top-level package.mo of the library is located",
)
unit_test_group.add_argument(
"-n",
"--number-of-processors",
type=int,
default=multiprocessing.cpu_count(),
help="Maximum number of processors to be used",
)
unit_test_group.add_argument(
"--show-gui", help="Show the GUI of the simulator", action="store_true"
)
unit_test_group.add_argument(
"--skip-verification",
help="If specified, do not verify simulation results against reference points",
action="store_true",
)

html_group = parser.add_argument_group("arguments to check html syntax only")
html_group.add_argument("--validate-html-only", action="store_true")

experiment_setup_group = parser.add_argument_group(
"arguments to check validity of .mos and .mo experiment setup only"
)
experiment_setup_group.add_argument(
"--validate-experiment-setup", action="store_true"
)

# Set environment variables
if platform.system() == "Windows":
_setEnvironmentVariables(
"PATH", os.path.join(os.path.abspath("."), "Resources", "Library", "win32")
)
else:
# For https://github.com/lbl-srg/modelica-buildings/issues/559, we add
# 32 and 64 bit resources to run the Utilities.IO.Python27 regression tests.
_setEnvironmentVariables(
"LD_LIBRARY_PATH",
os.path.join(os.path.abspath("."), "Resources", "Library", "linux32")
+ ":"
+ os.path.join(os.path.abspath("."), "Resources", "Library", "linux64"),
)

# The path to buildingspy must be added to sys.path to work on Linux.
# If only added to os.environ, the Python interpreter won't find buildingspy
sys.path.append(os.path.join(os.path.abspath("."), "..", "..", "BuildingsPy"))

# Parse the arguments
args = parser.parse_args()

if args.validate_html_only:
# Validate the html syntax only, and then exit
ret_val = _validate_html(args.path)
exit(ret_val)

if args.validate_experiment_setup:
# Match the mos file parameters with the mo files only, and then exit
ret_val = _validate_experiment_setup(args.path)
exit(ret_val)

if args.single_package:
single_package = args.single_package
else:
single_package = None

retVal = _runUnitTests(
batch=args.batch,
tool=args.tool,
package=single_package,
path=args.path,
n_pro=args.number_of_processors,
show_gui=args.show_gui,
skip_verification=args.skip_verification,
)
exit(retVal)

# _runOpenModelicaUnitTests()
11 changes: 11 additions & 0 deletions teaser/examples/e2_export_aixlib_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,17 @@ def example_export_aixlib():
# Be careful: Dymola does not like whitespaces in names and filenames,
# thus we will delete them anyway in TEASER.

# for CI testing purpose we set the reference result folder

prj.dir_reference_results = utilities.get_full_path(
os.path.join(
"examples",
"examplefiles",
"ReferenceResults",
"Dymola"))

print(prj.dir_reference_results)

prj.used_library_calc = 'AixLib'
prj.number_of_elements_calc = 2
prj.weather_file_path = utilities.get_full_path(
Expand Down
Loading