openstudio-standards 0.2.12.rc5 → 0.2.13
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/geometry/ASHRAE90120162019HighriseApartment.json +1042 -0
- data/data/geometry/ASHRAE90120162019Hospital.json +199 -0
- data/data/geometry/ASHRAE90120162019LargeHotel.json +73 -0
- data/data/geometry/ASHRAE90120162019LargeOffice.json +109 -0
- data/data/geometry/ASHRAE90120162019SecondarySchool.json +205 -0
- data/data/geometry/ASHRAECourthouse.json +112 -0
- data/data/geometry/ASHRAECourthouse.osm +26470 -0
- data/data/geometry/ASHRAELargeHotel.osm +11 -1
- data/data/geometry/ASHRAELargeOffice.json +4 -0
- data/data/geometry/ASHRAESmallDataCenter.json +1 -1
- data/data/standards/OpenStudio_Standards-ashrae_90_1(space_types).xlsx +0 -0
- data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
- data/data/standards/exclude_list.csv +19 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.boilers.json +49 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.chillers.json +293 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +25426 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_sets.json +1600 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.economizers.json +564 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.elevators.json +349 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ext_ltg.json +164 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ground_temperatures.json +10663 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps.json +508 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps_heating.json +156 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_rejection.json +44 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.motors.json +184 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.prototype_inputs.json +3094 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ref_cases.json +829 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ref_lnup.json +562 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_compressors.json +52 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_condenser.json +220 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_system.json +156 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_walkins.json +1316 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +21446 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.unitary_acs.json +554 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_heaters.json +68 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_source_heat_pumps.json +28 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_source_heat_pumps_heating.json +12 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.boilers.json +49 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.chillers.json +293 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +12487 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_sets.json +1600 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.economizers.json +564 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.elevators.json +349 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ext_ltg.json +164 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ground_temperatures.json +10663 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps.json +466 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps_heating.json +137 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_rejection.json +44 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.motors.json +184 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.prototype_inputs.json +3094 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ref_cases.json +829 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ref_lnup.json +562 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_compressors.json +52 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_condenser.json +220 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_system.json +156 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_walkins.json +1316 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +21380 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.unitary_acs.json +554 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_heaters.json +68 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_source_heat_pumps.json +28 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_source_heat_pumps_heating.json +12 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.boilers.json +49 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.chillers.json +395 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +12487 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_sets.json +1600 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.economizers.json +592 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.elevators.json +349 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.energy_recovery.json +550 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ext_ltg.json +164 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ground_temperatures.json +10663 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps.json +466 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps_heating.json +137 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_rejection.json +44 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.motors.json +238 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.prototype_inputs.json +3094 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ref_cases.json +829 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ref_lnup.json +562 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_compressors.json +52 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_condenser.json +220 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_system.json +156 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_walkins.json +1316 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +21548 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.unitary_acs.json +554 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_heaters.json +68 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_source_heat_pumps.json +28 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_source_heat_pumps_heating.json +12 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.boilers.json +64 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.chillers.json +871 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +12487 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_sets.json +1600 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.economizers.json +592 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.elevators.json +349 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.energy_recovery.json +1096 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ext_ltg.json +164 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ground_temperatures.json +10663 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps.json +886 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps_heating.json +194 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_rejection.json +44 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.motors.json +247 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.prototype_inputs.json +3094 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ref_cases.json +829 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ref_lnup.json +562 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_compressors.json +52 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_condenser.json +220 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_system.json +156 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_walkins.json +1316 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +22079 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.unitary_acs.json +994 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_heaters.json +68 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps.json +28 -0
- data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps_heating.json +12 -0
- data/data/standards/manage_OpenStudio_Standards.rb +87 -37
- data/data/standards/metadata_units_OpenStudio_Standards-ashrae_90_1-ALL-comstockspace_types.csv +236 -0
- data/data/standards/metadata_units_OpenStudio_Standards-ashrae_90_1.csv +622 -0
- data/data/standards/metadata_units_OpenStudio_Standards-ashrae_90_1space_types.csv +195 -0
- data/data/standards/openstudio_standards_duplicates_log.csv +28 -0
- data/data/standards/test_performance_expected_dd_results.csv +1934 -1134
- data/lib/openstudio-standards.rb +68 -17
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PumpVariableSpeed.rb +28 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanVariableVolume.rb +0 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.PumpVariableSpeed.rb +28 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Model.rb +53 -2
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.PumpVariableSpeed.rb +29 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Model.rb +157 -2
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.PumpVariableSpeed.rb +29 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +24 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanConstantVolume.rb +32 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanOnOff.rb +33 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanVariableVolume.rb +32 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.elevators.rb +25 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +366 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.PumpVariableSpeed.rb +144 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.hvac_systems.rb +11 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +24 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanConstantVolume.rb +32 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanOnOff.rb +33 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanVariableVolume.rb +32 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.elevators.rb +25 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +367 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.PumpVariableSpeed.rb +144 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.hvac_systems.rb +11 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirTerminalSingleDuctVAVReheat.rb +0 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirTerminalSingleDuctVAVReheat.rb +0 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.HeatExchangerAirToAirSensibleAndLatent.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.Model.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.HeatExchangerAirToAirSensibleAndLatent.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.Model.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +3 -3
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Courthouse.rb +74 -0
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.FullServiceRestaurant.rb +46 -30
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.HighRiseApartment.rb +23 -8
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +26 -15
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Laboratory.rb +8 -11
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterHighITE.rb +54 -60
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterLowITE.rb +56 -60
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +38 -12
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +218 -134
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOfficeDetailed.rb +6 -2
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +230 -134
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOfficeDetailed.rb +60 -62
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MidriseApartment.rb +25 -15
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb +34 -22
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +31 -7
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.QuickServiceRestaurant.rb +43 -28
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStandalone.rb +48 -38
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStripmall.rb +9 -5
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +575 -345
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterHighITE.rb +13 -19
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterLowITE.rb +13 -17
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallHotel.rb +9 -5
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOffice.rb +79 -51
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOfficeDetailed.rb +60 -60
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperMarket.rb +2 -4
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperTallBuilding.rb +133 -120
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.TallBuilding.rb +124 -112
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Warehouse.rb +138 -66
- data/lib/openstudio-standards/prototypes/common/do_not_edit_metaclasses.rb +7275 -199
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirConditionerVariableRefrigerantFlow.rb +35 -35
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.BoilerHotWater.rb +2 -2
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CentralAirSourceHeatPump.rb +2 -2
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXSingleSpeed.rb +3 -3
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXTwoSpeed.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWater.rb +2 -2
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +2 -2
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingElectric.rb +2 -2
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWater.rb +2 -2
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +2 -2
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoolingTower.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +4 -3
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanConstantVolume.rb +7 -8
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanOnOff.rb +7 -8
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanVariableVolume.rb +13 -14
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanZoneExhaust.rb +7 -5
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.elevators.rb +4 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +0 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +25 -14
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +474 -89
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.swh.rb +35 -33
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Pump.rb +3 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.PumpVariableSpeed.rb +72 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +120 -120
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +139 -151
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.radiant_system_controls.rb +9 -3
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.refrigeration.rb +11 -5
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +26 -14
- data/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb +270 -247
- data/lib/openstudio-standards/prototypes/deer/deer.Model.rb +1 -1
- data/lib/openstudio-standards/refs/references.rb +5 -2
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +47 -30
- data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.BuildingStory.rb +1 -0
- data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +2 -4
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +8 -10
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +4 -5
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.CoilDX.rb +12 -9
- data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +2 -1
- data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +3 -1
- data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +0 -3
- data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +4 -7
- data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +1 -3
- data/lib/openstudio-standards/standards/Standards.Construction.rb +124 -118
- data/lib/openstudio-standards/standards/Standards.CoolingTower.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.CoolingTowerSingleSpeed.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.CoolingTowerTwoSpeed.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.CoolingTowerVariableSpeed.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.Fan.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.FanConstantVolume.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.FanOnOff.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +2 -4
- data/lib/openstudio-standards/standards/Standards.FanZoneExhaust.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.FluidCooler.rb +10 -3
- data/lib/openstudio-standards/standards/Standards.HeaderedPumpsConstantSpeed.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.Model.rb +282 -253
- data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +2 -0
- data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +11 -9
- data/lib/openstudio-standards/standards/Standards.Pump.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.PumpConstantSpeed.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.PumpVariableSpeed.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.ScheduleCompact.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +103 -121
- data/lib/openstudio-standards/standards/Standards.Space.rb +42 -35
- data/lib/openstudio-standards/standards/Standards.SpaceType.rb +9 -17
- data/lib/openstudio-standards/standards/Standards.SubSurface.rb +25 -27
- data/lib/openstudio-standards/standards/Standards.Surface.rb +97 -52
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +39 -21
- data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +6 -7
- data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +85 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1.Standards.FanVariableVolume.rb +0 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb +10 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/ashrae_90_1.schedules.json +63 -99
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/comstock_ashrae_90_1_2004.ext_ltg.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +2420 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.economizers.json +32 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_rejection.json +9 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.prototype_inputs.json +70 -40
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ref_lnup.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_system.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +1729 -1663
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirLoopHVAC.rb +5 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/ashrae_90_1.schedules.json +63 -99
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/comstock_ashrae_90_1_2007.ext_ltg.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +1460 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.economizers.json +32 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_rejection.json +9 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.prototype_inputs.json +123 -39
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ref_lnup.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_system.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +1728 -1641
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirLoopHVAC.rb +32 -15
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Space.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/ashrae_90_1.schedules.json +63 -99
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/comstock_ashrae_90_1_2010.ext_ltg.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +1460 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.economizers.json +64 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.energy_recovery.json +52 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_rejection.json +9 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.prototype_inputs.json +123 -39
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ref_lnup.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_system.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +1727 -1640
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirLoopHVAC.rb +37 -14
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.WaterHeaterMixed.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/ashrae_90_1.schedules.json +63 -99
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/comstock_ashrae_90_1_2013.ext_ltg.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.boilers.json +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.chillers.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +1460 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.economizers.json +64 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.energy_recovery.json +104 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_rejection.json +9 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.prototype_inputs.json +125 -41
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ref_lnup.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_system.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +1882 -1765
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_heaters.json +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps_heating.json +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirLoopHVAC.rb +456 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +24 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTower.rb +19 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerSingleSpeed.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerTwoSpeed.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerVariableSpeed.rb +16 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanVariableVolume.rb +37 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Space.rb +189 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.ThermalZone.rb +57 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.ZoneHVACComponent.rb +22 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.rb +16 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.boilers.json +68 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.chillers.json +490 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +21244 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_sets.json +2111 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.economizers.json +676 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.elevators.json +372 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.energy_recovery.json +1096 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.ext_ltg.json +169 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps.json +532 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps_heating.json +164 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_rejection.json +49 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.motors.json +274 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.prototype_inputs.json +3094 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.ref_cases.json +854 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.ref_lnup.json +562 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_compressors.json +58 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_condenser.json +238 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_system.json +156 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_walkins.json +1316 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.spc_typ.json +23042 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.unitary_acs.json +648 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.water_heaters.json +72 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.water_source_heat_pumps.json +31 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.water_source_heat_pumps_heating.json +13 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +456 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +24 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTower.rb +19 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerSingleSpeed.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerTwoSpeed.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerVariableSpeed.rb +16 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanVariableVolume.rb +37 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Space.rb +189 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ThermalZone.rb +57 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ZoneHVACComponent.rb +22 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.rb +16 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.boilers.json +68 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.chillers.json +490 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +21244 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_sets.json +2111 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.economizers.json +676 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.elevators.json +372 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.energy_recovery.json +1096 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.ext_ltg.json +169 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps.json +664 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps_heating.json +204 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_rejection.json +49 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.motors.json +274 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.prototype_inputs.json +3094 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.ref_cases.json +854 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.ref_lnup.json +562 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_compressors.json +58 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_condenser.json +238 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_system.json +156 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_walkins.json +1316 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.spc_typ.json +23067 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.unitary_acs.json +671 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.water_heaters.json +72 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.water_source_heat_pumps.json +31 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.water_source_heat_pumps_heating.json +13 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +1614 -284
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.fans.json +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.materials.json +4860 -300
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.schedules.json +1743 -161
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/ashrae_90_1.schedules.json +63 -99
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/comstock_doe_ref_1980_2004.ext_ltg.json +11 -11
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.heat_rejection.json +9 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.prototype_inputs.json +50 -29
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.ref_lnup.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.refrigeration_system.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.spc_typ.json +1334 -1334
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.Model.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/ashrae_90_1.schedules.json +63 -99
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/comstock_doe_ref_pre_1980.ext_ltg.json +10 -10
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.heat_rejection.json +9 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.prototype_inputs.json +49 -28
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.ref_lnup.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.refrigeration_system.json +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.spc_typ.json +1322 -1322
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.Model.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.heat_rejection.json +9 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.prototype_inputs.json +14 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.spc_typ.json +450 -450
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +0 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.Model.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.PlantLoop.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.ZoneHVACComponent.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.heat_rejection.json +9 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.prototype_inputs.json +14 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.spc_typ.json +332 -332
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.water_heaters.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirLoopHVAC.rb +3 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.Model.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.PlantLoop.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.ZoneHVACComponent.rb +1 -1
- data/lib/openstudio-standards/standards/cbes/cbes.Model.rb +1 -3
- data/lib/openstudio-standards/standards/cbes/cbes.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer.AirLoopHVAC.rb +8 -13
- data/lib/openstudio-standards/standards/deer/deer.Model.rb +2 -2
- data/lib/openstudio-standards/standards/deer/deer.PlanarSurface.rb +2 -0
- data/lib/openstudio-standards/standards/deer/deer.Space.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2011/deer_2011.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.Space.rb +0 -1
- data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.Space.rb +0 -1
- data/lib/openstudio-standards/standards/icc_iecc/icc_iecc_2015/icc_iecc_2015.rb +0 -1
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +28 -7
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +16 -2
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +15 -0
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +14 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/erv.json +11 -7
- data/lib/openstudio-standards/standards/necb/ECMS/data/pv.json +112 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/unitary_acs.json +50 -0
- data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +21 -8
- data/lib/openstudio-standards/standards/necb/ECMS/erv.rb +17 -6
- data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +142 -6
- data/lib/openstudio-standards/standards/necb/ECMS/nv.rb +189 -0
- data/lib/openstudio-standards/standards/necb/ECMS/pv_ground.rb +104 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +19 -13
- data/lib/openstudio-standards/standards/necb/NECB2011/data/erv.json +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LowriseApartment.osm +39278 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +17 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +15 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +14 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +13 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +12 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +154 -12
- data/lib/openstudio-standards/standards/necb/NECB2011/lighting.rb +21 -3
- data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +187 -21
- data/lib/openstudio-standards/standards/necb/NECB2011/nv.md +74 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/pv_ground.md +44 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +2 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/qaqc_resources/neb_end_use_prices.csv +39 -84
- data/lib/openstudio-standards/standards/oeesc/oeesc_2014/oeesc_2014.rb +0 -1
- data/lib/openstudio-standards/standards/standard.rb +6 -5
- data/lib/openstudio-standards/utilities/Add_template_field_to_json.rb +3 -3
- data/lib/openstudio-standards/utilities/convert_surfaces_to_adiabatic_necb_8426.rb +54 -54
- data/lib/openstudio-standards/utilities/generate_prototype_database.rb +2 -2
- data/lib/openstudio-standards/utilities/generate_space_types.rb +3 -3
- data/lib/openstudio-standards/utilities/logging.rb +7 -7
- data/lib/openstudio-standards/utilities/necb_to_epw_map.rb +14 -14
- data/lib/openstudio-standards/utilities/os_sim_extract.rb +25 -25
- data/lib/openstudio-standards/utilities/rename_surfaces.rb +10 -13
- data/lib/openstudio-standards/utilities/round_surf_coords.rb +18 -20
- data/lib/openstudio-standards/utilities/sched_create.rb +39 -41
- data/lib/openstudio-standards/utilities/set_mult_to_adiabatic.rb +31 -31
- data/lib/openstudio-standards/utilities/simulation.rb +13 -21
- data/lib/openstudio-standards/utilities/speacetype_map_converter.rb +10 -11
- data/lib/openstudio-standards/utilities/sqlfile.rb +6 -8
- data/lib/openstudio-standards/utilities/template_measure/measure.rb +108 -0
- data/lib/openstudio-standards/utilities/template_measure/measure.xml +162 -0
- data/lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb +448 -0
- data/lib/openstudio-standards/utilities/template_measure/tests/test.rb +160 -0
- data/lib/openstudio-standards/utilities/weatherData1_xlsx_to_json.rb +23 -26
- data/lib/openstudio-standards/version.rb +1 -1
- data/lib/openstudio-standards/weather/Weather.Model.rb +112 -87
- data/lib/openstudio-standards/weather/Weather.stat_file.rb +17 -17
- metadata +216 -2
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
class Standard
|
3
2
|
# @!group FanVariableVolume
|
4
3
|
|
@@ -184,9 +183,8 @@ class Standard
|
|
184
183
|
|
185
184
|
# Get the air loop this fan is connected to
|
186
185
|
air_loop = fan_variable_volume.airLoopHVAC
|
187
|
-
unless air_loop.is_initialized
|
188
|
-
|
189
|
-
end
|
186
|
+
return clg_sys_type unless air_loop.is_initialized
|
187
|
+
|
190
188
|
air_loop = air_loop.get
|
191
189
|
|
192
190
|
# Check the types of coils on the AirLoopHVAC
|
@@ -14,8 +14,15 @@ class Standard
|
|
14
14
|
# rate will not (and should not)
|
15
15
|
# exactly equal the minimum tower performance.
|
16
16
|
#
|
17
|
+
# @param fluid_cooler [OpenStudio::Model::FluidCoolerSingleSpeed,
|
18
|
+
# OpenStudio::Model::FluidCoolerTwoSpeed,
|
19
|
+
# OpenStudio::Model::EvaporativeFluidCoolerSingleSpeed,
|
20
|
+
# OpenStudio::Model::EvaporativeFluidCoolerTwoSpeed] the fluid cooler
|
21
|
+
# @param equipment_type [String] heat rejection equipment type enumeration used for lookup query,
|
22
|
+
# options are 'Closed Cooling Tower', modeled as an EvaporativeFluidCooler,
|
23
|
+
# or 'Dry Cooler', modeled as a FluidCooler
|
17
24
|
# @return [Bool] true if successful, false if not
|
18
|
-
def fluid_cooler_apply_minimum_power_per_flow(fluid_cooler)
|
25
|
+
def fluid_cooler_apply_minimum_power_per_flow(fluid_cooler, equipment_type: 'Closed Cooling Tower')
|
19
26
|
# Get the design water flow rate
|
20
27
|
if fluid_cooler.designWaterFlowRate.is_initialized
|
21
28
|
design_water_flow_m3_per_s = fluid_cooler.designWaterFlowRate.get
|
@@ -36,7 +43,7 @@ class Standard
|
|
36
43
|
search_criteria['template'] = template
|
37
44
|
|
38
45
|
# Closed cooling towers are fluidcooler objects.
|
39
|
-
search_criteria['equipment_type'] =
|
46
|
+
search_criteria['equipment_type'] = equipment_type
|
40
47
|
|
41
48
|
# TODO: Standards replace this with a mechanism to store this
|
42
49
|
# data in the fluid cooler object itself.
|
@@ -121,4 +128,4 @@ class Standard
|
|
121
128
|
|
122
129
|
return true
|
123
130
|
end
|
124
|
-
end
|
131
|
+
end
|
@@ -150,6 +150,7 @@ class Standard
|
|
150
150
|
model.getPlantLoops.sort.each do |plant_loop|
|
151
151
|
# Skip the SWH loops
|
152
152
|
next if plant_loop_swh_loop?(plant_loop)
|
153
|
+
|
153
154
|
plant_loop_apply_prm_baseline_temperatures(plant_loop)
|
154
155
|
end
|
155
156
|
|
@@ -179,6 +180,7 @@ class Standard
|
|
179
180
|
model.getPlantLoops.sort.each do |plant_loop|
|
180
181
|
# Skip the SWH loops
|
181
182
|
next if plant_loop_swh_loop?(plant_loop)
|
183
|
+
|
182
184
|
plant_loop_apply_prm_number_of_boilers(plant_loop)
|
183
185
|
plant_loop_apply_prm_number_of_chillers(plant_loop)
|
184
186
|
end
|
@@ -188,6 +190,7 @@ class Standard
|
|
188
190
|
model.getPlantLoops.sort.each do |plant_loop|
|
189
191
|
# Skip the SWH loops
|
190
192
|
next if plant_loop_swh_loop?(plant_loop)
|
193
|
+
|
191
194
|
plant_loop_apply_prm_number_of_cooling_towers(plant_loop)
|
192
195
|
end
|
193
196
|
|
@@ -201,6 +204,7 @@ class Standard
|
|
201
204
|
model.getPlantLoops.sort.each do |plant_loop|
|
202
205
|
# Skip the SWH loops
|
203
206
|
next if plant_loop_swh_loop?(plant_loop)
|
207
|
+
|
204
208
|
plant_loop_apply_prm_baseline_pump_power(plant_loop)
|
205
209
|
plant_loop_apply_prm_baseline_pumping_type(plant_loop)
|
206
210
|
end
|
@@ -272,6 +276,7 @@ class Standard
|
|
272
276
|
zone.spaces.each do |space|
|
273
277
|
story = space.buildingStory
|
274
278
|
next if story.empty?
|
279
|
+
|
275
280
|
stories << story.get
|
276
281
|
end
|
277
282
|
end
|
@@ -738,10 +743,10 @@ class Standard
|
|
738
743
|
# Add a hot water PTAC to each zone
|
739
744
|
model_add_ptac(model,
|
740
745
|
zones,
|
741
|
-
cooling_type:
|
742
|
-
heating_type:
|
746
|
+
cooling_type: 'Single Speed DX AC',
|
747
|
+
heating_type: 'Water',
|
743
748
|
hot_water_loop: hot_water_loop,
|
744
|
-
fan_type:
|
749
|
+
fan_type: 'ConstantVolume')
|
745
750
|
end
|
746
751
|
|
747
752
|
when 'PTHP' # System 2
|
@@ -786,7 +791,7 @@ class Standard
|
|
786
791
|
cooling_type: cooling_type,
|
787
792
|
chilled_water_loop: chilled_water_loop,
|
788
793
|
heating_type: heating_type,
|
789
|
-
supplemental_heating_type:
|
794
|
+
supplemental_heating_type: 'Gas',
|
790
795
|
hot_water_loop: hot_water_loop,
|
791
796
|
fan_location: 'DrawThrough',
|
792
797
|
fan_type: 'ConstantVolume')
|
@@ -850,7 +855,7 @@ class Standard
|
|
850
855
|
story_group[0].spaces.each do |space|
|
851
856
|
stories << [space.buildingStory.get.name.get, building_story_minimum_z_value(space.buildingStory.get)]
|
852
857
|
end
|
853
|
-
story_name = stories.
|
858
|
+
story_name = stories.min_by { |nm, z| z }[0]
|
854
859
|
system_name = "#{story_name} PVAV_Reheat (Sys5)"
|
855
860
|
|
856
861
|
# If and only if there are primary zones to attach to the loop
|
@@ -901,7 +906,7 @@ class Standard
|
|
901
906
|
story_group[0].spaces.each do |space|
|
902
907
|
stories << [space.buildingStory.get.name.get, building_story_minimum_z_value(space.buildingStory.get)]
|
903
908
|
end
|
904
|
-
story_name = stories.
|
909
|
+
story_name = stories.min_by { |nm, z| z }[0]
|
905
910
|
system_name = "#{story_name} PVAV_PFP_Boxes (Sys6)"
|
906
911
|
# If and only if there are primary zones to attach to the loop
|
907
912
|
unless pri_zones.empty?
|
@@ -979,7 +984,7 @@ class Standard
|
|
979
984
|
story_group[0].spaces.each do |space|
|
980
985
|
stories << [space.buildingStory.get.name.get, building_story_minimum_z_value(space.buildingStory.get)]
|
981
986
|
end
|
982
|
-
story_name = stories.
|
987
|
+
story_name = stories.min_by { |nm, z| z }[0]
|
983
988
|
system_name = "#{story_name} VAV_Reheat (Sys7)"
|
984
989
|
|
985
990
|
# If and only if there are primary zones to attach to the loop
|
@@ -1046,7 +1051,7 @@ class Standard
|
|
1046
1051
|
story_group[0].spaces.each do |space|
|
1047
1052
|
stories << [space.buildingStory.get.name.get, building_story_minimum_z_value(space.buildingStory.get)]
|
1048
1053
|
end
|
1049
|
-
story_name = stories.
|
1054
|
+
story_name = stories.min_by { |nm, z| z }[0]
|
1050
1055
|
system_name = "#{story_name} VAV_PFP_Boxes (Sys8)"
|
1051
1056
|
# If and only if there are primary zones to attach to the loop
|
1052
1057
|
unless pri_zones.empty?
|
@@ -1054,7 +1059,7 @@ class Standard
|
|
1054
1059
|
pri_zones,
|
1055
1060
|
system_name: system_name,
|
1056
1061
|
chilled_water_loop: chilled_water_loop,
|
1057
|
-
fan_efficiency:0.62,
|
1062
|
+
fan_efficiency: 0.62,
|
1058
1063
|
fan_motor_efficiency: 0.9,
|
1059
1064
|
fan_pressure_rise: 4.0)
|
1060
1065
|
end
|
@@ -1294,6 +1299,7 @@ class Standard
|
|
1294
1299
|
full_load_hrs = 0.0
|
1295
1300
|
# Skip lights with no schedule
|
1296
1301
|
next if lights_sch.empty?
|
1302
|
+
|
1297
1303
|
lights_sch = lights_sch.get
|
1298
1304
|
if lights_sch.to_ScheduleRuleset.is_initialized
|
1299
1305
|
lights_sch = lights_sch.to_ScheduleRuleset.get
|
@@ -1404,6 +1410,7 @@ class Standard
|
|
1404
1410
|
# This can happen if a zone has multiple spaces on multiple stories.
|
1405
1411
|
# Stairwells and atriums are typical scenarios.
|
1406
1412
|
next if zones_already_assigned.include?(zone)
|
1413
|
+
|
1407
1414
|
zones_on_story << zone
|
1408
1415
|
zones_already_assigned << zone
|
1409
1416
|
end
|
@@ -1465,14 +1472,14 @@ class Standard
|
|
1465
1472
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying multizone vav OA sizing.')
|
1466
1473
|
|
1467
1474
|
# Multi-zone VAV outdoor air sizing
|
1468
|
-
model.getAirLoopHVACs.sort.each {|obj| air_loop_hvac_apply_multizone_vav_outdoor_air_sizing(obj)}
|
1475
|
+
model.getAirLoopHVACs.sort.each { |obj| air_loop_hvac_apply_multizone_vav_outdoor_air_sizing(obj) }
|
1469
1476
|
|
1470
1477
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying multizone vav OA sizing.')
|
1471
1478
|
end
|
1472
1479
|
|
1473
1480
|
# Applies the HVAC parts of the template to all objects in the model using the the template specified in the model.
|
1474
|
-
def model_apply_hvac_efficiency_standard(model, climate_zone, apply_controls: true)
|
1475
|
-
sql_db_vars_map = {}
|
1481
|
+
def model_apply_hvac_efficiency_standard(model, climate_zone, apply_controls: true, sql_db_vars_map: nil)
|
1482
|
+
sql_db_vars_map = {} if sql_db_vars_map.nil?
|
1476
1483
|
|
1477
1484
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Started applying HVAC efficiency standards for #{template} template.")
|
1478
1485
|
|
@@ -1535,20 +1542,20 @@ class Standard
|
|
1535
1542
|
model.getCoolingTowerVariableSpeeds.sort.each { |obj| cooling_tower_variable_speed_apply_efficiency_and_curves(obj) }
|
1536
1543
|
|
1537
1544
|
# Fluid Coolers
|
1538
|
-
|
1539
|
-
|
1540
|
-
|
1541
|
-
|
1542
|
-
# model.getEvaporativeFluidCoolerTwoSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj) }
|
1545
|
+
model.getFluidCoolerSingleSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj, equipment_type: 'Dry Cooler') }
|
1546
|
+
model.getFluidCoolerTwoSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj, equipment_type: 'Dry Cooler') }
|
1547
|
+
model.getEvaporativeFluidCoolerSingleSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj, equipment_type: 'Closed Cooling Tower') }
|
1548
|
+
model.getEvaporativeFluidCoolerTwoSpeeds.sort.each { |obj| fluid_cooler_apply_minimum_power_per_flow(obj, equipment_type: 'Closed Cooling Tower') }
|
1543
1549
|
|
1544
1550
|
# ERVs
|
1545
1551
|
model.getHeatExchangerAirToAirSensibleAndLatents.each { |obj| heat_exchanger_air_to_air_sensible_and_latent_apply_efficiency(obj) }
|
1546
1552
|
|
1547
1553
|
# Gas Heaters
|
1548
1554
|
model.getCoilHeatingGass.sort.each { |obj| coil_heating_gas_apply_efficiency_and_curves(obj) }
|
1549
|
-
model.getCoilHeatingGasMultiStages.each {|obj| coil_heating_gas_multi_stage_apply_efficiency_and_curves(obj)}
|
1555
|
+
model.getCoilHeatingGasMultiStages.each { |obj| coil_heating_gas_multi_stage_apply_efficiency_and_curves(obj) }
|
1550
1556
|
|
1551
1557
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Finished applying HVAC efficiency standards for #{template} template.")
|
1558
|
+
return true
|
1552
1559
|
end
|
1553
1560
|
|
1554
1561
|
# Applies daylighting controls to each space in the model per the standard.
|
@@ -1586,7 +1593,6 @@ class Standard
|
|
1586
1593
|
return true
|
1587
1594
|
end
|
1588
1595
|
|
1589
|
-
|
1590
1596
|
# Method to search through a hash for the objects that meets the desired search criteria, as passed via a hash.
|
1591
1597
|
# Returns an Array (empty if nothing found) of matching objects.
|
1592
1598
|
#
|
@@ -1608,7 +1614,6 @@ class Standard
|
|
1608
1614
|
# return false
|
1609
1615
|
# end
|
1610
1616
|
def model_find_objects(hash_of_objects, search_criteria, capacity = nil, date = nil, area = nil, num_floors = nil)
|
1611
|
-
|
1612
1617
|
matching_objects = []
|
1613
1618
|
if hash_of_objects.is_a?(Hash) && hash_of_objects.key?('table')
|
1614
1619
|
hash_of_objects = hash_of_objects['table']
|
@@ -1616,11 +1621,13 @@ class Standard
|
|
1616
1621
|
|
1617
1622
|
# Compare each of the objects against the search criteria
|
1618
1623
|
raise("This is not a table #{hash_of_objects}") unless hash_of_objects.respond_to?(:each)
|
1624
|
+
|
1619
1625
|
hash_of_objects.each do |object|
|
1620
1626
|
meets_all_search_criteria = true
|
1621
1627
|
search_criteria.each do |key, value|
|
1622
1628
|
# Don't check non-existent search criteria
|
1623
1629
|
next unless object.key?(key)
|
1630
|
+
|
1624
1631
|
# Stop as soon as one of the search criteria is not met
|
1625
1632
|
# 'Any' is a special key that matches anything
|
1626
1633
|
unless object[key] == value || object[key] == 'Any'
|
@@ -1630,6 +1637,7 @@ class Standard
|
|
1630
1637
|
end
|
1631
1638
|
# Skip objects that don't meet all search criteria
|
1632
1639
|
next unless meets_all_search_criteria
|
1640
|
+
|
1633
1641
|
# If made it here, object matches all search criteria
|
1634
1642
|
matching_objects << object
|
1635
1643
|
end
|
@@ -1725,7 +1733,6 @@ class Standard
|
|
1725
1733
|
# }
|
1726
1734
|
# motor_properties = self.model.find_object(motors, search_criteria, capacity: 2.5)
|
1727
1735
|
def model_find_object(hash_of_objects, search_criteria, capacity = nil, date = nil, area = nil, num_floors = nil)
|
1728
|
-
|
1729
1736
|
matching_objects = model_find_objects(hash_of_objects, search_criteria, capacity, date, area, num_floors)
|
1730
1737
|
|
1731
1738
|
# Check the number of matching objects found
|
@@ -1742,10 +1749,6 @@ class Standard
|
|
1742
1749
|
return desired_object
|
1743
1750
|
end
|
1744
1751
|
|
1745
|
-
|
1746
|
-
|
1747
|
-
|
1748
|
-
|
1749
1752
|
# Method to search through a hash for the objects that meets the desired search criteria, as passed via a hash.
|
1750
1753
|
# Returns an Array (empty if nothing found) of matching objects.
|
1751
1754
|
#
|
@@ -1766,13 +1769,13 @@ class Standard
|
|
1766
1769
|
# OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "Cannot find data for schedule: #{schedule_name}, will not be created.")
|
1767
1770
|
# return false
|
1768
1771
|
# end
|
1769
|
-
def standards_lookup_table_many(table_name
|
1772
|
+
def standards_lookup_table_many(table_name:, search_criteria: {}, capacity: nil, date: nil, area: nil, num_floors: nil)
|
1770
1773
|
desired_object = nil
|
1771
1774
|
search_criteria_matching_objects = []
|
1772
1775
|
matching_objects = []
|
1773
|
-
hash_of_objects= @standards_data[table_name]
|
1774
|
-
|
1775
|
-
#needed for NRCan data structure compatibility. We keep all tables in a 'tables' hash in @standards_data and the table
|
1776
|
+
hash_of_objects = @standards_data[table_name]
|
1777
|
+
|
1778
|
+
# needed for NRCan data structure compatibility. We keep all tables in a 'tables' hash in @standards_data and the table
|
1776
1779
|
# itself is in the 'table' hash index.
|
1777
1780
|
if hash_of_objects.nil?
|
1778
1781
|
if @standards_data['tables'].nil?
|
@@ -1790,6 +1793,7 @@ class Standard
|
|
1790
1793
|
search_criteria.each do |key, value|
|
1791
1794
|
# Don't check non-existent search criteria
|
1792
1795
|
next unless object.key?(key)
|
1796
|
+
|
1793
1797
|
# Stop as soon as one of the search criteria is not met
|
1794
1798
|
# 'Any' is a special key that matches anything
|
1795
1799
|
unless object[key] == value || object[key] == 'Any'
|
@@ -1799,6 +1803,7 @@ class Standard
|
|
1799
1803
|
end
|
1800
1804
|
# Skip objects that don't meet all search criteria
|
1801
1805
|
next unless meets_all_search_criteria
|
1806
|
+
|
1802
1807
|
# If made it here, object matches all search criteria
|
1803
1808
|
matching_objects << object
|
1804
1809
|
end
|
@@ -1830,6 +1835,7 @@ class Standard
|
|
1830
1835
|
next if capacity <= object['minimum_capacity'].to_f
|
1831
1836
|
# Skip objects whose max
|
1832
1837
|
next if capacity > object['maximum_capacity'].to_f
|
1838
|
+
|
1833
1839
|
# Found a matching object
|
1834
1840
|
matching_objects << object
|
1835
1841
|
end
|
@@ -1844,6 +1850,7 @@ class Standard
|
|
1844
1850
|
next if date <= Date.parse(object['start_date'])
|
1845
1851
|
# Skip objects whose end date is beyond the specified date
|
1846
1852
|
next if date > Date.parse(object['end_date'])
|
1853
|
+
|
1847
1854
|
# Found a matching object
|
1848
1855
|
date_matching_objects << object
|
1849
1856
|
end
|
@@ -1905,11 +1912,11 @@ class Standard
|
|
1905
1912
|
# }
|
1906
1913
|
# motor_properties = self.model.find_object(motors, search_criteria, 2.5)
|
1907
1914
|
def standards_lookup_table_first(table_name:, search_criteria: {}, capacity: nil, date: nil)
|
1908
|
-
#run the many version of the look up code...DRY.
|
1915
|
+
# run the many version of the look up code...DRY.
|
1909
1916
|
matching_objects = standards_lookup_table_many(table_name: table_name,
|
1910
|
-
|
1911
|
-
|
1912
|
-
|
1917
|
+
search_criteria: search_criteria,
|
1918
|
+
capacity: capacity,
|
1919
|
+
date: date)
|
1913
1920
|
|
1914
1921
|
# Check the number of matching objects found
|
1915
1922
|
if matching_objects.size.zero?
|
@@ -1983,7 +1990,7 @@ class Standard
|
|
1983
1990
|
|
1984
1991
|
if standard_sch_type_limit.nil?
|
1985
1992
|
if lower_limit_value.nil? || upper_limit_value.nil? || numeric_type.nil? || unit_type.nil?
|
1986
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model',
|
1993
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', 'If calling model_add_schedule_type_limits without a standard_sch_type_limit, you must specify all properties of ScheduleTypeLimits.')
|
1987
1994
|
return false
|
1988
1995
|
end
|
1989
1996
|
schedule_type_limits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
@@ -2043,8 +2050,8 @@ class Standard
|
|
2043
2050
|
schedule_type_limits.setUpperLimitValue(1000.0)
|
2044
2051
|
schedule_type_limits.setNumericType('Continuous')
|
2045
2052
|
schedule_type_limits.setUnitType('ActivityLevel')
|
2046
|
-
|
2047
|
-
|
2053
|
+
else
|
2054
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', 'Invalid standard_sch_type_limit for method model_add_schedule_type_limits.')
|
2048
2055
|
end
|
2049
2056
|
end
|
2050
2057
|
end
|
@@ -2059,6 +2066,7 @@ class Standard
|
|
2059
2066
|
# @todo make return an OptionalScheduleRuleset
|
2060
2067
|
def model_add_schedule(model, schedule_name)
|
2061
2068
|
return nil if schedule_name.nil? || schedule_name == ''
|
2069
|
+
|
2062
2070
|
# First check model and return schedule if it already exists
|
2063
2071
|
model.getSchedules.sort.each do |schedule|
|
2064
2072
|
if schedule.name.get.to_s == schedule_name
|
@@ -2330,7 +2338,7 @@ class Standard
|
|
2330
2338
|
else # if !data['intended_surface_type'] == 'ExteriorWindow' && !data['intended_surface_type'] == 'Skylight'
|
2331
2339
|
# Set the U-Value
|
2332
2340
|
construction_set_u_value(construction, target_u_value_ip.to_f, data['insulation_layer'], data['intended_surface_type'], u_includes_int_film, u_includes_ext_film)
|
2333
|
-
|
2341
|
+
# else
|
2334
2342
|
# OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Not modifying U-value for #{data['intended_surface_type']} u_val #{target_u_value_ip} f_fac #{target_f_factor_ip} c_fac #{target_c_factor_ip}")
|
2335
2343
|
end
|
2336
2344
|
|
@@ -2373,7 +2381,7 @@ class Standard
|
|
2373
2381
|
frame_with_m = OpenStudio.convert(frame_width_in, 'in', 'm').get
|
2374
2382
|
frame_resistance_ip = frame_data['resistance'].to_f
|
2375
2383
|
frame_resistance_si = OpenStudio.convert(frame_resistance_ip, 'hr*ft^2*R/Btu', 'm^2*K/W').get
|
2376
|
-
frame_conductance_si = 1.0/frame_resistance_si
|
2384
|
+
frame_conductance_si = 1.0 / frame_resistance_si
|
2377
2385
|
frame = OpenStudio::Model::WindowPropertyFrameAndDivider.new(model)
|
2378
2386
|
frame.setName("Skylight frame R-#{frame_resistance_ip.round(2)} #{frame_width_in.round(1)} in. wide")
|
2379
2387
|
frame.setFrameWidth(frame_with_m)
|
@@ -2381,7 +2389,8 @@ class Standard
|
|
2381
2389
|
skylights_frame_added = 0
|
2382
2390
|
model.getSubSurfaces.each do |sub_surface|
|
2383
2391
|
next unless sub_surface.outsideBoundaryCondition == 'Outdoors' && sub_surface.subSurfaceType == 'Skylight'
|
2384
|
-
|
2392
|
+
|
2393
|
+
# TODO: enable proper window frame setting after https://github.com/NREL/OpenStudio/issues/2895 is fixed
|
2385
2394
|
sub_surface.setString(8, frame.name.get.to_s)
|
2386
2395
|
skylights_frame_added += 1
|
2387
2396
|
# if sub_surface.allowWindowPropertyFrameAndDivider
|
@@ -2617,7 +2626,7 @@ class Standard
|
|
2617
2626
|
if data['exterior_glass_door_standards_construction_type'] && data['exterior_glass_door_building_category']
|
2618
2627
|
exterior_subsurfaces.setGlassDoorConstruction(model_find_and_add_construction(model,
|
2619
2628
|
climate_zone_set,
|
2620
|
-
|
2629
|
+
'GlassDoor',
|
2621
2630
|
data['exterior_glass_door_standards_construction_type'],
|
2622
2631
|
data['exterior_glass_door_building_category']))
|
2623
2632
|
end
|
@@ -2698,7 +2707,7 @@ class Standard
|
|
2698
2707
|
# Find curve data
|
2699
2708
|
data = model_find_object(standards_data['curves'], 'name' => curve_name)
|
2700
2709
|
if data.nil?
|
2701
|
-
OpenStudio
|
2710
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.Model.Model', "Could not find a curve called '#{curve_name}' in the standards.")
|
2702
2711
|
return nil
|
2703
2712
|
end
|
2704
2713
|
|
@@ -2788,7 +2797,7 @@ class Standard
|
|
2788
2797
|
return curve
|
2789
2798
|
when 'MultiVariableLookupTable'
|
2790
2799
|
num_ind_var = data['number_independent_variables'].to_i
|
2791
|
-
table = OpenStudio::Model::TableMultiVariableLookup.new(model,num_ind_var)
|
2800
|
+
table = OpenStudio::Model::TableMultiVariableLookup.new(model, num_ind_var)
|
2792
2801
|
table.setName(data['name'])
|
2793
2802
|
table.setInterpolationMethod(data['interpolation_method'])
|
2794
2803
|
table.setNumberofInterpolationPoints(data['number_of_interpolation_points'])
|
@@ -2804,17 +2813,17 @@ class Standard
|
|
2804
2813
|
table.setMaximumValueofX2(data['maximum_independent_variable_2'].to_f)
|
2805
2814
|
table.setInputUnitTypeforX2(data['input_unit_type_x2'])
|
2806
2815
|
end
|
2807
|
-
data_points = data.each.select {|key,value| key.include?
|
2808
|
-
data_points.each do |key,value|
|
2816
|
+
data_points = data.each.select { |key, value| key.include? 'data_point' }
|
2817
|
+
data_points.each do |key, value|
|
2809
2818
|
if num_ind_var == 1
|
2810
|
-
table.addPoint(value.split(',')[0].to_f,value.split(',')[1].to_f)
|
2819
|
+
table.addPoint(value.split(',')[0].to_f, value.split(',')[1].to_f)
|
2811
2820
|
elsif num_ind_var == 2
|
2812
|
-
table.addPoint(value.split(',')[0].to_f,value.split(',')[1].to_f,value.split(',')[2].to_f)
|
2821
|
+
table.addPoint(value.split(',')[0].to_f, value.split(',')[1].to_f, value.split(',')[2].to_f)
|
2813
2822
|
end
|
2814
2823
|
end
|
2815
2824
|
return table
|
2816
2825
|
else
|
2817
|
-
OpenStudio
|
2826
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.Model.Model', "#{curve_name}' has an invalid form: #{data['form']}', cannot create this curve.")
|
2818
2827
|
return nil
|
2819
2828
|
end
|
2820
2829
|
end
|
@@ -2876,14 +2885,14 @@ class Standard
|
|
2876
2885
|
temp = File.read("#{standards_data_dir}/legacy_idf_results.csv")
|
2877
2886
|
end
|
2878
2887
|
end
|
2879
|
-
legacy_idf_csv = CSV.new(temp, :
|
2880
|
-
legacy_idf_results = legacy_idf_csv.to_a.map
|
2888
|
+
legacy_idf_csv = CSV.new(temp, headers: true, converters: :all)
|
2889
|
+
legacy_idf_results = legacy_idf_csv.to_a.map(&:to_hash)
|
2881
2890
|
|
2882
2891
|
# Get the results for this building
|
2883
2892
|
search_criteria = {
|
2884
|
-
|
2885
|
-
|
2886
|
-
|
2893
|
+
'Building Type' => building_type,
|
2894
|
+
'Template' => template,
|
2895
|
+
'Climate Zone' => climate_zone
|
2887
2896
|
}
|
2888
2897
|
energy_values = model_find_object(legacy_idf_results, search_criteria)
|
2889
2898
|
if energy_values.nil?
|
@@ -2918,12 +2927,13 @@ class Standard
|
|
2918
2927
|
fuel_types = ['Electricity', 'Natural Gas', 'Additional Fuel', 'District Cooling', 'District Heating', 'Water']
|
2919
2928
|
|
2920
2929
|
# List of all end uses
|
2921
|
-
end_uses = ['Heating', 'Cooling', 'Interior Lighting', 'Exterior Lighting', 'Interior Equipment', 'Exterior Equipment', 'Fans', 'Pumps', 'Heat Rejection','Humidification', 'Heat Recovery', 'Water Systems', 'Refrigeration', 'Generators']
|
2930
|
+
end_uses = ['Heating', 'Cooling', 'Interior Lighting', 'Exterior Lighting', 'Interior Equipment', 'Exterior Equipment', 'Fans', 'Pumps', 'Heat Rejection', 'Humidification', 'Heat Recovery', 'Water Systems', 'Refrigeration', 'Generators']
|
2922
2931
|
|
2923
2932
|
# Sum the legacy results up by fuel and by end use
|
2924
2933
|
fuel_types.each do |fuel_type|
|
2925
2934
|
end_uses.each do |end_use|
|
2926
2935
|
next if end_use == 'Exterior Equipment'
|
2936
|
+
|
2927
2937
|
legacy_val = legacy_values["#{end_use}|#{fuel_type}"]
|
2928
2938
|
|
2929
2939
|
# Combine the exterior lighting and exterior equipment
|
@@ -2958,10 +2968,9 @@ class Standard
|
|
2958
2968
|
else
|
2959
2969
|
legacy_results_hash['total_energy_by_end_use'][end_use] = legacy_val # start new counter
|
2960
2970
|
end
|
2961
|
-
|
2962
2971
|
end
|
2963
|
-
end
|
2964
|
-
end
|
2972
|
+
end
|
2973
|
+
end
|
2965
2974
|
|
2966
2975
|
return legacy_results_hash
|
2967
2976
|
end
|
@@ -2983,14 +2992,15 @@ class Standard
|
|
2983
2992
|
result = 46_320
|
2984
2993
|
elsif building_type == 'MediumOffice' # 53,600 ft^2
|
2985
2994
|
result = 4982
|
2986
|
-
|
2995
|
+
elsif building_type == 'LargeOfficeDetailed' # 498,600 ft^2
|
2987
2996
|
result = 46_320
|
2988
2997
|
elsif building_type == 'MediumOfficeDetailed' # 53,600 ft^2
|
2989
2998
|
result = 4982
|
2990
2999
|
elsif building_type == 'MidriseApartment' # 33,700 ft^2
|
2991
3000
|
result = 3135
|
2992
3001
|
elsif building_type == 'Office'
|
2993
|
-
result = nil
|
3002
|
+
result = nil
|
3003
|
+
# TODO: there shouldn't be a prototype building for this
|
2994
3004
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', 'Measures calling this should choose between SmallOffice, MediumOffice, and LargeOffice')
|
2995
3005
|
elsif building_type == 'Outpatient' # 40.950 ft^2
|
2996
3006
|
result = 3804
|
@@ -3014,9 +3024,9 @@ class Standard
|
|
3014
3024
|
result = 4181
|
3015
3025
|
elsif building_type == 'Warehouse' # 49,495 ft^2 (legacy ref shows 52,045, but I wil calc using 49,495)
|
3016
3026
|
result = 4595
|
3017
|
-
elsif building_type == 'SmallDataCenterLowITE'
|
3027
|
+
elsif building_type == 'SmallDataCenterLowITE' || building_type == 'SmallDataCenterHighITE' # 600 ft^2
|
3018
3028
|
result = 56
|
3019
|
-
elsif building_type == 'LargeDataCenterLowITE'
|
3029
|
+
elsif building_type == 'LargeDataCenterLowITE' || building_type == 'LargeDataCenterHighITE' # 6000 ft^2
|
3020
3030
|
result = 557
|
3021
3031
|
elsif building_type == 'Laboratory' # 90000 ft^2
|
3022
3032
|
result = 8361
|
@@ -3253,6 +3263,7 @@ class Standard
|
|
3253
3263
|
# Hard-assigned surfaces
|
3254
3264
|
model.getSurfaces.sort.each do |surf|
|
3255
3265
|
next unless surf.outsideBoundaryCondition == boundary_condition
|
3266
|
+
|
3256
3267
|
surf_type = surf.surfaceType
|
3257
3268
|
if surf_type == 'Floor' || surf_type == 'Wall'
|
3258
3269
|
next unless type.include?(surf_type)
|
@@ -3265,6 +3276,7 @@ class Standard
|
|
3265
3276
|
# Hard-assigned subsurfaces
|
3266
3277
|
model.getSubSurfaces.sort.each do |surf|
|
3267
3278
|
next unless surf.outsideBoundaryCondition == boundary_condition
|
3279
|
+
|
3268
3280
|
surf_type = surf.subSurfaceType
|
3269
3281
|
if surf_type == 'FixedWindow' || surf_type == 'OperableWindow'
|
3270
3282
|
next unless type == 'ExteriorWindow'
|
@@ -3280,6 +3292,7 @@ class Standard
|
|
3280
3292
|
all_constructions = []
|
3281
3293
|
constructions.uniq.each do |const|
|
3282
3294
|
next if const.empty?
|
3295
|
+
|
3283
3296
|
all_constructions << const.get
|
3284
3297
|
end
|
3285
3298
|
|
@@ -3424,6 +3437,7 @@ class Standard
|
|
3424
3437
|
model.getSurfaces.sort.each do |surf|
|
3425
3438
|
next unless surf.outsideBoundaryCondition == boundary_condition
|
3426
3439
|
next unless surf.surfaceType == surface_type
|
3440
|
+
|
3427
3441
|
surfaces_to_modify << surf
|
3428
3442
|
end
|
3429
3443
|
|
@@ -3431,6 +3445,7 @@ class Standard
|
|
3431
3445
|
model.getSubSurfaces.sort.each do |surf|
|
3432
3446
|
next unless surf.outsideBoundaryCondition == boundary_condition
|
3433
3447
|
next unless surf.subSurfaceType == surface_type
|
3448
|
+
|
3434
3449
|
surfaces_to_modify << surf
|
3435
3450
|
end
|
3436
3451
|
end
|
@@ -3460,8 +3475,7 @@ class Standard
|
|
3460
3475
|
# @param building_category [string] the type of building
|
3461
3476
|
# @param climate_zone [string] the building's climate zone
|
3462
3477
|
# @return [hash] hash of construction properties
|
3463
|
-
def model_get_construction_properties(model, intended_surface_type, standards_construction_type, building_category, climate_zone=nil)
|
3464
|
-
|
3478
|
+
def model_get_construction_properties(model, intended_surface_type, standards_construction_type, building_category, climate_zone = nil)
|
3465
3479
|
# get climate_zone_set
|
3466
3480
|
climate_zone = model_get_building_climate_zone_and_building_type(model)['climate_zone'] if climate_zone.nil?
|
3467
3481
|
climate_zone_set = model_find_climate_zone_set(model, climate_zone)
|
@@ -3487,14 +3501,14 @@ class Standard
|
|
3487
3501
|
# @param space_type [string] space type within the building type. Typically nil.
|
3488
3502
|
# @return [hash] hash of construction set data
|
3489
3503
|
def model_get_construction_set(building_type, space_type = nil)
|
3490
|
-
#populate search hash
|
3504
|
+
# populate search hash
|
3491
3505
|
search_criteria = {
|
3492
|
-
|
3493
|
-
|
3494
|
-
|
3506
|
+
'template' => template,
|
3507
|
+
'building_type' => building_type,
|
3508
|
+
'space_type' => space_type
|
3495
3509
|
}
|
3496
3510
|
|
3497
|
-
#Search construction sets table for the exterior wall building category and construction type
|
3511
|
+
# Search construction sets table for the exterior wall building category and construction type
|
3498
3512
|
construction_set_data = model_find_object(standards_data['construction_sets'], search_criteria)
|
3499
3513
|
|
3500
3514
|
return construction_set_data
|
@@ -3533,11 +3547,13 @@ class Standard
|
|
3533
3547
|
next unless surface.outsideBoundaryCondition == 'Outdoors'
|
3534
3548
|
# Skip non-walls
|
3535
3549
|
next unless surface.surfaceType.casecmp('wall').zero?
|
3550
|
+
|
3536
3551
|
# This wall's gross area (including window area)
|
3537
3552
|
wall_area_m2 += surface.grossArea * space.multiplier
|
3538
3553
|
# Subsurfaces in this surface
|
3539
3554
|
surface.subSurfaces.sort.each do |ss|
|
3540
3555
|
next unless ss.subSurfaceType == 'FixedWindow' || ss.subSurfaceType == 'OperableWindow'
|
3556
|
+
|
3541
3557
|
wind_area_m2 += ss.netArea * space.multiplier
|
3542
3558
|
end
|
3543
3559
|
end
|
@@ -3632,12 +3648,15 @@ class Standard
|
|
3632
3648
|
next # Skip unconditioned spaces
|
3633
3649
|
when 'NonResConditioned'
|
3634
3650
|
next unless red_nr
|
3651
|
+
|
3635
3652
|
mult = mult_nr_red
|
3636
3653
|
when 'ResConditioned'
|
3637
3654
|
next unless red_res
|
3655
|
+
|
3638
3656
|
mult = mult_res_red
|
3639
3657
|
when 'Semiheated'
|
3640
3658
|
next unless red_sh
|
3659
|
+
|
3641
3660
|
mult = mult_sh_red
|
3642
3661
|
end
|
3643
3662
|
|
@@ -3647,9 +3666,11 @@ class Standard
|
|
3647
3666
|
next unless surface.outsideBoundaryCondition == 'Outdoors'
|
3648
3667
|
# Skip non-walls
|
3649
3668
|
next unless surface.surfaceType.casecmp('wall').zero?
|
3669
|
+
|
3650
3670
|
# Subsurfaces in this surface
|
3651
3671
|
surface.subSurfaces.sort.each do |ss|
|
3652
3672
|
next unless ss.subSurfaceType == 'FixedWindow' || ss.subSurfaceType == 'OperableWindow'
|
3673
|
+
|
3653
3674
|
# Reduce the size of the window
|
3654
3675
|
# If a vertical rectangle, raise sill height to avoid
|
3655
3676
|
# impacting daylighting areas, otherwise
|
@@ -3693,11 +3714,13 @@ class Standard
|
|
3693
3714
|
next unless surface.outsideBoundaryCondition == 'Outdoors'
|
3694
3715
|
# Skip non-walls
|
3695
3716
|
next unless surface.surfaceType == 'RoofCeiling'
|
3717
|
+
|
3696
3718
|
# This wall's gross area (including skylight area)
|
3697
3719
|
wall_area_m2 += surface.grossArea * space.multiplier
|
3698
3720
|
# Subsurfaces in this surface
|
3699
3721
|
surface.subSurfaces.sort.each do |ss|
|
3700
3722
|
next unless ss.subSurfaceType == 'Skylight'
|
3723
|
+
|
3701
3724
|
sky_area_m2 += ss.netArea * space.multiplier
|
3702
3725
|
end
|
3703
3726
|
end
|
@@ -3767,9 +3790,11 @@ class Standard
|
|
3767
3790
|
case cat
|
3768
3791
|
when 'NonRes'
|
3769
3792
|
next unless red_nr
|
3793
|
+
|
3770
3794
|
mult = mult_nr_red
|
3771
3795
|
when 'Res'
|
3772
3796
|
next unless red_res
|
3797
|
+
|
3773
3798
|
mult = mult_res_red
|
3774
3799
|
when 'Semiheated'
|
3775
3800
|
next unless red_sh
|
@@ -3782,9 +3807,11 @@ class Standard
|
|
3782
3807
|
next unless surface.outsideBoundaryCondition == 'Outdoors'
|
3783
3808
|
# Skip non-walls
|
3784
3809
|
next unless surface.surfaceType == 'RoofCeiling'
|
3810
|
+
|
3785
3811
|
# Subsurfaces in this surface
|
3786
3812
|
surface.subSurfaces.sort.each do |ss|
|
3787
3813
|
next unless ss.subSurfaceType == 'Skylight'
|
3814
|
+
|
3788
3815
|
# Reduce the size of the skylight
|
3789
3816
|
red = 1.0 - mult
|
3790
3817
|
sub_surface_reduce_area_by_percent_by_shrinking_toward_centroid(ss, red)
|
@@ -3812,6 +3839,7 @@ class Standard
|
|
3812
3839
|
model.getPlantLoops.sort.each do |loop|
|
3813
3840
|
# Don't remove service water heating loops
|
3814
3841
|
next if plant_loop_swh_loop?(loop)
|
3842
|
+
|
3815
3843
|
loop.remove
|
3816
3844
|
end
|
3817
3845
|
|
@@ -3822,6 +3850,7 @@ class Standard
|
|
3822
3850
|
model.getThermalZones.sort.each do |zone|
|
3823
3851
|
zone.equipment.each do |zone_equipment|
|
3824
3852
|
next if zone_equipment.to_FanZoneExhaust.is_initialized
|
3853
|
+
|
3825
3854
|
zone_equipment.remove
|
3826
3855
|
end
|
3827
3856
|
end
|
@@ -3836,18 +3865,18 @@ class Standard
|
|
3836
3865
|
#
|
3837
3866
|
# @return [Bool] true if successful, false if not
|
3838
3867
|
def model_remove_prm_ems_objects(model)
|
3839
|
-
model.getEnergyManagementSystemActuators.each
|
3840
|
-
model.getEnergyManagementSystemConstructionIndexVariables.each
|
3841
|
-
model.getEnergyManagementSystemCurveOrTableIndexVariables.each
|
3842
|
-
model.getEnergyManagementSystemGlobalVariables.each
|
3843
|
-
model.getEnergyManagementSystemInternalVariables.each
|
3844
|
-
model.getEnergyManagementSystemMeteredOutputVariables.each
|
3845
|
-
model.getEnergyManagementSystemOutputVariables.each
|
3846
|
-
model.getEnergyManagementSystemPrograms.each
|
3847
|
-
model.getEnergyManagementSystemProgramCallingManagers.each
|
3848
|
-
model.getEnergyManagementSystemSensors.each
|
3849
|
-
model.getEnergyManagementSystemSubroutines.each
|
3850
|
-
model.getEnergyManagementSystemTrendVariables.each
|
3868
|
+
model.getEnergyManagementSystemActuators.each(&:remove)
|
3869
|
+
model.getEnergyManagementSystemConstructionIndexVariables.each(&:remove)
|
3870
|
+
model.getEnergyManagementSystemCurveOrTableIndexVariables.each(&:remove)
|
3871
|
+
model.getEnergyManagementSystemGlobalVariables.each(&:remove)
|
3872
|
+
model.getEnergyManagementSystemInternalVariables.each(&:remove)
|
3873
|
+
model.getEnergyManagementSystemMeteredOutputVariables.each(&:remove)
|
3874
|
+
model.getEnergyManagementSystemOutputVariables.each(&:remove)
|
3875
|
+
model.getEnergyManagementSystemPrograms.each(&:remove)
|
3876
|
+
model.getEnergyManagementSystemProgramCallingManagers.each(&:remove)
|
3877
|
+
model.getEnergyManagementSystemSensors.each(&:remove)
|
3878
|
+
model.getEnergyManagementSystemSubroutines.each(&:remove)
|
3879
|
+
model.getEnergyManagementSystemTrendVariables.each(&:remove)
|
3851
3880
|
|
3852
3881
|
return true
|
3853
3882
|
end
|
@@ -3859,6 +3888,7 @@ class Standard
|
|
3859
3888
|
model.getShadingSurfaceGroups.sort.each do |shade_group|
|
3860
3889
|
# Skip Site shading
|
3861
3890
|
next if shade_group.shadingSurfaceType == 'Site'
|
3891
|
+
|
3862
3892
|
# Space shading surfaces should be removed
|
3863
3893
|
shading_surfaces_removed += shade_group.shadingSurfaces.size
|
3864
3894
|
shade_group.remove
|
@@ -3936,7 +3966,7 @@ class Standard
|
|
3936
3966
|
result << { units: 'unit', block: 75, max_hourly: 8.5, max_daily: 66.0, avg_day_unit: 38.0 }
|
3937
3967
|
result << { units: 'unit', block: 100, max_hourly: 7.0, max_daily: 60.0, avg_day_unit: 37.0 }
|
3938
3968
|
result << { units: 'unit', block: 200, max_hourly: 5.0, max_daily: 50.0, avg_day_unit: 35.0 }
|
3939
|
-
elsif ['Office', 'LargeOffice', 'MediumOffice', 'SmallOffice','LargeOfficeDetailed', 'MediumOfficeDetailed', 'SmallOfficeDetailed'].include? building_type
|
3969
|
+
elsif ['Office', 'LargeOffice', 'MediumOffice', 'SmallOffice', 'LargeOfficeDetailed', 'MediumOfficeDetailed', 'SmallOfficeDetailed'].include? building_type
|
3940
3970
|
result << { units: 'person', block: nil, max_hourly: 0.4, max_daily: 2.0, avg_day_unit: 1.0 }
|
3941
3971
|
elsif building_type == 'Outpatient'
|
3942
3972
|
OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "No SWH rules of thumbs for #{building_type}.")
|
@@ -4115,7 +4145,7 @@ class Standard
|
|
4115
4145
|
# Defaults to the least specific climate zone set.
|
4116
4146
|
# For example, 2A and 2 both contain 2A, so use 2.
|
4117
4147
|
def model_get_climate_zone_set_from_list(model, possible_climate_zone_sets)
|
4118
|
-
climate_zone_set = possible_climate_zone_sets.
|
4148
|
+
climate_zone_set = possible_climate_zone_sets.min
|
4119
4149
|
return climate_zone_set
|
4120
4150
|
end
|
4121
4151
|
|
@@ -4200,6 +4230,7 @@ class Standard
|
|
4200
4230
|
# update count of ground wall areas
|
4201
4231
|
next if surface.surfaceType != 'Wall'
|
4202
4232
|
next if surface.outsideBoundaryCondition != 'Ground' # TODO: - make more flexible for slab/basement model.modeling
|
4233
|
+
|
4203
4234
|
story_ground_wall_area += surface.grossArea
|
4204
4235
|
end
|
4205
4236
|
|
@@ -4298,6 +4329,7 @@ class Standard
|
|
4298
4329
|
# loop through spaces to get mis values
|
4299
4330
|
space_type.spaces.sort.each do |space|
|
4300
4331
|
next unless space.partofTotalFloorArea
|
4332
|
+
|
4301
4333
|
effective_num_spaces += space.multiplier
|
4302
4334
|
floor_area += space.floorArea * space.multiplier
|
4303
4335
|
num_people += space.numberOfPeople * space.multiplier
|
@@ -4373,7 +4405,6 @@ class Standard
|
|
4373
4405
|
return space_type_hash.sort.to_h
|
4374
4406
|
end
|
4375
4407
|
|
4376
|
-
|
4377
4408
|
# This method will apply the a FDWR to a model. It will remove any existing windows and doors and use the
|
4378
4409
|
# Default contruction to set to apply the window construction. Sill height is in meters
|
4379
4410
|
def apply_max_fdwr(model, runner, sillHeight_si, wwr)
|
@@ -4383,10 +4414,12 @@ class Standard
|
|
4383
4414
|
zone = surface.space.get.thermalZone
|
4384
4415
|
zone_multiplier = nil
|
4385
4416
|
next if zone.empty?
|
4386
|
-
|
4387
|
-
|
4417
|
+
|
4418
|
+
if (surface.outsideBoundaryCondition == 'Outdoors') && (surface.surfaceType == 'Wall')
|
4419
|
+
surface.subSurfaces.each(&:remove)
|
4388
4420
|
new_window = surface.setWindowToWallRatio(wwr, sillHeight_si, true)
|
4389
4421
|
raise "#{surface.name.get} did not get set to #{wwr}. The size of the surface is #{surface.grossArea}" unless surface.windowToWallRatio.round(3) == wwr.round(3)
|
4422
|
+
|
4390
4423
|
if new_window.empty?
|
4391
4424
|
runner.registerWarning("The requested window to wall ratio for surface '#{surface.name}' was too large. Fenestration was not altered for this surface.")
|
4392
4425
|
else
|
@@ -4406,10 +4439,10 @@ class Standard
|
|
4406
4439
|
# Default contruction to set to apply the skylight construction. A default skylight square area of 0.25^2 is used.
|
4407
4440
|
def apply_max_srr(model, runner, srr, skylight_area = 0.25 * 0.25)
|
4408
4441
|
spaces = []
|
4409
|
-
surface_type =
|
4442
|
+
surface_type = 'RoofCeiling'
|
4410
4443
|
model.getSpaces.sort.each do |space|
|
4411
4444
|
space.surfaces.sort.each do |surface|
|
4412
|
-
if surface.outsideBoundaryCondition == 'Outdoors'
|
4445
|
+
if (surface.outsideBoundaryCondition == 'Outdoors') && (surface.surfaceType == surface_type)
|
4413
4446
|
spaces << space
|
4414
4447
|
break
|
4415
4448
|
end
|
@@ -4418,13 +4451,13 @@ class Standard
|
|
4418
4451
|
pattern = OpenStudio::Model.generateSkylightPattern(spaces, spaces[0].directionofRelativeNorth, srr, Math.sqrt(skylight_area), Math.sqrt(skylight_area)) # ratio, x value, y value
|
4419
4452
|
# applying skylight pattern
|
4420
4453
|
skylights = OpenStudio::Model.applySkylightPattern(pattern, spaces, OpenStudio::Model::OptionalConstructionBase.new)
|
4421
|
-
spacenames = spaces.map {|space| space.name.get}
|
4454
|
+
spacenames = spaces.map { |space| space.name.get }
|
4422
4455
|
runner.registerInfo("Adding #{skylights.size} skylights to #{spacenames}")
|
4423
4456
|
end
|
4424
4457
|
|
4425
4458
|
# This method will limit the subsurface of a given surface_type ("Wall" or "RoofCeiling") to the ratio for the building.
|
4426
4459
|
# This method only reduces subsurface sizes at most.
|
4427
|
-
def apply_limit_to_subsurface_ratio(model, ratio, surface_type =
|
4460
|
+
def apply_limit_to_subsurface_ratio(model, ratio, surface_type = 'Wall')
|
4428
4461
|
fdwr = get_outdoor_subsurface_ratio(model, surface_type)
|
4429
4462
|
if fdwr <= ratio
|
4430
4463
|
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "Building FDWR of #{fdwr} is already lower than limit of #{ratio.round}%.")
|
@@ -4441,6 +4474,7 @@ class Standard
|
|
4441
4474
|
next unless surface.outsideBoundaryCondition == 'Outdoors'
|
4442
4475
|
# Skip non-walls
|
4443
4476
|
next unless surface.surfaceType == surface_type
|
4477
|
+
|
4444
4478
|
# Subsurfaces in this surface
|
4445
4479
|
surface.subSurfaces.sort.each do |ss|
|
4446
4480
|
# Reduce the size of the window
|
@@ -4465,6 +4499,7 @@ class Standard
|
|
4465
4499
|
model.getClimateZones.climateZones.each do |cz|
|
4466
4500
|
if cz.institution == 'ASHRAE'
|
4467
4501
|
next if cz.value == '' # Skip blank ASHRAE climate zones put in by OpenStudio Application
|
4502
|
+
|
4468
4503
|
climate_zone = if cz.value == '7' || cz.value == '8'
|
4469
4504
|
"ASHRAE 169-2013-#{cz.value}A"
|
4470
4505
|
else
|
@@ -4472,6 +4507,7 @@ class Standard
|
|
4472
4507
|
end
|
4473
4508
|
elsif cz.institution == 'CEC'
|
4474
4509
|
next if cz.value == '' # Skip blank ASHRAE climate zones put in by OpenStudio Application
|
4510
|
+
|
4475
4511
|
climate_zone = "CEC T24-CEC#{cz.value}"
|
4476
4512
|
end
|
4477
4513
|
end
|
@@ -4502,9 +4538,8 @@ class Standard
|
|
4502
4538
|
return true
|
4503
4539
|
end
|
4504
4540
|
|
4505
|
-
|
4506
4541
|
# This method return the building ratio of subsurface_area / surface_type_area where surface_type can be "Wall" or "RoofCeiling"
|
4507
|
-
def get_outdoor_subsurface_ratio(model, surface_type =
|
4542
|
+
def get_outdoor_subsurface_ratio(model, surface_type = 'Wall')
|
4508
4543
|
surface_area = 0.0
|
4509
4544
|
sub_surface_area = 0
|
4510
4545
|
all_surfaces = []
|
@@ -4513,9 +4548,10 @@ class Standard
|
|
4513
4548
|
zone = space.thermalZone
|
4514
4549
|
zone_multiplier = nil
|
4515
4550
|
next if zone.empty?
|
4551
|
+
|
4516
4552
|
zone_multiplier = zone.get.multiplier
|
4517
4553
|
space.surfaces.sort.each do |surface|
|
4518
|
-
if surface.outsideBoundaryCondition == 'Outdoors'
|
4554
|
+
if (surface.outsideBoundaryCondition == 'Outdoors') && (surface.surfaceType == surface_type)
|
4519
4555
|
surface_area += surface.grossArea * zone_multiplier
|
4520
4556
|
surface.subSurfaces.sort.each do |sub_surface|
|
4521
4557
|
sub_surface_area += sub_surface.grossArea * sub_surface.multiplier * zone_multiplier
|
@@ -4534,6 +4570,7 @@ class Standard
|
|
4534
4570
|
unless File.exist?(osm_file)
|
4535
4571
|
raise("The initial osm path: #{osm_file} does not exist.")
|
4536
4572
|
end
|
4573
|
+
|
4537
4574
|
osm_model_path = OpenStudio::Path.new(osm_file.to_s)
|
4538
4575
|
# Upgrade version if required.
|
4539
4576
|
version_translator = OpenStudio::OSVersion::VersionTranslator.new
|
@@ -4545,19 +4582,19 @@ class Standard
|
|
4545
4582
|
def validate_initial_model(model)
|
4546
4583
|
is_valid = true
|
4547
4584
|
if model.getBuildingStorys.empty?
|
4548
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model',
|
4585
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'Please assign Spaces to BuildingStorys the geometry model.')
|
4549
4586
|
is_valid = false
|
4550
4587
|
end
|
4551
4588
|
if model.getThermalZones.empty?
|
4552
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model',
|
4589
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'Please assign Spaces to ThermalZones the geometry model.')
|
4553
4590
|
is_valid = false
|
4554
4591
|
end
|
4555
4592
|
if model.getBuilding.standardsNumberOfStories.empty?
|
4556
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model',
|
4593
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'Please define Building.standardsNumberOfStories the geometry model.')
|
4557
4594
|
is_valid = false
|
4558
4595
|
end
|
4559
4596
|
if model.getBuilding.standardsNumberOfAboveGroundStories.empty?
|
4560
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model',
|
4597
|
+
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'Please define Building.standardsNumberOfAboveStories in the geometry model.')
|
4561
4598
|
is_valid = false
|
4562
4599
|
end
|
4563
4600
|
|
@@ -4568,12 +4605,12 @@ class Standard
|
|
4568
4605
|
is_valid = false
|
4569
4606
|
else
|
4570
4607
|
@space_type_map = @space_type_map.sort.to_h
|
4571
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model',
|
4608
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Loaded space type map from model')
|
4572
4609
|
end
|
4573
4610
|
end
|
4574
4611
|
|
4575
4612
|
# ensure that model is intersected correctly.
|
4576
|
-
model.getSpaces.each {|space1| model.getSpaces.each {|space2| space1.intersectSurfaces(space2)}}
|
4613
|
+
model.getSpaces.each { |space1| model.getSpaces.each { |space2| space1.intersectSurfaces(space2) } }
|
4577
4614
|
# Get multipliers from TZ in model. Need this for HVAC contruction.
|
4578
4615
|
@space_multiplier_map = {}
|
4579
4616
|
model.getSpaces.sort.each do |space|
|
@@ -4595,7 +4632,7 @@ class Standard
|
|
4595
4632
|
def model_ventilation_method(model)
|
4596
4633
|
building_data = model_get_building_climate_zone_and_building_type(model)
|
4597
4634
|
building_type = building_data['building_type']
|
4598
|
-
if building_type != 'Laboratory'
|
4635
|
+
if building_type != 'Laboratory' # Laboratory has multiple criteria on ventilation, pick the greatest
|
4599
4636
|
ventilation_method = 'Sum'
|
4600
4637
|
else
|
4601
4638
|
ventilation_method = 'Maximum'
|
@@ -4612,12 +4649,12 @@ class Standard
|
|
4612
4649
|
start_size = model.objects.size
|
4613
4650
|
model.getResourceObjects.sort.each do |obj|
|
4614
4651
|
if obj.directUseCount.zero?
|
4615
|
-
OpenStudio
|
4652
|
+
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.Model', "#{obj.name} is unused; it will be removed.")
|
4616
4653
|
model.removeObject(obj.handle)
|
4617
4654
|
end
|
4618
4655
|
end
|
4619
4656
|
end_size = model.objects.size
|
4620
|
-
OpenStudio
|
4657
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Model', "The model started with #{start_size} objects and finished with #{end_size} objects after removing unused resource objects.")
|
4621
4658
|
return true
|
4622
4659
|
end
|
4623
4660
|
|
@@ -4637,13 +4674,12 @@ class Standard
|
|
4637
4674
|
# @param gen_occ_profile [Bool] if true creates a merged occupancy schedule for diagnostic purposes. This schedule is added to the model but no specifically returned by this method
|
4638
4675
|
# @return [ScheduleRuleset] schedule that is assigned to the building as default hours of operation
|
4639
4676
|
def model_infer_hours_of_operation_building(model, fraction_of_daily_occ_range: 0.25, invert_res: true, gen_occ_profile: false)
|
4640
|
-
|
4641
4677
|
# create an array of non-residential and residential spaces
|
4642
4678
|
res_spaces = []
|
4643
4679
|
non_res_spaces = []
|
4644
4680
|
res_people_design = 0
|
4645
4681
|
non_res_people_design = 0
|
4646
|
-
model.getSpaces.each do |space|
|
4682
|
+
model.getSpaces.sort.each do |space|
|
4647
4683
|
if space_residential?(space)
|
4648
4684
|
res_spaces << space
|
4649
4685
|
res_people_design += space.numberOfPeople * space.multiplier
|
@@ -4652,31 +4688,31 @@ class Standard
|
|
4652
4688
|
non_res_people_design += space.numberOfPeople * space.multiplier
|
4653
4689
|
end
|
4654
4690
|
end
|
4655
|
-
OpenStudio
|
4691
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.Model', "Model has design level of #{non_res_people_design} people in non residential spaces and #{res_people_design} people in residential spaces.")
|
4656
4692
|
|
4657
4693
|
# create merged schedule for prevalent type (not used but can be generated for diagnostics)
|
4658
4694
|
if gen_occ_profile
|
4659
4695
|
res_prevalent = false
|
4660
4696
|
if res_people_design > non_res_people_design
|
4661
|
-
occ_merged = spaces_get_occupancy_schedule(res_spaces, sch_name:
|
4697
|
+
occ_merged = spaces_get_occupancy_schedule(res_spaces, sch_name: 'Calculated Occupancy Fraction Residential Merged')
|
4662
4698
|
res_prevalent = true
|
4663
4699
|
else
|
4664
|
-
occ_merged = spaces_get_occupancy_schedule(non_res_spaces, sch_name:
|
4700
|
+
occ_merged = spaces_get_occupancy_schedule(non_res_spaces, sch_name: 'Calculated Occupancy Fraction NonResidential Merged')
|
4665
4701
|
end
|
4666
4702
|
end
|
4667
4703
|
|
4668
4704
|
# re-run spaces_get_occupancy_schedule with x above min occupancy to create on/off schedule
|
4669
4705
|
if res_people_design > non_res_people_design
|
4670
4706
|
hours_of_operation = spaces_get_occupancy_schedule(res_spaces,
|
4671
|
-
|
4672
|
-
|
4673
|
-
|
4707
|
+
sch_name: 'Building Hours of Operation Residential',
|
4708
|
+
occupied_percentage_threshold: fraction_of_daily_occ_range,
|
4709
|
+
threshold_calc_method: 'normalized_daily_range')
|
4674
4710
|
res_prevalent = true
|
4675
4711
|
else
|
4676
4712
|
hours_of_operation = spaces_get_occupancy_schedule(non_res_spaces,
|
4677
|
-
sch_name:
|
4678
|
-
|
4679
|
-
|
4713
|
+
sch_name: 'Building Hours of Operation NonResidential',
|
4714
|
+
occupied_percentage_threshold: fraction_of_daily_occ_range,
|
4715
|
+
threshold_calc_method: 'normalized_daily_range')
|
4680
4716
|
end
|
4681
4717
|
|
4682
4718
|
# remove gaps resulting in multiple on off cycles for each rule in schedule so it will be valid hours of operation
|
@@ -4685,10 +4721,11 @@ class Standard
|
|
4685
4721
|
hours_of_operation.scheduleRules.each do |rule|
|
4686
4722
|
profiles << rule.daySchedule
|
4687
4723
|
end
|
4688
|
-
profiles.each do |profile|
|
4724
|
+
profiles.sort.each do |profile|
|
4689
4725
|
times = profile.times
|
4690
4726
|
values = profile.values
|
4691
4727
|
next if times.size <= 3 # length of 1-3 should produce valid hours_of_operation profiles
|
4728
|
+
|
4692
4729
|
# Find the latest time where the value == 1
|
4693
4730
|
latest_time = nil
|
4694
4731
|
times.zip(values).each do |time, value|
|
@@ -4698,6 +4735,7 @@ class Standard
|
|
4698
4735
|
end
|
4699
4736
|
# Skip profiles that are zero all the time
|
4700
4737
|
next if latest_time.nil?
|
4738
|
+
|
4701
4739
|
# Calculate the duration from this point to midnight
|
4702
4740
|
wrap_dur_left_hr = 0
|
4703
4741
|
if values.first == 0 && values.last == 0
|
@@ -4706,9 +4744,10 @@ class Standard
|
|
4706
4744
|
occ_gap_hash = {}
|
4707
4745
|
prev_time = 0
|
4708
4746
|
prev_val = nil
|
4709
|
-
times.each_with_index do |time,i|
|
4747
|
+
times.each_with_index do |time, i|
|
4710
4748
|
next if time.totalHours == 0.0 # should not see this
|
4711
4749
|
next if values[i] == prev_val # check if two 0 until time next to each other
|
4750
|
+
|
4712
4751
|
if values[i] == 0 # only store vacant segments
|
4713
4752
|
if time.totalHours == 24
|
4714
4753
|
occ_gap_hash[prev_time] = time.totalHours - prev_time + wrap_dur_left_hr
|
@@ -4734,44 +4773,42 @@ class Standard
|
|
4734
4773
|
target_end_min = ((max_occ_gap_end_hr - target_end_hr) * 60.0).truncate
|
4735
4774
|
max_occ_gap_end = OpenStudio::Time.new(0, target_end_hr, target_end_min, 0)
|
4736
4775
|
|
4737
|
-
profile.addValue(max_occ_gap_start,1)
|
4738
|
-
profile.addValue(max_occ_gap_end,0)
|
4776
|
+
profile.addValue(max_occ_gap_start, 1)
|
4777
|
+
profile.addValue(max_occ_gap_end, 0)
|
4739
4778
|
os_time_24 = OpenStudio::Time.new(0, 24, 0, 0)
|
4740
4779
|
if max_occ_gap_start > max_occ_gap_end
|
4741
|
-
profile.addValue(os_time_24,0)
|
4780
|
+
profile.addValue(os_time_24, 0)
|
4742
4781
|
else
|
4743
|
-
profile.addValue(os_time_24,1)
|
4782
|
+
profile.addValue(os_time_24, 1)
|
4744
4783
|
end
|
4745
4784
|
end
|
4746
4785
|
|
4747
4786
|
# reverse 1 and 0 values for res_prevalent building
|
4748
4787
|
# currently spaces_get_occupancy_schedule doesn't use defaultDayProflie, so only inspecting rules for now.
|
4749
4788
|
if invert_res && res_prevalent
|
4750
|
-
OpenStudio
|
4789
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.Standards.Model', 'Per argument passed in hours of operation are being inverted for buildings with more people in residential versus non-residential spaces.')
|
4751
4790
|
hours_of_operation.scheduleRules.each do |rule|
|
4752
4791
|
profile = rule.daySchedule
|
4753
4792
|
times = profile.times
|
4754
4793
|
values = profile.values
|
4755
4794
|
profile.clearValues
|
4756
|
-
times.each_with_index do |time,i|
|
4795
|
+
times.each_with_index do |time, i|
|
4757
4796
|
orig_val = values[i]
|
4758
4797
|
new_value = nil
|
4759
4798
|
if orig_val == 0 then new_value = 1 end
|
4760
4799
|
if orig_val == 1 then new_value = 0 end
|
4761
|
-
profile.addValue(time,new_value)
|
4800
|
+
profile.addValue(time, new_value)
|
4762
4801
|
end
|
4763
4802
|
end
|
4764
4803
|
end
|
4765
4804
|
|
4766
4805
|
# set hours of operation for building level hours of operation
|
4767
|
-
model.getDefaultScheduleSets.each
|
4768
|
-
sch_set.resetHoursofOperationSchedule
|
4769
|
-
end
|
4806
|
+
model.getDefaultScheduleSets.each(&:resetHoursofOperationSchedule)
|
4770
4807
|
if model.getBuilding.defaultScheduleSet.is_initialized
|
4771
4808
|
default_sch_set = model.getBuilding.defaultScheduleSet.get
|
4772
4809
|
else
|
4773
4810
|
default_sch_set = OpenStudio::Model::DefaultScheduleSet.new(model)
|
4774
|
-
default_sch_set.setName(
|
4811
|
+
default_sch_set.setName('Building Default Schedule Set')
|
4775
4812
|
model.getBuilding.setDefaultScheduleSet(default_sch_set)
|
4776
4813
|
end
|
4777
4814
|
default_sch_set.setHoursofOperationSchedule(hours_of_operation)
|
@@ -4788,9 +4825,10 @@ class Standard
|
|
4788
4825
|
# @param model [Model]
|
4789
4826
|
# @param step_ramp_logic [String]
|
4790
4827
|
# @param infer_hoo_for_non_assigned_objects [Bool] # attempt to get hoo for objects like swh with and exterior lighting
|
4828
|
+
# @param gather_data_only: false (stops method before changes made if true)
|
4829
|
+
# @param [hoo_var_method] accepts hours and fractional. Any other value value will result in hoo variables not being applied
|
4791
4830
|
# @return [Hash] schedule is key, value is hash of number of objects
|
4792
|
-
def model_setup_parametric_schedules(model, step_ramp_logic: nil, infer_hoo_for_non_assigned_objects: true,gather_data_only: false)
|
4793
|
-
|
4831
|
+
def model_setup_parametric_schedules(model, step_ramp_logic: nil, infer_hoo_for_non_assigned_objects: true, gather_data_only: false, hoo_var_method: 'hours')
|
4794
4832
|
parametric_inputs = {}
|
4795
4833
|
default_sch_type = OpenStudio::Model::DefaultScheduleType.new('HoursofOperationSchedule')
|
4796
4834
|
# thermal zones, air loops, plant loops will require some logic if they refer to more than one hours of operaiton schedule.
|
@@ -4800,14 +4838,14 @@ class Standard
|
|
4800
4838
|
# whatever approach is used for gathering parametric inputs for existing ruleset schedules should also be used for model_apply_parametric_schedules
|
4801
4839
|
|
4802
4840
|
# loop through spaces (trace hours of operation back to space)
|
4803
|
-
gather_inputs_parametric_space_space_type_schedules(model.getSpaces,parametric_inputs,gather_data_only)
|
4841
|
+
gather_inputs_parametric_space_space_type_schedules(model.getSpaces, parametric_inputs, gather_data_only)
|
4804
4842
|
|
4805
4843
|
# loop through space types (trace hours of operation back to space type).
|
4806
|
-
gather_inputs_parametric_space_space_type_schedules(model.getSpaceTypes,parametric_inputs,gather_data_only)
|
4844
|
+
gather_inputs_parametric_space_space_type_schedules(model.getSpaceTypes, parametric_inputs, gather_data_only)
|
4807
4845
|
|
4808
4846
|
# loop through thermal zones (trace hours of operation back to spaces in thermal zone)
|
4809
4847
|
thermal_zone_hash = {} # key is zone and hash is hours of operation
|
4810
|
-
model.getThermalZones.each do |zone|
|
4848
|
+
model.getThermalZones.sort.each do |zone|
|
4811
4849
|
# identify hours of operation
|
4812
4850
|
hours_of_operation = spaces_hours_of_operation(zone.spaces)
|
4813
4851
|
thermal_zone_hash[zone] = hours_of_operation
|
@@ -4816,39 +4854,39 @@ class Standard
|
|
4816
4854
|
thermostat = zone.thermostatSetpointDualSetpoint.get
|
4817
4855
|
if thermostat.heatingSetpointTemperatureSchedule.is_initialized && thermostat.heatingSetpointTemperatureSchedule.get.to_ScheduleRuleset.is_initialized
|
4818
4856
|
schedule = thermostat.heatingSetpointTemperatureSchedule.get.to_ScheduleRuleset.get
|
4819
|
-
gather_inputs_parametric_schedules(schedule,thermostat,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
|
4857
|
+
gather_inputs_parametric_schedules(schedule, thermostat, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
|
4820
4858
|
end
|
4821
|
-
if thermostat.coolingSetpointTemperatureSchedule.is_initialized&& thermostat.coolingSetpointTemperatureSchedule.get.to_ScheduleRuleset.is_initialized
|
4859
|
+
if thermostat.coolingSetpointTemperatureSchedule.is_initialized && thermostat.coolingSetpointTemperatureSchedule.get.to_ScheduleRuleset.is_initialized
|
4822
4860
|
schedule = thermostat.coolingSetpointTemperatureSchedule.get.to_ScheduleRuleset.get
|
4823
|
-
gather_inputs_parametric_schedules(schedule,thermostat,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
|
4861
|
+
gather_inputs_parametric_schedules(schedule, thermostat, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
|
4824
4862
|
end
|
4825
4863
|
end
|
4826
4864
|
end
|
4827
4865
|
|
4828
4866
|
# loop through air loops (trace hours of operation back through spaces served by air loops)
|
4829
4867
|
air_loop_hash = {} # key is zone and hash is hours of operation
|
4830
|
-
model.getAirLoopHVACs.each do |air_loop|
|
4868
|
+
model.getAirLoopHVACs.sort.each do |air_loop|
|
4831
4869
|
# identify hours of operation
|
4832
4870
|
air_loop_spaces = []
|
4833
|
-
air_loop.thermalZones.each do |zone|
|
4834
|
-
air_loop_spaces
|
4835
|
-
air_loop_spaces
|
4871
|
+
air_loop.thermalZones.sort.each do |zone|
|
4872
|
+
air_loop_spaces += zone.spaces
|
4873
|
+
air_loop_spaces += zone.spaces
|
4836
4874
|
end
|
4837
4875
|
hours_of_operation = spaces_hours_of_operation(air_loop_spaces)
|
4838
4876
|
air_loop_hash[air_loop] = hours_of_operation
|
4839
4877
|
if air_loop.availabilitySchedule.to_ScheduleRuleset.is_initialized
|
4840
4878
|
schedule = air_loop.availabilitySchedule.to_ScheduleRuleset.get
|
4841
|
-
gather_inputs_parametric_schedules(schedule,air_loop,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
|
4879
|
+
gather_inputs_parametric_schedules(schedule, air_loop, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
|
4842
4880
|
end
|
4843
4881
|
avail_mgrs = air_loop.availabilityManagers
|
4844
|
-
avail_mgrs.each do |avail_mgr|
|
4845
|
-
#
|
4882
|
+
avail_mgrs.sort.each do |avail_mgr|
|
4883
|
+
# TODO: - I'm finding availability mangers, but not any resources for them, even if I use OpenStudio::Model.getRecursiveChildren(avail_mgr)
|
4846
4884
|
resources = avail_mgr.resources
|
4847
4885
|
resources = OpenStudio::Model.getRecursiveResources(avail_mgr)
|
4848
|
-
resources.each do |resource|
|
4886
|
+
resources.sort.each do |resource|
|
4849
4887
|
if resource.to_ScheduleRuleset.is_initialized
|
4850
4888
|
schedule = resource.to_ScheduleRuleset.get
|
4851
|
-
gather_inputs_parametric_schedules(schedule,avail_mgr,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
|
4889
|
+
gather_inputs_parametric_schedules(schedule, avail_mgr, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
|
4852
4890
|
end
|
4853
4891
|
end
|
4854
4892
|
end
|
@@ -4856,7 +4894,7 @@ class Standard
|
|
4856
4894
|
|
4857
4895
|
# look through all model HVAC components find scheduleRuleset objects, resources, that use them and zone or air loop for hours of operation
|
4858
4896
|
hvac_components = model.getHVACComponents
|
4859
|
-
hvac_components.each do |component|
|
4897
|
+
hvac_components.sort.each do |component|
|
4860
4898
|
# identify zone, or air loop it refers to, some may refer to plant loop, OA or other component
|
4861
4899
|
thermal_zone = nil
|
4862
4900
|
air_loop = nil
|
@@ -4867,12 +4905,11 @@ class Standard
|
|
4867
4905
|
end
|
4868
4906
|
if component.airLoopHVAC.is_initialized
|
4869
4907
|
air_loop = component.airLoopHVAC.get
|
4870
|
-
else
|
4871
4908
|
end
|
4872
4909
|
if component.plantLoop.is_initialized
|
4873
4910
|
plant_loop = component.plantLoop.get
|
4874
4911
|
end
|
4875
|
-
component.resources.each do |resource|
|
4912
|
+
component.resources.sort.each do |resource|
|
4876
4913
|
if resource.to_ThermalZone.is_initialized
|
4877
4914
|
thermal_zone = resource.to_ThermalZone.get
|
4878
4915
|
elsif resource.to_ScheduleRuleset.is_initialized
|
@@ -4883,9 +4920,10 @@ class Standard
|
|
4883
4920
|
# inspect resources for children of objects found in thermal zone or plant loop
|
4884
4921
|
# get objects like OA controllers and unitary object components
|
4885
4922
|
next if thermal_zone.nil? && air_loop.nil?
|
4923
|
+
|
4886
4924
|
children = OpenStudio::Model.getRecursiveChildren(component)
|
4887
|
-
children.each do |child|
|
4888
|
-
child.resources.each do |sub_resource|
|
4925
|
+
children.sort.each do |child|
|
4926
|
+
child.resources.sort.each do |sub_resource|
|
4889
4927
|
if sub_resource.to_ScheduleRuleset.is_initialized
|
4890
4928
|
schedules << sub_resource.to_ScheduleRuleset.get
|
4891
4929
|
end
|
@@ -4893,7 +4931,7 @@ class Standard
|
|
4893
4931
|
end
|
4894
4932
|
|
4895
4933
|
# process schedules found for this component
|
4896
|
-
schedules.each do |schedule|
|
4934
|
+
schedules.sort.each do |schedule|
|
4897
4935
|
hours_of_operation = nil
|
4898
4936
|
if !thermal_zone.nil?
|
4899
4937
|
hours_of_operation = thermal_zone_hash[thermal_zone]
|
@@ -4906,37 +4944,35 @@ class Standard
|
|
4906
4944
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', "Cannot identify where #{component.name.get} is in system. Will not gather parametric inputs for #{schedule.name.get}")
|
4907
4945
|
next
|
4908
4946
|
end
|
4909
|
-
gather_inputs_parametric_schedules(schedule,component,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
|
4947
|
+
gather_inputs_parametric_schedules(schedule, component, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
|
4910
4948
|
end
|
4911
|
-
|
4912
4949
|
end
|
4913
4950
|
|
4914
|
-
#
|
4951
|
+
# TODO: - Service Water Heating supply side (may or may not be associated with a space)
|
4915
4952
|
# todo - water use equipment definitions (temperature, sensible, latent) may be in multiple spaces, need to identify hoo, but typically constant schedules
|
4916
4953
|
|
4917
4954
|
# water use equipment (flow rate fraction)
|
4918
4955
|
# todo - address common schedules used across multiple instances
|
4919
|
-
model.getWaterUseEquipments.each do |water_use_equipment|
|
4920
|
-
|
4956
|
+
model.getWaterUseEquipments.sort.each do |water_use_equipment|
|
4921
4957
|
if water_use_equipment.flowRateFractionSchedule.is_initialized && water_use_equipment.flowRateFractionSchedule.get.to_ScheduleRuleset.is_initialized
|
4922
4958
|
schedule = water_use_equipment.flowRateFractionSchedule.get.to_ScheduleRuleset.get
|
4923
|
-
next if parametric_inputs.
|
4959
|
+
next if parametric_inputs.key?(schedule)
|
4924
4960
|
|
4925
4961
|
opt_space = water_use_equipment.space
|
4926
4962
|
if opt_space.is_initialized
|
4927
4963
|
space = space.get
|
4928
4964
|
hours_of_operation = space_hours_of_operation(space)
|
4929
|
-
gather_inputs_parametric_schedules(schedule,water_use_equipment,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
|
4965
|
+
gather_inputs_parametric_schedules(schedule, water_use_equipment, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
|
4930
4966
|
else
|
4931
4967
|
hours_of_operation = spaces_hours_of_operation(model.getSpaces)
|
4932
4968
|
if !hours_of_operation.nil?
|
4933
|
-
gather_inputs_parametric_schedules(schedule,water_use_equipment,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
|
4969
|
+
gather_inputs_parametric_schedules(schedule, water_use_equipment, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: hoo_var_method)
|
4934
4970
|
end
|
4935
4971
|
end
|
4936
4972
|
|
4937
4973
|
end
|
4938
4974
|
end
|
4939
|
-
#
|
4975
|
+
# TODO: - Refrigeration (will be associated with thermal zone)
|
4940
4976
|
# todo - exterior lights (will be astronomical, but like AEDG's may have reduction later at night)
|
4941
4977
|
|
4942
4978
|
return parametric_inputs
|
@@ -4955,7 +4991,6 @@ class Standard
|
|
4955
4991
|
# @param error_on_out_of_order [Bool] true will error if applying formula creates out of order values
|
4956
4992
|
# @return [Array] of modified ScheduleRuleset objects
|
4957
4993
|
def model_apply_parametric_schedules(model, ramp_frequency: nil, infer_hoo_for_non_assigned_objects: true, error_on_out_of_order: true)
|
4958
|
-
|
4959
4994
|
# get ramp frequency (fractional hour) from timestep
|
4960
4995
|
if ramp_frequency.nil?
|
4961
4996
|
steps_per_hour = if model.getSimulationControl.timestep.is_initialized
|
@@ -4963,32 +4998,31 @@ class Standard
|
|
4963
4998
|
else
|
4964
4999
|
6 # default OpenStudio timestep if none specified
|
4965
5000
|
end
|
4966
|
-
ramp_frequency = 1.0/steps_per_hour.to_f
|
5001
|
+
ramp_frequency = 1.0 / steps_per_hour.to_f
|
4967
5002
|
end
|
4968
5003
|
|
4969
5004
|
# Go through model and create parametric formulas for all schedules
|
4970
|
-
parametric_inputs = model_setup_parametric_schedules(model,gather_data_only: true)
|
5005
|
+
parametric_inputs = model_setup_parametric_schedules(model, gather_data_only: true)
|
4971
5006
|
|
4972
5007
|
parametric_schedules = []
|
4973
5008
|
model.getScheduleRulesets.sort.each do |sch|
|
4974
|
-
if !sch.hasAdditionalProperties
|
5009
|
+
if !sch.hasAdditionalProperties || !sch.additionalProperties.hasFeature('param_sch_ver')
|
4975
5010
|
# for now don't look at schedules without targets, in future can alter these by looking at building level hours of operation
|
4976
|
-
next if
|
4977
|
-
|
5011
|
+
next if sch.directUseCount <= 0 # won't catch if used for space type load instance, but that space type isn't used
|
5012
|
+
|
5013
|
+
# TODO: - address schedules that fall into this category, if they are used in the model
|
4978
5014
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Model', "For #{sch.sources.first.name}, #{sch.name} is not setup as parametric schedule. It has #{sch.sources.size} sources.")
|
4979
5015
|
next
|
4980
5016
|
end
|
4981
5017
|
|
4982
5018
|
# apply parametric inputs
|
4983
|
-
schedule_apply_parametric_inputs(sch,ramp_frequency,infer_hoo_for_non_assigned_objects,error_on_out_of_order,parametric_inputs)
|
5019
|
+
schedule_apply_parametric_inputs(sch, ramp_frequency, infer_hoo_for_non_assigned_objects, error_on_out_of_order, parametric_inputs)
|
4984
5020
|
|
4985
5021
|
# add schedule to array
|
4986
5022
|
parametric_schedules << sch
|
4987
|
-
|
4988
5023
|
end
|
4989
5024
|
|
4990
5025
|
return parametric_schedules
|
4991
|
-
|
4992
5026
|
end
|
4993
5027
|
|
4994
5028
|
private
|
@@ -5000,6 +5034,7 @@ class Standard
|
|
5000
5034
|
elsif sch_type == 'Hourly'
|
5001
5035
|
(0..23).each do |i|
|
5002
5036
|
next if values[i] == values[i + 1]
|
5037
|
+
|
5003
5038
|
day_sch.addValue(OpenStudio::Time.new(0, i + 1, 0, 0), values[i])
|
5004
5039
|
end
|
5005
5040
|
else
|
@@ -5071,6 +5106,7 @@ class Standard
|
|
5071
5106
|
if electric
|
5072
5107
|
plant_loop.supplyComponents.each do |component|
|
5073
5108
|
next unless component.to_WaterHeaterMixed.is_initialized
|
5109
|
+
|
5074
5110
|
water_heater = component.to_WaterHeaterMixed.get
|
5075
5111
|
# G3.1.11.b: If electric, WaterHeater:Mixed with electric resistance
|
5076
5112
|
water_heater.setHeaterFuelType('Electricity')
|
@@ -5111,8 +5147,6 @@ class Standard
|
|
5111
5147
|
return true
|
5112
5148
|
end
|
5113
5149
|
|
5114
|
-
|
5115
|
-
|
5116
5150
|
def load_user_geometry_osm(osm_model_path:)
|
5117
5151
|
version_translator = OpenStudio::OSVersion::VersionTranslator.new
|
5118
5152
|
model = version_translator.loadModel(osm_model_path)
|
@@ -5150,11 +5184,6 @@ class Standard
|
|
5150
5184
|
return model
|
5151
5185
|
end
|
5152
5186
|
|
5153
|
-
|
5154
|
-
|
5155
|
-
|
5156
|
-
|
5157
|
-
|
5158
5187
|
# Loads a osm as a starting point.
|
5159
5188
|
#
|
5160
5189
|
# @param osm_file [String] path to the .osm file, relative to the /data folder
|
@@ -5207,7 +5236,6 @@ class Standard
|
|
5207
5236
|
end
|
5208
5237
|
end
|
5209
5238
|
return model
|
5210
|
-
|
5211
5239
|
end
|
5212
5240
|
|
5213
5241
|
# pass array of space types or spaces
|
@@ -5215,51 +5243,51 @@ class Standard
|
|
5215
5243
|
# @author David Goldwasser
|
5216
5244
|
# @param array of spaces or space types
|
5217
5245
|
# @return hash
|
5218
|
-
def gather_inputs_parametric_space_space_type_schedules(space_space_types,parametric_inputs,gather_data_only)
|
5219
|
-
|
5246
|
+
def gather_inputs_parametric_space_space_type_schedules(space_space_types, parametric_inputs, gather_data_only)
|
5220
5247
|
space_space_types.each do |space_type|
|
5221
5248
|
# get hours of operation for space type once
|
5222
|
-
next if space_type.class ==
|
5249
|
+
next if space_type.class == 'OpenStudio::Model::SpaceTypes' && space_type.floorArea == 0
|
5250
|
+
|
5223
5251
|
hours_of_operation = space_hours_of_operation(space_type)
|
5224
5252
|
if hours_of_operation.nil?
|
5225
|
-
OpenStudio
|
5253
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.Standards.Model', "Can't evaluate schedules for #{space_type.name}, doesn't have hours of operation.")
|
5226
5254
|
next
|
5227
5255
|
end
|
5228
5256
|
# loop through internal load instances
|
5229
5257
|
space_type.lights.each do |load_inst|
|
5230
|
-
gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
|
5258
|
+
gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
|
5231
5259
|
end
|
5232
5260
|
space_type.luminaires.each do |load_inst|
|
5233
|
-
gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
|
5261
|
+
gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
|
5234
5262
|
end
|
5235
5263
|
space_type.electricEquipment.each do |load_inst|
|
5236
|
-
gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
|
5264
|
+
gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
|
5237
5265
|
end
|
5238
5266
|
space_type.gasEquipment.each do |load_inst|
|
5239
|
-
gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
|
5267
|
+
gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
|
5240
5268
|
end
|
5241
5269
|
space_type.steamEquipment.each do |load_inst|
|
5242
|
-
gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
|
5270
|
+
gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
|
5243
5271
|
end
|
5244
5272
|
space_type.otherEquipment.each do |load_inst|
|
5245
|
-
gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
|
5273
|
+
gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
|
5246
5274
|
end
|
5247
5275
|
space_type.people.each do |load_inst|
|
5248
|
-
gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
|
5276
|
+
gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
|
5249
5277
|
if load_inst.activityLevelSchedule.is_initialized && load_inst.activityLevelSchedule.get.to_ScheduleRuleset.is_initialized
|
5250
5278
|
act_sch = load_inst.activityLevelSchedule.get.to_ScheduleRuleset.get
|
5251
|
-
gather_inputs_parametric_schedules(act_sch,load_inst,parametric_inputs,hours_of_operation,gather_data_only: gather_data_only)
|
5279
|
+
gather_inputs_parametric_schedules(act_sch, load_inst, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: 'hours')
|
5252
5280
|
end
|
5253
5281
|
end
|
5254
5282
|
space_type.spaceInfiltrationDesignFlowRates.each do |load_inst|
|
5255
|
-
gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
|
5283
|
+
gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
|
5256
5284
|
end
|
5257
5285
|
space_type.spaceInfiltrationEffectiveLeakageAreas.each do |load_inst|
|
5258
|
-
gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
|
5286
|
+
gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
|
5259
5287
|
end
|
5260
5288
|
dsgn_spec_oa = space_type.designSpecificationOutdoorAir
|
5261
5289
|
if dsgn_spec_oa.is_initialized
|
5262
|
-
gather_inputs_parametric_load_inst_schedules(dsgn_spec_oa.get,parametric_inputs,hours_of_operation,gather_data_only)
|
5290
|
+
gather_inputs_parametric_load_inst_schedules(dsgn_spec_oa.get, parametric_inputs, hours_of_operation, gather_data_only)
|
5263
5291
|
end
|
5264
5292
|
end
|
5265
5293
|
|
@@ -5271,10 +5299,10 @@ class Standard
|
|
5271
5299
|
# @author David Goldwasser
|
5272
5300
|
# @param opt_sch
|
5273
5301
|
# @return hash
|
5274
|
-
def gather_inputs_parametric_load_inst_schedules(load_inst,parametric_inputs,hours_of_operation,gather_data_only)
|
5275
|
-
if load_inst.class.to_s ==
|
5302
|
+
def gather_inputs_parametric_load_inst_schedules(load_inst, parametric_inputs, hours_of_operation, gather_data_only)
|
5303
|
+
if load_inst.class.to_s == 'OpenStudio::Model::People'
|
5276
5304
|
opt_sch = load_inst.numberofPeopleSchedule
|
5277
|
-
elsif load_inst.class.to_s ==
|
5305
|
+
elsif load_inst.class.to_s == 'OpenStudio::Model::DesignSpecificationOutdoorAir'
|
5278
5306
|
opt_sch = load_inst.outdoorAirFlowRateFractionSchedule
|
5279
5307
|
else
|
5280
5308
|
opt_sch = load_inst.schedule
|
@@ -5282,7 +5310,8 @@ class Standard
|
|
5282
5310
|
if !opt_sch.is_initialized || !opt_sch.get.to_ScheduleRuleset.is_initialized
|
5283
5311
|
return nil
|
5284
5312
|
end
|
5285
|
-
|
5313
|
+
|
5314
|
+
gather_inputs_parametric_schedules(opt_sch.get.to_ScheduleRuleset.get, load_inst, parametric_inputs, hours_of_operation, gather_data_only: gather_data_only, hoo_var_method: 'hours')
|
5286
5315
|
|
5287
5316
|
return parametric_inputs
|
5288
5317
|
end
|
@@ -5293,18 +5322,17 @@ class Standard
|
|
5293
5322
|
# @param [sch]
|
5294
5323
|
# @param [hoo_var_Method] accepts hours and fractional. Any other value value will result in hoo variables not being applied
|
5295
5324
|
# @return [hash]
|
5296
|
-
def gather_inputs_parametric_schedules(sch,load_inst,parametric_inputs,hours_of_operation,ramp: true,min_ramp_dur_hr: 2.0,gather_data_only: false,hoo_var_method:
|
5297
|
-
|
5298
|
-
if parametric_inputs.has_key?(sch)
|
5325
|
+
def gather_inputs_parametric_schedules(sch, load_inst, parametric_inputs, hours_of_operation, ramp: true, min_ramp_dur_hr: 2.0, gather_data_only: false, hoo_var_method: 'hours')
|
5326
|
+
if parametric_inputs.key?(sch)
|
5299
5327
|
if hours_of_operation != parametric_inputs[sch][:hoo_inputs] # don't warn if the hours of operation between old and new schedule are equivalent
|
5300
|
-
OpenStudio
|
5328
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.Standards.Model', "#{load_inst.name} uses #{sch.name} but parametric inputs have already been setup based on hours of operation for #{parametric_inputs[sch][:target].name}.")
|
5301
5329
|
return nil
|
5302
5330
|
end
|
5303
5331
|
end
|
5304
5332
|
|
5305
5333
|
# gather and store data for scheduleRuleset
|
5306
5334
|
min_max = schedule_ruleset_annual_min_max_value(sch)
|
5307
|
-
ruleset_hash = {floor: min_max['min'], ceiling: min_max['max'], target: load_inst, hoo_inputs: hours_of_operation}
|
5335
|
+
ruleset_hash = { floor: min_max['min'], ceiling: min_max['max'], target: load_inst, hoo_inputs: hours_of_operation }
|
5308
5336
|
parametric_inputs[sch] = ruleset_hash
|
5309
5337
|
|
5310
5338
|
# stop here if only gathering information otherwise will continue and generate additional parametric properties for schedules and rules
|
@@ -5312,9 +5340,9 @@ class Standard
|
|
5312
5340
|
|
5313
5341
|
# set scheduleRuleset properties
|
5314
5342
|
props = sch.additionalProperties
|
5315
|
-
props.setFeature(
|
5316
|
-
props.setFeature(
|
5317
|
-
props.setFeature(
|
5343
|
+
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
|
5344
|
+
props.setFeature('param_sch_floor', min_max['min'])
|
5345
|
+
props.setFeature('param_sch_ceiling', min_max['max'])
|
5318
5346
|
|
5319
5347
|
# cleanup existing profiles
|
5320
5348
|
schedule_ruleset_cleanup_profiles(sch)
|
@@ -5337,18 +5365,17 @@ class Standard
|
|
5337
5365
|
indices_vector = sch.getActiveRuleIndices(year_start_date, year_end_date)
|
5338
5366
|
|
5339
5367
|
# step through profiles and add additional properties to describe profiles
|
5340
|
-
schedule_days.each_with_index do |(schedule_day,current_rule_index),i|
|
5341
|
-
|
5368
|
+
schedule_days.each_with_index do |(schedule_day, current_rule_index), i|
|
5342
5369
|
# loop through indices looking of rule in hoo that contains days in the rule
|
5343
5370
|
hoo_target_index = nil
|
5344
5371
|
days_used = []
|
5345
|
-
indices_vector.each_with_index do |profile_index,i|
|
5346
|
-
if profile_index == current_rule_index then days_used << i+1 end
|
5372
|
+
indices_vector.each_with_index do |profile_index, i|
|
5373
|
+
if profile_index == current_rule_index then days_used << i + 1 end
|
5347
5374
|
end
|
5348
5375
|
# find days_used in hoo profiles that contains all days used from this profile
|
5349
5376
|
hoo_profile_match_hash = {}
|
5350
5377
|
best_fit_check = {}
|
5351
|
-
hours_of_operation.each do |profile_index,value|
|
5378
|
+
hours_of_operation.each do |profile_index, value|
|
5352
5379
|
days_for_rule_not_in_hoo_profile = days_used - value[:days_used]
|
5353
5380
|
hoo_profile_match_hash[profile_index] = days_for_rule_not_in_hoo_profile
|
5354
5381
|
best_fit_check[profile_index] = days_for_rule_not_in_hoo_profile.size
|
@@ -5362,7 +5389,7 @@ class Standard
|
|
5362
5389
|
hoo_end = nil
|
5363
5390
|
occ = nil
|
5364
5391
|
vac = nil
|
5365
|
-
#
|
5392
|
+
# TODO: - issue warning when this happens on any profile that isn't a constant value
|
5366
5393
|
else
|
5367
5394
|
# get hours of operation for this specific profile
|
5368
5395
|
hoo_start = hours_of_operation[hoo_target_index][:hoo_start]
|
@@ -5375,8 +5402,7 @@ class Standard
|
|
5375
5402
|
par_val_time_hash = {} # time is key, value is value in and optional value out as a one or two object array
|
5376
5403
|
times = schedule_day.times
|
5377
5404
|
values = schedule_day.values
|
5378
|
-
values.each_with_index do |value,j|
|
5379
|
-
|
5405
|
+
values.each_with_index do |value, j|
|
5380
5406
|
# don't add value until 24 if it is the same as first value for non constant profiles
|
5381
5407
|
if values.size > 1 && j == values.size - 1 && value == values.first
|
5382
5408
|
next
|
@@ -5384,18 +5410,18 @@ class Standard
|
|
5384
5410
|
|
5385
5411
|
current_time = times[j].totalHours
|
5386
5412
|
# if step height goes floor to ceiling then do not ramp.
|
5387
|
-
if !ramp
|
5413
|
+
if !ramp || (values.uniq.size < 3)
|
5388
5414
|
# this will result in steps like old profiles, update to ramp in most cases
|
5389
5415
|
if j == values.size - 1
|
5390
|
-
par_val_time_hash[current_time] = [value,values.first]
|
5416
|
+
par_val_time_hash[current_time] = [value, values.first]
|
5391
5417
|
else
|
5392
|
-
par_val_time_hash[current_time] = [value,values[j+1]]
|
5418
|
+
par_val_time_hash[current_time] = [value, values[j + 1]]
|
5393
5419
|
end
|
5394
5420
|
else
|
5395
5421
|
if j == 0
|
5396
5422
|
prev_time = times.last.totalHours - 24 # e.g. 24 would show as until 0
|
5397
5423
|
else
|
5398
|
-
prev_time = times[j-1].totalHours
|
5424
|
+
prev_time = times[j - 1].totalHours
|
5399
5425
|
end
|
5400
5426
|
if j == values.size - 1
|
5401
5427
|
next_time = times.first.totalHours + 24 # e.g. 6 would show as until 30
|
@@ -5407,15 +5433,15 @@ class Standard
|
|
5407
5433
|
end
|
5408
5434
|
|
5409
5435
|
else
|
5410
|
-
next_time = times[j+1].totalHours
|
5411
|
-
next_value = values[j+1]
|
5436
|
+
next_time = times[j + 1].totalHours
|
5437
|
+
next_value = values[j + 1]
|
5412
5438
|
end
|
5413
5439
|
# delta time is min min_ramp_dur_hr, half of previous dur, half of next dur
|
5414
5440
|
# todo - would be nice to change to 0.25 for vally less than 2 hours
|
5415
5441
|
multiplier = 0.5
|
5416
|
-
delta = [min_ramp_dur_hr,(current_time - prev_time)*multiplier,(next_time - current_time)*multiplier].min
|
5442
|
+
delta = [min_ramp_dur_hr, (current_time - prev_time) * multiplier, (next_time - current_time) * multiplier].min
|
5417
5443
|
# add value to left if not already added
|
5418
|
-
if !par_val_time_hash.
|
5444
|
+
if !par_val_time_hash.key?(current_time - delta)
|
5419
5445
|
time_left = current_time - delta
|
5420
5446
|
if time_left < 0.0 then time_left += 24.0 end
|
5421
5447
|
par_val_time_hash[time_left] = [value]
|
@@ -5432,11 +5458,11 @@ class Standard
|
|
5432
5458
|
|
5433
5459
|
# calculate estimated value (not including any secondary logic)
|
5434
5460
|
est_daily_flh = 0.0
|
5435
|
-
prev_time = par_val_time_hash.keys.
|
5461
|
+
prev_time = par_val_time_hash.keys.max - 24.0
|
5436
5462
|
prev_value = par_val_time_hash.values.last.last # last value in last optional pair of values
|
5437
|
-
par_val_time_hash.sort.each do |time,value_array|
|
5463
|
+
par_val_time_hash.sort.each do |time, value_array|
|
5438
5464
|
segment_length = time - prev_time
|
5439
|
-
avg_value = (value_array.first + prev_value)*0.5
|
5465
|
+
avg_value = (value_array.first + prev_value) * 0.5
|
5440
5466
|
est_daily_flh += segment_length * avg_value
|
5441
5467
|
prev_time = time
|
5442
5468
|
prev_value = value_array.last
|
@@ -5444,16 +5470,15 @@ class Standard
|
|
5444
5470
|
|
5445
5471
|
# test expected value against estimated value
|
5446
5472
|
daily_flh = day_schedule_equivalent_full_load_hrs(schedule_day)
|
5447
|
-
percent_change = ((daily_flh - est_daily_flh)/daily_flh) * 100.0
|
5473
|
+
percent_change = ((daily_flh - est_daily_flh) / daily_flh) * 100.0
|
5448
5474
|
if percent_change.abs > 0.05
|
5449
|
-
#
|
5475
|
+
# TODO: - this estimation can have flaws. Fix or remove it, make sure to update for secondary logic (if we implement that here)
|
5450
5476
|
# post application checks compares against actual instead of estimated values
|
5451
5477
|
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.Model', "For day schedule #{schedule_day.name} in #{sch.name} there was a #{percent_change.round(4)}% change. Expected full load hours is #{daily_flh.round(4)}, but estimated value is #{est_daily_flh.round(4)}")
|
5452
5478
|
end
|
5453
5479
|
|
5454
5480
|
raw_string = []
|
5455
|
-
par_val_time_hash.sort.each do |time,value_array|
|
5456
|
-
|
5481
|
+
par_val_time_hash.sort.each do |time, value_array|
|
5457
5482
|
# add in value variables
|
5458
5483
|
# not currently using range, only using min max for constant schedules or schedules with just two values
|
5459
5484
|
value_array_var = []
|
@@ -5476,20 +5501,20 @@ class Standard
|
|
5476
5501
|
start_delta_array = [hoo_start - time, hoo_start - time + 24, hoo_start - time - 24]
|
5477
5502
|
start_delta_array_abs = [(hoo_start - time).abs, (hoo_start - time + 24).abs, (hoo_start - time - 24).abs]
|
5478
5503
|
start_delta_h = start_delta_array[start_delta_array_abs.index(start_delta_array_abs.min)]
|
5479
|
-
formula_identifier[
|
5504
|
+
formula_identifier['start'] = start_delta_h
|
5480
5505
|
mid_calc = hoo_start + occ * 0.5
|
5481
5506
|
mid_delta_array = [mid_calc - time, mid_calc - time + 24, mid_calc - time - 24]
|
5482
5507
|
mid_delta_array_abs = [(mid_calc - time).abs, (mid_calc - time + 24).abs, (mid_calc - time - 24).abs]
|
5483
5508
|
mid_delta_h = mid_delta_array[mid_delta_array_abs.index(mid_delta_array_abs.min)]
|
5484
|
-
formula_identifier[
|
5509
|
+
formula_identifier['mid'] = mid_delta_h
|
5485
5510
|
end_delta_array = [hoo_end - time, hoo_end - time + 24, hoo_end - time - 24]
|
5486
5511
|
end_delta_array_abs = [(hoo_end - time).abs, (hoo_end - time + 24).abs, (hoo_end - time - 24).abs]
|
5487
5512
|
end_delta_h = end_delta_array[end_delta_array_abs.index(end_delta_array_abs.min)]
|
5488
|
-
formula_identifier[
|
5513
|
+
formula_identifier['end'] = end_delta_h
|
5489
5514
|
|
5490
5515
|
# need to store min absolute value to pick the best fit
|
5491
5516
|
formula_identifier_min_abs = {}
|
5492
|
-
formula_identifier.each do |k,v|
|
5517
|
+
formula_identifier.each do |k, v|
|
5493
5518
|
formula_identifier_min_abs[k] = v.abs
|
5494
5519
|
end
|
5495
5520
|
|
@@ -5497,20 +5522,20 @@ class Standard
|
|
5497
5522
|
min_key = formula_identifier_min_abs.key(formula_identifier_min_abs.values.min)
|
5498
5523
|
min_value = formula_identifier[min_key]
|
5499
5524
|
|
5500
|
-
if hoo_var_method ==
|
5525
|
+
if hoo_var_method == 'hours'
|
5501
5526
|
# minimize x, which should be no greater than 12, see if rounding to 2 decimal places works
|
5502
5527
|
min_value = min_value.round(2)
|
5503
|
-
if min_key ==
|
5528
|
+
if min_key == 'start'
|
5504
5529
|
if min_value == 0
|
5505
|
-
time =
|
5530
|
+
time = 'hoo_start'
|
5506
5531
|
elsif min_value < 0
|
5507
5532
|
time = "hoo_start + #{min_value.abs}"
|
5508
5533
|
else # greater than 0
|
5509
5534
|
time = "hoo_start - #{min_value}"
|
5510
5535
|
end
|
5511
|
-
elsif min_key ==
|
5536
|
+
elsif min_key == 'mid'
|
5512
5537
|
if min_value == 0
|
5513
|
-
time =
|
5538
|
+
time = 'mid'
|
5514
5539
|
# converted to variable for simplicity but could also be described like this
|
5515
5540
|
# time = "hoo_start + occ * 0.5"
|
5516
5541
|
elsif min_value < 0
|
@@ -5520,7 +5545,7 @@ class Standard
|
|
5520
5545
|
end
|
5521
5546
|
else # min_key == "end"
|
5522
5547
|
if min_value == 0
|
5523
|
-
time =
|
5548
|
+
time = 'hoo_end'
|
5524
5549
|
elsif min_value < 0
|
5525
5550
|
time = "hoo_end + #{min_value.abs}"
|
5526
5551
|
else # greater than 0
|
@@ -5528,31 +5553,31 @@ class Standard
|
|
5528
5553
|
end
|
5529
5554
|
end
|
5530
5555
|
|
5531
|
-
elsif hoo_var_method ==
|
5556
|
+
elsif hoo_var_method == 'fractional'
|
5532
5557
|
|
5533
5558
|
# minimize x(hour before converted to fraction), which should be no greater than 0.5 as fraction, see if rounding to 3 decimal places works
|
5534
5559
|
if occ > 0
|
5535
|
-
min_value_occ_fract = min_value.abs/occ
|
5560
|
+
min_value_occ_fract = min_value.abs / occ
|
5536
5561
|
else
|
5537
5562
|
min_value_occ_fract = 0.0
|
5538
5563
|
end
|
5539
5564
|
if vac > 0
|
5540
|
-
min_value_vac_fract = min_value.abs/vac
|
5565
|
+
min_value_vac_fract = min_value.abs / vac
|
5541
5566
|
else
|
5542
5567
|
min_value_vac_fract = 0.0
|
5543
5568
|
end
|
5544
|
-
if min_key ==
|
5569
|
+
if min_key == 'start'
|
5545
5570
|
if min_value == 0
|
5546
|
-
time =
|
5571
|
+
time = 'hoo_start'
|
5547
5572
|
elsif min_value < 0
|
5548
5573
|
time = "hoo_start + occ * #{min_value_occ_fract.round(3)}"
|
5549
5574
|
else # greater than 0
|
5550
5575
|
time = "hoo_start - vac * #{min_value_vac_fract.round(3)}"
|
5551
5576
|
end
|
5552
|
-
elsif min_key ==
|
5553
|
-
#
|
5577
|
+
elsif min_key == 'mid'
|
5578
|
+
# TODO: - see what is going wrong with after mid in formula
|
5554
5579
|
if min_value == 0
|
5555
|
-
time =
|
5580
|
+
time = 'mid'
|
5556
5581
|
# converted to variable for simplicity but could also be described like this
|
5557
5582
|
# time = "hoo_start + occ * 0.5"
|
5558
5583
|
elsif min_value < 0
|
@@ -5562,7 +5587,7 @@ class Standard
|
|
5562
5587
|
end
|
5563
5588
|
else # min_key == "end"
|
5564
5589
|
if min_value == 0
|
5565
|
-
time =
|
5590
|
+
time = 'hoo_end'
|
5566
5591
|
elsif min_value < 0
|
5567
5592
|
time = "hoo_end + vac * #{min_value_vac_fract.round(3)}"
|
5568
5593
|
else # greater than 0
|
@@ -5570,8 +5595,6 @@ class Standard
|
|
5570
5595
|
end
|
5571
5596
|
end
|
5572
5597
|
|
5573
|
-
else # "none"
|
5574
|
-
# do not add in hoo variables
|
5575
5598
|
end
|
5576
5599
|
|
5577
5600
|
end
|
@@ -5585,14 +5608,14 @@ class Standard
|
|
5585
5608
|
end
|
5586
5609
|
|
5587
5610
|
# store profile formula with hoo and value variables
|
5588
|
-
props.setFeature(
|
5611
|
+
props.setFeature('param_day_profile', raw_string.join(' | '))
|
5589
5612
|
|
5590
|
-
#
|
5613
|
+
# TODO: - not used yet, but will add methods described below and others
|
5591
5614
|
# todo - lower infiltration based on air loop hours of operation if air loop has outdoor air object
|
5592
5615
|
# todo - lower lighting or plug loads based on occupancy at given time steps in a space
|
5593
5616
|
# todo - set elevator fraction based multiple factors such as trips, occupants per trip, and elevator type to determine floor consumption when not in use.
|
5594
|
-
props.setFeature(
|
5595
|
-
props.setFeature(
|
5617
|
+
props.setFeature('param_day_secondary_logic', '') # secondary logic method such as occupancy impacting schedule values
|
5618
|
+
props.setFeature('param_day_secondary_logic_arg_val', '') # optional argument used for some secondary logic applied to values
|
5596
5619
|
|
5597
5620
|
# tag profile type
|
5598
5621
|
# may be useful for parametric changes to tag typical, medium, minimal, or same ones with off_peak prefix
|
@@ -5601,18 +5624,24 @@ class Standard
|
|
5601
5624
|
# todo - I think these tags should come from occpancy schedule for space(s) schedule. That way all schedules in a space will refer to same profile from hours of operation
|
5602
5625
|
# todo - add school specific logic hear or in post processing, currently default profile for school may not be most prevalent one
|
5603
5626
|
if current_rule_index == -1
|
5604
|
-
props.setFeature(
|
5627
|
+
props.setFeature('param_day_tag', 'typical_operation')
|
5605
5628
|
elsif daily_flh == daily_flhs.min
|
5606
|
-
props.setFeature(
|
5629
|
+
props.setFeature('param_day_tag', 'minimal_operation')
|
5607
5630
|
elsif daily_flh == daily_flhs.max
|
5608
|
-
props.setFeature(
|
5631
|
+
props.setFeature('param_day_tag', 'maximum_operation') # normally this should not be used as typical should be the most active day
|
5609
5632
|
else
|
5610
|
-
props.setFeature(
|
5633
|
+
props.setFeature('param_day_tag', 'medium_operation') # not min max or typical
|
5611
5634
|
end
|
5612
|
-
|
5613
5635
|
end
|
5614
5636
|
|
5615
5637
|
return parametric_inputs
|
5616
5638
|
end
|
5617
5639
|
|
5640
|
+
# Default SAT reset type
|
5641
|
+
#
|
5642
|
+
# @param air_loop_hvac [OpenStudio::model::AirLoopHVAC] Airloop
|
5643
|
+
# @return [String] Returns type of SAT reset
|
5644
|
+
def air_loop_hvac_supply_air_temperature_reset_type(air_loop_hvac)
|
5645
|
+
return 'warmest_zone'
|
5646
|
+
end
|
5618
5647
|
end
|