openstudio-standards 0.2.16 → 0.2.17.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/standards/manage_OpenStudio_Standards.rb +31 -4
- data/lib/openstudio-standards/btap/geometry.rb +1 -1
- data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +354 -2
- data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +79 -0
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Laboratory.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/do_not_edit_metaclasses.rb +3313 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +12 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +3 -4
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +167 -93
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +2 -4
- data/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb +1 -0
- data/lib/openstudio-standards/refs/references.rb +3 -0
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +279 -6
- data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctParallelPIUReheat.rb +50 -2
- data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +4 -0
- data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.Construction.rb +185 -3
- data/lib/openstudio-standards/standards/Standards.Fan.rb +14 -6
- data/lib/openstudio-standards/standards/Standards.HeatExchangerSensLat.rb +1 -0
- data/lib/openstudio-standards/standards/Standards.Model.rb +1751 -383
- data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +130 -9
- data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +50 -3
- data/lib/openstudio-standards/standards/Standards.ScheduleCompact.rb +44 -0
- data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +27 -0
- data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +543 -0
- data/lib/openstudio-standards/standards/Standards.Space.rb +665 -15
- data/lib/openstudio-standards/standards/Standards.SpaceType.rb +141 -4
- data/lib/openstudio-standards/standards/Standards.SubSurface.rb +2 -1
- data/lib/openstudio-standards/standards/Standards.Surface.rb +117 -0
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +197 -49
- data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +41 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +6 -8
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/comstock_ashrae_90_1_2004.spc_typ.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/comstock_ashrae_90_1_2007.spc_typ.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/comstock_ashrae_90_1_2010.spc_typ.json +9 -9
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/comstock_ashrae_90_1_2013.spc_typ.json +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/data/comstock_ashrae_90_1_2016.spc_typ.json +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/data/comstock_ashrae_90_1_2019.spc_typ.json +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.fans.json +12 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/comstock_doe_ref_1980_2004.spc_typ.json +10 -10
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/comstock_doe_ref_pre_1980.spc_typ.json +10 -10
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +792 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctParallelPIUReheat.rb +10 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctVAVReheat.rb +31 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.BoilerHotWater.rb +91 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +84 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +145 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +106 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +71 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +194 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +120 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTower.rb +110 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTowerVariableSpeed.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Fan.rb +73 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanVariableVolume.rb +24 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanZoneExhaust.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.HeatExchangerSensLat.rb +55 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +3045 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +187 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +450 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Space.rb +106 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +666 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Surface.rb +54 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ThermalZone.rb +168 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ZoneHVACComponent.rb +132 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.rb +239 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +176 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.rb +25 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.boilers.json +52 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.chillers.json +112 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.climate_zone_sets.json +210 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_properties.json +10384 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_sets.json +133 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.furnaces.json +43 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_pumps.json +119 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_pumps_heating.json +130 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_rejection.json +13 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.lpd_space_type.json +568 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.motors.json +264 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_baseline_hvac.json +439 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_constructions.json +685 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_economizers.json +213 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_ext_ltg.json +32 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_heat_type.json +136 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_hvac_bldg_type.json +32 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_interior_lighting.json +1837 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_swh_bldg_type.json +184 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_wwr_bldg_type.json +84 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.unitary_acs.json +148 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.water_heaters.json +157 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.climate_zone_sets.json +210 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.curves.json +18329 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.fans.json +340 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.materials.json +49924 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/baseline_building_rotation_exception.md +44 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/check_pump_power_and_control.md +71 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/dcv.md +68 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/dcv_implementation.png +0 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/elevators.md +14 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/exhaust_air_energy_recovery.md +36 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/f_c_factors.md +19 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/fan_power_credits.md +15 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/preheat_coil.md +59 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/pump_power_control.md +46 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/return_air_type.md +31 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_baseline_wwr.md +191 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_hw_and_chw_supply_water_temp_reset_control.md +24 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_num_boilers_chillers_towers.md +49 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_plug_load_measures.md +80 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_space_lpd.md +73 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/unenclosed_and_unconditioned_spaces.md +11 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/unmet_load_hours.md +20 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/vav_parallel_piu_terminals_fan_control.md +23 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/vav_terminals_min_flow_setpoint.md +21 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_airloop_hvac.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_airloop_hvac_doas.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_building.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_design_specification_outdoor_air.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_electric_equipment.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_exterior_lights.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_gas_equipment.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_lights.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_space.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_spacetype.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_thermal_zone.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_connections.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_equipment.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_equipment_definition.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_zone_hvac.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_zone_infiltration.csv +1 -0
- data/lib/openstudio-standards/standards/cbes/data/cbes.fans.json +12 -0
- data/lib/openstudio-standards/standards/deer/data/deer.fans.json +12 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps.json +1 -1
- data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps_heating.json +1 -1
- data/lib/openstudio-standards/standards/necb/ECMS/data/unitary_acs.json +24 -11
- data/lib/openstudio-standards/standards/necb/ECMS/erv.rb +13 -15
- data/lib/openstudio-standards/standards/necb/NECB2011/data/province_map.json +17 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +2 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +6 -5
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +3 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +2 -3
- data/lib/openstudio-standards/standards/necb/NECB2020/data/chillers.json +2 -2
- data/lib/openstudio-standards/standards/necb/NECB2020/data/space_types.json +33 -924
- data/lib/openstudio-standards/standards/necb/NECB2020/data/unitary_acs.json +15 -15
- data/lib/openstudio-standards/standards/necb/common/btap_data.rb +135 -29
- data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +16 -4
- data/lib/openstudio-standards/standards/necb/common/neb_end_use_prices.csv +40 -42
- data/lib/openstudio-standards/standards/necb/common/necb_reference_runs.csv +1 -1
- data/lib/openstudio-standards/standards/necb/common/space_type_upgrade_map.json +89 -89
- data/lib/openstudio-standards/utilities/array.rb +11 -0
- data/lib/openstudio-standards/utilities/logging.rb +48 -0
- data/lib/openstudio-standards/utilities/object_info.rb +20 -0
- data/lib/openstudio-standards/utilities/schedule_translator.rb +348 -0
- data/lib/openstudio-standards/utilities/sqlfile.rb +68 -0
- data/lib/openstudio-standards/version.rb +2 -2
- data/lib/openstudio-standards/weather/Weather.Model.rb +42 -55
- data/lib/openstudio-standards/weather/Weather.stat_file.rb +1 -1
- data/lib/openstudio-standards.rb +35 -1
- metadata +111 -6
- data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
- data/data/standards/OpenStudio_Standards-ashrae_90_1_28Jan2022.xlsx +0 -0
- data/data/standards/OpenStudio_Standards-ashrae_90_1_28_Jan2022_2.xlsx +0 -0
- data/data/standards/openstudio_standards_duplicates_log.csv +0 -143
@@ -0,0 +1,11 @@
|
|
1
|
+
# Taken from: https://github.com/rubyworks/facets/blob/master/lib/core/facets/array/mode.rb#L14
|
2
|
+
class Array
|
3
|
+
# Get most common value from an array
|
4
|
+
# If there is a tie for most common, an array is returned of the tied values
|
5
|
+
def mode
|
6
|
+
max = 0
|
7
|
+
c = Hash.new 0
|
8
|
+
each { |x| cc = c[x] += 1; max = cc if cc > max }
|
9
|
+
c.select { |k, v| v == max }.map { |k, v| k }
|
10
|
+
end
|
11
|
+
end
|
@@ -36,6 +36,54 @@ def log_messages_to_runner(runner, debug = false)
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
# A function that writes error message to log file and stop the execution.
|
40
|
+
#
|
41
|
+
# @param msg [String] error message
|
42
|
+
# @param log_level [OpenStudio::LogLevel] log level, eg. OpenStudio::Info
|
43
|
+
# @param log_path [String] the log file directory
|
44
|
+
# @param debug [Boolean] debug mode
|
45
|
+
def terminate_prm_write_log(msg, log_path, debug = false)
|
46
|
+
OpenStudio.logFree(OpenStudio::ERROR, 'prm.log', msg)
|
47
|
+
log_messages_to_file_prm("#{log_path}/prm.log", debug)
|
48
|
+
raise msg
|
49
|
+
end
|
50
|
+
|
51
|
+
# A function to export log messages specific to PRM to a log file.
|
52
|
+
#
|
53
|
+
# @param file_path [String] the file path to the log file
|
54
|
+
# @param debug [Boolean] debug mode
|
55
|
+
# @return message [Array] array of message strings
|
56
|
+
def log_messages_to_file_prm(file_path, debug = false)
|
57
|
+
messages = []
|
58
|
+
|
59
|
+
File.open(file_path, 'w') do |file|
|
60
|
+
$OPENSTUDIO_LOG.logMessages.each do |msg|
|
61
|
+
# only apply to prm
|
62
|
+
if msg.logChannel.casecmp? 'prm.log'
|
63
|
+
# Report the message in the correct way
|
64
|
+
if msg.logLevel == OpenStudio::Info
|
65
|
+
s = "[#{msg.logChannel}] INFO #{msg.logMessage}"
|
66
|
+
file.puts(s)
|
67
|
+
messages << s
|
68
|
+
elsif msg.logLevel == OpenStudio::Warn
|
69
|
+
s = "[#{msg.logChannel}] WARN #{msg.logMessage}"
|
70
|
+
file.puts(s)
|
71
|
+
messages << s
|
72
|
+
elsif msg.logLevel == OpenStudio::Error
|
73
|
+
s = "[#{msg.logChannel}] ERROR #{msg.logMessage}"
|
74
|
+
file.puts(s)
|
75
|
+
messages << s
|
76
|
+
elsif msg.logLevel == OpenStudio::Debug && debug
|
77
|
+
s = "[#{msg.logChannel}] DEBUG #{msg.logMessage}"
|
78
|
+
file.puts(s)
|
79
|
+
messages << s
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
return messages
|
85
|
+
end
|
86
|
+
|
39
87
|
# Log the info, warning, and error messages to a file.
|
40
88
|
#
|
41
89
|
# runner @param [file_path] The path to the log file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#
|
2
|
+
# Get hash of object field names and values
|
3
|
+
# @author: Xuechen (Jerry) Lei, PNNL
|
4
|
+
# @param obj [object]
|
5
|
+
#
|
6
|
+
# @return [Hash<String>] FieldName:Value
|
7
|
+
#
|
8
|
+
def getObjectHash(obj)
|
9
|
+
fields_array = obj.to_s.split(/\n/)
|
10
|
+
output_hash = { 'object type' => fields_array.shift.split(/,/)[0] }
|
11
|
+
right = nil
|
12
|
+
fields_array.each do |ori_field|
|
13
|
+
left, right = ori_field.split(/[,;]/)
|
14
|
+
left = left.strip
|
15
|
+
right.slice!('!-')
|
16
|
+
right = right.strip
|
17
|
+
output_hash[right] = left
|
18
|
+
end
|
19
|
+
return output_hash
|
20
|
+
end
|
@@ -0,0 +1,348 @@
|
|
1
|
+
# *******************************************************************************
|
2
|
+
# The following notice pertains to the function below named
|
3
|
+
# convert_schedule_compact_to_schedule_ruleset
|
4
|
+
# *******************************************************************************
|
5
|
+
# OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
|
6
|
+
# All rights reserved.
|
7
|
+
# Redistribution and use in source and binary forms, with or without
|
8
|
+
# modification, are permitted provided that the following conditions are met:
|
9
|
+
#
|
10
|
+
# (1) Redistributions of source code must retain the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer.
|
12
|
+
#
|
13
|
+
# (2) Redistributions in binary form must reproduce the above copyright notice,
|
14
|
+
# this list of conditions and the following disclaimer in the documentation
|
15
|
+
# and/or other materials provided with the distribution.
|
16
|
+
#
|
17
|
+
# (3) Neither the name of the copyright holder nor the names of any contributors
|
18
|
+
# may be used to endorse or promote products derived from this software without
|
19
|
+
# specific prior written permission from the respective party.
|
20
|
+
#
|
21
|
+
# (4) Other than as required in clauses (1) and (2), distributions in any form
|
22
|
+
# of modifications or other derivative works may not use the "OpenStudio"
|
23
|
+
# trademark, "OS", "os", or any other confusingly similar designation without
|
24
|
+
# specific prior written permission from Alliance for Sustainable Energy, LLC.
|
25
|
+
#
|
26
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
|
27
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
28
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
29
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
|
30
|
+
# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
|
31
|
+
# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
32
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
33
|
+
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
34
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
35
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
36
|
+
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
37
|
+
# *******************************************************************************
|
38
|
+
|
39
|
+
ForStruct = Struct.new(:daytypes)
|
40
|
+
UntilStruct = Struct.new(:timestamp)
|
41
|
+
ThroughStruct = Struct.new(:startdate)
|
42
|
+
|
43
|
+
class ScheduleTranslator
|
44
|
+
attr_accessor :os_schedule
|
45
|
+
|
46
|
+
def initialize(os_model, os_schedule, name_prefix = nil)
|
47
|
+
@os_schedule = os_schedule
|
48
|
+
@os = os_model
|
49
|
+
@sched_name = os_schedule.name.get.to_s
|
50
|
+
@sched_type = os_schedule.scheduleTypeLimits.get
|
51
|
+
@base_year = os_model.getYearDescription.assumedYear
|
52
|
+
@schedule = []
|
53
|
+
@name_prefix = name_prefix
|
54
|
+
end
|
55
|
+
|
56
|
+
# Convert from scheduleCompact to scheduleRuleset
|
57
|
+
# @Author Nicholas Long and Andrew Parker, NREL
|
58
|
+
# @Return ScheduleRuleset object
|
59
|
+
def convert_schedule_compact_to_schedule_ruleset
|
60
|
+
@sched_name = @os_schedule.getString(1).get
|
61
|
+
@sched_name = "#{@name_prefix} #{@sched_name}" unless @name_prefix.nil?
|
62
|
+
@sched_type = @os_schedule.scheduleTypeLimits.get # TODO: - will fail if no limits set in source schedule
|
63
|
+
|
64
|
+
# puts "Translating #{@sched_name}"
|
65
|
+
|
66
|
+
i_thru = -1
|
67
|
+
i_for = -1
|
68
|
+
i_until = -1
|
69
|
+
sUntil = ''
|
70
|
+
|
71
|
+
(3..@os_schedule.numFields - 1).each do |i|
|
72
|
+
val = @os_schedule.getString(i).get
|
73
|
+
|
74
|
+
# Trap for interpolated schedules
|
75
|
+
if val =~ /Interpolate/
|
76
|
+
puts "[WARNING] Schedule #{@sched_name} is interpolated. It will not be translated to .osm"
|
77
|
+
return false
|
78
|
+
end
|
79
|
+
|
80
|
+
# add : if it doesn't already exist
|
81
|
+
val = val.gsub(/Through\s/, 'Through: ')
|
82
|
+
val = val.gsub(/For\s/, 'For: ')
|
83
|
+
val = val.gsub(/Until\s/, 'Until: ')
|
84
|
+
|
85
|
+
if val =~ /through:/i
|
86
|
+
i_thru += 1
|
87
|
+
i_for = -1
|
88
|
+
i_until = -1
|
89
|
+
|
90
|
+
str = val.split(':')[1].strip
|
91
|
+
if @schedule.empty?
|
92
|
+
@schedule << { start_date: '01/01', end_date: str, for: [] }
|
93
|
+
else
|
94
|
+
@schedule << { start_date: @schedule[@schedule.size - 1][:end_date], end_date: str, for: [] }
|
95
|
+
end
|
96
|
+
|
97
|
+
next
|
98
|
+
end
|
99
|
+
|
100
|
+
if val =~ /for[:\s]/i
|
101
|
+
i_for += 1
|
102
|
+
i_until = -1
|
103
|
+
|
104
|
+
arr = val.match(/for[:\s](.*)/i)[0].strip.downcase.split(' ')
|
105
|
+
@schedule[i_thru][:for] << { daytype: arr, until: [] }
|
106
|
+
next
|
107
|
+
end
|
108
|
+
|
109
|
+
if val =~ /until:/i
|
110
|
+
i_until += 1
|
111
|
+
|
112
|
+
str = val.split(':')[1..2].join(':').strip
|
113
|
+
sUntil = str
|
114
|
+
|
115
|
+
next
|
116
|
+
end
|
117
|
+
|
118
|
+
dVal = @os_schedule.getDouble(i).get
|
119
|
+
# puts "thru: #{i_thru} for: #{i_for} until #{i_until}"
|
120
|
+
@schedule[i_thru][:for][i_for][:until] << { timestamp: sUntil, value: dVal }
|
121
|
+
end
|
122
|
+
|
123
|
+
# DEBUG spit out the schedule for quick check\
|
124
|
+
# puts @schedule.inspect
|
125
|
+
# @schedule.each do |sch|
|
126
|
+
# puts "#{sch[:start_date]} to #{sch[:end_date]}"
|
127
|
+
# sch[:for].each do |fr|
|
128
|
+
# puts fr[:daytype]
|
129
|
+
# fr[:until].each do |ut|
|
130
|
+
# puts "#{ut[:timestamp]} : #{ut[:value]}"
|
131
|
+
# end
|
132
|
+
# end
|
133
|
+
# end
|
134
|
+
|
135
|
+
os_schedule_ruleset = OpenStudio::Model::ScheduleRuleset.new(@os)
|
136
|
+
os_schedule_ruleset.setName(@sched_name)
|
137
|
+
os_schedule_ruleset.setScheduleTypeLimits(@sched_type)
|
138
|
+
|
139
|
+
i_rule = 0
|
140
|
+
@schedule.each do |sch|
|
141
|
+
# create a simple hash to make sure that the schedule covers all days needed
|
142
|
+
# and that "allotherdays", can adequately be handled
|
143
|
+
coverage = { mon: false, tue: false, wed: false, thu: false, fri: false, sat: false,
|
144
|
+
sun: false, sdd: false, wdd: false, hol: false }
|
145
|
+
sch[:for].each do |fr|
|
146
|
+
i_rule += 1
|
147
|
+
os_schedule_rule = OpenStudio::Model::ScheduleRule.new(os_schedule_ruleset)
|
148
|
+
os_schedule_rule.setName("#{@sched_name} Rule #{i_rule}")
|
149
|
+
os_schedule_rule.setApplyMonday(false)
|
150
|
+
os_schedule_rule.setApplyTuesday(false)
|
151
|
+
os_schedule_rule.setApplyWednesday(false)
|
152
|
+
os_schedule_rule.setApplyThursday(false)
|
153
|
+
os_schedule_rule.setApplyFriday(false)
|
154
|
+
os_schedule_rule.setApplySaturday(false)
|
155
|
+
os_schedule_rule.setApplySunday(false)
|
156
|
+
|
157
|
+
mody = sch[:start_date].split('/')
|
158
|
+
mo = mody[0].to_i
|
159
|
+
dy = mody[1].to_i
|
160
|
+
osdate_start = OpenStudio::Date.new(OpenStudio::MonthOfYear.new(mo.to_i), dy.to_i)
|
161
|
+
if mo != 1 && dy != 1
|
162
|
+
osdate_start += OpenStudio::Time.new(1)
|
163
|
+
end
|
164
|
+
os_schedule_rule.setStartDate(osdate_start)
|
165
|
+
mody = sch[:end_date].split('/')
|
166
|
+
mo = mody[0].to_i
|
167
|
+
dy = mody[1].to_i
|
168
|
+
osdate_end = OpenStudio::Date.new(OpenStudio::MonthOfYear.new(mo.to_i), dy.to_i)
|
169
|
+
os_schedule_rule.setEndDate(osdate_end)
|
170
|
+
|
171
|
+
# create os day model
|
172
|
+
# TODO break this out as a method
|
173
|
+
if fr[:daytype].include?('monday') || fr[:daytype].include?('alldays') || fr[:daytype].include?('weekdays')
|
174
|
+
os_schedule_rule.setApplyMonday(true)
|
175
|
+
coverage[:mon] = true
|
176
|
+
end
|
177
|
+
if fr[:daytype].include?('tuesday') || fr[:daytype].include?('alldays') || fr[:daytype].include?('weekdays')
|
178
|
+
os_schedule_rule.setApplyTuesday(true)
|
179
|
+
coverage[:tue] = true
|
180
|
+
end
|
181
|
+
if fr[:daytype].include?('wednesday') || fr[:daytype].include?('alldays') || fr[:daytype].include?('weekdays')
|
182
|
+
os_schedule_rule.setApplyWednesday(true)
|
183
|
+
coverage[:wed] = true
|
184
|
+
end
|
185
|
+
if fr[:daytype].include?('thursday') || fr[:daytype].include?('alldays') || fr[:daytype].include?('weekdays')
|
186
|
+
os_schedule_rule.setApplyThursday(true)
|
187
|
+
coverage[:thu] = true
|
188
|
+
end
|
189
|
+
if fr[:daytype].include?('friday') || fr[:daytype].include?('alldays') || fr[:daytype].include?('weekdays')
|
190
|
+
os_schedule_rule.setApplyFriday(true)
|
191
|
+
coverage[:fri] = true
|
192
|
+
end
|
193
|
+
if fr[:daytype].include?('saturday') || fr[:daytype].include?('alldays')
|
194
|
+
os_schedule_rule.setApplySaturday(true)
|
195
|
+
coverage[:sat] = true
|
196
|
+
end
|
197
|
+
if fr[:daytype].include?('sunday') || fr[:daytype].include?('alldays')
|
198
|
+
os_schedule_rule.setApplySunday(true)
|
199
|
+
coverage[:sun] = true
|
200
|
+
end
|
201
|
+
if fr[:daytype].include?('allotherdays')
|
202
|
+
# needs to be a unique rule set
|
203
|
+
if !coverage[:mon]
|
204
|
+
os_schedule_rule.setApplyMonday(true)
|
205
|
+
coverage[:mon] = true
|
206
|
+
end
|
207
|
+
if !coverage[:tue]
|
208
|
+
os_schedule_rule.setApplyTuesday(true)
|
209
|
+
coverage[:tue] = true
|
210
|
+
end
|
211
|
+
if !coverage[:wed]
|
212
|
+
os_schedule_rule.setApplyWednesday(true)
|
213
|
+
coverage[:wed] = true
|
214
|
+
end
|
215
|
+
if !coverage[:thu]
|
216
|
+
os_schedule_rule.setApplyThursday(true)
|
217
|
+
coverage[:thu] = true
|
218
|
+
end
|
219
|
+
if !coverage[:fri]
|
220
|
+
os_schedule_rule.setApplyFriday(true)
|
221
|
+
coverage[:fri] = true
|
222
|
+
end
|
223
|
+
if !coverage[:sat]
|
224
|
+
os_schedule_rule.setApplySaturday(true)
|
225
|
+
coverage[:sat] = true
|
226
|
+
end
|
227
|
+
if !coverage[:sun]
|
228
|
+
os_schedule_rule.setApplySunday(true)
|
229
|
+
coverage[:sun] = true
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
osday = os_schedule_rule.daySchedule
|
234
|
+
osday.setName("#{@sched_name} Rule #{i_rule} Day Sch")
|
235
|
+
# osday.setString(1, @sched_type)
|
236
|
+
fr[:until].each do |ut|
|
237
|
+
hr = ut[:timestamp].split(':')[0].to_i
|
238
|
+
mn = ut[:timestamp].split(':')[1].to_i
|
239
|
+
|
240
|
+
ostime = OpenStudio::Time.new(0, hr, mn, 0)
|
241
|
+
osday.addValue(ostime, ut[:value])
|
242
|
+
end
|
243
|
+
|
244
|
+
# set the winter and summer design days
|
245
|
+
if fr[:daytype].include?('winterdesignday') ||
|
246
|
+
(fr[:daytype].include?('allotherdays') && !coverage[:wdd])
|
247
|
+
|
248
|
+
# this actually clones osday
|
249
|
+
os_schedule_ruleset.setWinterDesignDaySchedule(osday)
|
250
|
+
|
251
|
+
coverage[:wdd] = true
|
252
|
+
end
|
253
|
+
if fr[:daytype].include?('summerdesignday') ||
|
254
|
+
(fr[:daytype].include?('allotherdays') && !coverage[:sdd])
|
255
|
+
|
256
|
+
# this actually clones osday
|
257
|
+
os_schedule_ruleset.setSummerDesignDaySchedule(osday)
|
258
|
+
|
259
|
+
coverage[:sdd] = true
|
260
|
+
end
|
261
|
+
|
262
|
+
# now check if for some reason that we have alldays for section
|
263
|
+
# but the date/time stamp is not in the winter/summer
|
264
|
+
if !coverage[:wdd]
|
265
|
+
osdate_wdd = OpenStudio::Date.new(OpenStudio::MonthOfYear.new(1), 15)
|
266
|
+
if fr[:daytype].include?('alldays') && (osdate_start < osdate_wdd) && (osdate_end > osdate_wdd)
|
267
|
+
os_schedule_ruleset.setWinterDesignDaySchedule(osday)
|
268
|
+
coverage[:wdd] = true
|
269
|
+
# puts "[INFO] **** Setting DesignDay based on date, not by actual schedule ****"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
if !coverage[:sdd]
|
273
|
+
osdate_wdd = OpenStudio::Date.new(OpenStudio::MonthOfYear.new(7), 15)
|
274
|
+
if fr[:daytype].include?('alldays') && (osdate_start < osdate_wdd) && (osdate_end > osdate_wdd)
|
275
|
+
os_schedule_ruleset.setSummerDesignDaySchedule(osday)
|
276
|
+
coverage[:sdd] = true
|
277
|
+
# puts "[INFO] **** Setting DesignDay based on date, not by actual schedule ****"
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
# Clean up tasks on the naming after all the schedule rule and days are
|
284
|
+
# configured
|
285
|
+
ostemp = os_schedule_ruleset.winterDesignDaySchedule
|
286
|
+
ostemp.setName("#{@sched_name} Winter Design Day")
|
287
|
+
# ostemp.setString(1, @sched_type)
|
288
|
+
|
289
|
+
ostemp = os_schedule_ruleset.summerDesignDaySchedule
|
290
|
+
ostemp.setName("#{@sched_name} Summer Design Day")
|
291
|
+
# ostemp.setString(1, @sched_type)
|
292
|
+
|
293
|
+
ostemp = os_schedule_ruleset.defaultDaySchedule
|
294
|
+
ostemp.setName("#{@sched_name} Default Schedule")
|
295
|
+
# ostemp.setString(1, @sched_type)
|
296
|
+
|
297
|
+
# Remove rules that don't apply to any days
|
298
|
+
os_schedule_ruleset.scheduleRules.each do |sr|
|
299
|
+
if !sr.applySunday && !sr.applyMonday && !sr.applyTuesday &&
|
300
|
+
!sr.applyWednesday && !sr.applyThursday && !sr.applyFriday &&
|
301
|
+
!sr.applySaturday
|
302
|
+
sr.daySchedule.remove
|
303
|
+
sr.remove
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
sched_i = 0
|
308
|
+
os_schedule_ruleset.scheduleRules.each do |sr|
|
309
|
+
sched_i += 1
|
310
|
+
sr.setName("#{@sched_name} Rule #{sched_i}")
|
311
|
+
sr.daySchedule.setName("#{@sched_name} Rule #{sched_i} Day Schedule")
|
312
|
+
end
|
313
|
+
|
314
|
+
# If the default profile is never used throughout the year,
|
315
|
+
# make the most commonly used rule the default instead.
|
316
|
+
|
317
|
+
# Get an array that shows which rule is used on each day in the date range.
|
318
|
+
# A value of -1 means that the default profile is used on that day,
|
319
|
+
# so if -1 never appears in the list, it isn't used.
|
320
|
+
year = @base_year
|
321
|
+
year_start_date = OpenStudio::Date.new(OpenStudio::MonthOfYear.new('January'), 1, year)
|
322
|
+
year_end_date = OpenStudio::Date.new(OpenStudio::MonthOfYear.new('December'), 31, year)
|
323
|
+
rules_used_each_day = os_schedule_ruleset.getActiveRuleIndices(year_start_date, year_end_date)
|
324
|
+
rules_freq = rules_used_each_day.group_by { |n| n }
|
325
|
+
most_freq_rule_index = rules_freq.values.max_by(&:size).first
|
326
|
+
if !rules_used_each_day.include?(-1)
|
327
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.schedule_translator', "#{os_schedule_ruleset.name} does not use the default profile, it will be replaced.")
|
328
|
+
|
329
|
+
# Get times/values from the most commonly used rule then remove that rule.
|
330
|
+
rule_vector = os_schedule_ruleset.scheduleRules
|
331
|
+
new_default_day_sch = rule_vector[most_freq_rule_index].daySchedule
|
332
|
+
new_default_day_sch_values = new_default_day_sch.values
|
333
|
+
new_default_day_sch_times = new_default_day_sch.times
|
334
|
+
rule_vector[most_freq_rule_index].remove
|
335
|
+
|
336
|
+
# Reset values in default profile
|
337
|
+
default_day_sch = os_schedule_ruleset.defaultDaySchedule
|
338
|
+
default_day_sch.clearValues
|
339
|
+
|
340
|
+
# Update values and times for default profile
|
341
|
+
for i in 0..(new_default_day_sch_values.size - 1)
|
342
|
+
default_day_sch.addValue(new_default_day_sch_times[i], new_default_day_sch_values[i])
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
return os_schedule_ruleset
|
347
|
+
end
|
348
|
+
end
|
@@ -16,6 +16,34 @@ Standard.class_eval do
|
|
16
16
|
return model.sqlFile.get
|
17
17
|
end
|
18
18
|
|
19
|
+
# Write out a SQL query to retrieve simulation outputs
|
20
|
+
# from the TabularDataWithStrings table in the SQL
|
21
|
+
# database produced by OpenStudio/EnergyPlus after
|
22
|
+
# running a simulation.
|
23
|
+
#
|
24
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
25
|
+
# @param report_name [String] Name of the report as defined in the HTM simulation output file
|
26
|
+
# @param table_name [String] Name of the table as defined in the HTM simulation output file
|
27
|
+
# @param row_name [String] Name of the row as defined in the HTM simulation output file
|
28
|
+
# @param column_name [String] Name of the column as defined in the HTM simulation output file
|
29
|
+
# @param units [String] Unit of the value to be retrieved
|
30
|
+
#
|
31
|
+
# @return [String] Result of the query
|
32
|
+
def run_query_tabulardatawithstrings(model, report_name, table_name, row_name, column_name, units = '*')
|
33
|
+
# Define the query
|
34
|
+
query = "Select Value FROM TabularDataWithStrings WHERE
|
35
|
+
ReportName = '#{report_name}' AND
|
36
|
+
TableName = '#{table_name}' AND
|
37
|
+
RowName = '#{row_name}' AND
|
38
|
+
ColumnName = '#{column_name}' AND
|
39
|
+
Units = '#{units}'"
|
40
|
+
# Run the query if the expected output is a string
|
41
|
+
return model.sqlFile.get.execAndReturnFirstString(query).get if units.empty?
|
42
|
+
|
43
|
+
# Run the query if the expected output is a double
|
44
|
+
return model.sqlFile.get.execAndReturnFirstDouble(query).get
|
45
|
+
end
|
46
|
+
|
19
47
|
# Get the weather run period for the model
|
20
48
|
#
|
21
49
|
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
@@ -384,6 +412,46 @@ Standard.class_eval do
|
|
384
412
|
return heating_or_cooling_setpoint_unmet
|
385
413
|
end
|
386
414
|
|
415
|
+
# Get the total unmet load hours during occupancy of a model that has been simulated
|
416
|
+
#
|
417
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
418
|
+
# @return [Float] returns the number of total unmet load hours during occupancy in a simulated model
|
419
|
+
def model_get_unmet_load_hours(model)
|
420
|
+
result = OpenStudio::OptionalDouble.new
|
421
|
+
sql = model.sqlFile
|
422
|
+
if sql.is_initialized
|
423
|
+
sql = sql.get
|
424
|
+
query = "SELECT Value
|
425
|
+
FROM tabulardatawithstrings
|
426
|
+
WHERE ReportName='AnnualBuildingUtilityPerformanceSummary'
|
427
|
+
AND ReportForString='Entire Facility'
|
428
|
+
AND TableName='Comfort and Setpoint Not Met Summary'
|
429
|
+
AND ColumnName='Facility'
|
430
|
+
AND RowName='Time Setpoint Not Met During Occupied Heating'
|
431
|
+
AND Units='Hours'"
|
432
|
+
val = sql.execAndReturnFirstDouble(query)
|
433
|
+
if val.is_initialized
|
434
|
+
result = OpenStudio::OptionalDouble.new(val.get).to_f
|
435
|
+
end
|
436
|
+
query = "SELECT Value
|
437
|
+
FROM tabulardatawithstrings
|
438
|
+
WHERE ReportName='AnnualBuildingUtilityPerformanceSummary'
|
439
|
+
AND ReportForString='Entire Facility'
|
440
|
+
AND TableName='Comfort and Setpoint Not Met Summary'
|
441
|
+
AND ColumnName='Facility'
|
442
|
+
AND RowName='Time Setpoint Not Met During Occupied Cooling'
|
443
|
+
AND Units='Hours'"
|
444
|
+
val = sql.execAndReturnFirstDouble(query)
|
445
|
+
if val.is_initialized
|
446
|
+
result += OpenStudio::OptionalDouble.new(val.get).to_f
|
447
|
+
end
|
448
|
+
else
|
449
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'Model has no sql file containing results, cannot lookup data.')
|
450
|
+
end
|
451
|
+
|
452
|
+
return result
|
453
|
+
end
|
454
|
+
|
387
455
|
# Gets the model annual energy consumption by fuel and enduse in GJ from the sql file
|
388
456
|
#
|
389
457
|
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
@@ -81,13 +81,49 @@ class Standard
|
|
81
81
|
return climate_zone_weather_file_map
|
82
82
|
end
|
83
83
|
|
84
|
+
# Get absolute path of a weather file included within openstudio-standards
|
85
|
+
#
|
86
|
+
# @param weather_file_name [String] Name of a weather file include within openstudio-standards
|
87
|
+
# @return [String] Weather file path
|
88
|
+
def model_get_weather_file(weather_file_name)
|
89
|
+
# Define where the weather files lives
|
90
|
+
weather_dir = nil
|
91
|
+
if __dir__[0] == ':' # Running from OpenStudio CLI
|
92
|
+
# load weather file from embedded files
|
93
|
+
epw_string = load_resource_relative("../../../data/weather/#{weather_file_name}")
|
94
|
+
ddy_string = load_resource_relative("../../../data/weather/#{weather_file_name.gsub('.epw', '.ddy')}")
|
95
|
+
stat_string = load_resource_relative("../../../data/weather/#{weather_file_name.gsub('.epw', '.stat')}")
|
96
|
+
|
97
|
+
# extract to local weather dir
|
98
|
+
weather_dir = File.expand_path(File.join(Dir.pwd, 'extracted_files/weather/'))
|
99
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.weather.Model', "Extracting weather files from OpenStudio CLI to #{weather_dir}")
|
100
|
+
FileUtils.mkdir_p(weather_dir)
|
101
|
+
File.open("#{weather_dir}/#{weather_file_name}", 'wb') { |f| f << epw_string; f.flush }
|
102
|
+
File.open("#{weather_dir}/#{weather_file_name.gsub('.epw', '.ddy')}", 'wb') { |f| f << ddy_string; f.flush }
|
103
|
+
File.open("#{weather_dir}/#{weather_file_name.gsub('.epw', '.stat')}", 'wb') { |f| f << stat_string; f.flush }
|
104
|
+
else
|
105
|
+
# loaded gem from system path
|
106
|
+
top_dir = File.expand_path('../../..', File.dirname(__FILE__))
|
107
|
+
weather_dir = File.expand_path("#{top_dir}/data/weather")
|
108
|
+
end
|
109
|
+
|
110
|
+
# Add Weather File
|
111
|
+
unless (Pathname.new weather_dir).absolute?
|
112
|
+
weather_dir = File.expand_path(File.join(File.dirname(__FILE__), weather_dir))
|
113
|
+
end
|
114
|
+
|
115
|
+
weather_file = File.join(weather_dir, weather_file_name)
|
116
|
+
|
117
|
+
return weather_file
|
118
|
+
end
|
119
|
+
|
84
120
|
# Adds the design days and weather file for the specified climate zone
|
85
121
|
#
|
86
122
|
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
87
123
|
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
|
88
124
|
# @param epw_file [String] the name of the epw file; if blank will default to epw file for the ASHRAE climate zone
|
89
125
|
# @return [Bool] returns true if successful, false if not
|
90
|
-
def model_add_design_days_and_weather_file(model, climate_zone, epw_file = '')
|
126
|
+
def model_add_design_days_and_weather_file(model, climate_zone, epw_file = '', weather_dir = nil)
|
91
127
|
success = true
|
92
128
|
require_relative 'Weather.stat_file'
|
93
129
|
|
@@ -110,33 +146,8 @@ class Standard
|
|
110
146
|
success = false
|
111
147
|
end
|
112
148
|
|
113
|
-
|
114
|
-
weather_dir = nil
|
115
|
-
if __dir__[0] == ':' # Running from OpenStudio CLI
|
116
|
-
# load weather file from embedded files
|
117
|
-
epw_string = load_resource_relative("../../../data/weather/#{weather_file_name}")
|
118
|
-
ddy_string = load_resource_relative("../../../data/weather/#{weather_file_name.gsub('.epw', '.ddy')}")
|
119
|
-
stat_string = load_resource_relative("../../../data/weather/#{weather_file_name.gsub('.epw', '.stat')}")
|
120
|
-
|
121
|
-
# extract to local weather dir
|
122
|
-
weather_dir = File.expand_path(File.join(Dir.pwd, 'extracted_files/weather/'))
|
123
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.weather.Model', "Extracting weather files from OpenStudio CLI to #{weather_dir}")
|
124
|
-
FileUtils.mkdir_p(weather_dir)
|
125
|
-
File.open("#{weather_dir}/#{weather_file_name}", 'wb') { |f| f << epw_string; f.flush }
|
126
|
-
File.open("#{weather_dir}/#{weather_file_name.gsub('.epw', '.ddy')}", 'wb') { |f| f << ddy_string; f.flush }
|
127
|
-
File.open("#{weather_dir}/#{weather_file_name.gsub('.epw', '.stat')}", 'wb') { |f| f << stat_string; f.flush }
|
128
|
-
else
|
129
|
-
# loaded gem from system path
|
130
|
-
top_dir = File.expand_path('../../..', File.dirname(__FILE__))
|
131
|
-
weather_dir = File.expand_path("#{top_dir}/data/weather")
|
132
|
-
end
|
133
|
-
|
134
|
-
# Add Weather File
|
135
|
-
unless (Pathname.new weather_dir).absolute?
|
136
|
-
weather_dir = File.expand_path(File.join(File.dirname(__FILE__), weather_dir))
|
137
|
-
end
|
149
|
+
weather_file = model_get_weather_file(weather_file_name)
|
138
150
|
|
139
|
-
weather_file = File.join(weather_dir, weather_file_name)
|
140
151
|
epw_file = OpenStudio::EpwFile.new(weather_file)
|
141
152
|
OpenStudio::Model::WeatherFile.setWeatherFile(model, epw_file).get
|
142
153
|
|
@@ -212,30 +223,8 @@ class Standard
|
|
212
223
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.weather.Model', "Could not determine the weather file for climate zone: #{climate_zone}, cannot get ground temperatures from stat file.")
|
213
224
|
end
|
214
225
|
|
215
|
-
# Define where the weather files lives
|
216
|
-
weather_dir = nil
|
217
|
-
if __dir__[0] == ':' # Running from OpenStudio CLI
|
218
|
-
# load stat file from embedded files
|
219
|
-
stat_string = load_resource_relative("../../../data/weather/#{weather_file_name.gsub('.epw', '.stat')}")
|
220
|
-
|
221
|
-
# extract to local weather dir
|
222
|
-
weather_dir = File.expand_path(File.join(Dir.pwd, 'extracted_files/weather/'))
|
223
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.weather.Model', "Extracting stat file from OpenStudio CLI to #{weather_dir}")
|
224
|
-
FileUtils.mkdir_p(weather_dir)
|
225
|
-
File.open("#{weather_dir}/#{weather_file_name.gsub('.epw', '.stat')}", 'wb') { |f| f << stat_string; f.flush }
|
226
|
-
else
|
227
|
-
# loaded gem from system path
|
228
|
-
top_dir = File.expand_path('../../..', File.dirname(__FILE__))
|
229
|
-
weather_dir = File.expand_path("#{top_dir}/data/weather")
|
230
|
-
end
|
231
|
-
|
232
|
-
# Expand the weather directory path
|
233
|
-
unless (Pathname.new weather_dir).absolute?
|
234
|
-
weather_dir = File.expand_path(File.join(File.dirname(__FILE__), weather_dir))
|
235
|
-
end
|
236
|
-
|
237
226
|
# Get the path to the stat file
|
238
|
-
weather_file =
|
227
|
+
weather_file = model_get_weather_file(weather_file_name)
|
239
228
|
|
240
229
|
# Add ground temperatures via parsing of STAT file.
|
241
230
|
ground_temperatures = []
|
@@ -347,7 +336,6 @@ end
|
|
347
336
|
module BTAP
|
348
337
|
module Environment
|
349
338
|
require_relative 'Weather.stat_file'
|
350
|
-
# rubocop:enable Style/MutableConstant
|
351
339
|
|
352
340
|
# this method is used to populate user interfaces if needed from the hash above.
|
353
341
|
def self.get_canadian_weather_file_names
|
@@ -922,7 +910,7 @@ module BTAP
|
|
922
910
|
end
|
923
911
|
end
|
924
912
|
return heating_design_day_number, cooling_design_day_number
|
925
|
-
end #def get_heating_design_day_number
|
913
|
+
end # def get_heating_design_day_number
|
926
914
|
|
927
915
|
# This method calculates dehumidification degree days (DDD)
|
928
916
|
# @author sara.gilani@canada.ca
|
@@ -960,7 +948,7 @@ module BTAP
|
|
960
948
|
c5 * (line[DRY_BULB_TEMPERATURE].to_f + convert_c_to_k)**3 +
|
961
949
|
c6 * (line[DRY_BULB_TEMPERATURE].to_f + convert_c_to_k)**4 +
|
962
950
|
c7 * Math.log((line[DRY_BULB_TEMPERATURE].to_f + convert_c_to_k), Math.exp(1)) # 2.718281828459
|
963
|
-
line[CALCULATED_SATURATION_PRESSURE_OF_WATER_VAPOR] =
|
951
|
+
line[CALCULATED_SATURATION_PRESSURE_OF_WATER_VAPOR] = Math.exp(1)**line[CALCULATED_SATURATION_PRESSURE_OF_WATER_VAPOR].to_f
|
964
952
|
else # if line[DRY_BULB_TEMPERATURE].to_f > 0.0
|
965
953
|
line[CALCULATED_SATURATION_PRESSURE_OF_WATER_VAPOR] = c8 / (line[DRY_BULB_TEMPERATURE].to_f + convert_c_to_k) +
|
966
954
|
c9 +
|
@@ -968,7 +956,7 @@ module BTAP
|
|
968
956
|
c11 * (line[DRY_BULB_TEMPERATURE].to_f + convert_c_to_k)**2 +
|
969
957
|
c12 * (line[DRY_BULB_TEMPERATURE].to_f + convert_c_to_k)**3 +
|
970
958
|
c13 * Math.log((line[DRY_BULB_TEMPERATURE].to_f + convert_c_to_k), Math.exp(1))
|
971
|
-
line[CALCULATED_SATURATION_PRESSURE_OF_WATER_VAPOR] =
|
959
|
+
line[CALCULATED_SATURATION_PRESSURE_OF_WATER_VAPOR] = Math.exp(1)**line[CALCULATED_SATURATION_PRESSURE_OF_WATER_VAPOR].to_f
|
972
960
|
end
|
973
961
|
|
974
962
|
# Step 2: calculate pw (PARTIAL_PRESSURE_OF_WATER_VAPOR), [Pascal]
|
@@ -1003,7 +991,6 @@ module BTAP
|
|
1003
991
|
# puts @filearray
|
1004
992
|
return ddd
|
1005
993
|
end # def calculate_humidity_ratio
|
1006
|
-
|
1007
994
|
end # Environment
|
1008
995
|
end
|
1009
996
|
end
|