Question-and-Answer Resource for the Building Energy Modeling Community
Get started with the Help page
Ask Your Question

Revision history [back]

You probably want to look in the "resources" directory at the OSLib_HVAC.rb file. This contains common methods used by a lot of the AEDG HVAC measures.

For example there is a method to make the primary air loop

def OsLib_HVAC.createPrimaryZoneEquipment(model, runner, options)

"model" is passed in because we need access to the model to get and add things to it. "runner" gives us the ability to add log messages from the helper. "options" is a hash containing many objects. If you search for "options" in the method above you will for example see an if statement with may elsif options for options["ZoneHVAC"] that has values such as ASHP, Baseboard, Radiant or DualDuct. You could extend this to have more methods, or add another key to the options hash to store additional inputs such as motor efficiency values, which or currently hard coded. Below is one of the "elsif" options for this ZoneHVAC.

    elsif options["zoneHVAC"] == "Baseboard"
      # create baseboard heater add add to thermal zone and hot water loop
      baseboard_coil = OpenStudio::Model::CoilHeatingWaterBaseboard.new(model)
      baseboard_heater = OpenStudio::Model::ZoneHVACBaseboardConvectiveWater.new(model, model.alwaysOnDiscreteSchedule(), baseboard_coil)
      baseboard_heater.addToThermalZone(zone)          
      options["hot_water_plant"].addDemandBranchForComponent(baseboard_coil)
    elsif options["zoneHVAC"] == "Radiant"
      #. . .

There is a hash value for options["PrimaryHVAC']. But instead of just returning a string, as you have found it returns its own hash. Really, we could have just made the main hash a lot bigger, but in this case when we ask about it in the measure check for the value two hashes deep. Below is an example of that in the method to make the primary air loop. Note how we are not currently setup to handle electric heat on the primary air loop, we didn't need it, but if you did, you could just extent the statement with an "elsif" option before the final "else".

    if options["primaryHVAC"]["heat"] == "Water"
      # water coil
      heating_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule())
      air_loop_comps << heating_coil
    else  
      # gas coil
      heating_coil = OpenStudio::Model::CoilHeatingGas.new(model, model.alwaysOnDiscreteSchedule())
      air_loop_comps << heating_coil
    end

You probably want to look in the "resources" directory at the OSLib_HVAC.rb file. This contains common methods used by a lot of the AEDG HVAC measures.

For example there is a method to make the primary air loop

def OsLib_HVAC.createPrimaryZoneEquipment(model, runner, options)

"model" is passed in because we need access to the model to get and add things to it. "runner" gives us the ability to add log messages from the helper. "options" is a hash containing many objects. If you search for "options" in the method above you will for example see an if statement with may many elsif options for options["ZoneHVAC"] that has values such as ASHP, Baseboard, Radiant or DualDuct. You could extend this to have more methods, or add another key to the options hash to store additional inputs such as motor efficiency values, which or currently hard coded. Below is one of the "elsif" options for this ZoneHVAC.

    elsif options["zoneHVAC"] == "Baseboard"
      # create baseboard heater add add to thermal zone and hot water loop
      baseboard_coil = OpenStudio::Model::CoilHeatingWaterBaseboard.new(model)
      baseboard_heater = OpenStudio::Model::ZoneHVACBaseboardConvectiveWater.new(model, model.alwaysOnDiscreteSchedule(), baseboard_coil)
      baseboard_heater.addToThermalZone(zone)          
      options["hot_water_plant"].addDemandBranchForComponent(baseboard_coil)
    elsif options["zoneHVAC"] == "Radiant"
      #. . .

There Back to your original question there is a hash value for options["PrimaryHVAC']. But instead of just returning a string, as you have found it returns its own hash. Really, we could have just made the main hash a lot bigger, but in this case when we ask about it in the measure check for the value two hashes deep. Below is an example of that in the method to make the primary air loop. Note how that we are not currently setup to handle electric heat on the primary air loop, we didn't need it, but if you did, you could just extent the statement with an "elsif" option before the final "else".

    if options["primaryHVAC"]["heat"] == "Water"
      # water coil
      heating_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule())
      air_loop_comps << heating_coil
    else  
      # gas coil
      heating_coil = OpenStudio::Model::CoilHeatingGas.new(model, model.alwaysOnDiscreteSchedule())
      air_loop_comps << heating_coil
    end

One last thing to think about. You will notice for the AEDG''s we didn't just make one measure for all of HVAC Types with a choice list to choose the one you want. We felt they were different enough that the user can choose form a collection of measures each which is focused on one type of HVAC system. There is no right or wrong answer for weather they should all be one measure or many. It depends on the needs of your use-case and how complex you want them. Our AEDG HVACmeasures also have code to address removal of existing systems, and handling plenums. If you know you will be working from clean models then you can simplify a lot of the code. You could also hand stub in air loops in your model vs. allowing OpenStudio to determine which zones go on which loop. In this case all of the objects on the primary loop on the same story were put on an air loop together.