Validation model for single zone VAV AHU outdoor and return air damper position modulation sequence. This example validates

Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Subsequences.Modulation
for supply air temeperature TSup and supply air temperature heating setpoint TSupSet
control signals.

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Subsequences.Validation;
model Modulation_TSup
  "Validation model for single zone VAV AHU outdoor and return air damper position modulation sequence"

  final parameter Real TSupSet(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")=291.15
    "Supply air temperature setpoint";

  Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Subsequences.Modulation
    mod "Economizer modulation sequence"

  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TSupSetSig(
    final k=TSupSet) "Supply air temperature setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp TSup(
    final duration=900,
    final height=4,
    final offset=TSupSet - 2) "Measured supply air temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant outDamPosMin(final k=0.1)
    "Minimum outdoor air damper position"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant outDamPosMax(final k=0.9)
    "Maximum outdoor air damper position"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant RetDamPosMin(final k=0.1)
    "Minimum return air damper position"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant RetDamPosMax(final k=0.9)
    "Maximum return air damper position"

  Buildings.Controls.OBC.CDL.Logical.Sources.Constant fanStatus(k=true)
    "Fan is on"
equation
  connect(TSupSetSig.y, mod.TSupHeaEcoSet)
  connect(TSup.y,mod.TSup)
  connect(RetDamPosMax.y, mod.uRetDam_max)
  connect(RetDamPosMin.y, mod.uRetDam_min)
  connect(outDamPosMax.y, mod.uOutDam_max)
  connect(outDamPosMin.y, mod.uOutDam_min)
  connect(mod.u1SupFan, fanStatus.y)
end Modulation_TSup;


Collection of validation models

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Subsequences;
package Validation "Collection of validation models"
end Validation;


Validation model for disabling the single zone VAV AHU economizer modulation and damper position limit control loops. This example validates

Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Controller
for control signals which disable modulation control loop only (economizer block)
and both minimum outdoor airflow and modulation control loops (economizer1 block).

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Validation;
model Controller_Disable
  "Validation model for disabling the single zone VAV AHU economizer modulation and damper position limit control loops"

  Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Controller economizer(
    final eneStd=Buildings.Controls.OBC.ASHRAE.G36.Types.EnergyStandard.ASHRAE90_1,
    final ecoHigLimCon=Buildings.Controls.OBC.ASHRAE.G36.Types.ControlEconomizer.FixedEnthalpyWithFixedDryBulb,
    final ashCliZon=Buildings.Controls.OBC.ASHRAE.G36.Types.ASHRAEClimateZone.Zone_1A,
    final supFanSpe_min=supFanSpe_min,
    final supFanSpe_max=supFanSpe_max,
    final VOutMin_flow=VOutMin_flow,
    final VOutDes_flow=VOutDes_flow) "Single zone VAV AHU economizer"

  Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Controller economizer1(
    final eneStd=Buildings.Controls.OBC.ASHRAE.G36.Types.EnergyStandard.ASHRAE90_1,
    final ecoHigLimCon=Buildings.Controls.OBC.ASHRAE.G36.Types.ControlEconomizer.FixedEnthalpyWithFixedDryBulb,
    final ashCliZon=Buildings.Controls.OBC.ASHRAE.G36.Types.ASHRAEClimateZone.Zone_1A,
    final supFanSpe_min=supFanSpe_min,
    final supFanSpe_max=supFanSpe_max,
    final VOutMin_flow=VOutMin_flow,
    final VOutDes_flow=VOutDes_flow) "Single zone VAV AHU economizer"

protected
  final parameter Real TOutCutoff(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")=297.15
    "Outdoor temperature high limit cutoff";
  final parameter Real hOutCutoff(
    final unit="J/kg",
    final quantity="SpecificEnergy")=65100
    "Outdoor air enthalpy high limit cutoff";
  final parameter Real TSupSet(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")=291.15
    "Supply air temperature setpoint";
  final parameter Real supFanSpe_min(
    final min=0,
    final max=1,
    final unit="1")=0.1 "Minimum supply fan operation speed";
  final parameter Real supFanSpe_max(
    final min=0,
    final max=1,
    final unit="1")=0.9 "Maximum supply fan operation speed";
  final parameter Real VOutMin_flow(
    final unit="m3/s",
    final quantity="VolumeFlowRate")=1.0
    "Calculated minimum outdoor airflow rate";
  final parameter Real VOutDes_flow(
    final unit="m3/s",
    final quantity="VolumeFlowRate")=2.0
    "Calculated design outdoor airflow rate";

  Buildings.Controls.OBC.CDL.Logical.Sources.Constant fanSta(
    final k=true) "Fan is on"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant freProSta(
    final k=Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeProtectionStages.stage0)
    "Freeze protection stage is 0"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant zonSta(
    final k=Buildings.Controls.OBC.ASHRAE.G36.Types.ZoneStates.heating)
    "Zone State is heating"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant opeMod(
    final k=Buildings.Controls.OBC.ASHRAE.G36.Types.OperationModes.occupied)
     "AHU operation mode is Occupied"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant hOutBelowCutoff(
    final k=hOutCutoff - 40000)
    "Outdoor air enthalpy is below the cutoff"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TSupSetSig(
    final k=TSupSet) "Heating supply air temperature setpoint"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant freProSta2(
    final k=Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeProtectionStages.stage2)
    "Freeze protection stage is 2"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TOutBelowCutoff(
    final k=TOutCutoff - 30)
    "Outdoor air temperature is below the cutoff"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp TSup(
    final height=4,
    final offset=TSupSet - 2,
    final duration=1800) "Supply air temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp VOutMinSetSig(
    final duration=1800,
    final offset=VOutMin_flow,
    final height=VOutDes_flow - VOutMin_flow)
    "Minimum outdoor airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp SupFanSpeSig(
    final duration=1800,
    final offset=supFanSpe_min,
    final height=supFanSpe_max - supFanSpe_min) "Supply fan speed signal"

equation
  connect(fanSta.y, economizer.u1SupFan)
  connect(hOutBelowCutoff.y, economizer.hOut)
  connect(TSup.y, economizer.TAirSup)
  connect(TOutBelowCutoff.y, economizer1.TOut)
  connect(hOutBelowCutoff.y, economizer1.hOut)
  connect(TSup.y, economizer1.TAirSup)
  connect(fanSta.y, economizer1.u1SupFan)
  connect(freProSta2.y, economizer1.uFreProSta)
  connect(zonSta.y, economizer.uZonSta)
  connect(opeMod.y, economizer.uOpeMod)
  connect(opeMod.y, economizer1.uOpeMod)
  connect(zonSta.y, economizer1.uZonSta)
  connect(VOutMinSetSig.y, economizer.VOutMinSet_flow)
  connect(SupFanSpeSig.y, economizer.uSupFan_actual)
  connect(VOutMinSetSig.y, economizer1.VOutMinSet_flow)
  connect(SupFanSpeSig.y, economizer1.uSupFan_actual)
  connect(freProSta.y, economizer.uFreProSta)
  connect(TSupSetSig.y, economizer1.TSupHeaEcoSet)
  connect(TOutBelowCutoff.y, economizer.TOut)
  connect(TSupSetSig.y, economizer.TSupHeaEcoSet)
end Controller_Disable;


Validation model for single zone VAV AHU economizer operation: damper modulation and minimum ooutdoor air requirement damper position limits. This example validates

Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Controller control loops:
minimum outdoor air damper position limits control loop (economizer block) and modulation
control loop (economizer1 block) for VOut_flow and TSup control signals.
Both control loops are enabled during the validation test.

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Validation;
model Controller_Mod_DamLim
  "Validation model for single zone VAV AHU economizer operation: damper modulation and minimum ooutdoor air requirement damper position limits"

  Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Controller economizer(
    final eneStd=Buildings.Controls.OBC.ASHRAE.G36.Types.EnergyStandard.ASHRAE90_1,
    final ecoHigLimCon=Buildings.Controls.OBC.ASHRAE.G36.Types.ControlEconomizer.FixedEnthalpyWithFixedDryBulb,
    final ashCliZon=Buildings.Controls.OBC.ASHRAE.G36.Types.ASHRAEClimateZone.Zone_1A,
    final supFanSpe_min=supFanSpe_min,
    final supFanSpe_max=supFanSpe_max,
    final VOutMin_flow=VOutMin_flow,
    final VOutDes_flow=VOutDes_flow) "Single zone VAV AHU economizer"

  Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers.Controller economizer1(
    final eneStd=Buildings.Controls.OBC.ASHRAE.G36.Types.EnergyStandard.ASHRAE90_1,
    final ecoHigLimCon=Buildings.Controls.OBC.ASHRAE.G36.Types.ControlEconomizer.FixedDryBulb,
    final ashCliZon=Buildings.Controls.OBC.ASHRAE.G36.Types.ASHRAEClimateZone.Zone_1A,
    final supFanSpe_min=supFanSpe_min,
    final supFanSpe_max=supFanSpe_max,
    final VOutMin_flow=VOutMin_flow,
    final VOutDes_flow=VOutDes_flow) "Single zone VAV AHU economizer"

protected
  parameter Real TOutCutoff(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")=297.15
    "Outdoor temperature high limit cutoff";
  parameter Real hOutCutoff(
    final unit="J/kg",
    final quantity="SpecificEnergy")=65100
    "Outdoor air enthalpy high limit cutoff";
  parameter Real TSupSet(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")=291.15
    "Supply air temperature Heating setpoint";
  parameter Real TSup(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")=290.15
    "Measured supply air temperature";
  parameter Real supFanSpe_min(
    final min=0,
    final max=1,
    final unit="1") = 0.1 "Minimum supply fan operation speed";
  parameter Real supFanSpe_max(
    final min=0,
    final max=1,
    final unit="1") = 0.9 "Maximum supply fan operation speed";
  parameter Real VOutMin_flow(
    final unit="m3/s",
    final quantity="VolumeFlowRate") = 1.0 "Calculated minimum outdoor airflow rate";
  parameter Real VOutDes_flow(
    final unit="m3/s",
    final quantity="VolumeFlowRate") = 2.0 "Calculated design outdoor airflow rate";

  Buildings.Controls.OBC.CDL.Logical.Sources.Constant fanSta(
    k=true) "Fan is on"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant freProSta(
    final k=Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeProtectionStages.stage0)
    "Freeze protection status is 0"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant zonSta(
    final k=Buildings.Controls.OBC.ASHRAE.G36.Types.ZoneStates.deadband)
    "Zone State is deadband"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant opeMod(
    final k=Buildings.Controls.OBC.ASHRAE.G36.Types.OperationModes.occupied)
    "AHU operation mode is Occupied"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant hOutBelowCutoff(
    final k=hOutCutoff - 10000)
    "Outdoor air enthalpy is slightly below the cutoff"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TOutBelowCutoff(
    final k=TOutCutoff - 5)
    "Outdoor air temperature is slightly below the cutoff"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TSupSetSig(
    final k=TSupSet) "Heating supply air temperature setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TSupSig(
    final k=TSup) "Measured supply air temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp TSupSig1(
    final duration=900,
    final height=2,
    final offset=TSupSet - 1) "Measured supply air temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp VOutMinSetSig(
    final duration=1800,
    final offset=VOutMin_flow,
    final height=VOutDes_flow - VOutMin_flow) "Minimum outdoor airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp SupFanSpeSig(
    final duration=1800,
    final offset=supFanSpe_min,
    final height=supFanSpe_max - supFanSpe_min) "Supply fan speed signal"

equation
  connect(fanSta.y, economizer.u1SupFan)
  connect(opeMod.y, economizer.uOpeMod)
  connect(hOutBelowCutoff.y, economizer.hOut)
  connect(TSupSetSig.y, economizer.TSupHeaEcoSet)
  connect(TSupSig.y, economizer.TAirSup)
  connect(TSupSig1.y, economizer1.TAirSup)
  connect(fanSta.y, economizer1.u1SupFan)
  connect(freProSta.y, economizer1.uFreProSta)
  connect(opeMod.y, economizer1.uOpeMod)
  connect(zonSta.y, economizer1.uZonSta)
  connect(VOutMinSetSig.y, economizer.VOutMinSet_flow)
  connect(VOutMinSetSig.y, economizer1.VOutMinSet_flow)
  connect(TOutBelowCutoff.y, economizer1.TOut)
  connect(SupFanSpeSig.y, economizer.uSupFan_actual)
  connect(TOutBelowCutoff.y, economizer.TOut)
  connect(zonSta.y, economizer.uZonSta)
  connect(freProSta.y, economizer.uFreProSta)
  connect(TSupSetSig.y, economizer1.TSupHeaEcoSet)
  connect(SupFanSpeSig.y, economizer1.uSupFan_actual)
end Controller_Mod_DamLim;


Collection of validation models

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.Economizers;
package Validation "Collection of validation models"
end Validation;


Controller for cooling coil valve. This block outputs the cooling coil control signal if the fan is on and the zone is
in cooling status (see

Buildings.Controls.OBC.ASHRAE.G36.Types.ZoneStates).
Otherwise, the control signal for the coil is set to 0.
The implementation is according to the Section 5.18.5.3 of ASHRAE Guideline 36, May 2020.

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.SetPoints;
block CoolingCoil "Controller for cooling coil valve"

  parameter Buildings.Controls.OBC.CDL.Types.SimpleController controllerTypeCooCoi=
    Buildings.Controls.OBC.CDL.Types.SimpleController.PI
    "Type of controller"
  parameter Real kCooCoi(final unit="1/K")=0.1
    "Gain for cooling coil control loop signal"
  parameter Real TiCooCoi(final unit="s")=900
    "Time constant of integrator block for cooling coil control loop signal"
  parameter Real TdCooCoi(final unit="s")=0.1
    "Time constant of derivative block for cooling coil control loop signal"

  Buildings.Controls.OBC.CDL.Interfaces.RealInput TSupCooSet(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    "Cooling supply air temperature setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TAirSup(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    "Supply air temperature measurement"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uZonSta "Zone state"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1SupFan
    "Supply fan proven on"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yCooCoi
    "Cooling coil valve commanded position"

  Buildings.Controls.OBC.CDL.Reals.PIDWithReset conCoi(
    final controllerType=controllerTypeCooCoi,
    final k=kCooCoi,
    final Ti=TiCooCoi,
    final Td=TdCooCoi,
    final reverseActing=false)
    "Cooling coil control signal"

protected
  Buildings.Controls.OBC.CDL.Integers.Equal intEqu
    "Logical block to check if zone is in cooling state"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt(
    final k=Buildings.Controls.OBC.ASHRAE.G36.Types.ZoneStates.cooling)
    "Cooling state value"
  Buildings.Controls.OBC.CDL.Reals.Switch switch "Switch to assign cooling coil control signal"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant const(k=0) "Cooling off mode"
  Buildings.Controls.OBC.CDL.Logical.And and2 "Conditions for cooling state"

equation
  connect(const.y, switch.u3)
  connect(conCoi.trigger, u1SupFan)
  connect(conCoi.u_s, TSupCooSet)
  connect(conCoi.u_m, TAirSup)
  connect(switch.y, yCooCoi)
  connect(intEqu.y, and2.u1)
  connect(and2.u2, u1SupFan)
  connect(and2.y, switch.u2)
  connect(conInt.y, intEqu.u1)
  connect(uZonSta, intEqu.u2)
  connect(conCoi.y, switch.u1)
end CoolingCoil;


Freeze protection sequence for single zone air handling unit. Freeze protection sequence for single zone AHU system. It is developed based on Section
5.18.11 of ASHRAE Guideline 36, May 2020.

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.SetPoints;
block FreezeProtection
  "Freeze protection sequence for single zone air handling unit"

  parameter Boolean have_frePro=true
    "True: enable freeze protection"
  parameter Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl buiPreCon=
      Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReliefDamper
    "Type of building pressure control system"
  parameter Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat freSta=Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.No_freeze_stat
    "Type of freeze stat"
  parameter Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil heaCoi=Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Heating coil type"
  parameter Integer minHotWatReq=2
    "Minimum heating hot-water plant request to active the heating plant"
  parameter Buildings.Controls.OBC.CDL.Types.SimpleController heaCoiCon=
    Buildings.Controls.OBC.CDL.Types.SimpleController.PI
    "Heating coil controller"
  parameter Real k(unit="1")=1
    "Gain of coil controller"
  parameter Real Ti(unit="s")=0.5
    "Time constant of integrator block"
  parameter Real Td(unit="s")=0.1
    "Time constant of derivative block"
  parameter Real yMax=1
    "Upper limit of output"
  parameter Real yMin=0
    "Lower limit of output"
  parameter Real Thys(unit="K")=0.25
    "Hysteresis for checking temperature difference"

  Buildings.Controls.OBC.CDL.Interfaces.RealInput uOutDamPosMin(
    final min=0,
    final max=1,
    final unit="1") if have_frePro
    "Minimum economizer damper position limit as returned by the damper position limits  sequence"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uOutDam(
    final min=0,
    final max=1,
    final unit="1") "Economizer outdoor air damper commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uHeaCoi(
    final min=0,
    final max=1,
    final unit="1") if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased "Heating coil valve commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uRetDam(
    final min=0,
    final max=1,
    final unit="1") "Economizer return air damper commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TAirSup(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature") if have_frePro
    "Measured supply air temperature"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1FreSta if freSta ==
    Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_BAS and
    have_frePro
    "Freeze protection stat signal. The stat is normally close (the input is normally true), when enabling freeze protection, the input becomes false"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1SofSwiRes if (freSta ==
    Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.No_freeze_stat or freSta ==
    Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment)
     and have_frePro
    "Freeze protection reset signal from software switch"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1SupFan
    "Supply fan commanded on"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uSupFan(
    final min=0,
    final max=1,
    final unit="1")
    "Supply fan commanded speed"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1RetFan if (buiPreCon ==
    Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanMeasuredAir
     or buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanDp)
    "Return fan commanded on"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uRetFan(
    final min=0,
    final max=1,
    final unit="1") if (buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanMeasuredAir
     or buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanDp)
    "Return fan commanded speed"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1RelFan if buiPreCon ==
    Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReliefFan
    "Relief fan commanded on"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uRelFan(
    final min=0,
    final max=1,
    final unit="1") if (buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReliefFan)
    "Relief fan commanded speed"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uCooCoi(
    final min=0,
    final max=1,
    final unit="1") "Cooling coil valve commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TAirMix(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature") if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and
    have_frePro
    "Measured mixed air temperature"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yFreProSta
    "Freeze protection stage index"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1EneCHWPum
    if have_frePro
    "Energize chilled water pump"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yRetDam(
    final min=0,
    final max=1,
    final unit="1")
    "Return air damper commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yOutDam(
    final min=0,
    final max=1,
    final unit="1")
    "Outdoor air damper commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1SupFan
    "Supply fan commanded on"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput ySupFan(
    final min=0,
    final max=1,
    final unit="1")
    "Supply fan commanded speed"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1RetFan if (buiPreCon
     == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanMeasuredAir
     or buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanDp)
    "Return fan commanded on"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yRetFan(
    final min=0,
    final max=1,
    final unit="1") if (buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanMeasuredAir
     or buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanDp)
    "Return fan commanded speed"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1RelFan if buiPreCon ==
    Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReliefFan
    "Relief fan commanded on"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yRelFan(
    final min=0,
    final max=1,
    final unit="1") if (buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReliefFan)
    "Relief fan commanded speed"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yCooCoi(
    final min=0,
    final max=1,
    final unit="1") "Cooling coil valve commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yHeaCoi(
    final min=0,
    final max=1,
    final unit="1") if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased "Heating coil valve commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yHotWatPlaReq
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Request to heating hot-water plant"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yAla if have_frePro
    "Alarm level"

protected
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr(
    final t=273.15 + 4,
    final h=Thys) if have_frePro
    "Check if supply air temperature is less than threshold"
  Buildings.Controls.OBC.CDL.Logical.Timer tim(
    final t=300) if have_frePro
    "Check if the supply air temperature has been lower than threshold value for sufficient long time"
  Buildings.Controls.OBC.CDL.Integers.Switch hotWatPlaReq
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and have_frePro
    "Hot water plant request in stage 1 mode"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt(
    final k=minHotWatReq) if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and have_frePro
    "Minimum hot-water plant requests"
  Buildings.Controls.OBC.CDL.Reals.Switch minVen if have_frePro
    "Minimum ventilation when in stage 1 mode"
  Buildings.Controls.OBC.CDL.Reals.PID heaCoiCon1(
    final controllerType=heaCoiCon,
    final k=k,
    final Ti=Ti,
    final Td=Td,
    final yMax=yMax,
    final yMin=yMin) if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and have_frePro
    "Heating coil control in stage 1 mode"
  Buildings.Controls.OBC.CDL.Reals.Switch heaCoi1
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and have_frePro
    "Heating coil position"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr(
    final t=273.15 + 7,
    final h=Thys) if have_frePro
    "Check if supply air temperature is greater than threshold"
  Buildings.Controls.OBC.CDL.Logical.Latch lat if have_frePro
    "Stay in stage 1 freeze protection mode"
  Buildings.Controls.OBC.CDL.Logical.Timer tim1(
    final t=300) if have_frePro
    "Check if the supply air temperature has been lower than threshold value for sufficient long time"
  Buildings.Controls.OBC.CDL.Logical.Edge endStaOne if have_frePro
    "Clear the latch to end the stage 1 freeze protection"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr1(
    final t=273.15 + 3,
    final h=Thys) if have_frePro
    "Check if supply air temperature is less than threshold"
  Buildings.Controls.OBC.CDL.Logical.Timer tim2(
    final t=300) if have_frePro
    "Check if the supply air temperature has been lower than threshold value for sufficient long time"
  Buildings.Controls.OBC.CDL.Logical.TrueFalseHold holSta2(
    final trueHoldDuration=3600,
    final falseHoldDuration=0) if have_frePro
    "Stage in stage 2 freeze protection mode"
  Buildings.Controls.OBC.CDL.Reals.Switch outDam2 if have_frePro
    "Outdoor air damper position"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant con(final k=0.0)
               if have_frePro
    "Fully closed damper position"
  Buildings.Controls.OBC.CDL.Reals.Switch retDam2 if have_frePro
    "Return air damper position"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant con1(final k=1.0)
               if have_frePro
    "Fully open damper or valve position"
  Buildings.Controls.OBC.CDL.Integers.Switch intSwi1 if have_frePro
    "Alarm when it is in stage 2 mode"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt1(
    final k=3) if have_frePro
    "Level 3 alarm"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt2(
    final k=0) if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and have_frePro
    "Zero request"
  Buildings.Controls.OBC.CDL.Logical.Timer tim3(
    final t=900) if have_frePro
    "Check if the supply air temperature has been lower than threshold value for sufficient long time"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr2(
    final t=273.15 + 1,
    final h=Thys) if have_frePro
    "Check if supply air temperature is less than threshold"
  Buildings.Controls.OBC.CDL.Logical.Timer tim4(
    final t=300) if have_frePro
    "Check if the supply air temperature has been lower than threshold value for sufficient long time"
  Buildings.Controls.OBC.CDL.Logical.Or or7 if have_frePro
    "Check if it should be in stage 3 mode"
  Buildings.Controls.OBC.CDL.Logical.Latch lat1 if have_frePro
    "Stay in stage 3 freeze protection mode"
  Buildings.Controls.OBC.CDL.Reals.Switch supFan if not freSta ==
    Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Supply fan speed"
  Buildings.Controls.OBC.CDL.Reals.Switch retFan if (buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanMeasuredAir
     or buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanDp)
     and not freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Return fan speed"
  Buildings.Controls.OBC.CDL.Reals.Switch relFan if (buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReliefFan)
     and not freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Relief fan speed"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant con3(
    final k=0) if have_frePro
    "Zero constant"
  Buildings.Controls.OBC.CDL.Reals.Switch outDam if not freSta ==
    Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Outdoor air damper"
  Buildings.Controls.OBC.CDL.Reals.Switch cooCoi if not freSta ==
    Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Cooling coil position"
  Buildings.Controls.OBC.CDL.Integers.Switch hotWatPlaReq3
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and have_frePro
    "Hot water plant request in stage 3 mode"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt3(
    final k=minHotWatReq) if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and have_frePro
    "Minimum hot-water plant requests"
  Buildings.Controls.OBC.CDL.Reals.Max max1
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and have_frePro
    "Higher of supply air and mixed air temperature"
  Buildings.Controls.OBC.CDL.Reals.PID heaCoiMod(
    final controllerType=heaCoiCon,
    final k=k,
    final Ti=Ti,
    final Td=Td,
    final yMax=yMax,
    final yMin=yMin) if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and have_frePro
    "Heating coil control when it is in stage 3 mode"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant con4(
    final k=273.15 + 27) if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and have_frePro
    "Setpoint temperature"
  Buildings.Controls.OBC.CDL.Reals.Switch heaCoiPos if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and
    not freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Heating coil position"
  Buildings.Controls.OBC.CDL.Integers.Switch intSwi3 if have_frePro
    "Alarm level"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt4(
    final k=2) if have_frePro
               "Level 2 alarm"
  Buildings.Controls.OBC.CDL.Utilities.Assert shuDowWar(
    final message="Warning: the unit is shut down by freeze protection!")
    if have_frePro
    "Unit shut down warning"
  Buildings.Controls.OBC.CDL.Logical.Not not1 if have_frePro
    "Logical not"
  Buildings.Controls.OBC.CDL.Utilities.Assert disMinVenWar(
    final message="Warning: minimum ventilation was interrupted by freeze protection!")
    if have_frePro
    "Warning of disabling minimum ventilation "
  Buildings.Controls.OBC.CDL.Logical.Not not2 if have_frePro
    "Logical not"
  Buildings.Controls.OBC.CDL.Logical.Timer tim5(
    final t=3600) if have_frePro
    "Check if it has been in stage 2 for sufficient long time"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt5(
    final k=0) if have_frePro
    "Level 0 alarm"
  Buildings.Controls.OBC.CDL.Logical.Latch lat2 if have_frePro
    "Stay in stage 2 freeze protection mode"
  Buildings.Controls.OBC.CDL.Logical.Edge endStaTwo if have_frePro
    "Clear the latch to end the stage 2 freeze protection"
  Buildings.Controls.OBC.CDL.Logical.Or or2 if have_frePro
    "Start stage 1 freeze protection mode"
  Buildings.Controls.OBC.CDL.Logical.FallingEdge falEdg if have_frePro
    "Switch from stage 2 to stage 1"
  Buildings.Controls.OBC.CDL.Reals.Switch retDam if not freSta ==
    Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Return air damper position"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant supTemSet(
    final k=273.15+ 6) if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and have_frePro
    "Supply air temperature setpoint"
  Buildings.Controls.OBC.CDL.Integers.Switch intSwi2 if have_frePro
    "Alarm level"
  Buildings.Controls.OBC.CDL.Integers.Switch intSwi4 if have_frePro
    "Alarm level"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt6(
    final k=2) if have_frePro
    "Stage 2 freeze protection"
  Buildings.Controls.OBC.CDL.Integers.Switch intSwi5 if have_frePro
    "Alarm level"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt7(
    final k=1) if have_frePro
    "Stage 1 freeze protection"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt8(
    final k=0) if have_frePro
    "Stage 0 freeze protection"
  Buildings.Controls.OBC.CDL.Logical.FallingEdge falEdg1 if freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_BAS
     and have_frePro
    "Reset the freeze protection by the physical reset switch in freeze stat"
  Buildings.Controls.OBC.CDL.Logical.Not norFal if freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_BAS
     and have_frePro
    "The output is normally false"
  Buildings.Controls.OBC.CDL.Logical.Sources.Constant con2(
    final k=false) if not freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_BAS
     and have_frePro
    "Constant false"
  Buildings.Controls.OBC.CDL.Logical.Not norSta1 if buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReliefFan
     and have_frePro
    "Not in stage 3"
  Buildings.Controls.OBC.CDL.Logical.And and2 if (buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReliefFan)
     and not freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Disable relief fan when in stage 3"
  Buildings.Controls.OBC.CDL.Logical.And and1 if (buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanMeasuredAir
     or buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanDp)
     and not freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Disable return fan when in stage 3"
  Buildings.Controls.OBC.CDL.Logical.Not norSta2 if (buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanMeasuredAir
     or buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanDp)
     and have_frePro
    "Not in stage 3"
  Buildings.Controls.OBC.CDL.Logical.Not norSta3 if have_frePro
    "Not in stage 3"
  Buildings.Controls.OBC.CDL.Logical.And and3 if not freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Disable supply fan when in stage 3"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai4(final k=1)
 if freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai1(final k=1)
 if freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Logical.Or or1 if freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     or not have_frePro
    "Dummy block for enabling and disabling conditional connection"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai2(final k=1)
 if freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Logical.Or or4 if (buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanMeasuredAir
     or buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanDp)
     and (freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     or not have_frePro)
    "Dummy block for enabling and disabling conditional connection"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai3(final k=1) if (
    buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanMeasuredAir
     or buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanDp)
     and freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Logical.Or or5 if (buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReliefFan)
     and (freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     or not have_frePro)
    "Dummy block for enabling and disabling conditional connection"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai5(final k=1) if (
    buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReliefFan)
     and freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai6(final k=1)
 if freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     and have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai7(final k=1)
 if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased and (freSta == Buildings.Controls.OBC.ASHRAE.G36.Types.FreezeStat.Hardwired_to_equipment
     or not have_frePro)
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Logical.Pre pre if have_frePro
    "Break loop"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt9(final k=0)
    if not have_frePro "Dummy constant"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt10(final k=0)
    if not have_frePro "Dummy constant"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai8(final k=1)
    if not have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai9(final k=1)
    if not have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai10(final k=1)
    if not have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai11(final k=1) if (
    buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanMeasuredAir
     or buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReturnFanDp)
     and not have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai12(final k=1) if (
    buiPreCon == Buildings.Controls.OBC.ASHRAE.G36.Types.PressureControl.ReliefFan)
     and not have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai13(final k=1)
    if not have_frePro
    "Dummy block for enabling and disabling the conditional connection"
  Buildings.Controls.OBC.CDL.Logical.Or or6 if have_frePro
    "Check if it should be in stage 3 mode"

equation
  connect(lesThr.y, tim.u)
  connect(TAirSup, lesThr.u)
  connect(conInt.y, hotWatPlaReq.u1)
  connect(uOutDamPosMin, minVen.u1)
  connect(supTemSet.y, heaCoiCon1.u_s)
  connect(TAirSup, heaCoiCon1.u_m)
  connect(heaCoiCon1.y, heaCoi1.u1)
  connect(TAirSup, greThr.u)
  connect(greThr.y, tim1.u)
  connect(tim1.passed, endStaOne.u)
  connect(endStaOne.y, lat.clr)
  connect(lat.y, hotWatPlaReq.u2)
  connect(lat.y, minVen.u2)
  connect(lat.y, heaCoi1.u2)
  connect(TAirSup, lesThr1.u)
  connect(lesThr1.y, tim2.u)
  connect(tim2.passed, holSta2.u)
  connect(con.y, outDam2.u1)
  connect(con1.y, retDam2.u1)
  connect(uRetDam, retDam2.u3)
  connect(conInt1.y, intSwi1.u1)
  connect(lesThr1.y, tim3.u)
  connect(TAirSup, lesThr2.u)
  connect(u1SofSwiRes, lat1.clr)
  connect(lat1.y, retFan.u2)
  connect(lat1.y, relFan.u2)
  connect(con3.y, supFan.u1)
  connect(con3.y, retFan.u1)
  connect(con3.y, relFan.u1)
  connect(uSupFan, supFan.u3)
  connect(uRetFan, retFan.u3)
  connect(uRelFan, relFan.u3)
  connect(supFan.y, ySupFan)
  connect(relFan.y, yRelFan)
  connect(retFan.y, yRetFan)
  connect(con3.y, outDam.u1)
  connect(lat1.y, outDam.u2)
  connect(uCooCoi, cooCoi.u3)
  connect(lat1.y, cooCoi.u2)
  connect(con1.y, cooCoi.u1)
  connect(conInt3.y, hotWatPlaReq3.u1)
  connect(lat1.y, hotWatPlaReq3.u2)
  connect(TAirMix, max1.u2)
  connect(TAirSup, max1.u1)
  connect(max1.y, heaCoiMod.u_m)
  connect(con4.y, heaCoiMod.u_s)
  connect(heaCoiMod.y, heaCoiPos.u1)
  connect(lat1.y, heaCoiPos.u2)
  connect(lat1.y, intSwi3.u2)
  connect(conInt4.y, intSwi3.u1)
  connect(lat1.y, not1.u)
  connect(not1.y, shuDowWar.u)
  connect(not2.y, disMinVenWar.u)
  connect(holSta2.y, tim5.u)
  connect(uOutDam, minVen.u3)
  connect(minVen.y, outDam2.u3)
  connect(outDam2.y, outDam.u3)
  connect(conInt2.y, hotWatPlaReq.u3)
  connect(conInt5.y, intSwi1.u3)
  connect(intSwi1.y, intSwi3.u3)
  connect(intSwi3.y, yAla)
  connect(hotWatPlaReq.y, hotWatPlaReq3.u3)
  connect(hotWatPlaReq3.y, yHotWatPlaReq)
  connect(uHeaCoi, heaCoi1.u3)
  connect(heaCoi1.y, heaCoiPos.u3)
  connect(heaCoiPos.y, yHeaCoi)
  connect(tim5.passed, endStaTwo.u)
  connect(endStaTwo.y, lat2.clr)
  connect(lat2.y, outDam2.u2)
  connect(lat2.y, not2.u)
  connect(lat2.y, retDam2.u2)
  connect(lat2.y, intSwi1.u2)
  connect(or2.y, lat.u)
  connect(falEdg.y, or2.u2)
  connect(lat2.y, falEdg.u)
  connect(lat1.y, retDam.u2)
  connect(con3.y, retDam.u1)
  connect(retDam2.y, retDam.u3)
  connect(retDam.y, yRetDam)
  connect(lat1.y, y1EneCHWPum)
  connect(outDam.y, yOutDam)
  connect(cooCoi.y, yCooCoi)
  connect(conInt1.y, intSwi2.u1)
  connect(lat1.y, intSwi2.u2)
  connect(lat2.y, intSwi4.u2)
  connect(conInt6.y, intSwi4.u1)
  connect(intSwi4.y, intSwi2.u3)
  connect(lat.y, intSwi5.u2)
  connect(intSwi5.y, intSwi4.u3)
  connect(conInt7.y, intSwi5.u1)
  connect(intSwi2.y, yFreProSta)
  connect(conInt8.y, intSwi5.u3)
  connect(u1FreSta, norFal.u)
  connect(falEdg1.y, lat1.clr)
  connect(u1RelFan, and2.u1)
  connect(lat1.y, norSta1.u)
  connect(norSta1.y, and2.u2)
  connect(u1RetFan, and1.u1)
  connect(lat1.y, norSta2.u)
  connect(norSta2.y, and1.u2)
  connect(lat1.y, norSta3.u)
  connect(u1SupFan, and3.u1)
  connect(norSta3.y, and3.u2)
  connect(and2.y, y1RelFan)
  connect(and1.y, y1RetFan)
  connect(and3.y, y1SupFan)
  connect(uRetDam, gai4.u)
  connect(gai4.y, yRetDam)
  connect(uOutDam, gai1.u)
  connect(gai1.y, yOutDam)
  connect(u1SupFan, or1.u1)
  connect(u1SupFan, or1.u2)
  connect(or1.y, y1SupFan)
  connect(uSupFan, gai2.u)
  connect(gai2.y, ySupFan)
  connect(u1RetFan, or4.u1)
  connect(u1RetFan, or4.u2)
  connect(or4.y, y1RetFan)
  connect(uRetFan, gai3.u)
  connect(gai3.y, yRetFan)
  connect(u1RelFan, or5.u1)
  connect(u1RelFan, or5.u2)
  connect(or5.y, y1RelFan)
  connect(uRelFan, gai5.u)
  connect(gai5.y, yRelFan)
  connect(uCooCoi, gai6.u)
  connect(gai6.y, yCooCoi)
  connect(uHeaCoi, gai7.u)
  connect(gai7.y, yHeaCoi)
  connect(lesThr2.y, tim4.u)
  connect(lat1.y, supFan.u2)
  connect(or7.y, pre.u)
  connect(pre.y, lat1.u)
  connect(holSta2.y, lat2.u)
  connect(tim.passed, or2.u1)
  connect(norFal.y, falEdg1.u)
  connect(conInt9.y, yFreProSta)
  connect(conInt10.y, yHotWatPlaReq)
  connect(uRetDam, gai8.u)
  connect(gai8.y, yRetDam)
  connect(uOutDam, gai9.u)
  connect(gai9.y, yOutDam)
  connect(uSupFan, gai10.u)
  connect(gai10.y, ySupFan)
  connect(uRetFan, gai11.u)
  connect(gai11.y, yRetFan)
  connect(uRelFan, gai12.u)
  connect(gai12.y, yRelFan)
  connect(uCooCoi, gai13.u)
  connect(gai13.y, yCooCoi)
  connect(tim3.passed, or6.u1)
  connect(tim4.passed, or6.u2)
  connect(or6.y, or7.u1)
  connect(norFal.y, or7.u2)
  connect(con2.y, or7.u2)
end FreezeProtection;


Output zone setpoint with operation mode selection. Block that outputs the zone setpoint temperature (TCooSet,
THeaSet) and system operation mode (yOpeMod).

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.SetPoints;
block ModeAndSetPoints
  "Output zone setpoint with operation mode selection"

  parameter Boolean have_winSen
    "Check if the zone has window status sensor";
  parameter Boolean have_occSen
    "Check if the zone has occupancy sensor";
  parameter Boolean have_locAdj
    "True: the zone has local setpoint adjustment knob"
  parameter Boolean sepAdj
    "True: cooling and heating setpoint can be adjusted separately"
  parameter Boolean ignDemLim
    "Flag, set to true to exempt individual zone from demand limit setpoint adjustment"
  parameter Real TActCoo_max(
    unit="K",
    displayUnit="degC")=300.15
    "Maximum active cooling setpoint"
  parameter Real TActCoo_min(
    unit="K",
    displayUnit="degC")=295.15
    "Minimum active cooling setpoint"
  parameter Real TActHea_max(
    unit="K",
    displayUnit="degC")=295.15
    "Maximum active heating setpoint"
  parameter Real TActHea_min(
    unit="K",
    displayUnit="degC")=291.15
    "Minimum active heating setpoint"
  parameter Real TWinOpeCooSet(
    unit="K",
    displayUnit="degC")=322.15
    "Cooling setpoint when window is open"
  parameter Real TWinOpeHeaSet(
    unit="K",
    displayUnit="degC")=277.15
    "Heating setpoint when window is open"
  parameter Real incTSetDem_1=0.5
    "Cooling setpoint increase value (degC) when cooling demand limit level 1 is imposed"
  parameter Real incTSetDem_2=1
    "Cooling setpoint increase value (degC) when cooling demand limit level 2 is imposed"
  parameter Real incTSetDem_3=2
    "Cooling setpoint increase value (degC) when cooling demand limit level 3 is imposed"
  parameter Real decTSetDem_1=0.5
    "Heating setpoint decrease value (degC) when heating demand limit level 1 is imposed"
  parameter Real decTSetDem_2=1
    "Heating setpoint decrease value (degC) when heating demand limit level 2 is imposed"
  parameter Real decTSetDem_3=2
    "Heating setpoint decrease value (degC) when heating demand limit level 3 is imposed"
  parameter Real bouLim=1
    "Threshold of temperature difference for indicating the end of setback or setup mode"
  parameter Real uLow=-0.1
    "Low limit of the hysteresis for checking temperature difference"
  parameter Real uHigh=0.1
    "High limit of the hysteresis for checking temperature difference"
  parameter Real preWarCooTim(unit="s")=10800
    "Maximum cool-down or warm-up time"
  parameter Real TZonFreProOn(
    unit="K",
    displayUnit="degC")=277.15
    "Threshold temperature to activate the freeze protection mode"
  parameter Real TZonFreProOff(
    unit="K",
    displayUnit="degC")=280.15
    "Threshold temperature to end the freeze protection mode"

  Buildings.Controls.OBC.CDL.Interfaces.RealInput cooDowTim(
    final unit="s",
    final quantity="Time")
    "Cool-down time retrieved from optimal cool-down block"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput warUpTim(
    final unit="s",
    final quantity="Time") "Warm-up time retrieved from optimal warm-up block"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Win if have_winSen
    "Window status, normally closed (true), when windows open, it becomes false"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TZon(
    final unit="K",
    displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    "Zone temperature"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TOccHeaSet(
    final unit="K",
    displayUnit="degC",
    final quantity="ThermodynamicTemperature") "Occupied heating setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TOccCooSet(
    final unit="K",
    displayUnit="degC",
    final quantity="ThermodynamicTemperature") "Occupied cooling setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TUnoHeaSet(
    final unit="K",
    displayUnit="degC",
    final quantity="ThermodynamicTemperature") "Unoccupied heating setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TUnoCooSet(
    final unit="K",
    displayUnit="degC",
    final quantity="ThermodynamicTemperature") "Unoccupied cooling setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Occ
    "Zone occupancy status according to the schedule: true=occupied, false=unoccupied"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput tNexOcc(
    final unit="s",
    final quantity="Time") "Time to next occupied period"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput setAdj
    if have_locAdj and not sepAdj
    "Setpoint adjustment value"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput cooSetAdj
    if have_locAdj and sepAdj
    "Cooling setpoint adjustment value"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput heaSetAdj
    if have_locAdj and sepAdj "Heating setpoint adjustment value"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1OccSen if have_occSen
    "Occupancy sensor (occupied=true, unoccupied=false)"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uCooDemLimLev
    "Cooling demand limit level"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uHeaDemLimLev
    "Heating demand limit level"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yOpeMod "Operation mode"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput TCooSet(
    final unit="K",
    displayUnit="degC",
    final quantity="ThermodynamicTemperature") "Cooling setpoint temperature"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput THeaSet(
    final unit="K",
    displayUnit="degC",
    final quantity="ThermodynamicTemperature") "Heating setpoint temperature"

  Buildings.Controls.OBC.ASHRAE.G36.ZoneGroups.OperationMode opeModSel(
    final nZon=1,
    final preWarCooTim=preWarCooTim,
    final TZonFreProOn=TZonFreProOn,
    final TZonFreProOff=TZonFreProOff) "Operation mode"
  Buildings.Controls.OBC.ASHRAE.G36.ThermalZones.Setpoints TZonSet(
    final have_occSen=have_occSen,
    final have_winSen=have_winSen,
    final have_locAdj=have_locAdj,
    final sepAdj=sepAdj,
    final ignDemLim=ignDemLim,
    final TActCoo_max=TActCoo_max,
    final TActCoo_min=TActCoo_min,
    final TActHea_max=TActHea_max,
    final TActHea_min=TActHea_min,
    final TWinOpeCooSet=TWinOpeCooSet,
    final TWinOpeHeaSet=TWinOpeHeaSet,
    final incTSetDem_1=incTSetDem_1,
    final incTSetDem_2=incTSetDem_2,
    final incTSetDem_3=incTSetDem_3,
    final decTSetDem_1=decTSetDem_1,
    final decTSetDem_2=decTSetDem_2,
    final decTSetDem_3=decTSetDem_3) "Adjust setpoint temperature"
  Buildings.Controls.OBC.ASHRAE.G36.ZoneGroups.ZoneStatus zonSta(
    final bouLim=bouLim,
    final have_winSen=have_winSen,
    final uLow=uLow,
    final uHigh=uHigh) "Zone temperature status"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger colZon
    "Check if the zone is cold"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger hotZon
    "Check if the zone is hot"
  Buildings.Controls.OBC.CDL.Logical.Sources.Constant winSta(
    final k=true)
    if not have_winSen
    "Assume window is closed when there is no windows status sensor"
  Buildings.Controls.OBC.CDL.Logical.Sources.Constant occSta(
    final k=true) if not have_occSen
    "Assume the zone is occupied when there is no occupancy sensor"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt
    "Boolean to integer"
  Buildings.Controls.OBC.CDL.Logical.Not winOpe "Window is open"
equation
  connect(zonSta.cooDowTim, cooDowTim)
  connect(zonSta.warUpTim, warUpTim)
  connect(zonSta.u1Win, u1Win)
  connect(zonSta.TZon, TZon)
  connect(zonSta.yCooTim, opeModSel.maxCooDowTim)
  connect(zonSta.yWarTim, opeModSel.maxWarUpTim)
  connect(zonSta.yHigOccCoo, opeModSel.u1HigOccCoo)
  connect(zonSta.yOccHeaHig, opeModSel.u1OccHeaHig)
  connect(zonSta.yUnoHeaHig, colZon.u)
  connect(colZon.y, opeModSel.totColZon)
  connect(zonSta.yHigUnoCoo, hotZon.u)
  connect(hotZon.y, opeModSel.totHotZon)
  connect(zonSta.yUnoHeaHig, opeModSel.u1SetBac)
  connect(zonSta.yEndSetBac, opeModSel.u1EndSetBac)
  connect(TZon, opeModSel.TZonMin)
  connect(zonSta.yHigUnoCoo, opeModSel.u1SetUp)
  connect(zonSta.yEndSetUp, opeModSel.u1EndSetUp)
  connect(opeModSel.u1Occ, u1Occ)
  connect(opeModSel.tNexOcc, tNexOcc)
  connect(opeModSel.yOpeMod, TZonSet.uOpeMod)
  connect(TZonSet.uCooDemLimLev, uCooDemLimLev)
  connect(TZonSet.uHeaDemLimLev, uHeaDemLimLev)
  connect(opeModSel.yOpeMod, yOpeMod)
  connect(TZonSet.TCooSet, TCooSet)
  connect(TZonSet.THeaSet, THeaSet)
  connect(booToInt.y, opeModSel.uOpeWin)
  connect(TZonSet.setAdj, setAdj)
  connect(TZonSet.heaSetAdj, heaSetAdj)
  connect(u1OccSen, TZonSet.u1Occ)
  connect(occSta.y, TZonSet.u1Occ)
  connect(u1Win, TZonSet.u1Win)
  connect(cooSetAdj, TZonSet.cooSetAdj)
  connect(TOccHeaSet,zonSta.TOccHeaSet)
  connect(TOccCooSet,zonSta.TOccCooSet)
  connect(TUnoHeaSet,zonSta.TUnoHeaSet)
  connect(TUnoCooSet,zonSta.TUnoCooSet)
  connect(TOccHeaSet, TZonSet.TOccHeaSet)
  connect(TOccCooSet, TZonSet.TOccCooSet)
  connect(TUnoHeaSet, TZonSet.TUnoHeaSet)
  connect(TUnoCooSet, TZonSet.TUnoCooSet)
  connect(winSta.y, winOpe.u)
  connect(winOpe.y, booToInt.u)
  connect(u1Win, winOpe.u)
end ModeAndSetPoints;


Output setpoints for AHU control

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV;
package SetPoints "Output setpoints for AHU control"
end SetPoints;


Output plant requests for single zone air handling unit. This sequence outputs the system reset requests for single zone air handling unit. The
implementation is according to the Section 5.18.15 of ASHRAE Guideline 36, May 2020.

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.SetPoints;
block PlantRequests
  "Output plant requests for single zone air handling unit"

  parameter Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil heaCoi=Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Heating coil type"
  parameter Real Thys = 0.1
    "Hysteresis for checking temperature difference"
  parameter Real posHys = 0.05
    "Hysteresis for checking valve position difference"

  Buildings.Controls.OBC.CDL.Interfaces.RealInput TAirSup(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    "Measured supply air temperature"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TSupCoo(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    "Cooling supply air temperature setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uCooCoi_actual(
    final unit="1",
    final min=0,
    final max=1)
    "Cooling coil valve actual position"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TSupHeaEco(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Heating supply air temperature setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uHeaCoi_actual(
    final unit="1",
    final min=0,
    final max=1) if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Heating coil valve actual position"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yChiWatResReq
    "Chilled water reset request"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yChiPlaReq
    "Chiller plant request"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yHotWatResReq
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Hot water reset request"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yHotWatPlaReq
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Hot water plant request"

protected
  Buildings.Controls.OBC.CDL.Reals.Subtract cooSupTemDif
    "Find the cooling supply temperature difference to the setpoint"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr(
    final t=3,
    final h=Thys)
    "Check if the supply temperature is greater than the setpoint by a threshold value"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr1(
    final t=2,
    final h=Thys)
    "Check if the supply temperature is greater than the setpoint by a threshold value"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel(
    final delayTime=120)
    "Check if the input has been true for a certain time"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel1(
    final delayTime=120)
    "Check if the input has been true for a certain time"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr2(
    final t=0.95,
    final h=posHys)
    "Check if the chilled water valve position is greater than a threshold value"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant thr(
    final k=3) "Constant 3"
  Buildings.Controls.OBC.CDL.Integers.Switch chiWatRes3
    "Send 3 chilled water reset request"
  Buildings.Controls.OBC.CDL.Integers.Switch chiWatRes2
    "Send 2 chilled water reset request"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant two(
    final k=2)
    "Constant 2"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr(
    final t=0.85,
    final h=posHys)
    "Check if the chilled water valve position is less than a threshold value"
  Buildings.Controls.OBC.CDL.Logical.Latch lat
    "Keep true signal until other condition becomes true"
  Buildings.Controls.OBC.CDL.Integers.Switch chiWatRes1
    "Send 1 chilled water reset request"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant one(
    final k=1) "Constant 1"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant zer(
    final k=0) "Constant 0"
  Buildings.Controls.OBC.CDL.Logical.Latch lat1
    "Keep true signal until other condition becomes true"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr1(
    final t=0.1,
    final h=posHys)
    "Check if the chilled water valve position is less than a threshold value"
  Buildings.Controls.OBC.CDL.Integers.Switch intSwi3
    "Send 1 chiller plant request"
  Buildings.Controls.OBC.CDL.Reals.Subtract heaSupTemDif
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Find the heating supply temperature difference to the setpoint"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr3(
    final t=17,
    final h=Thys)
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Check if the supply temperature is less than the setpoint by a threshold value"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr4(
    final t=8,
    final h=Thys)
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Check if the supply temperature is less than the setpoint by a threshold value"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel2(
    final delayTime=300)
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Check if the input has been true for a certain time"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel3(
    final delayTime=300)
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Check if the input has been true for a certain time"
  Buildings.Controls.OBC.CDL.Integers.Switch hotWatRes3
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Send 3 hot water reset request"
  Buildings.Controls.OBC.CDL.Integers.Switch hotWatRes2
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Send 2 hot water reset request"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr2(
    final t=0.85,
    final h=posHys)
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Check if the hot water valve position is less than a threshold value"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr5(
    final t=0.95,
    final h=posHys)
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Check if the hot water valve position is greater than a threshold value"
  Buildings.Controls.OBC.CDL.Logical.Latch lat2
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Keep true signal until other condition becomes true"
  Buildings.Controls.OBC.CDL.Integers.Switch hotWatRes1
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Send 1 hot water reset request"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr3(
    final t=0.1,
    final h=posHys)
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Check if the hot water valve position is less than a threshold value"
  Buildings.Controls.OBC.CDL.Logical.Latch lat3
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Keep true signal until other condition becomes true"
  Buildings.Controls.OBC.CDL.Integers.Switch intSwi1
    if heaCoi==Buildings.Controls.OBC.ASHRAE.G36.Types.HeatingCoil.WaterBased
    "Send 1 hot water plant request"

equation
  connect(TAirSup, cooSupTemDif.u1)
  connect(TSupCoo, cooSupTemDif.u2)
  connect(cooSupTemDif.y, greThr.u)
  connect(greThr.y, truDel.u)
  connect(greThr1.y, truDel1.u)
  connect(cooSupTemDif.y, greThr1.u)
  connect(uCooCoi_actual, greThr2.u)
  connect(truDel.y, chiWatRes3.u2)
  connect(thr.y, chiWatRes3.u1)
  connect(truDel1.y, chiWatRes2.u2)
  connect(two.y, chiWatRes2.u1)
  connect(greThr2.y, lat.u)
  connect(uCooCoi_actual, lesThr.u)
  connect(lesThr.y, lat.clr)
  connect(one.y, chiWatRes1.u1)
  connect(lat.y, chiWatRes1.u2)
  connect(chiWatRes1.y, chiWatRes2.u3)
  connect(chiWatRes2.y, chiWatRes3.u3)
  connect(zer.y, chiWatRes1.u3)
  connect(chiWatRes3.y, yChiWatResReq)
  connect(greThr2.y, lat1.u)
  connect(uCooCoi_actual, lesThr1.u)
  connect(lesThr1.y, lat1.clr)
  connect(lat1.y, intSwi3.u2)
  connect(one.y, intSwi3.u1)
  connect(zer.y, intSwi3.u3)
  connect(intSwi3.y, yChiPlaReq)
  connect(TAirSup, heaSupTemDif.u2)
  connect(greThr3.y, truDel2.u)
  connect(greThr4.y, truDel3.u)
  connect(heaSupTemDif.y, greThr3.u)
  connect(heaSupTemDif.y, greThr4.u)
  connect(truDel2.y, hotWatRes3.u2)
  connect(thr.y, hotWatRes3.u1)
  connect(hotWatRes2.y, hotWatRes3.u3)
  connect(two.y, hotWatRes2.u1)
  connect(truDel3.y, hotWatRes2.u2)
  connect(hotWatRes3.y, yHotWatResReq)
  connect(uHeaCoi_actual, greThr5.u)
  connect(greThr5.y, lat2.u)
  connect(uHeaCoi_actual, lesThr2.u)
  connect(lesThr2.y, lat2.clr)
  connect(lat2.y, hotWatRes1.u2)
  connect(one.y, hotWatRes1.u1)
  connect(zer.y, hotWatRes1.u3)
  connect(hotWatRes1.y, hotWatRes2.u3)
  connect(uHeaCoi_actual, lesThr3.u)
  connect(lesThr3.y, lat3.clr)
  connect(greThr5.y, lat3.u)
  connect(lat3.y, intSwi1.u2)
  connect(one.y, intSwi1.u1)
  connect(zer.y, intSwi1.u3)
  connect(intSwi1.y, yHotWatPlaReq)
  connect(TSupHeaEco, heaSupTemDif.u1)
end PlantRequests;


Relief damper control for AHUs using actuated dampers without fan. Sequence for controlling actuated relief damper yRelDam for AHUs using
actuated relief damper without a fan.
It is implemented according to Section 5.18.8 of ASHRAE Guideline G36, May 2020.

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.SetPoints;
block ReliefDamper
  "Relief damper control for AHUs using actuated dampers without fan"

  parameter Real relDam_min
    "Relief-damper position that maintains a building pressure of 12 Pa while the economizer damper is positioned to provide minimum outdoor air while the supply fan is at minimum speed";
  parameter Real relDam_max
    "Relief-damper position that maintains a building pressure of 12 Pa while the economizer damper is fully open and the fan speed is at cooling maximum";
  parameter Real posHys=0.05
    "Hysteresis for damper position check"

  Buildings.Controls.OBC.CDL.Interfaces.RealInput uOutDam_min(
    final min=0,
    final max=1,
    final unit="1")
    "Outdoor air damper minimum position"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uOutDam(
    final min=0,
    final max=1,
    final unit="1")
    "Outdoor damper position"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1SupFan
    "Supply fan command on"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yRelDam(
    final unit="1",
    final min=0,
    final max=1)
    "Relief damper commanded position"

protected
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr(
    final t=0.05,
    final h=posHys)
    "Check if the outdoor damper is open"
  Buildings.Controls.OBC.CDL.Logical.And and2
    "Check if the relief damper should be open"
  Buildings.Controls.OBC.CDL.Reals.Switch swi
    "Check if relief damper should be enabled"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant zerDam(
    final k=0) "Close damper when disabled"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant minRel(
    final k=relDam_min)
    "Minimum relief damper position"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant maxRel(
    final k=relDam_max)
    "Maximum relief damper position"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant fulOpe(
    final k=1)
    "Fully open relief damper"
  Buildings.Controls.OBC.CDL.Reals.Line relDam(
    final limitBelow=true,
    final limitAbove=true)
    "Relief damper signal is linearly proportional to the control signal between signal limits"

equation
  connect(zerDam.y, swi.u3)
  connect(swi.y, yRelDam)
  connect(greThr.y, and2.u1)
  connect(u1SupFan, and2.u2)
  connect(and2.y, swi.u2)
  connect(uOutDam, relDam.u)
  connect(uOutDam_min, relDam.x1)
  connect(minRel.y, relDam.f1)
  connect(relDam.y, swi.u1)
  connect(uOutDam, greThr.u)
  connect(fulOpe.y, relDam.x2)
  connect(maxRel.y, relDam.f2)
end ReliefDamper;


Sequence for control of relief fan in AHU. Sequence for controling relief fan that is part of AHU. It is developed based on
Section 5.16.9 of ASHRAE Guideline 36, May 2020, with the modification to accommodate
the single relief fan control.

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.SetPoints;
block ReliefFan "Sequence for control of relief fan in AHU"

  parameter Real relFanSpe_min(
    final min=0,
    final max=1)= 0.1
    "Relief fan minimum speed"
  parameter Real dpBuiSet(
    final unit="Pa",
    final quantity="PressureDifference",
    final max=30) = 12
    "Building static pressure difference relative to ambient (positive to pressurize the building)"
  parameter Real k(
    final unit="1") = 1
    "Gain, normalized using dpBuiSet"
  parameter Real hys = 0.005
    "Hysteresis for checking the controller output value"

  Buildings.Controls.OBC.CDL.Interfaces.RealInput dpBui(
    final unit="Pa",
    displayUnit="Pa",
    final quantity="PressureDifference")
    "Building static pressure difference, relative to ambient (positive if pressurized)"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1SupFan
    "AHU supply fan proven on status"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yDpBui(
    final unit="Pa",
    displayUnit="Pa",
    final quantity="PressureDifference")
    "Building static pressure difference, relative to ambient (positive if pressurized)"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yDam(
    final unit="1",
    final min=0,
    final max=1)
    "Damper commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yRelFan(
    final unit="1",
    final max=1)
    "Relief fan commanded speed"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1RelFan
    "Relief fan commanded on"

  Buildings.Controls.OBC.CDL.Reals.MovingAverage movMea(
    final delta=300)
    "Average building static pressure measurement"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant dpBuiSetPoi(
    final k=dpBuiSet)
    "Building pressure setpoint"
  Buildings.Controls.OBC.CDL.Reals.Divide div1
    "Normalized the control error"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conOne(
    final k=1)
    "Constant one"
  Buildings.Controls.OBC.CDL.Reals.PID conP(
    final controllerType=Buildings.Controls.OBC.CDL.Types.SimpleController.P,
    final k=k,
    final reverseActing=false)
    "Building static pressure controller"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr(
    final t=0.05,
    final h=hys)
    "Check if the controller output is greater than threshold"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr(
    final t=0.005,
    final h=hys)
    "Check if the controller output is near zero"
  Buildings.Controls.OBC.CDL.Logical.Timer tim(
    final t=300)
    "Check if the controller output has been near zero for threshold time"
  Buildings.Controls.OBC.CDL.Logical.And and2
    "Check if the controller output is greater than threshold and the relief system has been enabled"
  Buildings.Controls.OBC.CDL.Logical.Latch lat
    "Enable damper"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr2(
    final t=relFanSpe_min + 0.15,
    final h=hys)
    "Check if the controller output is greater than minimum speed plus threshold"
  Buildings.Controls.OBC.CDL.Logical.Timer upTim(
    final t=420)
    "Check if the controller output has been greater than threshold for sufficient long time"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr3(
    final t=relFanSpe_min,
    final h=hys)
    "Check if the controller output is less than minimum speed"
  Buildings.Controls.OBC.CDL.Logical.Timer dowTim(
    final t=300)
    "Check if the controller output has been less than threshold for sufficient long time"
  Buildings.Controls.OBC.CDL.Logical.Latch lat1
    "Stage down lag fan"
  Buildings.Controls.OBC.CDL.Logical.Or relDam
    "Open relief damper"
  Buildings.Controls.OBC.CDL.Logical.And relFan
    "Turn on relief fan"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea2
    "Convert boolean to real"
  Buildings.Controls.OBC.CDL.Reals.Multiply pro1 "Relief fan speed"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea1
    "Convert boolean to real"

equation
  connect(dpBui, movMea.u)
  connect(dpBuiSetPoi.y, div1.u2)
  connect(movMea.y, div1.u1)
  connect(div1.y, conP.u_m)
  connect(conOne.y, conP.u_s)
  connect(conP.y, greThr.u)
  connect(greThr.y, and2.u1)
  connect(conP.y, lesThr.u)
  connect(lesThr.y, tim.u)
  connect(tim.passed, lat.clr)
  connect(and2.y, lat.u)
  connect(u1SupFan, and2.u2)
  connect(conP.y, greThr2.u)
  connect(greThr2.y, upTim.u)
  connect(conP.y, lesThr3.u)
  connect(lesThr3.y, dowTim.u)
  connect(upTim.passed, lat1.u)
  connect(dowTim.passed, lat1.clr)
  connect(lat.y, relDam.u1)
  connect(u1SupFan, relFan.u1)
  connect(lat1.y, relFan.u2)
  connect(relFan.y, relDam.u2)
  connect(relFan.y, booToRea2.u)
  connect(booToRea2.y, pro1.u2)
  connect(conP.y, pro1.u1)
  connect(movMea.y, yDpBui)
  connect(relDam.y, booToRea1.u)
  connect(booToRea1.y, yDam)
  connect(pro1.y, yRelFan)
  connect(relFan.y, y1RelFan)
end ReliefFan;


Sequence for relief fans control for AHUs using actuated relief dampers with relief fan(s). Sequence for controlling relief fans and their dampers for AHUs using actuated
relief dampers with relief fan(s). It is developed based on Section 5.16.9 of ASHRAE
Guideline 36, May 2020.

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.SetPoints;
block ReliefFanGroup
  "Sequence for relief fans control for AHUs using actuated relief dampers with relief fan(s)"

  parameter Integer nSupFan = 2
    "Total number of AHU supply fans that are serving the same common space"
  parameter Integer nRelFan = 4
    "Total number of relief fans that are serving the same common space"
  parameter Real relFanSpe_min(
    final min=0,
    final max=1)= 0.1
    "Relief fan minimum speed"
  parameter Integer staVec[nRelFan] = {2,3,1,4}
    "Vector of the order for staging up relief fan, i.e. the 1st element means the 1st relief fan and its value showing its sequence when staging up"
  parameter Integer relFanMat[nRelFan, nSupFan] = {{1,0},{1,0},{0,1},{0,1}}
    "Relief fan matrix with relief fan as row index and AHU supply fan as column index. It flags which relief fan is associated with which supply fan"
  parameter Real dpBuiSet(
    final unit="Pa",
    final quantity="PressureDifference",
    final max=30) = 12
    "Building static pressure difference relative to ambient (positive to pressurize the building)"
  parameter Real k(
    final unit="1") = 1
    "Gain, normalized using dpBuiSet"
  parameter Real hys = 0.005
    "Hysteresis for checking the controller output value"

  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1SupFan[nSupFan]
    "AHU supply fan proven on status"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput dpBui(
    final unit="Pa",
    displayUnit="Pa",
    final quantity="PressureDifference")
    "Building static pressure difference, relative to ambient (positive if pressurized)"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uRelFanAla[nRelFan]
    "Relief fan current alarm index"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1RelFan[nRelFan]
    "Relief fan proven on status"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yDpBui(
    final unit="Pa",
    displayUnit="Pa",
    final quantity="PressureDifference")
    "Building static pressure difference, relative to ambient (positive if pressurized)"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yRelFan[nRelFan](
    final unit=fill("1", nRelFan),
    final max=fill(1, nRelFan))
    "Relief fan commanded speed"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yDam[nRelFan](
    final unit=fill("1",nRelFan),
    final min=fill(0,nRelFan),
    final max=fill(1,nRelFan)) "Relief damper commanded position"

  Buildings.Controls.OBC.CDL.Reals.MatrixGain enaRel(
    final K=relFanMat)
    "Vector of relief fans with the enabled one denoted by 1"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea[nSupFan]
    "Convert boolean to real"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai[nRelFan](
    final k=staVec)
    "Vector of enabling fan, along with its staging order"
  Buildings.Controls.OBC.CDL.Reals.MovingAverage movMea(
    final delta=300)
    "Average building static pressure measurement"
  Buildings.Controls.OBC.CDL.Reals.Divide div1
    "Normalized the control error"
  Buildings.Controls.OBC.CDL.Reals.PID conP(
    final controllerType=Buildings.Controls.OBC.CDL.Types.SimpleController.P,
    final k=k,
    final reverseActing=false)
    "Building static pressure controller"
  Buildings.Controls.OBC.CDL.Logical.MultiOr enaRelGro(
    final nin=nSupFan)
    "Relief group enabling status"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea1
    "Convert boolean to real"
  Buildings.Controls.OBC.CDL.Reals.Multiply pro
    "Set controller output to zero when the relief system is disabled"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr(
    final t=0.05,
    final h=hys)
    "Check if the controller output is greater than threshold"
  Buildings.Controls.OBC.CDL.Logical.And and2
    "Check if the controller output is greater than threshold and the relief system has been enabled"
  Buildings.Controls.OBC.CDL.Logical.Latch lat "Enable damper"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr(
    final t=0.005,
    final h=hys)
    "Check if the controller output is near zero"
  Buildings.Controls.OBC.CDL.Logical.Timer tim(
    final t=300)
    "Check if the controller output has been near zero for threshold time"
  Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator booRep(
    final nout=nRelFan)
    "Boolean replicator"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr1[nRelFan](
    final t=fill(0.5, nRelFan))
    "Check if a relief fan should be enabled"
  Buildings.Controls.OBC.CDL.Logical.And enaDam[nRelFan]
    "Enable damper"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr2(
    final t=relFanSpe_min + 0.15,
    final h=hys)
    "Check if the controller output is greater than minimum speed plus threshold"
  Buildings.Controls.OBC.CDL.Logical.Timer upTim(
    final t=420)
    "Check if the controller output has been greater than threshold for sufficient long time"
  Buildings.Controls.OBC.CDL.Logical.Pre pre(
    final pre_u_start=true)
    "Break algebraic loop"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea2[nRelFan]
    "Convert boolean to real"
  Buildings.Controls.OBC.CDL.Reals.Subtract sub2[nRelFan]
    "Identify relief fans that have been enabled but not yet operating"
  Buildings.Controls.OBC.CDL.Reals.Multiply pro1[nRelFan]
    "List of standby fans, along with their staging order"
  Buildings.Controls.OBC.CDL.Reals.MultiMin mulMin(nin=nRelFan)
    "Identify current order of staging"
  Buildings.Controls.OBC.CDL.Routing.RealScalarReplicator reaRep(
    final nout=nRelFan)
    "Replicate real number"
  Buildings.Controls.OBC.CDL.Reals.Subtract sub1[nRelFan]
    "Identify next operating fan"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr1[nRelFan](
    final t=fill(0.5, nRelFan))
    "Check if the input is less than threshold"
  Buildings.Controls.OBC.CDL.Reals.AddParameter addPar[nRelFan](
    final p=fill(nRelFan + 1, nRelFan))
    "Add value to the input"
  Buildings.Controls.OBC.CDL.Reals.Switch swi[nRelFan]
    "Switch input values"
  Buildings.Controls.OBC.CDL.Reals.Abs abs1[nRelFan]
    "Find absolute value"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr2[nRelFan](
    final t=fill(0.5, nRelFan))
    "Identify next operating fan"
  Buildings.Controls.OBC.CDL.Logical.Or or2[nRelFan]
    "Targeted vector of operating relief fan after one new fan being turned on"
  Buildings.Controls.OBC.CDL.Logical.Latch lat2
    "Stage up next relief fan"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr3(
    final t=relFanSpe_min,
    final h=hys)
    "Check if the controller output is less than minimum speed"
  Buildings.Controls.OBC.CDL.Logical.Timer dowTim(
    final t=300)
    "Check if the controller output has been less than threshold for sufficient long time"
  Buildings.Controls.OBC.CDL.Logical.Pre pre1(
    final pre_u_start=true)
    "Break algebraic loop"
  Buildings.Controls.OBC.CDL.Reals.Multiply pro2[nRelFan]
    "List of operating fans, along with their staging order"
  Buildings.Controls.OBC.CDL.Reals.AddParameter addPar1[nRelFan](
    final p=fill(nRelFan + 1, nRelFan))
    "Add value to the input"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr4[nRelFan](
    final t=fill(0.5, nRelFan))
    "Check if the input is less than threshold"
  Buildings.Controls.OBC.CDL.Reals.Switch swi1[nRelFan]
    "Switch input values"
  Buildings.Controls.OBC.CDL.Reals.MultiMin mulMin1(
    final nin=nRelFan) "Minimum staging order of the running relief fans"
  Buildings.Controls.OBC.CDL.Reals.Subtract sub3[nRelFan]
    "Identify next operating fan"
  Buildings.Controls.OBC.CDL.Reals.Abs abs2[nRelFan]
    "Find absolute value"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr5[nRelFan](
    final t=fill(0.5, nRelFan))
    "Identify next fan to be off"
  Buildings.Controls.OBC.CDL.Routing.RealScalarReplicator reaRep1(
    final nout=nRelFan)
    "Replicate real number"
  Buildings.Controls.OBC.CDL.Logical.Xor xor[nRelFan]
    "Vector of relief fan after one fan being turned off"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt[nRelFan]
    "Convert boolean to integer"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt1[nRelFan]
    "Convert boolean to integer"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt2[nRelFan]
    "Convert boolean to integer"
  Buildings.Controls.OBC.CDL.Integers.Equal intEqu[nRelFan]
    "Check if newly started fan has become proven on"
  Buildings.Controls.OBC.CDL.Logical.MultiAnd mulAnd(
    final nin=nRelFan)
    "Check if newly started fan has become proven on"
  Buildings.Controls.OBC.CDL.Integers.Equal intEqu1[nRelFan]
    "Check if newly turned off fan has become off"
  Buildings.Controls.OBC.CDL.Logical.MultiAnd mulAnd2(
    final nin=nRelFan)
    "Check if newly turned off fan has become off"
  Buildings.Controls.OBC.CDL.Logical.Latch lat1
    "Stage down lag fan"
  Buildings.Controls.OBC.CDL.Logical.Switch logSwi[nRelFan]
    "Vector of relief fan status after staging up"
  Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator booRep1(
    final nout=nRelFan)
    "Replicate boolean input"
  Buildings.Controls.OBC.CDL.Logical.Switch logSwi1[nRelFan]
    "Vector of relief fan status after staging down"
  Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator booRep2(
    final nout=nRelFan)
    "Replicate boolean input"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea3[nRelFan]
    "Convert boolean to real"
  Buildings.Controls.OBC.CDL.Reals.Limiter lim(
    final uMax=1,
    final uMin=relFanSpe_min)
    "Limit the controller output"
  Buildings.Controls.OBC.CDL.Routing.RealScalarReplicator reaRep2(
    final nout=nRelFan)
    "Replicate real input"
  Buildings.Controls.OBC.CDL.Reals.Multiply pro3[nRelFan]
    "Relief fan speed"
  Buildings.Controls.OBC.CDL.Logical.Switch logSwi2[nRelFan]
    "Vector of relief fan status after staging up"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant dpBuiSetPoi(
    final k=dpBuiSet)
    "Building pressure setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conOne(
    final k=1)
    "Constant one"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant con(
    final k=0)
    "Zero fan speed when it is in stage 0"
  Buildings.Controls.OBC.CDL.Reals.Switch swi2
    "Switch input values"
  Buildings.Controls.OBC.CDL.Logical.MultiOr mulOr(nin=nRelFan)
    "Check if there is any relief fan enabled, but may not be running"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea4[nRelFan]
    "Convert boolean to real"
  Buildings.Controls.OBC.CDL.Logical.Not not1
    "Logical not"
  Buildings.Controls.OBC.CDL.Logical.And and1
    "Start timer, and reset to zero if the threshold time has passed"
  Buildings.Controls.OBC.CDL.Logical.And and3
    "Start timer, and reset to zero if the threshold time has passed"
  Buildings.Controls.OBC.CDL.Logical.Not not2 "Logical not"
  Buildings.Controls.OBC.CDL.Integers.Equal intEqu2[nRelFan]
    "Check if the relief fan is in level 2 alarm"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt[nRelFan](
    final k=fill(2, nRelFan))
    "Constant"
  Buildings.Controls.OBC.CDL.Logical.Not not3[nRelFan] "Logical not"
  Buildings.Controls.OBC.CDL.Logical.And and4[nRelFan]
    "Check if the relief fan is in level 2 alarm and it is proven off"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea5[nRelFan](
    final realTrue=fill(0, nRelFan),
    final realFalse=fill(1, nRelFan))
    "Convert boolean to real"
  Buildings.Controls.OBC.CDL.Reals.Multiply mul[nRelFan]
    "Product of inputs"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr3[nRelFan](
    final t=fill(0.5, nRelFan))
    "Check if the relief fan is enabled"
  Buildings.Controls.OBC.CDL.Logical.MultiAnd mulAnd1(
    final nin=nRelFan) "Check if all the fans are proven off"
  Buildings.Controls.OBC.CDL.Reals.Switch swi3[nRelFan]
    "Switch input values"
  Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator booRep4(
    final nout=nRelFan)
    "Replicate boolean input"
  Buildings.Controls.OBC.CDL.Logical.Switch logSwi3[nRelFan]
    "Vector of relief fan status after staging down"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel[nRelFan](
    final delayTime=fill(2, nRelFan))
    "Delay true input"
  Buildings.Controls.OBC.CDL.Logical.MultiOr mulOr1(
    final nin=nRelFan)
    "Check if there is any fan is proven on"
  Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator booRep5(
    final nout=nRelFan)
    "Replicate boolean input"
  Buildings.Controls.OBC.CDL.Logical.Not not5[nRelFan] "Logical not"
  Buildings.Controls.OBC.CDL.Logical.Not not6[nRelFan] "Logical not"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel1[nRelFan](
    final delayTime=fill(2, nRelFan))
    "Delay true input"

equation
  connect(u1SupFan, booToRea.u)
  connect(enaRel.u, booToRea.y)
  connect(enaRel.y, gai.u)
  connect(dpBui, movMea.u)
  connect(conOne.y, conP.u_s)
  connect(movMea.y, div1.u1)
  connect(dpBuiSetPoi.y, div1.u2)
  connect(div1.y, conP.u_m)
  connect(u1SupFan, enaRelGro.u)
  connect(booToRea1.y, pro.u1)
  connect(enaRelGro.y, booToRea1.u)
  connect(conP.y, greThr.u)
  connect(enaRelGro.y, and2.u2)
  connect(greThr.y, and2.u1)
  connect(and2.y, lat.u)
  connect(conP.y, lesThr.u)
  connect(lesThr.y, tim.u)
  connect(tim.passed, lat.clr)
  connect(lat.y, booRep.u)
  connect(gai.y, greThr1.u)
  connect(greThr1.y, enaDam.u1)
  connect(booRep.y, enaDam.u2)
  connect(u1RelFan, booToRea2.u)
  connect(enaRel.y, sub2.u1)
  connect(booToRea2.y, sub2.u2)
  connect(gai.y, pro1.u1)
  connect(sub2.y, pro1.u2)
  connect(mulMin.y, reaRep.u)
  connect(lesThr1.y, swi.u2)
  connect(pro1.y, swi.u3)
  connect(pro1.y, addPar.u)
  connect(addPar.y, swi.u1)
  connect(gai.y, sub1.u1)
  connect(reaRep.y, sub1.u2)
  connect(sub1.y, abs1.u)
  connect(abs1.y, lesThr2.u)
  connect(lesThr2.y, or2.u1)
  connect(booToRea2.y, pro2.u2)
  connect(gai.y, pro2.u1)
  connect(pro2.y, addPar1.u)
  connect(pro2.y, lesThr4.u)
  connect(lesThr4.y, swi1.u2)
  connect(addPar1.y, swi1.u1)
  connect(pro2.y, swi1.u3)
  connect(swi1.y, mulMin1.u)
  connect(mulMin1.y, reaRep1.u)
  connect(reaRep1.y, sub3.u2)
  connect(gai.y, sub3.u1)
  connect(sub3.y, abs2.u)
  connect(abs2.y, lesThr5.u)
  connect(lesThr5.y, xor.u1)
  connect(booToInt.y, intEqu.u1)
  connect(booToInt1.y, intEqu.u2)
  connect(intEqu.y, mulAnd.u)
  connect(booToInt1.y, intEqu1.u1)
  connect(booToInt2.y, intEqu1.u2)
  connect(intEqu1.y, mulAnd2.u)
  connect(lat2.y, booRep1.u)
  connect(lat1.y, booRep2.u)
  connect(booRep2.y, logSwi1.u2)
  connect(mulAnd2.y, lat1.clr)
  connect(conP.y, lesThr3.u)
  connect(xor.y, logSwi1.u1)
  connect(conP.y, greThr2.u)
  connect(booRep1.y, logSwi.u2)
  connect(or2.y, logSwi.u1)
  connect(u1RelFan, xor.u2)
  connect(u1RelFan, logSwi1.u3)
  connect(u1RelFan, booToInt1.u)
  connect(u1RelFan, or2.u2)
  connect(logSwi.y, booToRea3.u)
  connect(conP.y, lim.u)
  connect(lim.y, pro.u2)
  connect(booToRea3.y, pro3.u2)
  connect(pro3.y, yRelFan)
  connect(reaRep2.y, pro3.u1)
  connect(con.y, swi2.u3)
  connect(mulOr.y, swi2.u2)
  connect(movMea.y, yDpBui)
  connect(logSwi2.y, booToRea4.u)
  connect(not1.y, pre.u)
  connect(and1.y, upTim.u)
  connect(greThr2.y, and1.u1)
  connect(not2.y, pre1.u)
  connect(lesThr3.y, and3.u1)
  connect(and3.y, dowTim.u)
  connect(uRelFanAla, intEqu2.u1)
  connect(conInt.y, intEqu2.u2)
  connect(u1RelFan, not3.u)
  connect(intEqu2.y, and4.u1)
  connect(not3.y, and4.u2)
  connect(and4.y, booToRea5.u)
  connect(booToRea4.y, mul.u1)
  connect(booToRea5.y, mul.u2)
  connect(mul.y, yDam)
  connect(enaDam.y, logSwi2.u3)
  connect(logSwi.y, logSwi2.u1)
  connect(upTim.passed, not1.u)
  connect(upTim.passed, lat2.u)
  connect(dowTim.passed, not2.u)
  connect(dowTim.passed, lat1.u)
  connect(enaRel.y, greThr3.u)
  connect(greThr3.y, mulOr.u)
  connect(pro.y, swi2.u1)
  connect(swi2.y, reaRep2.u)
  connect(pro1.y, lesThr1.u)
  connect(not3.y, mulAnd1.u)
  connect(mulAnd1.y, booRep4.u)
  connect(booRep4.y, swi3.u2)
  connect(pro1.y, swi3.u1)
  connect(swi.y, swi3.u3)
  connect(swi3.y, mulMin.u)
  connect(pre1.y, and3.u2)
  connect(u1RelFan, logSwi3.u1)
  connect(booRep4.y, logSwi3.u2)
  connect(logSwi1.y, logSwi3.u3)
  connect(logSwi3.y, logSwi.u3)
  connect(pre.y, and1.u2)
  connect(truDel.y, booToInt.u)
  connect(or2.y, truDel.u)
  connect(mulAnd.y, lat2.clr)
  connect(logSwi.y, mulOr1.u)
  connect(mulOr1.y, booRep5.u)
  connect(booRep5.y, logSwi2.u2)
  connect(not6.y, booToInt2.u)
  connect(truDel1.y, not6.u)
  connect(not5.y, truDel1.u)
  connect(xor.y, not5.u)
end ReliefFanGroup;


Return fan control for single zone AHU. Sequence for controlling return fan yRetFan for single AHUs.
It is implemented according to Section 5.18.10 of ASHRAE Guideline G36, May 2020.

within Buildings.Controls.OBC.ASHRAE.G36.AHUs.SingleZone.VAV.SetPoints;
block ReturnFan "Return fan control for single zone AHU"

  parameter Real speDif=-0.1
    "Speed difference between supply and return fan to maintain building pressure at desired pressure"

  Buildings.Controls.OBC.CDL.Interfaces.RealInput uSupFan_actual(
    final min=0,
    final max=1,
    final unit="1")
    "Actual supply fan speed"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1SupFan
    "Supply fan command on"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ExhDam
    "Exhaust damper commanded on"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yRetFan(
    final unit="1",
    final min=0,
    final max=1)
    "Return fan commanded speed"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1RetFan
    "Return fan command on"

  Buildings.Controls.OBC.CDL.Reals.AddParameter addPar(
    final p=speDif)
    "Adjusted return fan speed"
  Buildings.Controls.OBC.CDL.Reals.Switch swi "Return fan speed"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant con(
    final k=0) "Zero speed"

equation
  connect(uSupFan_actual, addPar.u)
  connect(u1SupFan, swi.u2)
  connect(con.y, swi.u3)
  connect(addPar.y, swi.u1)
  connect(swi.y, yRetFan)
  connect(u1SupFan, y1ExhDam)
  connect(u1SupFan, y1RetFan)
end ReturnFan;