Generate alarms of snap-acting controlled dual-duct terminal unit. This block outputs alarms of snap-acting controlled dual-duct terminal unit. The
implementation is according to the Section 5.11.6 of ASHRAE Guideline 36, May 2020.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences;
block Alarms "Generate alarms of snap-acting controlled dual-duct terminal unit"

  parameter Boolean have_duaSen
    "True: the unit have dual inlet flow sensor";
  parameter Real staPreMul
    "Importance multiplier for the zone static pressure reset control loop";
  parameter Real VCooMax_flow(
    final quantity="VolumeFlowRate",
    final unit="m3/s")
    "Design zone cooling maximum airflow rate";
  parameter Real VHeaMax_flow(
    final quantity="VolumeFlowRate",
    final unit="m3/s")
    "Design zone heating maximum airflow rate";
  parameter Real lowFloTim(
    final unit="s",
    final quantity="Time")=300
    "Threshold time to check low flow rate"
  parameter Real fanOffTim(
    final unit="s",
    final quantity="Time")=600
    "Threshold time to check fan off"
  parameter Real leaFloTim(
    final unit="s",
    final quantity="Time")=600
    "Threshold time to check damper leaking airflow"
  parameter Real floHys(
    final quantity="VolumeFlowRate",
    final unit="m3/s")=0.05
    "Near zero flow rate, below which the flow rate or difference will be seen as zero"
  parameter Real damPosHys(
    final unit="1")=0.05
    "Near zero damper position, below which the damper will be seen as closed"
  parameter Real staTim(
    final unit="s",
    final quantity="Time")=1800
    "Delay triggering alarms after enabling AHU supply fan"

  Buildings.Controls.OBC.CDL.Interfaces.RealInput VDis_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate") if not have_duaSen
    "Measured discharge airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VActSet_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate") "Active airflow setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uOpeMod
    "Zone operation mode"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VColDucDis_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate") if have_duaSen
    "Measured cold-duct discharge airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1CooFan
    "Cooling air handler supply fan status"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uCooDam(
    final min=0,
    final unit="1")
    "Cooling damper position setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VHotDucDis_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate") if have_duaSen
    "Measured hot-duct discharge airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1HeaFan
    "Heating air handler supply fan status"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uHeaDam(
    final min=0,
    final unit="1")
    "Heating damper position setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yLowFloAla
    "Low airflow alarms"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yFloSenAla
    if not have_duaSen
    "Airflow sensor calibration alarm"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yLeaDamAla
    if not have_duaSen
    "Leaking dampers alarm, could be heating or cooling damper"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yColFloSenAla
    if have_duaSen "Cold-duct airflow sensor calibration alarm"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yColLeaDamAla
    if have_duaSen "Leaking cold-duct damper alarm"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yHotFloSenAla
    if have_duaSen "Hot-duct airflow sensor calibration alarm"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yHotLeaDamAla
    if have_duaSen "Leaking hot-duct damper alarm"

  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai(
    final k=0.5)
    "Percentage of the setpoint"
  Buildings.Controls.OBC.CDL.Reals.Less les(
    final h=floHys)
    "Check if measured airflow is less than threshold"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel(
    final delayTime=lowFloTim)
    "Check if the measured airflow has been less than threshold value for threshold time"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr(
    final t=floHys,
    final h=0.5*floHys)
    "Check if setpoint airflow is greater than zero"
  Buildings.Controls.OBC.CDL.Reals.Greater gre(
    final h=floHys)
    "Check if measured airflow is less than threshold"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai1(
    final k=0.7)
    "Percentage of the setpoint"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel1(
    final delayTime=lowFloTim)
    "Check if the measured airflow has been less than threshold value for threshold time"
  Buildings.Controls.OBC.CDL.Logical.And and2
    "Measured airflow has been less than threshold value for sufficient time"
  Buildings.Controls.OBC.CDL.Logical.And and1
    "Measured airflow has been less than threshold value for sufficient time"
  Buildings.Controls.OBC.CDL.Integers.Switch lowFloAla
    "Low airflow alarm"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt(
    final k=2)
    "Level 2 alarm"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt(
    final integerTrue=3)
    "Convert boolean true to level 3 alarm"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conInt1(
    final k=staPreMul)
    "Importance multiplier for zone static pressure reset"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr1
    "Check if the multiplier is greater than zero"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt1
    "Suppress the alarm when multiplier is zero"
  Buildings.Controls.OBC.CDL.Integers.Multiply proInt
    "Low flow alarms"
  Buildings.Controls.OBC.CDL.Logical.And and8
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.Not not1
    "Logical not"
  Buildings.Controls.OBC.CDL.Utilities.Assert assMes(
    final message="Warning: airflow is less than 50% of the setpoint.")
    "Level 2 low airflow alarm"
  Buildings.Controls.OBC.CDL.Logical.And and4
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.Not not2
    "Logical not"
  Buildings.Controls.OBC.CDL.Utilities.Assert assMes1(
    final message="Warning: airflow is less than 70% of the setpoint.")
    "Level 3 low airflow alarm"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant cooMaxFlo(
    final k=VCooMax_flow) if have_duaSen "Cooling maximum airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai2(
    final k=0.1) if have_duaSen
    "Percentage of the setpoint"
  Buildings.Controls.OBC.CDL.Logical.Not not3 if have_duaSen
    "Logical not"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel2(
    final delayTime=fanOffTim) if have_duaSen
    "Check if the input has been true for more than threshold time"
  Buildings.Controls.OBC.CDL.Reals.Greater gre1(
    final h=floHys) if have_duaSen
    "Check if measured airflow is greater than threshold"
  Buildings.Controls.OBC.CDL.Logical.And and5 if have_duaSen
    "Check if the measured airflow is greater than the threshold and the supply fan is OFF"
  Buildings.Controls.OBC.CDL.Logical.Not not4 if have_duaSen
    "Logical not"
  Buildings.Controls.OBC.CDL.Utilities.Assert assMes2(
    final message="Warning: cold-duct airflow sensor should be calibrated.")
    if have_duaSen
    "Level 3 airflow sensor alarm"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt2(
    final integerTrue=3) if have_duaSen
    "Convert boolean true to level 3 alarm"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel3(
    final delayTime=leaFloTim) if have_duaSen
    "Check if the input has been true for more than threshold time"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold cloDam(
    final t=damPosHys,
    final h=0.5*damPosHys) "Check if damper position is near zero"
  Buildings.Controls.OBC.CDL.Logical.And leaDamAla if have_duaSen
    "Check if generating leak damper alarms"
  Buildings.Controls.OBC.CDL.Logical.Not not5 if have_duaSen
    "Logical not"
  Buildings.Controls.OBC.CDL.Utilities.Assert assMes3(
    final message="Warning: the cold-duct damper is leaking.")
    if have_duaSen
    "Level 4 leaking damper alarm"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt3(
    final integerTrue=4) if have_duaSen
    "Convert boolean true to level 4 alarm"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant heaMaxFlo(
    final k=VHeaMax_flow)
    if have_duaSen "Heating maximum airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai3(final k=0.1)
    if have_duaSen
    "Percentage of the setpoint"
  Buildings.Controls.OBC.CDL.Logical.Not not6 if have_duaSen
    "Logical not"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel4(
    final delayTime=fanOffTim) if have_duaSen
    "Check if the input has been true for more than threshold time"
  Buildings.Controls.OBC.CDL.Reals.Greater gre2(
    final h=floHys)
    if have_duaSen
    "Check if measured airflow is greater than threshold"
  Buildings.Controls.OBC.CDL.Logical.And and6 if have_duaSen
    "Check if the measured airflow is greater than the threshold and the supply fan is OFF"
  Buildings.Controls.OBC.CDL.Logical.Not not7 if have_duaSen
    "Logical not"
  Buildings.Controls.OBC.CDL.Utilities.Assert assMes4(
    final message="Warning: hot-duct airflow sensor should be calibrated.")
    if have_duaSen
    "Level 3 airflow sensor alarm"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt4(
    final integerTrue=3) if have_duaSen
    "Convert boolean true to level 3 alarm"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel5(
    final delayTime=leaFloTim) if have_duaSen
    "Check if the input has been true for more than threshold time"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold cloDam1(
    final t=damPosHys,
    final h=0.5*damPosHys)
    "Check if damper position is near zero"
  Buildings.Controls.OBC.CDL.Logical.And leaDamAla1 if have_duaSen
    "Check if generating leak damper alarms"
  Buildings.Controls.OBC.CDL.Logical.Not not8 if have_duaSen
    "Logical not"
  Buildings.Controls.OBC.CDL.Utilities.Assert assMes5(
    final message="Warning: the hot-duct damper is leaking.")
    if have_duaSen
    "Level 4 leaking damper alarm"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt5(
    final integerTrue=4) if have_duaSen
    "Convert boolean true to level 4 alarm"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant cooMaxFlo1(
    final k=VCooMax_flow) if not have_duaSen
    "Cooling maximum airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai4(
    final k=0.1)
    if not have_duaSen
    "Percentage of the setpoint"
  Buildings.Controls.OBC.CDL.Reals.Greater gre3(
    final h=floHys)
    if not have_duaSen
    "Check if measured airflow is greater than threshold"
  Buildings.Controls.OBC.CDL.Logical.And and7 if not have_duaSen
    "Check if the measured airflow is greater than the threshold and the supply fan is OFF"
  Buildings.Controls.OBC.CDL.Logical.Not not9 if not have_duaSen
    "Logical not"
  Buildings.Controls.OBC.CDL.Utilities.Assert assMes6(
    final message="Warning: airflow sensor should be calibrated.")
    if not have_duaSen
    "Level 3 airflow sensor alarm"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt6(
    final integerTrue=3) if not have_duaSen
    "Convert boolean true to level 3 alarm"
  Buildings.Controls.OBC.CDL.Logical.Or or2 if not have_duaSen
    "Check if there is any supply fan proven on"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel6(
    final delayTime=fanOffTim) if not have_duaSen
    "Check if the input has been true for more than threshold time"
  Buildings.Controls.OBC.CDL.Logical.Not not10 if not have_duaSen
    "Logical not"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel7(
    final delayTime=leaFloTim) if not have_duaSen
    "Check if the input has been true for more than threshold time"
  Buildings.Controls.OBC.CDL.Logical.And leaDamAla2 if not have_duaSen
    "Check if generating leak damper alarms"
  Buildings.Controls.OBC.CDL.Logical.And cloBotDam if not have_duaSen
    "Both heating and cooling dampers are closed"
  Buildings.Controls.OBC.CDL.Logical.Not not11 if not have_duaSen
    "Logical not"
  Buildings.Controls.OBC.CDL.Utilities.Assert assMes7(
    final message="Warning: the cold-duct or hot-dcut damper is leaking.")
    if not have_duaSen
    "Level 4 leaking damper alarm"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt7(
    final integerTrue=4) if not have_duaSen
    "Convert boolean true to level 4 alarm"
  Buildings.Controls.OBC.CDL.Reals.Add add2 if have_duaSen
    "Total discharge airflow"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay truDel8(
    final delayTime=lowFloTim)
    "Check if the active flow setpoint has been greater than zero for the threshold time"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay fanIni(
    final delayTime=staTim)
    "Check if the AHU supply fan has been enabled for threshold time"
  Buildings.Controls.OBC.CDL.Logical.And and11
    "True: AHU fan is enabled and the discharge flow is lower than the threshold"
  Buildings.Controls.OBC.CDL.Logical.And and10
    "True: AHU fan is enabled and the discharge flow is lower than the threshold"
  Buildings.Controls.OBC.CDL.Logical.Or or1
    "Check if there is any supply fan proven on"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant occMod(
    final k=Buildings.Controls.OBC.ASHRAE.G36.Types.OperationModes.occupied)
    "Occupied mode"
  Buildings.Controls.OBC.CDL.Integers.Equal isOcc
    "Check if current operation mode is occupied mode"
  Buildings.Controls.OBC.CDL.Logical.And and3
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.And and9
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.And leaDamAla3 if not have_duaSen
    "Check if generating leak damper alarms"
  Buildings.Controls.OBC.CDL.Logical.And  leaDamAla4 if have_duaSen
    "Check if generating leak damper alarms"
  Buildings.Controls.OBC.CDL.Logical.And leaDamAla5 if have_duaSen
    "Check if generating leak damper alarms"
equation
  connect(VActSet_flow, gai.u)
  connect(VDis_flow, les.u1)
  connect(VActSet_flow, greThr.u)
  connect(VActSet_flow, gai1.u)
  connect(VDis_flow, gre.u2)
  connect(gai1.y, gre.u1)
  connect(truDel.y, and2.u1)
  connect(truDel1.y, and1.u2)
  connect(conInt.y, lowFloAla.u1)
  connect(booToInt.y, lowFloAla.u3)
  connect(conInt1.y, greThr1.u)
  connect(greThr1.y, booToInt1.u)
  connect(lowFloAla.y, proInt.u1)
  connect(booToInt1.y, proInt.u2)
  connect(not1.y, assMes.u)
  connect(and2.y,and8. u1)
  connect(greThr1.y,and8. u2)
  connect(and1.y, and4.u1)
  connect(greThr1.y, and4.u2)
  connect(not2.y, assMes1.u)
  connect(cooMaxFlo.y, gai2.u)
  connect(u1CooFan, not3.u)
  connect(gai2.y, gre1.u2)
  connect(gre1.y, and5.u1)
  connect(not4.y, assMes2.u)
  connect(booToInt2.y, yColFloSenAla)
  connect(proInt.y, yLowFloAla)
  connect(uCooDam, cloDam.u)
  connect(u1CooFan, leaDamAla.u2)
  connect(not5.y, assMes3.u)
  connect(booToInt3.y, yColLeaDamAla)
  connect(VColDucDis_flow, gre1.u1)
  connect(heaMaxFlo.y, gai3.u)
  connect(u1HeaFan, not6.u)
  connect(gai3.y,gre2. u2)
  connect(gre2.y,and6. u1)
  connect(not7.y,assMes4. u)
  connect(booToInt4.y, yHotFloSenAla)
  connect(uHeaDam, cloDam1.u)
  connect(u1HeaFan, leaDamAla1.u2)
  connect(not8.y,assMes5. u)
  connect(booToInt5.y, yHotLeaDamAla)
  connect(VHotDucDis_flow, gre2.u1)
  connect(VDis_flow, gre3.u1)
  connect(u1CooFan, or2.u1)
  connect(u1HeaFan, or2.u2)
  connect(or2.y, not10.u)
  connect(not9.y, assMes6.u)
  connect(booToInt6.y, yFloSenAla)
  connect(gai4.y, gre3.u2)
  connect(cooMaxFlo1.y, gai4.u)
  connect(or2.y, leaDamAla2.u2)
  connect(cloDam.y, cloBotDam.u1)
  connect(cloDam1.y, cloBotDam.u2)
  connect(not11.y, assMes7.u)
  connect(booToInt7.y, yLeaDamAla)
  connect(VColDucDis_flow, add2.u1)
  connect(VHotDucDis_flow, add2.u2)
  connect(add2.y, les.u1)
  connect(add2.y, gre.u2)
  connect(add2.y, gre3.u1)
  connect(greThr.y, truDel8.u)
  connect(truDel8.y, and1.u1)
  connect(truDel8.y, and2.u2)
  connect(gre3.y, and7.u1)
  connect(not10.y, and7.u2)
  connect(and7.y, truDel6.u)
  connect(truDel6.y, booToInt6.u)
  connect(truDel6.y, not9.u)
  connect(truDel7.y, booToInt7.u)
  connect(truDel7.y, not11.u)
  connect(gre3.y, leaDamAla2.u1)
  connect(not3.y, and5.u2)
  connect(and5.y, truDel2.u)
  connect(truDel2.y, booToInt2.u)
  connect(truDel2.y, not4.u)
  connect(gre1.y, leaDamAla.u1)
  connect(truDel3.y, booToInt3.u)
  connect(truDel3.y, not5.u)
  connect(and6.y, truDel4.u)
  connect(truDel4.y, booToInt4.u)
  connect(not6.y, and6.u2)
  connect(truDel4.y, not7.u)
  connect(truDel5.y, booToInt5.u)
  connect(truDel5.y, not8.u)
  connect(gre2.y, leaDamAla1.u1)
  connect(les.y, and10.u1)
  connect(and10.y, truDel.u)
  connect(gre.y, and11.u1)
  connect(and11.y, truDel1.u)
  connect(fanIni.y, and10.u2)
  connect(u1CooFan, or1.u1)
  connect(u1HeaFan, or1.u2)
  connect(or1.y, fanIni.u)
  connect(occMod.y,isOcc. u2)
  connect(uOpeMod,isOcc. u1)
  connect(fanIni.y, and11.u2)
  connect(gai.y, les.u2)
  connect(and8.y, and9.u1)
  connect(and9.y, lowFloAla.u2)
  connect(booToInt.u, and3.y)
  connect(and9.y, not1.u)
  connect(and3.y, not2.u)
  connect(and4.y, and3.u1)
  connect(isOcc.y, and9.u2)
  connect(isOcc.y, and3.u2)
  connect(leaDamAla2.y, leaDamAla3.u1)
  connect(leaDamAla3.y, truDel7.u)
  connect(cloBotDam.y, leaDamAla3.u2)
  connect(leaDamAla.y, leaDamAla4.u1)
  connect(leaDamAla4.y, truDel3.u)
  connect(cloDam.y, leaDamAla4.u2)
  connect(leaDamAla1.y, leaDamAla5.u1)
  connect(leaDamAla5.y, truDel5.u)
  connect(cloDam1.y, leaDamAla5.u2)
end Alarms;


Output signals for controlling dampers of snap-acting controlled dual-duct terminal unit with dual inlet airflow sensors. This sequence sets the dampers for snap-acting controlled dual-duct terminal unit
with dual inlet airflow sensors.
The implementation is according to Section 5.11.5.1 of ASHRAE Guideline 36, May 2020. The
calculation is done following the steps below.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences;
block DampersDualSensors
  "Output signals for controlling dampers of snap-acting controlled dual-duct terminal unit with dual inlet airflow sensors"

  parameter Real VCooMax_flow(
    final quantity="VolumeFlowRate",
    final unit="m3/s")
    "Design zone cooling maximum airflow rate";
  parameter Real VHeaMax_flow(
    final quantity="VolumeFlowRate",
    final unit="m3/s")
    "Design zone heating maximum airflow rate";
  parameter Buildings.Controls.OBC.CDL.Types.SimpleController controllerTypeDam=
    Buildings.Controls.OBC.CDL.Types.SimpleController.PI
    "Type of controller"
  parameter Real kDam(final unit="1")=0.5
    "Gain of controller for damper control"
  parameter Real TiDam(
    final unit="s",
    final quantity="Time")=300
    "Time constant of integrator block for damper control"
  parameter Real TdDam(
    final unit="s",
    final quantity="Time")=0.1
    "Time constant of derivative block for damper control"
  parameter Real samplePeriod(
    final unit="s",
    final quantity="Time",
    final min=1E-3)
    "Sample period of component"
  parameter Real dTHys(
    final unit="K",
    final quantity="TemperatureDifference")=0.25
    "Temperature difference hysteresis below which the temperature difference will be seen as zero"
  parameter Real looHys(
    final unit="1") = 0.05
    "Loop output hysteresis below which the output will be seen as zero"
  parameter Real iniDam(unit="1")=0.01
    "Initial damper position when the damper control is enabled"

  Buildings.Controls.OBC.CDL.Interfaces.RealInput uCoo(
    final min=0,
    final max=1,
    final unit="1")
    "Cooling control signal"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VActCooMax_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Active cooling maximum airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TColSup(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    "Cold duct supply air temperature from central air handler"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VColDucDis_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Measured cold-duct discharge airflow rate airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1CooAHU
    "Cooling air handler status"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VActMin_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Active minimum airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TZon(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    "Measured zone temperature"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput THotSup(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    "Hot duct supply air temperature from central air handler"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uHea(
    final min=0,
    final max=1,
    final unit="1")
    "Heating control signal"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VActHeaMax_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Active heating maximum airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VHotDucDis_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Measured hot-duct discharge airflow rate airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1HeaAHU
    "Heating air handler status"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput VDis_flow_Set(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Discharge airflow setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput VColDucDis_flow_Set(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Cold duct discharge airflow setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yCooDam(
    final min=0,
    final max=1,
    final unit="1") "Cold duct damper commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput VHotDucDis_flow_Set(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate") "Hot duct discharge airflow setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yHeaDam(
    final min=0,
    final max=1,
    final unit="1") "Hot duct damper commanded position"

  Buildings.Controls.OBC.CDL.Logical.And and4 "Logical and"
  Buildings.Controls.OBC.CDL.Reals.Line lin
    "Active airflow setpoint for cooling"
  Buildings.Controls.OBC.CDL.Reals.PIDWithReset conCooDam(
    final controllerType=controllerTypeDam,
    final k=kDam,
    final Ti=TiDam,
    final Td=TdDam,
    final yMax=1,
    final yMin=0,
    final y_reset=iniDam)
    "Cooling damper position controller"
  Buildings.Controls.OBC.CDL.Reals.Switch swi
    "Output active cold duct airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.Switch swi5
    "Airflow setpoint when it is in cooling state"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conZer(
    final k=0) "Constant zero"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conOne(
    final k=1) "Constant one"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr1(
    final t=looHys,
    final h=0.5*looHys)
    "Check if it is cooling state"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr(
    final t=dTHys,
    final h=0.5*dTHys)
    "Check if supply air temperature is greater than room temperature"
  Buildings.Controls.OBC.CDL.Reals.Subtract sub2
    "Calculate temperature difference between AHU supply air and room "
  Buildings.Controls.OBC.CDL.Reals.Switch cooDamPos
    "Output cooling damper position"
  Buildings.Controls.OBC.CDL.Reals.Divide VDis_flowNor
    "Normalized discharge volume flow rate"
  Buildings.Controls.OBC.CDL.Reals.Divide VDisSet_flowNor
    "Normalized setpoint for discharge volume flow rate"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conZer1(
    final k=0)
    "Constant zero"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr2(
    final t=looHys,
    final h=0.5*looHys)
    "Check if it is heating state"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conOne1(
    final k=1)
    "Constant one"
  Buildings.Controls.OBC.CDL.Reals.Line lin1
    "Active airflow setpoint for heating"
  Buildings.Controls.OBC.CDL.Reals.Subtract sub1
    "Calculate temperature difference between AHU supply air and room "
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr3(
    final t=dTHys,
    final h=0.5*dTHys)
    "Check if supply air temperature is less than room temperature"
  Buildings.Controls.OBC.CDL.Logical.And and1 "Logical and"
  Buildings.Controls.OBC.CDL.Reals.Switch swi1
    "Airflow setpoint when it is in heating state"
  Buildings.Controls.OBC.CDL.Logical.Or or2
    "Cooing or heating state"
  Buildings.Controls.OBC.CDL.Logical.Not not1
    "In deadband"
  Buildings.Controls.OBC.CDL.Logical.FallingEdge falEdg
    "Becoming heating or cooling state"
  Buildings.Controls.OBC.CDL.Logical.And and2
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.And and3
    "Logical and"
  Buildings.Controls.OBC.CDL.Discrete.Sampler samHea(
    final samplePeriod=samplePeriod)
    "Sample the heating loop output"
  Buildings.Controls.OBC.CDL.Discrete.Sampler samCoo(
    final samplePeriod=samplePeriod)
    "Sample the cooling loop output"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr4(
    final t=looHys,
    final h=0.5*looHys)
    "Check if it is cooling state"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr5(
    final t=looHys,
    final h=0.5*looHys) "Check if it is heating state"
  Buildings.Controls.OBC.CDL.Logical.Latch lat
    "Changing from cooling state to deadband"
  Buildings.Controls.OBC.CDL.Logical.Latch lat1
    "Changing from heating state to deadband"
  Buildings.Controls.OBC.CDL.Reals.Switch swi2
    "Cold duct airflow setpoint when it is in deadband state"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conZer2(
    final k=0)
    "Constant zero"
  Buildings.Controls.OBC.CDL.Reals.Switch swi3
    "Hot duct airflow setpoint when it is in deadband state"
  Buildings.Controls.OBC.CDL.Reals.Switch swi4
    "Output active hot duct airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.PIDWithReset conHeaDam(
    final controllerType=controllerTypeDam,
    final k=kDam,
    final Ti=TiDam,
    final Td=TdDam,
    final yMax=1,
    final yMin=0,
    final y_reset=iniDam)
    "Heating damper position controller"
  Buildings.Controls.OBC.CDL.Reals.Switch heaDamPos
    "Output heating damper position"
  Buildings.Controls.OBC.CDL.Reals.Divide VDis_flowNor1
    "Normalized discharge volume flow rate"
  Buildings.Controls.OBC.CDL.Reals.Divide VDisSet_flowNor1
    "Normalized setpoint for discharge volume flow rate"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conZer3(
    final k=0)
    "Constant zero"
  Buildings.Controls.OBC.CDL.Logical.Not not2 "Not proven on"
  Buildings.Controls.OBC.CDL.Logical.Not not3
    "Not proven on"
  Buildings.Controls.OBC.CDL.Reals.Multiply mul
    "Make sure heating damper is closed when it is in cooling state"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea(
    final realTrue=0,
    final realFalse=1)
    "Ensure heating damper closed when it is in cooling state"
  Buildings.Controls.OBC.CDL.Reals.Multiply mul1
    "Make sure heating damper is closed when it is in cooling state"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea1(
    final realTrue=0,
    final realFalse=1)
    "Ensure cooling damper closed when it is in heating state"
  Buildings.Controls.OBC.CDL.Reals.Multiply mul2
    "Make sure cooling damper is closed when it is in heating state"
  Buildings.Controls.OBC.CDL.Reals.Multiply mul3
    "Make sure cooling damper is closed when it is in heating state"
  Buildings.Controls.OBC.CDL.Reals.Add add2
    "Total discharge airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant heaMax1(
    final k=VHeaMax_flow)
    "Heating maximum flow"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant cooMax1(
    final k=VCooMax_flow)
    "Cooling maximum flow"
  Buildings.Controls.OBC.CDL.Reals.Max max2
    "Nominal flow"
equation
  connect(uCoo, lin.u)
  connect(conZer.y, lin.x1)
  connect(conOne.y, lin.x2)
  connect(VActCooMax_flow, lin.f2)
  connect(uCoo, greThr1.u)
  connect(and4.y, swi5.u2)
  connect(lin.y, swi5.u3)
  connect(swi5.y, swi.u1)
  connect(TColSup, sub2.u1)
  connect(sub2.y, greThr.u)
  connect(greThr.y, and4.u2)
  connect(cooDamPos.y, yCooDam)
  connect(VColDucDis_flow, VDis_flowNor.u1)
  connect(VDis_flowNor.y, conCooDam.u_m)
  connect(VDisSet_flowNor.y, conCooDam.u_s)
  connect(greThr1.y, and4.u1)
  connect(greThr1.y, swi.u2)
  connect(VActMin_flow, swi5.u1)
  connect(VActMin_flow, lin.f1)
  connect(conZer1.y, lin1.x1)
  connect(VActMin_flow, lin1.f1)
  connect(conOne1.y, lin1.x2)
  connect(uHea, lin1.u)
  connect(TZon, sub2.u2)
  connect(uHea, greThr2.u)
  connect(VActHeaMax_flow, lin1.f2)
  connect(TZon, sub1.u1)
  connect(sub1.y, greThr3.u)
  connect(THotSup, sub1.u2)
  connect(greThr3.y, and1.u1)
  connect(greThr2.y, and1.u2)
  connect(and1.y, swi1.u2)
  connect(VActMin_flow, swi1.u1)
  connect(lin1.y, swi1.u3)
  connect(greThr1.y, or2.u1)
  connect(greThr2.y, or2.u2)
  connect(or2.y, not1.u)
  connect(not1.y, falEdg.u)
  connect(not1.y, and2.u1)
  connect(not1.y, and3.u2)
  connect(uHea, samHea.u)
  connect(uCoo, samCoo.u)
  connect(samCoo.y, greThr4.u)
  connect(greThr4.y, and3.u1)
  connect(samHea.y, greThr5.u)
  connect(greThr5.y, and2.u2)
  connect(and3.y, lat.u)
  connect(falEdg.y, lat.clr)
  connect(and2.y, lat1.u)
  connect(falEdg.y, lat1.clr)
  connect(lat.y, swi2.u2)
  connect(VActMin_flow, swi2.u1)
  connect(conZer2.y, swi2.u3)
  connect(lat1.y, swi3.u2)
  connect(VActMin_flow, swi3.u1)
  connect(conZer2.y, swi3.u3)
  connect(swi2.y, swi.u3)
  connect(greThr2.y, swi4.u2)
  connect(swi1.y, swi4.u1)
  connect(swi3.y, swi4.u3)
  connect(heaDamPos.y, yHeaDam)
  connect(VDis_flowNor1.y, conHeaDam.u_m)
  connect(VDisSet_flowNor1.y, conHeaDam.u_s)
  connect(VHotDucDis_flow, VDis_flowNor1.u1)
  connect(conZer3.y, cooDamPos.u1)
  connect(conZer3.y, heaDamPos.u1)
  connect(u1HeaAHU, not2.u)
  connect(not2.y, heaDamPos.u2)
  connect(u1HeaAHU, conHeaDam.trigger)
  connect(u1CooAHU, not3.u)
  connect(not3.y, cooDamPos.u2)
  connect(u1CooAHU, conCooDam.trigger)
  connect(greThr1.y, booToRea.u)
  connect(swi4.y, mul.u1)
  connect(booToRea.y, mul.u2)
  connect(mul.y, VHotDucDis_flow_Set)
  connect(mul.y, VDisSet_flowNor1.u1)
  connect(booToRea.y, mul1.u2)
  connect(mul1.y, heaDamPos.u3)
  connect(conHeaDam.y, mul1.u1)
  connect(greThr2.y, booToRea1.u)
  connect(swi.y, mul2.u1)
  connect(booToRea1.y, mul2.u2)
  connect(mul2.y, VColDucDis_flow_Set)
  connect(mul2.y, VDisSet_flowNor.u1)
  connect(booToRea1.y, mul3.u2)
  connect(conCooDam.y, mul3.u1)
  connect(mul3.y, cooDamPos.u3)
  connect(mul2.y, add2.u2)
  connect(mul.y, add2.u1)
  connect(add2.y, VDis_flow_Set)
  connect(cooMax1.y,max2. u1)
  connect(heaMax1.y,max2. u2)
  connect(max2.y, VDisSet_flowNor.u2)
  connect(max2.y, VDis_flowNor.u2)
  connect(max2.y, VDisSet_flowNor1.u2)
  connect(max2.y, VDis_flowNor1.u2)
end DampersDualSensors;


Output signals for controlling dampers of snap-acting controlled dual-duct terminal unit with single discharge airflow sensors. This sequence sets the dampers for snap-acting controlled dual-duct terminal unit
with single discharge airflow sensors.
The implementation is according to Section 5.11.5.2 of ASHRAE Guideline 36, May 2020. The
calculation is done following the steps below.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences;
block DampersSingleSensors
  "Output signals for controlling dampers of snap-acting controlled dual-duct terminal unit with single discharge airflow sensors"

  parameter Real VCooMax_flow(
    final quantity="VolumeFlowRate",
    final unit="m3/s")
    "Design zone cooling maximum airflow rate";
  parameter Real VHeaMax_flow(
    final quantity="VolumeFlowRate",
    final unit="m3/s")
    "Design zone heating maximum airflow rate";
  parameter Buildings.Controls.OBC.CDL.Types.SimpleController controllerTypeDam=
    Buildings.Controls.OBC.CDL.Types.SimpleController.PI
    "Type of controller"
  parameter Real kDam(final unit="1")=0.5
    "Gain of controller for damper control"
  parameter Real TiDam(
    final unit="s",
    final quantity="Time")=300
    "Time constant of integrator block for damper control"
  parameter Real TdDam(
    final unit="s",
    final quantity="Time")=0.1
    "Time constant of derivative block for damper control"
  parameter Real samplePeriod(
    final unit="s",
    final quantity="Time",
    final min=1E-3)
    "Sample period of component"
  parameter Real looHys(
    final unit="1") = 0.05
    "Loop output hysteresis below which the output will be seen as zero"
  parameter Real iniDam(unit="1")=0.01
    "Initial damper position when the damper control is enabled"

  Buildings.Controls.OBC.CDL.Interfaces.RealInput uCoo(
    final min=0,
    final max=1,
    final unit="1")
    "Cooling control signal"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VActCooMax_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Active cooling maximum airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VActMin_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Active minimum airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uHea(
    final min=0,
    final max=1,
    final unit="1")
    "Heating control signal"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VActHeaMax_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Active heating maximum airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VDis_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Measured discharge airflow rate airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1CooAHU
    "Cooling air handler status"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1HeaAHU
    "Heating air handler status"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput VDis_flow_Set(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Discharge airflow setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1CooDam
    "Cooling damper command open"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yCooDam(
    final min=0,
    final max=1,
    final unit="1") "Cold duct damper commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1HeaDam
    "Heating damper command open"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yHeaDam(
    final min=0,
    final max=1,
    final unit="1") "Hot duct damper commanded position"

  Buildings.Controls.OBC.CDL.Reals.Line lin
    "Active airflow setpoint for cooling"
  Buildings.Controls.OBC.CDL.Reals.PIDWithReset conCooDam(
    final controllerType=controllerTypeDam,
    final k=kDam,
    final Ti=TiDam,
    final Td=TdDam,
    final yMax=1,
    final yMin=0,
    final y_reset=iniDam)
    "Cooling damper position controller"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conZer(
    final k=0) "Constant zero"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conOne(
    final k=1) "Constant one"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr1(
    final t=looHys,
    final h=0.5*looHys)
    "Check if it is cooling state"
  Buildings.Controls.OBC.CDL.Reals.Switch damPos "Output damper position"
  Buildings.Controls.OBC.CDL.Reals.Divide VDis_flowNor
    "Normalized discharge volume flow rate"
  Buildings.Controls.OBC.CDL.Reals.Divide VDisSet_flowNor
    "Normalized setpoint for discharge volume flow rate"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conZer1(
    final k=0)
    "Constant zero"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr2(
    final t=looHys,
    final h=0.5*looHys)
    "Check if it is heating state"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conOne1(
    final k=1)
    "Constant one"
  Buildings.Controls.OBC.CDL.Reals.Line lin1
    "Active airflow setpoint for heating"
  Buildings.Controls.OBC.CDL.Logical.Or or2
    "Cooing or heating state"
  Buildings.Controls.OBC.CDL.Logical.Not not1
    "In deadband"
  Buildings.Controls.OBC.CDL.Logical.FallingEdge falEdg
    "Becoming heating or cooling state"
  Buildings.Controls.OBC.CDL.Logical.And and2
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.And and3
    "Logical and"
  Buildings.Controls.OBC.CDL.Discrete.Sampler samHea(
    final samplePeriod=samplePeriod)
    "Sample the heating loop output"
  Buildings.Controls.OBC.CDL.Discrete.Sampler samCoo(
    final samplePeriod=samplePeriod)
    "Sample the cooling loop output"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr4(
    final t=looHys,
    final h=0.5*looHys)
    "Check if it is cooling state"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr5(
    final t=looHys,
    final h=0.5*looHys) "Check if it is heating state"
  Buildings.Controls.OBC.CDL.Logical.Latch lat
    "Changing from cooling state to deadband"
  Buildings.Controls.OBC.CDL.Logical.Latch lat1
    "Changing from heating state to deadband"
  Buildings.Controls.OBC.CDL.Reals.Switch cooFloSet
    "Flow setpoint when it is in cooling state"
  Buildings.Controls.OBC.CDL.Reals.Switch heaFloSet
    "Flow setpoint when it is in heating state"
  Buildings.Controls.OBC.CDL.Logical.Or or1
    "Check if any air handler is proven on"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant conZer3(
    final k=0)
    "Constant zero"
  Buildings.Controls.OBC.CDL.Logical.Or or3
    "Check if it is in cooling state or in deadband that switched from cooling state"
  Buildings.Controls.OBC.CDL.Reals.Switch cooDamPos "Cooling damper position"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea(
    final realTrue=0,
    final realFalse=1)
    "Ensure cooling damper closed when the cooling air handler is not proven on"
  Buildings.Controls.OBC.CDL.Reals.Multiply mul1
    "Make sure cooling damper is closed when the cooling air handler is not proven on"
  Buildings.Controls.OBC.CDL.Logical.Or or4
    "Check if it is in heating state or in deadband that switched from heating state"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea1(
    final realTrue=0,
    final realFalse=1)
    "Ensure heating damper closed when the heating air handler is not proven on"
  Buildings.Controls.OBC.CDL.Reals.Multiply mul2
    "Make sure heating damper is closed when the heating air handler is not proven on"
  Buildings.Controls.OBC.CDL.Reals.Switch heaDamPos
    "Heating damper position"
  Buildings.Controls.OBC.CDL.Logical.And and1
    "Check if cooling damper is opening"
  Buildings.Controls.OBC.CDL.Logical.And and4
    "Check if heating damper is opening"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant heaMax1(
    final k=VHeaMax_flow)
    "Heating maximum flow"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant cooMax1(
    final k=VCooMax_flow)
    "Cooling maximum flow"
  Buildings.Controls.OBC.CDL.Reals.Max max2
    "Nominal flow"
equation
  connect(uCoo, lin.u)
  connect(conZer.y, lin.x1)
  connect(conOne.y, lin.x2)
  connect(VActCooMax_flow, lin.f2)
  connect(uCoo, greThr1.u)
  connect(VDis_flowNor.y, conCooDam.u_m)
  connect(VDisSet_flowNor.y, conCooDam.u_s)
  connect(VActMin_flow, lin.f1)
  connect(conZer1.y, lin1.x1)
  connect(VActMin_flow, lin1.f1)
  connect(conOne1.y, lin1.x2)
  connect(uHea, lin1.u)
  connect(uHea, greThr2.u)
  connect(VActHeaMax_flow, lin1.f2)
  connect(greThr1.y, or2.u1)
  connect(greThr2.y, or2.u2)
  connect(or2.y, not1.u)
  connect(not1.y, falEdg.u)
  connect(not1.y, and2.u1)
  connect(not1.y, and3.u2)
  connect(uHea, samHea.u)
  connect(uCoo, samCoo.u)
  connect(samCoo.y, greThr4.u)
  connect(greThr4.y, and3.u1)
  connect(samHea.y, greThr5.u)
  connect(greThr5.y, and2.u2)
  connect(and3.y, lat.u)
  connect(falEdg.y, lat.clr)
  connect(and2.y, lat1.u)
  connect(falEdg.y, lat1.clr)
  connect(greThr1.y, cooFloSet.u2)
  connect(lin.y, cooFloSet.u1)
  connect(heaFloSet.y, cooFloSet.u3)
  connect(greThr2.y, heaFloSet.u2)
  connect(lin1.y, heaFloSet.u1)
  connect(VActMin_flow, heaFloSet.u3)
  connect(cooFloSet.y, VDis_flow_Set)
  connect(cooFloSet.y, VDisSet_flowNor.u1)
  connect(VDis_flow, VDis_flowNor.u1)
  connect(u1CooAHU, or1.u1)
  connect(u1HeaAHU, or1.u2)
  connect(or1.y, conCooDam.trigger)
  connect(or1.y, damPos.u2)
  connect(conCooDam.y, damPos.u1)
  connect(conZer3.y, damPos.u3)
  connect(greThr1.y, or3.u1)
  connect(lat.y, or3.u2)
  connect(u1CooAHU, booToRea.u)
  connect(damPos.y, mul1.u1)
  connect(booToRea.y, mul1.u2)
  connect(or3.y, cooDamPos.u2)
  connect(mul1.y, cooDamPos.u1)
  connect(conZer3.y, cooDamPos.u3)
  connect(greThr2.y, or4.u1)
  connect(lat1.y, or4.u2)
  connect(u1HeaAHU, booToRea1.u)
  connect(or4.y, heaDamPos.u2)
  connect(damPos.y, mul2.u1)
  connect(booToRea1.y, mul2.u2)
  connect(mul2.y, heaDamPos.u1)
  connect(conZer3.y, heaDamPos.u3)
  connect(u1CooAHU, and1.u1)
  connect(or3.y, and1.u2)
  connect(and1.y, y1CooDam)
  connect(or4.y, and4.u2)
  connect(u1HeaAHU, and4.u1)
  connect(and4.y, y1HeaDam)
  connect(cooDamPos.y, yCooDam)
  connect(heaDamPos.y, yHeaDam)
  connect(heaMax1.y,max2. u2)
  connect(cooMax1.y,max2. u1)
  connect(max2.y, VDisSet_flowNor.u2)
  connect(max2.y, VDis_flowNor.u2)
end DampersSingleSensors;


Software switches to override setpoints. This block considers the overrides to the setpoints for snap-acting controlled
dual-duct terminal unit.
The implementation is according to the Section 5.11.7 of ASHRAE Guideline 36,
May 2020.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences;
block Overrides "Software switches to override setpoints"

  parameter Real VMin_flow(
    final quantity="VolumeFlowRate",
    final unit="m3/s")
    "Design zone minimum airflow setpoint";
  parameter Real VCooMax_flow(
    final quantity="VolumeFlowRate",
    final unit="m3/s")
    "Design zone cooling maximum airflow rate";
  parameter Real VHeaMax_flow(
    final quantity="VolumeFlowRate",
    final unit="m3/s")
    "Design zone heating maximum airflow rate";

  Buildings.Controls.OBC.CDL.Interfaces.IntegerInput oveFloSet
    "Index of overriding flow setpoint, 1: set to zero; 2: set to cooling maximum; 3: set to minimum flow; 4: set to heating maximum"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VActSet_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Active airflow setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerInput oveCooDamPos
    "Index of overriding cooling damper position, 1: set to close; 2: set to open"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uCooDam(
    final min=0,
    final unit="1") "Cooling damper commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerInput oveHeaDamPos
    "Index of overriding heating damper position, 1: set to close; 2: set to open"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uHeaDam(
    final min=0,
    final unit="1") "Heating damper commanded position"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput VSet_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Airflow setpoint after considering override"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yCooDam(
    final min=0,
    final unit="1")
    "Cooling damper commanded position, after considering override"
  Buildings.Controls.OBC.CDL.Interfaces.RealOutput yHeaDam(
    final min=0,
    final unit="1")
    "Heating damper commanded position, after considering override"

protected
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt(
    final k=1)
    "Constant 1"
  Buildings.Controls.OBC.CDL.Integers.Equal forZerFlo "Check if forcing zone airflow setpoint to zero"
  Buildings.Controls.OBC.CDL.Integers.Equal forCooMax
    "Check if forcing zone airflow setpoint to cooling maximum"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt1(
    final k=2)
    "Constant 2"
  Buildings.Controls.OBC.CDL.Integers.Equal forMinFlo
    "Check if forcing zone airflow setpoint to minimum flow"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt2(
    final k=3)
    "Constant 3"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal zerFlo(
    final realTrue=0)
    "Force zone airflow setpoint to zero"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal cooMax(
    final realTrue=VCooMax_flow)
    "Force zone airflow setpoint to cooling maximum"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal minFlo(
    final realTrue=VMin_flow)
    "Force zone airflow setpoint to zone minimum flow"
  Buildings.Controls.OBC.CDL.Reals.Add add2 "Add up two inputs"
  Buildings.Controls.OBC.CDL.Reals.Add add1 "Add up inputs"
  Buildings.Controls.OBC.CDL.Reals.Switch swi
    "Airflow setpoint after considering override"
  Buildings.Controls.OBC.CDL.Logical.Or or3
    "Check if the airflow setpoint should be overrided"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt3(
    final k=1)
    "Constant 1"
  Buildings.Controls.OBC.CDL.Integers.Equal intEqu3
    "Check if forcing damper to full close"
  Buildings.Controls.OBC.CDL.Integers.Equal intEqu4
    "Check if forcing damper to full open"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt4(
    final k=2)
    "Constant 2"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal cloDam(
    final realTrue=0)
    "Full closed damper position"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal opeDam(
    final realTrue=1)
    "Full open damper position"
  Buildings.Controls.OBC.CDL.Reals.Add add3 "Add up inputs"
  Buildings.Controls.OBC.CDL.Logical.Or or2
    "Check if the damper setpoint position should be overrided"
  Buildings.Controls.OBC.CDL.Reals.Switch swi1
    "Damper setpoint position after considering override"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt5(
    final k=4)
    "Constant 4"
  Buildings.Controls.OBC.CDL.Integers.Equal forMinFlo1
    "Check if forcing zone airflow setpoint to minimum flow"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal heaMax(
    final realTrue=VHeaMax_flow)
    "Force zone airflow setpoint to zone heating maximum flow"
  Buildings.Controls.OBC.CDL.Reals.Add add4
    "Add up two inputs"
  Buildings.Controls.OBC.CDL.Logical.Or or1
    "Check if the airflow setpoint should be overrided"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt6(
    final k=1)
    "Constant 1"
  Buildings.Controls.OBC.CDL.Integers.Equal intEqu1
    "Check if forcing damper to full close"
  Buildings.Controls.OBC.CDL.Integers.Equal intEqu2
    "Check if forcing damper to full open"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conInt7(
    final k=2)
    "Constant 2"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal cloDam1(
    final realTrue=0)
    "Full closed damper position"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal opeDam1(
    final realTrue=1)
    "Full open damper position"
  Buildings.Controls.OBC.CDL.Reals.Add add5
    "Add up inputs"
  Buildings.Controls.OBC.CDL.Logical.Or or4
    "Check if the damper setpoint position should be overrided"
  Buildings.Controls.OBC.CDL.Reals.Switch swi2
    "Damper setpoint position after considering override"
  Buildings.Controls.OBC.CDL.Logical.Or or5
    "Check if the airflow setpoint should be overrided"

equation
  connect(oveFloSet, forZerFlo.u1)
  connect(conInt.y, forZerFlo.u2)
  connect(oveFloSet, forCooMax.u1)
  connect(conInt1.y, forCooMax.u2)
  connect(oveFloSet, forMinFlo.u1)
  connect(conInt2.y, forMinFlo.u2)
  connect(forZerFlo.y, zerFlo.u)
  connect(forCooMax.y, cooMax.u)
  connect(forMinFlo.y, minFlo.u)
  connect(cooMax.y, add2.u1)
  connect(zerFlo.y, add1.u1)
  connect(forZerFlo.y, or3.u1)
  connect(forCooMax.y, or3.u2)
  connect(add1.y, swi.u1)
  connect(VActSet_flow, swi.u3)
  connect(swi.y, VSet_flow)
  connect(conInt3.y, intEqu3.u2)
  connect(conInt4.y,intEqu4. u2)
  connect(oveCooDamPos, intEqu3.u1)
  connect(oveCooDamPos, intEqu4.u1)
  connect(intEqu3.y, cloDam.u)
  connect(intEqu4.y, opeDam.u)
  connect(cloDam.y, add3.u1)
  connect(opeDam.y, add3.u2)
  connect(intEqu3.y, or2.u1)
  connect(intEqu4.y, or2.u2)
  connect(add3.y, swi1.u1)
  connect(or2.y, swi1.u2)
  connect(uCooDam, swi1.u3)
  connect(swi1.y, yCooDam)
  connect(oveFloSet, forMinFlo1.u1)
  connect(conInt5.y, forMinFlo1.u2)
  connect(forMinFlo1.y, heaMax.u)
  connect(add2.y, add1.u2)
  connect(minFlo.y, add4.u1)
  connect(heaMax.y, add4.u2)
  connect(add4.y, add2.u2)
  connect(forMinFlo1.y, or1.u2)
  connect(or1.y, swi.u2)
  connect(conInt6.y,intEqu1. u2)
  connect(conInt7.y,intEqu2. u2)
  connect(oveHeaDamPos, intEqu1.u1)
  connect(oveHeaDamPos, intEqu2.u1)
  connect(intEqu1.y, cloDam1.u)
  connect(intEqu2.y, opeDam1.u)
  connect(cloDam1.y, add5.u1)
  connect(opeDam1.y, add5.u2)
  connect(intEqu1.y,or4. u1)
  connect(intEqu2.y,or4. u2)
  connect(add5.y,swi2. u1)
  connect(or4.y,swi2. u2)
  connect(uHeaDam, swi2.u3)
  connect(swi2.y, yHeaDam)
  connect(or3.y, or5.u1)
  connect(or5.y, or1.u1)
  connect(forMinFlo.y, or5.u2)
end Overrides;


within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing;
package Subsequences "Package of subsequences for snap-acting controlled dual-duct terminal unit"
end Subsequences;


Output system requests for VAV terminal unit with reheat. This sequence outputs the system reset requests for snap-acting controlled dual-duct
terminal unit. The implementation is according to the Section 5.11.8 of ASHRAE
Guideline 36, May 2020.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences;
block SystemRequests "Output system requests for VAV terminal unit with reheat"

  parameter Boolean have_duaSen
    "True: the unit has dual inlet sensors";
  parameter Real thrTemDif(
    final unit="K",
    final quantity="TemperatureDifference")=3
    "Threshold difference between zone temperature and cooling setpoint for generating 3 cooling SAT reset requests"
  parameter Real twoTemDif(
    final unit="K",
    final quantity="TemperatureDifference")=2
    "Threshold difference between zone temperature and cooling setpoint for generating 2 cooling SAT reset requests"
  parameter Real durTimTem(
    final unit="s",
    final quantity="Time")=120
    "Duration time of zone temperature exceeds setpoint"
  parameter Real durTimFlo(
    final unit="s",
    final quantity="Time")=60
    "Duration time of airflow rate less than setpoint"
  parameter Real dTHys(
    final unit="K",
    final quantity="TemperatureDifference")=0.25
    "Near zero temperature difference, below which the difference will be seen as zero"
  parameter Real floHys(
    final quantity="VolumeFlowRate",
    final unit="m3/s")
    "Near zero flow rate, below which the flow rate or difference will be seen as zero"
  parameter Real looHys(unit="1")
    "Loop output hysteresis below which the output will be seen as zero"
  parameter Real damPosHys(
    final unit="1")
    "Near zero damper position, below which the damper will be seen as closed"

  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uAftSupCoo
    "After suppression period due to the cooling setpoint change"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TCooSet(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    "Zone cooling setpoint temperature"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput TZon(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    "Zone temperature"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uCoo(
    final min=0,
    final max=1,
    final unit="1") "Cooling loop signal"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VColDuc_flow_Set(
    final min=0,
    final unit="m3/s",
    quantity="VolumeFlowRate") "Cold duct discharge airflow rate setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VColDucDis_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Measured cold duct discharge airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uCooDam(
    final min=0,
    final max=1,
    final unit="1")
    "Cooling damper position setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1CooDam
    if not have_duaSen
    "Cold duct damper proven on"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput uAftSupHea
    "After suppression period due to the heating setpoint change"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput THeaSet(
    final unit="K",
    final displayUnit="degC",
    final quantity="ThermodynamicTemperature")
    "Zone heating setpoint temperature"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uHea(
    final min=0,
    final max=1,
    final unit="1")
    "Heating loop signal"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VHotDuc_flow_Set(
    final min=0,
    final unit="m3/s",
    quantity="VolumeFlowRate")
    "Hot duct discharge airflow rate setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput VHotDucDis_flow(
    final min=0,
    final unit="m3/s",
    final quantity="VolumeFlowRate")
    "Measured hot duct discharge airflow rate"
  Buildings.Controls.OBC.CDL.Interfaces.RealInput uHeaDam(
    final min=0,
    final max=1,
    final unit="1")
    "Heating damper position setpoint"
  Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1HeaDam
    if not have_duaSen
    "Hot duct damper proven on"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yZonCooTemResReq
    "Zone cooling supply air temperature reset request"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yColDucPreResReq
    "Cold duct static pressure reset requests"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yZonHeaTemResReq
    "Zone heating supply air temperature reset request"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yHotDucPreResReq
    "Hot duct static pressure reset requests"
  Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yHeaFanReq
    "Heating fan request"

protected
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr1(
    final t=thrTemDif,
    final h=dTHys)
    "Check if zone temperature is greater than cooling setpoint by threshold"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr2(
    final t=twoTemDif,
    final h=dTHys)
    "Check if zone temperature is greater than cooling setpoint by threshold"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr3(
    final t=0.95,
    final h=damPosHys)
    "Check if damper position is greater than 0.95"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr(
    final t=0.95,
    final h=looHys)
    "Check if cooling loop signal is greater than 0.95"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr4(
    final t=floHys,
    final h=0.5*floHys)
    "Check if discharge airflow setpoint is greater than 0"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt
    "Convert boolean to integer"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt1
    "Convert boolean to integer"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai1(
    final k=0.5)
    "50% of setpoint"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai2(
    final k=0.7)
    "70% of setpoint"
  Buildings.Controls.OBC.CDL.Reals.Subtract sub2
    "Calculate difference between zone temperature and cooling setpoint"
  Buildings.Controls.OBC.CDL.Reals.Subtract sub3
    "Calculate difference between zone temperature and cooling setpoint"
  Buildings.Controls.OBC.CDL.Logical.And and1
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.And and2
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.And and3
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.And and4
    "Logical and"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant thrCooResReq(
    final k=3)
    "Constant 3"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant twoCooResReq(
    final k=2) "Constant 2"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant thrPreResReq(
    final k=3) "Constant 3"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant twoPreResReq(
    final k=2)
    "Constant 2"
  Buildings.Controls.OBC.CDL.Integers.Switch intSwi
    "Output 3 or other request "
  Buildings.Controls.OBC.CDL.Integers.Switch intSwi1
    "Output 2 or other request "
  Buildings.Controls.OBC.CDL.Integers.Switch swi4
    "Output 3 or other request "
  Buildings.Controls.OBC.CDL.Integers.Switch swi5
    "Output 2 or other request "
  Buildings.Controls.OBC.CDL.Logical.TrueDelay tim1(
    final delayTime=durTimTem) "Check if it is more than threshold time"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay tim2(
    final delayTime=durTimTem) "Check if it is more than threshold time"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay tim3(
    final delayTime=durTimFlo) "Check if it is more than threshold time"
  Buildings.Controls.OBC.CDL.Reals.Greater greEqu(final h=floHys)
    "Check if discharge airflow is less than 50% of setpoint"
  Buildings.Controls.OBC.CDL.Reals.Greater greEqu1(final h=floHys)
    "Check if discharge airflow is less than 70% of setpoint"
  Buildings.Controls.OBC.CDL.Logical.And and5
    "Logical and"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr7(
    final t=thrTemDif,
    final h=dTHys)
    "Check if zone temperature is less than heating setpoint by threshold"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr8(
    final t=twoTemDif,
    final h=dTHys)
    "Check if zone temperature is less than heating setpoint by threshold"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr9(
    final t=0.95,
    final h=damPosHys)
    "Check if damper position is greater than 0.95"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr10(
    final t=0.95,
    final h=looHys) "Check if heating loop signal is greater than 0.95"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr11(
    final t=floHys,
    final h=0.5*floHys)
    "Check if discharge airflow setpoint is greater than 0"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt4
    "Convert boolean to integer"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt5
    "Convert boolean to integer"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai3(
    final k=0.5)
    "50% of setpoint"
  Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter gai4(
    final k=0.7)
    "70% of setpoint"
  Buildings.Controls.OBC.CDL.Reals.Subtract sub1
    "Calculate difference between zone temperature and heating setpoint"
  Buildings.Controls.OBC.CDL.Reals.Subtract sub4
    "Calculate difference between zone temperature and heating setpoint"
  Buildings.Controls.OBC.CDL.Logical.And and6
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.And and7
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.And and8
    "Logical and"
  Buildings.Controls.OBC.CDL.Logical.And and9
    "Logical and"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant thrCooResReq1(
    final k=3)
    "Constant 3"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant twoCooResReq1(
    final k=2)
    "Constant 2"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant thrPreResReq1(
    final k=3)
    "Constant 3"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant twoPreResReq1(
    final k=2)
    "Constant 2"
  Buildings.Controls.OBC.CDL.Integers.Switch intSwi4
    "Output 3 or other request "
  Buildings.Controls.OBC.CDL.Integers.Switch intSwi5
    "Output 2 or other request "
  Buildings.Controls.OBC.CDL.Integers.Switch swi1
    "Output 3 or other request "
  Buildings.Controls.OBC.CDL.Integers.Switch swi2
    "Output 2 or other request "
  Buildings.Controls.OBC.CDL.Logical.TrueDelay tim6(
    final delayTime=durTimTem)
    "Check if it is more than threshold time"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay tim7(
    final delayTime=durTimTem)
    "Check if it is more than threshold time"
  Buildings.Controls.OBC.CDL.Logical.TrueDelay tim8(
    final delayTime=durTimFlo)
    "Check if it is more than threshold time"
  Buildings.Controls.OBC.CDL.Reals.Greater greEqu2(final h=floHys)
    "Check if discharge airflow is less than 50% of setpoint"
  Buildings.Controls.OBC.CDL.Reals.Greater greEqu3(final h=floHys)
    "Check if discharge airflow is less than 70% of setpoint"
  Buildings.Controls.OBC.CDL.Logical.And and10
    "Logical and"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr12(
    final t=0.15,
    final h=looHys)
    "Check if heating loop signal is greater than 0.15"
  Buildings.Controls.OBC.CDL.Logical.Latch lat "Hold the true input"
  Buildings.Controls.OBC.CDL.Reals.LessThreshold lesThr(
    final t=0.01,
    final h=looHys)
    "Check if the heating loop output is less than threshold"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt6
    "Heating fan request"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conOne(
    final k=1) if have_duaSen
    "Constant 1"
  Buildings.Controls.OBC.CDL.Integers.Sources.Constant conOne1(
    final k=1) if have_duaSen
    "Constant 1"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt2 if not have_duaSen
    "Convert boolean to integer"
  Buildings.Controls.OBC.CDL.Integers.Multiply mulInt if not have_duaSen
    "Ensure zero request when the damper is not opening"
  Buildings.Controls.OBC.CDL.Integers.Multiply mulInt1 if have_duaSen
    "Two inputs product"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt3 if not have_duaSen
    "Convert boolean to integer"
  Buildings.Controls.OBC.CDL.Integers.Multiply mulInt2 if not have_duaSen
    "Ensure zero request when the damper is not opening"
  Buildings.Controls.OBC.CDL.Integers.Multiply mulInt3 if have_duaSen
    "Two inputs product"

equation
  connect(sub2.y, greThr1.u)
  connect(and2.y, intSwi.u2)
  connect(sub3.y, greThr2.u)
  connect(and1.y, intSwi1.u2)
  connect(and3.y, swi4.u2)
  connect(and4.y, swi5.u2)
  connect(greThr2.y, tim2.u)
  connect(tim2.y, and1.u2)
  connect(greThr1.y, tim1.u)
  connect(tim1.y, and2.u2)
  connect(greThr4.u, VColDuc_flow_Set)
  connect(greEqu.u1, gai1.y)
  connect(greEqu.y, and3.u2)
  connect(gai2.y, greEqu1.u1)
  connect(greEqu1.y, and4.u2)
  connect(uCoo, greThr.u)
  connect(uAftSupCoo, and2.u1)
  connect(uAftSupCoo, and1.u1)
  connect(thrCooResReq.y, intSwi.u1)
  connect(twoCooResReq.y, intSwi1.u1)
  connect(intSwi1.y, intSwi.u3)
  connect(intSwi.y, yZonCooTemResReq)
  connect(greThr.y, booToInt.u)
  connect(booToInt.y, intSwi1.u3)
  connect(uCooDam, greThr3.u)
  connect(VColDuc_flow_Set, gai1.u)
  connect(VColDuc_flow_Set, gai2.u)
  connect(VColDucDis_flow, greEqu.u2)
  connect(VColDucDis_flow, greEqu1.u2)
  connect(greThr3.y, tim3.u)
  connect(greThr4.y, and5.u1)
  connect(tim3.y, and5.u2)
  connect(and5.y, and3.u1)
  connect(and5.y, and4.u1)
  connect(greThr3.y, booToInt1.u)
  connect(booToInt1.y, swi5.u3)
  connect(twoPreResReq.y, swi5.u1)
  connect(thrPreResReq.y, swi4.u1)
  connect(swi5.y, swi4.u3)
  connect(TCooSet, sub3.u2)
  connect(TCooSet, sub2.u2)
  connect(TZon, sub2.u1)
  connect(TZon, sub3.u1)
  connect(sub1.y,greThr7. u)
  connect(and7.y, intSwi4.u2)
  connect(sub4.y,greThr8. u)
  connect(and6.y,intSwi5. u2)
  connect(and8.y,swi1. u2)
  connect(and9.y,swi2. u2)
  connect(greThr8.y,tim7. u)
  connect(tim7.y,and6. u2)
  connect(greThr7.y,tim6. u)
  connect(tim6.y,and7. u2)
  connect(greThr11.u, VHotDuc_flow_Set)
  connect(greEqu2.u1, gai3.y)
  connect(greEqu2.y, and8.u2)
  connect(gai4.y,greEqu3. u1)
  connect(greEqu3.y,and9. u2)
  connect(uHea, greThr10.u)
  connect(uAftSupHea, and7.u1)
  connect(uAftSupHea, and6.u1)
  connect(thrCooResReq1.y, intSwi4.u1)
  connect(twoCooResReq1.y, intSwi5.u1)
  connect(intSwi5.y, intSwi4.u3)
  connect(intSwi4.y, yZonHeaTemResReq)
  connect(greThr10.y, booToInt4.u)
  connect(booToInt4.y, intSwi5.u3)
  connect(uHeaDam, greThr9.u)
  connect(VHotDuc_flow_Set, gai3.u)
  connect(VHotDuc_flow_Set, gai4.u)
  connect(VHotDucDis_flow, greEqu2.u2)
  connect(VHotDucDis_flow, greEqu3.u2)
  connect(greThr9.y,tim8. u)
  connect(greThr11.y, and10.u1)
  connect(tim8.y, and10.u2)
  connect(and10.y, and8.u1)
  connect(and10.y, and9.u1)
  connect(greThr9.y,booToInt5. u)
  connect(booToInt5.y,swi2. u3)
  connect(twoPreResReq1.y, swi2.u1)
  connect(thrPreResReq1.y, swi1.u1)
  connect(swi2.y,swi1. u3)
  connect(THeaSet, sub1.u1)
  connect(THeaSet, sub4.u1)
  connect(TZon, sub1.u2)
  connect(TZon, sub4.u2)
  connect(uHea, greThr12.u)
  connect(greThr12.y, lat.u)
  connect(uHea, lesThr.u)
  connect(lesThr.y, lat.clr)
  connect(lat.y, booToInt6.u)
  connect(booToInt6.y, yHeaFanReq)
  connect(u1CooDam, booToInt2.u)
  connect(booToInt2.y, mulInt.u2)
  connect(swi4.y, mulInt.u1)
  connect(swi4.y, mulInt1.u1)
  connect(conOne.y, mulInt1.u2)
  connect(mulInt1.y, yColDucPreResReq)
  connect(mulInt.y, yColDucPreResReq)
  connect(u1HeaDam, booToInt3.u)
  connect(booToInt3.y, mulInt2.u2)
  connect(conOne1.y, mulInt3.u2)
  connect(swi1.y, mulInt3.u1)
  connect(swi1.y, mulInt2.u1)
  connect(mulInt3.y, yHotDucPreResReq)
  connect(mulInt2.y, yHotDucPreResReq)
end SystemRequests;


Validate the model for calculating active airflow setpoint for dual-duct terminal unit. This example validates

Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.ActiveAirFlow
for calculating active minimum and maximum airflow setpoint used in dual-duct terminal unit.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.Validation;
model ActiveAirFlow
  "Validate the model for calculating active airflow setpoint for dual-duct terminal unit"
  Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.ActiveAirFlow actAirSet(
    final VCooMax_flow=0.5,
    final VHeaMax_flow=0.4)
    "Output the active airflow setpoint for terminal unit"
  Buildings.Controls.OBC.CDL.Reals.Sources.Sin minFlo(
    final amplitude=0.3,
    final freqHz=1/3600,
    final offset=0.2) "Occupied zone minimum flow"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp opeMod(
    final offset=1,
    final height=5,
    final duration=3600)
    "Operation mode"
  Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt2
    "Convert real to integer"
  Buildings.Controls.OBC.CDL.Reals.Round round2(final n=0)
    "Round real number to given digits"

equation
  connect(opeMod.y,round2. u)
  connect(round2.y,reaToInt2. u)
  connect(reaToInt2.y, actAirSet.uOpeMod)
  connect(minFlo.y, actAirSet.VOccMin_flow)
end ActiveAirFlow;


Validation of model that generates alarms. This example validates

Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.Alarms
for generating system alarms.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.Validation;
model Alarms "Validation of model that generates alarms"

  Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.Alarms ala(
    final have_duaSen=true,
    final staPreMul=1,
    final VCooMax_flow=1,
    final VHeaMax_flow=0.9,
    final floHys=0.01,
    final damPosHys=0.01) "Block outputs system alarms"
  Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.Alarms ala1(
    final have_duaSen=false,
    final staPreMul=1,
    final VCooMax_flow=1,
    final VHeaMax_flow=0.9,
    final floHys=0.01,
    final damPosHys=0.01) "Block outputs system alarms"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp disAirSet(
    final height=0.9,
    final duration=7200,
    final offset=0.1) "Discharge airflow rate setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp cooDisAir(
    final duration=7200,
    final offset=0.1,
    final height=0.3) "Cooling duct discharge airflow rate"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp damPos(
    final duration=7200,
    final height=0.7,
    final offset=0.3) "Damper position"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse supCooFan(
    final width=0.75,
    final period=7500) "Cooling supply fan status"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea
    "Convert boolean input to real output"
  Buildings.Controls.OBC.CDL.Reals.Multiply mul
    "Damper position"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse colDammSta(
    final width=0.5,
    final period=7500) "Cooling duct damper open and close status"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp damPos1(
    final duration=7200,
    final height=0.7,
    final offset=0.3) "Damper position"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse supHeaFan(
    final width=0.75,
    final period=7500)
    "Heating supply fan status"
  Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea1
    "Convert boolean input to real output"
  Buildings.Controls.OBC.CDL.Reals.Multiply  mul1
    "Damper position"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse heaDammSta(
    final width=0.5,
    final period=7500)
    "Heating duct damper open and close status"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp heaDisAir(
    final duration=7200,
    final offset=0.1,
    final height=0.3) "Heating duct discharge airflow rate"
  Buildings.Controls.OBC.CDL.Integers.Sources.Pulse intPul(
    amplitude=6,
    width=0.1,
    period=8500,
    offset=1)
    "Operation mode"
equation
  connect(disAirSet.y, ala.VActSet_flow)
  connect(booToRea.y, mul.u1)
  connect(damPos.y, mul.u2)
  connect(colDammSta.y, booToRea.u)
  connect(booToRea1.y, mul1.u1)
  connect(damPos1.y, mul1.u2)
  connect(heaDammSta.y, booToRea1.u)
  connect(supCooFan.y, ala.u1CooFan)
  connect(mul.y, ala.uCooDam)
  connect(supHeaFan.y, ala.u1HeaFan)
  connect(mul1.y, ala.uHeaDam)
  connect(cooDisAir.y, ala.VColDucDis_flow)
  connect(heaDisAir.y, ala.VHotDucDis_flow)
  connect(supCooFan.y, ala1.u1CooFan)
  connect(mul.y, ala1.uCooDam)
  connect(supHeaFan.y, ala1.u1HeaFan)
  connect(mul1.y, ala1.uHeaDam)
  connect(disAirSet.y, ala1.VActSet_flow)
  connect(cooDisAir.y, ala1.VDis_flow)
  connect(intPul.y, ala.uOpeMod)
  connect(intPul.y, ala1.uOpeMod)
end Alarms;


Validate model for controlling damper position of dual-duct unit. This example validates

BBuildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.DampersDualSensors
for damper control of dual-duct unit.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.Validation;
model DampersDualSensors
  "Validate model for controlling damper position of dual-duct unit"

  Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.DampersDualSensors dam1(
    final VCooMax_flow=0.08,
    final VHeaMax_flow=0.06,
    final kDam=1,
    final samplePeriod=120) "Output signal for controlling damper position"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp uCoo(
    final height=-1,
    final duration=3600,
    final offset=1,
    final startTime=900) "Cooling control signal"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TZon(
    final k=273.15 + 22)
    "Zone temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant TCooSup(
    final k=273.15 + 13)
    "AHU supply air temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant VActMin_flow(
    final k=0.01)
    "Active minimum airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant VActCooMax_flow(
    final k=0.075)
    "Active cooling maximum airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Sin VColDuc(
    final offset=0.015,
    final amplitude=0.002,
    final freqHz=1/3600)
    "Cold-duct airflow rate"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse cooAhu(
    final width=0.75,
    final period=7200)
    "Cold air handling unit status"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant THeaSup(
    final k=273.15 + 25)
    "AHU supply air temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp uHea(
    final height=1,
    final duration=3600,
    final offset=0,
    final startTime=5500)
    "Heating control signal"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant VActHeaMax_flow(
    final k=0.07)
    "Active heating maximum airflow setpoint"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse heaAhu(
    final width=0.75,
    final period=7200,
    final shift=5000)
    "Hot air handling unit status"
  Buildings.Controls.OBC.CDL.Reals.Sources.Sin VHotDuc(
    final offset=0.015,
    final amplitude=0.002,
    final freqHz=1/3600)
    "Hot-duct airflow rate"

equation
  connect(VActMin_flow.y, dam1.VActMin_flow)
  connect(TZon.y, dam1.TZon)
  connect(VActCooMax_flow.y, dam1.VActCooMax_flow)
  connect(uCoo.y, dam1.uCoo)
  connect(TCooSup.y, dam1.TColSup)
  connect(cooAhu.y, dam1.u1CooAHU)
  connect(THeaSup.y, dam1.THotSup)
  connect(uHea.y, dam1.uHea)
  connect(VActHeaMax_flow.y, dam1.VActHeaMax_flow)
  connect(heaAhu.y, dam1.u1HeaAHU)
  connect(VColDuc.y, dam1.VColDucDis_flow)
  connect(VHotDuc.y, dam1.VHotDucDis_flow)
end DampersDualSensors;


Validate model for controlling damper position of dual-duct unit. This example validates

BBuildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.DampersSingleSensors
for damper control of dual-duct unit.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.Validation;
model DampersSingleSensors
  "Validate model for controlling damper position of dual-duct unit"

  Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.DampersSingleSensors dam1(
    final VCooMax_flow=0.08,
    final VHeaMax_flow=0.06,
    final kDam=1,
    final samplePeriod=120) "Output signal for controlling damper position"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp uCoo(
    final height=-1,
    final duration=3600,
    final offset=1,
    final startTime=900) "Cooling control signal"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant VActMin_flow(
    final k=0.01)
    "Active minimum airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant VActCooMax_flow(
    final k=0.075)
    "Active cooling maximum airflow setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Sin VDis(
    final offset=0.015,
    final amplitude=0.002,
    final freqHz=1/3600) "Discharge airflow rate"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse cooAhu(
    final width=0.75,
    final period=7200)
    "Cold air handling unit status"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp uHea(
    final height=1,
    final duration=3600,
    final offset=0,
    final startTime=5500)
    "Heating control signal"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant VActHeaMax_flow(
    final k=0.07)
    "Active heating maximum airflow setpoint"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse heaAhu(
    final width=0.75,
    final period=7200,
    final shift=5000)
    "Hot air handling unit status"

equation
  connect(VActMin_flow.y, dam1.VActMin_flow)
  connect(VActCooMax_flow.y, dam1.VActCooMax_flow)
  connect(uCoo.y, dam1.uCoo)
  connect(cooAhu.y, dam1.u1CooAHU)
  connect(uHea.y, dam1.uHea)
  connect(VActHeaMax_flow.y, dam1.VActHeaMax_flow)
  connect(heaAhu.y, dam1.u1HeaAHU)
  connect(VDis.y, dam1.VDis_flow)
end DampersSingleSensors;


Validation of model that overrides control. This example validates

Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.Overrides
for overrideing controls.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.Validation;
model Overrides "Validation of model that overrides control"

  Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.Overrides ove(
    final VMin_flow=0.1,
    final VCooMax_flow=0.9,
    final VHeaMax_flow=0.8) "Block outputs system requests"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp disAirSet(
    final height=0.9,
    final duration=7200,
    final offset=0.1) "Discharge airflow rate setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp cooDamPos(
    final duration=3600,
    final height=0.5,
    final offset=0.5) "Cooling damper position setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp oveFlo(
    final height=3,
    final duration=2000,
    startTime=1000) "Override flow setpoint"
  Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt2
    "Convert real to integer"
  Buildings.Controls.OBC.CDL.Reals.Round round2(
    final n=0)
    "Round real number to given digits"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp oveDam(
    final height=2,
    final duration=2000,
    startTime=1000) "Override damper position"
  Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt1
    "Convert real to integer"
  Buildings.Controls.OBC.CDL.Reals.Round round1(
    final n=0)
    "Round real number to given digits"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp heaDamPos(
    final duration=3600,
    final height=0.5,
    final offset=0.5) "Heating damper position setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp oveDam1(
    final height=2,
    final duration=2000,
    startTime=1000) "Override damper position"
  Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt3
    "Convert real to integer"
  Buildings.Controls.OBC.CDL.Reals.Round round3(final n=0)
    "Round real number to given digits"

equation
  connect(oveDam.y, round1.u)
  connect(round1.y, reaToInt1.u)
  connect(oveFlo.y, round2.u)
  connect(round2.y, reaToInt2.u)
  connect(reaToInt2.y, ove.oveFloSet)
  connect(disAirSet.y, ove.VActSet_flow)
  connect(reaToInt1.y, ove.oveCooDamPos)
  connect(cooDamPos.y, ove.uCooDam)
  connect(oveDam1.y, round3.u)
  connect(round3.y,reaToInt3. u)
  connect(reaToInt3.y, ove.oveHeaDamPos)
  connect(heaDamPos.y, ove.uHeaDam)
end Overrides;


Collection of validation models

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences;
package Validation "Collection of validation models"
end Validation;


Validation of model that generates system requests. This example validates

Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.SystemRequests
for generating system requests.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.Validation;
model SystemRequests
  "Validation of model that generates system requests"

  Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Subsequences.SystemRequests sysReq(
    final have_duaSen=false,
    final floHys=0.01,
    final looHys=0.01,
    final damPosHys=0.01) "Block outputs system requests"
  Buildings.Controls.OBC.CDL.Reals.Sources.Sin sine(
    final freqHz=1/7200,
    final offset=296.15)
    "Generate data for setpoint"
  Buildings.Controls.OBC.CDL.Discrete.UnitDelay TZonCooSet(
    final samplePeriod=1800) "Cooling setpoint temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Sin TZon(
    final freqHz=1/7200,
    final amplitude=2,
    final offset=299.15)
    "Zone temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp uCoo(
    final height=-1,
    final duration=2000,
    final offset=1,
    final startTime=1000)
    "Cooling loop signal"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp colDucAirSet(
    final height=0.9,
    final duration=7200,
    final offset=0.1) "Cold-duct airflow rate setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp colDucAirRate(
    final duration=7200,
    final offset=0.1,
    final height=0.3) "Cold duct airflow rate"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp colDamPos(
    final duration=3000,
    final height=-0.7,
    final offset=0.7) "Cold-duct damper position"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse booPul(
    final width=0.1,
    final period=7200)
    "After suppression"
  Buildings.Controls.OBC.CDL.Logical.Not not1 "Logical not"
  Buildings.Controls.OBC.CDL.Reals.Sources.Sin sine1(
    final freqHz=1/7200,
    final offset=293.15)
    "Generate data for setpoint"
  Buildings.Controls.OBC.CDL.Discrete.UnitDelay TZonHeaSet(
    final samplePeriod=1800)
    "Heating setpoint temperature"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse booPul1(
    final width=0.1,
    final period=7200)
    "After suppression"
  Buildings.Controls.OBC.CDL.Logical.Not not2 "Logical not"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp uHea(
    final height=0.9,
    final duration=3600,
    final startTime=3600)
    "Heating loop signal"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp hotDucAirSet(
    final height=0.9,
    final duration=7200,
    final offset=0.1)
    "Hot-duct airflow rate setpoint"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp hotDucAirRate(
    final duration=7200,
    final offset=0.1,
    final height=0.3)
    "Hot duct airflow rate"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp hotDamPos(
    final duration=3600,
    final height=0.7,
    startTime=3600)
    "Hot-duct damper position"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr(final t=0.01)
    "Check if damper is open"
  Buildings.Controls.OBC.CDL.Reals.GreaterThreshold greThr1(final t=0.01)
    "Check if damper is open"

equation
  connect(sine.y, TZonCooSet.u)
  connect(TZonCooSet.y, sysReq.TCooSet)
  connect(TZon.y, sysReq.TZon)
  connect(uCoo.y, sysReq.uCoo)
  connect(booPul.y, not1.u)
  connect(not1.y, sysReq.uAftSupCoo)
  connect(colDucAirSet.y, sysReq.VColDuc_flow_Set)
  connect(colDucAirRate.y, sysReq.VColDucDis_flow)
  connect(colDamPos.y, sysReq.uCooDam)
  connect(sine1.y, TZonHeaSet.u)
  connect(booPul1.y, not2.u)
  connect(not2.y, sysReq.uAftSupHea)
  connect(TZonHeaSet.y, sysReq.THeaSet)
  connect(uHea.y, sysReq.uHea)
  connect(hotDucAirSet.y, sysReq.VHotDuc_flow_Set)
  connect(hotDucAirRate.y, sysReq.VHotDucDis_flow)
  connect(hotDamPos.y, sysReq.uHeaDam)
  connect(colDamPos.y, greThr.u)
  connect(greThr.y, sysReq.u1CooDam)
  connect(hotDamPos.y, greThr1.u)
  connect(greThr1.y, sysReq.u1HeaDam)
end SystemRequests;


Validation of model that controls dual-duct unit with snap-acting control. This example validates

Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Controller.

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Validation;
model Controller
  "Validation of model that controls dual-duct unit with snap-acting control"

  Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing.Controller duaDucCon(
    final venStd=Buildings.Controls.OBC.ASHRAE.G36.Types.VentilationStandard.ASHRAE62_1,
    final have_duaSen=true,
    final VAreBreZon_flow=0.006,
    final VPopBreZon_flow=0.005,
    final VMin_flow=0.5,
    final VCooMax_flow=1.5,
    final VHeaMax_flow=1.2,
    final staPreMul=1,
    final floHys=0.01,
    final looHys=0.01,
    final damPosHys=0.01,
    final VOccMin_flow=0,
    final VAreMin_flow=0)
    "Dual duct unit controller"
  Buildings.Controls.OBC.CDL.Reals.Sources.Sin TZon(
    final freqHz=1/86400,
    final amplitude=4,
    final offset=299.15)
    "Zone temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp disAirTem(
    final height=2,
    final duration=43200,
    final offset=273.15 + 15,
    final startTime=28800)
    "Discharge airflow temperture"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse winSta(
    final width=0.05,
    final period=43200,
    final shift=43200)
    "Window opening status"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant cooSet(
    final k=273.15 + 24)
    "Zone cooling setpoint temperature"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant heaSet(
    final k=273.15 + 20)
    "Zone heating setpoint temperature"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse occ(
    final width=0.75,
    final period=43200,
    final shift=28800) "Occupancy status"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp opeMod(
    final offset=1,
    final height=2,
    final duration=28800,
    final startTime=28800)
    "Operation mode"
  Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt2
    "Convert real to integer"
  Buildings.Controls.OBC.CDL.Reals.Round round2(
    final n=0)
    "Round real number to given digits"
  Buildings.Controls.OBC.CDL.Reals.Sources.Sin CO2(
    final amplitude=400,
    final freqHz=1/28800,
    final offset=600) "CO2 concentration"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp colSupAirTem(
    final height=2,
    final duration=43200,
    final offset=273.15 + 14)
    "Cold-duct supply air temperature from air handling unit"
  Buildings.Controls.OBC.CDL.Reals.Sources.Sin VColDis_flow(
    final offset=1.2,
    final amplitude=0.6,
    final freqHz=1/28800) "Cold duct airflow rate"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp oveFlo(
    final height=2,
    final duration=10000,
    final startTime=35000)
    "Override flow setpoint"
  Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt1
    "Convert real to integer"
  Buildings.Controls.OBC.CDL.Reals.Round round1(
    final n=0)
    "Round real number to given digits"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp oveColDam(
    final height=2,
    final duration=5000,
    startTime=60000) "Override cold-duct damper position"
  Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt3
    "Convert real to integer"
  Buildings.Controls.OBC.CDL.Reals.Round round3(
    final n=0)
    "Round real number to given digits"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse cooSupFanSta(
    final width=0.9,
    final period=73200,
    final shift=18800) "Cooling supply fan status"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp oveHotDam(
    final height=2,
    final duration=5000,
    final startTime=60000) "Override hot-duct damper position"
  Buildings.Controls.OBC.CDL.Conversions.RealToInteger reaToInt4
    "Convert real to integer"
  Buildings.Controls.OBC.CDL.Reals.Round round4(
    final n=0)
    "Round real number to given digits"
  Buildings.Controls.OBC.CDL.Logical.Sources.Pulse heaSupFanSta(
    final width=0.9,
    final period=73200,
    final shift=18800) "Heating supply fan status"
  Buildings.Controls.OBC.CDL.Reals.Sources.Sin VHotDis_flow(
    final offset=1.2,
    final amplitude=0.6,
    final freqHz=1/28800) "Hot duct airflow rate"
  Buildings.Controls.OBC.CDL.Reals.Sources.Ramp hotSupAirTem(
    final height=2,
    final duration=43200,
    final offset=273.15 + 24)
    "Hot-duct supply air temperature from air handling unit"
  Buildings.Controls.OBC.CDL.Reals.Sources.Constant CO2Set(
    final k=894)
    "CO2 concentration setpoint"
  Buildings.Controls.OBC.CDL.Logical.Not not2 "Logical not"
equation
  connect(TZon.y,duaDucCon. TZon)
  connect(cooSet.y, duaDucCon.TCooSet)
  connect(heaSet.y, duaDucCon.THeaSet)
  connect(occ.y, duaDucCon.u1Occ)
  connect(opeMod.y,round2. u)
  connect(round2.y,reaToInt2. u)
  connect(reaToInt2.y,duaDucCon. uOpeMod)
  connect(CO2.y,duaDucCon. ppmCO2)
  connect(oveFlo.y,round1. u)
  connect(round1.y,reaToInt1. u)
  connect(oveColDam.y, round3.u)
  connect(round3.y,reaToInt3. u)
  connect(reaToInt1.y,duaDucCon. oveFloSet)
  connect(reaToInt3.y, duaDucCon.oveCooDamPos)
  connect(oveHotDam.y, round4.u)
  connect(round4.y,reaToInt4. u)
  connect(reaToInt4.y, duaDucCon.oveHeaDamPos)
  connect(disAirTem.y, duaDucCon.TDis)
  connect(colSupAirTem.y, duaDucCon.TColSup)
  connect(VColDis_flow.y, duaDucCon.VColDucDis_flow)
  connect(cooSupFanSta.y, duaDucCon.u1CooAHU)
  connect(hotSupAirTem.y, duaDucCon.THotSup)
  connect(VHotDis_flow.y, duaDucCon.VHotDucDis_flow)
  connect(heaSupFanSta.y, duaDucCon.u1HeaAHU)
  connect(CO2Set.y, duaDucCon.ppmCO2Set)
  connect(winSta.y, not2.u)
  connect(not2.y, duaDucCon.u1Win)
end Controller;


Collection of validation models

within Buildings.Controls.OBC.ASHRAE.G36.TerminalUnits.DualDuctSnapActing;
package Validation "Collection of validation models"
end Validation;