Buildings.Templates.Plants.Controls.StagingRotation

Package of sequences for equipment staging and rotation

Information

This package contains equipment staging and rotation sequences.

Package Content

Name Description
Buildings.Templates.Plants.Controls.StagingRotation.EquipmentAvailability EquipmentAvailability Equipment availability for heating and cooling applications
Buildings.Templates.Plants.Controls.StagingRotation.EquipmentEnable EquipmentEnable Return array of equipment to be enabled at given stage
Buildings.Templates.Plants.Controls.StagingRotation.EventSequencing EventSequencing Staging event sequencing
Buildings.Templates.Plants.Controls.StagingRotation.SortRuntime SortRuntime Sort equipment by increasing staging runtime
Buildings.Templates.Plants.Controls.StagingRotation.StageAvailability StageAvailability Compute stage availability
Buildings.Templates.Plants.Controls.StagingRotation.StageChangeCommand StageChangeCommand Generate stage change command
Buildings.Templates.Plants.Controls.StagingRotation.StageCompletion StageCompletion Checks successful completion of stage change
Buildings.Templates.Plants.Controls.StagingRotation.Validation Validation Collection of validation models

Buildings.Templates.Plants.Controls.StagingRotation.EquipmentAvailability Buildings.Templates.Plants.Controls.StagingRotation.EquipmentAvailability

Equipment availability for heating and cooling applications

Buildings.Templates.Plants.Controls.StagingRotation.EquipmentAvailability

Information

If a heat pump is commanded enabled in either heating or cooling mode, it is removed from the staging order of the opposite mode until it has been off for dtOff.

Parameters

TypeNameDefaultDescription
Booleanhave_heaWat Set to true for plants that provide HW
Booleanhave_chiWat Set to true for plants that provide CHW
RealdtOff900Off time required before equipment is deemed available again [s]

Connectors

TypeNameDescription
input BooleanInputu1Equipment enable command
output BooleanOutputy1HeaEquipment available for heating
input BooleanInputu1HeaEquipment operating mode command
output BooleanOutputy1CooEquipment available for cooling
input BooleanInputu1AvaEquipment available signal

Modelica definition

block EquipmentAvailability "Equipment availability for heating and cooling applications" parameter Boolean have_heaWat "Set to true for plants that provide HW"; parameter Boolean have_chiWat "Set to true for plants that provide CHW"; parameter Real dtOff( final min=0, final unit="s")=900 "Off time required before equipment is deemed available again"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1 "Equipment enable command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Hea if have_heaWat "Equipment available for heating"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Hea if have_heaWat and have_chiWat "Equipment operating mode command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Coo if have_chiWat "Equipment available for cooling"; Buildings.Controls.OBC.CDL.Logical.And onAndHea "Return true if equipment on and in heating mode"; Buildings.Controls.OBC.CDL.Logical.And onAndCoo "Return true if equipment on and in cooling mode"; Buildings.Controls.OBC.CDL.Logical.Not coo "Return true if equipment in cooling mode"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Ava "Equipment available signal"; Utilities.PlaceholderLogical phHea(final have_inp=have_heaWat and have_chiWat, final u_internal=have_heaWat or not have_chiWat) "Placeholder value if signal is not available"; Buildings.Controls.OBC.CDL.Logical.Not off "Return true if equipment is off"; inner Modelica.StateGraph.StateGraphRoot stateGraphRoot; Modelica.StateGraph.StepWithSignal onHea( nOut=2, nIn=1); Modelica.StateGraph.InitialStepWithSignal avaMod( nOut=3, nIn=2) "Initial state – Equipment available for all modes"; Modelica.StateGraph.TransitionWithSignal trnToOff "Transition to off state"; Modelica.StateGraph.StepWithSignal onCoo( nOut=2, nIn=1); Modelica.StateGraph.TransitionWithSignal trnToCoo "Transition to cooling mode"; Modelica.StateGraph.TransitionWithSignal trnToHea "Transition to heating mode"; Modelica.StateGraph.TransitionWithSignal trnToOff1 "Transition to off state"; Buildings.Controls.OBC.CDL.Logical.Or avaAllHea "Return true if equipment available for all modes or in heating mode"; Buildings.Controls.OBC.CDL.Logical.Or avaAllCoo "Return true if equipment available for all modes or in cooling mode"; Modelica.StateGraph.Step offSta( nOut=1, nIn=2) "Off state"; Modelica.StateGraph.Transition trnToAvaTim( enableTimer=true, final waitTime=dtOff) "Transition back to available state after off time elapsed"; Modelica.StateGraph.Step unaSta( nOut=1, nIn=3) "Unavailable state"; Modelica.StateGraph.TransitionWithSignal trnToUna "Transition to unavailable state"; Buildings.Controls.OBC.CDL.Logical.Not una "Return true if equipment is unavailable"; Modelica.StateGraph.TransitionWithSignal trnToAva "Transition back to available state"; Modelica.StateGraph.TransitionWithSignal trnToUna2 "Transition to unavailable state"; Modelica.StateGraph.TransitionWithSignal trnToUna3 "Transition to unavailable state"; equation connect(coo.y, onAndCoo.u2); connect(u1, onAndHea.u1); connect(u1, onAndCoo.u1); connect(u1Hea, phHea.u); connect(phHea.y, onAndHea.u2); connect(phHea.y, coo.u); connect(u1, off.u); connect(avaMod.outPort[1], trnToCoo.inPort); connect(onAndCoo.y, trnToCoo.condition); connect(onHea.outPort[1], trnToOff.inPort); connect(off.y, trnToOff.condition); connect(onCoo.outPort[1], trnToOff1.inPort); connect(trnToCoo.outPort, onCoo.inPort[1]); connect(onAndHea.y, trnToHea.condition); connect(avaMod.outPort[2], trnToHea.inPort); connect(avaMod.active, avaAllHea.u1); connect(onHea.active, avaAllHea.u2); connect(avaAllHea.y, y1Hea); connect(avaAllCoo.y, y1Coo); connect(off.y, trnToOff1.condition); connect(trnToHea.outPort, onHea.inPort[1]); connect(offSta.outPort[1], trnToAvaTim.inPort); connect(trnToOff.outPort, offSta.inPort[1]); connect(trnToOff1.outPort, offSta.inPort[2]); connect(trnToAvaTim.outPort, avaMod.inPort[1]); connect(u1Ava, una.u); connect(avaMod.outPort[3], trnToUna.inPort); connect(una.y, trnToUna.condition); connect(trnToUna.outPort, unaSta.inPort[1]); connect(unaSta.outPort[1], trnToAva.inPort); connect(u1Ava, trnToAva.condition); connect(trnToAva.outPort, avaMod.inPort[2]); connect(avaMod.active, avaAllCoo.u1); connect(onCoo.active, avaAllCoo.u2); connect(onHea.outPort[2], trnToUna2.inPort); connect(trnToUna2.outPort, unaSta.inPort[2]); connect(una.y, trnToUna2.condition); connect(onCoo.outPort[2], trnToUna3.inPort); connect(trnToUna3.outPort, unaSta.inPort[3]); connect(una.y, trnToUna3.condition); end EquipmentAvailability;

Buildings.Templates.Plants.Controls.StagingRotation.EquipmentEnable Buildings.Templates.Plants.Controls.StagingRotation.EquipmentEnable

Return array of equipment to be enabled at given stage

Buildings.Templates.Plants.Controls.StagingRotation.EquipmentEnable

Information

This block generates the equipment enable commands based on the active stage index uSta, the equipment available signal u1Ava and the indices of lead/lag alternate equipment, sorted by increasing staging runtime.

A staging matrix staEqu is required as a parameter.

The state of the enable signals is only updated at stage change, or if the number of previously enabled equipment that is available is strictly less than the number of equipment required to run. This avoids hot swapping equipment, e.g., an equipment would not be started and another stopped during operation just to fulfill the priority order. However, when a lead/lag alternate equipment becomes unavailable and another lead/lag alternate equipment can be enabled to meet the number of required equipment, then the state of the enable signals is updated.

Parameters

TypeNameDefaultDescription
RealstaEqu[:, :] Staging matrix – Equipment required for each stage [1]

Connectors

TypeNameDescription
input IntegerInputuIdxAltSor[nEquAlt]Indices of lead/lag alternate equipment sorted by increasing runtime
input IntegerInputuStaStage index
input BooleanInputu1Ava[nEqu]Equipment available signal
output BooleanOutputy1[nEqu]Equipment enable command

Modelica definition

block EquipmentEnable "Return array of equipment to be enabled at given stage" parameter Real staEqu[:,:]( each unit="1", each min=0, each max=1) "Staging matrix – Equipment required for each stage"; final parameter Integer nEquAlt=max({sum({(if staEqu[i, j] > 0 and staEqu[i, j] < 1 then 1 else 0) for j in 1:nEqu}) for i in 1:nSta}) "Number of lead/lag alternate equipment"; final parameter Integer nSta=size(staEqu, 1) "Number of stages"; final parameter Integer nEqu=size(staEqu, 2) "Number of equipment"; final parameter Real traStaEqu[nEqu, nSta]={{staEqu[i, j] for i in 1:nSta} for j in 1:nEqu} "Transpose of staging matrix"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uIdxAltSor[nEquAlt] "Indices of lead/lag alternate equipment sorted by increasing runtime"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uSta "Stage index"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Ava[nEqu] "Equipment available signal"; Buildings.Controls.OBC.CDL.Reals.Sources.Constant traMatStaEqu[nEqu, nSta]( final k=traStaEqu) "Transpose of staging matrix"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1[nEqu] "Equipment enable command"; Buildings.Controls.OBC.CDL.Routing.RealExtractor reqEquSta[nEqu]( each final nin=nSta) "Extract equipment required at given stage"; Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator intScaRep( final nout=nEqu) "Replicate signal"; Buildings.Controls.OBC.CDL.Reals.MultiSum nEquStaRea( nin=nEqu) "Return the number of equipment required"; Buildings.Controls.OBC.CDL.Reals.GreaterThreshold isReq[nEqu]( each final t=0.99) "Return true if equipment required without lead/lag alternate"; Buildings.Controls.OBC.CDL.Logical.And isReqAva[nEqu] "Return true if equipment required without lead/lag alternate and available"; Buildings.Controls.OBC.CDL.Reals.GreaterThreshold isReqPosAlt[nEqu]( each final t=1E-4) "Return true if equipment required (with or without lead/lag alternate)"; Buildings.Controls.OBC.CDL.Reals.LessThreshold isNotReqNoAlt[nEqu]( each final t=0.9999) "Return true if equipment not required or required with lead/lag alternate"; Buildings.Controls.OBC.CDL.Logical.MultiAnd isReqAltAva[nEqu]( each final nin=3) "Return true if lead/lag alternate equipment required and available"; Buildings.Controls.OBC.CDL.Logical.Or ena[nEqu] "Enable equipment required without lead/lag alternate and available or lead/lag alternate equipment to meet stage requirement"; Buildings.Controls.OBC.CDL.Conversions.RealToInteger nEquSta "Number of equipment required"; Buildings.Controls.OBC.CDL.Integers.Subtract nAltReq "Number of lead/lag alternate equipment to run to meet stage requirement"; Buildings.Controls.OBC.CDL.Logical.And isReqAltAvaNee[nEqu] "Return true if equipment required with lead/lag alternate and available and needed to meet stage requirement"; Buildings.Controls.OBC.CDL.Integers.Change cha "Detect stage index change"; Buildings.Controls.OBC.CDL.Logical.Pre y1Pre[nEqu] "Left limit of signal in discrete time"; Buildings.Controls.OBC.CDL.Logical.Switch logSwi[nEqu] "Switch to newly computed value at stage change"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator booScaRep( final nout=nEqu) "Replicate signal"; Utilities.CountTrue nReq( nin=nEqu) "Count the number of required equipment without lead/lag alternate, not necessarily available"; Utilities.CountTrue nEnaAvaPre( nin=nEqu) "Count the number of previously enabled equipment that are available"; Buildings.Controls.OBC.CDL.Integers.Less intLes "Compare to required number of equipment"; Buildings.Controls.OBC.CDL.Logical.Or swiEna "Evaluate condition to switch to newly computed enable signal"; Buildings.Controls.OBC.CDL.Logical.And isEnaPreAva[nEqu] "Return true if equipment previously enabled and available"; Utilities.TrueArrayConditional truArrCon( final nout=nEqu, final nin=nEquAlt) "Generate array of size nEqu with nAltReq true elements at uIdxAltSor indices "; Buildings.Controls.OBC.CDL.Integers.Sources.Constant one( final k=1) "Constant"; Buildings.Controls.OBC.CDL.Integers.Max maxInt "Maximum between stage index and 1"; Buildings.Controls.OBC.CDL.Integers.GreaterThreshold greZer( final t=0) "Check if stage index is greater than zero"; Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToRea( final realTrue=1, final realFalse=0) "Cast to real"; Buildings.Controls.OBC.CDL.Routing.RealScalarReplicator reaScaRep( final nout=nEqu) "Replicate signal"; Buildings.Controls.OBC.CDL.Reals.Multiply voiStaZer[nEqu] "Void if stage is equal to zero"; equation connect(intScaRep.y, reqEquSta.index); connect(traMatStaEqu.y, reqEquSta.u); connect(isReq.y, isReqAva.u1); connect(u1Ava, isReqAva.u2); connect(isReqPosAlt.y, isReqAltAva.u[1]); connect(isNotReqNoAlt.y, isReqAltAva.u[2]); connect(u1Ava, isReqAltAva.u[3]); connect(isReqAva.y, ena.u2); connect(nEquStaRea.y, nEquSta.u); connect(nEquSta.y, nAltReq.u1); connect(isReqAltAva.y, isReqAltAvaNee.u2); connect(isReqAltAvaNee.y, ena.u1); connect(uSta, cha.u); connect(logSwi.y, y1); connect(y1, y1Pre.u); connect(y1Pre.y, logSwi.u3); connect(ena.y, logSwi.u1); connect(booScaRep.y, logSwi.u2); connect(nReq.y, nAltReq.u2); connect(isReq.y, nReq.u1); connect(nEnaAvaPre.y, intLes.u1); connect(nEquSta.y, intLes.u2); connect(swiEna.y, booScaRep.u); connect(cha.y, swiEna.u1); connect(intLes.y, swiEna.u2); connect(isEnaPreAva.y, nEnaAvaPre.u1); connect(y1Pre.y, isEnaPreAva.u2); connect(u1Ava, isEnaPreAva.u1); connect(nAltReq.y, truArrCon.u); connect(uIdxAltSor, truArrCon.uIdx); connect(truArrCon.y1, isReqAltAvaNee.u1); connect(one.y, maxInt.u1); connect(uSta, maxInt.u2); connect(maxInt.y, intScaRep.u); connect(uSta, greZer.u); connect(greZer.y, booToRea.u); connect(booToRea.y, reaScaRep.u); connect(reqEquSta.y, voiStaZer.u1); connect(reaScaRep.y, voiStaZer.u2); connect(voiStaZer.y, nEquStaRea.u); connect(voiStaZer.y, isReqPosAlt.u); connect(voiStaZer.y, isNotReqNoAlt.u); connect(voiStaZer.y, isReq.u); end EquipmentEnable;

Buildings.Templates.Plants.Controls.StagingRotation.EventSequencing Buildings.Templates.Plants.Controls.StagingRotation.EventSequencing

Staging event sequencing

Buildings.Templates.Plants.Controls.StagingRotation.EventSequencing

Information

If a heat pump is commanded on in a desired heating or cooling mode:

If a heat pump is commanded off:

Parameters

TypeNameDefaultDescription
Booleanhave_heaWat Set to true for plants that provide HW
Booleanhave_chiWat Set to true for plants that provide CHW
Booleanhave_valInlIso Set to true if the system as inlet isolation valves
Booleanhave_valOutIso Set to true if the system as outlet isolation valves
Booleanhave_pumHeaWatPri Set to true for plants with primary HW pumps
Booleanhave_pumChiWatPri Set to true for plants with separate primary CHW pumps
Booleanhave_pumHeaWatSec Set to true for plants with secondary HW pumps
Booleanhave_pumChiWatSec Set to true for plants with secondary CHW pumps
RealdtVal90Nominal valve timing [s]
RealdtOff180Heat pump internal shutdown cycle timing [s]

Connectors

TypeNameDescription
input BooleanInputu1HeaEnable command from heating mode sequence
input BooleanInputu1PumHeaWatPri_actualPrimary HW pump status (dedicated or lead headered pump)
input BooleanInputu1PumChiWatPri_actualPrimary CHW pump status – Dedicated or lead headered pump
input BooleanInputu1PumHeaWatSec_actualLead headered secondary HW pump status
input BooleanInputu1PumChiWatSec_actualLead headered secondary CHW pump status
output BooleanOutputy1ValHeaWatInlIsoInlet HW inlet isolation valve command
output BooleanOutputy1ValHeaWatOutIsoOutlet HW isolation valve command
output BooleanOutputy1ValChiWatInlIsoInlet CHW isolation valve command
output BooleanOutputy1ValChiWatOutIsoOutlet CHW isolation valve command
output BooleanOutputy1PumHeaWatPriPrimary HW pump start command – Dedicated or lead headered pump
output BooleanOutputy1PumChiWatPriPrimary CHW pump start command – Dedicated or lead headered pump
output BooleanOutputy1Equipment enable command
output BooleanOutputy1HeaHeating/cooling mode command: true=heating, false=cooling
input BooleanInputu1CooEnable command from cooling mode sequence
output BooleanOutputy1AndHeaEquipment commanded on in heating mode
output BooleanOutputy1AndCooEquipment commanded on in cooling mode

Modelica definition

block EventSequencing "Staging event sequencing" parameter Boolean have_heaWat "Set to true for plants that provide HW"; parameter Boolean have_chiWat "Set to true for plants that provide CHW"; parameter Boolean have_valInlIso "Set to true if the system as inlet isolation valves"; parameter Boolean have_valOutIso "Set to true if the system as outlet isolation valves"; parameter Boolean have_pumHeaWatPri(start=false) "Set to true for plants with primary HW pumps"; parameter Boolean have_pumChiWatPri( start=false) "Set to true for plants with separate primary CHW pumps"; parameter Boolean have_pumHeaWatSec(start=false) "Set to true for plants with secondary HW pumps"; parameter Boolean have_pumChiWatSec(start=false) "Set to true for plants with secondary CHW pumps"; parameter Real dtVal( min=0, start=90, unit="s")=90 "Nominal valve timing"; parameter Real dtOff( min=0, unit="s") = 180 "Heat pump internal shutdown cycle timing"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Hea if have_heaWat "Enable command from heating mode sequence"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumHeaWatPri_actual if have_heaWat and have_pumHeaWatPri "Primary HW pump status (dedicated or lead headered pump)"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumChiWatPri_actual if have_chiWat and have_pumChiWatPri "Primary CHW pump status – Dedicated or lead headered pump"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumHeaWatSec_actual if have_heaWat and have_pumHeaWatSec "Lead headered secondary HW pump status"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumChiWatSec_actual if have_chiWat and have_pumChiWatSec "Lead headered secondary CHW pump status"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValHeaWatInlIso if have_heaWat and have_valInlIso "Inlet HW inlet isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValHeaWatOutIso if have_heaWat and have_valOutIso "Outlet HW isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValChiWatInlIso if have_chiWat and have_valInlIso "Inlet CHW isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValChiWatOutIso if have_chiWat and have_valOutIso "Outlet CHW isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1PumHeaWatPri if have_heaWat and have_pumHeaWatPri "Primary HW pump start command – Dedicated or lead headered pump"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1PumChiWatPri if have_chiWat and have_pumChiWatPri "Primary CHW pump start command – Dedicated or lead headered pump"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1 "Equipment enable command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Hea if have_heaWat and have_chiWat "Heating/cooling mode command: true=heating, false=cooling"; Buildings.Controls.OBC.CDL.Logical.Timer timVal( final t=dtVal) "Return true when nominal valve timing elapsed"; Buildings.Controls.OBC.CDL.Logical.MultiAnd heaValPum( nin=3) "Return true if heating AND valve timing elapsed AND lead HW pumps on"; Buildings.Controls.OBC.CDL.Logical.Or ena "Return true if enabled"; Buildings.Controls.OBC.CDL.Logical.MultiAnd cooValPum( nin=4) "Return true if cooling AND valve timing elapsed AND lead CHW pumps on"; Utilities.PlaceholderLogical u1PumChiWatSec_internal( final have_inp=have_chiWat and have_pumChiWatSec, final have_inpPh=false, final u_internal=true) "Replace with placeholder value if input signal is not available"; Utilities.PlaceholderLogical timVal_internal( final have_inp=have_valInlIso or have_valOutIso, final have_inpPh=true, final u_internal=true) "Replace with placeholder value if input signal is not available"; Utilities.PlaceholderLogical u1PumHeaWatSec_internal( final have_inp=have_heaWat and have_pumHeaWatSec, final have_inpPh=false, final u_internal=true) "Replace with placeholder value if input signal is not available"; Utilities.PlaceholderLogical u1PumChiWatPri_internal( final have_inp=have_chiWat and have_pumChiWatPri, final have_inpPh=false, final u_internal=true) "Replace with placeholder value if input signal is not available"; Utilities.PlaceholderLogical u1PumHeaWatPri_internal( final have_inp=have_heaWat and have_pumHeaWatPri, final have_inpPh=false, final u_internal=true) "Replace with placeholder value if input signal is not available"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Coo if have_chiWat "Enable command from cooling mode sequence"; Utilities.PlaceholderLogical u1Coo_internal( final have_inp=have_chiWat, final have_inpPh=false, final u_internal=false) "Replace with placeholder value if input signal is not available"; Buildings.Controls.OBC.CDL.Logical.Or u1HeaOrCoo "Return true if enabled from heating or cooling mode sequence"; Utilities.PlaceholderLogical u1Hea_internal( final have_inp=have_heaWat, final have_inpPh=false, final u_internal=false) "Replace with placeholder value if input signal is not available"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1AndHea if have_heaWat "Equipment commanded on in heating mode"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1AndCoo if have_chiWat "Equipment commanded on in cooling mode"; Buildings.Controls.OBC.CDL.Logical.And enaAndHea "Return true if enabled in heating mode"; Buildings.Controls.OBC.CDL.Logical.And enaAndCoo "Return true if enabled in cooling mode"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator rou( final nout=1) if have_pumChiWatPri "Signal routing for plants with dedicated primary CHW pumps"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator rou1( final nout=1) if not have_pumChiWatPri "Signal routing for plants without dedicated primary CHW pumps"; Buildings.Controls.OBC.CDL.Logical.Nor off "Return true if disabled from heating and cooling mode sequence"; Buildings.Controls.OBC.CDL.Logical.Timer timHp(final t=dtOff) "Return true when heat pump internal shutdown cycle times out"; Buildings.Controls.OBC.CDL.Logical.Latch latValHeaWatIso if have_heaWat "Keep valve open until heat pump internal shutdown cycle times out"; Buildings.Controls.OBC.CDL.Logical.Latch latValChiWatIso if have_chiWat "Keep valve open until heat pump internal shutdown cycle times out"; Buildings.Controls.OBC.CDL.Logical.Latch latPumHeaWatPri if have_heaWat "Keep pump running until heat pump internal shutdown cycle times out"; Buildings.Controls.OBC.CDL.Logical.Latch latPumChiWatPri if have_chiWat and have_pumChiWatPri "Keep pump running until heat pump internal shutdown cycle times out"; equation connect(heaValPum.y, ena.u1); connect(cooValPum.y, ena.u2); connect(timVal.passed, timVal_internal.u); connect(timVal_internal.y, heaValPum.u[1]); connect(u1PumChiWatSec_actual, u1PumChiWatSec_internal.u); connect(u1PumHeaWatPri_actual, u1PumHeaWatPri_internal.u); connect(u1PumChiWatPri_actual, u1PumChiWatPri_internal.u); connect(u1PumHeaWatSec_actual, u1PumHeaWatSec_internal.u); connect(u1PumHeaWatPri_internal.y, heaValPum.u[2]); connect(u1PumHeaWatSec_internal.y, heaValPum.u[3]); connect(timVal_internal.y, cooValPum.u[1]); connect(u1PumChiWatPri_internal.y, cooValPum.u[2]); connect(u1PumChiWatSec_internal.y, cooValPum.u[3]); connect(ena.y, y1); connect(u1Hea, u1Hea_internal.u); connect(u1Coo_internal.y, u1HeaOrCoo.u2); connect(u1Hea_internal.y, u1HeaOrCoo.u1); connect(u1HeaOrCoo.y, timVal.u); connect(u1HeaOrCoo.y, timVal_internal.uPh); connect(u1Coo, u1Coo_internal.u); connect(u1Coo_internal.y, cooValPum.u[4]); connect(u1Hea_internal.y, y1Hea); connect(ena.y, enaAndHea.u1); connect(u1Hea_internal.y, enaAndHea.u2); connect(enaAndHea.y, y1AndHea); connect(ena.y, enaAndCoo.u1); connect(u1Coo_internal.y, enaAndCoo.u2); connect(enaAndCoo.y, y1AndCoo); connect(u1Hea_internal.y, rou.u); connect(u1HeaOrCoo.y, rou1.u); connect(u1Hea_internal.y, off.u1); connect(u1Coo_internal.y, off.u2); connect(off.y, timHp.u); connect(timHp.passed, latValHeaWatIso.clr); connect(latValHeaWatIso.y, y1ValHeaWatInlIso); connect(u1Hea_internal.y, latValHeaWatIso.u); connect(latValChiWatIso.y, y1ValChiWatInlIso); connect(timHp.passed, latValChiWatIso.clr); connect(latValHeaWatIso.y, y1ValHeaWatOutIso); connect(latValChiWatIso.y, y1ValChiWatOutIso); connect(rou1.y[1], latPumHeaWatPri.u); connect(rou.y[1], latPumHeaWatPri.u); connect(timHp.passed, latPumHeaWatPri.clr); connect(latPumHeaWatPri.y, y1PumHeaWatPri); connect(latPumChiWatPri.y, y1PumChiWatPri); connect(timHp.passed, latPumChiWatPri.clr); connect(u1Coo_internal.y, latPumChiWatPri.u); connect(u1Coo_internal.y, latValChiWatIso.u); end EventSequencing;

Buildings.Templates.Plants.Controls.StagingRotation.SortRuntime Buildings.Templates.Plants.Controls.StagingRotation.SortRuntime

Sort equipment by increasing staging runtime

Buildings.Templates.Plants.Controls.StagingRotation.SortRuntime

Information

This block implements the rotation logic for identical parallel staged equipment that are lead/lag alternated.

Two runtime points are defined for each equipment. The Lifetime Runtime is the cumulative runtime of the equipment since equipment start-up. This point is not readily resettable by operators. Lifetime Runtime should be stored to a software point on the control system server so the recorded value is not lost due to controller reset, loss of power, programming file update, etc. The Staging Runtime is an operator resettable runtime point that stores cumulative runtime since the last operator reset.

In the case of available equipment, when more than one equipment is off or more than one is on, the equipment with the most operating hours as determined by Staging Runtime is made the last stage equipment and the one with the least number of hours is made the lead stage equipment.

In the case of unavailable equipment, the equipment that alarmed most recently is sent to the last position. The equipment in alarm automatically moves up in the staging order only if another equipment goes into alarm.

Staging runtime initialization

When the controller is initialized, the choice of the first equipment to run is random since all runtimes are equal to zero. So, before this first equipment reports status, all equipment will be considered off and only this first equipment will increase runtime and be queued in the staging order. At next stage change, another equipment will then be staged on instead, resulting in the first running equipment being "hot swapped". To avoid this behavior, the vector parameter runTim_start is used to initialize the staging runtime, which will be fixed at this parameter value until it becomes higher. The parameter runTim_start should be set to a vector of strictly increasing values, where the minimum value is greater than the time needed for the equipment to report status.

Details

The sorting logic is implemented using the following method.

This is effectively the same as sorting the units within the three following subsets: units that are on and available, units that are off and available, units that are unavailable. In particular, the order index of a given unit remains unchanged if it is the only element of a given subset. Note that the staging runtime and the time elapsed since an equipment became unavailable are both computed from Boolean signals (u1Run and u1Ava). These are discrete-time, piecewise constant variables, which is why the caveat in the documentation of Buildings.Templates.Plants.Controls.Utilities.SortWithIndices for purely continuous time-varying variables does not apply here. Therefore, no sampling is performed before sorting the equipment runtimes.

To facilitate integration into the plant controller, the input vectors cover the full set of equipment, including equipment that may not be lead/lag alternate. The output vectors cover only the subset of lead/lag alternate equipment, and the vector of sorted equipment provides indices with respect to the input vectors (full set of equipment).

Parameters

TypeNameDefaultDescription
IntegeridxEquAlt[:]{i for i in 1:nin}Indices of lead/lag alternate equipment
RealrunTim_start[nEquAlt]{60 + i for i in 1:nEquAlt}Staging runtime initial values

Connectors

TypeNameDescription
input BooleanInputu1Run[nin]Boolean signal used to assess equipment runtime
input BooleanInputu1Ava[nin]Equipment available signal
output RealOutputyRunTimLif[nEquAlt]Lifetime runtime
output RealOutputyRunTimSta[nEquAlt]Staging runtime
output IntegerOutputyIdx[nEquAlt]Indices of equipment sorted by increasing staging runtime

Modelica definition

block SortRuntime "Sort equipment by increasing staging runtime" parameter Integer nin=0 "Size of input array"; parameter Integer idxEquAlt[:]={i for i in 1:nin} "Indices of lead/lag alternate equipment"; final parameter Integer nEquAlt=size(idxEquAlt, 1) "Number of lead/lag alternate equipment"; parameter Real runTim_start[nEquAlt]={60 + i for i in 1:nEquAlt} "Staging runtime initial values"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Run[nin] "Boolean signal used to assess equipment runtime"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Ava[nin] "Equipment available signal"; Buildings.Controls.OBC.CDL.Interfaces.RealOutput yRunTimLif[nEquAlt] "Lifetime runtime"; Buildings.Controls.OBC.CDL.Interfaces.RealOutput yRunTimSta[nEquAlt] "Staging runtime"; Buildings.Controls.OBC.CDL.Interfaces.IntegerOutput yIdx[nEquAlt]( start={i for i in 1:nEquAlt}) "Indices of equipment sorted by increasing staging runtime"; Buildings.Controls.OBC.CDL.Logical.TimerAccumulating timRun[nEquAlt] "Compute staging runtime"; Buildings.Controls.OBC.CDL.Logical.Not off[nEquAlt] "Return true if equipment off"; Buildings.Controls.OBC.CDL.Logical.Sources.Constant u1Res[nEquAlt]( each k=false) "Signal for staging runtime reset"; Utilities.SortWithIndices sor( final ascending=true, nin=nEquAlt) "Sort equipment by increasing weighted runtime"; Buildings.Controls.OBC.CDL.Conversions.BooleanToReal weiOffAva[nEquAlt]( each final realTrue=1E10, each final realFalse=1) "Weight to be applied to runtime of equipment off and available"; Buildings.Controls.OBC.CDL.Reals.Multiply appWeiOffAva[nEquAlt] "Apply weights to runtime of equipment off and available"; Buildings.Controls.OBC.CDL.Reals.Multiply voiRunUna[nEquAlt] "Void runtime of unavailable equipment"; Buildings.Controls.OBC.CDL.Logical.And offAva[nEquAlt] "Return true if equipment off and available"; Buildings.Controls.OBC.CDL.Logical.Not una[nEquAlt] "Return true if equipment unavailable"; Buildings.Controls.OBC.CDL.Conversions.BooleanToReal zerUna[nEquAlt]( each final realTrue=0, each final realFalse=1) "Assign zero to unavailable equipment"; Buildings.Controls.OBC.CDL.Logical.Timer timUna[nEquAlt] "Compute time elapsed since equipment is unavailable"; Buildings.Controls.OBC.CDL.Reals.AddParameter addWei[nEquAlt]( each final p=1E20) "Add weight"; Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter opp[nEquAlt]( each final k=- 1) "Take opposite value"; Buildings.Controls.OBC.CDL.Reals.Add addWeiUna[nEquAlt] "Add weight to unavailable equipment"; Buildings.Controls.OBC.CDL.Reals.Multiply voiWeiAva[nEquAlt] "Void weight of available equipment"; Buildings.Controls.OBC.CDL.Conversions.BooleanToReal zerAva[nEquAlt]( each final realTrue=0, each final realFalse=1) "Assign zero to available equipment"; Buildings.Controls.OBC.CDL.Logical.TimerAccumulating timRunLif[nEquAlt] "Compute lifetime runtime"; Buildings.Controls.OBC.CDL.Logical.Sources.Constant fal[nEquAlt]( each final k=false) "Constant"; Buildings.Controls.OBC.CDL.Routing.BooleanExtractSignal u1RunEquAlt( final nin=nin, final nout=nEquAlt, final extract=idxEquAlt) "Extract signal for lead/lag alternate equipment only"; Buildings.Controls.OBC.CDL.Routing.BooleanExtractSignal u1AvaEquAlt( final nin=nin, final nout=nEquAlt, final extract=idxEquAlt) "Extract signal for lead/lag alternate equipment only"; Buildings.Controls.OBC.CDL.Routing.IntegerExtractor resIdxInp[nEquAlt]( each final nin=nEquAlt) "Restore indices consistent with input vectors"; Buildings.Controls.OBC.CDL.Integers.Sources.Constant idxEquAltMat[nEquAlt, nEquAlt]( final k={idxEquAlt for i in 1:nEquAlt}) "Indices of lead/lag alternate equipment repeated nEquAlt times"; Buildings.Controls.OBC.CDL.Reals.Sources.Constant runTimSta[nEquAlt]( final k=runTim_start) "Staging runtime initial values"; Buildings.Controls.OBC.CDL.Reals.Max iniRunTim[nEquAlt] "Fix runtime until it exceeds the initial value"; equation connect(u1Res.y, timRun.reset); connect(weiOffAva.y, appWeiOffAva.u1); connect(off.y, offAva.u1); connect(offAva.y, weiOffAva.u); connect(appWeiOffAva.y, voiRunUna.u1); connect(zerUna.y, voiRunUna.u2); connect(una.y, timUna.u); connect(una.y, zerUna.u); connect(timUna.y, opp.u); connect(opp.y, addWei.u); connect(addWeiUna.y, sor.u); connect(voiRunUna.y, addWeiUna.u1); connect(voiWeiAva.y, addWeiUna.u2); connect(addWei.y, voiWeiAva.u1); connect(zerAva.y, voiWeiAva.u2); connect(timRunLif.y, yRunTimLif); connect(fal.y, timRunLif.reset); connect(u1Run, u1RunEquAlt.u); connect(u1RunEquAlt.y, off.u); connect(u1RunEquAlt.y, timRunLif.u); connect(u1RunEquAlt.y, timRun.u); connect(u1Ava, u1AvaEquAlt.u); connect(u1AvaEquAlt.y, una.u); connect(u1AvaEquAlt.y, zerAva.u); connect(u1AvaEquAlt.y, offAva.u2); connect(idxEquAltMat.y, resIdxInp.u); connect(sor.yIdx, resIdxInp.index); connect(resIdxInp.y, yIdx); connect(runTimSta.y, iniRunTim.u1); connect(timRun.y, iniRunTim.u2); connect(iniRunTim.y, appWeiOffAva.u2); connect(timRun.y, yRunTimSta); end SortRuntime;

Buildings.Templates.Plants.Controls.StagingRotation.StageAvailability Buildings.Templates.Plants.Controls.StagingRotation.StageAvailability

Compute stage availability

Buildings.Templates.Plants.Controls.StagingRotation.StageAvailability

Information

A stage is deemed available if both the following are true:

Otherwise, the stage is deemed unavailable.

Parameters

TypeNameDefaultDescription
RealstaEqu[:, :] Staging matrix – Equipment required for each stage [1]

Connectors

TypeNameDescription
input BooleanInputu1Ava[nEqu]Equipment available signal
output BooleanOutputy1[nSta]Stage available signal

Modelica definition

block StageAvailability "Compute stage availability" parameter Real staEqu[:,:]( each unit="1", each min=0, each max=1) "Staging matrix – Equipment required for each stage"; final parameter Integer nSta=size(staEqu, 1) "Number of stages"; final parameter Integer nEqu=size(staEqu, 2) "Number of equipment"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Ava[nEqu] "Equipment available signal"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1[nSta] "Stage available signal"; Buildings.Controls.OBC.CDL.Reals.Sources.Constant matStaEqu[nSta, nEqu]( final k=staEqu) "Staging matrix"; Buildings.Controls.OBC.CDL.Reals.GreaterThreshold isReq[nSta, nEqu]( each final t=0.99) "Return true if equipment required without lead/lag alternate"; Buildings.Controls.OBC.CDL.Reals.GreaterThreshold isReqPosAlt[nSta, nEqu]( each final t=0) "Return true if equipment required (with or without lead/lag alternate)"; Buildings.Controls.OBC.CDL.Reals.LessThreshold isNotReqNoAlt[nSta, nEqu]( each final t=1) "Return true if equipment not required or required with lead/lag alternate"; Buildings.Controls.OBC.CDL.Routing.BooleanVectorReplicator booVecRep( final nin=nEqu, final nout=nSta) "Replicate equipment available signal"; Buildings.Controls.OBC.CDL.Logical.And isReqAva[nSta, nEqu] "Return true if equipment required without lead/lag alternate and available"; Buildings.Controls.OBC.CDL.Logical.And isReqAltAva[nSta, nEqu] "Return true if equipment required (with or without lead/lag alternate) and available"; Buildings.Controls.OBC.CDL.Logical.Or isReqAvaOrNotReq[nSta, nEqu] "Return true if equipment required without lead/lag alternate and available, or if not required"; Buildings.Controls.OBC.CDL.Logical.MultiAnd all[nSta]( each final nin=nEqu) "Return true if previous block condition valid for all elements"; Buildings.Controls.OBC.CDL.Logical.And isAva[nSta] "Return true if stage available"; Buildings.Controls.OBC.CDL.Reals.MultiSum nEquSta[nSta]( each final nin=nEqu) "Return the number of equipment required at each stage"; Buildings.Controls.OBC.CDL.Conversions.BooleanToInteger booToInt[nSta, nEqu] "Convert to integer"; Buildings.Controls.OBC.CDL.Integers.GreaterEqual isReqAltAvaGreReq[nSta] "Return true if number of required available equipment higher than number of required equipment"; Buildings.Controls.OBC.CDL.Integers.MultiSum nReqAltAva[nSta]( each final nin=nEqu) "Number of equipment required (with or without lead/lag alternate) and available"; Buildings.Controls.OBC.CDL.Conversions.RealToInteger nEquStaInt[nSta] "Integer cast of number of equipment required at each stage"; equation connect(matStaEqu.y, isReq.u); connect(matStaEqu.y, isReqPosAlt.u); connect(matStaEqu.y, isNotReqNoAlt.u); connect(isReq.y, isReqAva.u1); connect(booVecRep.y, isReqAva.u2); connect(booVecRep.y, isReqAltAva.u2); connect(isReqAva.y, isReqAvaOrNotReq.u2); connect(isNotReqNoAlt.y, isReqAvaOrNotReq.u1); connect(isAva.y, y1); connect(isReqAvaOrNotReq.y, all.u); connect(matStaEqu.y, nEquSta.u); connect(nReqAltAva.y, isReqAltAvaGreReq.u1); connect(nReqAltAva.u, booToInt.y); connect(nEquSta.y, nEquStaInt.u); connect(nEquStaInt.y, isReqAltAvaGreReq.u2); connect(u1Ava, booVecRep.u); connect(isReqPosAlt.y, isReqAltAva.u1); connect(isReqAltAva.y, booToInt.u); connect(isReqAltAvaGreReq.y, isAva.u1); connect(all.y, isAva.u2); end StageAvailability;

Buildings.Templates.Plants.Controls.StagingRotation.StageChangeCommand Buildings.Templates.Plants.Controls.StagingRotation.StageChangeCommand

Generate stage change command

Buildings.Templates.Plants.Controls.StagingRotation.StageChangeCommand

Information

The plant equipment is staged in part based on required capacity, Qrequired, relative to nominal capacity of a given stage, Qstage. This ratio is the operative part load ratio, OPLR.

OPLR = Qrequired / Qstage

If both primary and secondary hot water temperatures and flow rates are available, the sensors in the primary loop are used for calculating Qrequired. If a heat recovery chiller is piped into the secondary return, the sensors in the primary loop are used. (These conditions are implemented in Buildings.Templates.Plants.Controls.HeatPumps.AirToWater.)

The required capacity is calculated based on return temperature, active supply temperature setpoint and measured flow through the associated circuit flow meter.

The required capacity used in logic is a rolling average over a period of dtMea of instantaneous values sampled at minimum once every 30 s.

When a stage up or stage down transition is initiated, Qrequired is held fixed at its last value until the longer of the successful completion of the stage change and the duration dtRun.

The nominal capacity of a given stage, Qstage, is calculated as the sum of the design capacities of all units enabled in a given stage.

Staging is executed per the conditions below subject to the following requirements.

A stage up command is triggered if any of the following is true:

A stage down command is triggered if the following is true:

Details

A staging matrix staEqu is required as a parameter. See the documentation of Buildings.Templates.Plants.Controls.StagingRotation.EquipmentEnable for the associated definition and requirements.

An "if" condition is used to generate the stage up and down command as opposed to a "when" condition. This means that the command remains true as long as the condition is verified. This is necessary, for example, if no higher stage is available when a stage up command is triggered. Using a "when" condition – which is only valid at the point in time at which the condition becomes true – would prevent the plant from staging when a higher stage becomes available again. To avoid multiple consecutive stage changes, the block that receives the stage up and down command and computes the stage index must enforce a minimum stage runtime of dtRun.

Parameters

TypeNameDefaultDescription
Booleanhave_inpPlrStafalseSet to true to use an input signal for SPLR, false to use a parameter
RealplrSta0.9Staging part load ratio [1]
RealstaEqu[:, :] Staging matrix – Equipment required for each stage [1]
RealcapEqu[nEqu] Design capacity of each equipment [W]
RealdtRun900Runtime with exceeded staging part load ratio before staging event is triggered [s]
RealdtMea300Duration used to compute the moving average of required capacity [s]
Realcp_default Default specific heat capacity used to compute required capacity [J/(kg.K)]
Realrho_default Default density used to compute required capacity [kg/m3]

Connectors

TypeNameDescription
input BooleanInputu1AvaSta[nSta]Stage available signal
input BooleanInputu1StaProStaging process in progress
input RealInputuPlrStaInput signal for staging part load ratio [1]
input IntegerInputuStaStage index
input RealInputTRetReturn temperature used to compute required capacity [K]
input RealInputTSupSetActive supply temperature setpoint used to compute required capacity [K]
input RealInputV_flowVolume flow rate used to compute required capacity [m3/s]
output BooleanOutputy1UpStage up command
output BooleanOutputy1DowStage down command

Modelica definition

block StageChangeCommand "Generate stage change command" parameter Boolean have_inpPlrSta=false "Set to true to use an input signal for SPLR, false to use a parameter"; parameter Real plrSta( final max=1, final min=0, start=0.9, final unit="1")=0.9 "Staging part load ratio"; final parameter Real traStaEqu[nEqu, nSta]={{staEqu[i, j] for i in 1:nSta} for j in 1:nEqu} "Transpose of staging matrix"; parameter Real staEqu[:,:]( each final max=1, each final min=0, each final unit="1") "Staging matrix – Equipment required for each stage"; final parameter Integer nSta=size(staEqu, 1) "Number of stages"; final parameter Integer nEqu=size(staEqu, 2) "Number of equipment"; parameter Real capEqu[nEqu]( each final min=0, each final unit="W") "Design capacity of each equipment"; parameter Real dtRun( final min=0, final unit="s")=900 "Runtime with exceeded staging part load ratio before staging event is triggered"; parameter Real dtMea( final min=0, final unit="s")=300 "Duration used to compute the moving average of required capacity"; parameter Real cp_default( final min=0, final unit="J/(kg.K)") "Default specific heat capacity used to compute required capacity"; parameter Real rho_default( final min=0, final unit="kg/m3") "Default density used to compute required capacity"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1AvaSta[nSta] "Stage available signal"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1StaPro "Staging process in progress"; Buildings.Controls.OBC.CDL.Interfaces.RealInput uPlrSta( final unit="1", final min=0, final max=1) if have_inpPlrSta "Input signal for staging part load ratio"; // We allow the stage index to be zero, e.g., when the plant is disabled. Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uSta( final min=0, final max=nSta) "Stage index"; Buildings.Controls.OBC.CDL.Interfaces.RealInput TRet( final unit="K", displayUnit="degC") "Return temperature used to compute required capacity"; Buildings.Controls.OBC.CDL.Interfaces.RealInput TSupSet( final unit="K", displayUnit="degC") "Active supply temperature setpoint used to compute required capacity"; Buildings.Controls.OBC.CDL.Interfaces.RealInput V_flow( final unit="m3/s") "Volume flow rate used to compute required capacity"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Up "Stage up command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Dow "Stage down command"; Buildings.Controls.OBC.CDL.Reals.Subtract delT( y(final unit="K")) "Compute ∆T"; Buildings.Controls.OBC.CDL.Reals.Abs absDelT( y(final unit="K")) "Compute absolute value of ∆T"; Buildings.Controls.OBC.CDL.Reals.MultiplyByParameter capFlo( y(final unit="W/K"), final k=rho_default * cp_default) "Compute capacity flow rate"; Buildings.Controls.OBC.CDL.Reals.Multiply capReq "Compute required capacity"; Buildings.Controls.OBC.CDL.Reals.Sources.Constant traMatStaEqu[nEqu, nSta]( final k=traStaEqu) "Transpose of staging matrix"; Buildings.Controls.OBC.CDL.Routing.RealExtractor reqEquSta[nEqu]( each final nin=nSta) "Extract equipment required at given stage"; Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator intScaRep( final nout=nEqu) "Replicate signal"; Buildings.Controls.OBC.CDL.Reals.Multiply capEquSta[nEqu] "Capacity of each equipment required at given stage"; Buildings.Controls.OBC.CDL.Reals.Sources.Constant capEquPar[nEqu]( final k=capEqu) "Capacity of each equipment"; Buildings.Controls.OBC.CDL.Reals.MultiSum capSta( nin=nEqu) "Compute nominal capacity of active stage"; Buildings.Controls.OBC.CDL.Reals.Greater gre(h=1E-4*min(capEqu)) "Compare OPLR to SPLR (hysteresis is to avoid chattering with some simulators)"; Buildings.Controls.OBC.CDL.Reals.MovingAverage movAve( delta=dtMea) "Compute moving average"; Buildings.Templates.Plants.Controls.Utilities.TimerWithReset timUp( final t=dtRun) "Timer"; Buildings.Controls.OBC.CDL.Reals.Less les(h=1E-4*min(capEqu)) "Compare OPLR to SPLR (hysteresis is to avoid chattering with some simulators)"; Buildings.Templates.Plants.Controls.Utilities.TimerWithReset timDow( final t=dtRun) "Timer"; Utilities.HoldReal hol(final dtHol=dtRun) "Hold value of required capacity at stage change"; Buildings.Controls.OBC.CDL.Integers.Max maxInt "Maximum between stage index and 1"; Buildings.Controls.OBC.CDL.Integers.Sources.Constant one( final k=1) "Constant"; Buildings.Controls.OBC.CDL.Integers.Sources.Constant idxSta[nSta]( final k={i for i in 1:nSta}) "Stage index"; Buildings.Controls.OBC.CDL.Integers.Less idxStaLesAct[nSta] "Return true if stage index lower than active stage index"; Buildings.Controls.OBC.CDL.Logical.And idxStaLesActAva[nSta]; Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator intScaRep1( final nout=nSta) "Replicate signal"; Utilities.LastTrueIndex idxLasTru( nin=nSta) "Index of next available lower stage"; Buildings.Controls.OBC.CDL.Integers.Max maxInt1 "Maximum between stage index and 1"; Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator intScaRep2( final nout=nEqu) "Replicate signal"; Buildings.Controls.OBC.CDL.Routing.RealExtractor reqEquStaLow[nEqu]( each final nin=nSta) "Extract equipment required at next available lower stage"; Buildings.Controls.OBC.CDL.Reals.Multiply capEquStaLow[nEqu] "Capacity of each equipment required at next available lower stage"; Buildings.Controls.OBC.CDL.Reals.MultiSum capStaLow( nin=nEqu) "Compute nominal capacity of next available lower stage"; Buildings.Controls.OBC.CDL.Integers.Min minInt "Minimum between stage index and 1"; Buildings.Controls.OBC.CDL.Conversions.IntegerToReal intToRea "Convert to real value"; Buildings.Controls.OBC.CDL.Reals.Multiply setZer "Set nominal capacity to zero if no lower available stage"; Buildings.Controls.OBC.CDL.Reals.Multiply splTimCapSta "SPLR times capacity of active stage"; Buildings.Controls.OBC.CDL.Reals.Multiply splTimCapStaLow "SPLR times capacity of next available lower stage"; Utilities.PlaceholderReal parPlrSta( final have_inp=have_inpPlrSta, final have_inpPh=false, final u_internal=plrSta) "Parameter value for SPLR"; Buildings.Controls.OBC.CDL.Logical.FallingEdge endStaPro "True when staging process terminates"; equation connect(delT.y, absDelT.u); connect(absDelT.y, capReq.u1); connect(capFlo.y, capReq.u2); connect(intScaRep.y, reqEquSta.index); connect(traMatStaEqu.y, reqEquSta.u); connect(reqEquSta.y, capEquSta.u1); connect(capEquPar.y, capEquSta.u2); connect(capEquSta.y, capSta.u); connect(movAve.y, hol.u); connect(intScaRep.u, maxInt.y); connect(idxSta.y, idxStaLesAct.u1); connect(uSta, intScaRep1.u); connect(intScaRep1.y, idxStaLesAct.u2); connect(idxStaLesAct.y, idxStaLesActAva.u1); connect(u1AvaSta, idxStaLesActAva.u2); connect(idxStaLesActAva.y, idxLasTru.u1); connect(idxLasTru.y, maxInt1.u2); connect(one.y, maxInt1.u1); connect(maxInt1.y, intScaRep2.u); connect(uSta, maxInt.u1); connect(one.y, maxInt.u2); connect(intScaRep2.y, reqEquStaLow.index); connect(traMatStaEqu.y, reqEquStaLow.u); connect(reqEquStaLow.y, capEquStaLow.u2); connect(capEquPar.y, capEquStaLow.u1); connect(capEquStaLow.y, capStaLow.u); connect(idxLasTru.y, minInt.u2); connect(one.y, minInt.u1); connect(minInt.y, intToRea.u); connect(capStaLow.y, setZer.u1); connect(intToRea.y, setZer.u2); connect(hol.y, gre.u1); connect(splTimCapSta.y, gre.u2); connect(capSta.y, splTimCapSta.u2); connect(setZer.y, splTimCapStaLow.u2); connect(splTimCapStaLow.y, les.u2); connect(hol.y, les.u1); connect(gre.y, timUp.u); connect(les.y, timDow.u); connect(uPlrSta, parPlrSta.u); connect(parPlrSta.y, splTimCapSta.u1); connect(parPlrSta.y, splTimCapStaLow.u1); connect(u1StaPro, hol.u1); connect(u1StaPro, endStaPro.u); connect(endStaPro.y, timUp.reset); connect(endStaPro.y, timDow.reset); connect(timUp.passed, y1Up); connect(timDow.passed, y1Dow); connect(TSupSet, delT.u1); connect(TRet, delT.u2); connect(V_flow, capFlo.u); connect(capReq.y, movAve.u); end StageChangeCommand;

Buildings.Templates.Plants.Controls.StagingRotation.StageCompletion Buildings.Templates.Plants.Controls.StagingRotation.StageCompletion

Checks successful completion of stage change

Buildings.Templates.Plants.Controls.StagingRotation.StageCompletion

Information

Block that detects a stage change and evaluates whether the stage transition is completed.

The completion of a stage change is considered successful when both of the following conditions have been verified.

The output signal y1End is true exactly at the time when the successful completion of the stage change is confirmed. The output signal y1 is true during the entire time in which the stage change is in progress.

Connectors

TypeNameDescription
input BooleanInputu1[nin]Equipment enable command
input BooleanInputu1_actual[nin]Equipment status
output BooleanOutputy1EndSuccessful completion of stage change
output BooleanOutputy1Stage change in progress
input IntegerInputuStaStage index

Modelica definition

block StageCompletion "Checks successful completion of stage change" parameter Integer nin=0 "Size of input array"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1[nin] "Equipment enable command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1_actual[nin] "Equipment status"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1End "Successful completion of stage change"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1 "Stage change in progress"; Buildings.Controls.OBC.CDL.Logical.And enaAndOn[nin] "True if equipment enabled and on status returned"; Buildings.Controls.OBC.CDL.Logical.Nor disAndOff[nin] "True if equipment disabled and off status returned"; Buildings.Controls.OBC.CDL.Logical.MultiAnd allTru( nin=nin) "True if all inputs true"; Buildings.Controls.OBC.CDL.Logical.Or onOrOff[nin] "True if on or off condition met"; Buildings.Controls.OBC.CDL.Logical.FallingEdge endStaPro "True when staging process terminates"; Buildings.Controls.OBC.CDL.Logical.Latch lckChaSta "Lock stage change signal until conditions on equipment command and status met"; Buildings.Controls.OBC.CDL.Logical.Change cha[nin] "True if enable signal changes"; Buildings.Controls.OBC.CDL.Logical.Latch lckAnyCha "Lock equipment command change signal until next stage change"; Buildings.Controls.OBC.CDL.Logical.MultiOr anyCha( nin=nin) "True if any enable signal changes"; Buildings.Controls.OBC.CDL.Logical.And chaAndMat "True if enable command changed and equipment status matches command"; Buildings.Controls.OBC.CDL.Logical.TrueFalseHold holAnyCha( trueHoldDuration=1, falseHoldDuration=0) "Hold signal to guard against concomitant stage change and command change"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uSta "Stage index"; Buildings.Controls.OBC.CDL.Integers.Change chaSta "Return true when stage change is initiated"; equation connect(u1_actual, disAndOff.u2); connect(u1_actual, enaAndOn.u2); connect(endStaPro.y, y1End); connect(lckChaSta.y, y1); connect(cha.y, anyCha.u); connect(u1, cha.u); connect(u1, enaAndOn.u1); connect(lckAnyCha.y, chaAndMat.u1); connect(chaAndMat.y, lckChaSta.clr); connect(lckChaSta.y, endStaPro.u); connect(u1, disAndOff.u1); connect(enaAndOn.y, onOrOff.u1); connect(disAndOff.y, onOrOff.u2); connect(onOrOff.y, allTru.u); connect(allTru.y, chaAndMat.u2); connect(anyCha.y, holAnyCha.u); connect(holAnyCha.y, lckAnyCha.u); connect(chaSta.y, lckChaSta.u); connect(chaSta.y, lckAnyCha.clr); connect(uSta, chaSta.u); end StageCompletion;