Revision history [back]
API Python examples of Data Transfer in EnergyPlus
Thank you again for your responses. I am attaching the Python script and the list of actuators for a better understanding.
1) My goal is to override the air properties at the inlet of the AHUs (not the weather file). Thus, from the available API data list of the simulation, I chose all the actuators related to the “Outdoor Air System Node” to perform the override of the Wet bulb temperature, which are (…._OAINLET NODE, …._COOLC COND OA NODE, … _COOLCOA REF NODE) and I used almost all the calling points. However, I could not get any satisfactory overrideC:\fakepath\Actuators.png.
class AverageZoneCalcs(EnergyPlusPlugin):
def __init__(self):
super().__init__()
self.do_setup = True
def on_end_of_zone_timestep_before_zone_reporting(self, state) -> int:
if self.do_setup:
self.data["zone_volumes"] = []
self.data["zone_temps"] = []
self.data["zone_humidity_ratios"] = []
zone_names = ["Perimeter_top_ZN_" + str(i) for i in range(1, 5)] + ["Perimeter_mid_ZN_" + str(i) for i in range(1, 5)] + ["Perimeter_bot_ZN_" + str(i) for i in range(1, 5)] + ["Core_bottom", "TopFloor_Plenum", "MidFloor_Plenum", "FirstFloor_Plenum", "Core_mid", "Core_top"]
for zone_name in zone_names:
handle = self.api.exchange.get_internal_variable_handle(state, "Zone Air Volume", zone_name)
zone_volume = self.api.exchange.get_internal_variable_value(state, handle)
self.data["zone_volumes"].append(zone_volume)
self.data["zone_temps"].append(
self.api.exchange.get_variable_handle(state, "Zone Mean Air Temperature", zone_name)
)
self.data["zone_humidity_ratios"].append(
self.api.exchange.get_variable_handle(state, "Zone Mean Air Humidity Ratio", zone_name)
)
self.data["avg_temp_variable"] = self.api.exchange.get_global_handle(state, "AverageBuildingTemp")
self.data["avg_hum_ratio_variable"] = self.api.exchange.get_global_handle(state, "AverageBuildingHR")
self.do_setup = False
zone_temps = list()
zone_humidity_ratios = list()
for t_handle in self.data["zone_temps"]:
zone_temps.append(self.api.exchange.get_variable_value(state, t_handle))
for hr_handle in self.data["zone_humidity_ratios"]:
zone_humidity_ratios.append(self.api.exchange.get_variable_value(state, hr_handle))
numerator_t = 0.0
numerator_hr = 0.0
denominator = 0.0
for i in range(5):
numerator_t += self.data["zone_volumes"][i] * zone_temps[i]
numerator_hr += self.data["zone_volumes"][i] * zone_humidity_ratios[i]
denominator += self.data["zone_volumes"][i]
average_temp = numerator_t / denominator
average_HR = numerator_hr / denominator
self.api.exchange.set_global_value(state, self.data["avg_temp_variable"], average_temp)
self.api.exchange.set_global_value(state, self.data["avg_hum_ratio_variable"], average_HR)
return 0
class Dehumidifier(EnergyPlusPlugin):
def __init__(self):
super().__init__()
self.need_to_get_handles = True
self.handles = {}
self.values = {}
self.psych = None
self.OA_DBT_handle = None
self.OA_WBT_handle = None
self.Patm_handle = None
self.WBT_override_handle = None
def get_handles(self, state):
if self.need_to_get_handles:
self.handles["OA_DBT"] = self.api.exchange.get_variable_handle(
state,
"Site Outdoor Air Drybulb Temperature",
"Environment"
)
self.handles["OA_WBT"] = self.api.exchange.get_variable_handle(
state,
"Site Outdoor Air Wetbulb Temperature",
"Environment"
)
self.handles["Patm"] = self.api.exchange.get_variable_handle(
state,
"Site Outdoor Air Barometric Pressure",
"Environment"
)
self.handles["PACU_BOT_WBT_override"] = self.api.exchange.get_actuator_handle(
state,
"Outdoor Air System Node",
"Wetbulb Temperature",
"PACU_VAV_BOT_OAINLET NODE"
)
self.handles["PACU_MID_WBT_override"] = self.api.exchange.get_actuator_handle(
state,
"Outdoor Air System Node",
"Wetbulb Temperature",
"PACU_VAV_MID_OAINLET NODE"
)
self.handles["PACU_TOP_WBT_override"] = self.api.exchange.get_actuator_handle(
state,
"Outdoor Air System Node",
"Wetbulb Temperature",
"PACU_VAV_TOP_OAINLET NODE"
)
self.need_to_get_handles = False
def handles_are_valid(self, state):
handles_are_valid = True
for (k, v) in self.handles.items():
if v == -1:
handles_are_valid = False
print(k, v)
self.api.runtime.issue_severe(state, f"Handle not found for '{k}'")
return handles_are_valid
def OA_inlet_manager(self, state):
if not self.psych:
self.psych = self.api.functional.psychrometrics(state)
self.values["OA_DBT"] = self.api.exchange.get_variable_value(state, self.handles["OA_DBT"])
self.values["OA_WBT"] = self.api.exchange.get_variable_value(state, self.handles["OA_WBT"])
self.values["Patm"] = self.api.exchange.get_variable_value(state, self.handles["Patm"])
OA_DBT = self.values["OA_DBT"]
OA_WBT = self.values["OA_WBT"]
Patm = self.values["Patm"]
OA_HR = self.psych.humidity_ratio_d(state, OA_DBT, OA_WBT, Patm)
if OA_HR >= 0.0092:
HR_deh = 0.0092
WBT_in = self.psych.wet_bulb(state, OA_DBT, HR_deh, Patm)
self.api.exchange.set_actuator_value(state, self.handles["PACU_BOT_WBT_override"], WBT_in )
self.api.exchange.set_actuator_value(state, self.handles["PACU_MID_WBT_override"], WBT_in )
self.api.exchange.set_actuator_value(state, self.handles["PACU_TOP_WBT_override"], WBT_in )
def on_begin_zone_timestep_before_set_current_weather(self, state):
if not self.api.exchange.api_data_fully_ready(state):
return 0
if self.need_to_get_handles:
self.get_handles(state)
if not self.handles_are_valid(state):
return 1
self.OA_inlet_manager(state)
return 0
2) As you can see in the script, there is a global variable for the average building humidity ratio which is calculated with a callback function “on_end_of_zone_timestep_before_zone_reporting” in the first class instance, however, I am not able to use that variable in the second class instance, which is the one that overrides the air Wet bulb temperature.
Could you please help me with these issues?
Thank you for your advice in advance.
API Python examples of Data Transfer in EnergyPlus
Thank you again for your responses. I am attaching the Python script and the list of actuators for response. Now I have a better understanding.understanding of how to use sensors and actuators. However, I still have other issues, I will try to give good detail in my questions.
1) My goal In my simulations, I am using the API to “Call EnergyPlus as a library”, so from my understanding I cannot use global variables because they are meant to work with Python Plugin applications, right?
2) What I’m trying to do is to override the model different configurations of dehumidification devices. Thus, the idea is to get air properties at the inlet of the AHUs (not from the weather file). Thus, from the available variables, run a script to calculate the parameters of the dehumidification device, including the properties of the dehumidified air. Then I would like to send these outputs to the simulation again to continue with the calculations of the HVAC equipment. Could be performed something like this?
3) From my understanding, when using callbacks, those are meant to callback only one function, so, should I use nested functions for these purposes?
In summary, I'm planning to use the Python API data list of the simulation, I chose all the actuators related to the “Outdoor Air System Node” to perform the override of the Wet bulb temperature, which are (…._OAINLET NODE, …._COOLC COND OA NODE, … _COOLCOA REF NODE) as "bypass" during the simulation by getting data, performing calculations, and I used almost all the calling points. However, I could not get any satisfactory overrideC:\fakepath\Actuators.png.
class AverageZoneCalcs(EnergyPlusPlugin):
def __init__(self):
super().__init__()
self.do_setup = True
def on_end_of_zone_timestep_before_zone_reporting(self, state) -> int:
if self.do_setup:
self.data["zone_volumes"] = []
self.data["zone_temps"] = []
self.data["zone_humidity_ratios"] = []
zone_names = ["Perimeter_top_ZN_" + str(i) for i in range(1, 5)] + ["Perimeter_mid_ZN_" + str(i) for i in range(1, 5)] + ["Perimeter_bot_ZN_" + str(i) for i in range(1, 5)] + ["Core_bottom", "TopFloor_Plenum", "MidFloor_Plenum", "FirstFloor_Plenum", "Core_mid", "Core_top"]
for zone_name in zone_names:
handle = self.api.exchange.get_internal_variable_handle(state, "Zone Air Volume", zone_name)
zone_volume = self.api.exchange.get_internal_variable_value(state, handle)
self.data["zone_volumes"].append(zone_volume)
self.data["zone_temps"].append(
self.api.exchange.get_variable_handle(state, "Zone Mean Air Temperature", zone_name)
)
self.data["zone_humidity_ratios"].append(
self.api.exchange.get_variable_handle(state, "Zone Mean Air Humidity Ratio", zone_name)
)
self.data["avg_temp_variable"] = self.api.exchange.get_global_handle(state, "AverageBuildingTemp")
self.data["avg_hum_ratio_variable"] = self.api.exchange.get_global_handle(state, "AverageBuildingHR")
self.do_setup = False
zone_temps = list()
zone_humidity_ratios = list()
for t_handle in self.data["zone_temps"]:
zone_temps.append(self.api.exchange.get_variable_value(state, t_handle))
for hr_handle in self.data["zone_humidity_ratios"]:
zone_humidity_ratios.append(self.api.exchange.get_variable_value(state, hr_handle))
numerator_t = 0.0
numerator_hr = 0.0
denominator = 0.0
for i in range(5):
numerator_t += self.data["zone_volumes"][i] * zone_temps[i]
numerator_hr += self.data["zone_volumes"][i] * zone_humidity_ratios[i]
denominator += self.data["zone_volumes"][i]
average_temp = numerator_t / denominator
average_HR = numerator_hr / denominator
self.api.exchange.set_global_value(state, self.data["avg_temp_variable"], average_temp)
self.api.exchange.set_global_value(state, self.data["avg_hum_ratio_variable"], average_HR)
return 0
class Dehumidifier(EnergyPlusPlugin):
def __init__(self):
super().__init__()
self.need_to_get_handles = True
self.handles = {}
self.values = {}
self.psych = None
self.OA_DBT_handle = None
self.OA_WBT_handle = None
self.Patm_handle = None
self.WBT_override_handle = None
def get_handles(self, state):
if self.need_to_get_handles:
self.handles["OA_DBT"] = self.api.exchange.get_variable_handle(
state,
"Site Outdoor Air Drybulb Temperature",
"Environment"
)
self.handles["OA_WBT"] = self.api.exchange.get_variable_handle(
state,
"Site Outdoor Air Wetbulb Temperature",
"Environment"
)
self.handles["Patm"] = self.api.exchange.get_variable_handle(
state,
"Site Outdoor Air Barometric Pressure",
"Environment"
)
self.handles["PACU_BOT_WBT_override"] = self.api.exchange.get_actuator_handle(
state,
"Outdoor Air System Node",
"Wetbulb Temperature",
"PACU_VAV_BOT_OAINLET NODE"
)
self.handles["PACU_MID_WBT_override"] = self.api.exchange.get_actuator_handle(
state,
"Outdoor Air System Node",
"Wetbulb Temperature",
"PACU_VAV_MID_OAINLET NODE"
)
self.handles["PACU_TOP_WBT_override"] = self.api.exchange.get_actuator_handle(
state,
"Outdoor Air System Node",
"Wetbulb Temperature",
"PACU_VAV_TOP_OAINLET NODE"
)
self.need_to_get_handles = False
def handles_are_valid(self, state):
handles_are_valid = True
for (k, v) in self.handles.items():
if v == -1:
handles_are_valid = False
print(k, v)
self.api.runtime.issue_severe(state, f"Handle not found for '{k}'")
return handles_are_valid
def OA_inlet_manager(self, state):
if not self.psych:
self.psych = self.api.functional.psychrometrics(state)
self.values["OA_DBT"] = self.api.exchange.get_variable_value(state, self.handles["OA_DBT"])
self.values["OA_WBT"] = self.api.exchange.get_variable_value(state, self.handles["OA_WBT"])
self.values["Patm"] = self.api.exchange.get_variable_value(state, self.handles["Patm"])
OA_DBT = self.values["OA_DBT"]
OA_WBT = self.values["OA_WBT"]
Patm = self.values["Patm"]
OA_HR = self.psych.humidity_ratio_d(state, OA_DBT, OA_WBT, Patm)
if OA_HR >= 0.0092:
HR_deh = 0.0092
WBT_in = self.psych.wet_bulb(state, OA_DBT, HR_deh, Patm)
self.api.exchange.set_actuator_value(state, self.handles["PACU_BOT_WBT_override"], WBT_in )
self.api.exchange.set_actuator_value(state, self.handles["PACU_MID_WBT_override"], WBT_in )
self.api.exchange.set_actuator_value(state, self.handles["PACU_TOP_WBT_override"], WBT_in )
def on_begin_zone_timestep_before_set_current_weather(self, state):
if not self.api.exchange.api_data_fully_ready(state):
return 0
if self.need_to_get_handles:
self.get_handles(state)
if not self.handles_are_valid(state):
return 1
self.OA_inlet_manager(state)
return 0
2) As you can see in the script, there is a global variable for the average building humidity ratio which is calculated then returning outputs to continue with a callback function “on_end_of_zone_timestep_before_zone_reporting” in the first class instance, however, I am not able to use that variable in the second class instance, which is the one that overrides the air Wet bulb temperature.
Could you please help me with these issues?the simulation.
Thank you for your advice in advance.
API Python examples of Data Transfer in EnergyPlus
Thank you for your response. Now I have a better understanding of how to use sensors and actuators. However, I still have other issues, I will try to give good detail in my questions.
1) In my simulations, I am using the API to “Call EnergyPlus as a library”, so from my understanding I cannot use global variables because they are meant to work with Python Plugin applications, right?
2) What I’m trying to do is to model different configurations of dehumidification devices. Thus, the idea is to get air properties from the weather variables, run a script to calculate the parameters of the dehumidification device, including the properties of the dehumidified air. Then I would like to send these outputs to the simulation again to continue with the calculations of the HVAC equipment. Could be performed something like this?
3) From my understanding, when using callbacks, those are meant to callback only one function, so, should I use nested functions for these purposes?
In summary, I'm planning to use the Python API as "bypass" during the simulation by getting data, performing calculations, and then returning outputs to continue with the simulation.
Thank you for your advice in advance.
API Python examples of Data Transfer in EnergyPlus
Thank you Hi everyone. I have been working for a while trying to call Python scripts during a simulation to perform some calculations to then override some actuators. However, I am stuck with some issues. I’ll appreciate your response. Now I have a better understanding of how to use sensors and actuators. However, I still have other issues, I will try to give good detail advice and/or examples on these topics:
1) I know certain variables cannot be actuated; however, when I actuated over “Outdoor Relative Humidity” during “begin_zone_timestep_before_set_current_weather” (which theoretically can be actuated), I do not get different results in my questions.
1) In my simulations, I am using the API to “Call EnergyPlus as a library”, so from my understanding I cannot use global variables because they are meant to work with Python Plugin applications, right? simulations. How can I know which variable can be actuated and the specific calling point to perform these tasks?
2) What I’m trying to do is to model different configurations of dehumidification devices. Thus, the idea is to get air properties from the weather variables, run a script to calculate the parameters of the dehumidification device, including the properties of the dehumidified air. Then I would like to send these know if there is a way to save the outputs to the simulation again to continue of the API python functions as part of the output variable or output meter reports. Since the length of the arrays or data frames are unknown, I do not know how to collect the time step generated data while running a callback function.
3) Where can I find an example of how to return variables from a call-back function at a specific calling point to be used with the calculations of the HVAC equipment. Could be performed something like this?
3) From my understanding, when using callbacks, those are meant to another python function or callback only one function, so, should I use nested functions for these purposes?
function into a further calling point. In summary, I'm planning to use the Python API as "bypass" during the simulation by getting data, performing calculations, and then I am having trouble returning outputs to continue with the simulation.values to other functions at different calling points.
Thank you for your advice in advance.
API Python examples of Data Transfer in EnergyPlus
Hi everyone. I have been working for a while trying to call Python scripts during a simulation to perform some calculations to then override some actuators. However, I am stuck with some issues. I’ll appreciate your advice and/or examples on these topics:
1) I know certain variables cannot be actuated; however, when I actuated over “Outdoor Relative Humidity” during “begin_zone_timestep_before_set_current_weather” (which theoretically can be actuated), I do not get different results in my simulations. How can I know which variable can be actuated and the specific calling point to perform these tasks?
2) I would like to know if there is a way to save the outputs of the API python functions as part of the output variable or output meter reports. Since the length of the arrays or data frames are unknown, I do not know how to collect the time step generated data while running a callback function.
3) Where can I find an example of how to return variables from a call-back function at a specific calling point to be used with another python function or callback function into a further calling point. In summary, I am having trouble returning values to other functions at different calling points.
Thank you for your advice in advance.