honeybee-openstudio 2.33.6 → 2.34.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/measures/from_honeybee_model/measure.rb +81 -1
- data/lib/to_openstudio/hvac/Model.hvac.rb +4 -0
- data/lib/to_openstudio/hvac/template.rb +35 -18
- data/lib/to_openstudio/model.rb +10 -5
- data/lib/to_openstudio/simulation/parameter_model.rb +26 -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: 0db23d24e0621410e05134519babfe4ae11c803b8df518b3e587afb836eb0304
|
4
|
+
data.tar.gz: b2984946072c3c094057e5e0f97dd52c15012290fa6953d1b245d95c9f9f6a06
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e948fb628063eb9f0d7bc6477aaa3e05b425cc68ac0e3127472a7a8df34f7050d70901538f39656aaa39198465a6515ccc9697d632d38249ac1914e218f9dafc
|
7
|
+
data.tar.gz: 46cf5d6d1619847528ce5ae15b592dab6c16492b87deb13ca38c5270af7918af581e18891b6062c3904f3b9b0322812815e53cb633dde1699f2b580461650005
|
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.34.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
|
|
@@ -36,6 +36,7 @@ require 'to_openstudio'
|
|
36
36
|
|
37
37
|
require 'fileutils'
|
38
38
|
require 'pathname'
|
39
|
+
require 'json'
|
39
40
|
|
40
41
|
# start the measure
|
41
42
|
class FromHoneybeeModel < OpenStudio::Measure::ModelMeasure
|
@@ -87,17 +88,19 @@ class FromHoneybeeModel < OpenStudio::Measure::ModelMeasure
|
|
87
88
|
return false
|
88
89
|
end
|
89
90
|
|
91
|
+
# get the input arguments
|
90
92
|
model_json = runner.getStringArgumentValue('model_json', user_arguments)
|
91
93
|
schedule_csv_dir = runner.getStringArgumentValue('schedule_csv_dir', user_arguments)
|
92
94
|
include_datetimes = runner.getBoolArgumentValue('include_datetimes', user_arguments)
|
93
95
|
|
96
|
+
# load the HBJSON file
|
94
97
|
if !File.exist?(model_json)
|
95
98
|
runner.registerError("Cannot find file '#{model_json}'")
|
96
99
|
return false
|
97
100
|
end
|
98
|
-
|
99
101
|
honeybee_model = Honeybee::Model.read_from_disk(model_json)
|
100
102
|
|
103
|
+
# setup the schedule directory
|
101
104
|
if schedule_csv_dir && !schedule_csv_dir.empty?
|
102
105
|
schedule_csv_dir = Pathname.new(schedule_csv_dir).cleanpath
|
103
106
|
if !Dir.exist?(schedule_csv_dir)
|
@@ -107,11 +110,88 @@ class FromHoneybeeModel < OpenStudio::Measure::ModelMeasure
|
|
107
110
|
honeybee_model.set_schedule_csv_dir(schedule_csv_dir, include_datetimes)
|
108
111
|
end
|
109
112
|
|
113
|
+
# translate the Honeybee Model to OSM
|
110
114
|
STDOUT.flush
|
111
115
|
honeybee_model.to_openstudio_model(model)
|
112
116
|
STDOUT.flush
|
113
117
|
|
118
|
+
# if there are any detailed HVACs, incorproate them into the OSM
|
114
119
|
generated_files_dir = "#{runner.workflow.absoluteRootDir}/generated_files"
|
120
|
+
unless $detailed_hvac_hash.nil? || $detailed_hvac_hash.empty?
|
121
|
+
runner.registerInfo("Translating Detailed HVAC systems in '#{generated_files_dir}'")
|
122
|
+
if $ironbug_exe.nil?
|
123
|
+
runner.registerError("No Ironbug installation was found on the system.")
|
124
|
+
end
|
125
|
+
FileUtils.mkdir_p(generated_files_dir)
|
126
|
+
$detailed_hvac_hash.each do |hvac_id, hvac_spec|
|
127
|
+
# write the JSON and OSM files
|
128
|
+
hvac_json_path = generated_files_dir + '/' + hvac_id + '.json'
|
129
|
+
osm_path = generated_files_dir + '/' + hvac_id + '.osm'
|
130
|
+
File.open(hvac_json_path, 'w') do |f|
|
131
|
+
f.write(hvac_spec.to_json)
|
132
|
+
end
|
133
|
+
model.save(osm_path, true)
|
134
|
+
# call the Ironbug console to add the HVAC to the OSM
|
135
|
+
ironbug_exe = '"' + $ironbug_exe + '"'
|
136
|
+
system(ironbug_exe + ' "' + osm_path + '" "' + hvac_json_path + '"')
|
137
|
+
# load the new model
|
138
|
+
translator = OpenStudio::OSVersion::VersionTranslator.new
|
139
|
+
o_model = translator.loadModel(osm_path)
|
140
|
+
if o_model.empty?
|
141
|
+
runner.registerError("Could not load Ironbug model from '" + osm_path.to_s + "'.")
|
142
|
+
return false
|
143
|
+
end
|
144
|
+
new_model = o_model.get
|
145
|
+
# replace the current model with the contents of the loaded model
|
146
|
+
handles = OpenStudio::UUIDVector.new
|
147
|
+
model.objects.each do |obj|
|
148
|
+
handles << obj.handle
|
149
|
+
end
|
150
|
+
model.removeObjects(handles)
|
151
|
+
# add new file to empty model
|
152
|
+
model.addObjects(new_model.toIdfFile.objects)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# if an efficiency standard has been set on the model, then run sizing and set everything
|
157
|
+
building = model.getBuilding
|
158
|
+
unless building.standardsTemplate.empty?
|
159
|
+
puts 'Autosizing HVAC systems and assigning efficiencies'
|
160
|
+
standard_id = building.standardsTemplate.get
|
161
|
+
require 'openstudio-standards'
|
162
|
+
standard = Standard.build(standard_id)
|
163
|
+
# Set the heating and cooling sizing parameters
|
164
|
+
standard.model_apply_prm_sizing_parameters(model)
|
165
|
+
# Perform a sizing run
|
166
|
+
if standard.model_run_sizing_run(model, "#{Dir.pwd}/SR1") == false
|
167
|
+
log_messages_to_runner(runner, debug = true)
|
168
|
+
return false
|
169
|
+
end
|
170
|
+
# If there are any multizone systems, reset damper positions
|
171
|
+
# to achieve a 60% ventilation effectiveness minimum for the system
|
172
|
+
# following the ventilation rate procedure from 62.1
|
173
|
+
standard.model_apply_multizone_vav_outdoor_air_sizing(model)
|
174
|
+
# get the climate zone
|
175
|
+
climate_zone_obj = model.getClimateZones.getClimateZone('ASHRAE', 2006)
|
176
|
+
if climate_zone_obj.empty
|
177
|
+
climate_zone_obj = model.getClimateZones.getClimateZone('ASHRAE', 2013)
|
178
|
+
end
|
179
|
+
climate_zone = climate_zone_obj.value
|
180
|
+
# get the building type
|
181
|
+
bldg_type = nil
|
182
|
+
unless building.standardsBuildingType.empty?
|
183
|
+
bldg_type = building.standardsBuildingType.get
|
184
|
+
end
|
185
|
+
# Apply the prototype HVAC assumptions
|
186
|
+
standard.model_apply_prototype_hvac_assumptions(model, bldg_type, climate_zone)
|
187
|
+
# Apply the HVAC efficiency standard
|
188
|
+
standard.model_apply_hvac_efficiency_standard(model, climate_zone)
|
189
|
+
puts 'Done with autosizing HVAC systems!'
|
190
|
+
end
|
191
|
+
|
192
|
+
puts 'Done with Model translation!'
|
193
|
+
|
194
|
+
# copy the CSV schedules into the directory where EnergyPlus can find them
|
115
195
|
if schedule_csv_dir && !schedule_csv_dir.empty?
|
116
196
|
if Dir.exist?(schedule_csv_dir)
|
117
197
|
runner.registerInfo("Copying exported schedules from '#{schedule_csv_dir}' to '#{generated_files_dir}'")
|
@@ -308,6 +308,10 @@ class OpenStudio::Model::Model
|
|
308
308
|
when 'Furnace'
|
309
309
|
# includes ventilation, whereas residential forced air furnace does not.
|
310
310
|
standard.model_add_hvac_system(self, 'Forced Air Furnace', ht = 'NaturalGas', znht = nil, cl = nil, heated_zones)
|
311
|
+
|
312
|
+
when 'Furnace_Electric'
|
313
|
+
# includes ventilation, whereas residential forced air furnace does not.
|
314
|
+
standard.model_add_hvac_system(self, 'Forced Air Furnace', ht = 'Electricity', znht = nil, cl = nil, heated_zones)
|
311
315
|
|
312
316
|
when 'GasHeaters'
|
313
317
|
standard.model_add_hvac_system(self, 'Unit Heaters', ht = 'NaturalGas', znht = nil, cl = nil, heated_zones)
|
@@ -90,26 +90,28 @@ module Honeybee
|
|
90
90
|
|
91
91
|
# Get the air loops and assign the display name to the air loop name if it exists
|
92
92
|
os_air_loops = []
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
93
|
+
unless equipment_type.to_s.include? 'Furnace'
|
94
|
+
air_loops = openstudio_model.getAirLoopHVACs
|
95
|
+
unless air_loops.length == $air_loop_count
|
96
|
+
$air_loop_count = air_loops.length
|
97
|
+
zones.each do |zon|
|
98
|
+
os_air_terminal = zon.airLoopHVACTerminal
|
99
|
+
unless os_air_terminal.empty?
|
100
|
+
os_air_terminal = os_air_terminal.get
|
101
|
+
os_air_loop_opt = os_air_terminal.airLoopHVAC
|
102
|
+
unless os_air_loop_opt.empty?
|
103
|
+
os_air_loop = os_air_loop_opt.get
|
104
|
+
os_air_loops << os_air_loop
|
105
|
+
loop_name = os_air_loop.name
|
106
|
+
unless loop_name.empty?
|
107
|
+
# set the name of the air loop to align with the HVAC name
|
108
|
+
if @hash[:display_name]
|
109
|
+
clean_name = @hash[:display_name].to_s.gsub(/[^.A-Za-z0-9_-] /, " ")
|
110
|
+
os_air_loop.setName(clean_name + ' - ' + loop_name.get)
|
111
|
+
end
|
110
112
|
end
|
113
|
+
break if !equipment_type.include? 'PSZ' # multiple air loops have been added
|
111
114
|
end
|
112
|
-
break if !equipment_type.include? 'PSZ' # multiple air loops have been added
|
113
115
|
end
|
114
116
|
end
|
115
117
|
end
|
@@ -197,6 +199,21 @@ module Honeybee
|
|
197
199
|
end
|
198
200
|
end
|
199
201
|
|
202
|
+
# change furnace to electric if specified
|
203
|
+
if equipment_type.to_s.include? 'Furnace_Electric'
|
204
|
+
openstudio_model.getAirLoopHVACUnitarySystems.sort.each do |obj|
|
205
|
+
unless obj.heatingCoil.empty?
|
206
|
+
old_coil = obj.heatingCoil.get
|
207
|
+
heat_coil = OpenStudio::Model::CoilHeatingElectric.new(openstudio_model)
|
208
|
+
unless old_coil.name.empty?
|
209
|
+
heat_coil.setName(old_coil.name.get)
|
210
|
+
end
|
211
|
+
obj.setHeatingCoil(heat_coil)
|
212
|
+
old_coil.remove()
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
200
217
|
# assign the economizer type if there's an air loop and the economizer is specified
|
201
218
|
if @hash[:economizer_type] && !os_air_loops.empty?
|
202
219
|
os_air_loops.each do |os_air_loop|
|
data/lib/to_openstudio/model.rb
CHANGED
@@ -92,10 +92,6 @@ module Honeybee
|
|
92
92
|
# create all openstudio objects in the model
|
93
93
|
create_openstudio_objects(log_report)
|
94
94
|
|
95
|
-
if log_report
|
96
|
-
puts 'Done with Model translation!'
|
97
|
-
end
|
98
|
-
|
99
95
|
@openstudio_model
|
100
96
|
end
|
101
97
|
|
@@ -105,7 +101,9 @@ module Honeybee
|
|
105
101
|
def create_openstudio_objects(log_report=true)
|
106
102
|
# assign a standards building type so that David's measures can run
|
107
103
|
building = @openstudio_model.getBuilding
|
108
|
-
building.
|
104
|
+
if building.standardsBuildingType.empty?
|
105
|
+
building.setStandardsBuildingType('MediumOffice')
|
106
|
+
end
|
109
107
|
|
110
108
|
# initialize a global variable for whether the AFN is used instead of simple ventilation
|
111
109
|
$use_simple_vent = true
|
@@ -127,6 +125,8 @@ module Honeybee
|
|
127
125
|
$programtype_setpoint_hash = Hash.new # hash to track Setpoint objects
|
128
126
|
$interior_afn_srf_hash = Hash.new # track whether an adjacent surface is already in the AFN
|
129
127
|
$shw_for_plant = nil # track whether a hot water plant is needed
|
128
|
+
$detailed_hvac_hash = Hash.new # track the detailed HVAC systems that have been assigned
|
129
|
+
$ironbug_exe = nil # ironbug executable; will be overwritten by any detailed HVACs
|
130
130
|
|
131
131
|
# create all of the non-geometric model elements
|
132
132
|
if @hash[:properties].key?(:energy)
|
@@ -572,6 +572,11 @@ module Honeybee
|
|
572
572
|
end
|
573
573
|
end
|
574
574
|
end
|
575
|
+
elsif system_type == 'DetailedHVAC'
|
576
|
+
$detailed_hvac_hash[hvac[:identifier]] = hvac[:specification]
|
577
|
+
unless hvac[:ironbug_exe].nil?
|
578
|
+
$ironbug_exe = hvac[:ironbug_exe]
|
579
|
+
end
|
575
580
|
elsif TemplateHVAC.types.include?(system_type)
|
576
581
|
template_system = TemplateHVAC.new(hvac)
|
577
582
|
template_system.to_openstudio(@openstudio_model, hvac['rooms'])
|
@@ -35,6 +35,16 @@ require 'openstudio'
|
|
35
35
|
|
36
36
|
module Honeybee
|
37
37
|
class SimulationParameter
|
38
|
+
@@standard_mapper = {
|
39
|
+
DOE_Ref_Pre_1980: 'DOE Ref Pre-1980',
|
40
|
+
DOE_Ref_1980_2004: 'DOE Ref 1980-2004',
|
41
|
+
ASHRAE_2004: '90.1-2004',
|
42
|
+
ASHRAE_2007: '90.1-2007',
|
43
|
+
ASHRAE_2010: '90.1-2010',
|
44
|
+
ASHRAE_2013: '90.1-2013',
|
45
|
+
ASHRAE_2016: '90.1-2016',
|
46
|
+
ASHRAE_2019: '90.1-2019'
|
47
|
+
}
|
38
48
|
|
39
49
|
# convert to openstudio model, clears errors and warnings
|
40
50
|
def to_openstudio_model(openstudio_model=nil, log_report=false)
|
@@ -226,6 +236,22 @@ module Honeybee
|
|
226
236
|
climate_zone_objs.setClimateZone('ASHRAE', cz)
|
227
237
|
end
|
228
238
|
|
239
|
+
# note any efficency standards that have been assigned to the
|
240
|
+
if @hash[:sizing_parameter]
|
241
|
+
if @hash[:sizing_parameter][:efficiency_standard]
|
242
|
+
std_gem_standard = @@standard_mapper[@hash[:sizing_parameter][:efficiency_standard].to_sym]
|
243
|
+
building = @openstudio_model.getBuilding
|
244
|
+
building.setStandardsTemplate(std_gem_standard)
|
245
|
+
end
|
246
|
+
if @hash[:sizing_parameter][:climate_zone]
|
247
|
+
climate_zone_objs.setClimateZone('ASHRAE', @hash[:sizing_parameter][:climate_zone])
|
248
|
+
end
|
249
|
+
if @hash[:sizing_parameter][:building_type]
|
250
|
+
building = @openstudio_model.getBuilding
|
251
|
+
building.setStandardsBuildingType(@hash[:sizing_parameter][:building_type])
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
229
255
|
# set Outputs for the simulation
|
230
256
|
if @hash[:output]
|
231
257
|
if @hash[:output][:outputs]
|
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.34.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: 2023-
|
14
|
+
date: 2023-02-11 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: json_pure
|