honeybee-openstudio 2.24.0 → 2.25.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aaaa7ddfb52102f325f31d2090e14c7174c3a98ba156859b989b30391a4abbdb
4
- data.tar.gz: 5f6fb58c9f9f926fab088fb0c300cbe4527039a984d2bc5d816d72c27f64d7f7
3
+ metadata.gz: 4e1a8b30344f5ddd1ab1066be049b6dd652a9093a3a7419557d7359a90962803
4
+ data.tar.gz: cd2cff6c82e3c4a0e49d54b01f1074af4fbf270aaf2fa0a32abd333cb57ff89d
5
5
  SHA512:
6
- metadata.gz: 47d6f83ad9135c92c77e5924c9d1872c2b2573a2d056f9940bec7f96b7aba8e74c6bcd0aca8cd83766a79c4c8398df88bbf54ae2a29edb8a080cc6d57a6f13ef
7
- data.tar.gz: dc582df2f41e9ffe26b67a0c92b0d256dbab7215697573655d4eb50edd6a498ef9f084fd66016f8dfff3882555afacdcb6b558db7d7ed4fabc795145d3df89af
6
+ metadata.gz: 6880870d22ce32cc6dd217b2ddc86cce39e6402e4134012ab3c135ee6addbdf27bef3738bdc721e09563c865cd476a4d237149a6c54d5d92f41215a7e86bfbc3
7
+ data.tar.gz: 98fcd830229b574f193d16b0803a608a0b8e126f8fc86c13ab23076e33bd0c9911d065fa9b3fa6104a3ded52e476ab13cfe953dd5682249be420b503147ea6e0
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'honeybee-openstudio'
7
- spec.version = '2.24.0'
7
+ spec.version = '2.25.0'
8
8
  spec.authors = ['Tanushree Charan', 'Dan Macumber', 'Chris Mackey', 'Mostapha Sadeghipour Roudsari']
9
9
  spec.email = ['tanushree.charan@nrel.gov', 'chris@ladybug.tools']
10
10
 
@@ -280,7 +280,8 @@ module Honeybee
280
280
  # assign service hot water if it exists
281
281
  if @hash[:properties][:energy][:service_hot_water]
282
282
  shw_space = ServiceHotWaterAbridged.new(@hash[:properties][:energy][:service_hot_water])
283
- os_shw_space = shw_space.to_openstudio(openstudio_model, os_space)
283
+ os_shw_space = shw_space.to_openstudio(
284
+ openstudio_model, os_space, @hash[:properties][:energy][:shw])
284
285
  $shw_for_plant = shw_space
285
286
  end
286
287
 
@@ -37,7 +37,14 @@ module Honeybee
37
37
  class ServiceHotWaterAbridged
38
38
  @@max_target_temp = 60
39
39
  @@max_temp_schedule = nil
40
- @@shw_connections = []
40
+ @@shw_connections = {}
41
+ @@shw_rates = {}
42
+ @@hp_deadband = 4
43
+ @@sys_count = 1
44
+
45
+ def shw_connections
46
+ @@shw_connections
47
+ end
41
48
 
42
49
  def find_existing_openstudio_object(openstudio_model)
43
50
  model_shw = openstudio_model.getWaterUseEquipmentByName(@hash[:identifier])
@@ -45,51 +52,188 @@ module Honeybee
45
52
  nil
46
53
  end
47
54
 
48
- def add_district_hot_water_plant(openstudio_model)
49
- # add a defaul district hot water system to supply all of the shw_connections
50
- # create the plant loop
51
- hot_water_plant = OpenStudio::Model::PlantLoop.new(openstudio_model)
52
- hot_water_plant.setName('Service Hot Water Loop')
53
- hot_water_plant.setMaximumLoopTemperature(@@max_target_temp)
54
- hot_water_plant.setMinimumLoopTemperature(10) # default value in C from OpenStudio Application
55
-
56
- # edit the sizing information to be for a hot water loop
57
- loop_sizing = hot_water_plant.sizingPlant()
58
- loop_sizing.setLoopType('Heating')
59
- loop_sizing.setDesignLoopExitTemperature(@@max_target_temp)
60
- loop_sizing.setLoopDesignTemperatureDifference(5) # default value in C from OpenStudio Application
61
-
62
- # add a setpoint manager for the loop
63
- hot_sch = @@max_temp_schedule
64
- if @@max_temp_schedule.nil?
65
- hot_sch_name = @@max_target_temp.to_s + 'C Hot Water'
66
- hot_sch = create_constant_schedule(openstudio_model, hot_sch_name, @@max_target_temp)
67
- end
68
- sp_manager = OpenStudio::Model::SetpointManagerScheduled.new(openstudio_model, hot_sch)
69
- sp_manager.addToNode(hot_water_plant.supplyOutletNode())
70
-
71
- # add a constant speed pump for the loop
72
- hot_water_pump = OpenStudio::Model::PumpConstantSpeed.new(openstudio_model)
73
- hot_water_pump.setName('Service Hot Water Pump')
74
- hot_water_pump.setRatedPumpHead(29891) # default value in Pa from OpenStudio Application
75
- hot_water_pump.setMotorEfficiency(0.9) # default value from OpenStudio Application
76
- hot_water_pump.addToNode(hot_water_plant.supplyInletNode())
77
-
78
- # add a district heating system to supply the heat for the loop
79
- district_hw = OpenStudio::Model::DistrictHeating.new(openstudio_model)
80
- district_hw.setName('Service Hot Water District Heat')
81
- district_hw.setNominalCapacity(1000000)
82
- hot_water_plant.addSupplyBranchForComponent(district_hw)
83
-
84
- # add all of the water use connections to the loop
85
- @@shw_connections.each do |shw_conn|
86
- hot_water_plant.addDemandBranchForComponent(shw_conn)
55
+ def add_hot_water_plants(openstudio_model, shw_hashes)
56
+ # add district hot water loops to supply all of the shw_connections
57
+ shw_hashes.each do |shw_hash|
58
+ # create the plant loop
59
+ hot_water_plant = OpenStudio::Model::PlantLoop.new(openstudio_model)
60
+ hot_water_plant.setName('SHW Loop ' + shw_hash[:identifier])
61
+ hot_water_plant.setMaximumLoopTemperature(@@max_target_temp)
62
+ hot_water_plant.setMinimumLoopTemperature(10) # default value in C from OpenStudio Application
63
+
64
+ # edit the sizing information to be for a hot water loop
65
+ loop_sizing = hot_water_plant.sizingPlant()
66
+ loop_sizing.setLoopType('Heating')
67
+ loop_sizing.setDesignLoopExitTemperature(@@max_target_temp)
68
+ loop_sizing.setLoopDesignTemperatureDifference(5) # default value in C from OpenStudio Application
69
+
70
+ # add a setpoint manager for the loop
71
+ hot_sch = @@max_temp_schedule
72
+ if @@max_temp_schedule.nil?
73
+ hot_sch_name = @@max_target_temp.to_s + 'C Hot Water'
74
+ hot_sch = create_constant_schedule(openstudio_model, hot_sch_name, @@max_target_temp)
75
+ end
76
+ sp_manager = OpenStudio::Model::SetpointManagerScheduled.new(openstudio_model, hot_sch)
77
+ sp_manager.addToNode(hot_water_plant.supplyOutletNode())
78
+
79
+ # add a constant speed pump for the loop
80
+ hot_water_pump = OpenStudio::Model::PumpConstantSpeed.new(openstudio_model)
81
+ hot_water_pump.setName('SHW Pump' + @@sys_count.to_s)
82
+ hot_water_pump.setRatedPumpHead(29891) # default value in Pa from OpenStudio Application
83
+ hot_water_pump.setMotorEfficiency(0.9) # default value from OpenStudio Application
84
+ hot_water_pump.addToNode(hot_water_plant.supplyInletNode())
85
+ if shw_hash[:equipment_type] != 'Default_District_SHW'
86
+ hot_water_pump.setEndUseSubcategory('Water Systems')
87
+ end
88
+
89
+ eq_type = shw_hash[:equipment_type]
90
+ if eq_type == 'Default_District_SHW'
91
+ # add a district heating system to supply the heat for the loop
92
+ district_hw = OpenStudio::Model::DistrictHeating.new(openstudio_model)
93
+ district_hw.setName('Service Hot Water District Heat')
94
+ district_hw.setNominalCapacity(1000000)
95
+ hot_water_plant.addSupplyBranchForComponent(district_hw)
96
+ elsif eq_type == 'Gas_WaterHeater' || eq_type == 'Electric_WaterHeater' || eq_type == 'HeatPump_WaterHeater'
97
+ # add a water heater to supply the heat for the loop
98
+ heater = OpenStudio::Model::WaterHeaterMixed.new(openstudio_model)
99
+ if eq_type == 'Electric_WaterHeater' || eq_type == 'HeatPump_WaterHeater'
100
+ heater.setHeaterFuelType('Electricity')
101
+ heater.setOffCycleParasiticFuelType('Electricity')
102
+ heater.setOnCycleParasiticFuelType('Electricity')
103
+ end
104
+ heater.setName('SHW WaterHeater' + @@sys_count.to_s)
105
+
106
+ # set the water heater efficiency
107
+ if eq_type == 'HeatPump_WaterHeater'
108
+ heater.setHeaterThermalEfficiency(1.0)
109
+ elsif shw_hash[:heater_efficiency].nil?
110
+ if eq_type == 'Electric_WaterHeater'
111
+ heater.setHeaterThermalEfficiency(1.0)
112
+ else
113
+ heater.setHeaterThermalEfficiency(0.8)
114
+ end
115
+ else
116
+ heater.setHeaterThermalEfficiency(shw_hash[:heater_efficiency])
117
+ end
118
+
119
+ # set the ambient condition of the water tank
120
+ to_thermal_zone = false
121
+ unless shw_hash[:ambient_condition].nil?
122
+ if shw_hash[:ambient_condition].is_a? Numeric
123
+ target_sch_name = shw_hash[:ambient_condition].to_s + 'C Ambient Condition'
124
+ target_sch = create_constant_schedule(
125
+ openstudio_model, target_sch_name, shw_hash[:ambient_condition])
126
+ heater.setAmbientTemperatureSchedule(target_sch)
127
+ else
128
+ source_zone_ref = openstudio_model.getThermalZoneByName(shw_hash[:ambient_condition])
129
+ unless source_zone_ref.empty?
130
+ source_zone = source_zone_ref.get
131
+ heater.setAmbientTemperatureThermalZone(source_zone)
132
+ end
133
+ heater.setAmbientTemperatureIndicator('ThermalZone')
134
+ to_thermal_zone = true
135
+ end
136
+ else
137
+ target_sch_name = '22C Ambient Condition'
138
+ target_sch = create_constant_schedule(openstudio_model, target_sch_name, 22)
139
+ heater.setAmbientTemperatureSchedule(target_sch)
140
+ end
141
+
142
+ # set the ambient loss coefficient
143
+ if to_thermal_zone
144
+ unless shw_hash[:ambient_loss_coefficient].nil?
145
+ heater.setOffCycleLossFractiontoThermalZone(
146
+ shw_hash[:ambient_loss_coefficient])
147
+ heater.setOnCycleLossFractiontoThermalZone(
148
+ shw_hash[:ambient_loss_coefficient])
149
+ else
150
+ heater.setOffCycleLossFractiontoThermalZone(6)
151
+ heater.setOnCycleLossFractiontoThermalZone(6)
152
+ end
153
+ else
154
+ unless shw_hash[:ambient_loss_coefficient].nil?
155
+ heater.setOffCycleLossCoefficienttoAmbientTemperature(
156
+ shw_hash[:ambient_loss_coefficient])
157
+ heater.setOnCycleLossCoefficienttoAmbientTemperature(
158
+ shw_hash[:ambient_loss_coefficient])
159
+ else
160
+ heater.setOffCycleLossCoefficienttoAmbientTemperature(6)
161
+ heater.setOnCycleLossCoefficienttoAmbientTemperature(6)
162
+ end
163
+ end
164
+
165
+ # ensure that the tank is sized appropriately and add it to the loop
166
+ heater.setHeaterMaximumCapacity(1000000)
167
+ heater.setTankVolume(@@shw_rates[shw_hash[:identifier]])
168
+ hot_water_plant.addSupplyBranchForComponent(heater)
169
+
170
+ # if it's a heat pump system, then add the pump
171
+ if eq_type == 'HeatPump_WaterHeater'
172
+ # create a coil for the heat pump
173
+ heat_pump = OpenStudio::Model::CoilWaterHeatingAirToWaterHeatPump.new(openstudio_model)
174
+ heat_pump.setName('HPWH DX Coil' + @@sys_count.to_s)
175
+ if shw_hash[:heater_efficiency].nil?
176
+ heat_pump.setRatedCOP(3.5)
177
+ else
178
+ heat_pump.setRatedCOP(shw_hash[:heater_efficiency])
179
+ end
180
+
181
+ # add a fan for the heat pump system
182
+ fan = OpenStudio::Model::FanOnOff.new(openstudio_model)
183
+ fan.setName('HPWH Fan' + @@sys_count.to_s)
184
+ fan.setEndUseSubcategory('Water Systems')
185
+ setpt_sch = create_constant_schedule(
186
+ openstudio_model, 'HPWH Setpoint' + @@sys_count.to_s, @@max_target_temp + (@@hp_deadband * 2))
187
+ inlet_sch = create_constant_schedule(
188
+ openstudio_model, 'Inlet Air Mixer Fraction' + @@sys_count.to_s, 0.2)
189
+
190
+ # add a water heater to supply the heat for the loop
191
+ heat_sys = OpenStudio::Model::WaterHeaterHeatPump.new(
192
+ openstudio_model, heat_pump, heater, fan, setpt_sch, inlet_sch)
193
+ heat_sys.setDeadBandTemperatureDifference(@@hp_deadband)
194
+
195
+ source_zone_ref = openstudio_model.getThermalZoneByName(shw_hash[:ambient_condition])
196
+ unless source_zone_ref.empty?
197
+ source_zone = source_zone_ref.get
198
+ heat_sys.addToThermalZone(source_zone)
199
+ end
200
+ heat_sys.setName('SHW WaterHeater HeatPump' + @@sys_count.to_s)
201
+ end
202
+
203
+ elsif eq_type == 'Gas_TanklessHeater' || eq_type == 'Electric_TanklessHeater'
204
+ # add a boiler to supply the heat for the loop
205
+ heater = OpenStudio::Model::BoilerHotWater.new(openstudio_model)
206
+ if eq_type == 'Electric_TanklessHeater'
207
+ heater.setFuelType('Electricity')
208
+ end
209
+ heater.setName('SHW Tankless WaterHeater' + @@sys_count.to_s)
210
+ heater.setEndUseSubcategory('Water Systems')
211
+
212
+ # set the water heater efficiency
213
+ unless shw_hash[:heater_efficiency].nil?
214
+ heater.setNominalThermalEfficiency(shw_hash[:heater_efficiency])
215
+ else
216
+ if eq_type == 'Electric_TanklessHeater'
217
+ heater.setNominalThermalEfficiency(1.0)
218
+ else
219
+ heater.setNominalThermalEfficiency(0.8)
220
+ end
221
+ end
222
+
223
+ # ensure that the boiler is sized appropriately and add it to the loop
224
+ heater.setNominalCapacity(1000000)
225
+ hot_water_plant.addSupplyBranchForComponent(heater)
226
+ end
227
+
228
+ # add all of the water use connections to the loop and total the capacity
229
+ @@shw_connections[shw_hash[:identifier]].each do |shw_conn|
230
+ hot_water_plant.addDemandBranchForComponent(shw_conn)
231
+ end
232
+ @@sys_count = @@sys_count + 1
87
233
  end
88
-
89
- hot_water_plant
90
234
  end
91
235
 
92
- def to_openstudio(openstudio_model, os_space)
236
+ def to_openstudio(openstudio_model, os_space, shw_name)
93
237
  # create water use equipment + connection and set identifier
94
238
  os_shw_def = OpenStudio::Model::WaterUseEquipmentDefinition.new(openstudio_model)
95
239
  os_shw = OpenStudio::Model::WaterUseEquipment.new(os_shw_def)
@@ -101,6 +245,10 @@ module Honeybee
101
245
  total_flow = (@hash[:flow_per_area].to_f * os_space.floorArea) / 3600000
102
246
  os_shw_def.setPeakFlowRate(total_flow)
103
247
  os_shw_def.setEndUseSubcategory('General')
248
+ if @@shw_rates[shw_name].nil?
249
+ @@shw_rates[shw_name] = 0
250
+ end
251
+ @@shw_rates[shw_name] = @@shw_rates[shw_name] + (total_flow * 3600)
104
252
 
105
253
  # assign schedule
106
254
  shw_schedule = openstudio_model.getScheduleByName(@hash[:schedule])
@@ -126,7 +274,13 @@ module Honeybee
126
274
  @@max_target_temp = target_temp
127
275
  @@max_temp_schedule = target_water_sch
128
276
  end
129
- @@shw_connections << os_shw_conn
277
+ if shw_name.nil?
278
+ shw_name = 'default_district_shw'
279
+ end
280
+ if @@shw_connections[shw_name].nil?
281
+ @@shw_connections[shw_name] = []
282
+ end
283
+ @@shw_connections[shw_name] << os_shw_conn
130
284
 
131
285
  # assign sensible fraction if it exists
132
286
  sens_fract = defaults[:sensible_fraction][:default]
@@ -448,7 +448,8 @@ module Honeybee
448
448
  shw_hash = $programtype_shw_hash[program_type_id]
449
449
  unless shw_hash.nil?
450
450
  shw_object = ServiceHotWaterAbridged.new(shw_hash)
451
- openstudio_shw = shw_object.to_openstudio(@openstudio_model, openstudio_room)
451
+ openstudio_shw = shw_object.to_openstudio(
452
+ @openstudio_model, openstudio_room, room[:properties][:energy][:shw])
452
453
  $shw_for_plant = shw_object
453
454
  end
454
455
  end
@@ -570,7 +571,18 @@ module Honeybee
570
571
  def create_hot_water_plant
571
572
  # create a hot water plant if there's any service hot water in the model
572
573
  unless $shw_for_plant.nil?
573
- $shw_for_plant.add_district_hot_water_plant(@openstudio_model)
574
+ if @hash[:properties][:energy][:shws].nil?
575
+ shw_list = []
576
+ else
577
+ shw_list = @hash[:properties][:energy][:shws]
578
+ end
579
+ unless $shw_for_plant.shw_connections['default_district_shw'].nil?
580
+ def_hash = {}
581
+ def_hash[:equipment_type] = 'Default_District_SHW'
582
+ def_hash[:identifier] = 'default_district_shw'
583
+ shw_list << def_hash
584
+ end
585
+ $shw_for_plant.add_hot_water_plants(@openstudio_model, shw_list)
574
586
  end
575
587
  end
576
588
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeybee-openstudio
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.24.0
4
+ version: 2.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanushree Charan
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2021-10-02 00:00:00.000000000 Z
14
+ date: 2021-10-10 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler