Creation of a Water-to-Water Heat Pump in OpenStudio
Hello all!
I am trying to add a water-to-water heat pump using a measure to OpenStudio files. I have not been able to find one that exists already, so I somewhat started from scratch.
The file deletes the current HVAC system, then adds a cooling heat pump, heating heat pump, hot water loop, chilled water loop, a source loop, and then connects fan coils to the zones.
I kept receiving errors about missing control names when reaching the EnergyPlus part of the simulation - "* Severe * <root>[PlantEquipmentOperationSchemes][Source Loop Operation Schemes] - Missing required property 'control_scheme_1_name'." So I tried to fix that and then I got errors on how I was defining loops in OpenStudio.
I've attached my code here. Any idea on what I might be doing wrong? I'm running OpenStudio 3.9, the OS 1.9.0rc-1 application, and EnergyPlus 24-2.
class AddReversibleWWHPSystem < OpenStudio::Measure::ModelMeasure
def name return 'Add Reversible WWHP System and Remove Existing HVAC' end
def description return 'Removes existing HVAC and adds a reversible water-to-water heat pump system with hot, chilled, and shared source loops.' end
def modeler_description return 'Installs heating and cooling WWHPs on separate loops sharing a source loop and serves all zones with four-pipe fan coils.' end
def arguments(model) return OpenStudio::Measure::OSArgumentVector.new end
def run(model, runner, user_arguments) super(model, runner, user_arguments)
runner.registerInitialCondition("Model has #{model.getThermalZones.size} thermal zones.")
# Remove existing HVAC
model.getAirLoopHVACs.each(&:remove)
model.getPlantLoops.each(&:remove)
model.getZoneHVACComponents.each(&:remove)
runner.registerInfo('Removed all existing HVAC systems.')
# -------------------------------
# Hot Water Loop
# -------------------------------
heating_loop = OpenStudio::Model::PlantLoop.new(model)
heating_loop.setName('Hot Water Loop')
hw_inlet = heating_loop.supplyInletNode
hw_outlet = heating_loop.supplyOutletNode
hw_sched = OpenStudio::Model::ScheduleRuleset.new(model)
hw_sched.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 60.0)
hw_spm = OpenStudio::Model::SetpointManagerScheduled.new(model, hw_sched)
hw_spm.addToNode(hw_outlet)
# -------------------------------
# Chilled Water Loop
# -------------------------------
cooling_loop = OpenStudio::Model::PlantLoop.new(model)
cooling_loop.setName('Chilled Water Loop')
cw_inlet = cooling_loop.supplyInletNode
cw_outlet = cooling_loop.supplyOutletNode
cw_sched = OpenStudio::Model::ScheduleRuleset.new(model)
cw_sched.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 7.0)
cw_spm = OpenStudio::Model::SetpointManagerScheduled.new(model, cw_sched)
cw_spm.addToNode(cw_outlet)
# -------------------------------
# Source Loop
# -------------------------------
source_loop = OpenStudio::Model::PlantLoop.new(model)
source_loop.setName('Source Loop')
src_inlet = source_loop.supplyInletNode
src_outlet = source_loop.supplyOutletNode
src_sched = OpenStudio::Model::ScheduleRuleset.new(model)
src_sched.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 15.0)
src_spm = OpenStudio::Model::SetpointManagerScheduled.new(model, src_sched)
src_spm.addToNode(src_outlet)
# -------------------------------
# Heat Pumps
# -------------------------------
heating_hp = OpenStudio::Model::HeatPumpWaterToWaterEquationFitHeating.new(model)
heating_hp.setName('WWHP Heating')
heating_hp.addToNode(hw_inlet)
cooling_hp = OpenStudio::Model::HeatPumpWaterToWaterEquationFitCooling.new(model)
cooling_hp.setName('WWHP Cooling')
cooling_hp.addToNode(cw_inlet)
# -------------------------------
# Add to Loops
# -------------------------------
source_loop.addDemandBranchForComponent(heating_hp)
source_loop.addDemandBranchForComponent(cooling_hp)
heating_loop.addSupplyBranchForComponent(heating_hp)
cooling_loop.addSupplyBranchForComponent(cooling_hp)
# -------------------------------
# Fan Coil Units in Zones
# -------------------------------
model.getThermalZones.each do |zone|
sched = model.alwaysOnDiscreteSchedule
fan = OpenStudio::Model::FanOnOff.new(model, sched)
cc = OpenStudio::Model::CoilCoolingWater.new(model)
hc = OpenStudio::Model::CoilHeatingWater.new(model)
fcu = OpenStudio::Model::ZoneHVACFourPipeFanCoil.new(model, sched, fan, cc, hc)
fcu.setName("Fan Coil - #{zone.name}")
fcu.addToThermalZone(zone)
cooling_loop.addDemandBranchForComponent(cc)
heating_loop.addDemandBranchForComponent ...
Also, would it be easier to just go into the osm, delete the current HVAC, and then add in WSHPs? I just have 123 zones in my building, so I'm not sure how feasible that would actually be. I would like to treat it like one heating and one cooling HP serves the whole building.