Hello @behnammmohseni!
So my old laptop was stolen so i dont have any used examples but this should be a general example using python specifically the eppy library: (the following has not been tested)
from eppy.modeleditor import IDF
# Load IDF file
idf = IDF("input.idf")
# Define EMS Sensor (Zone Air Temperature)
zone_name = "SPACE1-1" # Replace with your zone name
sensor = idf.newidfobject(
"EnergyManagementSystem:Sensor",
Name="ZoneTempSensor",
OutputVariable_or_OutputMeter_Index_Key_Name=zone_name,
OutputVariable_or_OutputMeter_Name="Zone Mean Air Temperature"
)
# Define EMS Actuator (Chilled Water Coil Valve Mass Flow Rate)
coil_name = "Cooling Coil Water Valve" # Replace with your coil actuator name
actuator = idf.newidfobject(
"EnergyManagementSystem:Actuator",
Name="CoolingValveActuator",
Actuated_Component_Unique_Name=coil_name,
Actuated_Component_Type="Plant Component Cooling Demand",
Actuated_Component_Control_Type="Mass Flow Rate"
)
# Define EMS Internal Variable (System timestep)
sys_time = idf.newidfobject(
"EnergyManagementSystem:InternalVariable",
Name="SysTime",
Internal_Data_Index_Key_Name="SystemTimeStep"
)
# Define EMS Global Variables (to hold previous values)
global_vars = ["IntegralError", "PrevError"]
idf.newidfobject(
"EnergyManagementSystem:GlobalVariable",
Erl_Variable_1_Name=global_vars[0],
Erl_Variable_2_Name=global_vars[1]
)
# Define EMS Program (PID logic)
ems_program = idf.newidfobject(
"EnergyManagementSystem:Program",
Name="PID_Control_Prog",
Program_Line_1="SET T_setpoint = 22.0,", # °C Setpoint
Program_Line_2="Kp = 0.05,", # Proportional Gain
Program_Line_3="Ki = 0.01,", # Integral Gain
Program_Line_4="Kd = 0.02;", # Derivative Gain
Program_Line_5="SET Error = ZoneTempSensor - T_setpoint;",
Program_Line_6="SET IntegralError = IntegralError + Error * SysTime;",
Program_Line_7="SET DerivativeError = (Error - PrevError) / SysTime;",
Program_Line_8="SET PID_Output = (Kp*Error) + (Ki*IntegralError) + (Kd*DerivativeError);",
Program_Line_9="IF PID_Output > 0.05,",
Program_Line_10="SET PID_Output = 0.05;",
Program_Line_11="ELSEIF PID_Output < 0,",
Program_Line_12="SET PID_Output = 0;",
Program_Line_13="ENDIF;",
Program_Line_14="SET CoolingValveActuator = PID_Output;",
Program_Line_15="SET PrevError = Error;"
)
# Define Program Calling Managers
idf.newidfobject(
"EnergyManagementSystem:ProgramCallingManager",
Name="PID_Controller_Manager",
EnergyPlus_Model_Calling_Point="AfterPredictorAfterHVACManagers",
Program_Name_1="PID_Control_Prog"
)
# Initialize PID variables at simulation start
init_program = idf.newidfobject(
"EnergyManagementSystem:Program",
Name="PID_Initialization",
Program_Line_1="SET IntegralError = 0.0;",
Program_Line_2="SET PrevError = 0.0;"
)
idf.newidfobject(
"EnergyManagementSystem:ProgramCallingManager",
Name="Init_PID_Manager",
EnergyPlus_Model_Calling_Point="BeginNewEnvironment",
Program_Name_1="PID_Initialization"
)
# Save modified IDF
idf.saveas("output_pid.idf")
Hopefully that is of some help!
best
-trevor
Also you should be able to emulate similar with ironbug ems components I’d think.