openstudio-standards 0.2.16 → 0.2.17.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/standards/manage_OpenStudio_Standards.rb +31 -4
- data/lib/openstudio-standards/btap/geometry.rb +1 -1
- data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +354 -2
- data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +79 -0
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Laboratory.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/do_not_edit_metaclasses.rb +3313 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +12 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +3 -4
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +167 -93
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +2 -4
- data/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb +1 -0
- data/lib/openstudio-standards/refs/references.rb +3 -0
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +279 -6
- data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctParallelPIUReheat.rb +50 -2
- data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +4 -0
- data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +0 -1
- data/lib/openstudio-standards/standards/Standards.Construction.rb +185 -3
- data/lib/openstudio-standards/standards/Standards.Fan.rb +14 -6
- data/lib/openstudio-standards/standards/Standards.HeatExchangerSensLat.rb +1 -0
- data/lib/openstudio-standards/standards/Standards.Model.rb +1751 -383
- data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +130 -9
- data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +50 -3
- data/lib/openstudio-standards/standards/Standards.ScheduleCompact.rb +44 -0
- data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +27 -0
- data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +543 -0
- data/lib/openstudio-standards/standards/Standards.Space.rb +665 -15
- data/lib/openstudio-standards/standards/Standards.SpaceType.rb +141 -4
- data/lib/openstudio-standards/standards/Standards.SubSurface.rb +2 -1
- data/lib/openstudio-standards/standards/Standards.Surface.rb +117 -0
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +197 -49
- data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +41 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +6 -8
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/comstock_ashrae_90_1_2004.spc_typ.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/comstock_ashrae_90_1_2007.spc_typ.json +7 -7
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/comstock_ashrae_90_1_2010.spc_typ.json +9 -9
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/comstock_ashrae_90_1_2013.spc_typ.json +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/data/comstock_ashrae_90_1_2016.spc_typ.json +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/data/comstock_ashrae_90_1_2019.spc_typ.json +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.fans.json +12 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/comstock_doe_ref_1980_2004.spc_typ.json +10 -10
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/ashrae_90_1.schedules.json +45 -45
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/comstock_doe_ref_pre_1980.spc_typ.json +10 -10
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +792 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctParallelPIUReheat.rb +10 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctVAVReheat.rb +31 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.BoilerHotWater.rb +91 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +84 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +145 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +106 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +71 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +194 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +120 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTower.rb +110 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTowerVariableSpeed.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Fan.rb +73 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanVariableVolume.rb +24 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanZoneExhaust.rb +5 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.HeatExchangerSensLat.rb +55 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +3045 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +187 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +450 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Space.rb +106 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +666 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Surface.rb +54 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ThermalZone.rb +168 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ZoneHVACComponent.rb +132 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.rb +239 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +176 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.rb +25 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.boilers.json +52 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.chillers.json +112 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.climate_zone_sets.json +210 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_properties.json +10384 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_sets.json +133 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.furnaces.json +43 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_pumps.json +119 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_pumps_heating.json +130 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_rejection.json +13 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.lpd_space_type.json +568 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.motors.json +264 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_baseline_hvac.json +439 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_constructions.json +685 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_economizers.json +213 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_ext_ltg.json +32 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_heat_type.json +136 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_hvac_bldg_type.json +32 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_interior_lighting.json +1837 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_swh_bldg_type.json +184 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_wwr_bldg_type.json +84 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.unitary_acs.json +148 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.water_heaters.json +157 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.climate_zone_sets.json +210 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.curves.json +18329 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.fans.json +340 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.materials.json +49924 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/baseline_building_rotation_exception.md +44 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/check_pump_power_and_control.md +71 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/dcv.md +68 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/dcv_implementation.png +0 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/elevators.md +14 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/exhaust_air_energy_recovery.md +36 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/f_c_factors.md +19 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/fan_power_credits.md +15 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/preheat_coil.md +59 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/pump_power_control.md +46 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/return_air_type.md +31 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_baseline_wwr.md +191 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_hw_and_chw_supply_water_temp_reset_control.md +24 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_num_boilers_chillers_towers.md +49 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_plug_load_measures.md +80 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_space_lpd.md +73 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/unenclosed_and_unconditioned_spaces.md +11 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/unmet_load_hours.md +20 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/vav_parallel_piu_terminals_fan_control.md +23 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/vav_terminals_min_flow_setpoint.md +21 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_airloop_hvac.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_airloop_hvac_doas.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_building.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_design_specification_outdoor_air.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_electric_equipment.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_exterior_lights.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_gas_equipment.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_lights.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_space.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_spacetype.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_thermal_zone.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_connections.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_equipment.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_wateruse_equipment_definition.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_zone_hvac.csv +1 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_zone_infiltration.csv +1 -0
- data/lib/openstudio-standards/standards/cbes/data/cbes.fans.json +12 -0
- data/lib/openstudio-standards/standards/deer/data/deer.fans.json +12 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps.json +1 -1
- data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps_heating.json +1 -1
- data/lib/openstudio-standards/standards/necb/ECMS/data/unitary_acs.json +24 -11
- data/lib/openstudio-standards/standards/necb/ECMS/erv.rb +13 -15
- data/lib/openstudio-standards/standards/necb/NECB2011/data/province_map.json +17 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +2 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +6 -5
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +3 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +2 -3
- data/lib/openstudio-standards/standards/necb/NECB2020/data/chillers.json +2 -2
- data/lib/openstudio-standards/standards/necb/NECB2020/data/space_types.json +33 -924
- data/lib/openstudio-standards/standards/necb/NECB2020/data/unitary_acs.json +15 -15
- data/lib/openstudio-standards/standards/necb/common/btap_data.rb +135 -29
- data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +16 -4
- data/lib/openstudio-standards/standards/necb/common/neb_end_use_prices.csv +40 -42
- data/lib/openstudio-standards/standards/necb/common/necb_reference_runs.csv +1 -1
- data/lib/openstudio-standards/standards/necb/common/space_type_upgrade_map.json +89 -89
- data/lib/openstudio-standards/utilities/array.rb +11 -0
- data/lib/openstudio-standards/utilities/logging.rb +48 -0
- data/lib/openstudio-standards/utilities/object_info.rb +20 -0
- data/lib/openstudio-standards/utilities/schedule_translator.rb +348 -0
- data/lib/openstudio-standards/utilities/sqlfile.rb +68 -0
- data/lib/openstudio-standards/version.rb +2 -2
- data/lib/openstudio-standards/weather/Weather.Model.rb +42 -55
- data/lib/openstudio-standards/weather/Weather.stat_file.rb +1 -1
- data/lib/openstudio-standards.rb +35 -1
- metadata +111 -6
- data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
- data/data/standards/OpenStudio_Standards-ashrae_90_1_28Jan2022.xlsx +0 -0
- data/data/standards/OpenStudio_Standards-ashrae_90_1_28_Jan2022_2.xlsx +0 -0
- data/data/standards/openstudio_standards_duplicates_log.csv +0 -143
@@ -0,0 +1,54 @@
|
|
1
|
+
class ASHRAE901PRM < Standard
|
2
|
+
# Adjust the fenestration area to the values specified by the reduction value in a surface
|
3
|
+
#
|
4
|
+
# @param surface [OpenStudio::Model:Surface] openstudio surface object
|
5
|
+
# @param reduction [Float] ratio of adjustments
|
6
|
+
# @param model [OpenStudio::Model::Model] openstudio model
|
7
|
+
# @return [Bool] return true if successful, false if not
|
8
|
+
def surface_adjust_fenestration_in_a_surface(surface, reduction, model)
|
9
|
+
# do nothing for cases when reduction == 1.0
|
10
|
+
if reduction < 1.0
|
11
|
+
surface.subSurfaces.sort.each do |ss|
|
12
|
+
next unless ss.subSurfaceType == 'FixedWindow' || ss.subSurfaceType == 'OperableWindow' || ss.subSurfaceType == 'GlassDoor'
|
13
|
+
|
14
|
+
sub_surface_reduce_area_by_percent_by_shrinking_toward_centroid(ss, reduction)
|
15
|
+
end
|
16
|
+
elsif reduction > 1.0
|
17
|
+
# case increase the window
|
18
|
+
surface_wwr = surface_get_wwr_of_a_surface(surface)
|
19
|
+
if surface_wwr == 0.0
|
20
|
+
# In this case, we are adding fenestration
|
21
|
+
wwr_adjusted = reduction - 1.0
|
22
|
+
# add the value to additional properties in case of readjusting WWR for doors
|
23
|
+
surface.additionalProperties.setFeature('added_wwr', wwr_adjusted)
|
24
|
+
else
|
25
|
+
wwr_adjusted = surface_wwr * reduction
|
26
|
+
end
|
27
|
+
# Save doors to a temp list
|
28
|
+
door_list = []
|
29
|
+
surface.subSurfaces.sort.each do |sub|
|
30
|
+
if sub.subSurfaceType == 'Door'
|
31
|
+
door = {}
|
32
|
+
door['name'] = sub.name.get
|
33
|
+
door['vertices'] = sub.vertices
|
34
|
+
door['construction'] = sub.construction.get
|
35
|
+
door_list << door
|
36
|
+
end
|
37
|
+
end
|
38
|
+
# remove all existing windows and set the window to wall ratio to the calculated new WWR
|
39
|
+
# Remove all sub-surfaces including doors
|
40
|
+
surface.subSurfaces.sort.each(&:remove)
|
41
|
+
# Apply default construction to the subsurface - the standard construction will be applied later.
|
42
|
+
surface.setWindowToWallRatio(wwr_adjusted, 0.6, true)
|
43
|
+
# add door back.
|
44
|
+
unless door_list.empty?
|
45
|
+
door_list.each do |door|
|
46
|
+
os_door = OpenStudio::Model::SubSurface.new(door['vertices'], model)
|
47
|
+
os_door.setName(door['name'])
|
48
|
+
os_door.setConstruction(door['construction'])
|
49
|
+
os_door.setSurface(surface)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
class ASHRAE901PRM < Standard
|
2
|
+
# @!group ThermalZone
|
3
|
+
|
4
|
+
# Determine the fan power limitation pressure drop adjustment
|
5
|
+
# Per Table 6.5.3.1-2 (90.1-2019)
|
6
|
+
#
|
7
|
+
# @param thermal_zone
|
8
|
+
def thermal_zone_get_fan_power_limitations(thermal_zone, is_energy_recovery_required)
|
9
|
+
fan_pwr_adjustment_in_wc = 0
|
10
|
+
# Get autosized zone design supply air flow rate
|
11
|
+
dsn_zone_air_flow_m3_per_s = thermal_zone.designAirFlowRate.to_f
|
12
|
+
dsn_zone_air_flow_cfm = OpenStudio.convert(dsn_zone_air_flow_m3_per_s, 'm^3/s', 'cfm').get
|
13
|
+
|
14
|
+
# Retrieve credits from zone additional features
|
15
|
+
# Fully ducted return and/or exhaust air systems
|
16
|
+
if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_fully_ducted')
|
17
|
+
mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_fully_ducted').to_f
|
18
|
+
adj_in_wc = 0.5 * mult
|
19
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
20
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for fully ducted return and/or exhaust air systems")
|
21
|
+
end
|
22
|
+
|
23
|
+
# Return and/or exhaust airflow control devices
|
24
|
+
if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_return_or_exhaust_flow_control')
|
25
|
+
mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_return_or_exhaust_flow_control').to_f
|
26
|
+
adj_in_wc = 0.5 * mult
|
27
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
28
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for return and/or exhaust airflow control devices")
|
29
|
+
end
|
30
|
+
|
31
|
+
# Exhaust filters, scrubbers, or other exhaust treatment
|
32
|
+
if thermal_zone.additionalProperties.hasFeature('fan_power_credit_exhaust_treatment')
|
33
|
+
adj_in_wc = thermal_zone.additionalProperties.getFeatureAsDouble('fan_power_credit_exhaust_treatment').to_f
|
34
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
35
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for exhaust filters, scrubbers, or other exhaust treatment")
|
36
|
+
end
|
37
|
+
|
38
|
+
# MERV 9 through 12
|
39
|
+
if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_filtration_m9to12')
|
40
|
+
mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_filtration_m9to12').to_f
|
41
|
+
adj_in_wc = 0.5 * mult
|
42
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
43
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for particulate Filtration Credit: MERV 9 through 12")
|
44
|
+
end
|
45
|
+
|
46
|
+
# MERV 13 through 15
|
47
|
+
if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_filtration_m13to15')
|
48
|
+
mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_filtration_m13to15').to_f
|
49
|
+
adj_in_wc = 0.9 * mult
|
50
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
51
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for particulate Filtration Credit: MERV 13 through 15")
|
52
|
+
end
|
53
|
+
|
54
|
+
# MERV 16 and greater and electronically enhanced filters
|
55
|
+
if thermal_zone.additionalProperties.hasFeature('clean_filter_pressure_drop_for_fan_power_credit_filtration_m16plus')
|
56
|
+
adj_in_wc = thermal_zone.additionalProperties.getFeatureAsDouble('clean_filter_pressure_drop_for_fan_power_credit_filtration_m16plus').to_f
|
57
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
58
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for particulate Filtration Credit: MERV 16 and greater and electronically enhanced filters")
|
59
|
+
end
|
60
|
+
|
61
|
+
# Carbon and other gas-phase air cleaners
|
62
|
+
if thermal_zone.additionalProperties.hasFeature('fan_power_credit_gas_phase_cleaners')
|
63
|
+
adj_in_wc = thermal_zone.additionalProperties.getFeatureAsDouble('fan_power_credit_gas_phase_cleaners').to_f
|
64
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
65
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for carbon and other gas-phase air cleaners")
|
66
|
+
end
|
67
|
+
|
68
|
+
# Biosafety cabinet
|
69
|
+
if thermal_zone.additionalProperties.hasFeature('fan_power_credit_biosafety')
|
70
|
+
adj_in_wc = thermal_zone.additionalProperties.getFeatureAsDouble('fan_power_credit_biosafety').to_f
|
71
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
72
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for biosafety cabinet")
|
73
|
+
end
|
74
|
+
|
75
|
+
# Energy recovery device, other than coil runaround loop
|
76
|
+
if thermal_zone.additionalProperties.hasFeature('fan_power_credit_other_than_coil_runaround')
|
77
|
+
if is_energy_recovery_required
|
78
|
+
adj_in_wc = thermal_zone.additionalProperties.getFeatureAsDouble('fan_power_credit_other_than_coil_runaround').to_f
|
79
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
80
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for energy recovery device other than coil runaround loop")
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# Coil runaround loop
|
85
|
+
if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_coil_runaround')
|
86
|
+
if is_energy_recovery_required
|
87
|
+
mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_coil_runaround').to_f
|
88
|
+
adj_in_wc = 0.6 * 2 * mult # for each stream
|
89
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
90
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for coil runaround loop")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Evaporative humidifier/cooler in series with another cooling coil
|
95
|
+
if thermal_zone.additionalProperties.hasFeature('fan_power_credit_evaporative_humidifier_or_cooler')
|
96
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', '--Added 0 in wc for evaporative humidifier/cooler in series with another coil as per Table G3.1.2.9 Note 2')
|
97
|
+
end
|
98
|
+
|
99
|
+
# Sound attenuation section (fans serving spoaces with design background noise goals below NC35)
|
100
|
+
if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_sound_attenuation')
|
101
|
+
mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_sound_attenuation').to_f
|
102
|
+
adj_in_wc = 0.15 * mult
|
103
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
104
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for sound attenuation section")
|
105
|
+
end
|
106
|
+
|
107
|
+
# Exhaust system serving fume hoods
|
108
|
+
if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_exhaust_serving_fume_hoods')
|
109
|
+
mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_exhaust_serving_fume_hoods').to_f
|
110
|
+
adj_in_wc = 0.35 * mult
|
111
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
112
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for exhaust system serving fume hoods")
|
113
|
+
end
|
114
|
+
|
115
|
+
# Laboratory and vivarium exhaust systems in high-rise buildings
|
116
|
+
if thermal_zone.additionalProperties.hasFeature('has_fan_power_credit_lab_or_vivarium_highrise_vertical_duct')
|
117
|
+
mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_credit_lab_or_vivarium_highrise_vertical_duct').to_f
|
118
|
+
adj_in_wc = 0.35 * mult
|
119
|
+
fan_pwr_adjustment_in_wc += adj_in_wc
|
120
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Added #{adj_in_wc} in wc for laboratory and vivarium exhaust systems in high-rise buildings")
|
121
|
+
end
|
122
|
+
|
123
|
+
# Deductions
|
124
|
+
# Systems without central cooling device
|
125
|
+
if thermal_zone.additionalProperties.hasFeature('has_fan_power_deduction_system_without_central_cooling_device')
|
126
|
+
mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_deduction_system_without_central_cooling_device').to_f
|
127
|
+
adj_in_wc = 0.60 * mult
|
128
|
+
fan_pwr_adjustment_in_wc -= adj_in_wc
|
129
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Removed #{adj_in_wc} in wc for system without central cooling device")
|
130
|
+
end
|
131
|
+
|
132
|
+
# Systems without central heating device
|
133
|
+
if thermal_zone.additionalProperties.hasFeature('has_fan_power_deduction_system_without_central_heating_device')
|
134
|
+
mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_deduction_system_without_central_heating_device').to_f
|
135
|
+
adj_in_wc = 0.30 * mult
|
136
|
+
fan_pwr_adjustment_in_wc -= adj_in_wc
|
137
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Removed #{adj_in_wc} in wc for system without central heating device")
|
138
|
+
end
|
139
|
+
|
140
|
+
# Systems with central electric resistance heat
|
141
|
+
if thermal_zone.additionalProperties.hasFeature('has_fan_power_deduction_system_with_central_electric_resistance_heat')
|
142
|
+
mult = thermal_zone.additionalProperties.getFeatureAsDouble('has_fan_power_deduction_system_with_central_electric_resistance_heat').to_f
|
143
|
+
adj_in_wc = 0.20 * mult
|
144
|
+
fan_pwr_adjustment_in_wc -= adj_in_wc
|
145
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "--Removed #{adj_in_wc} in wc for system with central electric resistance heat")
|
146
|
+
end
|
147
|
+
|
148
|
+
# Convert the pressure drop adjustment to brake horsepower (bhp)
|
149
|
+
# assuming that all supply air passes through all devices
|
150
|
+
return fan_pwr_adjustment_in_wc * dsn_zone_air_flow_cfm / 4131
|
151
|
+
end
|
152
|
+
|
153
|
+
# Identify if zone has district energy for occ_and_fuel_type method
|
154
|
+
# @param themal_zone
|
155
|
+
# @return [string] with applicable DistrictHeating and/or DistrictCooling
|
156
|
+
def thermal_zone_get_zone_fuels_for_occ_and_fuel_type(zone)
|
157
|
+
zone_fuels = ''
|
158
|
+
htg_fuels = zone.heating_fuels
|
159
|
+
if htg_fuels.include?('DistrictHeating')
|
160
|
+
zone_fuels = 'DistrictHeating'
|
161
|
+
end
|
162
|
+
clg_fuels = zone.cooling_fuels
|
163
|
+
if clg_fuels.include?('DistrictCooling')
|
164
|
+
zone_fuels += 'DistrictCooling'
|
165
|
+
end
|
166
|
+
return zone_fuels
|
167
|
+
end
|
168
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
class ASHRAE901PRM < Standard
|
2
|
+
# @!group ZoneHVACComponent
|
3
|
+
|
4
|
+
# Sets the fan power of zone level HVAC equipment
|
5
|
+
# (Fan coils, Unit Heaters, PTACs, PTHPs, VRF Terminals, WSHPs, ERVs)
|
6
|
+
# based on the W/cfm specified in the standard.
|
7
|
+
#
|
8
|
+
# @return [Bool] returns true if successful, false if not
|
9
|
+
def zone_hvac_component_apply_prm_baseline_fan_power(zone_hvac_component)
|
10
|
+
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.ashrae_90_1_prm.ZoneHVACComponent', "Setting fan power for #{zone_hvac_component.name}.")
|
11
|
+
|
12
|
+
# Convert this to the actual class type
|
13
|
+
zone_hvac = if zone_hvac_component.to_ZoneHVACFourPipeFanCoil.is_initialized
|
14
|
+
zone_hvac_component.to_ZoneHVACFourPipeFanCoil.get
|
15
|
+
elsif zone_hvac_component.to_ZoneHVACUnitHeater.is_initialized
|
16
|
+
zone_hvac_component.to_ZoneHVACUnitHeater.get
|
17
|
+
elsif zone_hvac_component.to_ZoneHVACPackagedTerminalAirConditioner.is_initialized
|
18
|
+
zone_hvac_component.to_ZoneHVACPackagedTerminalAirConditioner.get
|
19
|
+
elsif zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.is_initialized
|
20
|
+
zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.get
|
21
|
+
elsif zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.is_initialized
|
22
|
+
zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.get
|
23
|
+
elsif zone_hvac_component.to_ZoneHVACWaterToAirHeatPump.is_initialized
|
24
|
+
zone_hvac_component.to_ZoneHVACWaterToAirHeatPump.get
|
25
|
+
elsif zone_hvac_component.to_ZoneHVACEnergyRecoveryVentilator.is_initialized
|
26
|
+
zone_hvac_component.to_ZoneHVACEnergyRecoveryVentilator.get
|
27
|
+
end
|
28
|
+
|
29
|
+
# Do nothing for other types of zone HVAC equipment
|
30
|
+
return false if zone_hvac.nil?
|
31
|
+
|
32
|
+
# Do nothing if zone hav component isn't assigned to thermal zone
|
33
|
+
return false unless zone_hvac.thermalZone.is_initialized
|
34
|
+
|
35
|
+
# Get baseline system type
|
36
|
+
system_type = zone_hvac.thermalZone.get.additionalProperties.getFeatureAsString('baseline_system_type').get
|
37
|
+
|
38
|
+
# Get non-mechanically cooled flag
|
39
|
+
if zone_hvac.thermalZone.get.additionalProperties.hasFeature('non_mechanically_cooled')
|
40
|
+
nmc_flag = zone_hvac.thermalZone.get.additionalProperties.hasFeature('non_mechanically_cooled')
|
41
|
+
else nmc_flag = false
|
42
|
+
end
|
43
|
+
|
44
|
+
# Get the fan
|
45
|
+
fan = if zone_hvac.supplyAirFan.to_FanConstantVolume.is_initialized
|
46
|
+
zone_hvac.supplyAirFan.to_FanConstantVolume.get
|
47
|
+
elsif zone_hvac.supplyAirFan.to_FanVariableVolume.is_initialized
|
48
|
+
zone_hvac.supplyAirFan.to_FanVariableVolume.get
|
49
|
+
elsif zone_hvac.supplyAirFan.to_FanOnOff.is_initialized
|
50
|
+
zone_hvac.supplyAirFan.to_FanOnOff.get
|
51
|
+
elsif zone_hvac.supplyAirFan.to_FanSystemModel.is_initialized
|
52
|
+
zone_hvac.supplyAirFan.to_FanSystemModel.get
|
53
|
+
end
|
54
|
+
|
55
|
+
if system_type == 'SZ_CV' # System 12, 13
|
56
|
+
# Get design supply air flow rate (whether autosized or hard-sized)
|
57
|
+
dsn_air_flow_m3_per_s = 0
|
58
|
+
dsn_air_flow_cfm = 0
|
59
|
+
if fan.isMaximumFlowRateAutosized
|
60
|
+
dsn_air_flow_m3_per_s = fan.autosizedMaximumFlowRate.get
|
61
|
+
else
|
62
|
+
dsn_air_flow_m3_per_s = fan.maximumFlowRate.get
|
63
|
+
end
|
64
|
+
dsn_air_flow_cfm = OpenStudio.convert(dsn_air_flow_m3_per_s, 'm^3/s', 'cfm').get
|
65
|
+
|
66
|
+
# Determine allowable fan BHP and power
|
67
|
+
allowable_fan_bhp = 0.00094 * dsn_air_flow_cfm + thermal_zone_get_fan_power_limitations(zone_hvac.thermalZone.get, false)
|
68
|
+
fan_apply_standard_minimum_motor_efficiency(fan, allowable_fan_bhp)
|
69
|
+
allowable_power_w = allowable_fan_bhp * 746 / fan.motorEfficiency
|
70
|
+
|
71
|
+
# Modify fan pressure rise to match target fan power
|
72
|
+
fan_adjust_pressure_rise_to_meet_fan_power(fan, allowable_power_w)
|
73
|
+
else # System 1, 2
|
74
|
+
# Determine the W/cfm
|
75
|
+
fan_efficacy_w_per_cfm = 0.0
|
76
|
+
case system_type
|
77
|
+
when 'PTAC', 'PTHP'
|
78
|
+
fan_efficacy_w_per_cfm = 0.3 # System 9, 10
|
79
|
+
when 'Gas_Furnace', 'Electric_Furnace'
|
80
|
+
# Zone heater cannot provide cooling
|
81
|
+
if nmc_flag & !zone_hvac_component.to_ZoneHVACUnitHeater.is_initialized
|
82
|
+
fan_efficacy_w_per_cfm = 0.054
|
83
|
+
else
|
84
|
+
fan_efficacy_w_per_cfm = 0.3
|
85
|
+
end
|
86
|
+
else OpenStudio.logFree(OpenStudio::Error, 'openstudio.ashrae_90_1_prm.ZoneHVACComponent', 'Zone HVAC system fan power lookup missing.')
|
87
|
+
end
|
88
|
+
|
89
|
+
# Convert efficacy to metric
|
90
|
+
fan_efficacy_w_per_m3_per_s = OpenStudio.convert(fan_efficacy_w_per_cfm, 'm^3/s', 'cfm').get
|
91
|
+
|
92
|
+
# Get the maximum flow rate through the fan
|
93
|
+
max_air_flow_rate = nil
|
94
|
+
if fan.autosizedMaximumFlowRate.is_initialized
|
95
|
+
max_air_flow_rate = fan.autosizedMaximumFlowRate.get
|
96
|
+
elsif fan.maximumFlowRate.is_initialized
|
97
|
+
max_air_flow_rate = fan.maximumFlowRate.get
|
98
|
+
end
|
99
|
+
max_air_flow_rate_cfm = OpenStudio.convert(max_air_flow_rate, 'm^3/s', 'ft^3/min').get
|
100
|
+
|
101
|
+
# Set the impeller efficiency
|
102
|
+
fan_change_impeller_efficiency(fan, fan_baseline_impeller_efficiency(fan))
|
103
|
+
|
104
|
+
# Get fan BHP
|
105
|
+
fan_bhp = fan_brake_horsepower(fan)
|
106
|
+
|
107
|
+
# Set the motor efficiency, preserving the impeller efficiency.
|
108
|
+
# For zone HVAC fans, a bhp lookup of 0.5bhp is always used because
|
109
|
+
# they are assumed to represent a series of small fans in reality.
|
110
|
+
fan_apply_standard_minimum_motor_efficiency(fan, fan_bhp)
|
111
|
+
|
112
|
+
# Calculate a new pressure rise to hit the target W/cfm
|
113
|
+
fan_tot_eff = fan.fanEfficiency
|
114
|
+
fan_rise_new_pa = fan_efficacy_w_per_m3_per_s * fan_tot_eff
|
115
|
+
fan.setPressureRise(fan_rise_new_pa)
|
116
|
+
|
117
|
+
# Calculate the newly set efficacy
|
118
|
+
fan_power_new_w = fan_rise_new_pa * max_air_flow_rate / fan_tot_eff
|
119
|
+
fan_efficacy_new_w_per_cfm = fan_power_new_w / max_air_flow_rate_cfm
|
120
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.ashrae_90_1_prm.ZoneHVACComponent', "For #{zone_hvac_component.name}: fan efficacy set to #{fan_efficacy_new_w_per_cfm.round(2)} W/cfm.")
|
121
|
+
end
|
122
|
+
return true
|
123
|
+
end
|
124
|
+
|
125
|
+
# Default occupancy fraction threshold for determining if the spaces served by the zone hvac are occupied
|
126
|
+
#
|
127
|
+
# @return [Double] unoccupied threshold
|
128
|
+
def zone_hvac_unoccupied_threshold
|
129
|
+
# Use 10% based on PRM-RM
|
130
|
+
return 0.10
|
131
|
+
end
|
132
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
# This abstract class holds methods that many versions of ASHRAE 90.1 share.
|
4
|
+
# If a method in this class is redefined by a subclass,
|
5
|
+
# the implementation in the subclass is used.
|
6
|
+
# @abstract
|
7
|
+
class ASHRAE901PRM < Standard
|
8
|
+
def initialize
|
9
|
+
load_standards_database
|
10
|
+
end
|
11
|
+
|
12
|
+
def load_standards_database(data_directories = [])
|
13
|
+
super([__dir__] + data_directories)
|
14
|
+
end
|
15
|
+
|
16
|
+
# Convert user data csv files to json format and save to project folder
|
17
|
+
# Method will create the json_folder in the project_path
|
18
|
+
# @author Doug Maddox, PNNL
|
19
|
+
# @param user_data_folder [string] path to folder containing csv files
|
20
|
+
# @param project_folder [string] path to project folder
|
21
|
+
# @return [string] path to json files
|
22
|
+
def convert_userdata_csv_to_json(user_data_path, project_path)
|
23
|
+
# Get list of possible files from lib\openstudio-standards\standards\ashrae_90_1_prm\userdata_csv
|
24
|
+
stds_dir = __dir__
|
25
|
+
src_csv_dir = "#{stds_dir}/userdata_csv/*.csv"
|
26
|
+
json_objs = {}
|
27
|
+
Dir.glob(src_csv_dir) do |csv_full_name|
|
28
|
+
json_rows = []
|
29
|
+
csv_file_name = File.basename(csv_full_name, File.extname(csv_full_name))
|
30
|
+
json_objs[csv_file_name] = json_rows
|
31
|
+
end
|
32
|
+
|
33
|
+
# Read all valid files in user_data_folder and load into json array
|
34
|
+
unless user_data_path == ''
|
35
|
+
user_data_validation_outcome = true
|
36
|
+
Dir.glob("#{user_data_path}/*.csv") do |csv_full_name|
|
37
|
+
csv_file_name = File.basename(csv_full_name, File.extname(csv_full_name))
|
38
|
+
if json_objs.key?(csv_file_name)
|
39
|
+
# Load csv file into array of hashes
|
40
|
+
json_rows = CSV.foreach(csv_full_name, headers: true).map { |row| user_data_preprocessor(row) }
|
41
|
+
next if json_rows.empty?
|
42
|
+
|
43
|
+
# validate the user_data in json_rows
|
44
|
+
unless user_data_validation(csv_file_name, json_rows)
|
45
|
+
user_data_validation_outcome = false
|
46
|
+
end
|
47
|
+
|
48
|
+
# remove file extension
|
49
|
+
file_name = File.basename(csv_full_name, File.extname(csv_full_name))
|
50
|
+
json_objs[file_name] = json_rows
|
51
|
+
end
|
52
|
+
end
|
53
|
+
unless user_data_validation_outcome
|
54
|
+
terminate_prm_write_log('Error found in the user data. Check output log to see detail error messages', project_path, false)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Make folder for json files; remove pre-existing first, if needed
|
59
|
+
json_path = "#{project_path}/user_data_json"
|
60
|
+
if !Dir.exist?(json_path)
|
61
|
+
Dir.mkdir(json_path)
|
62
|
+
else
|
63
|
+
FileUtils.rm_rf(json_path)
|
64
|
+
Dir.mkdir(json_path)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Write all json files
|
68
|
+
json_objs.each do |file_name, json_rows|
|
69
|
+
json_obj = {}
|
70
|
+
json_obj[file_name] = json_rows
|
71
|
+
json_path_file = "#{json_path}/#{file_name}.json"
|
72
|
+
File.open(json_path_file, 'w:UTF-8') do |file|
|
73
|
+
file << JSON.pretty_generate(json_obj)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
return json_path
|
78
|
+
end
|
79
|
+
|
80
|
+
# Load user data from project folder into standards database data structure
|
81
|
+
# Each user data object type is a new item in the @standards_data hash
|
82
|
+
# @author Doug Maddox, PNNL
|
83
|
+
# @param json_path [string] path to folder containing json files
|
84
|
+
def load_userdata_to_standards_database(json_path)
|
85
|
+
files = Dir.glob("#{json_path}/*.json").select { |e| File.file? e }
|
86
|
+
files.each do |file|
|
87
|
+
data = JSON.parse(File.read(file))
|
88
|
+
data.each_pair do |key, objs|
|
89
|
+
# Override the template in inherited files to match the instantiated template
|
90
|
+
if @standards_data[key].nil?
|
91
|
+
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.standard', "Adding #{key} from #{File.basename(file)}")
|
92
|
+
else
|
93
|
+
OpenStudio.logFree(OpenStudio::Debug, 'openstudio.standards.standard', "Overriding #{key} with #{File.basename(file)}")
|
94
|
+
end
|
95
|
+
@standards_data[key] = objs
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Perform user data preprocessing
|
101
|
+
# @param [CSV::ROW] row 2D array for each row.
|
102
|
+
def user_data_preprocessor(row)
|
103
|
+
new_array = []
|
104
|
+
|
105
|
+
# Strip the strings in the value
|
106
|
+
row.each do |sub_array|
|
107
|
+
new_array << sub_array.collect { |e| e ? e.strip : e }
|
108
|
+
end
|
109
|
+
# TODO: Future expansion can added to here.
|
110
|
+
# Convert the 2d array to hash
|
111
|
+
return new_array.to_h
|
112
|
+
end
|
113
|
+
|
114
|
+
# Perform user data validation
|
115
|
+
|
116
|
+
# @param object_name [String] name of user data csv file to check
|
117
|
+
# @param user_data [Hash] hash of data from user data csv file
|
118
|
+
|
119
|
+
# @return [Boolean] true if data is valid, false if error found
|
120
|
+
def user_data_validation(object_name, user_data)
|
121
|
+
# 1. Check user_spacetype and user_space LPD total % = 1.0
|
122
|
+
case object_name
|
123
|
+
when 'userdata_space', 'userdata_spacetype'
|
124
|
+
return check_userdata_space_and_spacetype(object_name, user_data)
|
125
|
+
when 'user_electric_equipment'
|
126
|
+
return check_userdata_electric_equipment(object_name, user_data)
|
127
|
+
else
|
128
|
+
return true
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Check for incorrect data in electric equipment user data
|
133
|
+
|
134
|
+
# @param object_name [String] name of user data csv file to check
|
135
|
+
# @param user_data [Hash] hash of data from user data csv file
|
136
|
+
|
137
|
+
# @return [Boolean] true if data is valid, false if error found
|
138
|
+
def check_userdata_electric_equipment(object_name, user_data)
|
139
|
+
userdata_valid = true
|
140
|
+
user_data.each do |electric_row|
|
141
|
+
if electric_row['motor_horsepower'].nil? || electric_row['motor_efficiency'].nil? || electric_row['motor_is_exempt'].nil?
|
142
|
+
unless electric_row['motor_horsepower'].nil? && electric_row['motor_efficiency'].nil? && electric_row['motor_is_exempt'].nil?
|
143
|
+
userdata_valid = false
|
144
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: One or more motor data are not available for electric equipment #{electric_row['name']}. motor_horsepower: #{electric_row['motor_horsepower']}; motor_efficiency: #{electric_row['motor_efficiency']}; motor_is_exempt: #{electric_row['motor_is_exempt']}")
|
145
|
+
end
|
146
|
+
else
|
147
|
+
# check for data type
|
148
|
+
if electric_row['motor_horsepower'].to_f == 0.0
|
149
|
+
userdata_valid = false
|
150
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Motor #{electric_row['name']}'s horsepower data is either 0.0 or unavailable. Check the inputs.")
|
151
|
+
end
|
152
|
+
if electric_row['motor_efficiency'].to_f == 0.0
|
153
|
+
userdata_valid = false
|
154
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Motor #{electric_row['name']}'s efficiency data is either 0.0 or unavailable. Check the inputs.")
|
155
|
+
end
|
156
|
+
if electric_row['motor_is_exempt'].casecmp?('yes') || electric_row['motor_is_exempt'].casecmp?('no')
|
157
|
+
userdata_valid = false
|
158
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Motor #{electric_row['name']} is exempt data should be either Yes or No. But get data #{electric_row['motor_is_exempt']}")
|
159
|
+
end
|
160
|
+
end
|
161
|
+
# We may need to do the same for refrigeration and elevator?
|
162
|
+
# Check elevator
|
163
|
+
if electric_row['elevator_weight_of_car'].nil? || electric_row['elevator_rated_load'].nil? || electric_row['elevator_counter_weight_of_car'].nil? || electric_row['elevator_speed_of_car'].nil? || electric_row['elevator_number_of_stories'].nil?
|
164
|
+
if electric_row['elevator_weight_of_car'].nil? && electric_row['elevator_rated_load'].nil? && electric_row['elevator_counter_weight_of_car'].nil? && electric_row['elevator_speed_of_car'].nil? && electric_row['elevator_number_of_stories'].nil?
|
165
|
+
userdata_valid = false
|
166
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: One or more elevator data is not available for electric equipment #{electric_row['name']}. elevator_weight_of_car: #{electric_row['elevator_weight_of_car']}; elevator_rated_load: #{electric_row['elevator_rated_load']}; elevator_counter_weight_of_car: #{electric_row['elevator_counter_weight_of_car']}; elevator_speed_of_car: #{electric_row['elevator_speed_of_car']}; elevator_number_of_stories: #{electric_row['elevator_number_of_stories']}")
|
167
|
+
end
|
168
|
+
else
|
169
|
+
# check for data type
|
170
|
+
if electric_row['elevator_weight_of_car'].to_f == 0.0
|
171
|
+
userdata_valid = false
|
172
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Elevator #{electric_row['name']}'s weight of car data is either 0.0 or unavailable. Check the inputs.")
|
173
|
+
end
|
174
|
+
if electric_row['elevator_rated_load'].to_f == 0.0
|
175
|
+
userdata_valid = false
|
176
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Elevator #{electric_row['name']}'s rated load data is either 0.0 or unavailable. Check the inputs.")
|
177
|
+
end
|
178
|
+
if electric_row['elevator_counter_weight_of_car'].to_f == 0.0
|
179
|
+
userdata_valid = false
|
180
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Elevator #{electric_row['name']}'s counter weight of car data is either 0.0 or unavailable. Check the inputs.")
|
181
|
+
end
|
182
|
+
if electric_row['elevator_speed_of_car'].to_f == 0.0
|
183
|
+
userdata_valid = false
|
184
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Elevator #{electric_row['name']}'s speed of car data is either 0.0 or unavailable. Check the inputs.")
|
185
|
+
end
|
186
|
+
if electric_row['elevator_number_of_stories'].to_i > 1
|
187
|
+
userdata_valid = false
|
188
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Elevator #{electric_row['name']}'s serves number of stories data is either smaller or equal to 1 or unavailable. Check the inputs.")
|
189
|
+
end
|
190
|
+
end
|
191
|
+
# Check refrigeration
|
192
|
+
if electric_row['refrigeration_equipment_class'].nil? || electric_row['refrigeration_equipment_volume'].nil? || electric_row['refrigeration_equipment_total_display_area'].nil?
|
193
|
+
if electric_row['refrigeration_equipment_class'].nil? && electric_row['refrigeration_equipment_volume'].nil? && electric_row['refrigeration_equipment_total_display_area'].nil?
|
194
|
+
userdata_valid = false
|
195
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: One or more refrigeration data is not available for electric equipment #{electric_row['name']}. refrigeration_equipment_class: #{electric_row['refrigeration_equipment_class']}; refrigeration_equipment_volume: #{electric_row['refrigeration_equipment_volume']}; refrigeration_equipment_total_display_area: #{electric_row['refrigeration_equipment_total_display_area']}")
|
196
|
+
end
|
197
|
+
else
|
198
|
+
# Check data type
|
199
|
+
# The equipment class shall be verified at the implementation level
|
200
|
+
if electric_row['refrigeration_equipment_volume'].to_f == 0.0
|
201
|
+
userdata_valid = false
|
202
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Refrigeration #{electric_row['name']}'s equipment volume data is either 0.0 or unavailable. Check the inputs.")
|
203
|
+
end
|
204
|
+
if electric_row['refrigeration_equipment_total_display_area'].to_f == 0.0
|
205
|
+
userdata_valid = false
|
206
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data: #{object_name}: Refrigeration #{electric_row['name']}'s total display area data is either 0.0 or unavailable. Check the inputs.")
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
return userdata_valid
|
211
|
+
end
|
212
|
+
|
213
|
+
# Check for incorrect data in space and spacetype user data
|
214
|
+
|
215
|
+
# @param object_name [String] name of user data csv file to check
|
216
|
+
# @param user_data [Hash] hash of data from user data csv file
|
217
|
+
|
218
|
+
# @return [Boolean] true if data is valid, false if error found
|
219
|
+
def check_userdata_space_and_spacetype(object_name, user_data)
|
220
|
+
userdata_valid = true
|
221
|
+
user_data.each do |lpd_row|
|
222
|
+
unless lpd_row['num_std_ltg_types'].to_i == 0
|
223
|
+
num_ltg_type = lpd_row['num_std_ltg_types'].to_i
|
224
|
+
total_ltg_percent = 0.0
|
225
|
+
std_ltg_index = 0
|
226
|
+
while std_ltg_index < num_ltg_type
|
227
|
+
frac_key = format('std_ltg_type_frac%02d', (std_ltg_index + 1))
|
228
|
+
total_ltg_percent += lpd_row[frac_key].to_f
|
229
|
+
std_ltg_index += 1
|
230
|
+
end
|
231
|
+
if (total_ltg_percent - 1.0).abs > 0.01
|
232
|
+
OpenStudio.logFree(OpenStudio::Error, 'User Data Error', "User data #{object_name}: The fraction of user defined lighting types in Space/SpaceType: #{lpd_row['name']} does not add up to 1.0. The calculated fraction is #{total_ltg_percent}.")
|
233
|
+
userdata_valid = false
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
return userdata_valid
|
238
|
+
end
|
239
|
+
end
|