openstudio-standards 0.2.15 → 0.2.16.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/data/geometry/ASHRAEHighriseApartment.osm +0 -27
  3. data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
  4. data/data/standards/OpenStudio_Standards-ashrae_90_1_28Jan2022.xlsx +0 -0
  5. data/data/standards/test_performance_expected_dd_results.csv +710 -710
  6. data/lib/openstudio-standards/btap/btap_result.rb +2 -2
  7. data/lib/openstudio-standards/btap/reporting.rb +2 -2
  8. data/lib/openstudio-standards/btap/simmanager.rb +2 -2
  9. data/lib/openstudio-standards/hvac_sizing/Siz.ControllerOutdoorAir.rb +0 -54
  10. data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +11 -1
  11. data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +1 -1
  12. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +26 -5
  13. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +35 -16
  14. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +23 -10
  15. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +36 -0
  16. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +6 -6
  17. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +0 -3
  18. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +2 -2
  19. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +9 -3
  20. data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +2 -0
  21. data/lib/openstudio-standards/standards/Standards.Construction.rb +12 -6
  22. data/lib/openstudio-standards/standards/Standards.Model.rb +38 -7
  23. data/lib/openstudio-standards/standards/Standards.Space.rb +1 -1
  24. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +7 -0
  25. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +32 -11
  26. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +22 -742
  27. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_sets.json +2 -2
  28. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.prototype_inputs.json +3 -3
  29. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +6 -6
  30. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +19 -559
  31. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_sets.json +2 -2
  32. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.prototype_inputs.json +3 -3
  33. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +6 -6
  34. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +19 -559
  35. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_sets.json +2 -2
  36. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.prototype_inputs.json +5 -5
  37. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +7 -7
  38. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +19 -559
  39. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_sets.json +2 -2
  40. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.prototype_inputs.json +5 -5
  41. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +7 -7
  42. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +370 -910
  43. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_sets.json +2 -2
  44. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.prototype_inputs.json +6 -6
  45. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_system.json +0 -8
  46. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.spc_typ.json +12 -12
  47. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +19 -6
  48. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +2380 -1300
  49. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_sets.json +2 -2
  50. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.prototype_inputs.json +6 -6
  51. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_system.json +0 -8
  52. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.spc_typ.json +12 -12
  53. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +140 -0
  54. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.schedules.json +1176 -312
  55. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.construction_properties.json +172 -1132
  56. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.construction_sets.json +14 -14
  57. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.prototype_inputs.json +2 -2
  58. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.spc_typ.json +9 -9
  59. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.construction_properties.json +180 -1140
  60. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.construction_sets.json +14 -14
  61. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.prototype_inputs.json +2 -2
  62. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.spc_typ.json +10 -10
  63. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.construction_properties.json +9 -9
  64. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.construction_properties.json +9 -9
  65. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +12 -6
  66. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +12 -6
  67. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +16 -8
  68. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +10 -20
  69. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +209 -37
  70. data/lib/openstudio-standards/standards/necb/ECMS/loads.rb +1 -0
  71. data/lib/openstudio-standards/standards/necb/ECMS/pv_ground.rb +8 -6
  72. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +16 -9
  73. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/HighriseApartment.osm +1 -1
  74. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LowriseApartment.osm +1 -1
  75. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/MidriseApartment.osm +1 -1
  76. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_multi_speed.rb +9 -5
  77. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +10 -6
  78. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +9 -5
  79. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +14 -8
  80. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +14 -8
  81. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +13 -6
  82. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +12 -6
  83. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +4 -2
  84. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +38 -19
  85. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +2 -2
  86. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +15 -4
  87. data/lib/openstudio-standards/standards/necb/NECB2020/building_envelope.rb +10 -651
  88. data/lib/openstudio-standards/standards/necb/NECB2020/necb_2020.rb +8 -38
  89. data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +159 -0
  90. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +41 -43
  91. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +7 -4
  92. data/lib/openstudio-standards/version.rb +1 -1
  93. data/lib/openstudio-standards.rb +1 -0
  94. metadata +4 -2
@@ -1,13 +1,13 @@
1
1
  # This class holds methods that apply NECB2020 rules.
2
2
 
3
3
  # Notes for adding new version of NECB:
4
- # Essentially all you need to do is copy this file to a new folder and update the class name. Only add json files and other rb
5
- # files if the content has changed. Do not forget to update the class name in the rb files.
4
+ # Essentially all you need to do is copy this file to a new folder and update the class name (only the initialize and load_standards_database_new methods are required,
5
+ # everything else will be inherited. Only add methods, json files and other rb files if the content/functionality has changed. Do not forget to update the class name in the rb files!
6
6
  # The spacetypes and led lighting json files are required (in the data folder) as they have the NECB version hardcoded (which requires updating).
7
7
  # However there are a few other files to update:
8
8
  # 1) NECB2011/necb_2011.rb:determine_spacetype_vintage method has an array of available versions of NECB hardcoded. Add the new one.
9
9
  # 2) common/space_type_upgrade_map.json needs all the space types for the new version defined (386 in NECB 2020).
10
- # 3) Add references to the new rb files in openstudio_standards.rb
10
+ # 3) Add references to the rb files in this folder to openstudio_standards.rb
11
11
 
12
12
  # @ref [References::NECB2020]
13
13
  class NECB2020 < NECB2017
@@ -21,8 +21,8 @@ class NECB2020 < NECB2017
21
21
  self.corrupt_standards_database()
22
22
  end
23
23
 
24
- def load_standards_database_new()
25
- #load NECB2017 data.
24
+ def load_standards_database_new
25
+ # load NECB2020 data.
26
26
  super()
27
27
 
28
28
  if __dir__[0] == ':' # Running from OpenStudio CLI
@@ -37,7 +37,7 @@ class NECB2020 < NECB2017
37
37
  end
38
38
  end
39
39
  else
40
- files = Dir.glob("#{File.dirname(__FILE__)}/data/*.json").select {|e| File.file? e}
40
+ files = Dir.glob("#{File.dirname(__FILE__)}/data/*.json").select { |e| File.file? e }
41
41
  files.each do |file|
42
42
  data = JSON.parse(File.read(file))
43
43
  if !data['tables'].nil?
@@ -49,41 +49,11 @@ class NECB2020 < NECB2017
49
49
  end
50
50
  end
51
51
  end
52
- #Write test report file.
52
+ # Write test report file.
53
53
  # Write database to file.
54
- # File.open(File.join(File.dirname(__FILE__), '..', 'NECB2020.json'), 'w') {|f| f.write(JSON.pretty_generate(@standards_data))}
55
-
54
+ # File.open(File.join(File.dirname(__FILE__), '..', 'NECB2017.json'), 'w') {|f| f.write(JSON.pretty_generate(@standards_data))}
56
55
  return @standards_data
57
56
  end
58
-
59
- def set_lighting_per_area_led_lighting(space_type:, definition:, lighting_per_area_led_lighting:, lights_scale:)
60
-
61
- # puts "#{space_type.name.to_s} - 'space_height' - #{space_height.to_s}"
62
- #TODO: Note that 'occ_sens_lpd_frac' in this function has been removed for NECB2015 and 2017.
63
- # ##### Since Atrium's LPD for LED lighting depends on atrium's height, the height of the atrium (if applicable) should be found.
64
- standards_space_type = space_type.standardsSpaceType.is_initialized ? space_type.standardsSpaceType.get : nil #Sara
65
- if standards_space_type.include? 'Atrium' # TODO: Note that since none of the archetypes has Atrium, this was tested for 'Dining'. #Atrium
66
- puts "#{standards_space_type} - has atrium" # space_type.name.to_s
67
- # puts space_height
68
- if get_max_space_height_for_space_type(space_type: space_type) < 12.0
69
- # TODO: Regarding the below equations, identify which version of ASHRAE 90.1 was used in NECB2017.
70
- atrium_lpd_eq_smaller_12_intercept = 0
71
- atrium_lpd_eq_smaller_12_slope = 1.06
72
- atrium_lpd_eq_larger_12_intercept = 4.3
73
- atrium_lpd_eq_larger_12_slope = 0.71
74
- lighting_per_area_led_lighting_atrium = (atrium_lpd_eq_smaller_12_intercept + atrium_lpd_eq_smaller_12_slope * space_height) * 0.092903 # W/ft2
75
- else # i.e. get_max_space_height_for_space_type >= 12.0
76
- lighting_per_area_led_lighting_atrium = (atrium_lpd_eq_larger_12_intercept + atrium_lpd_eq_larger_12_slope * space_height) * 0.092903 # W/ft2
77
- end
78
- puts "#{standards_space_type} - has lighting_per_area_led_lighting_atrium - #{lighting_per_area_led_lighting_atrium}"
79
- lighting_per_area_led_lighting = lighting_per_area_led_lighting_atrium
80
- end
81
- lighting_per_area_led_lighting *= lights_scale
82
-
83
- definition.setWattsperSpaceFloorArea(OpenStudio.convert(lighting_per_area_led_lighting.to_f, 'W/ft^2', 'W/m^2').get)
84
-
85
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.SpaceType', "#{space_type.name} set LPD to #{lighting_per_area_led_lighting} W/ft^2.")
86
- end
87
57
 
88
58
  # Set the infiltration rate for this space to include
89
59
  # the impact of air leakage requirements in the standard.
@@ -0,0 +1,159 @@
1
+ class NECB2020
2
+
3
+ # Applies the standard efficiency ratings and typical losses and paraisitic loads to this object.
4
+ # Efficiency and skin loss coefficient (UA)
5
+ # Per PNNL http://www.energycodes.gov/sites/default/files/documents/PrototypeModelEnhancements_2014_0.pdf
6
+ # Appendix A: Service Water Heating
7
+ #
8
+ # @return [Bool] true if successful, false if not
9
+ #
10
+ # This was modified in PCF 1630
11
+ #
12
+ def water_heater_mixed_apply_efficiency(water_heater_mixed)
13
+ # Get the capacity of the water heater
14
+ # TODO add capability to pull autosized water heater capacity
15
+ # if the Sizing:WaterHeater object is ever implemented in OpenStudio.
16
+ capacity_w = water_heater_mixed.heaterMaximumCapacity
17
+ if capacity_w.empty?
18
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.WaterHeaterMixed', "For #{water_heater_mixed.name}, cannot find capacity, standard will not be applied.")
19
+ return false
20
+ else
21
+ capacity_w = capacity_w.get
22
+ end
23
+ capacity_btu_per_hr = OpenStudio.convert(capacity_w, 'W', 'Btu/hr').get
24
+ capacity_kbtu_per_hr = OpenStudio.convert(capacity_w, 'W', 'kBtu/hr').get
25
+
26
+ # Get the volume of the water heater
27
+ # TODO add capability to pull autosized water heater volume
28
+ # if the Sizing:WaterHeater object is ever implemented in OpenStudio.
29
+ volume_m3 = water_heater_mixed.tankVolume
30
+ if volume_m3.empty?
31
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.WaterHeaterMixed', "For #{water_heater_mixed.name}, cannot find volume, standard will not be applied.")
32
+ return false
33
+ else
34
+ volume_m3 = volume_m3.get
35
+ end
36
+ volume_gal = OpenStudio.convert(volume_m3, 'm^3', 'gal').get
37
+
38
+ # Get the heater fuel type
39
+ fuel_type = water_heater_mixed.heaterFuelType
40
+ unless fuel_type == 'NaturalGas' || fuel_type == 'Electricity' || fuel_type == 'FuelOilNo2'
41
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.WaterHeaterMixed', "For #{water_heater_mixed.name}, fuel type of #{fuel_type} is not yet supported, standard will not be applied.")
42
+ end
43
+
44
+ # Calculate the water heater efficiency and
45
+ # skin loss coefficient (UA)
46
+ # Calculate the energy factor (EF)
47
+ # From PNNL http://www.energycodes.gov/sites/default/files/documents/PrototypeModelEnhancements_2014_0.pdf
48
+ # Appendix A: Service Water Heating
49
+ # and modified by PCF 1630 as noted below.
50
+ water_heater_eff = nil
51
+ ua_btu_per_hr_per_f = nil
52
+ sl_btu_per_hr = nil
53
+ case fuel_type
54
+ when 'Electricity'
55
+ volume_l_per_s = volume_m3 * 1000
56
+ if capacity_btu_per_hr <= OpenStudio.convert(12, 'kW', 'Btu/hr').get
57
+ # Fixed water heater efficiency per PNNL
58
+ water_heater_eff = 1
59
+ # Calculate the max allowable standby loss (SL)
60
+ sl_w = if volume_l_per_s < 270
61
+ 40 + 0.2 * volume_l_per_s # assume bottom inlet
62
+ else
63
+ 0.472 * volume_l_per_s - 33.5
64
+ # assume bottom inlet
65
+ end
66
+ sl_btu_per_hr = OpenStudio.convert(sl_w, 'W', 'Btu/hr').get
67
+ else
68
+ # Fixed water heater efficiency per PNNL
69
+ water_heater_eff = 1
70
+ # Calculate the max allowable standby loss (SL) # use this - NECB does not give SL calculation for cap > 12 kW
71
+ sl_btu_per_hr = 20 + (35 * Math.sqrt(volume_gal))
72
+ end
73
+ # Calculate the skin loss coefficient (UA)
74
+ ua_btu_per_hr_per_f = sl_btu_per_hr / 70
75
+ when 'NaturalGas'
76
+ volume_l = volume_m3 / 1000
77
+ if capacity_btu_per_hr <= 75_000
78
+ # Fixed water heater thermal efficiency per PNNL
79
+ water_heater_eff = 0.82
80
+
81
+ # Calculate the minimum Energy Factor (EF) (This was introduced in PCF 1630)
82
+ if volume_l < 68
83
+ uef = 0.5982 - 0.0005 * volume_l
84
+ ef = 1.0005 * uef + 0.0019
85
+ elsif volume_l >= 68 and volume_l < 193
86
+ uef = 0.6483 - 0.00045 * volume_l
87
+ ef = 1.0005 * uef + 0.0019
88
+ elsif volume_l >= 193 and volume_l < 284
89
+ uef = 0.692 - 0.00034 * volume_l
90
+ ef = 1.0005 * uef + 0.0019
91
+ end
92
+
93
+ # Calculate the Recovery Efficiency (RE)
94
+ # based on a fixed capacity of 75,000 Btu/hr
95
+ # and a fixed volume of 40 gallons by solving
96
+ # this system of equations:
97
+ # ua = (1/.95-1/re)/(67.5*(24/41094-1/(re*cap)))
98
+ # 0.82 = (ua*67.5+cap*re)/cap
99
+ cap = 75_000.0
100
+ re = (Math.sqrt(6724 * ef**2 * cap**2 + 40_409_100 * ef**2 * cap - 28_080_900 * ef * cap + 29_318_000_625 * ef**2 - 58_636_001_250 * ef + 29_318_000_625) + 82 * ef * cap + 171_225 * ef - 171_225) / (200 * ef * cap)
101
+
102
+ # Calculate the skin loss coefficient (UA)
103
+ # based on the actual capacity.
104
+ ua_btu_per_hr_per_f = (water_heater_eff - re) * capacity_btu_per_hr / 67.5
105
+
106
+ # This capacity band was introduced in PCF 1630
107
+ elsif capacity_btu_per_hr > 75_000 and capacity_btu_per_hr < 103977 and volume_l < 454
108
+ water_heater_eff = 0.82
109
+ uef = 0.8107 - 0.00021 * volume_l
110
+ ef = 1.0005 * uef + 0.0019
111
+ cap = 103977
112
+ re = (Math.sqrt(6724 * ef**2 * cap**2 + 40_409_100 * ef**2 * cap - 28_080_900 * ef * cap + 29_318_000_625 * ef**2 - 58_636_001_250 * ef + 29_318_000_625) + 82 * ef * cap + 171_225 * ef - 171_225) / (200 * ef * cap)
113
+
114
+ # Calculate the skin loss coefficient (UA)
115
+ # based on the actual capacity.
116
+ ua_btu_per_hr_per_f = (water_heater_eff - re) * capacity_btu_per_hr / 67.5
117
+ else
118
+ # Thermal efficiency (PCF 1630 update)
119
+ et = 0.9
120
+ sl_w = 0.84 * capacity_btu_per_hr / 3412.412 / 0.234 + 16.57 * (volume_l ** 0.5)
121
+ sl_btu_per_hr = sl_w * 3.412
122
+ # Calculate the skin loss coefficient (UA)
123
+ ua_btu_per_hr_per_f = (sl_btu_per_hr * et) / 70
124
+ # Calculate water heater efficiency
125
+ water_heater_eff = (ua_btu_per_hr_per_f * 70 + capacity_btu_per_hr * et) / capacity_btu_per_hr
126
+ end
127
+ end
128
+
129
+ # Convert to SI
130
+ ua_btu_per_hr_per_c = OpenStudio.convert(ua_btu_per_hr_per_f, 'Btu/hr*R', 'W/K').get
131
+
132
+ # Set the water heater properties
133
+ # Efficiency
134
+ water_heater_mixed.setHeaterThermalEfficiency(water_heater_eff)
135
+ # Skin loss
136
+ water_heater_mixed.setOffCycleLossCoefficienttoAmbientTemperature(ua_btu_per_hr_per_c)
137
+ water_heater_mixed.setOnCycleLossCoefficienttoAmbientTemperature(ua_btu_per_hr_per_c)
138
+ # TODO: Parasitic loss (pilot light)
139
+ # PNNL document says pilot lights were removed, but IDFs
140
+ # still have the on/off cycle parasitic fuel consumptions filled in
141
+ water_heater_mixed.setOnCycleParasiticFuelType(fuel_type)
142
+ # self.setOffCycleParasiticFuelConsumptionRate(??)
143
+ water_heater_mixed.setOnCycleParasiticHeatFractiontoTank(0)
144
+ water_heater_mixed.setOffCycleParasiticFuelType(fuel_type)
145
+ # self.setOffCycleParasiticFuelConsumptionRate(??)
146
+ water_heater_mixed.setOffCycleParasiticHeatFractiontoTank(0.8)
147
+
148
+ # set part-load performance curve
149
+ if (fuel_type == 'NaturalGas') || (fuel_type == 'FuelOilNo2')
150
+ plf_vs_plr_curve = model_add_curve(water_heater_mixed.model, 'SWH-EFFFPLR-NECB2011')
151
+ water_heater_mixed.setPartLoadFactorCurve(plf_vs_plr_curve)
152
+ end
153
+
154
+ # Append the name with standards information
155
+ water_heater_mixed.setName("#{water_heater_mixed.name} #{water_heater_eff.round(3)} Therm Eff")
156
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.WaterHeaterMixed', "For #{template}: #{water_heater_mixed.name}; thermal efficiency = #{water_heater_eff.round(3)}, skin-loss UA = #{ua_btu_per_hr_per_f.round}Btu/hr")
157
+ return true
158
+ end
159
+ end
@@ -408,9 +408,19 @@ class BTAPData
408
408
  'NU' => 'Nunavut' }
409
409
  building_type = 'Commercial'
410
410
  province = provinces_names_map[model.getWeatherFile.stateProvinceRegion]
411
- neb_eplus_fuel_map = { 'Electricity' => 'Electricity',
412
- 'Natural Gas' => 'Gas',
413
- 'Oil' => 'FuelOilNo2' }
411
+ neb_eplus_fuel_map = {'Natural Gas' => {eplus_fuel_name: 'NaturalGas',
412
+ eplus_table_name: 'Annual and Peak Values - Natural Gas',
413
+ eplus_row_name: 'NaturalGas:Facility',
414
+ eplus_column_name: 'Natural Gas Annual Value'},
415
+ 'Electricity' => {eplus_fuel_name: 'Electricity',
416
+ eplus_table_name: 'Annual and Peak Values - Electricity',
417
+ eplus_row_name: 'Electricity:Facility',
418
+ eplus_column_name: 'Electricity Annual Value'},
419
+ 'Oil' => {eplus_fuel_name: 'FuelOilNo2',
420
+ eplus_table_name: 'Annual and Peak Values - Other',
421
+ eplus_row_name: 'FuelOilNo2:Facility',
422
+ eplus_column_name: 'Annual Value'}
423
+ }
414
424
  economics_data['cost_utility_neb_total_cost_per_m_sq'] = 0.0
415
425
  economics_data['cost_utility_ghg_total_kg_per_m_sq'] = 0.0
416
426
  # Create a hash of the neb data.
@@ -424,32 +434,20 @@ class BTAPData
424
434
  end
425
435
  neb_fuel_cost = row['2020']
426
436
  fuel_consumption_gj = 0.0
427
- if neb_fuel == 'Electricity' || neb_fuel == 'Natural Gas'
428
- sql_command = "SELECT Value FROM tabulardatawithstrings
429
- WHERE ReportName='EnergyMeters'
430
- AND ReportForString='Entire Facility'
431
- AND TableName='Annual and Peak Values - #{ep_fuel}'
432
- AND RowName='#{ep_fuel}:Facility'
433
- AND ColumnName='#{ep_fuel} Annual Value'
434
- AND Units='GJ'"
435
- fuel_consumption_gj = model.sqlFile.get.execAndReturnFirstDouble(sql_command).is_initialized ? model.sqlFile.get.execAndReturnFirstDouble(sql_command).get : 0.0
436
- else
437
- sql_command = " SELECT Value FROM tabulardatawithstrings
438
- WHERE ReportName='EnergyMeters'
439
- AND ReportForString='Entire Facility'
440
- AND TableName='Annual and Peak Values - Other'
441
- AND RowName='#{ep_fuel}:Facility'
442
- AND ColumnName='Annual Value'
443
- AND Units='GJ'"
444
-
445
- fuel_consumption_gj = model.sqlFile.get.execAndReturnFirstDouble(sql_command).is_initialized ? model.sqlFile.get.execAndReturnFirstDouble(sql_command).get : 0.0
446
- end
437
+ sql_command = "SELECT Value FROM tabulardatawithstrings
438
+ WHERE ReportName='EnergyMeters'
439
+ AND ReportForString='Entire Facility'
440
+ AND TableName='#{ep_fuel[:eplus_table_name]}'
441
+ AND RowName='#{ep_fuel[:eplus_row_name]}'
442
+ AND ColumnName='#{ep_fuel[:eplus_column_name]}'
443
+ AND Units='GJ'"
444
+ fuel_consumption_gj = model.sqlFile.get.execAndReturnFirstDouble(sql_command).is_initialized ? model.sqlFile.get.execAndReturnFirstDouble(sql_command).get : 0.0
447
445
 
448
446
  # Determine costs in $$
449
447
  economics_data["cost_utility_neb_#{neb_fuel.downcase}_cost_per_m_sq"] = fuel_consumption_gj * neb_fuel_cost.to_f / @conditioned_floor_area_m_sq
450
448
  economics_data['cost_utility_neb_total_cost_per_m_sq'] += economics_data["cost_utility_neb_#{neb_fuel.downcase}_cost_per_m_sq"]
451
449
  # Determine cost in GHG kg of CO2
452
- economics_data["cost_utility_ghg_#{neb_fuel.downcase}_kg_per_m_sq"] = fuel_consumption_gj * get_utility_ghg_kg_per_gj(province: model.getWeatherFile.stateProvinceRegion, fuel_type: ep_fuel) / @conditioned_floor_area_m_sq
450
+ economics_data["cost_utility_ghg_#{neb_fuel.downcase}_kg_per_m_sq"] = fuel_consumption_gj * get_utility_ghg_kg_per_gj(province: model.getWeatherFile.stateProvinceRegion, fuel_type: ep_fuel[:eplus_fuel_name]) / @conditioned_floor_area_m_sq
453
451
  economics_data['cost_utility_ghg_total_kg_per_m_sq'] += economics_data["cost_utility_ghg_#{neb_fuel.downcase}_kg_per_m_sq"]
454
452
  end
455
453
  # Commenting out block charge rates for now....
@@ -1242,8 +1240,8 @@ class BTAPData
1242
1240
  " AND ReportForString='Entire Facility' AND TableName='Annual and Peak Values - Electricity' AND RowName='Electricity:Facility'" \
1243
1241
  " AND ColumnName='Electricity Maximum Value' AND Units='W'")
1244
1242
  natural_gas_peak = @model.sqlFile.get.execAndReturnFirstDouble("SELECT Value FROM tabulardatawithstrings WHERE ReportName='EnergyMeters'" \
1245
- " AND ReportForString='Entire Facility' AND TableName='Annual and Peak Values - Gas' AND RowName='Gas:Facility'" \
1246
- " AND ColumnName='Gas Maximum Value' AND Units='W'")
1243
+ " AND ReportForString='Entire Facility' AND TableName='Annual and Peak Values - Natural Gas' AND RowName='NaturalGas:Facility'" \
1244
+ " AND ColumnName='Natural Gas Maximum Value' AND Units='W'")
1247
1245
  data['energy_peak_electric_w_per_m_sq'] = electric_peak.empty? ? 0.0 : electric_peak.get / @conditioned_floor_area_m_sq
1248
1246
  data['energy_peak_natural_gas_w_per_m_sq'] = natural_gas_peak.empty? ? 0.0 : natural_gas_peak.get / @conditioned_floor_area_m_sq
1249
1247
 
@@ -1261,9 +1259,9 @@ class BTAPData
1261
1259
  FROM TabularDataWithStrings
1262
1260
  WHERE ReportName='EnergyMeters'
1263
1261
  AND ReportForString='Entire Facility'
1264
- AND TableName='Annual and Peak Values - Gas'
1262
+ AND TableName='Annual and Peak Values - Natural Gas'
1265
1263
  AND RowName='Heating:Gas'
1266
- AND ColumnName='Gas Maximum Value'
1264
+ AND ColumnName='Natural Gas Maximum Value'
1267
1265
  AND Units='W'"
1268
1266
  heating_peak_w_gas = @sqlite_file.get.execAndReturnFirstDouble(command)
1269
1267
  heating_peak_w = [heating_peak_w_electricity.to_f, heating_peak_w_gas.to_f].max
@@ -1283,7 +1281,7 @@ class BTAPData
1283
1281
  FROM TabularDataWithStrings
1284
1282
  WHERE ReportName='EnergyMeters'
1285
1283
  AND ReportForString='Entire Facility'
1286
- AND TableName='Annual and Peak Values - Gas'
1284
+ AND TableName='Annual and Peak Values - Natural Gas'
1287
1285
  AND RowName='Cooling:Electricity'
1288
1286
  AND ColumnName='Electricity Maximum Value'
1289
1287
  AND Units='W'"
@@ -1406,7 +1404,7 @@ class BTAPData
1406
1404
  # ["InputVerificationandResultsSummary", "Entire Facility", "Skylight-Roof Ratio"],
1407
1405
  # ["DemandEndUseComponentsSummary", "Entire Facility", "End Uses"],
1408
1406
  # ["ComponentSizingSummary", "Entire Facility", "AirLoopHVAC"],
1409
- # ["EnergyMeters", "Entire Facility", 'Annual and Peak Values - Gas'],
1407
+ # ["EnergyMeters", "Entire Facility", 'Annual and Peak Values - Natural Gas'],
1410
1408
  # ["EnergyMeters", "Entire Facility", 'Annual and Peak Values - Electricity'],
1411
1409
  # ["EnergyMeters", "Entire Facility", 'Annual and Peak Values - FuelOilNo2'],
1412
1410
  # ["EnergyMeters", "Entire Facility", 'Annual and Peak Values - Other'],
@@ -1648,19 +1646,19 @@ class BTAPData
1648
1646
  def get_utility_ghg_kg_per_gj(province:, fuel_type:)
1649
1647
  ghg_data = [
1650
1648
  # Obtained from Portfolio Manager https://portfoliomanager.energystar.gov/pdf/reference/Emissions.pdf 10/10/2020
1651
- { "province": 'AB', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 53.24, "CO2eq Emissions (g/m3)": 1939.0 },
1652
- { "province": 'BC', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 53.19, "CO2eq Emissions (g/m3)": 1937.0 },
1653
- { "province": 'MB', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 52.09, "CO2eq Emissions (g/m3)": 1897.0 },
1654
- { "province": 'NB', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1655
- { "province": 'NL', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1656
- { "province": 'NT', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1657
- { "province": 'NS', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1658
- { "province": 'NU', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1659
- { "province": 'ON', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 52.14, "CO2eq Emissions (g/m3)": 1912.0 },
1660
- { "province": 'PE', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1661
- { "province": 'QC', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 52.12, "CO2eq Emissions (g/m3)": 1898.0 },
1662
- { "province": 'SK', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 50.53, "CO2eq Emissions (g/m3)": 1840.0 },
1663
- { "province": 'YT', "fuel_type": 'Gas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1649
+ { "province": 'AB', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 53.24, "CO2eq Emissions (g/m3)": 1939.0 },
1650
+ { "province": 'BC', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 53.19, "CO2eq Emissions (g/m3)": 1937.0 },
1651
+ { "province": 'MB', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.09, "CO2eq Emissions (g/m3)": 1897.0 },
1652
+ { "province": 'NB', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1653
+ { "province": 'NL', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1654
+ { "province": 'NT', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1655
+ { "province": 'NS', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1656
+ { "province": 'NU', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1657
+ { "province": 'ON', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.14, "CO2eq Emissions (g/m3)": 1912.0 },
1658
+ { "province": 'PE', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1659
+ { "province": 'QC', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.12, "CO2eq Emissions (g/m3)": 1898.0 },
1660
+ { "province": 'SK', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 50.53, "CO2eq Emissions (g/m3)": 1840.0 },
1661
+ { "province": 'YT', "fuel_type": 'NaturalGas', "CO2eq Emissions (kg/MBtu)": 52.50, "CO2eq Emissions (g/m3)": 1912.0 },
1664
1662
 
1665
1663
  { "province": 'AB', "fuel_type": 'FuelOilNo2', "CO2eq Emissions (kg/MBtu)": 75.13, "CO2eq Emissions (g/m3)": 2763.0 },
1666
1664
  { "province": 'BC', "fuel_type": 'FuelOilNo2', "CO2eq Emissions (kg/MBtu)": 75.13, "CO2eq Emissions (g/m3)": 2763.0 },
@@ -2,7 +2,7 @@ require 'openstudio'
2
2
  require 'securerandom'
3
3
  require 'optparse'
4
4
  require 'yaml'
5
- # require 'git-revision'
5
+ #require 'git-revision'
6
6
  # resource_folder = File.join(__dir__, '..', '..', 'measures/btap_results/resources')
7
7
  # OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
8
8
 
@@ -113,6 +113,7 @@ class BTAPDatapoint
113
113
  lights_scale: @options[:lights_scale],
114
114
  daylighting_type: @options[:daylighting_type], # Two options: @options[: (1) 'NECB_Default', (2) 'add_daylighting_controls'
115
115
  ecm_system_name: @options[:ecm_system_name],
116
+ ecm_system_zones_map_option: @options[:ecm_system_zones_map_option], # (1) 'NECB_Default' (2) 'one_sys_per_floor' (3) 'one_sys_per_bldg'
116
117
  erv_package: @options[:erv_package],
117
118
  boiler_eff: @options[:boiler_eff],
118
119
  # Inconsistent naming Todo Chris K.
@@ -155,7 +156,9 @@ class BTAPDatapoint
155
156
  chiller_type: @options[:chiller_type],
156
157
  output_variables: @options[:output_variables],
157
158
  output_meters: @options[:output_meters],
158
- airloop_economizer_type: @options[:airloop_economizer_type])
159
+ airloop_economizer_type: @options[:airloop_economizer_type],
160
+ shw_scale: @options[:shw_scale],
161
+ baseline_system_zones_map_option: @options[:baseline_system_zones_map_option])
159
162
  end
160
163
 
161
164
  # Save model to to disk.
@@ -267,8 +270,8 @@ class BTAPDatapoint
267
270
  end
268
271
 
269
272
  def s3_copy_file_to_s3(bucket_name:, source_file:, target_file:, n: 0)
270
- require 'aws-sdk-core'
271
- require 'aws-sdk-s3'
273
+ # require 'aws-sdk-core'
274
+ # require 'aws-sdk-s3'
272
275
  Aws.use_bundled_cert!
273
276
  s3_resource = Aws::S3::Resource.new(region: 'ca-central-1')
274
277
 
@@ -13,5 +13,5 @@ module OpenstudioStandards
13
13
  end
14
14
  return 'git-not-found-on-this-system'
15
15
  end
16
- VERSION = '0.2.15'.freeze
16
+ VERSION = '0.2.16.rc1'.freeze
17
17
  end
@@ -55,6 +55,7 @@ module OpenstudioStandards
55
55
  # NECB2020 Code
56
56
  require_relative "#{stds}/necb/NECB2020/necb_2020"
57
57
  require_relative "#{stds}/necb/NECB2020/building_envelope"
58
+ require_relative "#{stds}/necb/NECB2020/service_water_heating"
58
59
 
59
60
  # BTAPPRE1980
60
61
  require_relative "#{stds}/necb/BTAPPRE1980/btap_pre1980"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openstudio-standards
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.15
4
+ version: 0.2.16.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Parker
@@ -28,7 +28,7 @@ authors:
28
28
  autorequire:
29
29
  bindir: bin
30
30
  cert_chain: []
31
- date: 2021-11-01 00:00:00.000000000 Z
31
+ date: 2022-03-18 00:00:00.000000000 Z
32
32
  dependencies:
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: minitest-reporters
@@ -640,6 +640,7 @@ files:
640
640
  - data/geometry/DOERefWarehouse.json
641
641
  - data/geometry/DOERefWarehouse.osm
642
642
  - data/standards/OpenStudio_Standards-ashrae_90_1.xlsx
643
+ - data/standards/OpenStudio_Standards-ashrae_90_1_28Jan2022.xlsx
643
644
  - data/standards/exclude_list.csv
644
645
  - data/standards/export_OpenStudio_libraries.rb
645
646
  - data/standards/legacy_dd_results.csv
@@ -2879,6 +2880,7 @@ files:
2879
2880
  - lib/openstudio-standards/standards/necb/NECB2020/data/surface_thermal_transmittance.json
2880
2881
  - lib/openstudio-standards/standards/necb/NECB2020/data/unitary_acs.json
2881
2882
  - lib/openstudio-standards/standards/necb/NECB2020/necb_2020.rb
2883
+ - lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb
2882
2884
  - lib/openstudio-standards/standards/necb/common/bc_step_code_indicators.md
2883
2885
  - lib/openstudio-standards/standards/necb/common/btap_data.rb
2884
2886
  - lib/openstudio-standards/standards/necb/common/btap_datapoint.rb