honeybee-openstudio 2.38.0 → 2.38.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yaml +2 -2
- data/honeybee-openstudio.gemspec +1 -1
- data/lib/honeybee/_defaults/simulation-parameter.json +7 -1
- data/lib/measures/from_honeybee_model/measure.rb +1 -1
- data/lib/to_openstudio/load/service_hot_water.rb +151 -149
- data/lib/to_openstudio/simulation/parameter_model.rb +4 -0
- 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: 442c8aa4274ac13d16351b5dabe23eb51649a9948c3d6b65d34ff63807d27afe
|
4
|
+
data.tar.gz: ecc978397d71705ae9c87b85384533c2d7d9b0b1732357de8d06610011284c00
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50190abacb231e1d39ac4c80e4d90d889e97ea1369edcbc8cc5130162916b922cc972cf0218d0a99bf4a4e242b65e7a0ea0826b91295adbb24b5fda179997aa5
|
7
|
+
data.tar.gz: dbcd7a1cd8668934b040bf737f7bc86b2474d1d6a4fb78d85b64550aaf574690b25a1e7bf81ce477ae937bcd58f907fd8f3eb39765a1cd32a8ae124a66483cf9
|
data/.github/workflows/ci.yaml
CHANGED
@@ -15,8 +15,8 @@ jobs:
|
|
15
15
|
run: |
|
16
16
|
echo $(pwd)
|
17
17
|
echo $(ls)
|
18
|
-
docker pull nrel/openstudio:3.
|
19
|
-
docker run --name test --rm -d -t -v $(pwd):/work -w /work nrel/openstudio:3.
|
18
|
+
docker pull nrel/openstudio:3.7.0
|
19
|
+
docker run --name test --rm -d -t -v $(pwd):/work -w /work nrel/openstudio:3.7.0
|
20
20
|
docker exec -t test pwd
|
21
21
|
docker exec -t test ls
|
22
22
|
docker exec -t test bundle update
|
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.38.
|
7
|
+
spec.version = '2.38.2'
|
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
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
"servers": [],
|
4
4
|
"info": {
|
5
5
|
"description": "Honeybee simulation-parameter schema.",
|
6
|
-
"version": "1.
|
6
|
+
"version": "1.57.1",
|
7
7
|
"title": "Honeybee Simulation Parameter Schema",
|
8
8
|
"contact": {
|
9
9
|
"name": "Ladybug Tools",
|
@@ -919,6 +919,12 @@
|
|
919
919
|
"title": "Building Type",
|
920
920
|
"description": "Text for the building type to be used in the efficiency_standard. If the type is not recognized or is None, it will be assumed that the building is a generic NonResidential. The following have specified systems per the standard: Residential, NonResidential, MidriseApartment, HighriseApartment, LargeOffice, MediumOffice, SmallOffice, Retail, StripMall, PrimarySchool, SecondarySchool, SmallHotel, LargeHotel, Hospital, Outpatient, Warehouse, SuperMarket, FullServiceRestaurant, QuickServiceRestaurant, Laboratory, Courthouse.",
|
921
921
|
"type": "string"
|
922
|
+
},
|
923
|
+
"bypass_efficiency_sizing": {
|
924
|
+
"title": "Bypass Efficiency Sizing",
|
925
|
+
"description": "A boolean to indicate whether the efficiency standard should trigger an sizing run that sets the efficiencies of all HVAC equipment in the Model (False) or the standard should only be written into the OSM and the sizing run should be bypassed (True). Bypassing the sizing run is useful when you only want to check that the overall HVAC system architecture is correct and you do not want to wait the extra time that it takes to run the sizing calculation.",
|
926
|
+
"default": false,
|
927
|
+
"type": "boolean"
|
922
928
|
}
|
923
929
|
},
|
924
930
|
"additionalProperties": false
|
@@ -161,7 +161,7 @@ class FromHoneybeeModel < OpenStudio::Measure::ModelMeasure
|
|
161
161
|
|
162
162
|
# if an efficiency standard has been set on the model, then run sizing and set everything
|
163
163
|
building = model.getBuilding
|
164
|
-
unless building.standardsTemplate.empty?
|
164
|
+
unless $bypass_eff_sizing == true || building.standardsTemplate.empty?
|
165
165
|
puts 'Autosizing HVAC systems and assigning efficiencies'
|
166
166
|
standard_id = building.standardsTemplate.get
|
167
167
|
require 'openstudio-standards'
|
@@ -55,178 +55,180 @@ module Honeybee
|
|
55
55
|
def add_hot_water_plants(openstudio_model, shw_hashes)
|
56
56
|
# add district hot water loops to supply all of the shw_connections
|
57
57
|
shw_hashes.each do |shw_hash|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
58
|
+
unless @@shw_rates[shw_hash[:identifier]].nil?
|
59
|
+
# create the plant loop
|
60
|
+
hot_water_plant = OpenStudio::Model::PlantLoop.new(openstudio_model)
|
61
|
+
hot_water_plant.setName('SHW Loop ' + shw_hash[:identifier])
|
62
|
+
hot_water_plant.setMaximumLoopTemperature(@@max_target_temp)
|
63
|
+
hot_water_plant.setMinimumLoopTemperature(10) # default value in C from OpenStudio Application
|
63
64
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
65
|
+
# edit the sizing information to be for a hot water loop
|
66
|
+
loop_sizing = hot_water_plant.sizingPlant()
|
67
|
+
loop_sizing.setLoopType('Heating')
|
68
|
+
loop_sizing.setDesignLoopExitTemperature(@@max_target_temp)
|
69
|
+
loop_sizing.setLoopDesignTemperatureDifference(5) # default value in C from OpenStudio Application
|
69
70
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
71
|
+
# add a setpoint manager for the loop
|
72
|
+
hot_sch = @@max_temp_schedule
|
73
|
+
if @@max_temp_schedule.nil?
|
74
|
+
hot_sch_name = @@max_target_temp.to_s + 'C Hot Water'
|
75
|
+
hot_sch = create_constant_schedule(openstudio_model, hot_sch_name, @@max_target_temp)
|
76
|
+
end
|
77
|
+
sp_manager = OpenStudio::Model::SetpointManagerScheduled.new(openstudio_model, hot_sch)
|
78
|
+
sp_manager.addToNode(hot_water_plant.supplyOutletNode())
|
78
79
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
80
|
+
# add a constant speed pump for the loop
|
81
|
+
hot_water_pump = OpenStudio::Model::PumpConstantSpeed.new(openstudio_model)
|
82
|
+
hot_water_pump.setName('SHW Pump' + @@sys_count.to_s)
|
83
|
+
hot_water_pump.setRatedPumpHead(29891) # default value in Pa from OpenStudio Application
|
84
|
+
hot_water_pump.setMotorEfficiency(0.9) # default value from OpenStudio Application
|
85
|
+
hot_water_pump.addToNode(hot_water_plant.supplyInletNode())
|
85
86
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
87
|
+
eq_type = shw_hash[:equipment_type]
|
88
|
+
if eq_type == 'Default_District_SHW'
|
89
|
+
# add a district heating system to supply the heat for the loop
|
90
|
+
district_hw = OpenStudio::Model::WaterHeaterMixed.new(openstudio_model)
|
91
|
+
district_hw.setName('Ideal Service Hot Water Heater')
|
92
|
+
district_hw.setHeaterFuelType('DistrictHeating')
|
93
|
+
district_hw.setOffCycleParasiticFuelType('DistrictHeating')
|
94
|
+
district_hw.setOnCycleParasiticFuelType('DistrictHeating')
|
95
|
+
district_hw.setHeaterThermalEfficiency(1.0)
|
96
|
+
district_hw.setHeaterMaximumCapacity(1000000)
|
97
|
+
district_hw.setTankVolume(0)
|
98
|
+
district_hw.setHeaterControlType('Modulate')
|
99
|
+
target_sch_name = '22C Ambient Condition'
|
100
|
+
target_sch = create_constant_schedule(openstudio_model, target_sch_name, 22)
|
101
|
+
district_hw.setAmbientTemperatureSchedule(target_sch)
|
102
|
+
district_hw.setOffCycleLossCoefficienttoAmbientTemperature(0)
|
103
|
+
district_hw.setOnCycleLossCoefficienttoAmbientTemperature(0)
|
104
|
+
hot_water_plant.addSupplyBranchForComponent(district_hw)
|
105
|
+
# try to minimize the impact of the pump as much as possible
|
106
|
+
hot_water_pump.setEndUseSubcategory('Water Systems')
|
107
|
+
hot_water_pump.setMotorEfficiency(0.9)
|
108
|
+
else
|
109
|
+
# add a water heater to supply the heat for the loop
|
110
|
+
heater = OpenStudio::Model::WaterHeaterMixed.new(openstudio_model)
|
111
|
+
if eq_type == 'Electric_WaterHeater' || eq_type == 'HeatPump_WaterHeater' || eq_type == 'Electric_TanklessHeater'
|
112
|
+
heater.setHeaterFuelType('Electricity')
|
113
|
+
heater.setOffCycleParasiticFuelType('Electricity')
|
114
|
+
heater.setOnCycleParasiticFuelType('Electricity')
|
115
|
+
end
|
115
116
|
|
116
|
-
|
117
|
-
|
118
|
-
heater.setHeaterThermalEfficiency(1.0)
|
119
|
-
elsif shw_hash[:heater_efficiency].nil?
|
120
|
-
if eq_type == 'Electric_WaterHeater' || eq_type == 'Electric_TanklessHeater'
|
117
|
+
# set the water heater efficiency
|
118
|
+
if eq_type == 'HeatPump_WaterHeater'
|
121
119
|
heater.setHeaterThermalEfficiency(1.0)
|
120
|
+
elsif shw_hash[:heater_efficiency].nil?
|
121
|
+
if eq_type == 'Electric_WaterHeater' || eq_type == 'Electric_TanklessHeater'
|
122
|
+
heater.setHeaterThermalEfficiency(1.0)
|
123
|
+
else
|
124
|
+
heater.setHeaterThermalEfficiency(0.8)
|
125
|
+
end
|
122
126
|
else
|
123
|
-
heater.setHeaterThermalEfficiency(
|
127
|
+
heater.setHeaterThermalEfficiency(shw_hash[:heater_efficiency])
|
124
128
|
end
|
125
|
-
else
|
126
|
-
heater.setHeaterThermalEfficiency(shw_hash[:heater_efficiency])
|
127
|
-
end
|
128
129
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
130
|
+
# set the ambient condition of the water tank
|
131
|
+
to_thermal_zone = false
|
132
|
+
unless shw_hash[:ambient_condition].nil?
|
133
|
+
if shw_hash[:ambient_condition].is_a? Numeric
|
134
|
+
target_sch_name = shw_hash[:ambient_condition].to_s + 'C Ambient Condition'
|
135
|
+
target_sch = create_constant_schedule(
|
136
|
+
openstudio_model, target_sch_name, shw_hash[:ambient_condition])
|
137
|
+
heater.setAmbientTemperatureSchedule(target_sch)
|
138
|
+
else
|
139
|
+
source_zone_ref = openstudio_model.getThermalZoneByName(shw_hash[:ambient_condition])
|
140
|
+
unless source_zone_ref.empty?
|
141
|
+
source_zone = source_zone_ref.get
|
142
|
+
heater.setAmbientTemperatureThermalZone(source_zone)
|
143
|
+
end
|
144
|
+
heater.setAmbientTemperatureIndicator('ThermalZone')
|
145
|
+
to_thermal_zone = true
|
142
146
|
end
|
143
|
-
heater.setAmbientTemperatureIndicator('ThermalZone')
|
144
|
-
to_thermal_zone = true
|
145
|
-
end
|
146
|
-
else
|
147
|
-
target_sch_name = '22C Ambient Condition'
|
148
|
-
target_sch = create_constant_schedule(openstudio_model, target_sch_name, 22)
|
149
|
-
heater.setAmbientTemperatureSchedule(target_sch)
|
150
|
-
end
|
151
|
-
|
152
|
-
# set the ambient loss coefficient
|
153
|
-
if to_thermal_zone
|
154
|
-
unless shw_hash[:ambient_loss_coefficient].nil?
|
155
|
-
heater.setOffCycleLossFractiontoThermalZone(
|
156
|
-
shw_hash[:ambient_loss_coefficient])
|
157
|
-
heater.setOnCycleLossFractiontoThermalZone(
|
158
|
-
shw_hash[:ambient_loss_coefficient])
|
159
147
|
else
|
160
|
-
|
161
|
-
|
148
|
+
target_sch_name = '22C Ambient Condition'
|
149
|
+
target_sch = create_constant_schedule(openstudio_model, target_sch_name, 22)
|
150
|
+
heater.setAmbientTemperatureSchedule(target_sch)
|
162
151
|
end
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
152
|
+
|
153
|
+
# set the ambient loss coefficient
|
154
|
+
if to_thermal_zone
|
155
|
+
unless shw_hash[:ambient_loss_coefficient].nil?
|
156
|
+
heater.setOffCycleLossFractiontoThermalZone(
|
157
|
+
shw_hash[:ambient_loss_coefficient])
|
158
|
+
heater.setOnCycleLossFractiontoThermalZone(
|
159
|
+
shw_hash[:ambient_loss_coefficient])
|
160
|
+
else
|
161
|
+
heater.setOffCycleLossFractiontoThermalZone(6)
|
162
|
+
heater.setOnCycleLossFractiontoThermalZone(6)
|
163
|
+
end
|
169
164
|
else
|
170
|
-
|
171
|
-
|
165
|
+
unless shw_hash[:ambient_loss_coefficient].nil?
|
166
|
+
heater.setOffCycleLossCoefficienttoAmbientTemperature(
|
167
|
+
shw_hash[:ambient_loss_coefficient])
|
168
|
+
heater.setOnCycleLossCoefficienttoAmbientTemperature(
|
169
|
+
shw_hash[:ambient_loss_coefficient])
|
170
|
+
else
|
171
|
+
heater.setOffCycleLossCoefficienttoAmbientTemperature(6)
|
172
|
+
heater.setOnCycleLossCoefficienttoAmbientTemperature(6)
|
173
|
+
end
|
172
174
|
end
|
173
|
-
end
|
174
175
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
else
|
184
|
-
heater.setName('SHW WaterHeater' + @@sys_count.to_s)
|
185
|
-
heater.setTankVolume(@@shw_rates[shw_hash[:identifier]])
|
186
|
-
end
|
187
|
-
|
188
|
-
# add it to the loop
|
189
|
-
hot_water_plant.addSupplyBranchForComponent(heater)
|
190
|
-
|
191
|
-
# if it's a heat pump system, then add the pump
|
192
|
-
if eq_type == 'HeatPump_WaterHeater'
|
193
|
-
# create a coil for the heat pump
|
194
|
-
heat_pump = OpenStudio::Model::CoilWaterHeatingAirToWaterHeatPump.new(openstudio_model)
|
195
|
-
heat_pump.setName('SHW HPWH DX Coil' + @@sys_count.to_s)
|
196
|
-
if shw_hash[:heater_efficiency].nil?
|
197
|
-
heat_pump.setRatedCOP(3.5)
|
176
|
+
# set the capactiy and and controls of the water heater
|
177
|
+
heater.setHeaterMaximumCapacity(1000000)
|
178
|
+
if eq_type == 'Gas_TanklessHeater' || eq_type == 'Electric_TanklessHeater'
|
179
|
+
heater.setName('SHW Tankless WaterHeater' + @@sys_count.to_s)
|
180
|
+
heater.setTankVolume(0)
|
181
|
+
heater.setHeaterControlType('Modulate')
|
182
|
+
heater.setOffCycleLossCoefficienttoAmbientTemperature(0)
|
183
|
+
heater.setOnCycleLossCoefficienttoAmbientTemperature(0)
|
198
184
|
else
|
199
|
-
|
185
|
+
heater.setName('SHW WaterHeater' + @@sys_count.to_s)
|
186
|
+
heater.setTankVolume(@@shw_rates[shw_hash[:identifier]])
|
200
187
|
end
|
201
188
|
|
202
|
-
# add
|
203
|
-
|
204
|
-
fan.setName('HPWH Fan' + @@sys_count.to_s)
|
205
|
-
fan.setEndUseSubcategory('Water Systems')
|
206
|
-
setpt_sch = create_constant_schedule(
|
207
|
-
openstudio_model, 'HPWH Setpoint' + @@sys_count.to_s, @@max_target_temp + (@@hp_deadband * 2))
|
208
|
-
inlet_sch = create_constant_schedule(
|
209
|
-
openstudio_model, 'Inlet Air Mixer Fraction' + @@sys_count.to_s, 0.2)
|
210
|
-
|
211
|
-
# add a water heater to supply the heat for the loop
|
212
|
-
heat_sys = OpenStudio::Model::WaterHeaterHeatPump.new(
|
213
|
-
openstudio_model, heat_pump, heater, fan, setpt_sch, inlet_sch)
|
214
|
-
heat_sys.setDeadBandTemperatureDifference(@@hp_deadband)
|
189
|
+
# add it to the loop
|
190
|
+
hot_water_plant.addSupplyBranchForComponent(heater)
|
215
191
|
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
192
|
+
# if it's a heat pump system, then add the pump
|
193
|
+
if eq_type == 'HeatPump_WaterHeater'
|
194
|
+
# create a coil for the heat pump
|
195
|
+
heat_pump = OpenStudio::Model::CoilWaterHeatingAirToWaterHeatPump.new(openstudio_model)
|
196
|
+
heat_pump.setName('SHW HPWH DX Coil' + @@sys_count.to_s)
|
197
|
+
if shw_hash[:heater_efficiency].nil?
|
198
|
+
heat_pump.setRatedCOP(3.5)
|
199
|
+
else
|
200
|
+
heat_pump.setRatedCOP(shw_hash[:heater_efficiency])
|
201
|
+
end
|
202
|
+
|
203
|
+
# add a fan for the heat pump system
|
204
|
+
fan = OpenStudio::Model::FanOnOff.new(openstudio_model)
|
205
|
+
fan.setName('HPWH Fan' + @@sys_count.to_s)
|
206
|
+
fan.setEndUseSubcategory('Water Systems')
|
207
|
+
setpt_sch = create_constant_schedule(
|
208
|
+
openstudio_model, 'HPWH Setpoint' + @@sys_count.to_s, @@max_target_temp + (@@hp_deadband * 2))
|
209
|
+
inlet_sch = create_constant_schedule(
|
210
|
+
openstudio_model, 'Inlet Air Mixer Fraction' + @@sys_count.to_s, 0.2)
|
211
|
+
|
212
|
+
# add a water heater to supply the heat for the loop
|
213
|
+
heat_sys = OpenStudio::Model::WaterHeaterHeatPump.new(
|
214
|
+
openstudio_model, heat_pump, heater, fan, setpt_sch, inlet_sch)
|
215
|
+
heat_sys.setDeadBandTemperatureDifference(@@hp_deadband)
|
216
|
+
|
217
|
+
source_zone_ref = openstudio_model.getThermalZoneByName(shw_hash[:ambient_condition])
|
218
|
+
unless source_zone_ref.empty?
|
219
|
+
source_zone = source_zone_ref.get
|
220
|
+
heat_sys.addToThermalZone(source_zone)
|
221
|
+
end
|
222
|
+
heat_sys.setName('SHW WaterHeater HeatPump' + @@sys_count.to_s)
|
220
223
|
end
|
221
|
-
heat_sys.setName('SHW WaterHeater HeatPump' + @@sys_count.to_s)
|
222
224
|
end
|
223
|
-
end
|
224
225
|
|
225
|
-
|
226
|
-
|
227
|
-
|
226
|
+
# add all of the water use connections to the loop and total the capacity
|
227
|
+
@@shw_connections[shw_hash[:identifier]].each do |shw_conn|
|
228
|
+
hot_water_plant.addDemandBranchForComponent(shw_conn)
|
229
|
+
end
|
230
|
+
@@sys_count = @@sys_count + 1
|
228
231
|
end
|
229
|
-
@@sys_count = @@sys_count + 1
|
230
232
|
end
|
231
233
|
end
|
232
234
|
|
@@ -50,6 +50,7 @@ module Honeybee
|
|
50
50
|
def to_openstudio_model(openstudio_model=nil, log_report=false)
|
51
51
|
@errors = []
|
52
52
|
@warnings = []
|
53
|
+
$bypass_eff_sizing = false # default value to bypass efficiency standard
|
53
54
|
|
54
55
|
if log_report
|
55
56
|
puts 'Starting SimulationParameter translation from Honeybee to OpenStudio'
|
@@ -252,6 +253,9 @@ module Honeybee
|
|
252
253
|
building = @openstudio_model.getBuilding
|
253
254
|
building.setStandardsBuildingType(@hash[:sizing_parameter][:building_type])
|
254
255
|
end
|
256
|
+
unless @hash[:sizing_parameter][:bypass_efficiency_sizing].nil?
|
257
|
+
$bypass_eff_sizing = @hash[:sizing_parameter][:bypass_efficiency_sizing]
|
258
|
+
end
|
255
259
|
end
|
256
260
|
|
257
261
|
# set defaults for the simulation output
|
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.38.
|
4
|
+
version: 2.38.2
|
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: 2024-
|
14
|
+
date: 2024-02-23 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: json_pure
|