Buildings.Templates.Plants.Controls.HeatPumps.Subsequences

Subsequences for heat pump staging controls

Information

This package contains subsequences that are specific to heat pump controls.

Package Content

Name Description
Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.AssertMinimumRuntime AssertMinimumRuntime Assert that heat pumps are not short cycling
Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EquipmentAvailability EquipmentAvailability Equipment availability for heating and cooling applications
Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EventSequencingMultiple EventSequencingMultiple Staging event sequencing for multiple heat pumps
Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EventSequencingSingle EventSequencingSingle Staging event sequencing for a single heat pump
Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.RoutingPrimaryPumpStatus RoutingPrimaryPumpStatus Primary pump status signal routing
Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.SelectModeState SelectModeState Equipment state and mode selection at a given stage
Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.Validation Validation Collection of validation models

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.AssertMinimumRuntime Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.AssertMinimumRuntime

Assert that heat pumps are not short cycling

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.AssertMinimumRuntime

Information

This block asserts that each heat pump does not short cycle, based on its enable and heating/cooling mode commands.

If use_runTim=true (default), it asserts that the heat pump has been enabled in the same mode for at least dt_min before its enable command turns false or its mode command changes.

If use_runTim=false, it asserts that the heat pump has been commanded off and its mode command hasn't changed for at least dt_min before its enable command turns true again or its mode command changes.

Parameters

TypeNameDefaultDescription
Booleanhave_chiWat Set to true for reversible HP, false for heating-only HP
Booleanuse_runTimtrueSet to true to assert minimum runtime, false for minimum off time
IntegernUni Number of units
Realdt_min10*60Minimum runtime or off-time [s]
Stringmessageif use_runTim then "HP minim...Warning message

Connectors

TypeNameDescription
input BooleanInputu1[nUni]HP on/off command
input BooleanInputu1Hea[nUni]HP heating/cooling mode command: true=heating, false=cooling

Modelica definition

block AssertMinimumRuntime "Assert that heat pumps are not short cycling" parameter Boolean have_chiWat "Set to true for reversible HP, false for heating-only HP"; parameter Boolean use_runTim = true "Set to true to assert minimum runtime, false for minimum off time"; parameter Integer nUni(final min=1) "Number of units"; parameter Real dt_min(final min=0, final unit="s") = 10 * 60 "Minimum runtime or off-time"; parameter String message = if use_runTim then "HP minimum runtime is not met." else "HP minimum off-time is not met." "Warning message"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1[nUni] "HP on/off command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Hea[nUni] if have_chiWat "HP heating/cooling mode command: true=heating, false=cooling"; Buildings.Controls.OBC.CDL.Logical.TrueFalseHold holOn[nUni]( each final trueHoldDuration=if use_runTim then dt_min else 0, each final falseHoldDuration=if use_runTim then 0 else dt_min) "On/off command held for minimum runtime or off-time"; Buildings.Controls.OBC.CDL.Logical.Xor xorOn[nUni] "True if on/off command differs from held command"; Utilities.PlaceholderLogical phHea[nUni]( each final have_inp=have_chiWat, each final u_internal=true) "Placeholder signal"; Buildings.Controls.OBC.CDL.Logical.TrueFalseHold holHea[nUni]( each final trueHoldDuration=dt_min, each final falseHoldDuration=dt_min) "Mode command held for minimum runtime or off-time"; Buildings.Controls.OBC.CDL.Logical.Xor xorHea[nUni] "True if mode command differs from held command"; Buildings.Controls.OBC.CDL.Logical.Nor nor[nUni] "True if minimum runtime or off-time is met"; Buildings.Controls.OBC.CDL.Utilities.Assert assRunTim[nUni]( each message=message) "Assert that minimum runtime or off-time is met"; equation connect(u1, holOn.u); connect(u1, xorOn.u1); connect(holOn.y, xorOn.u2); connect(u1Hea, phHea.u); connect(phHea.y, holHea.u); connect(phHea.y, xorHea.u1); connect(holHea.y, xorHea.u2); connect(xorOn.y, nor.u1); connect(xorHea.y, nor.u2); connect(nor.y, assRunTim.u); end AssertMinimumRuntime;

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EquipmentAvailability Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EquipmentAvailability

Equipment availability for heating and cooling applications

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EquipmentAvailability

Information

If a reversible 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.

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

Implementation details

To avoid concurrent stage transitions between heating and cooling modes, "commanded enabled in a given mode" should be interpreted as "required to run in a given mode", and evaluated before the heat pump is actually enabled. Event sequencing during stage transitions introduces a delay between these two events. During this delay, the heat pump should not be considered available for the opposite mode.

Since the enable commands are computed from the availability signals within the plant controller, the block is structured to avoid creating an algebraic loop at simulation time and at initialization: the heating availability has no direct dependency on any enable command, and the cooling availability directly depends on the heating enable command only. If both single mode commands are received at the same time event, the heating command prevails and the equipment is reported unavailable for cooling.

A mode command is only accepted – and the equipment considered as operating in that mode – if it is received while the equipment is available or already operating in that mode. Commands received before the off time has elapsed are disregarded, so the availability outputs remain false even if an enable command is issued.

At initial time the equipment is available for all modes.

Parameters

TypeNameDefaultDescription
Booleanis_phpfalseSet to true for polyvalent heat pumps
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 BooleanInputu1EnaHeaHeating enable command
output BooleanOutputy1HeaEquipment available for heating
input BooleanInputu1EnaCooCooling enable command
output BooleanOutputy1CooEquipment available for cooling
input BooleanInputu1AvaEquipment available signal
input BooleanInputu1EnaShcSimultaneous heating and cooling enable command
output BooleanOutputy1ShcEquipment available for simultaneous heating and cooling

Modelica definition

block EquipmentAvailability "Equipment availability for heating and cooling applications" parameter Boolean is_php = false "Set to true for polyvalent heat pumps"; 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(min=0, unit="s") = 900 "Off time required before equipment is deemed available again"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1EnaHea if have_heaWat "Heating enable command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Hea if have_heaWat "Equipment available for heating"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1EnaCoo if have_chiWat "Cooling enable command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Coo if have_chiWat "Equipment available for cooling"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Ava "Equipment available signal"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1EnaShc if is_php "Simultaneous heating and cooling enable command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Shc if is_php "Equipment available for simultaneous heating and cooling"; Utilities.PlaceholderLogical phHea( final have_inp=have_heaWat, final u_internal=false) "Placeholder value if signal is not available"; Utilities.PlaceholderLogical phCoo( final have_inp=have_chiWat, final u_internal=false) "Placeholder value if signal is not available"; Utilities.PlaceholderLogical phShc( final have_inp=is_php, final u_internal=false) "Placeholder value if signal is not available"; Buildings.Controls.OBC.CDL.Logical.Not notShc "Return true if equipment not required to run in simultaneous heating and cooling mode"; Buildings.Controls.OBC.CDL.Logical.And reqHea "Return true if equipment required to run in heating mode only"; Buildings.Controls.OBC.CDL.Logical.And reqCoo "Return true if equipment required to run in cooling mode only"; Buildings.Controls.OBC.CDL.Logical.Pre preLatHea "Previous value of heating mode latch"; Buildings.Controls.OBC.CDL.Logical.Pre preLatCoo "Previous value of cooling mode latch"; Buildings.Controls.OBC.CDL.Logical.Or latAll "Return true if equipment has operated in a single mode and off time has not elapsed – Previous values"; Buildings.Controls.OBC.CDL.Logical.Not entHea "Return true if equipment allowed to enter heating mode – Off time elapsed for all modes"; Buildings.Controls.OBC.CDL.Logical.Nor entCoo "Return true if equipment allowed to enter cooling mode – No heating command and off time elapsed for all modes"; Buildings.Controls.OBC.CDL.Logical.Pre preRunHea "Previous value of heating mode operation signal"; Buildings.Controls.OBC.CDL.Logical.Or avaHea "Return true if equipment operating in heating mode or allowed to enter it"; Buildings.Controls.OBC.CDL.Logical.And runHea "Return true if equipment operating in heating mode"; Buildings.Controls.OBC.CDL.Logical.Pre preRunCoo "Previous value of cooling mode operation signal"; Buildings.Controls.OBC.CDL.Logical.Or avaCoo "Return true if equipment operating in cooling mode or allowed to enter it"; Buildings.Controls.OBC.CDL.Logical.And runCoo "Return true if equipment operating in cooling mode"; Buildings.Controls.OBC.CDL.Logical.Nor off "Return true if equipment not operating in any single mode"; Buildings.Controls.OBC.CDL.Logical.Timer tim(final t=dtOff) "Return true if equipment has been off for the required time"; Buildings.Controls.OBC.CDL.Logical.Latch latHea "Return true from the time equipment enters heating mode until off time has elapsed"; Buildings.Controls.OBC.CDL.Logical.Latch latCoo "Return true from the time equipment enters cooling mode until off time has elapsed"; Buildings.Controls.OBC.CDL.Logical.And avaAllHea "Return true if equipment available for heating"; Buildings.Controls.OBC.CDL.Logical.And avaAllCoo "Return true if equipment available for cooling"; equation connect(phHea.u, u1EnaHea); connect(u1EnaCoo, phCoo.u); connect(u1EnaShc, phShc.u); connect(phShc.y, notShc.u); connect(phHea.y, reqHea.u1); connect(notShc.y, reqHea.u2); connect(phCoo.y, reqCoo.u1); connect(notShc.y, reqCoo.u2); connect(preLatHea.y, latAll.u1); connect(preLatCoo.y, latAll.u2); connect(latAll.y, entHea.u); connect(phHea.y, entCoo.u1); connect(latAll.y, entCoo.u2); connect(runHea.y, preRunHea.u); connect(runCoo.y, preRunCoo.u); connect(runHea.y, off.u1); connect(runCoo.y, off.u2); connect(off.y, tim.u); connect(runHea.y, latHea.u); connect(tim.passed, latHea.clr); connect(runCoo.y, latCoo.u); connect(tim.passed, latCoo.clr); connect(latHea.y, preLatHea.u); connect(latCoo.y, preLatCoo.u); connect(avaHea.y, avaAllHea.u1); connect(u1Ava, avaAllHea.u2); connect(u1Ava, avaAllCoo.u2); connect(avaAllHea.y, y1Hea); connect(avaAllCoo.y, y1Coo); connect(u1Ava, y1Shc); connect(avaHea.y, runHea.u1); connect(reqHea.y, runHea.u2); connect(entHea.y, avaHea.u1); connect(preRunHea.y, avaHea.u2); connect(avaCoo.y, runCoo.u1); connect(avaCoo.y, avaAllCoo.u1); connect(reqCoo.y, runCoo.u2); connect(preRunCoo.y, avaCoo.u2); connect(entCoo.y, avaCoo.u1); end EquipmentAvailability;

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EventSequencingMultiple Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EventSequencingMultiple

Staging event sequencing for multiple heat pumps

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EventSequencingMultiple

Information

This block applies the staging event sequencing logic of Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EventSequencingSingle to a group of nHp reversible heat pumps and nPhp polyvalent heat pumps.

To facilitate integration into plant controllers serving both reversible and polyvalent heat pumps, the output connectors for the isolation valve commands and the primary pump enable commands have always the same dimension nHp + nPhp. When a piece of equipment is not present for a given unit, the corresponding array element is set to false.

Parameters

TypeNameDefaultDescription
IntegernHp Number of heat pumps
IntegernPhp Number of polyvalent eat pumps
Booleanhave_heaWat Set to true for plants that provide HW
Booleanhave_chiWat Set to true for plants that provide CHW
Booleanhave_valHpInlIso Set to true for plants with isolation valves at heat pump inlet
Booleanhave_valHpOutIso Set to true for plants with isolation valves at heat pump outlet
Booleanhave_valPhpInlIso Set to true for isolation valves at polyvalent HP inlet
Booleanhave_valPhpOutIso Set to true for isolation valves at polyvalent HP outlet
Booleanhave_pumPriHdr Set to true for plants with headered primary pumps
Booleanhave_pumChiWatPriDedHp Set to true for HP with separate dedicated primary pumps for CHW and HW circuits
IntegernPumHeaWatPri Number of primary HW pumps
IntegernPumChiWatPri Number of primary CHW pumps
RealdtVal90Nominal valve timing [s]
RealdtOff180Heat pump internal shutdown cycle timing [s]

Connectors

TypeNameDescription
input BooleanInputu1ShcPhp[nPhp]SHC enable command – Polyvalent HP
input BooleanInputu1HeaHpPhp[nHp + nPhp]Heating enable command – HP or polyvalent HP (single mode)
input BooleanInputu1PumHeaWatPriDed_actual[nPumHeaWatPri]Dedicated primary HW pump status
input BooleanInputu1PumChiWatPriDed_actual[nPumChiWatPri]Dedicated primary CHW pump status
output BooleanOutputy1ValHeaWatInlIso[nHp + nPhp]Inlet HW isolation valve command
output BooleanOutputy1ValHeaWatOutIso[nHp + nPhp]Outlet HW isolation valve command
output BooleanOutputy1ValChiWatInlIso[nHp + nPhp]Inlet CHW isolation valve command
output BooleanOutputy1ValChiWatOutIso[nHp + nPhp]Outlet CHW isolation valve command
output BooleanOutputy1PumHeaWatPri[nHp + nPhp]Primary HW pump request to pump staging logic
output BooleanOutputy1PumChiWatPri[nHp + nPhp]Primary CHW pump request to pump staging logic
output BooleanOutputy1Hp[nHp]Heat pump enable command
output BooleanOutputy1HeaHp[nHp]Heat pump heating mode command
input BooleanInputu1CooHpPhp[nHp + nPhp]Cooling enable command – HP or polyvalent HP (single mode)
output BooleanOutputy1HeaPhp[nPhp]Polyvalent HP heating on/off command
output BooleanOutputy1CooPhp[nPhp]Polyvalent HP cooling on/off command
input BooleanInputu1PumHeaWatPriHdr_actualLead headered primary HW pump status
input BooleanInputu1PumChiWatPriHdr_actualLead headered primary CHW pump status

Modelica definition

block EventSequencingMultiple "Staging event sequencing for multiple heat pumps" parameter Integer nHp "Number of heat pumps"; parameter Integer nPhp "Number of polyvalent eat pumps"; 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_valHpInlIso(start=false) "Set to true for plants with isolation valves at heat pump inlet"; parameter Boolean have_valHpOutIso(start=false) "Set to true for plants with isolation valves at heat pump outlet"; parameter Boolean have_valPhpInlIso(start=false) "Set to true for isolation valves at polyvalent HP inlet"; parameter Boolean have_valPhpOutIso(start=false) "Set to true for isolation valves at polyvalent HP outlet"; parameter Boolean have_pumPriHdr "Set to true for plants with headered primary pumps"; parameter Boolean have_pumChiWatPriDedHp(start=false) "Set to true for HP with separate dedicated primary pumps for CHW and HW circuits"; parameter Integer nPumHeaWatPri "Number of primary HW pumps"; parameter Integer nPumChiWatPri "Number of primary 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 u1ShcPhp[nPhp] if nPhp > 0 "SHC enable command – Polyvalent HP"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1HeaHpPhp[nHp + nPhp] if have_heaWat "Heating enable command – HP or polyvalent HP (single mode)"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumHeaWatPriDed_actual[nPumHeaWatPri] if have_heaWat and not have_pumPriHdr "Dedicated primary HW pump status"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumChiWatPriDed_actual[nPumChiWatPri] if have_chiWat and not have_pumPriHdr or have_pumChiWatPriDedHp "Dedicated primary CHW pump status"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValHeaWatInlIso[nHp + nPhp] if have_heaWat and (have_valHpInlIso or have_valPhpInlIso) "Inlet HW isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValHeaWatOutIso[nHp + nPhp] if have_heaWat and (have_valHpOutIso or have_valPhpOutIso) "Outlet HW isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValChiWatInlIso[nHp + nPhp] if have_chiWat and (have_valHpInlIso or have_valPhpInlIso) "Inlet CHW isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValChiWatOutIso[nHp + nPhp] if have_chiWat and (have_valHpOutIso or have_valPhpOutIso) "Outlet CHW isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1PumHeaWatPri[nHp + nPhp] "Primary HW pump request to pump staging logic"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1PumChiWatPri[nHp + nPhp] "Primary CHW pump request to pump staging logic"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Hp[nHp] if nHp > 0 "Heat pump enable command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1HeaHp[nHp] if have_heaWat and have_chiWat and nHp > 0 "Heat pump heating mode command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1CooHpPhp[nHp + nPhp] if have_chiWat "Cooling enable command – HP or polyvalent HP (single mode)"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1HeaPhp[nPhp] if nPhp > 0 "Polyvalent HP heating on/off command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1CooPhp[nPhp] if nPhp > 0 "Polyvalent HP cooling on/off command"; EventSequencingSingle seqEveHp[nHp]( each final is_php=false, each final have_heaWat=have_heaWat, each final have_chiWat=have_chiWat, each final have_valInlIso=have_valHpInlIso, each final have_valOutIso=have_valHpOutIso, each final have_pumHeaWatPri=have_heaWat, each final have_pumChiWatPri=have_chiWat and have_pumPriHdr or have_pumChiWatPriDedHp, each final dtVal=dtVal, each final dtOff=dtOff) if nHp > 0 "HP event sequencing"; EventSequencingSingle seqEvePhp[nPhp]( each final is_php=true, each final have_heaWat=have_heaWat, each final have_chiWat=have_chiWat, each final have_valInlIso=have_valPhpInlIso, each final have_valOutIso=have_valPhpOutIso, each final have_pumHeaWatPri=have_heaWat, each final have_pumChiWatPri=have_chiWat, each final dtVal=dtVal, each final dtOff=dtOff) if nPhp > 0 "Polyvalent HP event sequencing"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumHeaWatPriHdr_actual if have_heaWat and have_pumPriHdr "Lead headered primary HW pump status"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumChiWatPriHdr_actual if have_chiWat and have_pumPriHdr "Lead headered primary CHW pump status"; Utilities.ConcatenateParameterLogical u1PumHeaWatPriDed_internal( final nin1=nPumHeaWatPri, final is_app=false, final new=fill(false, max(0, nHp + nPhp - nPumHeaWatPri))) if have_heaWat and not have_pumPriHdr "Prepend with false if nHp+nPhp > nPum"; Utilities.ConcatenateParameterLogical u1PumChiWatPriDed_internal( final nin1=nPumChiWatPri, final is_app=false, final new=fill(false, max(0, nHp + nPhp - nPumChiWatPri))) if have_chiWat and (not have_pumPriHdr and nPhp > 0 or have_pumChiWatPriDedHp) "Prepend with false if nHp+nPhp > nPum"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator u1PumHeaWatPriHdr_internal( final nout=nHp + nPhp) if have_heaWat and have_pumPriHdr "Replicate"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator u1PumChiWatPriHdr_internal( final nout=nHp + nPhp) if have_chiWat and have_pumPriHdr "Replicate"; equation connect(u1HeaHpPhp[1:nHp], seqEveHp.u1Hea); connect(u1CooHpPhp[1:nHp], seqEveHp.u1Coo); connect(seqEveHp.y1, y1Hp); connect(seqEveHp.y1Hea, y1HeaHp); connect(u1HeaHpPhp[nHp + 1:nHp + nPhp], seqEvePhp.u1Hea); connect(u1CooHpPhp[nHp + 1:nHp + nPhp], seqEvePhp.u1Coo); connect(u1ShcPhp, seqEvePhp.u1Shc); connect(u1PumHeaWatPriDed_actual, u1PumHeaWatPriDed_internal.u1); connect(u1PumHeaWatPriDed_internal.y[1:nHp], seqEveHp.u1PumHeaWatPri_actual); connect(u1PumChiWatPriDed_actual, u1PumChiWatPriDed_internal.u1); connect(u1PumChiWatPriDed_internal.y[nHp + 1:nHp + nPhp], seqEvePhp.u1PumChiWatPri_actual); connect(u1PumHeaWatPriDed_internal.y[nHp + 1:nHp + nPhp], seqEvePhp.u1PumHeaWatPri_actual); connect(u1PumChiWatPriDed_internal.y[1:nHp], seqEveHp.u1PumChiWatPri_actual); connect(u1PumHeaWatPriHdr_actual, u1PumHeaWatPriHdr_internal.u); connect(u1PumChiWatPriHdr_actual, u1PumChiWatPriHdr_internal.u); connect(u1PumHeaWatPriHdr_internal.y[1:nHp], seqEveHp.u1PumHeaWatPri_actual); connect(u1PumChiWatPriHdr_internal.y[1:nHp], seqEveHp.u1PumChiWatPri_actual); connect(u1PumHeaWatPriHdr_internal.y[nHp + 1:nHp + nPhp], seqEvePhp.u1PumHeaWatPri_actual); connect(u1PumChiWatPriHdr_internal.y[nHp + 1:nHp + nPhp], seqEvePhp.u1PumChiWatPri_actual); connect(seqEvePhp.y1PumChiWatPri, y1PumChiWatPri[nHp + 1:nHp + nPhp]); connect(seqEvePhp.y1PumHeaWatPri, y1PumHeaWatPri[nHp + 1:nHp + nPhp]); connect(seqEvePhp.y1AndHea, y1HeaPhp); connect(seqEvePhp.y1AndCoo, y1CooPhp); connect(seqEveHp.y1ValHeaWatInlIso, y1ValHeaWatInlIso[1:nHp]); connect(seqEveHp.y1ValHeaWatOutIso, y1ValHeaWatOutIso[1:nHp]); connect(seqEveHp.y1ValChiWatInlIso, y1ValChiWatInlIso[1:nHp]); connect(seqEveHp.y1ValChiWatOutIso, y1ValChiWatOutIso[1:nHp]); connect(seqEvePhp.y1ValHeaWatInlIso, y1ValHeaWatInlIso[nHp + 1:nHp + nPhp]); connect(seqEvePhp.y1ValHeaWatOutIso, y1ValHeaWatOutIso[nHp + 1:nHp + nPhp]); connect(seqEvePhp.y1ValChiWatInlIso, y1ValChiWatInlIso[nHp + 1:nHp + nPhp]); connect(seqEvePhp.y1ValChiWatOutIso, y1ValChiWatOutIso[nHp + 1:nHp + nPhp]); connect(seqEveHp.y1PumChiWatPri, y1PumChiWatPri[1:nHp]); connect(seqEveHp.y1PumHeaWatPri, y1PumHeaWatPri[1:nHp]); end EventSequencingMultiple;

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EventSequencingSingle Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EventSequencingSingle

Staging event sequencing for a single heat pump

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EventSequencingSingle

Information

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

If a heat pump is commanded off:

Polyvalent heat pumps

Note: For polyvalent heat pumps with dedicated primary pumps, no isolation valves are required. This is in contrast with two-pipe reversible heat pumps, which require changeover valves regardless of the primary pump arrangement.

If a polyvalent heat pump is commanded on in either heating-only or cooling-only mode:

If a polyvalent heat pump is commanded on in simultaneous heating and cooling mode, the enable interlocking logic described above applies to both the CHW and HW sides. Once both the CHW and HW isolation valves, if any, are fully open (based on nominal valve timing dtVal) and the associated CHW and HW primary pumps are proven on, the polyvalent heat pump commands for both modes are switched on.

If a polyvalent heat pump switches from heating-only or cooling-only mode to simultaneous heating and cooling mode, the enable interlocking logic described above applies to the side being enabled: the polyvalent heat pump command for the newly enabled mode is switched on once the isolation valves of that side, if any, are fully open (based on nominal valve timing dtVal) and the associated primary pumps are proven on.

If a polyvalent heat pump switches from simultaneous heating and cooling mode to heating-only or cooling-only mode:

If a polyvalent heat pump is commanded off:

Implementation details

The timer tracking the heat pump shutdown cycle is reset if the heat pump is enabled in any mode. This implies that the isolation valves remain open unless the heat pump stays disabled for at least dtOff. The heat pump enable sequence must therefore guarantee that the heat pump remains off for at least dtOff before being enabled in the opposite mode. For polyvalent heat pumps, this requirement is not needed for valve and pump control: when one mode is disabled while the other remains enabled, the isolation valves and pumps of the disabled side are commanded off without delay. However, any minimum off time required by the heat pump between opposite operating modes must still be enforced by the enable sequence.

To facilitate integration into plant controllers serving both reversible and polyvalent heat pumps, the output connectors for the isolation valve commands and the primary pump enable commands are always instantiated, and set to false when the corresponding equipment is not present.

Parameters

TypeNameDefaultDescription
Booleanis_phpfalseSet to true for polyvalent heat pumps
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 has inlet isolation valves
Booleanhave_valOutIso Set to true if the system has 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
RealdtVal90Nominal valve timing [s]
RealdtOff180Heat pump internal shutdown cycle timing [s]

Connectors

TypeNameDescription
input BooleanInputu1ShcEnable command in SHC mode
input BooleanInputu1HeaEnable command from heating mode sequence
input BooleanInputu1PumHeaWatPri_actualPrimary HW pump status – Lead headered or dedicated pump
input BooleanInputu1PumChiWatPri_actualPrimary CHW pump status – Lead headered or dedicated pump
output BooleanOutputy1ValHeaWatInlIsoInlet HW 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 request to pump staging logic
output BooleanOutputy1PumChiWatPriPrimary CHW pump request to pump staging logic
output BooleanOutputy1Enable command
output BooleanOutputy1HeaHeating mode command
input BooleanInputu1CooEnable command from cooling mode sequence
output BooleanOutputy1AndHeaEquipment commanded on in heating mode
output BooleanOutputy1AndCooEquipment commanded on in cooling mode

Modelica definition

block EventSequencingSingle "Staging event sequencing for a single heat pump" parameter Boolean is_php = false "Set to true for polyvalent heat pumps"; 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 has inlet isolation valves"; parameter Boolean have_valOutIso "Set to true if the system has 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 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 u1Shc if is_php "Enable command in SHC mode"; 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 – Lead headered or dedicated pump"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumChiWatPri_actual if have_chiWat and have_pumChiWatPri "Primary CHW pump status – Lead headered or dedicated pump"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValHeaWatInlIso if have_heaWat "Inlet HW isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValHeaWatOutIso if have_heaWat "Outlet HW isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValChiWatInlIso if have_chiWat "Inlet CHW isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ValChiWatOutIso if have_chiWat "Outlet CHW isolation valve command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1PumHeaWatPri "Primary HW pump request to pump staging logic"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1PumChiWatPri "Primary CHW pump request to pump staging logic"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1 "Enable command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1Hea if have_heaWat and have_chiWat "Heating mode command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1Coo if have_chiWat "Enable command from cooling mode sequence"; 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.Timer timValHea(final t=dtVal) if have_heaWat and (have_valInlIso or have_valOutIso) "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 heaOrCooMet "True if either heating or cooling enable clause met"; Buildings.Controls.OBC.CDL.Logical.MultiAnd cooValPum(nin=3) "Return true if cooling AND valve timing elapsed AND lead CHW pumps on"; Utilities.PlaceholderLogical timValHea_internal( final have_inp=have_heaWat and (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 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 if have_heaWat and have_chiWat and not have_pumChiWatPri "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.Routing.BooleanScalarReplicator rou(final nout=1) if have_heaWat and (have_chiWat and have_pumChiWatPri or not have_chiWat) "Signal routing for plants with dedicated primary CHW pumps"; Buildings.Controls.OBC.CDL.Routing.BooleanScalarReplicator rou1(final nout=1) if have_heaWat and have_chiWat and 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"; Buildings.Controls.OBC.CDL.Logical.Timer timValCoo(final t=dtVal) if have_chiWat and (have_valInlIso or have_valOutIso) "Return true when nominal valve timing elapsed"; Utilities.PlaceholderLogical timValCoo_internal( final have_inp=have_chiWat and (have_valInlIso or have_valOutIso), final have_inpPh=true, final u_internal=true) "Replace with placeholder value if input signal is not available"; Buildings.Controls.OBC.CDL.Logical.Not notHea "Return true if disabled from heating sequence"; Buildings.Controls.OBC.CDL.Logical.Not notCoo "Return true if disabled from cooling sequence"; Buildings.Controls.OBC.CDL.Logical.MultiAnd isPhpAndNotCooAndHea(nin=3) "Return true if polyvalent HP disabled for cooling and enabled for heating"; Buildings.Controls.OBC.CDL.Logical.Or timHpOrPhpNotCooAndHea "Return true if HP shutdown cycle ended or polyvalent HP switching to cooling disabled"; Buildings.Controls.OBC.CDL.Logical.MultiAnd isPhpAndNotHeaAndCoo(nin=3) "Return true if polyvalent HP disabled for heating and enabled for cooling"; Buildings.Controls.OBC.CDL.Logical.Or timHpOrPhpNotHeaAndCoo "Return true if HP shutdown cycle ended or polyvalent HP switching to heating disabled"; Utilities.PlaceholderLogical u1ShcHea_internal( final have_inp=is_php, final have_inpPh=false, final u_internal=false) "Replace with placeholder value if input signal is not available"; Buildings.Controls.OBC.CDL.Logical.Or u1HeaOrShcHea "Return true if heating enabled"; Buildings.Controls.OBC.CDL.Logical.Or u1CooOrShcCoo "Return true if cooling enabled"; Buildings.Controls.OBC.CDL.Logical.And heaAndCooMet "True if both heating and cooling enable clauses met"; Buildings.Controls.OBC.CDL.Logical.Pre y1AndHeaPre if have_heaWat and have_chiWat "True if heating previously enabled"; Buildings.Controls.OBC.CDL.Logical.Pre y1AndCooPre if have_heaWat and have_chiWat "True if cooling previously enabled"; Buildings.Controls.OBC.CDL.Logical.Switch swiShcHea "Switch to conditions on both modes being met to transition from off to SHC"; Buildings.Controls.OBC.CDL.Logical.Nor offPre if have_heaWat and have_chiWat "True if heating and cooling previously disabled"; Buildings.Controls.OBC.CDL.Logical.And u1ShcAndOffPre "True if SHC command with heating and cooling previously disabled"; Buildings.Controls.OBC.CDL.Logical.Switch swiShcCoo "Switch to conditions on both modes being met to transition from off to SHC"; Utilities.PlaceholderLogical offPre_internal( final have_inp=have_heaWat and 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.Sources.Constant isPhp(final k=is_php) "Return true for polyvalent HP"; Utilities.PlaceholderLogical y1ValHeaWatInlIso_internal( final have_inp=have_heaWat and have_valInlIso, final have_inpPh=false, final u_internal=false) "Replace with placeholder value if input signal is not available"; Utilities.PlaceholderLogical y1ValHeaWatOutIso_internal( final have_inp=have_heaWat and have_valOutIso, final have_inpPh=false, final u_internal=false) "Replace with placeholder value if input signal is not available"; Utilities.PlaceholderLogical y1ValChiWatInlIso_internal( final have_inp=have_chiWat and have_valInlIso, final have_inpPh=false, final u_internal=false) "Replace with placeholder value if input signal is not available"; Utilities.PlaceholderLogical y1ValChiWatOutIso_internal( final have_inp=have_chiWat and have_valOutIso, final have_inpPh=false, final u_internal=false) "Replace with placeholder value if input signal is not available"; Utilities.PlaceholderLogical y1PumHeaWatPri_internal( final have_inp=have_heaWat and have_pumHeaWatPri, final have_inpPh=false, final u_internal=false) "Replace with placeholder value if input signal is not available"; Utilities.PlaceholderLogical y1PumChiWatPri_internal( final have_inp=have_chiWat and have_pumChiWatPri, final have_inpPh=false, final u_internal=false) "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"; equation connect(timValHea.passed, timValHea_internal.u); connect(u1PumHeaWatPri_internal.y, heaValPum.u[1]); connect(u1PumChiWatPri_internal.y, cooValPum.u[1]); connect(heaOrCooMet.y, y1); connect(u1Hea, u1Hea_internal.u); connect(u1Coo, u1Coo_internal.u); connect(u1HeaOrCoo.y, rou1.u); connect(off.y, timHp.u); connect(rou1.y[1], latPumHeaWatPri.u); connect(rou.y[1], latPumHeaWatPri.u); connect(timValHea_internal.y, heaValPum.u[2]); connect(timValCoo_internal.y, cooValPum.u[2]); connect(timHp.passed, timHpOrPhpNotCooAndHea.u2); connect(timHpOrPhpNotCooAndHea.y, latValChiWatIso.clr); connect(timHpOrPhpNotCooAndHea.y, latPumChiWatPri.clr); connect(isPhpAndNotCooAndHea.y, timHpOrPhpNotCooAndHea.u1); connect(timHp.passed, timHpOrPhpNotHeaAndCoo.u2); connect(isPhpAndNotHeaAndCoo.y, timHpOrPhpNotHeaAndCoo.u1); connect(timHpOrPhpNotHeaAndCoo.y, latValHeaWatIso.clr); connect(timHpOrPhpNotHeaAndCoo.y, latPumHeaWatPri.clr); connect(u1Shc, u1ShcHea_internal.u); connect(u1HeaOrShcHea.y, timValHea.u); connect(u1HeaOrShcHea.y, y1Hea); connect(u1HeaOrShcHea.y, timValHea_internal.uPh); connect(u1HeaOrShcHea.y, notHea.u); connect(u1HeaOrShcHea.y, off.u1); connect(u1HeaOrShcHea.y, rou.u); connect(u1HeaOrShcHea.y, heaValPum.u[3]); connect(u1HeaOrShcHea.y, u1HeaOrCoo.u1); connect(u1CooOrShcCoo.y, timValCoo.u); connect(u1CooOrShcCoo.y, timValCoo_internal.uPh); connect(u1CooOrShcCoo.y, cooValPum.u[3]); connect(u1CooOrShcCoo.y, notCoo.u); connect(u1CooOrShcCoo.y, off.u2); connect(u1CooOrShcCoo.y, u1HeaOrCoo.u2); connect(u1CooOrShcCoo.y, latValChiWatIso.u); connect(u1HeaOrShcHea.y, latValHeaWatIso.u); connect(u1CooOrShcCoo.y, latPumChiWatPri.u); connect(heaValPum.y, heaAndCooMet.u1); connect(cooValPum.y, heaAndCooMet.u2); connect(y1AndHea, y1AndHeaPre.u); connect(y1AndCoo, y1AndCooPre.u); connect(y1AndCooPre.y, offPre.u2); connect(y1AndHeaPre.y, offPre.u1); connect(heaAndCooMet.y, swiShcHea.u1); connect(heaValPum.y, swiShcHea.u3); connect(swiShcHea.y, y1AndHea); connect(cooValPum.y, swiShcCoo.u3); connect(swiShcCoo.y, y1AndCoo); connect(heaAndCooMet.y, swiShcCoo.u1); connect(timValCoo.passed, timValCoo_internal.u); connect(offPre.y, offPre_internal.u); connect(offPre_internal.y, u1ShcAndOffPre.u2); connect(u1ShcAndOffPre.y, swiShcCoo.u2); connect(u1ShcAndOffPre.y, swiShcHea.u2); connect(notCoo.y, isPhpAndNotCooAndHea.u[1]); connect(notHea.y, isPhpAndNotHeaAndCoo.u[1]); connect(isPhp.y, isPhpAndNotHeaAndCoo.u[2]); connect(u1CooOrShcCoo.y, isPhpAndNotHeaAndCoo.u[3]); connect(isPhp.y, isPhpAndNotCooAndHea.u[2]); connect(u1HeaOrShcHea.y, isPhpAndNotCooAndHea.u[3]); connect(latValHeaWatIso.y, y1ValHeaWatInlIso_internal.u); connect(y1ValHeaWatInlIso_internal.y, y1ValHeaWatInlIso); connect(latValHeaWatIso.y, y1ValHeaWatOutIso_internal.u); connect(y1ValHeaWatOutIso_internal.y, y1ValHeaWatOutIso); connect(latValChiWatIso.y, y1ValChiWatInlIso_internal.u); connect(y1ValChiWatInlIso_internal.y, y1ValChiWatInlIso); connect(latValChiWatIso.y, y1ValChiWatOutIso_internal.u); connect(y1ValChiWatOutIso_internal.y, y1ValChiWatOutIso); connect(swiShcHea.y, heaOrCooMet.u1); connect(swiShcCoo.y, heaOrCooMet.u2); connect(u1ShcHea_internal.y, u1ShcAndOffPre.u1); connect(u1Hea_internal.y, u1HeaOrShcHea.u1); connect(u1Coo_internal.y, u1CooOrShcCoo.u1); connect(u1ShcHea_internal.y, u1CooOrShcCoo.u2); connect(u1ShcHea_internal.y, u1HeaOrShcHea.u2); connect(latPumHeaWatPri.y, y1PumHeaWatPri_internal.u); connect(y1PumHeaWatPri_internal.y, y1PumHeaWatPri); connect(latPumChiWatPri.y, y1PumChiWatPri_internal.u); connect(y1PumChiWatPri_internal.y, y1PumChiWatPri); connect(u1PumHeaWatPri_actual, u1PumHeaWatPri_internal.u); connect(u1PumChiWatPri_actual, u1PumChiWatPri_internal.u); end EventSequencingSingle;

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.RoutingPrimaryPumpStatus Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.RoutingPrimaryPumpStatus

Primary pump status signal routing

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.RoutingPrimaryPumpStatus

Information

This block consolidates primary pump status signals into a single output array. Based on the specified pumping configuration, exactly one of the following paths is instantiated:

Parameters

TypeNameDefaultDescription
Booleanhave_pumPriHdr Set to true for headered primary pumps, false for dedicated pumps
IntegernPumPriDedHp Number of dedicated primary pumps serving HP
IntegernPumPriDedPhp Number of dedicated primary pumps serving polyvalent HP
IntegernPumPri Number of primary pumps

Connectors

TypeNameDescription
input BooleanInputu1PumPriDedPhp_actual[nPumPriDedPhp]Primary pump status – Polyvalent HP dedicated pumps
input BooleanInputu1PumPriDedHp_actual[nPumPriDedHp]Primary pump status – HP dedicated pumps
input BooleanInputu1PumPriHdr_actual[nPumPri]Primary pump status – Headered pumps
output BooleanOutputy1[nPumPri]Primary CHW pump status

Modelica definition

block RoutingPrimaryPumpStatus "Primary pump status signal routing" parameter Boolean have_pumPriHdr "Set to true for headered primary pumps, false for dedicated pumps"; parameter Integer nPumPriDedHp "Number of dedicated primary pumps serving HP"; parameter Integer nPumPriDedPhp "Number of dedicated primary pumps serving polyvalent HP"; parameter Integer nPumPri "Number of primary pumps"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumPriDedPhp_actual[nPumPriDedPhp] if nPumPriDedPhp > 0 "Primary pump status – Polyvalent HP dedicated pumps"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumPriDedHp_actual[nPumPriDedHp] if nPumPriDedHp > 0 "Primary pump status – HP dedicated pumps"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1PumPriHdr_actual[nPumPri] if have_pumPriHdr "Primary pump status – Headered pumps"; Utilities.ConcatenateLogical pumPriDedHpPhp( nin1=nPumPriDedHp, nin2=nPumPriDedPhp) if nPumPriDedHp > 0 and nPumPriDedPhp > 0 "Concatenate dedicated pump signals – Plants with HP and polyvalent HP"; Buildings.Controls.OBC.CDL.Routing.BooleanExtractSignal pumPriDedHp( final nin=nPumPriDedHp, final nout=nPumPriDedHp) if nPumPriDedHp > 0 and nPumPriDedPhp == 0 "Direct pass-through – Plants with HP and no polyvalent HP"; Buildings.Controls.OBC.CDL.Routing.BooleanExtractSignal pumPriDedPhp( final nin=nPumPriDedPhp, final nout=nPumPriDedPhp) if nPumPriDedHp == 0 and nPumPriDedPhp > 0 "Direct pass-through – Plants with polyvalent HP and no HP"; Buildings.Controls.OBC.CDL.Routing.BooleanExtractSignal pumPriHdr( final nin=nPumPri, final nout=nPumPri) if have_pumPriHdr "Direct pass-through – Plants with headered primary pumps"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1[nPumPri] "Primary CHW pump status"; equation connect(u1PumPriDedHp_actual, pumPriDedHpPhp.u1); connect(u1PumPriDedPhp_actual, pumPriDedHpPhp.u2); connect(u1PumPriDedHp_actual, pumPriDedHp.u); connect(u1PumPriDedPhp_actual, pumPriDedPhp.u); connect(u1PumPriHdr_actual, pumPriHdr.u); connect(pumPriHdr.y, y1); connect(pumPriDedHp.y, y1); connect(pumPriDedHpPhp.y, y1); connect(pumPriDedPhp.y, y1); end RoutingPrimaryPumpStatus;

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.SelectModeState Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.SelectModeState

Equipment state and mode selection at a given stage

Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.SelectModeState

Information

State alternation

Heat pumps are lead/lag controlled as specified in Buildings.Templates.Plants.Controls.StagingRotation.SortRuntime, in all operating modes.

A single runtime point accumulates per heat pump inclusive of all operating mode runtimes.

Mode alternation

Plants with reversible heat pumps

Alternation between heating and cooling mode is subject to the requirements specified in Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EquipmentAvailability.

Plants with polyvalents heat pumps

Alternation between heating-only and cooling-only mode is subject to the requirements specified in Buildings.Templates.Plants.Controls.HeatPumps.Subsequences.EquipmentAvailability.

Alternation between heating-only or cooling-only mode and SHC mode is subject to the requirements specified in Buildings.Templates.Plants.Controls.PolyvalentHeatPumps.ModeAlternation.

Parameters

TypeNameDefaultDescription
Booleanhave_chiWat Set to true for plants that provide CHW
IntegernStaHp Number of stages in HP staging matrix
RealstaHp[:, :]{min(iSta, nHp)/nHp for _ in...HP staging matrix – Equipment required for each stage [1]
IntegernHp Number of reversible heat pumps
IntegernAltHp_selectnHpNumber of reversible heat pumps subject to lead/lag alternation
IntegernPhp Number of polyvalent units

Connectors

TypeNameDescription
input IntegerInputuIdxSorHp[nAltHp]Indices of heat pumps sorted by increasing runtime
input IntegerInputuStaHeaHeating stage index
input BooleanInputu1AvaHeaHp[nHp]HP heating mode available signal
input RealInputstaTraHea[nCol, nSta]Transpose of heating staging matrix at current cooling stage
output BooleanOutputy1HeaHp[nHp]HP heating mode command
input IntegerInputuIdxSorPhp[nPhp]Indices of polyvalent units sorted by increasing runtime
input BooleanInputu1AvaHeaPhp[nPhp]Polyvalent HP heating-only mode available signal
input BooleanInputu1AvaShcPhp[nPhp]Polyvalent HP SHC mode available signal
output BooleanOutputy1HeaPhp[nPhp]Polyvalent HP heating-only mode command
output BooleanOutputy1ShcPhp[nPhp]Polyvalent HP SHC mode command
output BooleanOutputy1HeaOrShcPhp[nPhp]True if polyvalent HP commanded on in heating-only or SHC mode
output BooleanOutputy1HeaHpPhp[nHp + nPhp]Heating mode command – HP (up to nHp) and polyvalent HP (from nHp+1)
input IntegerInputuStaCooCooling stage index
input RealInputstaTraCoo[nCol, nSta]Transpose of cooling staging matrix at current heating stage
input BooleanInputu1AvaCooPhp[nPhp]Polyvalent HP cooling-only mode available signal
output BooleanOutputy1CooPhp[nPhp]Polyvalent HP cooling-only mode command
output BooleanOutputy1CooHp[nHp]HP cooling mode command
output BooleanOutputy1CooHpPhp[nHp + nPhp]Cooling mode command – HP (up to nHp) and polyvalent HP (from nHp+1)
input BooleanInputu1AvaCooHp[nHp]HP cooling mode available signal

Modelica definition

block SelectModeState "Equipment state and mode selection at a given stage" parameter Boolean have_chiWat "Set to true for plants that provide CHW"; parameter Integer nStaHp(start=nHp) "Number of stages in HP staging matrix"; parameter Real staHp[:, :]( each final unit="1", each final min=0, each final max=1) = {min(iSta, nHp) / nHp for _ in 1:nHp, iSta in 1:nStaHp} "HP staging matrix – Equipment required for each stage"; final parameter Real traStaHp[:, :] = {staHp[i, j] for i in 1:nStaHp, j in 1:nHp} "Transpose of staging matrix"; parameter Integer nHp "Number of reversible heat pumps"; parameter Integer nAltHp_select(start=nHp) = nHp "Number of reversible heat pumps subject to lead/lag alternation"; final parameter Integer nAltHp = if nPhp > 0 then nHp else nAltHp_select "Number of reversible heat pumps subject to lead/lag alternation"; parameter Integer nPhp "Number of polyvalent units"; final parameter Integer nSta = if nPhp > 0 then nHp + nPhp else size(staHp, 1) "Number of stages"; final parameter Integer nCol = if nPhp > 0 then nHp + 2 * nPhp else size(staHp, 2) "Number of columns in staging matrix"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uIdxSorHp[nAltHp] if nHp > 0 "Indices of heat pumps sorted by increasing runtime"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uStaHea "Heating stage index"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1AvaHeaHp[nHp] if nHp > 0 "HP heating mode available signal"; Buildings.Controls.OBC.CDL.Interfaces.RealInput staTraHea[nCol, nSta] if nPhp > 0 "Transpose of heating staging matrix at current cooling stage"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1HeaHp[nHp] if nHp > 0 "HP heating mode command"; Buildings.Controls.OBC.CDL.Routing.RealExtractor reqEquStaHea[nCol]( each final nin=nSta) "Extract equipment required at given heating stage"; Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator intScaRepHea( final nout=nCol) "Replicate signal"; Buildings.Controls.OBC.CDL.Integers.Sources.Constant one(final k=1) "Constant"; Buildings.Controls.OBC.CDL.Integers.Max maxIntHea "Maximum between stage index and 1"; Buildings.Controls.OBC.CDL.Integers.GreaterThreshold greZerHea(final t=0) "Check if stage index is greater than zero"; Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToReaHea( final realTrue=1, final realFalse=0) "Cast to real"; Buildings.Controls.OBC.CDL.Routing.RealScalarReplicator reaScaRepHea( final nout=nCol) "Replicate signal"; Buildings.Controls.OBC.CDL.Reals.Multiply voiStaZerHea[nCol] "Void if stage is equal to zero"; Buildings.Controls.OBC.CDL.Routing.RealExtractSignal reqHpStaHea( nin=nCol, nout=nHp, extract={i for i in 1:nHp}) if nHp > 0 "Extract heat pumps required at given heating stage"; Buildings.Controls.OBC.CDL.Routing.RealExtractSignal reqPhpHeaSta( nin=nCol, nout=nPhp, extract={nHp + i for i in 1:nPhp}) if nPhp > 0 "Extract polyvalent units required in heating-only mode at given heating stage"; Buildings.Controls.OBC.CDL.Routing.RealExtractSignal reqPhpShcSta( nin=nCol, nout=nPhp, extract={nHp + nPhp + i for i in 1:nPhp}) if nPhp > 0 "Extract polyvalent units required in SHC mode at given heating stage"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uIdxSorPhp[nPhp] if nPhp > 0 "Indices of polyvalent units sorted by increasing runtime"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1AvaHeaPhp[nPhp] if nPhp > 0 "Polyvalent HP heating-only mode available signal"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1AvaShcPhp[nPhp] if nPhp > 0 "Polyvalent HP SHC mode available signal"; StagingRotation.BaseClasses.SelectSortedAvailable selSorAvaHeaHp( final nEqu=nHp, final nEquAlt=nAltHp) if nHp > 0 "Select units by priority order and availability – HP"; StagingRotation.BaseClasses.SelectSortedAvailable selSorAvaPhpHea( final nEqu=nPhp, final nEquAlt=nPhp) if nPhp > 0 "Select units by priority order and availability – Polyvalent HP in heating-only mode"; StagingRotation.BaseClasses.SelectSortedAvailable selSorAvaPhpShc( final nEqu=nPhp, final nEquAlt=nPhp) if nPhp > 0 "Select units by priority order and availability – Polyvalent HP in SHC mode"; Buildings.Controls.OBC.CDL.Logical.And isHpAvaAltNeeHea[nHp] if nHp > 0 "True if available and lead/lag alternate needed to meet stage requirement"; Buildings.Controls.OBC.CDL.Logical.And isPhpAvaReqOrAltNeeHea[nPhp] if nPhp > 0 "True if available and required or indexed as lead/lag alternate and needed to meet stage requirement"; Buildings.Controls.OBC.CDL.Logical.And isPhpAvaReqOrAltNeeShc[nPhp] if nPhp > 0 "True if available and required or indexed as lead/lag alternate and needed to meet stage requirement"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1HeaPhp[nPhp] if nPhp > 0 "Polyvalent HP heating-only mode command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1ShcPhp[nPhp] if nPhp > 0 "Polyvalent HP SHC mode command"; StagingRotation.BaseClasses.SelectEquipmentAtStage selEquStaHpHea( final nEqu=nHp) if nHp > 0 "Select equipment at stage"; StagingRotation.BaseClasses.SelectEquipmentAtStage selEquStaPhpHea( final nEqu=nPhp) if nPhp > 0 "Select equipment at stage"; StagingRotation.BaseClasses.SelectEquipmentAtStage selEquStaPhpShc( final nEqu=nPhp) if nPhp > 0 "Select equipment at stage"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1HeaOrShcPhp[nPhp] if nPhp > 0 "True if polyvalent HP commanded on in heating-only or SHC mode"; Buildings.Controls.OBC.CDL.Logical.Or onHeaOrShc[nPhp] if nPhp > 0 "True if polyvalent HP commanded on in either heating-only or SHC mode"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1HeaHpPhp[nHp + nPhp] "Heating mode command – HP (up to nHp) and polyvalent HP (from nHp+1)"; Buildings.Controls.OBC.CDL.Logical.Or enaHeaHp[nHp] if nHp > 0 "Enable HP required without lead/lag alternate and available or lead/lag alternate to meet stage requirement"; Buildings.Controls.OBC.CDL.Reals.Sources.Constant traMatStaHp[nCol, nSta]( final k=traStaHp) if nPhp == 0 "Transpose of HP staging matrix"; Buildings.Controls.OBC.CDL.Interfaces.IntegerInput uStaCoo if have_chiWat "Cooling stage index"; Buildings.Controls.OBC.CDL.Interfaces.RealInput staTraCoo[nCol, nSta] if nPhp > 0 "Transpose of cooling staging matrix at current heating stage"; Buildings.Controls.OBC.CDL.Routing.RealExtractor reqEquStaCoo[nCol]( each final nin=nSta) if have_chiWat "Extract equipment required at given cooling stage"; Buildings.Controls.OBC.CDL.Routing.IntegerScalarReplicator intScaRepCoo( final nout=nCol) if have_chiWat "Replicate signal"; Buildings.Controls.OBC.CDL.Integers.Max maxIntCoo if have_chiWat "Maximum between stage index and 1"; Buildings.Controls.OBC.CDL.Integers.GreaterThreshold greZerCoo(final t=0) if have_chiWat "Check if stage index is greater than zero"; Buildings.Controls.OBC.CDL.Conversions.BooleanToReal booToReaCoo( final realTrue=1, final realFalse=0) if have_chiWat "Cast to real"; Buildings.Controls.OBC.CDL.Routing.RealScalarReplicator reaScaRepCoo( final nout=nCol) if have_chiWat "Replicate signal"; Buildings.Controls.OBC.CDL.Reals.Multiply voiStaZerCoo[nCol] if have_chiWat "Void if stage is equal to zero"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1AvaCooPhp[nPhp] if nPhp > 0 "Polyvalent HP cooling-only mode available signal"; Buildings.Controls.OBC.CDL.Routing.RealExtractSignal reqPhpCooSta( nin=nCol, nout=nPhp, extract={nHp + i for i in 1:nPhp}) if nPhp > 0 "Extract polyvalent units required in cooling-only mode at given cooling stage"; StagingRotation.BaseClasses.SelectEquipmentAtStage selEquStaPhpCoo( final nEqu=nPhp) if nPhp > 0 "Select equipment at stage"; StagingRotation.BaseClasses.SelectSortedAvailable selSorAvaPhpCoo( final nEqu=nPhp, final nEquAlt=nPhp) if nPhp > 0 "Select units by priority order and availability – Polyvalent HP in cooling-only mode"; Buildings.Controls.OBC.CDL.Logical.And isPhpAvaReqOrAltNeeCoo[nPhp] if nPhp > 0 "True if available and required or indexed as lead/lag alternate and needed to meet stage requirement"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1CooPhp[nPhp] if nPhp > 0 "Polyvalent HP cooling-only mode command"; PolyvalentHeatPumps.ModeAlternation selModPhp(final nPhp=nPhp) if nPhp > 0 "Mode selection for polyvalent HP"; Buildings.Controls.OBC.CDL.Routing.RealExtractSignal reqHpStaCoo( nin=nCol, nout=nHp, extract={i for i in 1:nHp}) if nHp > 0 and have_chiWat "Extract heat pumps required at given cooling stage"; StagingRotation.BaseClasses.SelectSortedAvailable selSorAvaCooHp( final nEqu=nHp, final nEquAlt=nAltHp) if nHp > 0 and have_chiWat "Select units by priority order and availability – HP"; Buildings.Controls.OBC.CDL.Logical.And isHpAvaAltNeeCoo[nHp] if nHp > 0 and have_chiWat "True if available and lead/lag alternate needed to meet stage requirement"; StagingRotation.BaseClasses.SelectEquipmentAtStage selEquStaHpCoo( final nEqu=nHp) if nHp > 0 and have_chiWat "Select equipment at stage"; Buildings.Controls.OBC.CDL.Logical.Or enaCooHp[nHp] if nHp > 0 and have_chiWat "Enable HP required without lead/lag alternate and available or lead/lag alternate to meet stage requirement"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1CooHp[nHp] if nHp > 0 and have_chiWat "HP cooling mode command"; Buildings.Controls.OBC.CDL.Interfaces.BooleanOutput y1CooHpPhp[nHp + nPhp] if have_chiWat "Cooling mode command – HP (up to nHp) and polyvalent HP (from nHp+1)"; Buildings.Controls.OBC.CDL.Interfaces.BooleanInput u1AvaCooHp[nHp] if nHp > 0 and have_chiWat "HP cooling mode available signal"; equation connect(intScaRepHea.y, reqEquStaHea.index); connect(one.y, maxIntHea.u1); connect(uStaHea, maxIntHea.u2); connect(maxIntHea.y, intScaRepHea.u); connect(uStaHea, greZerHea.u); connect(greZerHea.y, booToReaHea.u); connect(booToReaHea.y, reaScaRepHea.u); connect(reqEquStaHea.y, voiStaZerHea.u1); connect(reaScaRepHea.y, voiStaZerHea.u2); connect(staTraHea, reqEquStaHea.u); connect(voiStaZerHea.y, reqHpStaHea.u); connect(voiStaZerHea.y, reqPhpHeaSta.u); connect(voiStaZerHea.y, reqPhpShcSta.u); connect(uIdxSorHp, selSorAvaHeaHp.uIdxSor); connect(u1AvaHeaHp, selSorAvaHeaHp.u1Ava); connect(u1AvaHeaPhp, selSorAvaPhpHea.u1Ava); connect(selSorAvaHeaHp.y1, isHpAvaAltNeeHea.u1); connect(selSorAvaPhpHea.y1, isPhpAvaReqOrAltNeeHea.u1); connect(selSorAvaPhpShc.y1, isPhpAvaReqOrAltNeeShc.u1); connect(reqHpStaHea.y, selEquStaHpHea.uEquSta); connect(reqPhpHeaSta.y, selEquStaPhpHea.uEquSta); connect(reqPhpShcSta.y, selEquStaPhpShc.uEquSta); connect(u1AvaHeaHp, selEquStaHpHea.u1Ava); connect(u1AvaHeaPhp, selEquStaPhpHea.u1Ava); connect(selEquStaPhpHea.nTot, selSorAvaPhpHea.n); connect(selEquStaPhpShc.nTot, selSorAvaPhpShc.n); connect(selEquStaPhpShc.y1ReqOrAltAndAva, isPhpAvaReqOrAltNeeShc.u2); connect(selEquStaPhpHea.y1ReqOrAltAndAva, isPhpAvaReqOrAltNeeHea.u2); connect(onHeaOrShc.y, y1HeaOrShcPhp); connect(isPhpAvaReqOrAltNeeHea.y, onHeaOrShc.u1); connect(isPhpAvaReqOrAltNeeShc.y, onHeaOrShc.u2); connect(isPhpAvaReqOrAltNeeHea.y, y1HeaHpPhp[nHp + 1:nHp + nPhp]); connect(isHpAvaAltNeeHea.y, enaHeaHp.u1); connect(traMatStaHp.y, reqEquStaHea.u); connect(enaHeaHp.y, y1HeaHp); connect(selEquStaHpHea.nAlt, selSorAvaHeaHp.n); connect(selEquStaHpHea.y1AltAndAva, isHpAvaAltNeeHea.u2); connect(selEquStaHpHea.y1ReqAndAva, enaHeaHp.u2); connect(enaHeaHp.y, y1HeaHpPhp[1:nHp]); connect(isPhpAvaReqOrAltNeeHea.y, y1HeaPhp); connect(isPhpAvaReqOrAltNeeShc.y, y1ShcPhp); connect(u1AvaShcPhp, selEquStaPhpShc.u1Ava); connect(u1AvaShcPhp, selSorAvaPhpShc.u1Ava); connect(staTraCoo, reqEquStaCoo.u); connect(uStaCoo, maxIntCoo.u2); connect(maxIntCoo.y, intScaRepCoo.u); connect(intScaRepCoo.y, reqEquStaCoo.index); connect(greZerCoo.y, booToReaCoo.u); connect(booToReaCoo.y, reaScaRepCoo.u); connect(uStaCoo, greZerCoo.u); connect(reqEquStaCoo.y, voiStaZerCoo.u1); connect(reaScaRepCoo.y, voiStaZerCoo.u2); connect(voiStaZerCoo.y, reqPhpCooSta.u); connect(reqPhpCooSta.y, selEquStaPhpCoo.uEquSta); connect(u1AvaCooPhp, selEquStaPhpCoo.u1Ava); connect(isPhpAvaReqOrAltNeeCoo.y, y1CooPhp); connect(selEquStaPhpCoo.nTot, selSorAvaPhpCoo.n); connect(u1AvaCooPhp, selSorAvaPhpCoo.u1Ava); connect(selSorAvaPhpCoo.y1, isPhpAvaReqOrAltNeeCoo.u1); connect(uIdxSorPhp, selModPhp.uIdxSor); connect(selModPhp.yIdxSorHea, selSorAvaPhpHea.uIdxSor); connect(selEquStaPhpCoo.nTot, selModPhp.nCoo); connect(y1HeaPhp, selModPhp.u1Hea); connect(y1ShcPhp, selModPhp.u1Shc); connect(y1CooPhp, selModPhp.u1Coo); connect(selModPhp.yIdxSorShc, selSorAvaPhpShc.uIdxSor); connect(selModPhp.yIdxSorCoo, selSorAvaPhpCoo.uIdxSor); connect(uIdxSorHp, selSorAvaCooHp.uIdxSor); connect(selSorAvaCooHp.y1, isHpAvaAltNeeCoo.u1); connect(reqHpStaCoo.y, selEquStaHpCoo.uEquSta); connect(isHpAvaAltNeeCoo.y, enaCooHp.u1); connect(selEquStaHpCoo.nAlt, selSorAvaCooHp.n); connect(selEquStaHpCoo.y1AltAndAva, isHpAvaAltNeeCoo.u2); connect(selEquStaHpCoo.y1ReqAndAva, enaCooHp.u2); connect(selEquStaPhpHea.nTot, selModPhp.nHea); connect(selEquStaPhpShc.nTot, selModPhp.nShc); connect(enaCooHp.y, y1CooHp); connect(u1AvaCooHp, selSorAvaCooHp.u1Ava); connect(traMatStaHp.y, reqEquStaCoo.u); connect(one.y, maxIntCoo.u1); connect(voiStaZerCoo.y, reqHpStaCoo.u); connect(selEquStaPhpCoo.y1ReqOrAltAndAva, isPhpAvaReqOrAltNeeCoo.u2); connect(enaCooHp.y, y1CooHpPhp[1:nHp]); connect(isPhpAvaReqOrAltNeeCoo.y, y1CooHpPhp[nHp + 1:nHp + nPhp]); connect(u1AvaCooHp, selEquStaHpCoo.u1Ava); end SelectModeState;