openstudio-standards 0.6.3 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
  3. data/data/standards/manage_OpenStudio_Standards.rb +2 -49
  4. data/data/standards/openstudio_standards_duplicates_log.csv +1 -7962
  5. data/data/standards/test_performance_expected_dd_results.csv +2005 -97
  6. data/lib/openstudio-standards/create_typical/space_type_ratios.rb +47 -57
  7. data/lib/openstudio-standards/geometry/create.rb +8 -2
  8. data/lib/openstudio-standards/geometry/create_bar.rb +6 -3
  9. data/lib/openstudio-standards/geometry/create_shape.rb +1 -1
  10. data/lib/openstudio-standards/geometry/group.rb +1 -1
  11. data/lib/openstudio-standards/geometry/information.rb +1 -1
  12. data/lib/openstudio-standards/geometry/modify.rb +53 -1
  13. data/lib/openstudio-standards/infiltration/nist_infiltration.rb +1 -1
  14. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +11 -11
  15. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +11 -11
  16. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.hvac_systems.rb +2 -2
  17. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperTallBuilding.rb +44 -47
  18. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.TallBuilding.rb +43 -48
  19. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CentralAirSourceHeatPump.rb +1 -1
  20. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +44 -24
  21. data/lib/openstudio-standards/prototypes/common/objects/Prototype.refrigeration.rb +24 -24
  22. data/lib/openstudio-standards/schedules/information.rb +1 -1
  23. data/lib/openstudio-standards/schedules/parametric.rb +1 -1
  24. data/lib/openstudio-standards/service_water_heating/create_piping_losses.rb +152 -0
  25. data/lib/openstudio-standards/service_water_heating/create_water_heater.rb +544 -0
  26. data/lib/openstudio-standards/service_water_heating/create_water_heating_loop.rb +303 -0
  27. data/lib/openstudio-standards/service_water_heating/create_water_use.rb +95 -0
  28. data/lib/openstudio-standards/space/space.rb +1 -1
  29. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +65 -70
  30. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +12 -14
  31. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +16 -5
  32. data/lib/openstudio-standards/standards/Standards.Model.rb +2 -2
  33. data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +10 -2
  34. data/lib/openstudio-standards/{prototypes/common/objects/Prototype.Model.swh.rb → standards/Standards.ServiceWaterHeating.rb} +209 -139
  35. data/lib/openstudio-standards/standards/Standards.Surface.rb +1 -1
  36. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +4 -8
  37. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +2 -2
  38. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +22251 -12963
  39. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_sets.json +91 -91
  40. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +8981 -5228
  41. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +8935 -5182
  42. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +7281 -5391
  43. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_sets.json +91 -91
  44. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +9005 -15215
  45. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_sets.json +136 -136
  46. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +1 -1
  47. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +8717 -17168
  48. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_sets.json +136 -136
  49. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +1941 -651
  50. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.construction_properties.json +135 -135
  51. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.construction_properties.json +135 -135
  52. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.construction_properties.json +36 -36
  53. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.construction_properties.json +36 -36
  54. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +377 -99
  55. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +2 -2
  56. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +3 -3
  57. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_properties.json +6889 -4044
  58. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_constructions.json +108 -108
  59. data/lib/openstudio-standards/standards/cbes/cbes_pre_1978/data/cbes_pre_1978.construction_properties.json +16 -16
  60. data/lib/openstudio-standards/standards/cbes/cbes_t24_1978/data/cbes_t24_1978.construction_properties.json +16 -16
  61. data/lib/openstudio-standards/standards/cbes/cbes_t24_1992/data/cbes_t24_1992.construction_properties.json +16 -16
  62. data/lib/openstudio-standards/standards/cbes/cbes_t24_2001/data/cbes_t24_2001.construction_properties.json +16 -16
  63. data/lib/openstudio-standards/standards/cbes/cbes_t24_2005/data/cbes_t24_2005.construction_properties.json +16 -16
  64. data/lib/openstudio-standards/standards/cbes/cbes_t24_2008/data/cbes_t24_2008.construction_properties.json +16 -16
  65. data/lib/openstudio-standards/standards/cbes/data/cbes.constructions.json +142 -142
  66. data/lib/openstudio-standards/standards/deer/data/deer.constructions.json +5 -1551
  67. data/lib/openstudio-standards/standards/deer/data/deer.materials.json +40 -0
  68. data/lib/openstudio-standards/standards/deer/deer_1985/data/deer_1985.motors.json +88 -8
  69. data/lib/openstudio-standards/standards/deer/deer_1996/data/deer_1996.motors.json +88 -8
  70. data/lib/openstudio-standards/standards/deer/deer_2003/data/deer_2003.motors.json +88 -8
  71. data/lib/openstudio-standards/standards/deer/deer_2007/data/deer_2007.motors.json +88 -8
  72. data/lib/openstudio-standards/standards/deer/deer_2011/data/deer_2011.motors.json +88 -8
  73. data/lib/openstudio-standards/standards/deer/deer_2014/data/deer_2014.motors.json +88 -8
  74. data/lib/openstudio-standards/standards/deer/deer_2015/data/deer_2015.motors.json +88 -8
  75. data/lib/openstudio-standards/standards/deer/deer_2017/data/deer_2017.motors.json +88 -8
  76. data/lib/openstudio-standards/standards/deer/deer_2020/data/deer_2020.motors.json +88 -8
  77. data/lib/openstudio-standards/standards/deer/deer_2025/data/deer_2025.motors.json +88 -8
  78. data/lib/openstudio-standards/standards/deer/deer_2030/data/deer_2030.motors.json +88 -8
  79. data/lib/openstudio-standards/standards/deer/deer_2035/data/deer_2035.motors.json +88 -8
  80. data/lib/openstudio-standards/standards/deer/deer_2040/data/deer_2040.motors.json +88 -8
  81. data/lib/openstudio-standards/standards/deer/deer_2045/data/deer_2045.motors.json +88 -8
  82. data/lib/openstudio-standards/standards/deer/deer_2050/data/deer_2050.motors.json +88 -8
  83. data/lib/openstudio-standards/standards/deer/deer_2055/data/deer_2055.motors.json +88 -8
  84. data/lib/openstudio-standards/standards/deer/deer_2060/data/deer_2060.motors.json +88 -8
  85. data/lib/openstudio-standards/standards/deer/deer_2065/data/deer_2065.motors.json +88 -8
  86. data/lib/openstudio-standards/standards/deer/deer_2070/data/deer_2070.motors.json +88 -8
  87. data/lib/openstudio-standards/standards/deer/deer_2075/data/deer_2075.motors.json +88 -8
  88. data/lib/openstudio-standards/standards/deer/deer_pre_1975/data/deer_pre_1975.motors.json +88 -8
  89. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +17 -0
  90. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_systems.rb +2 -1
  91. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +4 -4
  92. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +61 -88
  93. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +3 -2
  94. data/lib/openstudio-standards/standards/necb/NECB2011/data/boiler_fuel_type_sets.json +54 -0
  95. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPMidriseApartment.osm +1 -1
  96. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPMultiTower.osm +1 -1
  97. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPPointTower.osm +1 -1
  98. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPTownHouse.osm +1 -1
  99. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernEducation.osm +4 -4
  100. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernHealthCare.osm +4 -4
  101. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +32 -24
  102. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +89 -15
  103. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +5 -1
  104. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +22 -65
  105. data/lib/openstudio-standards/standards/necb/NECB2011/system_fuels.rb +19 -0
  106. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +56 -2
  107. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +3 -1
  108. data/lib/openstudio-standards/standards/necb/common/construction_defaults.osm +2 -2
  109. data/lib/openstudio-standards/standards/necb/docs/air_system_names_method.md +127 -0
  110. data/lib/openstudio-standards/thermal_zone/thermal_zone.rb +1 -1
  111. data/lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb +1 -1
  112. data/lib/openstudio-standards/version.rb +1 -1
  113. data/lib/openstudio-standards/weather/information.rb +61 -5
  114. data/lib/openstudio-standards/weather/modify.rb +1 -1
  115. data/lib/openstudio-standards.rb +5 -3
  116. metadata +12 -63
  117. data/data/standards/OpenStudio_Standards-deer.xlsx +0 -0
  118. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +0 -1100
  119. data/lib/openstudio-standards/service_water_heating/component.rb +0 -189
@@ -19296,7 +19296,7 @@ OS:Building,
19296
19296
  4, !- Standards Number of Stories
19297
19297
  4, !- Standards Number of Above Ground Stories
19298
19298
  , !- Standards Template
19299
- , !- Standards Building Type
19299
+ LEEPTownHouse, !- Standards Building Type
19300
19300
  , !- Standards Number of Living Units
19301
19301
  , !- Relocatable
19302
19302
  ; !- Nominal Floor to Ceiling Height {m}
@@ -44366,7 +44366,7 @@ OS:Connection,
44366
44366
 
44367
44367
  OS:Schedule:Ruleset,
44368
44368
  {9d5b666a-4e1e-46b3-9d97-8c5c37fc3b63}, !- Handle
44369
- Water Heater Ambient Temp Schedule 70F, !- Name
44369
+ Water Heater Ambient Temp Schedule - 70F, !- Name
44370
44370
  {85e3f998-9b04-469c-b1ae-993d46032970}, !- Schedule Type Limits Name
44371
44371
  {74f82300-3fbb-4409-b504-cf26bb955cdb}, !- Default Day Schedule Name
44372
44372
  {756b8134-4003-4632-9ddb-72e4c2c884b6}, !- Summer Design Day Schedule Name
@@ -44374,7 +44374,7 @@ OS:Schedule:Ruleset,
44374
44374
 
44375
44375
  OS:Schedule:Day,
44376
44376
  {74f82300-3fbb-4409-b504-cf26bb955cdb}, !- Handle
44377
- Water Heater Ambient Temp Schedule 70F_Default, !- Name
44377
+ Water Heater Ambient Temp Schedule - 70F_Default, !- Name
44378
44378
  {85e3f998-9b04-469c-b1ae-993d46032970}, !- Schedule Type Limits Name
44379
44379
  , !- Interpolate to Timestep
44380
44380
  24, !- Hour 1
@@ -44383,7 +44383,7 @@ OS:Schedule:Day,
44383
44383
 
44384
44384
  OS:Schedule:Day,
44385
44385
  {756b8134-4003-4632-9ddb-72e4c2c884b6}, !- Handle
44386
- Water Heater Ambient Temp Schedule 70F_Summer_Design_Day, !- Name
44386
+ Water Heater Ambient Temp Schedule - 70F_Summer_Design_Day, !- Name
44387
44387
  {85e3f998-9b04-469c-b1ae-993d46032970}, !- Schedule Type Limits Name
44388
44388
  , !- Interpolate to Timestep
44389
44389
  24, !- Hour 1
@@ -44392,7 +44392,7 @@ OS:Schedule:Day,
44392
44392
 
44393
44393
  OS:Schedule:Day,
44394
44394
  {1016e14d-d134-44b4-8243-fef610fe7c9c}, !- Handle
44395
- Water Heater Ambient Temp Schedule 70F_Winter_Design_Day, !- Name
44395
+ Water Heater Ambient Temp Schedule - 70F_Winter_Design_Day, !- Name
44396
44396
  {85e3f998-9b04-469c-b1ae-993d46032970}, !- Schedule Type Limits Name
44397
44397
  , !- Interpolate to Timestep
44398
44398
  24, !- Hour 1
@@ -48651,7 +48651,7 @@ OS:Connection,
48651
48651
 
48652
48652
  OS:Schedule:Ruleset,
48653
48653
  {4f677daa-59d2-49b5-aa1a-6dd83e0b19bd}, !- Handle
48654
- Water Heater Ambient Temp Schedule 70F, !- Name
48654
+ Water Heater Ambient Temp Schedule - 70F, !- Name
48655
48655
  {85e3f998-9b04-469c-b1ae-993d46032970}, !- Schedule Type Limits Name
48656
48656
  {d34869e3-d524-49a8-be02-404ef50ddebd}, !- Default Day Schedule Name
48657
48657
  {1b0aa04d-8083-4db1-b00e-25f523c27ed6}, !- Summer Design Day Schedule Name
@@ -48659,7 +48659,7 @@ OS:Schedule:Ruleset,
48659
48659
 
48660
48660
  OS:Schedule:Day,
48661
48661
  {d34869e3-d524-49a8-be02-404ef50ddebd}, !- Handle
48662
- Water Heater Ambient Temp Schedule 70F_Default, !- Name
48662
+ Water Heater Ambient Temp Schedule - 70F_Default, !- Name
48663
48663
  {85e3f998-9b04-469c-b1ae-993d46032970}, !- Schedule Type Limits Name
48664
48664
  , !- Interpolate to Timestep
48665
48665
  24, !- Hour 1
@@ -48668,7 +48668,7 @@ OS:Schedule:Day,
48668
48668
 
48669
48669
  OS:Schedule:Day,
48670
48670
  {1b0aa04d-8083-4db1-b00e-25f523c27ed6}, !- Handle
48671
- Water Heater Ambient Temp Schedule 70F_Summer_Design_Day, !- Name
48671
+ Water Heater Ambient Temp Schedule - 70F_Summer_Design_Day, !- Name
48672
48672
  {85e3f998-9b04-469c-b1ae-993d46032970}, !- Schedule Type Limits Name
48673
48673
  , !- Interpolate to Timestep
48674
48674
  24, !- Hour 1
@@ -48677,7 +48677,7 @@ OS:Schedule:Day,
48677
48677
 
48678
48678
  OS:Schedule:Day,
48679
48679
  {96989d3c-9a1f-45e2-aa14-e96ed361f0b5}, !- Handle
48680
- Water Heater Ambient Temp Schedule 70F_Winter_Design_Day, !- Name
48680
+ Water Heater Ambient Temp Schedule - 70F_Winter_Design_Day, !- Name
48681
48681
  {85e3f998-9b04-469c-b1ae-993d46032970}, !- Schedule Type Limits Name
48682
48682
  , !- Interpolate to Timestep
48683
48683
  24, !- Hour 1
@@ -542,31 +542,38 @@ class NECB2011
542
542
  # Get the capacity
543
543
  capacity_w = boiler_hot_water_find_capacity(boiler_hot_water)
544
544
 
545
- # Check if secondary and/or modulating boiler required
546
- # If boiler names include 'Primary Boiler' or 'Secondary Boiler' then NECB rules are applied
547
545
  boiler_capacity = capacity_w
548
- if boiler_hot_water.name.to_s.include?('Primary Boiler') || boiler_hot_water.name.to_s.include?('Secondary Boiler')
549
- if capacity_w / 1000.0 >= 352.0
550
- if boiler_hot_water.name.to_s.include?('Primary Boiler')
551
- boiler_capacity = capacity_w
552
- boiler_hot_water.setBoilerFlowMode('LeavingSetpointModulated')
553
- boiler_hot_water.setMinimumPartLoadRatio(0.25)
554
- elsif boiler_hot_water.name.to_s.include?('Secondary Boiler')
555
- boiler_capacity = 0.001
556
- end
557
- elsif ((capacity_w / 1000.0) >= 176.0) && ((capacity_w / 1000.0) < 352.0)
558
- boiler_capacity = capacity_w / 2
559
- elsif (capacity_w / 1000.0) <= 176.0
560
- if boiler_hot_water.name.to_s.include?('Primary Boiler')
561
- if capacity_w <= 1.0
562
- boiler_capacity = 1.0
563
- else
546
+ # Use the NECB capacities if the SystemFuels class is not defined (i.e. this method was not called from something
547
+ # that created a SystemFuels object) or if either primary or secondary boiler capacity fractions are not defined.
548
+ if !self.fuel_type_set.is_a?(SystemFuels) || self.fuel_type_set.primary_boiler_cap_frac.nil? || self.fuel_type_set.secondary_boiler_cap_frac.nil?
549
+ # Check if secondary and/or modulating boiler required
550
+ # If boiler names include 'Primary Boiler' or 'Secondary Boiler' then NECB rules are applied
551
+ if boiler_hot_water.name.to_s.include?('Primary Boiler') || boiler_hot_water.name.to_s.include?('Secondary Boiler')
552
+ if capacity_w / 1000.0 >= 352.0
553
+ if boiler_hot_water.name.to_s.include?('Primary Boiler')
564
554
  boiler_capacity = capacity_w
555
+ boiler_hot_water.setBoilerFlowMode('LeavingSetpointModulated')
556
+ boiler_hot_water.setMinimumPartLoadRatio(0.25)
557
+ elsif boiler_hot_water.name.to_s.include?('Secondary Boiler')
558
+ boiler_capacity = 0.001
559
+ end
560
+ elsif ((capacity_w / 1000.0) >= 176.0) && ((capacity_w / 1000.0) < 352.0)
561
+ boiler_capacity = capacity_w / 2
562
+ elsif (capacity_w / 1000.0) <= 176.0
563
+ if boiler_hot_water.name.to_s.include?('Primary Boiler')
564
+ if capacity_w <= 1.0
565
+ boiler_capacity = 1.0
566
+ else
567
+ boiler_capacity = capacity_w
568
+ end
569
+ elsif boiler_hot_water.name.to_s.include?('Secondary Boiler')
570
+ boiler_capacity = 0.001
565
571
  end
566
- elsif boiler_hot_water.name.to_s.include?('Secondary Boiler')
567
- boiler_capacity = 0.001
568
572
  end
569
573
  end
574
+ else
575
+ boiler_capacity = capacity_w * self.fuel_type_set.primary_boiler_cap_frac if boiler_hot_water.name.to_s.include?('Primary Boiler')
576
+ boiler_capacity = capacity_w * self.fuel_type_set.secondary_boiler_cap_frac if boiler_hot_water.name.to_s.include?('Secondary Boiler')
570
577
  end
571
578
  boiler_hot_water.setNominalCapacity(boiler_capacity)
572
579
 
@@ -1117,7 +1124,7 @@ class NECB2011
1117
1124
  # This method will seem like an error in number of args..but this is due to swig voodoo.
1118
1125
  heat_pump_avail_sch_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(updated_heat_pump_avail_sch, 'Schedule:Constant', 'Schedule Value')
1119
1126
  heat_pump_avail_sch_prog = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
1120
- heat_pump_avail_sch_prog.setName("#{multi_speed_heat_pump.name.to_s.gsub(/[ +-.]/, '_')} Availability Schedule Program by Line")
1127
+ heat_pump_avail_sch_prog.setName("#{ems_friendly_name(multi_speed_heat_pump.name)} Availability Schedule Program by Line")
1121
1128
  heat_pump_avail_sch_prog_body = <<-EMS
1122
1129
  IF #{heat_pump_avail_sch_sensor.handle} > 0.0
1123
1130
  SET #{heat_pump_avail_sch_actuator.handle} = #{heat_pump_avail_sch_sensor.handle}
@@ -1129,7 +1136,7 @@ class NECB2011
1129
1136
  EMS
1130
1137
  heat_pump_avail_sch_prog.setBody(heat_pump_avail_sch_prog_body)
1131
1138
  pcm = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
1132
- pcm.setName("#{heat_pump_avail_sch_prog.name.to_s.gsub(/[ +-.]/, '_')} Calling Manager")
1139
+ pcm.setName("#{heat_pump_avail_sch_prog.name} Calling Manager")
1133
1140
  pcm.setCallingPoint('InsideHVACSystemIterationLoop')
1134
1141
  pcm.addProgram(heat_pump_avail_sch_prog)
1135
1142
  end
@@ -1650,6 +1657,7 @@ class NECB2011
1650
1657
  def setup_hw_loop_with_components(model,
1651
1658
  hw_loop,
1652
1659
  boiler_fueltype,
1660
+ backup_boiler_fueltype,
1653
1661
  pump_flow_sch)
1654
1662
  hw_loop.setName('Hot Water Loop')
1655
1663
  sizing_plant = hw_loop.sizingPlant
@@ -1671,7 +1679,7 @@ class NECB2011
1671
1679
  boiler1 = OpenStudio::Model::BoilerHotWater.new(model)
1672
1680
  boiler2 = OpenStudio::Model::BoilerHotWater.new(model)
1673
1681
  boiler1.setFuelType(boiler_fueltype)
1674
- boiler2.setFuelType(boiler_fueltype)
1682
+ boiler2.setFuelType(backup_boiler_fueltype)
1675
1683
  boiler1.setName('Primary Boiler')
1676
1684
  boiler2.setName('Secondary Boiler')
1677
1685
 
@@ -2178,7 +2186,7 @@ class NECB2011
2178
2186
  end
2179
2187
 
2180
2188
  # Method to set the base system name based on the following syntax:
2181
- # |sys_abbr|sys_oa|sc>?|sh>?|ssf>?|zh>?|zc>?|srf>?|
2189
+ # |sys_abbr|sys_oa|shr>?|sc>?|sh>?|ssf>?|zh>?|zc>?|srf>?|
2182
2190
  # "sys_abbr" designates the NECB system type ("sys_1, sys_2, ... sys_6")
2183
2191
  # "sys_oa": "mixed" or "doas"
2184
2192
  # "sys_name_pars" is a hash for the remaining system name parts for heat recovery,
@@ -16,7 +16,7 @@ class NECB2011 < Standard
16
16
  # This is a helper method to convert arguments that may support 'NECB_Default, and nils to convert to float'
17
17
  def convert_arg_to_f(variable:, default:)
18
18
  return variable if variable.kind_of?(Numeric)
19
- return default if variable.nil? || (variable == 'NECB_Default')
19
+ return default if variable.nil? || (variable.to_s == 'NECB_Default')
20
20
  return unless variable.kind_of?(String)
21
21
 
22
22
  variable = variable.strip
@@ -26,13 +26,25 @@ class NECB2011 < Standard
26
26
  # This method converts arguments to bool. Anything other than a bool false or string 'false' is converted
27
27
  # to a bool true. Bool false and case insesitive string false are turned into bool false.
28
28
  def convert_arg_to_bool(variable:, default:)
29
- return true if variable.nil?
29
+ return default if variable.nil?
30
30
  if variable.is_a? String
31
- return true if variable.to_s.downcase == 'necb_default'
31
+ return default if variable.to_s.downcase == 'necb_default'
32
32
  return false if variable.to_s.downcase == 'false'
33
+ return true if variable.to_s.downcase == 'true'
33
34
  end
34
35
  return false if variable == false
35
- return true
36
+ return variable
37
+ end
38
+
39
+ # This method checks if a variable is a string. If it is anything but a string it returns the default. If it is a
40
+ # string set to "NECB_Default" it return the default. Otherwise it returns the strirng set to it.
41
+ def convert_arg_to_string(variable:, default:)
42
+ return default if variable.nil?
43
+ if variable.is_a? String
44
+ return default if variable.to_s.downcase == 'necb_default'
45
+ return variable
46
+ end
47
+ return default
36
48
  end
37
49
 
38
50
  def get_standards_table(table_name:)
@@ -257,7 +269,9 @@ class NECB2011 < Standard
257
269
  baseline_system_zones_map_option: nil,
258
270
  tbd_option: nil,
259
271
  tbd_interpolate: false,
260
- necb_hdd: true)
272
+ necb_hdd: true,
273
+ boiler_fuel: nil,
274
+ boiler_cap_ratio: nil)
261
275
  model = load_building_type_from_library(building_type: building_type)
262
276
  return model_apply_standard(model: model,
263
277
  tbd_option: tbd_option,
@@ -317,9 +331,10 @@ class NECB2011 < Standard
317
331
  output_meters: output_meters,
318
332
  airloop_economizer_type: airloop_economizer_type, # (1) 'NECB_Default'/nil/' (2) 'DifferentialEnthalpy' (3) 'DifferentialTemperature'
319
333
  baseline_system_zones_map_option: baseline_system_zones_map_option, # Three options: (1) 'NECB_Default'/'none'/nil (i.e. 'one_sys_per_bldg'), (2) 'one_sys_per_dwelling_unit', (3) 'one_sys_per_bldg'
320
- necb_hdd: necb_hdd
334
+ necb_hdd: necb_hdd,
335
+ boiler_fuel: boiler_fuel,
336
+ boiler_cap_ratio: boiler_cap_ratio
321
337
  )
322
-
323
338
  end
324
339
 
325
340
  def load_building_type_from_library(building_type:)
@@ -394,14 +409,24 @@ class NECB2011 < Standard
394
409
  output_meters: nil,
395
410
  airloop_economizer_type: nil,
396
411
  baseline_system_zones_map_option: nil,
397
- necb_hdd: true)
412
+ necb_hdd: true,
413
+ boiler_fuel: nil,
414
+ boiler_cap_ratio: nil)
415
+
416
+ primary_heating_fuel = validate_primary_heating_fuel(primary_heating_fuel: primary_heating_fuel)
398
417
  self.fuel_type_set = SystemFuels.new()
399
418
  swh_fuel = swh_fuel.nil? ? 'NECB_Default' : swh_fuel.to_s
400
419
  self.fuel_type_set.set_defaults(standards_data: @standards_data, primary_heating_fuel: primary_heating_fuel, swh_fuel: swh_fuel)
420
+ swh_fuel = self.fuel_type_set.swh_fueltype if swh_fuel.to_s.downcase == 'necb_default'
401
421
  clean_and_scale_model(model: model, rotation_degrees: rotation_degrees, scale_x: scale_x, scale_y: scale_y, scale_z: scale_z)
402
422
  fdwr_set = convert_arg_to_f(variable: fdwr_set, default: -1)
403
423
  srr_set = convert_arg_to_f(variable: srr_set, default: -1)
404
424
  necb_hdd = convert_arg_to_bool(variable: necb_hdd, default: true)
425
+ boiler_fuel = convert_arg_to_string(variable: boiler_fuel, default: nil)
426
+ boiler_cap_ratio = convert_arg_to_string(variable: boiler_cap_ratio, default: nil)
427
+
428
+ boiler_cap_ratios = set_boiler_cap_ratios(boiler_cap_ratio: boiler_cap_ratio, boiler_fuel: boiler_fuel) unless boiler_cap_ratio.nil? && boiler_fuel.nil?
429
+ self.fuel_type_set.set_boiler_fuel(standards_data: @standards_data, boiler_fuel: boiler_fuel, boiler_cap_ratios: boiler_cap_ratios) unless boiler_fuel.nil?
405
430
 
406
431
  # Ensure the volume calculation in all spaces is done automatically
407
432
  model.getSpaces.sort.each do |space|
@@ -564,8 +589,6 @@ class NECB2011 < Standard
564
589
  ecm.apply_system_ecm(model: model,
565
590
  ecm_system_name: ecm_system_name,
566
591
  template_standard: self,
567
- primary_heating_fuel: self.fuel_type_set.ecm_fueltype,
568
- swh_fuel: self.fuel_type_set.ecm_fueltype,
569
592
  ecm_system_zones_map_option: ecm_system_zones_map_option)
570
593
 
571
594
  # -------- Performace, Efficiencies, Controls and Sensors ------------
@@ -1176,11 +1199,6 @@ class NECB2011 < Standard
1176
1199
  end
1177
1200
  end
1178
1201
 
1179
- # Determine whether or not water fixtures are attached to spaces
1180
- def model_attach_water_fixtures_to_spaces?(model)
1181
- return true
1182
- end
1183
-
1184
1202
  # Set the infiltration rate for this space to include
1185
1203
  # the impact of air leakage requirements in the standard.
1186
1204
  #
@@ -2417,4 +2435,60 @@ class NECB2011 < Standard
2417
2435
  return true
2418
2436
  end
2419
2437
 
2438
+ # This method is defined and used by the vintage classes to address he issue with the heat pump fuel types. This
2439
+ # method does nothing when creating NECB reference buildings.
2440
+ def validate_primary_heating_fuel(primary_heating_fuel:)
2441
+ return primary_heating_fuel
2442
+ end
2443
+
2444
+ # This method expects a string with the following pattern: number-number
2445
+ # The first number is the percent of the total capacity that the primary boiler's capacity will be set to.
2446
+ # The second number is the percent of the total capacity that the secondary boiler's capacity will be set to.
2447
+ # If no boiler_cap_ratio is provided the the primary boiler will have its capacity set to 75% of the total and the
2448
+ # secondary boiler will have its capacity set to 25% of the total. If a boiler_cap_ratio is set to '0_0' then the
2449
+ # NECB default capacities are assigned.
2450
+ def set_boiler_cap_ratios(boiler_cap_ratio:, boiler_fuel:)
2451
+ # Rules if boiler_fuel is defined
2452
+ unless boiler_fuel.nil?
2453
+ # Set the NECB default boiler capacities if the boiler_cap_ratio is set to '0-0'
2454
+ if boiler_cap_ratio == '0-0'
2455
+ boiler_cap_ratios = {
2456
+ primary_ratio: nil,
2457
+ secondary_ratio: nil
2458
+ }
2459
+ return boiler_cap_ratios
2460
+ elsif !boiler_fuel.to_s.downcase.include?('backup') && boiler_cap_ratio.nil?
2461
+ # Set the NECB default boiler capacities if the boiler_cap_ratio in not defined and the boiler fuel type is set
2462
+ # and the primary and secondary fuel types are the same.
2463
+ boiler_cap_ratios = {
2464
+ primary_ratio: nil,
2465
+ secondary_ratio: nil
2466
+ }
2467
+ return boiler_cap_ratios
2468
+ end
2469
+ end
2470
+ # Assuming the above rules do not apply, set the default boiler capacity ratio to 75% for the primary boiler and 25%
2471
+ # for the secondary boiler
2472
+ if boiler_cap_ratio.nil?
2473
+ boiler_cap_ratios = {
2474
+ primary_ratio: 0.75,
2475
+ secondary_ratio: 0.25
2476
+ }
2477
+ return boiler_cap_ratios
2478
+ end
2479
+ # If you defined the boiler capacity ratios set them accordingly.
2480
+ # Split the capacity ratio using the '-' symbol
2481
+ string_ratios = boiler_cap_ratio.to_s.split('-')
2482
+ # Turn the percentages into fractions
2483
+ primary_ratio = string_ratios[0].to_f/100.0
2484
+ secondary_ratio = string_ratios[1].to_f/100.0
2485
+ # Set the hash containg the ratios and return
2486
+ boiler_cap_ratios = {
2487
+ primary_ratio: primary_ratio,
2488
+ secondary_ratio: secondary_ratio
2489
+ }
2490
+ return boiler_cap_ratios
2491
+ end
2420
2492
  end
2493
+
2494
+
@@ -224,6 +224,10 @@ class NECB2011
224
224
  qaqc = {}
225
225
  qaqc[:sql_data] = get_sql_tables_to_json(model)
226
226
  error_warning = []
227
+ qaqc[:os_standards_revision] = OpenstudioStandards.git_revision
228
+ qaqc[:os_standards_version] = OpenstudioStandards::VERSION
229
+ qaqc[:openstudio_version] = os_version.strip
230
+ qaqc[:energyplus_version] = eplus_version.strip
227
231
  # Store Building data.
228
232
  qaqc[:building] = {}
229
233
  qaqc[:building][:name] = model.building.get.name.get
@@ -1919,7 +1923,7 @@ class NECB2011
1919
1923
  matches = nil
1920
1924
  # save a copy of the headers
1921
1925
  headers = nil
1922
- CSV.open(csv_fname, 'r', options) do |csv|
1926
+ CSV.open(csv_fname, 'r', **options) do |csv|
1923
1927
  # Since CSV includes Enumerable we can use 'find_all'
1924
1928
  # which will return all the elements of the Enumerble for
1925
1929
  # which the block returns true
@@ -21,77 +21,34 @@ class NECB2011
21
21
  # Add the main service water heating loop
22
22
  shw_pump_motor_eff = 0.9
23
23
 
24
- main_swh_loop = model_add_swh_loop(model,
25
- 'Main Service Water Loop',
26
- nil,
27
- shw_sizing['max_temp_SI'],
28
- shw_pump_head,
29
- shw_pump_motor_eff,
30
- shw_sizing['tank_capacity_SI'],
31
- shw_sizing['tank_volume_SI'],
32
- swh_fueltype,
33
- shw_sizing['parasitic_loss'],
34
- nil)
24
+ main_swh_loop = OpenstudioStandards::ServiceWaterHeating.create_service_water_heating_loop(model,
25
+ system_name: 'Main Service Water Loop',
26
+ service_water_temperature: shw_sizing['max_temp_SI'],
27
+ service_water_pump_head: shw_pump_head,
28
+ service_water_pump_motor_efficiency: shw_pump_motor_eff,
29
+ water_heater_capacity: shw_sizing['tank_capacity_SI'],
30
+ water_heater_volume: shw_sizing['tank_volume_SI'],
31
+ water_heater_fuel: swh_fueltype,
32
+ on_cycle_parasitic_fuel_consumption_rate: shw_sizing['parasitic_loss'],
33
+ off_cycle_parasitic_fuel_consumption_rate: shw_sizing['parasitic_loss'])
35
34
 
36
35
  # Note that when water use equipment is assigned to spaces then the water used by the equipment is multiplied by
37
36
  # the space (ultimately thermal zone) multiplier. Note that there is a separate water use equipment multiplier
38
37
  # as well which is different than the space (ultimately thermal zone) multiplier.
39
- shw_sizing['spaces_w_dhw'].each { |space| model_add_swh_end_uses_by_spaceonly(model, space, main_swh_loop) }
38
+ shw_sizing['spaces_w_dhw'].each do |space|
39
+ OpenstudioStandards::ServiceWaterHeating.create_water_use(model,
40
+ name: "#{space['shw_spaces'].name.get.capitalize}",
41
+ flow_rate: space['shw_peakflow_ind_SI'],
42
+ flow_rate_fraction_schedule: model_add_schedule(model, space['shw_sched']),
43
+ water_use_temperature: space['shw_temp_SI'],
44
+ service_water_loop: main_swh_loop,
45
+ space: space['shw_spaces'])
46
+ end
40
47
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding Service Water Heating')
41
48
 
42
49
  return true
43
50
  end
44
51
 
45
- # This method will add an swh water fixture to the model for the space.
46
- # if the it will return a water fixture object, or NIL if there is no water load at all.
47
- #
48
- # @param model [OpenStudio::Model::Model] OpenStudio model object
49
- # @param space [Hash] hash of shw space information
50
- # @param swh_loop [OpenStudio::Model::PlantLoop] plant loop to add swh
51
- # @return [OpenStudio::Model::WaterUseEquipment] water use equipment
52
- def model_add_swh_end_uses_by_spaceonly(model, space, swh_loop)
53
- # Water use connection
54
- swh_connection = OpenStudio::Model::WaterUseConnections.new(model)
55
-
56
- # Water fixture definition
57
- water_fixture_def = OpenStudio::Model::WaterUseEquipmentDefinition.new(model)
58
-
59
- # water_use_sensible_frac_sch = OpenStudio::Model::ScheduleConstant.new(self)
60
- # water_use_sensible_frac_sch.setValue(0.2)
61
- # water_use_latent_frac_sch = OpenStudio::Model::ScheduleConstant.new(self)
62
- # water_use_latent_frac_sch.setValue(0.05)
63
- # Note that when water use equipment is assigned to spaces then the water used by the equipment is multiplied by the
64
- # space (ultimately thermal zone) multiplier. Note that there is a separate water use equipment multiplier as well
65
- # which is different than the space (ultimately thermal zone) multiplier.
66
- rated_flow_rate_gal_per_min = OpenStudio.convert(space['shw_peakflow_ind_SI'], 'm^3/s', 'gal/min').get
67
- water_use_sensible_frac_sch = OpenStudio::Model::ScheduleRuleset.new(model)
68
- water_use_sensible_frac_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 0.2)
69
- water_use_latent_frac_sch = OpenStudio::Model::ScheduleRuleset.new(model)
70
- water_use_latent_frac_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 0.05)
71
- water_fixture_def.setSensibleFractionSchedule(water_use_sensible_frac_sch)
72
- water_fixture_def.setLatentFractionSchedule(water_use_latent_frac_sch)
73
- water_fixture_def.setPeakFlowRate(space['shw_peakflow_ind_SI'])
74
- water_fixture_def.setName("#{space['shw_spaces'].name.to_s.capitalize} Service Water Use Def #{rated_flow_rate_gal_per_min.round(2)}gal/min")
75
- # Target mixed water temperature
76
- mixed_water_temp_c = space['shw_temp_SI']
77
- mixed_water_temp_sch = OpenStudio::Model::ScheduleRuleset.new(model)
78
- mixed_water_temp_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), mixed_water_temp_c)
79
- water_fixture_def.setTargetTemperatureSchedule(mixed_water_temp_sch)
80
-
81
- # Water use equipment
82
- water_fixture = OpenStudio::Model::WaterUseEquipment.new(water_fixture_def)
83
- schedule = model_add_schedule(model, space['shw_sched'])
84
- water_fixture.setFlowRateFractionSchedule(schedule)
85
- water_fixture.setName("#{space['shw_spaces'].name.to_s.capitalize} Service Water Use #{rated_flow_rate_gal_per_min.round(2)}gal/min")
86
- swh_connection.addWaterUseEquipment(water_fixture)
87
- # Assign water fixture to a space
88
- water_fixture.setSpace(space['shw_spaces']) if model_attach_water_fixtures_to_spaces?(model)
89
-
90
- # Connect the water use connection to the SWH loop
91
- swh_loop.addDemandBranchForComponent(swh_connection)
92
- return water_fixture
93
- end
94
-
95
52
  # add swh
96
53
 
97
54
  # Applies the standard efficiency ratings and typical losses and paraisitic loads to this object.
@@ -476,9 +433,9 @@ class NECB2011
476
433
  # space that has a demand for shw. It calculates the x, y, and z components of the vector between the shw space and the
477
434
  # spaces with demand for shw. The distance of the piping run is calculated by adding the x, y, and z components of the
478
435
  # vector (rather than the magnitude of the vector). For the purposes of calculating pressure loss along the pipe bends,
479
- # and other minor losses are accounted by doubling the calculated length of the pipe. The default kinematic viscosity
480
- # of water is assumed to be that at 60 C (in m^2/s). The default density of water is assumed to be 983 kg/m^3 as per
481
- # https://hypertextbook.com/facts/2007/AllenMa.shtml accessed 2018-07-27. The pipe is assumed to be made out of PVC and
436
+ # and other minor losses are accounted by doubling the calculated length of the pipe. The default kinematic viscosity
437
+ # of water is assumed to be that at 60 C (in m^2/s). The default density of water is assumed to be 983 kg/m^3 as per
438
+ # https://hypertextbook.com/facts/2007/AllenMa.shtml accessed 2018-07-27. The pipe is assumed to be made out of PVC and
482
439
  # have a roughness height of 1.5*10^-6 m as per:
483
440
  # www.pipeflow.com/pipe-pressure-drop-calculations/pipe-roughness accessed on 2018-07-25.
484
441
  # The default maximum velocity is from the table from 'The Engineering Toolbox' link:
@@ -1,6 +1,9 @@
1
1
  class SystemFuels
2
2
  attr_accessor :name
3
3
  attr_accessor :boiler_fueltype
4
+ attr_accessor :backup_boiler_fueltype
5
+ attr_accessor :primary_boiler_cap_frac
6
+ attr_accessor :secondary_boiler_cap_frac
4
7
  attr_accessor :baseboard_type
5
8
  attr_accessor :mau_type
6
9
  attr_accessor :mau_heating_coil_type
@@ -23,6 +26,9 @@ class SystemFuels
23
26
  # Assign fuel sources.
24
27
  @name = system_fuel_defaults['name']
25
28
  @boiler_fueltype = system_fuel_defaults['boiler_fueltype']
29
+ @backup_boiler_fueltype = system_fuel_defaults['boiler_fueltype']
30
+ @primary_boiler_cap_frac = nil
31
+ @secondary_boiler_cap_frac = nil
26
32
  @baseboard_type = system_fuel_defaults['baseboard_type']
27
33
  @mau_type = system_fuel_defaults['mau_type']
28
34
  @mau_cooling_type = system_fuel_defaults['mau_cooling_type']
@@ -37,4 +43,17 @@ class SystemFuels
37
43
  @swh_fueltype = system_fuel_defaults['swh_fueltype']
38
44
  @ecm_fueltype = system_fuel_defaults['ecm_fueltype']
39
45
  end
46
+
47
+ # Forces a boiler to be generated. It searches boiler_fuel_type_sets.json for the boiler_fuel string and sets the
48
+ # primary and backup boiler fuels to be whatever is boiler fuel type set.
49
+ def set_boiler_fuel(standards_data:, boiler_fuel:, boiler_cap_ratios:)
50
+ boiler_fuel_defaults = standards_data['boiler_fuel_type_sets'].detect { |fuel_type_set| fuel_type_set['name'] == boiler_fuel }
51
+ @boiler_fueltype = boiler_fuel_defaults['boiler_fueltype']
52
+ @primary_boiler_cap_frac = boiler_cap_ratios[:primary_ratio]
53
+ @backup_boiler_fueltype = boiler_fuel_defaults['backup_boiler_fueltype']
54
+ @secondary_boiler_cap_frac = boiler_cap_ratios[:secondary_ratio]
55
+ @baseboard_type = boiler_fuel_defaults['baseboard_type']
56
+ @mau_heating_coil_type = boiler_fuel_defaults['mau_heating_coil_type'] unless @mau_heating_coil_type == 'DX'
57
+ @heating_coil_type_sys6 = boiler_fuel_defaults['heating_coil_type_sys6']
58
+ end
40
59
  end
@@ -2075,8 +2075,62 @@ class BTAPData
2075
2075
  dehumidification_degree_days = OpenstudioStandards::Weather.epw_file_get_dehumidification_degree_days(epw_file)
2076
2076
 
2077
2077
  ### annual global horizontal irradiance (GHI)
2078
- ghi_timeseries = epw_file.getTimeSeries('Global Horizontal Radiation').get
2079
- annual_ghi_kwh_per_m_sq = ghi_timeseries.values.sum / 1000.0
2078
+
2079
+ # Workaround for case when the weather file contains the February from a leap year but that February only has 28
2080
+ # days of data.
2081
+ has_leap_day = false
2082
+
2083
+ # Find the first day in February
2084
+ feb_index = epw_file.data.find_index { |entry| entry.date.monthOfYear.value == 2 }
2085
+
2086
+ # Find the year for February
2087
+ feb_year = epw_file.data[feb_index].year
2088
+ # Determine if February's year is a leap year
2089
+ leap_year = false
2090
+ if (feb_year % 100) > 0
2091
+ leap_year = true if (feb_year % 4) == 0
2092
+ else
2093
+ leap_year = true if (feb_year % 400) == 0
2094
+ end
2095
+ # If the February is from a leap year determine if it contains a leap day
2096
+ if leap_year
2097
+
2098
+ day = epw_file.data[feb_index].date.dayOfMonth
2099
+ inc = 0
2100
+
2101
+ while epw_file.data[feb_index].date.dayOfMonth == day
2102
+ feb_index += 1
2103
+ inc += 1
2104
+ end
2105
+
2106
+ has_leap_day = epw_file.data[feb_index + (inc * 28)].date.dayOfMonth == 29
2107
+ end
2108
+
2109
+ # If the February is from a leap year and there is no leap day then do not use the faulty OpenStudio Epw
2110
+ # .getTimeSeries method. Otherwise, use the method.
2111
+ if has_leap_day || !leap_year
2112
+ ghi_timeseries = epw_file.getTimeSeries('Global Horizontal Radiation').get.values
2113
+ else
2114
+ # Access the data directly instead of using the OpenStudio API to avoid the faulty OpenStudioEpw
2115
+ # .getTimeSeries method.
2116
+
2117
+ # Open the weather file
2118
+ regex_csv = /[^,]+/
2119
+ regex_num = /[0-9]/
2120
+ f = File.open(epw_file.path.to_s, 'r')
2121
+ i = 0
2122
+
2123
+ # Skip the header
2124
+ i += 1 until f.readline[0] =~ regex_num
2125
+
2126
+ # Get all of the hourly weather data
2127
+ lines = IO.readlines(f)[i..-1]
2128
+
2129
+ # Get hourly weather data for a specific column
2130
+ ghi_timeseries = lines.map {|line| Float(line.scan(regex_csv)[13])}
2131
+ end
2132
+
2133
+ annual_ghi_kwh_per_m_sq = ghi_timeseries.sum / 1000.0
2080
2134
 
2081
2135
  ### THD-1 Temperature at the colder of the two heating design conditions in PHIUS, 2021
2082
2136
  ### ('Heating design temperature' in REF: Wright (2019))
@@ -176,7 +176,9 @@ class BTAPDatapoint
176
176
  shw_scale: @options[:shw_scale],
177
177
  baseline_system_zones_map_option: @options[:baseline_system_zones_map_option],
178
178
  tbd_option: @options[:tbd_option],
179
- necb_hdd: @options[:necb_hdd]
179
+ necb_hdd: @options[:necb_hdd],
180
+ boiler_fuel: @options[:boiler_fuel],
181
+ boiler_cap_ratio: @options[:boiler_cap_ratio]
180
182
  )
181
183
  end
182
184
 
@@ -1928,13 +1928,13 @@ OS:Schedule:Day,
1928
1928
 
1929
1929
  OS:Schedule:Ruleset,
1930
1930
  {402721ef-5979-4bdf-8041-e590c3fe0060}, !- Handle
1931
- Water Heater Ambient Temp Schedule 70F, !- Name
1931
+ Water Heater Ambient Temp Schedule - 70F, !- Name
1932
1932
  {7b49cd38-34d6-4fe8-8f95-f7546eac6e94}, !- Schedule Type Limits Name
1933
1933
  {5d1da6bc-bb9e-4fd7-930d-a079c77f9584}; !- Default Day Schedule Name
1934
1934
 
1935
1935
  OS:Schedule:Day,
1936
1936
  {5d1da6bc-bb9e-4fd7-930d-a079c77f9584}, !- Handle
1937
- Water Heater Ambient Temp Schedule 70F Default, !- Name
1937
+ Water Heater Ambient Temp Schedule - 70F Default, !- Name
1938
1938
  {7b49cd38-34d6-4fe8-8f95-f7546eac6e94}, !- Schedule Type Limits Name
1939
1939
  , !- Interpolate to Timestep
1940
1940
  24, !- Hour 1