honeybee-openstudio 2.23.6 → 2.25.1
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/from_openstudio/geometry/shade.rb +2 -0
- data/lib/from_openstudio/model.rb +15 -0
- data/lib/from_openstudio/schedule/fixed_interval.rb +71 -0
- data/lib/to_openstudio/geometry/face.rb +8 -1
- data/lib/to_openstudio/geometry/room.rb +2 -1
- data/lib/to_openstudio/geometry/shade.rb +8 -1
- data/lib/to_openstudio/load/service_hot_water.rb +195 -44
- data/lib/to_openstudio/model.rb +14 -2
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 532f9efe39fa576e8a8da58d4af039f9d87655bdb810d479e80f51d7c1e5073d
|
4
|
+
data.tar.gz: 4171a9fd68a74a84f08d113e01ba495dd6bbe9a1ba7f89cfb09617598a6e2b6c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz: '
|
6
|
+
metadata.gz: b1632b1397a821f23fa9d5b60bb8d0766d5317455872feed4e4962be88fbf84d0e1873f4cb7f35990c88f24779d39e195795d0b1e3741b754e2c5da96c5c194e
|
7
|
+
data.tar.gz: '057379314b07d93d4573a654853d151d3bc49ddcc746e5120a23b2d9a562f8b427f638854692a547d113be79f7b4340689a1d2a7a88755122ffaccf74294bae8'
|
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.1'
|
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
|
|
@@ -75,6 +75,8 @@ module Honeybee
|
|
75
75
|
transmittance_schedule = shading_surface.transmittanceSchedule
|
76
76
|
if !transmittance_schedule.empty?
|
77
77
|
trans_sch_name = clean_identifier(transmittance_schedule.get.nameString)
|
78
|
+
# Check whether schedules other than schedule ruleset or schedule fixed interval are
|
79
|
+
# being assigned
|
78
80
|
unless $schedules[trans_sch_name].nil?
|
79
81
|
hash[:transmittance_schedule] = trans_sch_name
|
80
82
|
end
|
@@ -48,6 +48,7 @@ require 'from_openstudio/construction/shade'
|
|
48
48
|
require 'from_openstudio/construction_set'
|
49
49
|
require 'from_openstudio/schedule/type_limit'
|
50
50
|
require 'from_openstudio/schedule/ruleset'
|
51
|
+
require 'from_openstudio/schedule/fixed_interval'
|
51
52
|
|
52
53
|
require 'openstudio'
|
53
54
|
|
@@ -134,6 +135,7 @@ module Honeybee
|
|
134
135
|
hash[:construction_sets] = constructionsets_from_model(openstudio_model)
|
135
136
|
hash[:schedule_type_limits] = schedtypelimits_from_model(openstudio_model)
|
136
137
|
hash[:schedules] = scheduleruleset_from_model(openstudio_model)
|
138
|
+
hash[:schedules] = schedulefixedinterval_from_model(openstudio_model)
|
137
139
|
|
138
140
|
hash
|
139
141
|
end
|
@@ -290,5 +292,18 @@ module Honeybee
|
|
290
292
|
result
|
291
293
|
end
|
292
294
|
|
295
|
+
# Create HB Schedule Fixed Interval from OpenStudio Schedule Fixed Interval
|
296
|
+
def self.schedulefixedinterval_from_model(openstudio_model)
|
297
|
+
result = []
|
298
|
+
# check if it is a leap year
|
299
|
+
is_leap_year = openstudio_model.getYearDescription.isLeapYear
|
300
|
+
openstudio_model.getScheduleFixedIntervals.each do |sch_fix_int|
|
301
|
+
sched_fixed_hash = ScheduleFixedIntervalAbridged.from_schedule_fixedinterval(sch_fix_int, is_leap_year)
|
302
|
+
$schedules[sched_fixed_hash[:identifier]] = sched_fixed_hash
|
303
|
+
result << sched_fixed_hash
|
304
|
+
end
|
305
|
+
result
|
306
|
+
end
|
307
|
+
|
293
308
|
end # Model
|
294
309
|
end # Honeybee
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# *******************************************************************************
|
2
|
+
# Honeybee OpenStudio Gem, Copyright (c) 2020, Alliance for Sustainable
|
3
|
+
# Energy, LLC, Ladybug Tools LLC and other contributors. All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# (1) Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# (2) Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# (3) Neither the name of the copyright holder nor the names of any contributors
|
16
|
+
# may be used to endorse or promote products derived from this software without
|
17
|
+
# specific prior written permission from the respective party.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
|
20
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
21
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
|
23
|
+
# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
|
24
|
+
# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
25
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
26
|
+
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
28
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
29
|
+
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
# *******************************************************************************
|
31
|
+
|
32
|
+
require 'honeybee/schedule/fixed_interval'
|
33
|
+
require 'from_openstudio/model_object'
|
34
|
+
|
35
|
+
module Honeybee
|
36
|
+
class ScheduleFixedIntervalAbridged < ModelObject
|
37
|
+
|
38
|
+
def self.from_schedule_fixedinterval(schedule_fixedinterval, is_leap_year)
|
39
|
+
# create an empty hash
|
40
|
+
hash = {}
|
41
|
+
hash[:type] = 'ScheduleFixedIntervalAbridged'
|
42
|
+
hash[:identifier] = clean_name(schedule_fixedinterval.nameString)
|
43
|
+
start_month = schedule_fixedinterval.startMonth
|
44
|
+
start_day = schedule_fixedinterval.startDay
|
45
|
+
if is_leap_year
|
46
|
+
# if it is a leap year then add 1 as third value
|
47
|
+
hash[:start_date] = [start_month, start_day, 1]
|
48
|
+
else
|
49
|
+
hash[:start_date] = [start_month, start_day]
|
50
|
+
end
|
51
|
+
hash[:interpolate] = schedule_fixedinterval.interpolatetoTimestep
|
52
|
+
# assigning schedule type limit if it exists
|
53
|
+
unless schedule_fixedinterval.scheduleTypeLimits.empty?
|
54
|
+
typ_lim = schedule_fixedinterval.scheduleTypeLimits.get
|
55
|
+
hash[:schedule_type_limit] = clean_name(typ_lim.nameString)
|
56
|
+
end
|
57
|
+
interval_length = schedule_fixedinterval.intervalLength
|
58
|
+
hash[:timestep] = 60 / interval_length.to_i
|
59
|
+
# get values from schedule fixed interval
|
60
|
+
values = schedule_fixedinterval.timeSeries.values
|
61
|
+
value_array = []
|
62
|
+
for i in 0..(values.size - 1)
|
63
|
+
value_array << values[i]
|
64
|
+
end
|
65
|
+
hash[:values] = value_array
|
66
|
+
|
67
|
+
hash
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
@@ -43,9 +43,16 @@ module Honeybee
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def to_openstudio(openstudio_model)
|
46
|
+
# get the vertices from the face
|
47
|
+
if @hash[:geometry][:vertices].nil?
|
48
|
+
hb_verts = @hash[:geometry][:boundary]
|
49
|
+
else
|
50
|
+
hb_verts = @hash[:geometry][:vertices]
|
51
|
+
end
|
52
|
+
|
46
53
|
# reorder the vertices to ensure they start from the upper-left corner
|
47
54
|
os_vertices = OpenStudio::Point3dVector.new
|
48
|
-
|
55
|
+
hb_verts.each do |vertex|
|
49
56
|
os_vertices << OpenStudio::Point3d.new(vertex[0], vertex[1], vertex[2])
|
50
57
|
end
|
51
58
|
reordered_vertices = OpenStudio.reorderULC(os_vertices)
|
@@ -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
|
|
@@ -43,9 +43,16 @@ module Honeybee
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def to_openstudio(openstudio_model)
|
46
|
+
# get the vertices from the face
|
47
|
+
if @hash[:geometry][:vertices].nil?
|
48
|
+
hb_verts = @hash[:geometry][:boundary]
|
49
|
+
else
|
50
|
+
hb_verts = @hash[:geometry][:vertices]
|
51
|
+
end
|
52
|
+
|
46
53
|
# create the openstudio shading surface
|
47
54
|
os_vertices = OpenStudio::Point3dVector.new
|
48
|
-
|
55
|
+
hb_verts.each do |vertex|
|
49
56
|
os_vertices << OpenStudio::Point3d.new(vertex[0], vertex[1], vertex[2])
|
50
57
|
end
|
51
58
|
reordered_vertices = OpenStudio.reorderULC(os_vertices)
|
@@ -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,185 @@ 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
|
+
|
86
|
+
eq_type = shw_hash[:equipment_type]
|
87
|
+
if eq_type == 'Default_District_SHW'
|
88
|
+
# add a district heating system to supply the heat for the loop
|
89
|
+
district_hw = OpenStudio::Model::DistrictHeating.new(openstudio_model)
|
90
|
+
district_hw.setName('Service Hot Water District Heat')
|
91
|
+
district_hw.setNominalCapacity(1000000)
|
92
|
+
hot_water_plant.addSupplyBranchForComponent(district_hw)
|
93
|
+
elsif eq_type == 'Gas_WaterHeater' || eq_type == 'Electric_WaterHeater' || eq_type == 'HeatPump_WaterHeater'
|
94
|
+
# add a water heater to supply the heat for the loop
|
95
|
+
heater = OpenStudio::Model::WaterHeaterMixed.new(openstudio_model)
|
96
|
+
if eq_type == 'Electric_WaterHeater' || eq_type == 'HeatPump_WaterHeater'
|
97
|
+
heater.setHeaterFuelType('Electricity')
|
98
|
+
heater.setOffCycleParasiticFuelType('Electricity')
|
99
|
+
heater.setOnCycleParasiticFuelType('Electricity')
|
100
|
+
end
|
101
|
+
heater.setName('SHW WaterHeater' + @@sys_count.to_s)
|
102
|
+
|
103
|
+
# set the water heater efficiency
|
104
|
+
if eq_type == 'HeatPump_WaterHeater'
|
105
|
+
heater.setHeaterThermalEfficiency(1.0)
|
106
|
+
elsif shw_hash[:heater_efficiency].nil?
|
107
|
+
if eq_type == 'Electric_WaterHeater'
|
108
|
+
heater.setHeaterThermalEfficiency(1.0)
|
109
|
+
else
|
110
|
+
heater.setHeaterThermalEfficiency(0.8)
|
111
|
+
end
|
112
|
+
else
|
113
|
+
heater.setHeaterThermalEfficiency(shw_hash[:heater_efficiency])
|
114
|
+
end
|
115
|
+
|
116
|
+
# set the ambient condition of the water tank
|
117
|
+
to_thermal_zone = false
|
118
|
+
unless shw_hash[:ambient_condition].nil?
|
119
|
+
if shw_hash[:ambient_condition].is_a? Numeric
|
120
|
+
target_sch_name = shw_hash[:ambient_condition].to_s + 'C Ambient Condition'
|
121
|
+
target_sch = create_constant_schedule(
|
122
|
+
openstudio_model, target_sch_name, shw_hash[:ambient_condition])
|
123
|
+
heater.setAmbientTemperatureSchedule(target_sch)
|
124
|
+
else
|
125
|
+
source_zone_ref = openstudio_model.getThermalZoneByName(shw_hash[:ambient_condition])
|
126
|
+
unless source_zone_ref.empty?
|
127
|
+
source_zone = source_zone_ref.get
|
128
|
+
heater.setAmbientTemperatureThermalZone(source_zone)
|
129
|
+
end
|
130
|
+
heater.setAmbientTemperatureIndicator('ThermalZone')
|
131
|
+
to_thermal_zone = true
|
132
|
+
end
|
133
|
+
else
|
134
|
+
target_sch_name = '22C Ambient Condition'
|
135
|
+
target_sch = create_constant_schedule(openstudio_model, target_sch_name, 22)
|
136
|
+
heater.setAmbientTemperatureSchedule(target_sch)
|
137
|
+
end
|
138
|
+
|
139
|
+
# set the ambient loss coefficient
|
140
|
+
if to_thermal_zone
|
141
|
+
unless shw_hash[:ambient_loss_coefficient].nil?
|
142
|
+
heater.setOffCycleLossFractiontoThermalZone(
|
143
|
+
shw_hash[:ambient_loss_coefficient])
|
144
|
+
heater.setOnCycleLossFractiontoThermalZone(
|
145
|
+
shw_hash[:ambient_loss_coefficient])
|
146
|
+
else
|
147
|
+
heater.setOffCycleLossFractiontoThermalZone(6)
|
148
|
+
heater.setOnCycleLossFractiontoThermalZone(6)
|
149
|
+
end
|
150
|
+
else
|
151
|
+
unless shw_hash[:ambient_loss_coefficient].nil?
|
152
|
+
heater.setOffCycleLossCoefficienttoAmbientTemperature(
|
153
|
+
shw_hash[:ambient_loss_coefficient])
|
154
|
+
heater.setOnCycleLossCoefficienttoAmbientTemperature(
|
155
|
+
shw_hash[:ambient_loss_coefficient])
|
156
|
+
else
|
157
|
+
heater.setOffCycleLossCoefficienttoAmbientTemperature(6)
|
158
|
+
heater.setOnCycleLossCoefficienttoAmbientTemperature(6)
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
# ensure that the tank is sized appropriately and add it to the loop
|
163
|
+
heater.setHeaterMaximumCapacity(1000000)
|
164
|
+
heater.setTankVolume(@@shw_rates[shw_hash[:identifier]])
|
165
|
+
hot_water_plant.addSupplyBranchForComponent(heater)
|
166
|
+
|
167
|
+
# if it's a heat pump system, then add the pump
|
168
|
+
if eq_type == 'HeatPump_WaterHeater'
|
169
|
+
# create a coil for the heat pump
|
170
|
+
heat_pump = OpenStudio::Model::CoilWaterHeatingAirToWaterHeatPump.new(openstudio_model)
|
171
|
+
heat_pump.setName('HPWH DX Coil' + @@sys_count.to_s)
|
172
|
+
if shw_hash[:heater_efficiency].nil?
|
173
|
+
heat_pump.setRatedCOP(3.5)
|
174
|
+
else
|
175
|
+
heat_pump.setRatedCOP(shw_hash[:heater_efficiency])
|
176
|
+
end
|
177
|
+
|
178
|
+
# add a fan for the heat pump system
|
179
|
+
fan = OpenStudio::Model::FanOnOff.new(openstudio_model)
|
180
|
+
fan.setName('HPWH Fan' + @@sys_count.to_s)
|
181
|
+
fan.setEndUseSubcategory('Water Systems')
|
182
|
+
setpt_sch = create_constant_schedule(
|
183
|
+
openstudio_model, 'HPWH Setpoint' + @@sys_count.to_s, @@max_target_temp + (@@hp_deadband * 2))
|
184
|
+
inlet_sch = create_constant_schedule(
|
185
|
+
openstudio_model, 'Inlet Air Mixer Fraction' + @@sys_count.to_s, 0.2)
|
186
|
+
|
187
|
+
# add a water heater to supply the heat for the loop
|
188
|
+
heat_sys = OpenStudio::Model::WaterHeaterHeatPump.new(
|
189
|
+
openstudio_model, heat_pump, heater, fan, setpt_sch, inlet_sch)
|
190
|
+
heat_sys.setDeadBandTemperatureDifference(@@hp_deadband)
|
191
|
+
|
192
|
+
source_zone_ref = openstudio_model.getThermalZoneByName(shw_hash[:ambient_condition])
|
193
|
+
unless source_zone_ref.empty?
|
194
|
+
source_zone = source_zone_ref.get
|
195
|
+
heat_sys.addToThermalZone(source_zone)
|
196
|
+
end
|
197
|
+
heat_sys.setName('SHW WaterHeater HeatPump' + @@sys_count.to_s)
|
198
|
+
end
|
199
|
+
|
200
|
+
elsif eq_type == 'Gas_TanklessHeater' || eq_type == 'Electric_TanklessHeater'
|
201
|
+
# add a boiler to supply the heat for the loop
|
202
|
+
heater = OpenStudio::Model::BoilerHotWater.new(openstudio_model)
|
203
|
+
if eq_type == 'Electric_TanklessHeater'
|
204
|
+
heater.setFuelType('Electricity')
|
205
|
+
end
|
206
|
+
heater.setName('SHW Tankless WaterHeater' + @@sys_count.to_s)
|
207
|
+
heater.setEndUseSubcategory('Water Systems')
|
208
|
+
|
209
|
+
# set the water heater efficiency
|
210
|
+
unless shw_hash[:heater_efficiency].nil?
|
211
|
+
heater.setNominalThermalEfficiency(shw_hash[:heater_efficiency])
|
212
|
+
else
|
213
|
+
if eq_type == 'Electric_TanklessHeater'
|
214
|
+
heater.setNominalThermalEfficiency(1.0)
|
215
|
+
else
|
216
|
+
heater.setNominalThermalEfficiency(0.8)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# ensure that the boiler is sized appropriately and add it to the loop
|
221
|
+
heater.setNominalCapacity(1000000)
|
222
|
+
hot_water_plant.addSupplyBranchForComponent(heater)
|
223
|
+
end
|
224
|
+
|
225
|
+
# add all of the water use connections to the loop and total the capacity
|
226
|
+
@@shw_connections[shw_hash[:identifier]].each do |shw_conn|
|
227
|
+
hot_water_plant.addDemandBranchForComponent(shw_conn)
|
228
|
+
end
|
229
|
+
@@sys_count = @@sys_count + 1
|
87
230
|
end
|
88
|
-
|
89
|
-
hot_water_plant
|
90
231
|
end
|
91
232
|
|
92
|
-
def to_openstudio(openstudio_model, os_space)
|
233
|
+
def to_openstudio(openstudio_model, os_space, shw_name)
|
93
234
|
# create water use equipment + connection and set identifier
|
94
235
|
os_shw_def = OpenStudio::Model::WaterUseEquipmentDefinition.new(openstudio_model)
|
95
236
|
os_shw = OpenStudio::Model::WaterUseEquipment.new(os_shw_def)
|
@@ -101,6 +242,10 @@ module Honeybee
|
|
101
242
|
total_flow = (@hash[:flow_per_area].to_f * os_space.floorArea) / 3600000
|
102
243
|
os_shw_def.setPeakFlowRate(total_flow)
|
103
244
|
os_shw_def.setEndUseSubcategory('General')
|
245
|
+
if @@shw_rates[shw_name].nil?
|
246
|
+
@@shw_rates[shw_name] = 0
|
247
|
+
end
|
248
|
+
@@shw_rates[shw_name] = @@shw_rates[shw_name] + (total_flow * 3600)
|
104
249
|
|
105
250
|
# assign schedule
|
106
251
|
shw_schedule = openstudio_model.getScheduleByName(@hash[:schedule])
|
@@ -126,7 +271,13 @@ module Honeybee
|
|
126
271
|
@@max_target_temp = target_temp
|
127
272
|
@@max_temp_schedule = target_water_sch
|
128
273
|
end
|
129
|
-
|
274
|
+
if shw_name.nil?
|
275
|
+
shw_name = 'default_district_shw'
|
276
|
+
end
|
277
|
+
if @@shw_connections[shw_name].nil?
|
278
|
+
@@shw_connections[shw_name] = []
|
279
|
+
end
|
280
|
+
@@shw_connections[shw_name] << os_shw_conn
|
130
281
|
|
131
282
|
# assign sensible fraction if it exists
|
132
283
|
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.1
|
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-
|
14
|
+
date: 2021-10-10 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -187,6 +187,7 @@ files:
|
|
187
187
|
- lib/from_openstudio/material/window_simpleglazsys.rb
|
188
188
|
- lib/from_openstudio/model.rb
|
189
189
|
- lib/from_openstudio/model_object.rb
|
190
|
+
- lib/from_openstudio/schedule/fixed_interval.rb
|
190
191
|
- lib/from_openstudio/schedule/ruleset.rb
|
191
192
|
- lib/from_openstudio/schedule/type_limit.rb
|
192
193
|
- lib/from_openstudio/simulation/design_day.rb
|