openstudio-standards 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.md +33 -0
- data/data/inventory/thermal_bridging.csv +90 -0
- data/data/standards/OpenStudio_Standards-deer-comstock.xlsx +0 -0
- data/data/standards/manage_OpenStudio_Standards.rb +1 -1
- data/data/standards/test_performance_expected_dd_results.csv +2014 -1891
- data/lib/openstudio-standards/btap/analysis.rb +8 -8
- data/lib/openstudio-standards/btap/bridging.rb +664 -645
- data/lib/openstudio-standards/btap/btap.model.rb +14 -14
- data/lib/openstudio-standards/btap/btap.rb +7 -7
- data/lib/openstudio-standards/btap/btap_result.rb +1 -1
- data/lib/openstudio-standards/btap/economics.rb +23 -23
- data/lib/openstudio-standards/btap/envelope.rb +8 -8
- data/lib/openstudio-standards/btap/equest.rb +1 -1
- data/lib/openstudio-standards/btap/geometry.rb +2 -2
- data/lib/openstudio-standards/btap/mpc.rb +7 -7
- data/lib/openstudio-standards/btap/schedules.rb +1 -1
- data/lib/openstudio-standards/btap/simmanager.rb +4 -4
- data/lib/openstudio-standards/btap/spaceloads.rb +26 -26
- data/lib/openstudio-standards/btap/utilities.rb +6 -6
- data/lib/openstudio-standards/btap/vintagizer.rb +1 -1
- data/lib/openstudio-standards/constructions/information.rb +83 -0
- data/lib/openstudio-standards/constructions/materials/modify.rb +72 -0
- data/lib/openstudio-standards/constructions/modify.rb +80 -0
- data/lib/openstudio-standards/create_typical/create_typical.rb +983 -0
- data/lib/openstudio-standards/create_typical/enumerations.rb +484 -0
- data/lib/openstudio-standards/create_typical/space_type_blend.rb +791 -0
- data/lib/openstudio-standards/create_typical/space_type_ratios.rb +494 -0
- data/lib/openstudio-standards/daylighting/space.rb +47 -0
- data/lib/openstudio-standards/geometry/create.rb +801 -0
- data/lib/openstudio-standards/geometry/create_bar.rb +2170 -0
- data/lib/openstudio-standards/geometry/information.rb +462 -0
- data/lib/openstudio-standards/geometry/modify.rb +48 -0
- data/lib/openstudio-standards/hvac/air_loop/information.rb +79 -0
- data/lib/openstudio-standards/hvac/cbecs_hvac.rb +616 -0
- data/lib/openstudio-standards/hvac/setpoint_managers/information.rb +91 -0
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Model.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Model.rb +2 -2
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.hvac_systems.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +4 -36
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.hvac_systems.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +4 -36
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Space.rb +3 -3
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.hvac_systems.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.Model.elevators.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.CoilHeatingGas.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.Model.elevators.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +7 -7
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Courthouse.rb +8 -8
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.FullServiceRestaurant.rb +14 -14
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.HighRiseApartment.rb +9 -9
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +16 -16
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Laboratory.rb +7 -7
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterHighITE.rb +8 -8
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterLowITE.rb +8 -8
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +11 -11
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +7 -7
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOfficeDetailed.rb +9 -9
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +8 -8
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOfficeDetailed.rb +11 -11
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MidriseApartment.rb +9 -9
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb +19 -19
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +10 -10
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.QuickServiceRestaurant.rb +13 -13
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStandalone.rb +6 -6
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStripmall.rb +6 -6
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +9 -9
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterHighITE.rb +8 -8
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterLowITE.rb +8 -8
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallHotel.rb +8 -8
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOffice.rb +8 -8
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOfficeDetailed.rb +11 -11
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperMarket.rb +10 -10
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperTallBuilding.rb +19 -19
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.TallBuilding.rb +18 -18
- data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Warehouse.rb +6 -6
- data/lib/openstudio-standards/prototypes/common/do_not_edit_metaclasses.rb +957 -957
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirConditionerVariableRefrigerantFlow.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +84 -16
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingGas.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +61 -10
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.ControllerWaterCoil.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoolingTower.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanConstantVolume.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanOnOff.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanZoneExhaust.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.HeatExchangerAirToAirSensibleAndLatent.rb +2 -2
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +4 -4
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +4 -4
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +43 -30
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.swh.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +18 -11
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +774 -117
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.radiant_system_controls.rb +340 -481
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.refrigeration.rb +3 -3
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +3 -3
- data/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb +22 -22
- data/lib/openstudio-standards/prototypes/deer/deer.Model.rb +1 -1
- data/lib/openstudio-standards/qaqc/calibration.rb +131 -0
- data/lib/openstudio-standards/qaqc/create_results.rb +983 -0
- data/lib/openstudio-standards/qaqc/envelope.rb +399 -0
- data/lib/openstudio-standards/qaqc/eui.rb +213 -0
- data/lib/openstudio-standards/qaqc/hvac.rb +1943 -0
- data/lib/openstudio-standards/qaqc/internal_loads.rb +568 -0
- data/lib/openstudio-standards/qaqc/reporting.rb +141 -0
- data/lib/openstudio-standards/qaqc/schedules.rb +129 -0
- data/lib/openstudio-standards/qaqc/service_water_heating.rb +273 -0
- data/lib/openstudio-standards/qaqc/weather_files.rb +497 -0
- data/lib/openstudio-standards/qaqc/zone_conditions.rb +278 -0
- data/lib/openstudio-standards/schedules/create.rb +364 -0
- data/lib/openstudio-standards/schedules/information.rb +169 -0
- data/lib/openstudio-standards/schedules/modify.rb +445 -0
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +110 -71
- data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctParallelPIUReheat.rb +3 -3
- data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +4 -4
- data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +2 -1
- data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +16 -10
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +4 -4
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.CoilDX.rb +4 -4
- data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +5 -5
- data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.Construction.rb +17 -18
- data/lib/openstudio-standards/standards/Standards.CoolingTower.rb +6 -6
- data/lib/openstudio-standards/standards/Standards.CoolingTowerSingleSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.CoolingTowerTwoSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.CoolingTowerVariableSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.Fan.rb +6 -12
- data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +2 -2
- data/lib/openstudio-standards/standards/Standards.FluidCooler.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.HeatExchangerSensLat.rb +3 -3
- data/lib/openstudio-standards/standards/Standards.Model.rb +411 -261
- data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +2 -2
- data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +94 -29
- data/lib/openstudio-standards/standards/Standards.Pump.rb +2 -2
- data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +2 -2
- data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +14 -14
- data/lib/openstudio-standards/standards/Standards.Space.rb +37 -30
- data/lib/openstudio-standards/standards/Standards.SpaceType.rb +38 -29
- data/lib/openstudio-standards/standards/Standards.SubSurface.rb +7 -7
- data/lib/openstudio-standards/standards/Standards.Surface.rb +13 -13
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +109 -66
- data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +11 -4
- data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PlantLoop.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Space.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.Space.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirLoopHVAC.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Space.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirLoopHVAC.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.CoolingTowerVariableSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Model.rb +5 -21
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Space.rb +4 -4
- 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/ashrae_90_1_2013.ZoneHVACComponent.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirLoopHVAC.rb +36 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerVariableSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Space.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.ZoneHVACComponent.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/comstock_ashrae_90_1_2016.AirLoopHVAC.rb +26 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +53 -10
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerVariableSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Space.rb +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ZoneHVACComponent.rb +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/comstock_ashrae_90_1_2019.AirLoopHVAC.rb +26 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.curves.json +211 -211
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.economizers.json +14 -14
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirLoopHVAC.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.Model.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.PlantLoop.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.economizers.json +14 -14
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirLoopHVAC.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.Model.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.PlantLoop.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.CoolingTowerVariableSpeed.rb +1 -1
- 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.Space.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirLoopHVAC.rb +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.CoolingTowerVariableSpeed.rb +1 -1
- 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.Space.rb +4 -4
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +22 -28
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctParallelPIUReheat.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctVAVReheat.rb +2 -2
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.BoilerHotWater.rb +1 -74
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +7 -59
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +1 -21
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.DesignSpecificationOutdoorAir.rb +101 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanVariableVolume.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.HeatExchangerSensLat.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +643 -526
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +8 -2
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +17 -77
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Space.rb +74 -16
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +96 -44
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Surface.rb +6 -6
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ThermalZone.rb +18 -6
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ZoneHVACComponent.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.rb +328 -74
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +0 -118
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.rb +2 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_rejection.json +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/baseline_outdoor_air.md +35 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_plug_load_measures.md +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/ashrae_90_1_prm.UserData.rb +228 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_enums.rb +131 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_space.csv +1 -1
- data/lib/openstudio-standards/standards/cbes/cbes.AirLoopHVAC.rb +5 -5
- data/lib/openstudio-standards/standards/cbes/cbes.Model.rb +1 -1
- data/lib/openstudio-standards/standards/cbes/cbes.PlantLoop.rb +1 -1
- data/lib/openstudio-standards/standards/cbes/cbes.Space.rb +1 -1
- data/lib/openstudio-standards/standards/cbes/cbes_t24_2005/cbes_t24_2005.Space.rb +1 -1
- data/lib/openstudio-standards/standards/cbes/cbes_t24_2008/cbes_t24_2008.Space.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer.AirLoopHVAC.rb +109 -27
- data/lib/openstudio-standards/standards/deer/deer.Space.rb +1 -1
- data/lib/openstudio-standards/standards/deer/deer_1985/data/deer_1985.economizers.json +246 -4
- data/lib/openstudio-standards/standards/deer/deer_1996/data/deer_1996.economizers.json +246 -4
- data/lib/openstudio-standards/standards/deer/deer_2003/data/deer_2003.economizers.json +246 -4
- data/lib/openstudio-standards/standards/deer/deer_2003/deer_2003.ThermalZone.rb +18 -18
- data/lib/openstudio-standards/standards/deer/deer_2007/data/deer_2007.economizers.json +246 -4
- data/lib/openstudio-standards/standards/deer/deer_2007/deer_2007.ThermalZone.rb +18 -18
- data/lib/openstudio-standards/standards/deer/deer_2011/data/deer_2011.economizers.json +246 -4
- data/lib/openstudio-standards/standards/deer/deer_2011/deer_2011.ThermalZone.rb +18 -18
- data/lib/openstudio-standards/standards/deer/deer_2014/data/deer_2014.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.Space.rb +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.ThermalZone.rb +18 -18
- data/lib/openstudio-standards/standards/deer/deer_2015/data/deer_2015.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.Space.rb +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.ThermalZone.rb +18 -18
- data/lib/openstudio-standards/standards/deer/deer_2017/data/deer_2017.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.Space.rb +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.ThermalZone.rb +18 -18
- data/lib/openstudio-standards/standards/deer/deer_2020/data/deer_2020.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.AirLoopHVAC.rb +18 -5
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.ThermalZone.rb +18 -18
- data/lib/openstudio-standards/standards/deer/deer_2025/data/deer_2025.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.AirLoopHVAC.rb +3 -3
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2030/data/deer_2030.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2030/data/deer_2030.heat_pumps.json +2 -2
- data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.AirLoopHVAC.rb +3 -3
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2035/data/deer_2035.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.AirLoopHVAC.rb +3 -3
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2040/data/deer_2040.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.AirLoopHVAC.rb +3 -3
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2045/data/deer_2045.economizers.json +260 -0
- data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.AirLoopHVAC.rb +3 -3
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2050/data/deer_2050.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.AirLoopHVAC.rb +3 -3
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2055/data/deer_2055.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.AirLoopHVAC.rb +3 -3
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2060/data/deer_2060.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.AirLoopHVAC.rb +3 -3
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2065/data/deer_2065.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.AirLoopHVAC.rb +3 -3
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2070/data/deer_2070.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.AirLoopHVAC.rb +3 -3
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_2075/data/deer_2075.economizers.json +248 -6
- data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.AirLoopHVAC.rb +3 -3
- 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 +3 -3
- data/lib/openstudio-standards/standards/deer/deer_pre_1975/data/deer_pre_1975.economizers.json +246 -4
- data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/data/space_types.json +447 -223
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/building_envelope.rb +1 -1
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/space_types.json +447 -223
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_systems.rb +5 -2
- data/lib/openstudio-standards/standards/necb/ECMS/data/chiller_types.json +25 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/chillers.json +44 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/curves.json +225 -0
- data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +2 -2
- data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +193 -73
- data/lib/openstudio-standards/standards/necb/ECMS/pv_ground.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +10 -4
- data/lib/openstudio-standards/standards/necb/NECB2011/beps_compliance_path.rb +7 -7
- data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +4 -5
- data/lib/openstudio-standards/standards/necb/NECB2011/data/chiller_types.json +32 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/data/chillers.json +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +36 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +7 -7
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernEducation.osm +47587 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernHealthCare.osm +49764 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Warehouse.osm +283 -297
- data/lib/openstudio-standards/standards/necb/NECB2011/data/space_type_unit_definitions.txt +2 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +447 -223
- data/lib/openstudio-standards/standards/necb/NECB2011/data/standards_data.rb +3 -3
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_multi_speed.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +49 -27
- data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +400 -202
- data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +4 -4
- data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +637 -318
- data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +18 -1
- data/lib/openstudio-standards/standards/necb/NECB2015/necb_2015.rb +3 -3
- data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +637 -318
- data/lib/openstudio-standards/standards/necb/NECB2017/hvac_systems.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2017/necb_2017.rb +3 -3
- data/lib/openstudio-standards/standards/necb/NECB2020/building_envelope.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2020/data/space_types.json +615 -307
- data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +4 -4
- data/lib/openstudio-standards/standards/necb/common/btap_data.rb +10 -5
- data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +1 -1
- data/lib/openstudio-standards/utilities/assertion.rb +128 -0
- data/lib/openstudio-standards/utilities/logging.rb +2 -3
- data/lib/openstudio-standards/utilities/object_info.rb +39 -18
- data/lib/openstudio-standards/utilities/schedule_translator.rb +8 -6
- data/lib/openstudio-standards/utilities/simulation.rb +24 -11
- data/lib/openstudio-standards/utilities/sqlfile.rb +10 -5
- data/lib/openstudio-standards/version.rb +1 -1
- data/lib/openstudio-standards/weather/Weather.Model.rb +8 -9
- data/lib/openstudio-standards/weather/Weather.stat_file.rb +3 -3
- data/lib/openstudio-standards/weather/information.rb +35 -0
- data/lib/openstudio-standards.rb +69 -5
- metadata +54 -18
- data/License.txt +0 -65
- data/data/standards/OpenStudio_Standards-deer-ALL-comstock(space_types).xlsx +0 -0
- data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVAC.rb +0 -59
- data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingWater.rb +0 -13
- data/lib/openstudio-standards/hvac_sizing/Siz.HVACComponent.rb +0 -36
- data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +0 -898
- data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +0 -126
- data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +0 -356
- data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.Model.rb +0 -35
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTower.rb +0 -110
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTowerVariableSpeed.rb +0 -5
@@ -0,0 +1,278 @@
|
|
1
|
+
# Module to apply QAQC checks to a model
|
2
|
+
module OpenstudioStandards
|
3
|
+
module QAQC
|
4
|
+
# @!group Zone Conditions
|
5
|
+
|
6
|
+
# Check that there are no people or lights in plenums.
|
7
|
+
#
|
8
|
+
# @param category [String] category to bin this check into
|
9
|
+
# @param target_standard [String] standard template, e.g. '90.1-2013'
|
10
|
+
# @param name_only [Boolean] If true, only return the name of this check
|
11
|
+
# @return [OpenStudio::Attribute] OpenStudio Attribute object containing check results
|
12
|
+
def self.check_plenum_loads(category, target_standard, name_only: false)
|
13
|
+
# summary of the check
|
14
|
+
check_elems = OpenStudio::AttributeVector.new
|
15
|
+
check_elems << OpenStudio::Attribute.new('name', 'Plenum Loads')
|
16
|
+
check_elems << OpenStudio::Attribute.new('category', category)
|
17
|
+
check_elems << OpenStudio::Attribute.new('description', 'Check that the plenums do not have people or lights.')
|
18
|
+
|
19
|
+
# stop here if only name is requested this is used to populate display name for arguments
|
20
|
+
if name_only == true
|
21
|
+
results = []
|
22
|
+
check_elems.each do |elem|
|
23
|
+
results << elem.valueAsString
|
24
|
+
end
|
25
|
+
return results
|
26
|
+
end
|
27
|
+
|
28
|
+
std = Standard.build(target_standard)
|
29
|
+
|
30
|
+
begin
|
31
|
+
@model.getThermalZones.sort.each do |zone|
|
32
|
+
next unless std.thermal_zone_plenum?(zone)
|
33
|
+
|
34
|
+
# people
|
35
|
+
num_people = zone.numberOfPeople
|
36
|
+
if num_people > 0
|
37
|
+
check_elems << OpenStudio::Attribute.new('flag', "#{zone.name} is a plenum, but has #{num_people.round(1)} people. Plenums should not contain people.")
|
38
|
+
end
|
39
|
+
# lights
|
40
|
+
lights_w = zone.lightingPower
|
41
|
+
if lights_w > 0
|
42
|
+
check_elems << OpenStudio::Attribute.new('flag', "#{zone.name} is a plenum, but has #{lights_w.round(1)} W of lights. Plenums should not contain lights.")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
rescue StandardError => e
|
46
|
+
# brief description of ruby error
|
47
|
+
check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
|
48
|
+
|
49
|
+
# backtrace of ruby error for diagnostic use
|
50
|
+
if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
|
51
|
+
end
|
52
|
+
|
53
|
+
# add check_elms to new attribute
|
54
|
+
check_elem = OpenStudio::Attribute.new('check', check_elems)
|
55
|
+
|
56
|
+
return check_elem
|
57
|
+
end
|
58
|
+
|
59
|
+
# Check for excess simulataneous heating and cooling
|
60
|
+
#
|
61
|
+
# @param category [String] category to bin this check into
|
62
|
+
# @param target_standard [String] standard template, e.g. '90.1-2013'
|
63
|
+
# @param max_delta [Double] threshold for throwing an error for temperature difference
|
64
|
+
# @param name_only [Boolean] If true, only return the name of this check
|
65
|
+
# @return [OpenStudio::Attribute] OpenStudio Attribute object containing check results
|
66
|
+
def self.check_supply_air_and_thermostat_temperature_difference(category, target_standard, max_delta: 2.0, name_only: false)
|
67
|
+
# G3.1.2.9 requires a 20 degree F delta between supply air temperature and zone temperature.
|
68
|
+
target_clg_delta = 20.0
|
69
|
+
|
70
|
+
# summary of the check
|
71
|
+
check_elems = OpenStudio::AttributeVector.new
|
72
|
+
check_elems << OpenStudio::Attribute.new('name', 'Supply and Zone Air Temperature')
|
73
|
+
check_elems << OpenStudio::Attribute.new('category', category)
|
74
|
+
if @utility_name.nil?
|
75
|
+
check_elems << OpenStudio::Attribute.new('description', "Check if fans modeled to ASHRAE 90.1 2013 Section G3.1.2.9 requirements. Compare the supply air temperature for each thermal zone against the thermostat setpoints. Throw flag if temperature difference excedes threshold of #{target_clg_delta}F plus the selected tolerance.")
|
76
|
+
else
|
77
|
+
check_elems << OpenStudio::Attribute.new('description', "Check if fans modeled to ASHRAE 90.1 2013 Section G3.1.2.9 requirements. Compare the supply air temperature for each thermal zone against the thermostat setpoints. Throw flag if temperature difference excedes threshold set by #{@utility_name}.")
|
78
|
+
end
|
79
|
+
|
80
|
+
# stop here if only name is requested this is used to populate display name for arguments
|
81
|
+
if name_only == true
|
82
|
+
results = []
|
83
|
+
check_elems.each do |elem|
|
84
|
+
results << elem.valueAsString
|
85
|
+
end
|
86
|
+
return results
|
87
|
+
end
|
88
|
+
|
89
|
+
std = Standard.build(target_standard)
|
90
|
+
|
91
|
+
begin
|
92
|
+
# loop through thermal zones
|
93
|
+
@model.getThermalZones.sort.each do |thermal_zone|
|
94
|
+
# skip plenums
|
95
|
+
next if std.thermal_zone_plenum?(thermal_zone)
|
96
|
+
|
97
|
+
# populate thermostat ranges
|
98
|
+
model_clg_min = nil
|
99
|
+
if thermal_zone.thermostatSetpointDualSetpoint.is_initialized
|
100
|
+
|
101
|
+
thermostat = thermal_zone.thermostatSetpointDualSetpoint.get
|
102
|
+
if thermostat.coolingSetpointTemperatureSchedule.is_initialized
|
103
|
+
|
104
|
+
clg_sch = thermostat.coolingSetpointTemperatureSchedule.get
|
105
|
+
schedule_values = nil
|
106
|
+
if clg_sch.to_ScheduleRuleset.is_initialized
|
107
|
+
schedule_values = std.schedule_ruleset_annual_min_max_value(clg_sch.to_ScheduleRuleset.get)
|
108
|
+
elsif clg_sch.to_ScheduleConstant.is_initialized
|
109
|
+
schedule_values = std.schedule_constant_annual_min_max_value(clg_sch.to_ScheduleConstant.get)
|
110
|
+
end
|
111
|
+
|
112
|
+
unless schedule_values.nil?
|
113
|
+
model_clg_min = schedule_values['min']
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
else
|
118
|
+
# go to next zone if not conditioned
|
119
|
+
next
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
# flag if there is setpoint schedule can't be inspected (isn't ruleset)
|
124
|
+
if model_clg_min.nil?
|
125
|
+
check_elems << OpenStudio::Attribute.new('flag', "Can't inspect thermostat schedules for #{thermal_zone.name}")
|
126
|
+
else
|
127
|
+
|
128
|
+
# get supply air temps from thermal zone sizing
|
129
|
+
sizing_zone = thermal_zone.sizingZone
|
130
|
+
clg_supply_air_temp = sizing_zone.zoneCoolingDesignSupplyAirTemperature
|
131
|
+
|
132
|
+
# convert model values to IP
|
133
|
+
model_clg_min_ip = OpenStudio.convert(model_clg_min, 'C', 'F').get
|
134
|
+
clg_supply_air_temp_ip = OpenStudio.convert(clg_supply_air_temp, 'C', 'F').get
|
135
|
+
|
136
|
+
# check supply air against zone temperature (only check against min setpoint, assume max is night setback)
|
137
|
+
if model_clg_min_ip - clg_supply_air_temp_ip > target_clg_delta + max_delta
|
138
|
+
check_elems << OpenStudio::Attribute.new('flag', "For #{thermal_zone.name} the delta temp between the cooling supply air temp of #{clg_supply_air_temp_ip.round(2)} (F) and the minimum thermostat cooling temp of #{model_clg_min_ip.round(2)} (F) is more than #{max_delta} (F) larger than the expected delta of #{target_clg_delta} (F)")
|
139
|
+
elsif model_clg_min_ip - clg_supply_air_temp_ip < target_clg_delta - max_delta
|
140
|
+
check_elems << OpenStudio::Attribute.new('flag', "For #{thermal_zone.name} the delta temp between the cooling supply air temp of #{clg_supply_air_temp_ip.round(2)} (F) and the minimum thermostat cooling temp of #{model_clg_min_ip.round(2)} (F) is more than #{max_delta} (F) smaller than the expected delta of #{target_clg_delta} (F)")
|
141
|
+
end
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
145
|
+
rescue StandardError => e
|
146
|
+
# brief description of ruby error
|
147
|
+
check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
|
148
|
+
|
149
|
+
# backtrace of ruby error for diagnostic use
|
150
|
+
if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
|
151
|
+
end
|
152
|
+
|
153
|
+
# add check_elms to new attribute
|
154
|
+
check_elem = OpenStudio::Attribute.new('check', check_elems)
|
155
|
+
|
156
|
+
return check_elem
|
157
|
+
end
|
158
|
+
|
159
|
+
# Check that all zones with people are conditioned (have a thermostat with setpoints)
|
160
|
+
#
|
161
|
+
# @param category [String] category to bin this check into
|
162
|
+
# @param target_standard [String] standard template, e.g. '90.1-2013'
|
163
|
+
# @param name_only [Boolean] If true, only return the name of this check
|
164
|
+
# @return [OpenStudio::Attribute] OpenStudio Attribute object containing check results
|
165
|
+
def self.check_occupied_zones_conditioned(category, target_standard, name_only: false)
|
166
|
+
# summary of the check
|
167
|
+
check_elems = OpenStudio::AttributeVector.new
|
168
|
+
check_elems << OpenStudio::Attribute.new('name', 'Conditioned Zones')
|
169
|
+
check_elems << OpenStudio::Attribute.new('category', category)
|
170
|
+
check_elems << OpenStudio::Attribute.new('description', 'Check that all zones with people have thermostats.')
|
171
|
+
|
172
|
+
# stop here if only name is requested this is used to populate display name for arguments
|
173
|
+
if name_only == true
|
174
|
+
results = []
|
175
|
+
check_elems.each do |elem|
|
176
|
+
results << elem.valueAsString
|
177
|
+
end
|
178
|
+
return results
|
179
|
+
end
|
180
|
+
|
181
|
+
std = Standard.build(target_standard)
|
182
|
+
|
183
|
+
begin
|
184
|
+
@model.getThermalZones.sort.each do |zone|
|
185
|
+
# only check zones with people
|
186
|
+
num_ppl = zone.numberOfPeople
|
187
|
+
next unless zone.numberOfPeople > 0
|
188
|
+
|
189
|
+
# Check that the zone is heated (at a minimum) by checking that the heating setpoint is at least 41F.
|
190
|
+
# Sometimes people include thermostats but use setpoints such that the system never comes on.
|
191
|
+
unless std.thermal_zone_heated?(zone)
|
192
|
+
check_elems << OpenStudio::Attribute.new('flag', "#{zone.name} has #{num_ppl} people but is not heated. Zones containing people are expected to be conditioned, heated-only at a minimum. Heating setpoint must be at least 41F to be considered heated.")
|
193
|
+
end
|
194
|
+
end
|
195
|
+
rescue StandardError => e
|
196
|
+
# brief description of ruby error
|
197
|
+
check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
|
198
|
+
|
199
|
+
# backtrace of ruby error for diagnostic use
|
200
|
+
if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
|
201
|
+
end
|
202
|
+
|
203
|
+
# add check_elms to new attribute
|
204
|
+
check_elem = OpenStudio::Attribute.new('check', check_elems)
|
205
|
+
|
206
|
+
return check_elem
|
207
|
+
end
|
208
|
+
|
209
|
+
# Check unmet hours
|
210
|
+
#
|
211
|
+
# @param category [String] category to bin this check into
|
212
|
+
# @param target_standard [String] standard template, e.g. '90.1-2013'
|
213
|
+
# @param max_unmet_hrs [Double] threshold for unmet hours reporting
|
214
|
+
# @param expect_clg_unmet_hrs [Bool] boolean on whether to expect unmet cooling hours for a model without a cooling system
|
215
|
+
# @param expect_htg_unmet_hrs [Bool] boolean on whether to expect unmet heating hours for a model without a heating system
|
216
|
+
# @param name_only [Boolean] If true, only return the name of this check
|
217
|
+
# @return [OpenStudio::Attribute] OpenStudio Attribute object containing check results
|
218
|
+
def self.check_unmet_hours(category, target_standard,
|
219
|
+
max_unmet_hrs: 550.0,
|
220
|
+
expect_clg_unmet_hrs: false,
|
221
|
+
expect_htg_unmet_hrs: false,
|
222
|
+
name_only: false)
|
223
|
+
# summary of the check
|
224
|
+
check_elems = OpenStudio::AttributeVector.new
|
225
|
+
check_elems << OpenStudio::Attribute.new('name', 'Unmet Hours')
|
226
|
+
check_elems << OpenStudio::Attribute.new('category', category)
|
227
|
+
check_elems << OpenStudio::Attribute.new('description', 'Check model unmet hours.')
|
228
|
+
|
229
|
+
# stop here if only name is requested this is used to populate display name for arguments
|
230
|
+
if name_only == true
|
231
|
+
results = []
|
232
|
+
check_elems.each do |elem|
|
233
|
+
results << elem.valueAsString
|
234
|
+
end
|
235
|
+
return results
|
236
|
+
end
|
237
|
+
|
238
|
+
std = Standard.build(target_standard)
|
239
|
+
|
240
|
+
begin
|
241
|
+
unmet_heating_hrs = std.model_annual_occupied_unmet_heating_hours(@model)
|
242
|
+
unmet_cooling_hrs = std.model_annual_occupied_unmet_cooling_hours(@model)
|
243
|
+
unmet_hrs = std.model_annual_occupied_unmet_hours(@model)
|
244
|
+
|
245
|
+
if unmet_hrs
|
246
|
+
if unmet_hrs > max_unmet_hrs
|
247
|
+
if expect_clg_unmet_hrs && expect_htg_unmet_hrs
|
248
|
+
check_elems << OpenStudio::Attribute.new('flag', "Warning: Unmet heating and cooling hours expected. There were #{unmet_heating_hrs.round(1)} unmet occupied heating hours and #{unmet_cooling_hrs.round(1)} unmet occupied cooling hours (total: #{unmet_hrs.round(1)}).")
|
249
|
+
elsif expect_clg_unmet_hrs && !expect_htg_unmet_hrs && unmet_heating_hrs >= max_unmet_hrs
|
250
|
+
check_elems << OpenStudio::Attribute.new('flag', "Major Error: Unmet cooling hours expected, but unmet heating hours exceeds limit of #{max_unmet_hrs}. There were #{unmet_heating_hrs.round(1)} unmet occupied heating hours and #{unmet_cooling_hrs.round(1)} unmet occupied cooling hours (total: #{unmet_hrs.round(1)}).")
|
251
|
+
elsif expect_clg_unmet_hrs && !expect_htg_unmet_hrs && unmet_heating_hrs < max_unmet_hrs
|
252
|
+
check_elems << OpenStudio::Attribute.new('flag', "Warning: Unmet cooling hours expected. There were #{unmet_heating_hrs.round(1)} unmet occupied heating hours and #{unmet_cooling_hrs.round(1)} unmet occupied cooling hours (total: #{unmet_hrs.round(1)}).")
|
253
|
+
elsif expect_htg_unmet_hrs && !expect_clg_unmet_hrs && unmet_cooling_hrs >= max_unmet_hrs
|
254
|
+
check_elems << OpenStudio::Attribute.new('flag', "Major Error: Unmet heating hours expected, but unmet cooling hours exceeds limit of #{max_unmet_hrs}. There were #{unmet_heating_hrs.round(1)} unmet occupied heating hours and #{unmet_cooling_hrs.round(1)} unmet occupied cooling hours (total: #{unmet_hrs.round(1)}).")
|
255
|
+
elsif expect_htg_unmet_hrs && !expect_clg_unmet_hrs && unmet_cooling_hrs < max_unmet_hrs
|
256
|
+
check_elems << OpenStudio::Attribute.new('flag', "Warning: Unmet heating hours expected. There were #{unmet_heating_hrs.round(1)} unmet occupied heating hours and #{unmet_cooling_hrs.round(1)} unmet occupied cooling hours (total: #{unmet_hrs.round(1)}).")
|
257
|
+
else
|
258
|
+
check_elems << OpenStudio::Attribute.new('flag', "Major Error: There were #{unmet_heating_hrs.round(1)} unmet occupied heating hours and #{unmet_cooling_hrs.round(1)} unmet occupied cooling hours (total: #{unmet_hrs.round(1)}), more than the limit of #{max_unmet_hrs}.")
|
259
|
+
end
|
260
|
+
end
|
261
|
+
else
|
262
|
+
check_elems << OpenStudio::Attribute.new('flag', 'Warning: Could not determine unmet hours; simulation may have failed.')
|
263
|
+
end
|
264
|
+
rescue StandardError => e
|
265
|
+
# brief description of ruby error
|
266
|
+
check_elems << OpenStudio::Attribute.new('flag', "Error prevented QAQC check from running (#{e}).")
|
267
|
+
|
268
|
+
# backtrace of ruby error for diagnostic use
|
269
|
+
if @error_backtrace then check_elems << OpenStudio::Attribute.new('flag', e.backtrace.join("\n").to_s) end
|
270
|
+
end
|
271
|
+
|
272
|
+
# add check_elms to new attribute
|
273
|
+
check_elem = OpenStudio::Attribute.new('check', check_elems)
|
274
|
+
|
275
|
+
return check_elem
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
@@ -0,0 +1,364 @@
|
|
1
|
+
# Methods to create Schedule objects
|
2
|
+
module OpenstudioStandards
|
3
|
+
module Schedules
|
4
|
+
# @!group Create
|
5
|
+
|
6
|
+
# create a ruleset schedule with a basic profile
|
7
|
+
#
|
8
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
9
|
+
# @param options [Hash] Hash of name and time value pairs
|
10
|
+
# @return [OpenStudio::Model::ScheduleRuleset] OpenStudio ScheduleRuleset object
|
11
|
+
def self.create_simple_schedule(model, options = {})
|
12
|
+
defaults = {
|
13
|
+
'name' => nil,
|
14
|
+
'winter_time_value_pairs' => { 24.0 => 0.0 },
|
15
|
+
'summer_time_value_pairs' => { 24.0 => 1.0 },
|
16
|
+
'default_time_value_pairs' => { 24.0 => 1.0 }
|
17
|
+
}
|
18
|
+
|
19
|
+
# merge user inputs with defaults
|
20
|
+
options = defaults.merge(options)
|
21
|
+
|
22
|
+
# ScheduleRuleset
|
23
|
+
sch_ruleset = OpenStudio::Model::ScheduleRuleset.new(model)
|
24
|
+
if name
|
25
|
+
sch_ruleset.setName(options['name'])
|
26
|
+
end
|
27
|
+
|
28
|
+
# Winter Design Day
|
29
|
+
winter_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
30
|
+
sch_ruleset.setWinterDesignDaySchedule(winter_dsn_day)
|
31
|
+
winter_dsn_day = sch_ruleset.winterDesignDaySchedule
|
32
|
+
winter_dsn_day.setName("#{sch_ruleset.name} Winter Design Day")
|
33
|
+
options['winter_time_value_pairs'].each do |k, v|
|
34
|
+
hour = k.truncate
|
35
|
+
min = ((k - hour) * 60).to_i
|
36
|
+
winter_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0), v)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Summer Design Day
|
40
|
+
summer_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
41
|
+
sch_ruleset.setSummerDesignDaySchedule(summer_dsn_day)
|
42
|
+
summer_dsn_day = sch_ruleset.summerDesignDaySchedule
|
43
|
+
summer_dsn_day.setName("#{sch_ruleset.name} Summer Design Day")
|
44
|
+
options['summer_time_value_pairs'].each do |k, v|
|
45
|
+
hour = k.truncate
|
46
|
+
min = ((k - hour) * 60).to_i
|
47
|
+
summer_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0), v)
|
48
|
+
end
|
49
|
+
|
50
|
+
# All Days
|
51
|
+
default_day = sch_ruleset.defaultDaySchedule
|
52
|
+
default_day.setName("#{sch_ruleset.name} Schedule Week Day")
|
53
|
+
options['default_time_value_pairs'].each do |k, v|
|
54
|
+
hour = k.truncate
|
55
|
+
min = ((k - hour) * 60).to_i
|
56
|
+
default_day.addValue(OpenStudio::Time.new(0, hour, min, 0), v)
|
57
|
+
end
|
58
|
+
|
59
|
+
return sch_ruleset
|
60
|
+
end
|
61
|
+
|
62
|
+
# create a ruleset schedule with a complex profile
|
63
|
+
#
|
64
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
65
|
+
# @param options [Hash] Hash of name and time value pairs
|
66
|
+
# @return [OpenStudio::Model::ScheduleRuleset] OpenStudio ruleset schedule object
|
67
|
+
def self.create_complex_schedule(model, options = {})
|
68
|
+
defaults = {
|
69
|
+
'name' => nil,
|
70
|
+
'default_day' => ['always_on', [24.0, 1.0]]
|
71
|
+
}
|
72
|
+
|
73
|
+
# merge user inputs with defaults
|
74
|
+
options = defaults.merge(options)
|
75
|
+
|
76
|
+
# ScheduleRuleset
|
77
|
+
sch_ruleset = OpenStudio::Model::ScheduleRuleset.new(model)
|
78
|
+
if name
|
79
|
+
sch_ruleset.setName(options['name'])
|
80
|
+
end
|
81
|
+
|
82
|
+
# Winter Design Day
|
83
|
+
unless options['winter_design_day'].nil?
|
84
|
+
winter_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
85
|
+
sch_ruleset.setWinterDesignDaySchedule(winter_dsn_day)
|
86
|
+
winter_dsn_day = sch_ruleset.winterDesignDaySchedule
|
87
|
+
winter_dsn_day.setName("#{sch_ruleset.name} Winter Design Day")
|
88
|
+
options['winter_design_day'].each do |data_pair|
|
89
|
+
hour = data_pair[0].truncate
|
90
|
+
min = ((data_pair[0] - hour) * 60).to_i
|
91
|
+
winter_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0), data_pair[1])
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
# Summer Design Day
|
96
|
+
unless options['summer_design_day'].nil?
|
97
|
+
summer_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
98
|
+
sch_ruleset.setSummerDesignDaySchedule(summer_dsn_day)
|
99
|
+
summer_dsn_day = sch_ruleset.summerDesignDaySchedule
|
100
|
+
summer_dsn_day.setName("#{sch_ruleset.name} Summer Design Day")
|
101
|
+
options['summer_design_day'].each do |data_pair|
|
102
|
+
hour = data_pair[0].truncate
|
103
|
+
min = ((data_pair[0] - hour) * 60).to_i
|
104
|
+
summer_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0), data_pair[1])
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Default Day
|
109
|
+
default_day = sch_ruleset.defaultDaySchedule
|
110
|
+
default_day.setName("#{sch_ruleset.name} #{options['default_day'][0]}")
|
111
|
+
default_data_array = options['default_day']
|
112
|
+
default_data_array.delete_at(0)
|
113
|
+
default_data_array.each do |data_pair|
|
114
|
+
hour = data_pair[0].truncate
|
115
|
+
min = ((data_pair[0] - hour) * 60).to_i
|
116
|
+
default_day.addValue(OpenStudio::Time.new(0, hour, min, 0), data_pair[1])
|
117
|
+
end
|
118
|
+
|
119
|
+
# Rules
|
120
|
+
unless options['rules'].nil?
|
121
|
+
options['rules'].each do |data_array|
|
122
|
+
rule = OpenStudio::Model::ScheduleRule.new(sch_ruleset)
|
123
|
+
rule.setName("#{sch_ruleset.name} #{data_array[0]} Rule")
|
124
|
+
date_range = data_array[1].split('-')
|
125
|
+
start_date = date_range[0].split('/')
|
126
|
+
end_date = date_range[1].split('/')
|
127
|
+
rule.setStartDate(model.getYearDescription.makeDate(start_date[0].to_i, start_date[1].to_i))
|
128
|
+
rule.setEndDate(model.getYearDescription.makeDate(end_date[0].to_i, end_date[1].to_i))
|
129
|
+
days = data_array[2].split('/')
|
130
|
+
rule.setApplySunday(true) if days.include? 'Sun'
|
131
|
+
rule.setApplyMonday(true) if days.include? 'Mon'
|
132
|
+
rule.setApplyTuesday(true) if days.include? 'Tue'
|
133
|
+
rule.setApplyWednesday(true) if days.include? 'Wed'
|
134
|
+
rule.setApplyThursday(true) if days.include? 'Thu'
|
135
|
+
rule.setApplyFriday(true) if days.include? 'Fri'
|
136
|
+
rule.setApplySaturday(true) if days.include? 'Sat'
|
137
|
+
day_schedule = rule.daySchedule
|
138
|
+
day_schedule.setName("#{sch_ruleset.name} #{data_array[0]}")
|
139
|
+
data_array.delete_at(0)
|
140
|
+
data_array.delete_at(0)
|
141
|
+
data_array.delete_at(0)
|
142
|
+
data_array.each do |data_pair|
|
143
|
+
hour = data_pair[0].truncate
|
144
|
+
min = ((data_pair[0] - hour) * 60).to_i
|
145
|
+
day_schedule.addValue(OpenStudio::Time.new(0, hour, min, 0), data_pair[1])
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
return sch_ruleset
|
151
|
+
end
|
152
|
+
|
153
|
+
# create a new schedule using absolute velocity of existing schedule
|
154
|
+
#
|
155
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
156
|
+
# @param schedule_ruleset [OpenStudio::Model::ScheduleRuleset] OpenStudio ruleset schedule object
|
157
|
+
# @return [OpenStudio::Model::ScheduleRuleset] OpenStudio ScheduleRuleset object
|
158
|
+
# @todo fix velocity so it isn't fraction change per step, but per hour
|
159
|
+
# (I need to count hours between times and divide value by this)
|
160
|
+
def self.create_schedule_from_rate_of_change(model, schedule_ruleset)
|
161
|
+
# clone source schedule
|
162
|
+
new_schedule = schedule_ruleset.clone(model)
|
163
|
+
new_schedule.setName("#{schedule_ruleset.name} - Rate of Change")
|
164
|
+
new_schedule = new_schedule.to_ScheduleRuleset.get
|
165
|
+
|
166
|
+
# create array of all profiles to change. This includes summer, winter, default, and rules
|
167
|
+
profiles = []
|
168
|
+
profiles << new_schedule.winterDesignDaySchedule
|
169
|
+
profiles << new_schedule.summerDesignDaySchedule
|
170
|
+
profiles << new_schedule.defaultDaySchedule
|
171
|
+
|
172
|
+
# time values may need
|
173
|
+
end_profile_time = OpenStudio::Time.new(0, 24, 0, 0)
|
174
|
+
hour_bump_time = OpenStudio::Time.new(0, 1, 0, 0)
|
175
|
+
one_hour_left_time = OpenStudio::Time.new(0, 23, 0, 0)
|
176
|
+
|
177
|
+
rules = new_schedule.scheduleRules
|
178
|
+
rules.each do |rule|
|
179
|
+
profiles << rule.daySchedule
|
180
|
+
end
|
181
|
+
|
182
|
+
profiles.uniq.each do |profile|
|
183
|
+
times = profile.times
|
184
|
+
values = profile.values
|
185
|
+
|
186
|
+
i = 0
|
187
|
+
values_intermediate = []
|
188
|
+
times_intermediate = []
|
189
|
+
until i == values.size
|
190
|
+
if i == 0
|
191
|
+
values_intermediate << 0.0
|
192
|
+
if times[i] > hour_bump_time
|
193
|
+
times_intermediate << times[i] - hour_bump_time
|
194
|
+
if times[i + 1].nil?
|
195
|
+
time_step_value = end_profile_time.hours + end_profile_time.minutes / 60 - times[i].hours - times[i].minutes / 60
|
196
|
+
else
|
197
|
+
time_step_value = times[i + 1].hours + times[i + 1].minutes / 60 - times[i].hours - times[i].minutes / 60
|
198
|
+
end
|
199
|
+
values_intermediate << (values[i + 1].to_f - values[i].to_f).abs / (time_step_value * 2)
|
200
|
+
end
|
201
|
+
times_intermediate << times[i]
|
202
|
+
elsif i == (values.size - 1)
|
203
|
+
if times[times.size - 2] < one_hour_left_time
|
204
|
+
times_intermediate << times[times.size - 2] + hour_bump_time # this should be the second to last time
|
205
|
+
time_step_value = times[i - 1].hours + times[i - 1].minutes / 60 - times[i - 2].hours - times[i - 2].minutes / 60
|
206
|
+
values_intermediate << (values[i - 1].to_f - values[i - 2].to_f).abs / (time_step_value * 2)
|
207
|
+
end
|
208
|
+
values_intermediate << 0.0
|
209
|
+
times_intermediate << times[i] # this should be the last time
|
210
|
+
else
|
211
|
+
# get value multiplier based on how many hours it is spread over
|
212
|
+
time_step_value = times[i].hours + times[i].minutes / 60 - times[i - 1].hours - times[i - 1].minutes / 60
|
213
|
+
values_intermediate << (values[i].to_f - values[i - 1].to_f).abs / time_step_value
|
214
|
+
times_intermediate << times[i]
|
215
|
+
end
|
216
|
+
i += 1
|
217
|
+
end
|
218
|
+
|
219
|
+
# delete all profile values
|
220
|
+
profile.clearValues
|
221
|
+
|
222
|
+
i = 0
|
223
|
+
until i == times_intermediate.size
|
224
|
+
if i == (times_intermediate.size - 1)
|
225
|
+
profile.addValue(times_intermediate[i], values_intermediate[i].to_f)
|
226
|
+
else
|
227
|
+
profile.addValue(times_intermediate[i], values_intermediate[i].to_f)
|
228
|
+
end
|
229
|
+
i += 1
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
return new_schedule
|
234
|
+
end
|
235
|
+
|
236
|
+
# merge multiple schedules into one using load or other value to weight each schedules influence on the merge
|
237
|
+
#
|
238
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
239
|
+
# @param schedule_weights_hash [Hash] Hash of OpenStudio::Model::ScheduleRuleset, Double
|
240
|
+
# @param sch_name [String] Optional name of new schedule
|
241
|
+
# @return [Hash] Hash of merged schedule and the total denominator
|
242
|
+
# @todo apply weights to schedule rules as well, not just winter, summer, and default profile
|
243
|
+
def self.create_weighted_merge_schedules(model, schedule_weights_hash, sch_name: 'Merged Schedule')
|
244
|
+
# get denominator for weight
|
245
|
+
denominator = 0.0
|
246
|
+
schedule_weights_hash.each do |schedule, weight|
|
247
|
+
denominator += weight
|
248
|
+
end
|
249
|
+
|
250
|
+
# create new schedule
|
251
|
+
sch_ruleset = OpenStudio::Model::ScheduleRuleset.new(model)
|
252
|
+
sch_ruleset.setName(sch_name)
|
253
|
+
|
254
|
+
# create winter design day profile
|
255
|
+
winter_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
256
|
+
sch_ruleset.setWinterDesignDaySchedule(winter_dsn_day)
|
257
|
+
winter_dsn_day = sch_ruleset.winterDesignDaySchedule
|
258
|
+
winter_dsn_day.setName("#{sch_ruleset.name} Winter Design Day")
|
259
|
+
|
260
|
+
# create summer design day profile
|
261
|
+
summer_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
262
|
+
sch_ruleset.setSummerDesignDaySchedule(summer_dsn_day)
|
263
|
+
summer_dsn_day = sch_ruleset.summerDesignDaySchedule
|
264
|
+
summer_dsn_day.setName("#{sch_ruleset.name} Summer Design Day")
|
265
|
+
|
266
|
+
# create default profile
|
267
|
+
default_day = sch_ruleset.defaultDaySchedule
|
268
|
+
default_day.setName("#{sch_ruleset.name} Schedule Week Day")
|
269
|
+
|
270
|
+
# hash of schedule rules
|
271
|
+
rules_hash = {} # mon, tue, wed, thur, fri, sat, sun, startDate, endDate
|
272
|
+
# to avoid stacking order issues across schedules, I may need to make a rule for each day of the week for each date range
|
273
|
+
|
274
|
+
schedule_weights_hash.each do |schedule, weight|
|
275
|
+
# populate winter design day profile
|
276
|
+
old_winter_profile = schedule.to_ScheduleRuleset.get.winterDesignDaySchedule
|
277
|
+
times_final = summer_dsn_day.times
|
278
|
+
i = 0
|
279
|
+
value_updated_array = []
|
280
|
+
# loop through times already in profile and update values
|
281
|
+
until i > times_final.size - 1
|
282
|
+
value = old_winter_profile.getValue(times_final[i]) * weight / denominator
|
283
|
+
starting_value = winter_dsn_day.getValue(times_final[i])
|
284
|
+
winter_dsn_day.addValue(times_final[i], value + starting_value)
|
285
|
+
value_updated_array << times_final[i]
|
286
|
+
i += 1
|
287
|
+
end
|
288
|
+
# loop through any new times unique to the current old profile to be merged
|
289
|
+
j = 0
|
290
|
+
times = old_winter_profile.times
|
291
|
+
values = old_winter_profile.values
|
292
|
+
until j > times.size - 1
|
293
|
+
unless value_updated_array.include? times[j]
|
294
|
+
value = values[j] * weight / denominator
|
295
|
+
starting_value = winter_dsn_day.getValue(times[j])
|
296
|
+
winter_dsn_day.addValue(times[j], value + starting_value)
|
297
|
+
end
|
298
|
+
j += 1
|
299
|
+
end
|
300
|
+
|
301
|
+
# populate summer design day profile
|
302
|
+
old_summer_profile = schedule.to_ScheduleRuleset.get.summerDesignDaySchedule
|
303
|
+
times_final = summer_dsn_day.times
|
304
|
+
i = 0
|
305
|
+
value_updated_array = []
|
306
|
+
# loop through times already in profile and update values
|
307
|
+
until i > times_final.size - 1
|
308
|
+
value = old_summer_profile.getValue(times_final[i]) * weight / denominator
|
309
|
+
starting_value = summer_dsn_day.getValue(times_final[i])
|
310
|
+
summer_dsn_day.addValue(times_final[i], value + starting_value)
|
311
|
+
value_updated_array << times_final[i]
|
312
|
+
i += 1
|
313
|
+
end
|
314
|
+
# loop through any new times unique to the current old profile to be merged
|
315
|
+
j = 0
|
316
|
+
times = old_summer_profile.times
|
317
|
+
values = old_summer_profile.values
|
318
|
+
until j > times.size - 1
|
319
|
+
unless value_updated_array.include? times[j]
|
320
|
+
value = values[j] * weight / denominator
|
321
|
+
starting_value = summer_dsn_day.getValue(times[j])
|
322
|
+
summer_dsn_day.addValue(times[j], value + starting_value)
|
323
|
+
end
|
324
|
+
j += 1
|
325
|
+
end
|
326
|
+
|
327
|
+
# populate default profile
|
328
|
+
old_default_profile = schedule.to_ScheduleRuleset.get.defaultDaySchedule
|
329
|
+
times_final = default_day.times
|
330
|
+
i = 0
|
331
|
+
value_updated_array = []
|
332
|
+
# loop through times already in profile and update values
|
333
|
+
until i > times_final.size - 1
|
334
|
+
value = old_default_profile.getValue(times_final[i]) * weight / denominator
|
335
|
+
starting_value = default_day.getValue(times_final[i])
|
336
|
+
default_day.addValue(times_final[i], value + starting_value)
|
337
|
+
value_updated_array << times_final[i]
|
338
|
+
i += 1
|
339
|
+
end
|
340
|
+
# loop through any new times unique to the current old profile to be merged
|
341
|
+
j = 0
|
342
|
+
times = old_default_profile.times
|
343
|
+
values = old_default_profile.values
|
344
|
+
until j > times.size - 1
|
345
|
+
unless value_updated_array.include? times[j]
|
346
|
+
value = values[j] * weight / denominator
|
347
|
+
starting_value = default_day.getValue(times[j])
|
348
|
+
default_day.addValue(times[j], value + starting_value)
|
349
|
+
end
|
350
|
+
j += 1
|
351
|
+
end
|
352
|
+
|
353
|
+
# create rules
|
354
|
+
|
355
|
+
# gather data for rule profiles
|
356
|
+
|
357
|
+
# populate rule profiles
|
358
|
+
end
|
359
|
+
|
360
|
+
result = { 'mergedSchedule' => sch_ruleset, 'denominator' => denominator }
|
361
|
+
return result
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|