honeybee-openstudio 2.24.0 → 2.25.0

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