openstudio-standards 0.2.15 → 0.2.16.rc1

Sign up to get free protection for your applications and to get access to all the features.
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