Buildings.Examples.HydronicHeating

Hydronic heating system with storage, two rooms and thermostatic radiator valves

Information

This package demonstrates the implementation of a hydronic heating system.

Extends from Modelica.Icons.ExamplesPackage (Icon for packages containing runnable examples).

Package Content

Name Description
Buildings.Examples.HydronicHeating.TwoRoomsWithStorage TwoRoomsWithStorage Model of a hydronic heating system with energy storage

Buildings.Examples.HydronicHeating.TwoRoomsWithStorage Buildings.Examples.HydronicHeating.TwoRoomsWithStorage

Model of a hydronic heating system with energy storage

Buildings.Examples.HydronicHeating.TwoRoomsWithStorage

Information

This example demonstrates the implementation of a building that has the following properties:

There are two rooms. (For simplicity, we only modeled two rooms, but more could be added.) Each room is modeled using a dynamic model for the heat transfer through the opaque constructions. The room roo1 has a south- and west-facing window, the room roo2 has a south- and east-facing window. The rooms are modeled as if they were in an intermediate floor, with the same temperature above and below the room. The rooms share one common wall. The north facing wall is modeled as a partition wall, i.e., both surfaces have the same boundary conditions. Weather data are used from Chicago.

There is a hydronic heating system with a boiler, a storage tank and a radiator with a thermostatic valve in each room. The supply water temperature setpoint is reset based on the outside temperature. A three-way-valve mixes the water from the tank with the water from the radiator return. The pump has a variable frequency drive that controls the pump head.

A finite state machine is used to switch the boiler and its pump on and off. The boiler and pump are switched on when the temperature at the top of the tank is less then 1 Kelvin above the setpoint temperature for the supply water temperature of the radiator loop. The boiler and pump are switched off when the temperature at the bottom of the tank reaches 55 degree Celsius. The state transition of the finite state machine is such that first the pump of the boiler is switched on. Ten seconds later, the boiler will be switched on. When the tank reaches its temperature, the boiler is switched off, and ten seconds later, the pump will be switched off.

The building has a controlled fresh air supply. A heat recovery ventilator is used to preheat the outside air. Each room has a model for the leakage of the facade. If supply and exhaust air are unbalanced, then the difference in air supply will flow through this leakage model.

The hydronic heating system is connected to an expansion vessel. Some medium models for water compute the density as a function of temperature, while others assume a constant density. If the density is modeled as a function of temperature, then the water volume will increase when heated, and the expansion vessel will accumulate the added volume. As the water cools, this volume will flow from the expansion vessel into the hydronic heating system. If the medium model assumes the density to be constant, then the expansion vessel provides a reference pressure for the hydronic heating system.

The cooling of the two rooms is controlled using the temperature of roo1. The set point for mechanical cooling is 25 degree Celsius, with a proportional band of 1 Kelvin.

If the room air temperature is above 22 degree Celsius, the free cooling is enabled by opening the bypass damper of the heat recovery. Free cooling is only allowed if the outside air temperature is above 16 degree Celsius and 1 Kelvin below the room air temperature.

The cooling control is implemented in the model Buildings.Examples.HydronicHeating.TwoRoomsWithStorage.CoolingControl.

Extends from Modelica.Icons.Example (Icon for runnable examples).

Parameters

TypeNameDefaultDescription
replaceable package MediumABuildings.Media.Air (T_defau...Medium model for air
replaceable package MediumWBuildings.Media.WaterMedium model
IntegernRoo2Number of rooms
VolumeVRoo4*6*3Volume of one room [m3]
PowerQ_flow_nominal2200Nominal power of heating plant [W]
RealscaFacRad1.5Scaling factor to scale the power (and mass flow rate) of the radiator loop
TemperatureTSup_nominal273.15 + 50 + 5Nominal supply temperature for radiators [K]
TemperatureTRet_nominal273.15 + 40 + 5Nominal return temperature for radiators [K]
TemperaturedTRad_nominalTSup_nominal - TRet_nominalNominal temperature difference for radiator loop [K]
TemperaturedTBoi_nominal20Nominal temperature difference for boiler loop [K]
MassFlowRatemRad_flow_nominalscaFacRad*Q_flow_nominal/dTR...Nominal mass flow rate of radiator loop [kg/s]
MassFlowRatemBoi_flow_nominalscaFacRad*Q_flow_nominal/dTB...Nominal mass flow rate of boiler loop [kg/s]
PressureDifferencedpPip_nominal10000Pressure difference of pipe (without valve) [Pa]
PressureDifferencedpVal_nominal1000Pressure difference of valve [Pa]
PressureDifferencedpRoo_nominal6000Pressure difference of flow leg that serves a room [Pa]
PressureDifferencedpThrWayVal_nominal6000Pressure difference of three-way valve [Pa]
PressureDifferencedp_nominaldpPip_nominal + dpVal_nomina...Pressure difference of loop [Pa]
Insulation100Concrete200matLayExt Construction material for exterior walls
Brick120matLayPar Construction material for partition walls
GenericmatLayFlomatLayFlo( material={ ...Construction material for floor
DoubleClearAir13ClearglaSysglaSys( UFra=2, shade=...Data record for the glazing system

Connectors

TypeNameDescription
replaceable package MediumAMedium model for air
replaceable package MediumWMedium model
BusweaBusBus with weather data

Modelica definition

model TwoRoomsWithStorage "Model of a hydronic heating system with energy storage" extends Modelica.Icons.Example; replaceable package MediumA = Buildings.Media.Air(T_default=293.15) "Medium model for air"; replaceable package MediumW = Buildings.Media.Water "Medium model"; parameter Integer nRoo = 2 "Number of rooms"; parameter Modelica.SIunits.Volume VRoo = 4*6*3 "Volume of one room"; parameter Modelica.SIunits.Power Q_flow_nominal = 2200 "Nominal power of heating plant"; // Due to the night setback, in which the radiator do not provide heat input into the room, // we scale the design power of the radiator loop parameter Real scaFacRad = 1.5 "Scaling factor to scale the power (and mass flow rate) of the radiator loop"; parameter Modelica.SIunits.Temperature TSup_nominal=273.15 + 50 + 5 "Nominal supply temperature for radiators"; parameter Modelica.SIunits.Temperature TRet_nominal=273.15 + 40 + 5 "Nominal return temperature for radiators"; parameter Modelica.SIunits.Temperature dTRad_nominal = TSup_nominal-TRet_nominal "Nominal temperature difference for radiator loop"; parameter Modelica.SIunits.Temperature dTBoi_nominal = 20 "Nominal temperature difference for boiler loop"; parameter Modelica.SIunits.MassFlowRate mRad_flow_nominal = scaFacRad*Q_flow_nominal/dTRad_nominal/4200 "Nominal mass flow rate of radiator loop"; parameter Modelica.SIunits.MassFlowRate mBoi_flow_nominal = scaFacRad*Q_flow_nominal/dTBoi_nominal/4200 "Nominal mass flow rate of boiler loop"; parameter Modelica.SIunits.PressureDifference dpPip_nominal = 10000 "Pressure difference of pipe (without valve)"; parameter Modelica.SIunits.PressureDifference dpVal_nominal = 1000 "Pressure difference of valve"; parameter Modelica.SIunits.PressureDifference dpRoo_nominal = 6000 "Pressure difference of flow leg that serves a room"; parameter Modelica.SIunits.PressureDifference dpThrWayVal_nominal = 6000 "Pressure difference of three-way valve"; parameter Modelica.SIunits.PressureDifference dp_nominal= dpPip_nominal + dpVal_nominal + dpRoo_nominal + dpThrWayVal_nominal "Pressure difference of loop"; // Room model Buildings.Fluid.Movers.SpeedControlled_y pumBoi( redeclare package Medium = MediumW, per(pressure(V_flow=mBoi_flow_nominal/1000*{0.5,1}, dp=(3000 + 2000)*{2,1})), use_inputFilter=false, energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState) "Pump for boiler circuit"; Buildings.Fluid.Movers.SpeedControlled_y pumRad( redeclare package Medium = MediumW, per(pressure(V_flow=mRad_flow_nominal/1000*{0,2}, dp=dp_nominal*{2,0})), energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState) "Pump that serves the radiators"; parameter HeatTransfer.Data.OpaqueConstructions.Insulation100Concrete200 matLayExt "Construction material for exterior walls"; parameter HeatTransfer.Data.OpaqueConstructions.Brick120 matLayPar "Construction material for partition walls"; parameter HeatTransfer.Data.OpaqueConstructions.Generic matLayFlo( material={ HeatTransfer.Data.Solids.Concrete(x=0.2), HeatTransfer.Data.Solids.InsulationBoard(x=0.15), HeatTransfer.Data.Solids.Concrete(x=0.05)}, final nLay=3) "Construction material for floor"; parameter HeatTransfer.Data.GlazingSystems.DoubleClearAir13Clear glaSys( UFra=2, shade=Buildings.HeatTransfer.Data.Shades.Gray(), haveInteriorShade=false, haveExteriorShade=false) "Data record for the glazing system"; ThermalZones.Detailed.MixedAir roo1( redeclare package Medium = MediumA, AFlo=6*4, hRoo=2.7, nConExt=0, nConExtWin=2, datConExtWin( layers={matLayExt, matLayExt}, A={4*3, 6*3}, glaSys={glaSys, glaSys}, wWin={3, 2}, each hWin=2, each fFra=0.1, til={Buildings.Types.Tilt.Wall, Buildings.Types.Tilt.Wall}, azi={Buildings.Types.Azimuth.W, Buildings.Types.Azimuth.S}), nConPar=2, datConPar( layers={matLayFlo, matLayPar}, A={6*4, 6*3/2}, til={Buildings.Types.Tilt.Floor, Buildings.Types.Tilt.Wall}, azi={Buildings.Types.Azimuth.N, Buildings.Types.Azimuth.N}), nConBou=0, nSurBou=1, surBou( each A=4*3, each absIR=0.9, each absSol=0.9, each til=Buildings.Types.Tilt.Wall), energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial, nPorts=3, linearizeRadiation=true, lat=0.73268921998722, extConMod=Buildings.HeatTransfer.Types.ExteriorConvection.Fixed) "Room model"; ThermalZones.Detailed.MixedAir roo2( redeclare package Medium = MediumA, AFlo=6*4, hRoo=2.7, nConExt=0, nConExtWin=2, datConExtWin( layers={matLayExt, matLayExt}, A={4*3, 6*3}, glaSys={glaSys, glaSys}, wWin={2, 2}, each hWin=2, each fFra=0.1, til={Buildings.Types.Tilt.Wall, Buildings.Types.Tilt.Wall}, azi={Buildings.Types.Azimuth.E, Buildings.Types.Azimuth.S}), nConPar=2, datConPar( layers={matLayFlo, matLayPar}, A={6*4, 6*3/2}, til={Buildings.Types.Tilt.Floor, Buildings.Types.Tilt.Wall}, azi={Buildings.Types.Azimuth.N, Buildings.Types.Azimuth.N}), nConBou=0, nSurBou=1, surBou( each A=4*3, each absIR=0.9, each absSol=0.9, each til=Buildings.Types.Tilt.Wall), energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial, linearizeRadiation=true, nPorts=3, lat=0.73268921998722, extConMod=Buildings.HeatTransfer.Types.ExteriorConvection.Fixed) "Room model"; Buildings.Fluid.Boilers.BoilerPolynomial boi( a={0.9}, effCur=Buildings.Fluid.Types.EfficiencyCurves.Constant, redeclare package Medium = MediumW, Q_flow_nominal=Q_flow_nominal, m_flow_nominal=mBoi_flow_nominal, fue=Buildings.Fluid.Data.Fuels.HeatingOilLowerHeatingValue(), dp_nominal=3000 + 2000, energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial, T_start=293.15) "Boiler"; Buildings.HeatTransfer.Sources.FixedTemperature TAmb(T=288.15) "Ambient temperature in boiler room"; Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor TRoo2; Modelica.Blocks.Sources.Constant pumRadOn(k=1) "Pump on signal"; Controls.Continuous.PIDHysteresisTimer conPum( yMax=1, Td=60, yMin=0.05, controllerType=Modelica.Blocks.Types.SimpleController.PI, eOn=0.5, k=0.5, Ti=15) "Controller for pump"; Buildings.Fluid.Sensors.RelativePressure dpSen(redeclare package Medium = MediumW); Buildings.Fluid.Actuators.Valves.TwoWayEqualPercentage val2( redeclare package Medium = MediumW, dpValve_nominal(displayUnit="Pa") = dpVal_nominal, m_flow_nominal=mRad_flow_nominal/nRoo, dpFixed_nominal=dpRoo_nominal, from_dp=true, use_inputFilter=false) "Radiator valve"; Controls.Continuous.LimPID conRoo2( yMax=1, yMin=0, Ti=60, Td=60, controllerType=Modelica.Blocks.Types.SimpleController.P, k=0.5) "Controller for room temperature"; Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor TRoo1; Buildings.Fluid.Actuators.Valves.TwoWayEqualPercentage val1( redeclare package Medium = MediumW, dpValve_nominal(displayUnit="Pa") = dpVal_nominal, m_flow_nominal=mRad_flow_nominal/nRoo, dpFixed_nominal=dpRoo_nominal, from_dp=true, use_inputFilter=false) "Radiator valve"; Controls.Continuous.LimPID conRoo1( yMax=1, yMin=0, Ti=60, Td=60, controllerType=Modelica.Blocks.Types.SimpleController.P, k=0.5) "Controller for room temperature"; Buildings.Fluid.HeatExchangers.Radiators.RadiatorEN442_2 rad1( redeclare package Medium = MediumW, Q_flow_nominal=scaFacRad*Q_flow_nominal/nRoo, energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial, T_a_nominal=323.15, T_b_nominal=313.15) "Radiator"; Buildings.Fluid.HeatExchangers.Radiators.RadiatorEN442_2 rad2( redeclare package Medium = MediumW, Q_flow_nominal=scaFacRad*Q_flow_nominal/nRoo, energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial, T_a_nominal=323.15, T_b_nominal=313.15) "Radiator"; Buildings.Fluid.Actuators.Valves.ThreeWayEqualPercentageLinear thrWayVal( redeclare package Medium = MediumW, dpValve_nominal=dpThrWayVal_nominal, l={0.01,0.01}, tau=10, m_flow_nominal=mRad_flow_nominal, dpFixed_nominal={100,0}, use_inputFilter=false, energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState) "Three-way valve"; Controls.Continuous.LimPID conVal( yMax=1, yMin=0, initType=Modelica.Blocks.Types.InitPID.InitialState, xi_start=1, Td=60, k=0.1, Ti=120, controllerType=Modelica.Blocks.Types.SimpleController.PI) "Controller for pump"; Buildings.Fluid.Storage.Stratified tan( m_flow_nominal=mRad_flow_nominal, dIns=0.3, redeclare package Medium = MediumW, hTan=2, nSeg=5, show_T=true, VTan=0.2, energyDynamics=Modelica.Fluid.Types.Dynamics.FixedInitial) "Storage tank"; Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor tanTemBot "Tank temperature"; Modelica.Thermal.HeatTransfer.Sensors.TemperatureSensor tanTemTop "Tank temperature"; Modelica.Blocks.Logical.GreaterThreshold greThr(threshold=TSup_nominal + 5) "Check for temperature at the bottom of the tank"; Modelica.Blocks.Math.BooleanToReal booToReaPum "Signal converter for pump"; Modelica.Blocks.Logical.Greater lesThr "Check for temperature at the top of the tank"; Buildings.Fluid.Sensors.TemperatureTwoPort temSup( redeclare package Medium = MediumW, m_flow_nominal=mRad_flow_nominal); Buildings.Fluid.Sensors.TemperatureTwoPort temRet( redeclare package Medium = MediumW, m_flow_nominal=mRad_flow_nominal); Buildings.Controls.SetPoints.HotWaterTemperatureReset heaCha( dTOutHeaBal=0, use_TRoo_in=true, TSup_nominal=TSup_nominal, TRet_nominal=TRet_nominal, TOut_nominal=258.15); Controls.SetPoints.OccupancySchedule occSch1(occupancy=3600*{7,8,10,11,11.5, 15,19,21}) "Occupancy schedule"; Modelica.Blocks.Logical.Switch switch1; Modelica.Blocks.Sources.RealExpression occ1(y=1/6/4) "Heat gain if occupied in room 1"; Modelica.Blocks.Sources.Constant zer(k=0) "Outputs zero"; Controls.SetPoints.OccupancySchedule occSch2( firstEntryOccupied=false, occupancy=3600*{7,10,12,22}) "Occupancy schedule"; Modelica.Blocks.Logical.Switch switch2; Modelica.Blocks.Sources.RealExpression occ2(y=1/6/4) "Heat gain if occupied in room 2"; Controls.SetPoints.OccupancySchedule occSch "Occupancy schedule"; Modelica.Blocks.Logical.Switch swi "Switch to select set point"; Modelica.Blocks.Sources.Constant TRooNig(k=273.15 + 16) "Room temperature set point at night"; Modelica.Blocks.Sources.Constant TRooSet(k=273.15 + 21); Buildings.Utilities.Math.Max maxYVal(nin=2) "Maximum radiator valve position"; Modelica.Blocks.Logical.Hysteresis hysPum( uLow=0.01, uHigh=0.5) "Hysteresis for pump"; Modelica.Blocks.Logical.Switch swiPum "Pump switch"; Modelica.Blocks.Sources.Constant pumRadOff(k=0) "Pump off signal"; Buildings.BoundaryConditions.WeatherData.ReaderTMY3 weaDat(filNam= Modelica.Utilities.Files.loadResource("modelica://Buildings/Resources/weatherdata/USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.mos")) "File reader that reads weather data"; Buildings.BoundaryConditions.WeatherData.Bus weaBus "Bus with weather data"; Buildings.Fluid.Sources.Outside out( redeclare package Medium = MediumA, use_C_in=false, nPorts=4) "Outside air conditions"; Buildings.Fluid.FixedResistances.PressureDrop dpFac4( from_dp=false, redeclare package Medium = MediumA, m_flow_nominal=6*4*3*1.2*0.3/3600, dp_nominal=10) "Pressure drop at facade"; HeatTransfer.Conduction.MultiLayer parWal(A=4*3, layers=matLayPar, stateAtSurface_a=true, stateAtSurface_b=true) "Partition wall between the two rooms"; Buildings.Fluid.FixedResistances.PressureDrop dpFac1( from_dp=false, redeclare package Medium = MediumA, m_flow_nominal=6*4*3*1.2*0.3/3600, dp_nominal=10) "Pressure drop at facade"; Buildings.Fluid.HeatExchangers.ConstantEffectiveness hex( redeclare package Medium1 = MediumA, redeclare package Medium2 = MediumA, m1_flow_nominal=2*VRoo*1.2*0.3/3600, m2_flow_nominal=2*VRoo*1.2*0.3/3600, dp1_nominal=100, dp2_nominal=100, eps=0.9) "Heat recovery"; Buildings.Fluid.Movers.FlowControlled_m_flow fanSup( redeclare package Medium = MediumA, m_flow_nominal=2*VRoo*1.2*0.37/3600, energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, use_inputFilter=false) "Supply air fan"; Modelica.Blocks.Sources.Constant m_flow_out(k=2*VRoo*1.2*0.37/3600) "Outside air mass flow rate"; Buildings.Fluid.Movers.FlowControlled_m_flow fanRet( redeclare package Medium = MediumA, m_flow_nominal=2*VRoo*1.2*0.37/3600, energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState, use_inputFilter=false) "Return air fan"; Airflow.Multizone.Orifice lea1(redeclare package Medium = MediumA, A=0.01^2) "Leakage of facade of room"; Airflow.Multizone.Orifice lea2(redeclare package Medium = MediumA, A=0.01^2) "Leakage of facade of room"; Modelica.Blocks.MathBoolean.Or pumOnSig(nu=3) "Signal for pump being on"; Modelica.Blocks.Math.BooleanToReal booToReaBoi "Signal converter for boiler"; Modelica.Blocks.Math.MatrixGain gai1(K=[35; 70; 30]) "Gain to convert from occupancy (per person) to radiant, convective and latent heat in [W/m2] "; Modelica.Blocks.Math.MatrixGain gai2(K=[35; 70; 30]) "Gain to convert from occupancy (per person) to radiant, convective and latent heat in [W/m2] "; Modelica.Blocks.Sources.Constant dTThr(k=1) "Threshold to switch boiler off"; Modelica.Blocks.Math.Add add1(k2=-1); Modelica.Blocks.Sources.Constant TRooOff(k=273.15 - 5) "Low room temperature set point to switch heating off"; Modelica.Blocks.Logical.Switch swi1 "Switch to select set point"; Modelica.Blocks.Logical.OnOffController onOff(bandwidth=2) "On/off switch"; Modelica.Blocks.Continuous.FirstOrder aveTOut( T=24*3600, initType=Modelica.Blocks.Types.Init.SteadyState, y(unit="K")) "Integrated average of outside temperature"; Modelica.Blocks.Sources.Constant TOutSwi(k=16 + 293.15) "Outside air temperature to switch heating on or off"; Buildings.Fluid.Sources.Boundary_pT bou(nPorts=1, redeclare package Medium = MediumW) "Fixed boundary condition, needed to provide a pressure in the system"; Modelica.Blocks.Math.Gain gain(k=1/dp_nominal) "Gain used to normalize pressure measurement signal"; Buildings.Fluid.FixedResistances.Junction splVal( dp_nominal={dpPip_nominal,0,0}, m_flow_nominal=mRad_flow_nominal*{1,-1,-1}, redeclare package Medium = MediumW, energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState) "Flow splitter"; Buildings.Fluid.FixedResistances.Junction splVal1( m_flow_nominal=mRad_flow_nominal*{1,-1,-1}, redeclare package Medium = MediumW, dp_nominal={0,0,0}, energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState) "Flow splitter"; Buildings.Fluid.FixedResistances.Junction splVal2( m_flow_nominal=mRad_flow_nominal*{1,-1,-1}, redeclare package Medium = MediumW, dp_nominal={0,0,0}, energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState) "Flow splitter"; CoolingControl cooCon "Controller for cooling"; Buildings.Fluid.Actuators.Dampers.Exponential damSupByp( redeclare package Medium = MediumA, m_flow_nominal=2*VRoo*1.2*0.37/3600, use_inputFilter=false) "Supply air damper that bypasses the heat recovery"; Buildings.Fluid.HeatExchangers.SensibleCooler_T coo( redeclare package Medium = MediumA, m_flow_nominal=2*VRoo*1.2*0.37/3600, dp_nominal=0, energyDynamics=Modelica.Fluid.Types.Dynamics.SteadyState) "Coil for mechanical cooling"; Modelica.Blocks.Logical.LessThreshold lesThrTRoo(threshold=18 + 273.15) "Test to block boiler if room air temperature is sufficiently high"; Modelica.Blocks.Logical.And and1 "Logical test to enable pump and subsequently the boiler"; block CoolingControl "Controller for the free cooling and the mechanical cooling" extends Modelica.Blocks.Icons.Block; parameter Modelica.SIunits.Temperature TRooCoo = 25+273.15 "Set point for mechanical cooling"; parameter Modelica.SIunits.Temperature TRooFre = 22+273.15 "Maximum temperature above which free cooling is enabled"; parameter Modelica.SIunits.Temperature TOutFre = 16+273.15 "Outside temperature above which free cooling is allowed"; parameter Modelica.SIunits.TemperatureDifference dT = 1 "Dead-band for free cooling"; parameter Real Kp(min=0) = 1 "Proportional band for mechanical cooling"; Modelica.Blocks.Interfaces.RealInput TRoo(unit="K") "Room air temperature"; Modelica.Blocks.Interfaces.RealInput TOut(unit="K") "Outside air temperature"; Modelica.Blocks.Interfaces.RealOutput TSupCoo "Control signal for set point for leaving air temperature of cooling coil"; Modelica.Blocks.Interfaces.RealOutput yF "Control signal for free cooling, 1 if free cooling should be provided"; Modelica.Blocks.Interfaces.RealOutput yHex "Control signal for heat recovery damper"; initial equation yF = 0; yHex = 1; algorithm when TRoo > TRooFre and TOut > TOutFre and TOut < TRoo - dT then yF := 1; yHex := 0; elsewhen TOut < TOutFre-dT or TOut > TRoo then yF := 0; yHex := 1; end when; TSupCoo :=273.15 + Buildings.Utilities.Math.Functions.smoothLimit( x=30 - 20*Kp*(TRoo - TRooCoo), l=10, u=30, deltaX=0.1); end CoolingControl; Buildings.Fluid.Actuators.Dampers.Exponential damHex( redeclare package Medium = MediumA, m_flow_nominal=2*VRoo*1.2*0.37/3600, use_inputFilter=false) "Supply air damper that closes the heat recovery"; Buildings.Fluid.Actuators.Dampers.Exponential damRetByp( redeclare package Medium = MediumA, m_flow_nominal=2*VRoo*1.2*0.37/3600, use_inputFilter=false) "Return air damper that bypasses the heat recovery"; Modelica.StateGraph.InitialStep off "Pump and furnace off"; Modelica.StateGraph.TransitionWithSignal T1 "Transition to pump on"; Modelica.StateGraph.StepWithSignal pumOn "Pump on"; Modelica.StateGraph.Transition T3(enableTimer=true, waitTime=10) "Transition to boiler on"; Modelica.StateGraph.StepWithSignal boiOn "Boiler on"; Modelica.StateGraph.TransitionWithSignal T2 "Transition that switches boiler off"; Modelica.StateGraph.StepWithSignal pumOn2 "Pump on"; Modelica.StateGraph.Transition T4(enableTimer=true, waitTime=10) "Transition to boiler on"; inner Modelica.StateGraph.StateGraphRoot stateGraphRoot "Root of the state graph"; equation connect(TAmb.port,boi. heatPort); connect(pumRad.port_b, dpSen.port_a); connect(dpSen.port_b, pumRad.port_a); connect(val1.port_b, rad1.port_a); connect(val2.port_b, rad2.port_a); connect(conRoo1.y, val1.y); connect(conRoo2.y, val2.y); connect(pumRad.port_a, thrWayVal.port_2); connect(boi.port_b,pumBoi. port_a); connect(tan.heaPorVol[1], tanTemTop.port); connect(tanTemBot.port, tan.heaPorVol[tan.nSeg]); connect(temSup.T, conVal.u_m); connect(heaCha.TSup, conVal.u_s); connect(tan.port_b, boi.port_a); connect(occSch1.occupied, switch1.u2); connect(occ1.y, switch1.u1); connect(zer.y, switch1.u3); connect(occSch2.occupied, switch2.u2); connect(occ2.y, switch2.u1); connect(zer.y, switch2.u3); connect(swi.y, conRoo1.u_s); connect(swi.y, conRoo2.u_s); connect(maxYVal.y, hysPum.u); connect(hysPum.y, swiPum.u2); connect(pumRadOn.y, swiPum.u1); connect(pumRadOff.y, swiPum.u3); connect(swiPum.y, conPum.u_s); connect(conRoo1.y, maxYVal.u[1]); connect(conRoo2.y, maxYVal.u[2]); connect(conVal.y, thrWayVal.y); connect(booToReaPum.y, pumBoi.y); connect(rad1.heatPortCon, roo1.heaPorAir); connect(roo1.heaPorRad, rad1.heatPortRad); connect(roo1.heaPorAir, TRoo1.port); connect(weaBus, roo1.weaBus); connect(rad2.heatPortCon, roo2.heaPorAir); connect(rad2.heatPortRad, roo2.heaPorRad); connect(roo2.heaPorAir, TRoo2.port); connect(weaBus, roo2.weaBus); connect(roo1.surf_surBou[1], parWal.port_b); connect(parWal.port_a, roo2.surf_surBou[1]); connect(roo1.ports[1], dpFac1.port_b); connect(dpFac1.port_a, hex.port_a2); connect(dpFac4.port_b, roo2.ports[1]); connect(dpFac4.port_a, hex.port_a2); connect(fanSup.m_flow_in, m_flow_out.y); connect(fanRet.port_a, hex.port_b2); connect(out.ports[1], fanSup.port_a); connect(fanRet.port_b, out.ports[2]); connect(m_flow_out.y, fanRet.m_flow_in); connect(lea1.port_b, roo1.ports[2]); connect(lea1.port_a, out.ports[3]); connect(lea2.port_b, roo2.ports[2]); connect(lea2.port_a, out.ports[4]); connect(swi.y, heaCha.TRoo_in); connect(pumRad.port_b, temSup.port_a); connect(booToReaPum.u, pumOnSig.y); connect(weaBus.TDryBul, heaCha.TOut); connect(weaBus, out.weaBus); connect(switch1.y, gai1.u[1]); connect(gai1.y, roo1.qGai_flow); connect(switch2.y, gai2.u[1]); connect(gai2.y, roo2.qGai_flow); connect(heaCha.TSup, lesThr.u1); connect(booToReaBoi.y, boi.y); connect(tan.heaPorTop, TAmb.port); connect(TAmb.port, tan.heaPorSid); connect(TAmb.port, tan.heaPorBot); connect(add1.y, lesThr.u2); connect(tanTemTop.T, add1.u1); connect(dTThr.y, add1.u2); connect(tanTemBot.T, greThr.u); connect(TRooSet.y, swi1.u1); connect(swi1.u2, occSch.occupied); connect(TRooNig.y, swi1.u3); connect(aveTOut.y, onOff.u); connect(TOutSwi.y, onOff.reference); connect(swi1.y, swi.u1); connect(onOff.y, swi.u2); connect(TRooOff.y, swi.u3); connect(weaBus.TDryBul, aveTOut.u); connect(weaBus, weaDat.weaBus); connect(conPum.y, pumRad.y); connect(TRoo1.T, conRoo1.u_m); connect(TRoo2.T, conRoo2.u_m); connect(bou.ports[1], boi.port_a); connect(gain.u, dpSen.p_rel); connect(gain.y, conPum.u_m); connect(pumBoi.port_b, tan.port_a); connect(pumBoi.port_b, thrWayVal.port_1); connect(temRet.port_b, splVal.port_1); connect(thrWayVal.port_3, splVal.port_3); connect(splVal.port_2, tan.port_b); connect(splVal1.port_3, val2.port_a); connect(splVal1.port_1, temSup.port_b); connect(splVal1.port_2, val1.port_a); connect(temRet.port_a, splVal2.port_1); connect(splVal2.port_3, rad2.port_b); connect(splVal2.port_2, rad1.port_b); connect(weaBus.TDryBul, cooCon.TOut); connect(TRoo1.T, cooCon.TRoo); connect(fanSup.port_b, damSupByp.port_a); connect(cooCon.yF, damSupByp.y); connect(hex.port_b1, coo.port_a); connect(damSupByp.port_b, coo.port_a); connect(coo.port_b, roo1.ports[3]); connect(coo.port_b, roo2.ports[3]); connect(lesThr.y, and1.u2); connect(lesThrTRoo.y, and1.u1); connect(TRoo1.T, lesThrTRoo.u); connect(damHex.port_b, hex.port_a1); connect(damHex.port_a, fanSup.port_b); connect(hex.port_a2, damRetByp.port_a); connect(damRetByp.port_b, fanRet.port_a); connect(damHex.y, cooCon.yHex); connect(damRetByp.y, cooCon.yF); connect(cooCon.TSupCoo, coo.TSet); connect(and1.y, T1.condition); connect(greThr.y, T2.condition); connect(boiOn.active, booToReaBoi.u); connect(pumOn2.active, pumOnSig.u[1]); connect(boiOn.active, pumOnSig.u[2]); connect(pumOn.active, pumOnSig.u[3]); connect(off.outPort[1], T1.inPort); connect(T1.outPort, pumOn.inPort[1]); connect(pumOn.outPort[1], T3.inPort); connect(T3.outPort, boiOn.inPort[1]); connect(boiOn.outPort[1], T2.inPort); connect(T2.outPort, pumOn2.inPort[1]); connect(pumOn2.outPort[1], T4.inPort); connect(T4.outPort, off.inPort[1]); end TwoRoomsWithStorage;

Buildings.Examples.HydronicHeating.TwoRoomsWithStorage.CoolingControl Buildings.Examples.HydronicHeating.TwoRoomsWithStorage.CoolingControl

Controller for the free cooling and the mechanical cooling

Buildings.Examples.HydronicHeating.TwoRoomsWithStorage.CoolingControl

Information

This block computes a control signal for free cooling and for mechanical cooling.

Extends from Modelica.Blocks.Icons.Block (Basic graphical layout of input/output block).

Parameters

TypeNameDefaultDescription
TemperatureTRooCoo25 + 273.15Set point for mechanical cooling [K]
TemperatureTRooFre22 + 273.15Maximum temperature above which free cooling is enabled [K]
TemperatureTOutFre16 + 273.15Outside temperature above which free cooling is allowed [K]
TemperatureDifferencedT1Dead-band for free cooling [K]
RealKp1Proportional band for mechanical cooling

Connectors

TypeNameDescription
input RealInputTRooRoom air temperature [K]
input RealInputTOutOutside air temperature [K]
output RealOutputTSupCooControl signal for set point for leaving air temperature of cooling coil
output RealOutputyFControl signal for free cooling, 1 if free cooling should be provided
output RealOutputyHexControl signal for heat recovery damper

Modelica definition

block CoolingControl "Controller for the free cooling and the mechanical cooling" extends Modelica.Blocks.Icons.Block; parameter Modelica.SIunits.Temperature TRooCoo = 25+273.15 "Set point for mechanical cooling"; parameter Modelica.SIunits.Temperature TRooFre = 22+273.15 "Maximum temperature above which free cooling is enabled"; parameter Modelica.SIunits.Temperature TOutFre = 16+273.15 "Outside temperature above which free cooling is allowed"; parameter Modelica.SIunits.TemperatureDifference dT = 1 "Dead-band for free cooling"; parameter Real Kp(min=0) = 1 "Proportional band for mechanical cooling"; Modelica.Blocks.Interfaces.RealInput TRoo(unit="K") "Room air temperature"; Modelica.Blocks.Interfaces.RealInput TOut(unit="K") "Outside air temperature"; Modelica.Blocks.Interfaces.RealOutput TSupCoo "Control signal for set point for leaving air temperature of cooling coil"; Modelica.Blocks.Interfaces.RealOutput yF "Control signal for free cooling, 1 if free cooling should be provided"; Modelica.Blocks.Interfaces.RealOutput yHex "Control signal for heat recovery damper"; initial equation yF = 0; yHex = 1; algorithm when TRoo > TRooFre and TOut > TOutFre and TOut < TRoo - dT then yF := 1; yHex := 0; elsewhen TOut < TOutFre-dT or TOut > TRoo then yF := 0; yHex := 1; end when; TSupCoo :=273.15 + Buildings.Utilities.Math.Functions.smoothLimit( x=30 - 20*Kp*(TRoo - TRooCoo), l=10, u=30, deltaX=0.1); end CoolingControl;