Skip to content

Commit

Permalink
fix(eplus): fix error when cfs is None
Browse files Browse the repository at this point in the history
  • Loading branch information
taoning committed Aug 20, 2024
1 parent 29c7f59 commit 0b8aa98
Showing 1 changed file with 37 additions and 75 deletions.
112 changes: 37 additions & 75 deletions frads/eplus.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@
Class and functions for accessing EnergyPlus Python API
"""

import ast
import datetime
import json
from pathlib import Path
from typing import Dict, List, Optional, Callable, Union
import inspect
import ast
import json
import tempfile
from pathlib import Path
from typing import Callable, Dict, List, Optional, Union

import numpy as np
from epmodel import epmodel as epm
from pyenergyplus.api import EnergyPlusAPI

from frads.ep2rad import epmodel_to_radmodel
from frads.methods import (
WorkflowConfig,
ThreePhaseMethod,
)
from frads.eplus_model import EnergyPlusModel
import numpy as np
from pyenergyplus.api import EnergyPlusAPI
from frads.methods import ThreePhaseMethod, WorkflowConfig


def ep_datetime_parser(inp: str):
Expand All @@ -31,9 +29,9 @@ def ep_datetime_parser(inp: str):
month, day = [int(i) for i in date.split("/")]
hr, mi, sc = [int(i) for i in time.split(":")]
if hr == 24 and mi == 0 and sc == 0:
return datetime.datetime(
1900, month, day, 0, mi, sc
) + datetime.timedelta(days=1)
return datetime.datetime(1900, month, day, 0, mi, sc) + datetime.timedelta(
days=1
)
else:
return datetime.datetime(1900, month, day, hr, mi, sc)

Expand Down Expand Up @@ -86,9 +84,7 @@ def __init__(
k: WorkflowConfig.from_dict(v) for k, v in self.rmodels.items()
}
# Default to Three-Phase Method
self.rworkflows = {
k: ThreePhaseMethod(v) for k, v in self.rconfigs.items()
}
self.rworkflows = {k: ThreePhaseMethod(v) for k, v in self.rconfigs.items()}
for v in self.rworkflows.values():
v.config.settings.save_matrices = True
v.generate_matrices(view_matrices=False)
Expand All @@ -101,9 +97,7 @@ def __init__(
self.construction_handles = {}
self.construction_names = {}
self.enable_radiance = enable_radiance
self.api.runtime.callback_begin_new_environment(
self.state, self._get_handles()
)
self.api.runtime.callback_begin_new_environment(self.state, self._get_handles())
self.actuators = []
self._get_list_of_actuators()

Expand All @@ -119,9 +113,7 @@ def __exit__(self, exc_type, exc_value, exc_tb):
def _actuator_func(self, state):
if len(self.actuators) == 0:
api_data: List[str] = (
self.api.api.listAllAPIDataCSV(state)
.decode("utf-8")
.splitlines()
self.api.api.listAllAPIDataCSV(state).decode("utf-8").splitlines()
)
for line in api_data:
if line.startswith("Actuator"):
Expand All @@ -140,18 +132,14 @@ def _get_list_of_actuators(self):
with tempfile.TemporaryDirectory() as tmpdir:
inp = Path(tmpdir) / "in.json"
with open(inp, "w") as wtr:
wtr.write(
self.model.model_dump_json(by_alias=True, exclude_none=True)
)
wtr.write(self.model.model_dump_json(by_alias=True, exclude_none=True))

if self.epw is not None:
self.api.runtime.run_energyplus(
actuator_state, ["-p", "actuator", "-w", self.epw, str(inp)]
)
elif self.model.sizing_period_design_day is not None:
self.api.runtime.run_energyplus(
actuator_state, ["-D", str(inp)]
)
self.api.runtime.run_energyplus(actuator_state, ["-D", str(inp)])
else:
raise ValueError(
"Specify weather file in EnergyPlusSetup "
Expand All @@ -177,9 +165,7 @@ def actuate(self, component_type: str, name: str, key: str, value: float):
Examples:
>>> epsetup.actuate("Weather Data", "Outdoor Dew Point", "Environment", 10)
"""
if (
key not in self.actuator_handles
): # check if key exists in actuator handles
if key not in self.actuator_handles: # check if key exists in actuator handles
self.actuator_handles[key] = {}
if (
name not in self.actuator_handles[key]
Expand Down Expand Up @@ -335,45 +321,34 @@ def callback_function(state):
for key in self.variable_handles:
try:
for name in self.variable_handles[key]:
handle = self.api.exchange.get_variable_handle(
state, name, key
)
handle = self.api.exchange.get_variable_handle(state, name, key)
if handle == -1:
raise ValueError(
"Variable handle not found: "
f"name = {name}, key = {key}"
)
self.variable_handles[key][name] = handle
except TypeError:
print(
"No variables requested for", self.variable_handles, key
)
print("No variables requested for", self.variable_handles, key)

if self.model.construction_complex_fenestration_state is not None:
for cfs in self.model.construction_complex_fenestration_state:
handle = self.api.api.getConstructionHandle(
state, cfs.encode()
)
handle = self.api.api.getConstructionHandle(state, cfs.encode())
if handle == -1:
raise ValueError(
"Construction handle not found: "
f"Construction = {cfs}"
"Construction handle not found: " f"Construction = {cfs}"
)
self.construction_handles[cfs] = handle
self.construction_names[handle] = cfs
for w in self.model.fenestration_surface_detailed:
if (
self.model.fenestration_surface_detailed[
w
].construction_name
in self.model.construction_complex_fenestration_state
):
self.actuate_cfs_state(
w,
self.model.fenestration_surface_detailed[
w
].construction_name,
)
for wname, window in self.model.fenestration_surface_detailed.items():
if (
window.construction_name
in self.model.construction_complex_fenestration_state
):
self.actuate_cfs_state(
wname,
window.construction_name,
)

return callback_function

Expand Down Expand Up @@ -470,14 +445,10 @@ def run(
}

with open(f"{output_prefix}.json", "w") as wtr:
wtr.write(
self.model.model_dump_json(by_alias=True, exclude_none=True)
)
wtr.write(self.model.model_dump_json(by_alias=True, exclude_none=True))

self.api.runtime.set_console_output_status(self.state, not silent)
self.api.runtime.run_energyplus(
self.state, [*opt, f"{output_prefix}.json"]
)
self.api.runtime.run_energyplus(self.state, [*opt, f"{output_prefix}.json"])

def set_callback(self, method_name: str, func: Callable):
"""Set callback function for EnergyPlus runtime API.
Expand All @@ -504,9 +475,7 @@ def set_callback(self, method_name: str, func: Callable):
# method(self.state, partial(func, self))
method(self.state, func)

def _request_variables_from_callback(
self, callable_nodes: List[ast.Call]
) -> None:
def _request_variables_from_callback(self, callable_nodes: List[ast.Call]) -> None:
key_value_pairs = set()
for node in callable_nodes:
key_value_dict = {}
Expand Down Expand Up @@ -544,20 +513,15 @@ def _request_variables_from_callback(
key="Environment",
)

def _check_actuators_from_callback(
self, callable_nodes: List[ast.Call]
) -> None:
def _check_actuators_from_callback(self, callable_nodes: List[ast.Call]) -> None:
def get_zone_from_pair_arg(node: ast.Call) -> str:
if len(node.args) == 2:
zone = ast.literal_eval(node.args[0])
elif len(node.keywords) == 2:
key_value_dict = {
node.keywords[i].arg: node.keywords[i].value.value
for i in range(2)
node.keywords[i].arg: node.keywords[i].value.value for i in range(2)
}
zone = key_value_dict.get(
"zone", key_value_dict.get("surface", None)
)
zone = key_value_dict.get("zone", key_value_dict.get("surface", None))
else:
raise ValueError(f"Invalid number of arguments in {node}.")
return zone
Expand All @@ -566,9 +530,7 @@ def get_zone_from_pair_arg(node: ast.Call) -> str:
key_value = None
if node.func.attr == "actuate":
if len(node.args) == 4:
key_value = [
ast.literal_eval(node.args[i]) for i in range(3)
]
key_value = [ast.literal_eval(node.args[i]) for i in range(3)]
elif len(node.keywords) == 4:
key_value_dict = {
node.keywords[i].arg: node.keywords[i].value.value
Expand Down

0 comments on commit 0b8aa98

Please sign in to comment.