HVAC consumption controller

Hi IronBug users,

Do you have any examples that use the scripts (Python/C#) to implement a PID controller (or any other controller except adaptive ON/OFF sensor) for HVAC systems?

If so, would it be possible to share? I need to get inspiration from the example to understand how to employ a controller.

Thank you very much for your time and support.

Sincerely,
Behnam
Maynooth, Ireland

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.

1 Like

Hi @TrevorFedyna :smiley:

Thanks very much. This helps me a lot to start.

Thanks a myriad for your time and sharing.

Sincerely,
Behnam

no problem!
Would be happy to aide in further workflow development.
best
-trevor

1 Like