remove CoilCoolingWater from .OSM without leaving OS:Connection behind

asked 2024-07-30 19:40:15 -0500

mattkoch's avatar

updated 2024-07-31 19:14:02 -0500

I have written a number of OpenStudio 3.7.0 Python scripts which populate/modify an OpenStudioApp 1.7.0 .OSM file with CoilCoolingWater or CoilHeatingWater objects. The scripts also connect these coils to the respective PlantLoops and AirLoopHVACs. My intent is that I have "add" scripts which insert and connect these coils and "delete" scripts which disconnect and remove these coils. All work as expected at this point, except after running "delete" scripts, I always end up with a number of OS:Connection objects as leftovers in the .OSM file, when all I expect is the OS:Version object that I start out with before running "add" scripts. These objects look as follows:

OS:Connection,
  {90c97a52-dc19-4df2-a3c1-25df6ded4921}, !- Handle
  ,                                       !- Source Object
  2,                                      !- Outlet Port
  ,                                       !- Target Object
  2;                                      !- Inlet Port

I would have thought that the various:

coil.removeFromPlantLoop()
coil.removeFromAirLoopHVAC()
coil.remove()

which I use in the "delete" scripts would result in a clean .OSM file, but as I say, I find these OS:Connection remnants. Also, there does not seem to be a model.getConnections() to collect and remove these separately after the fact - or at least I seem to recall there wasn't when I last tried?

Surely I am missing something, as is usually the case when I post here, but I can't figure it out. I'd welcome your thoughts, thank you.

Per request, here is a MCVE:

import openstudio

def add(path):
  model = openstudio.model.Model()
  plant_loop = openstudio.model.PlantLoop(model)
  air_loop = openstudio.model.AirLoopHVAC(model)
  for index in range(0,3):
    thermal_zone = openstudio.model.ThermalZone(model)
    coil = openstudio.model.CoilHeatingWater(model)
    plant_loop.addDemandBranchForComponent(coil)
    controller = coil.controllerWaterCoil().get()
    fan = openstudio.model.FanConstantVolume(model)
    air_terminal = openstudio.model.AirTerminalSingleDuctSeriesPIUReheat(model,fan,coil)
    air_loop.addBranchForZone(thermal_zone,air_terminal)
    model.save(path,True)

def delete(path):
  model = openstudio.model.Model()
  model = model.load(path).get()
  if False: # Removing coil and fan before air_terminal does not change the outcome.
    for coil in model.getCoilHeatingWaters():
      coil.removeFromPlantLoop()
      coil.remove()
    for fan in model.getFanConstantVolumes():
      fan.remove()
  for air_terminal in model.getAirTerminalSingleDuctSeriesPIUReheats():
    air_terminal.removeFromLoop()
    air_terminal.remove()
  for thermal_zone in model.getThermalZones():
    thermal_zone.remove()
  for air_loop in model.getAirLoopHVACs():
    air_loop.remove()
  for plant_loop in model.getPlantLoops():
    plant_loop.remove()
  if False: # This may be the fallback though not elegant solution.
    connections = model.getObjectsByType("OS:Connection")
    for connection in connections:
      connection.remove()
  model.save(path,True)

if __name__ == "__main__":
  path = "mcve_1.osm"
  add(path)
  delete(path)
edit retag flag offensive close merge delete

Comments

Can you give us a MCVE to reproduce please?

This works as expected AFAIK. Here is a ruby and pytest version : https://gist.github.com/jmarrec/26b26...

Julien Marrec's avatar Julien Marrec  ( 2024-07-31 08:33:29 -0500 )edit
1

Thank you jmarrec, please see added contents in the question above for the MCVE. I should note that a version of this that has neither fans, air terminals, thermal zones nor the air loop works exactly as you suggest in the link you provided (ignore the schedule that somehow gets introduced to the .OSM). So, perhaps the OS:Connection remnants come from the air side rather than the water side.

mattkoch's avatar mattkoch  ( 2024-07-31 19:21:10 -0500 )edit