Skip to content

Commit

Permalink
Summarize EndUses for any IDF model (#225)
Browse files Browse the repository at this point in the history
* adds IDF.copy() and IDF.saveas(inplace=True) (#254)

* Adjusts svg repr to the min/max values of the schedule (#255)

* Graceful warning when Slab or Basement program is not found

* Adds KeyBoardInterupt to IDF Thread

* catches more variations of unit name

* Adds ability to scale a schedule

* Fixes fallback limits for Schedule.plot2d() when Type is not defined

* Type can be specified in Schedule.from_values constructor

* plot2d is prettier by default

* more Typing

* Return existing object when new_object is there (#257)

* Adds ability to replace schedule values without affecting the full load hours

* more robust IDF.name property

* Keep sim files when error occurs (#276)

* Better Output class for IDF model

* Added tests for Outputs

* more tests

* Parse existing outputs in IDF model when initializing class

* Backwards compatibility with E+ <= 7.2 and meters objects

* Latest transitioned object more robust

* eplus_interface looks in /bin when version is lower or equal to E+ 7.2

* New method: add_idf_object_from_idf_string

* code format

* Adds enduse balance class

* Adds default output variables and meters to Output class

* Towards working characterization

* removed zone predicted load and temp

* adds cooling routine to sankey

* Name convention

* Fixes the window gains and losses

* Fixes an issue reading multipliers

* Fixes names in sankey

* better

* Collect by outputs

* Revert "Collect by outputs"

This reverts commit 121549fc252835c7e72747248828702e113ccaea.

* multipliers

* Current state

* include html and sql by default

* add missing outputs to method

* Added construction table to Sql

* adds storage outputs

* Uses outside face storage

* Fix issue with getattr

* Fixes a test

* isort+black

* Removes IDF and SQL by default

* Fix test

* Fix test with failing transition

* Fixes tests

* Fixes test

* fix test
  • Loading branch information
Samuel Letellier-Duchesne authored Apr 6, 2022
1 parent 1759572 commit 66d0ff5
Show file tree
Hide file tree
Showing 23 changed files with 2,991 additions and 401 deletions.
36 changes: 25 additions & 11 deletions archetypal/eplus_interface/basement.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,17 @@ def run(self):

# Get executable using shutil.which (determines the extension based on
# the platform, eg: .exe. And copy the executable to tmp
self.basement_exe = Path(
shutil.which(
"Basement", path=self.eplus_home / "PreProcess" / "GrndTempCalc"
basemenet_exe = shutil.which(
"Basement", path=self.eplus_home / "PreProcess" / "GrndTempCalc"
)
if basemenet_exe is None:
log(
f"The Basement program could not be found at "
f"'{self.eplus_home / 'PreProcess' / 'GrndTempCalc'}'",
lg.WARNING,
)
).copy(self.run_dir)
return
self.basement_exe = Path(basemenet_exe).copy(self.run_dir)
self.basement_idd = (
self.eplus_home / "PreProcess" / "GrndTempCalc" / "BasementGHT.idd"
).copy(self.run_dir)
Expand Down Expand Up @@ -207,11 +213,19 @@ def cancelled_callback(self, stdin, stdout):

@property
def eplus_home(self):
eplus_exe, eplus_home = paths_from_version(self.idf.as_version.dash)
if not Path(eplus_home).exists():
raise EnergyPlusVersionError(
msg=f"No EnergyPlus Executable found for version "
f"{EnergyPlusVersion(self.idf.as_version)}"
)
"""Get the version-dependant directory where executables are installed."""
if self.idf.file_version <= EnergyPlusVersion("7.2"):
install_dir = self.idf.file_version.current_install_dir / "bin"
else:
return Path(eplus_home)
install_dir = (
self.idf.file_version.current_install_dir
/ "PreProcess"
/ "GrndTempCalc"
)
return install_dir

def stop(self):
if self.p.poll() is None:
self.msg_callback("Attempting to cancel simulation ...")
self.cancelled = True
self.p.kill()
2 changes: 1 addition & 1 deletion archetypal/eplus_interface/energy_plus.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ def failure_callback(self):
with open(error_filename, "r") as stderr:
stderr_r = stderr.read()
if self.idf.keep_data_err:
failed_dir = self.idf.simulation_dir.mkdir_p() / "failed"
failed_dir = self.idf.simulation_dir.mkdir_p()
try:
failed_dir.rmtree_p()
except PermissionError as e:
Expand Down
23 changes: 13 additions & 10 deletions archetypal/eplus_interface/expand_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ def run(self):
self.epw = self.idf.epw.copy(tmp / "in.epw").expand()
self.idfname = Path(self.idf.savecopy(tmp / "in.idf")).expand()
self.idd = self.idf.iddname.copy(tmp / "Energy+.idd").expand()
self.expandobjectsexe = Path(
shutil.which("ExpandObjects", path=self.eplus_home.expand())
).copy2(tmp)
expand_object_exe = shutil.which("ExpandObjects", path=self.eplus_home)
self.expandobjectsexe = Path(expand_object_exe).copy2(tmp)
self.run_dir = Path(tmp).expand()

# Run ExpandObjects Program
Expand Down Expand Up @@ -151,11 +150,15 @@ def cancelled_callback(self, stdin, stdout):

@property
def eplus_home(self):
eplus_exe, eplus_home = paths_from_version(self.idf.as_version.dash)
if not Path(eplus_home).exists():
raise EnergyPlusVersionError(
msg=f"No EnergyPlus Executable found for version "
f"{EnergyPlusVersion(self.idf.as_version)}"
)
"""Get the version-dependant directory where executables are installed."""
if self.idf.file_version <= EnergyPlusVersion("7.2"):
install_dir = self.idf.file_version.current_install_dir / "bin"
else:
return Path(eplus_home)
install_dir = self.idf.file_version.current_install_dir
return install_dir

def stop(self):
if self.p.poll() is None:
self.msg_callback("Attempting to cancel simulation ...")
self.cancelled = True
self.p.kill()
36 changes: 26 additions & 10 deletions archetypal/eplus_interface/slab.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,17 @@ def run(self):

# Get executable using shutil.which (determines the extension based on
# the platform, eg: .exe. And copy the executable to tmp
self.slabexe = Path(
shutil.which("Slab", path=self.eplus_home / "PreProcess" / "GrndTempCalc")
).copy(self.run_dir)
slab_exe = shutil.which(
"Slab", path=self.eplus_home / "PreProcess" / "GrndTempCalc"
)
if slab_exe is None:
log(
f"The Slab program could not be found at "
f"'{self.eplus_home / 'PreProcess' / 'GrndTempCalc'}'",
lg.WARNING,
)
return
self.slabexe = Path(slab_exe).copy(self.run_dir)
self.slabidd = (
self.eplus_home / "PreProcess" / "GrndTempCalc" / "SlabGHT.idd"
).copy(self.run_dir)
Expand Down Expand Up @@ -164,11 +172,19 @@ def cancelled_callback(self, stdin, stdout):

@property
def eplus_home(self):
eplus_exe, eplus_home = paths_from_version(self.idf.as_version.dash)
if not Path(eplus_home).exists():
raise EnergyPlusVersionError(
msg=f"No EnergyPlus Executable found for version "
f"{EnergyPlusVersion(self.idf.as_version)}"
)
"""Get the version-dependant directory where executables are installed."""
if self.idf.file_version <= EnergyPlusVersion("7.2"):
install_dir = self.idf.file_version.current_install_dir / "bin"
else:
return Path(eplus_home)
install_dir = (
self.idf.file_version.current_install_dir
/ "PreProcess"
/ "GrndTempCalc"
)
return install_dir

def stop(self):
if self.p.poll() is None:
self.msg_callback("Attempting to cancel simulation ...")
self.cancelled = True
self.p.kill()
13 changes: 11 additions & 2 deletions archetypal/eplus_interface/transition.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ def run(self):

generator = TransitionExe(self.idf, tmp_dir=tmp)

# set the initial version from which we are transitioning
last_successful_transition = self.idf.file_version

for trans in tqdm(
generator,
total=len(generator.transitions),
Expand Down Expand Up @@ -214,10 +217,14 @@ def run(self):
time.time() - start_time
)
)
last_successful_transition = trans.trans
self.success_callback()
for line in self.p.stderr:
self.msg_callback(line.decode("utf-8"))
else:
# set the version of the IDF the latest it was able to transition
# to.
self.idf.as_version = last_successful_transition
self.msg_callback("Transition failed")
self.failure_callback()

Expand Down Expand Up @@ -275,7 +282,9 @@ def failure_callback(self):
"""Read stderr and pass to logger."""
for line in self.p.stderr:
self.msg_callback(line.decode("utf-8"), level=lg.ERROR)
raise CalledProcessError(self.p.returncode, cmd=self.cmd, stderr=self.p.stderr)
self.exception = CalledProcessError(
self.p.returncode, cmd=self.cmd, stderr=self.p.stderr
)

def cancelled_callback(self, stdin, stdout):
"""Call on cancelled."""
Expand All @@ -286,7 +295,7 @@ def eplus_home(self):
"""Return the location of the EnergyPlus directory."""
eplus_exe, eplus_home = paths_from_version(self.idf.as_version.dash)
if not Path(eplus_home).exists():
raise EnergyPlusVersionError(
self.exception = EnergyPlusVersionError(
msg=f"No EnergyPlus Executable found for version "
f"{EnergyPlusVersion(self.idf.as_version)}"
)
Expand Down
12 changes: 10 additions & 2 deletions archetypal/eplus_interface/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from archetypal import settings
from archetypal.eplus_interface.exceptions import (
EnergyPlusVersionError,
InvalidEnergyPlusVersion,
)

Expand Down Expand Up @@ -109,7 +110,12 @@ def current_idd_path(self):
@property
def current_install_dir(self):
"""Get the current installation directory for this EnergyPlus version."""
return self.install_locations[self.dash]
try:
return self.install_locations[self.dash]
except KeyError:
raise EnergyPlusVersionError(
f"EnergyPlusVersion {self.dash} is not installed."
)

@property
def tuple(self) -> tuple:
Expand All @@ -121,7 +127,9 @@ def valid_versions(self) -> set:
"""List the idd file version found on this machine."""
if not self.valid_idd_paths:
# Little hack in case E+ is not installed
_choices = {settings.ep_version,}
_choices = {
settings.ep_version,
}
else:
_choices = set(self.valid_idd_paths.keys())

Expand Down
Loading

0 comments on commit 66d0ff5

Please sign in to comment.