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 +4 -4
- data/honeybee-openstudio.gemspec +1 -1
- data/lib/to_openstudio/geometry/room.rb +2 -1
- data/lib/to_openstudio/load/service_hot_water.rb +198 -44
- data/lib/to_openstudio/model.rb +14 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e1a8b30344f5ddd1ab1066be049b6dd652a9093a3a7419557d7359a90962803
|
4
|
+
data.tar.gz: cd2cff6c82e3c4a0e49d54b01f1074af4fbf270aaf2fa0a32abd333cb57ff89d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6880870d22ce32cc6dd217b2ddc86cce39e6402e4134012ab3c135ee6addbdf27bef3738bdc721e09563c865cd476a4d237149a6c54d5d92f41215a7e86bfbc3
|
7
|
+
data.tar.gz: 98fcd830229b574f193d16b0803a608a0b8e126f8fc86c13ab23076e33bd0c9911d065fa9b3fa6104a3ded52e476ab13cfe953dd5682249be420b503147ea6e0
|
data/honeybee-openstudio.gemspec
CHANGED
@@ -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.
|
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(
|
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
|
49
|
-
# add
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
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
|
-
|
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]
|
data/lib/to_openstudio/model.rb
CHANGED
@@ -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(
|
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
|
-
|
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.
|
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-
|
14
|
+
date: 2021-10-10 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|