From 9c67e326814739f2f8c8ec228833a1751dab0913 Mon Sep 17 00:00:00 2001 From: Eric Ringold Date: Tue, 2 Jul 2024 17:16:07 -0600 Subject: [PATCH 1/3] fix new matched rules getting removed --- .../schedules/parametric.rb | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/openstudio-standards/schedules/parametric.rb b/lib/openstudio-standards/schedules/parametric.rb index eb3fdc4885..a723afae40 100644 --- a/lib/openstudio-standards/schedules/parametric.rb +++ b/lib/openstudio-standards/schedules/parametric.rb @@ -510,9 +510,15 @@ def self.schedule_ruleset_get_parametric_inputs(schedule_ruleset, space_load_ins # set scheduleRuleset properties props = schedule_ruleset.additionalProperties - props.setFeature('param_sch_ver', '0.0.1') # this is needed to see if formulas are in sync with version of standards that processes them also used to flag schedule as parametric - props.setFeature('param_sch_floor', min_max['min']) - props.setFeature('param_sch_ceiling', min_max['max']) + + if props.getFeatureAsString('param_sch_ver') == '0.0.1' + # don't need to gather more than once + return parametric_inputs + else + props.setFeature('param_sch_ver', '0.0.1') # this is needed to see if formulas are in sync with version of standards that processes them also used to flag schedule as parametric + props.setFeature('param_sch_floor', min_max['min']) + props.setFeature('param_sch_ceiling', min_max['max']) + end # cleanup existing profiles OpenstudioStandards::Schedules.schedule_ruleset_cleanup_profiles(schedule_ruleset) @@ -525,8 +531,11 @@ def self.schedule_ruleset_get_parametric_inputs(schedule_ruleset, space_load_ins sch_ruleset_days_used = OpenstudioStandards::Schedules.schedule_ruleset_get_annual_days_used(schedule_ruleset) # match up schedule rule days with hours of operation days + # sch_day_map is a hash where keys are the rule indices of the schedule + # and values are hashes where keys are the hours of operation rule index, and values are arrays of days that the shcedu sch_day_map = {} sch_ruleset_days_used.each do |sch_index, sch_days| + # first create a hash that maps each day index to the hoo index that covers that day day_map = {} sch_days.each do |day| # find the hour of operation rule that contains the day number @@ -555,6 +564,8 @@ def self.schedule_ruleset_get_parametric_inputs(schedule_ruleset, space_load_ins # skip if rules already match if (sch_ruleset_days_used[sch_index] - day_group).empty? OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.Parametric.Schedules', "in #{__method__}: #{schedule_ruleset.name} rule #{sch_index} already matches hours of operation rule #{hoo_index}; new rule won't be created.") + # iterate new_rule_ct anyway to keep these rules + new_rule_ct += 1 unless sch_index == -1 next end # create new rules @@ -563,7 +574,9 @@ def self.schedule_ruleset_get_parametric_inputs(schedule_ruleset, space_load_ins end end # new rules are created at top of list - cleanup old rules - schedule_ruleset.scheduleRules[new_rule_ct..-1].each(&:remove) unless new_rule_ct == 0 + if !(new_rule_ct == 0 || new_rule_ct == schedule_ruleset.scheduleRules.size) + schedule_ruleset.scheduleRules[new_rule_ct..-1].each(&:remove) + end # re-collect new schedule rules schedule_days = OpenstudioStandards::Schedules.schedule_ruleset_get_schedule_day_rule_indices(schedule_ruleset) From 91161fa047171eebdf2be04948cb10b5d931d27d Mon Sep 17 00:00:00 2001 From: Eric Ringold Date: Tue, 2 Jul 2024 17:17:10 -0600 Subject: [PATCH 2/3] catch missing stat file ground temps --- lib/openstudio-standards/weather/modify.rb | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/lib/openstudio-standards/weather/modify.rb b/lib/openstudio-standards/weather/modify.rb index b0e31b9195..f7fcc008da 100644 --- a/lib/openstudio-standards/weather/modify.rb +++ b/lib/openstudio-standards/weather/modify.rb @@ -74,6 +74,10 @@ def self.model_set_undisturbed_ground_temperature_shallow(model, stat_file: nil) stat_file = OpenstudioStandards::Weather::StatFile.load(weather_file_path.sub('.epw', '.stat')) end + if stat_file.monthly_undis_ground_temps_0p5m.empty? + return false + end + # set ground temperature shallow values based on .stat file ground_temperature_shallow = OpenStudio::Model::SiteGroundTemperatureShallow.new(model) ground_temperature_shallow.setJanuarySurfaceGroundTemperature(stat_file.monthly_undis_ground_temps_0p5m[0]) @@ -104,6 +108,10 @@ def self.model_set_undisturbed_ground_temperature_deep(model, stat_file: nil) stat_file = OpenstudioStandards::Weather::StatFile.load(weather_file_path.sub('.epw', '.stat')) end + if stat_file.monthly_undis_ground_temps_4p0m.empty? + return false + end + # set ground temperature deep values based on .stat file ground_temperature_deep = OpenStudio::Model::SiteGroundTemperatureDeep.new(model) ground_temperature_deep.setJanuaryDeepGroundTemperature(stat_file.monthly_undis_ground_temps_4p0m[0]) @@ -364,7 +372,7 @@ def self.model_set_building_location(model, ddy_list: nil) # check that either weather_file_path or climate_zone provided if weather_file_path.nil? && climate_zone.nil? - OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Weather.modify', 'model_set_building_location must be called with either the weather_file_path or climate_zone argument specified.') + OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Weather.modify', "#{__method__} must be called with either the weather_file_path or climate_zone argument specified.") return false end @@ -389,8 +397,14 @@ def self.model_set_building_location(model, if File.file?(stat_file_path) stat_file = OpenstudioStandards::Weather::StatFile.load(stat_file_path) OpenstudioStandards::Weather.model_set_site_water_mains_temperature(model, stat_file: stat_file) - OpenstudioStandards::Weather.model_set_undisturbed_ground_temperature_shallow(model, stat_file: stat_file) - OpenstudioStandards::Weather.model_set_undisturbed_ground_temperature_deep(model, stat_file: stat_file) + if !OpenstudioStandards::Weather.model_set_undisturbed_ground_temperature_shallow(model, stat_file: stat_file) + OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Weather.modify', "Could not find undisturbed shallow ground temps in .stat file at #{stat_file_path}. Unable to set undisturbed ground temperatures.") + end + + if !OpenstudioStandards::Weather.model_set_undisturbed_ground_temperature_deep(model, stat_file: stat_file) + OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Weather.modify', "Could not find undisturbed deep ground temps in .stat file at #{stat_file_path}. Unable to set undisturbed ground temperatures.") + end + stat_file_climate_zone = stat_file.climate_zone else OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Weather.modify', "Could not find .stat file at #{stat_file_path}. Unable to set site water mains temperature and undisturbed ground temperatures.") From f67df86654688485dc40470b2cb2decdf720a078 Mon Sep 17 00:00:00 2001 From: Eric Ringold Date: Wed, 3 Jul 2024 14:14:55 -0600 Subject: [PATCH 3/3] rubocop fixes --- lib/openstudio-standards/schedules/parametric.rb | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/lib/openstudio-standards/schedules/parametric.rb b/lib/openstudio-standards/schedules/parametric.rb index a723afae40..8718cf1f56 100644 --- a/lib/openstudio-standards/schedules/parametric.rb +++ b/lib/openstudio-standards/schedules/parametric.rb @@ -511,14 +511,12 @@ def self.schedule_ruleset_get_parametric_inputs(schedule_ruleset, space_load_ins # set scheduleRuleset properties props = schedule_ruleset.additionalProperties - if props.getFeatureAsString('param_sch_ver') == '0.0.1' - # don't need to gather more than once - return parametric_inputs - else - props.setFeature('param_sch_ver', '0.0.1') # this is needed to see if formulas are in sync with version of standards that processes them also used to flag schedule as parametric - props.setFeature('param_sch_floor', min_max['min']) - props.setFeature('param_sch_ceiling', min_max['max']) - end + # don't need to gather more than once + return parametric_inputs if props.getFeatureAsString('param_sch_ver') == '0.0.1' + + props.setFeature('param_sch_ver', '0.0.1') # this is needed to see if formulas are in sync with version of standards that processes them also used to flag schedule as parametric + props.setFeature('param_sch_floor', min_max['min']) + props.setFeature('param_sch_ceiling', min_max['max']) # cleanup existing profiles OpenstudioStandards::Schedules.schedule_ruleset_cleanup_profiles(schedule_ruleset) @@ -575,7 +573,7 @@ def self.schedule_ruleset_get_parametric_inputs(schedule_ruleset, space_load_ins end # new rules are created at top of list - cleanup old rules if !(new_rule_ct == 0 || new_rule_ct == schedule_ruleset.scheduleRules.size) - schedule_ruleset.scheduleRules[new_rule_ct..-1].each(&:remove) + schedule_ruleset.scheduleRules[new_rule_ct..].each(&:remove) end # re-collect new schedule rules