urbanopt-cli 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/release.yml +24 -0
- data/.github/workflows/nightly_ci_build.yml +39 -29
- data/.gitignore +1 -0
- data/CHANGELOG.md +17 -0
- data/CMakeLists.txt +7 -7
- data/FindOpenStudioSDK.cmake +8 -8
- data/LICENSE.md +8 -35
- data/README.md +25 -10
- data/example_files/Gemfile +9 -9
- data/example_files/example_project_combined.json +6 -2
- data/example_files/example_project_with_ghe.json +859 -0
- data/example_files/mappers/Baseline.rb +39 -415
- data/example_files/mappers/ChilledWaterStorage.rb +1 -1
- data/example_files/mappers/CreateBar.rb +1 -1
- data/example_files/mappers/EvCharging.rb +1 -1
- data/example_files/mappers/FlexibleHotWater.rb +1 -1
- data/example_files/mappers/Floorspace.rb +1 -1
- data/example_files/mappers/HighEfficiency.rb +1 -1
- data/example_files/mappers/HighEfficiencyCreateBar.rb +1 -1
- data/example_files/mappers/HighEfficiencyFloorspace.rb +1 -1
- data/example_files/mappers/PeakHoursMelsShedding.rb +1 -1
- data/example_files/mappers/PeakHoursThermostatAdjust.rb +1 -1
- data/example_files/mappers/ThermalStorage.rb +1 -1
- data/example_files/mappers/base_workflow.osw +11 -4
- data/example_files/mappers/residential/template/util.rb +138 -0
- data/example_files/mappers/residential/util.rb +276 -0
- data/example_files/measures/BuildResidentialModel/measure.rb +118 -230
- data/example_files/measures/BuildResidentialModel/measure.xml +344 -233
- data/example_files/measures/BuildResidentialModel/resources/geometry.rb +7 -2
- data/example_files/measures/BuildResidentialModel/resources/unit_conversions.rb +5 -0
- data/example_files/measures/BuildResidentialModel/resources/util.rb +5 -0
- data/example_files/measures/BuildResidentialModel/tests/test_build_residential_model.rb +344 -0
- data/example_files/measures/BuildResidentialModel/tests/xml_building/17/feature1.xml +2112 -0
- data/example_files/measures/BuildResidentialModel/tests/xml_building/17/feature2.xml +2112 -0
- data/example_files/osm_building/7.osm +0 -2
- data/example_files/osm_building/8.osm +0 -2
- data/example_files/osm_building/9.osm +0 -2
- data/example_files/python_deps/dependencies.json +4 -3
- data/example_files/resources/hpxml-measures/.gitattributes +3 -0
- data/example_files/resources/hpxml-measures/.github/pull_request_template.md +2 -2
- data/example_files/resources/hpxml-measures/.github/workflows/add_to_project.yml +17 -0
- data/example_files/resources/hpxml-measures/.github/workflows/config.yml +37 -8
- data/example_files/resources/hpxml-measures/.gitignore +1 -0
- data/example_files/resources/hpxml-measures/.readthedocs.yml +6 -2
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/README.md +5596 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/README.md.erb +41 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +1324 -1035
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +325 -236
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +119 -152
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{build_residential_hpxml_test.rb → test_build_residential_hpxml.rb} +225 -107
- data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/README.md +96 -0
- data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/README.md.erb +41 -0
- data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.rb +73 -31
- data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.xml +60 -40
- data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/README.md +48 -23
- data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/constants.rb +5 -0
- data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules.rb +6 -12
- data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/tests/{build_residential_schedule_file_test.rb → test_build_residential_schedule_file.rb} +162 -35
- data/example_files/resources/hpxml-measures/Changelog.md +57 -1
- data/example_files/resources/hpxml-measures/Gemfile +1 -1
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/README.md +83 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/README.md.erb +41 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +1081 -878
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +258 -204
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +205 -178
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/battery.rb +43 -18
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +37 -112
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +34 -73
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/Xing_okstate_0664D_13659_Table_A-3.csv +4165 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/unavailable_periods.csv +2 -2
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +5 -1
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/generator.rb +13 -7
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +95 -42
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +132 -108
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +1695 -1267
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +668 -589
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXML.xsd +304 -553
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml +197 -112
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +1140 -1745
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +412 -325
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +56 -48
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +49 -38
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/materials.rb +5 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +17 -1
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/minitest_helper.rb +5 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +94 -78
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/output.rb +60 -2
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/psychrometrics.rb +6 -1
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb +11 -5
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-non-stochastic.csv +1 -1
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic-30-mins.csv +52561 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic_2.csv +8761 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic_3.csv +8761 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic_4.csv +8761 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic_5.csv +8761 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic_6.csv +8761 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +129 -137
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/simcontrols.rb +12 -21
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/unit_conversions.rb +5 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/util.rb +7 -2
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/utility_bills.rb +6 -1
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +7 -2
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +179 -144
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/weather.rb +129 -71
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +5 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlvalidator.rb +23 -6
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +129 -118
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_battery.rb +25 -20
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +2282 -2239
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_enclosure.rb +395 -204
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +12 -7
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +56 -51
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +369 -230
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +371 -191
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +27 -20
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_location.rb +55 -5
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +35 -30
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +13 -8
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_schedules.rb +107 -93
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_simcontrols.rb +11 -6
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +757 -573
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +77 -72
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_weather.rb +36 -6
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/util.rb +5 -0
- data/example_files/resources/hpxml-measures/README.md +2 -0
- data/example_files/resources/hpxml-measures/Rakefile +10 -3
- data/example_files/resources/hpxml-measures/ReportSimulationOutput/README.md +787 -0
- data/example_files/resources/hpxml-measures/ReportSimulationOutput/README.md.erb +41 -0
- data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.rb +730 -418
- data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.xml +1215 -9
- data/example_files/resources/hpxml-measures/ReportSimulationOutput/tests/{output_report_test.rb → test_report_sim_output.rb} +130 -299
- data/example_files/resources/hpxml-measures/ReportUtilityBills/README.md +87 -0
- data/example_files/resources/hpxml-measures/ReportUtilityBills/README.md.erb +41 -0
- data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.rb +261 -89
- data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.xml +179 -94
- data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/simple_rates/Average_retail_price_of_electricity.csv +68 -68
- data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/simple_rates/NG_PRI_SUM_A_EPG0_PRS_DMCF_A.csv +3 -2
- data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/simple_rates/PET_PRI_WFR_A_EPD2F_PRS_DPGAL_W.csv +713 -685
- data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/simple_rates/PET_PRI_WFR_A_EPLLPA_PRS_DPGAL_W.csv +716 -688
- data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/simple_rates/README.md +5 -2
- data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/util.rb +18 -9
- data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/test_report_utility_bills.rb +1308 -0
- data/example_files/resources/hpxml-measures/docs/requirements.txt +5 -0
- data/example_files/resources/hpxml-measures/docs/source/conf.py +1 -2
- data/example_files/resources/hpxml-measures/docs/source/intro.rst +3 -20
- data/example_files/resources/hpxml-measures/docs/source/usage_instructions.rst +1 -1
- data/example_files/resources/hpxml-measures/docs/source/workflow_inputs.rst +917 -564
- data/example_files/resources/hpxml-measures/docs/source/workflow_outputs.rst +79 -42
- data/example_files/resources/hpxml-measures/tasks.rb +2305 -2055
- data/example_files/resources/hpxml-measures/workflow/hpxml_inputs.json +270 -587
- data/example_files/resources/hpxml-measures/workflow/real_homes/house001.xml +559 -557
- data/example_files/resources/hpxml-measures/workflow/real_homes/house002.xml +522 -520
- data/example_files/resources/hpxml-measures/workflow/real_homes/house003.xml +534 -532
- data/example_files/resources/hpxml-measures/workflow/real_homes/house004.xml +547 -545
- data/example_files/resources/hpxml-measures/workflow/real_homes/house005.xml +546 -544
- data/example_files/resources/hpxml-measures/workflow/real_homes/house006.xml +603 -623
- data/example_files/resources/hpxml-measures/workflow/real_homes/house007.xml +613 -633
- data/example_files/resources/hpxml-measures/workflow/real_homes/house008.xml +699 -721
- data/example_files/resources/hpxml-measures/workflow/real_homes/house009.xml +662 -661
- data/example_files/resources/hpxml-measures/workflow/real_homes/house010.xml +657 -677
- data/example_files/resources/hpxml-measures/workflow/real_homes/house011.xml +470 -467
- data/example_files/resources/hpxml-measures/workflow/real_homes/house012.xml +441 -438
- data/example_files/resources/hpxml-measures/workflow/real_homes/house013.xml +468 -465
- data/example_files/resources/hpxml-measures/workflow/real_homes/house014.xml +469 -466
- data/example_files/resources/hpxml-measures/workflow/real_homes/house015.xml +468 -465
- data/example_files/resources/hpxml-measures/workflow/real_homes/house016.xml +717 -714
- data/example_files/resources/hpxml-measures/workflow/real_homes/house017.xml +647 -645
- data/example_files/resources/hpxml-measures/workflow/real_homes/house018.xml +569 -566
- data/example_files/resources/hpxml-measures/workflow/real_homes/house019.xml +602 -599
- data/example_files/resources/hpxml-measures/workflow/real_homes/house020.xml +630 -627
- data/example_files/resources/hpxml-measures/workflow/real_homes/house021.xml +776 -774
- data/example_files/resources/hpxml-measures/workflow/real_homes/house022.xml +670 -667
- data/example_files/resources/hpxml-measures/workflow/real_homes/house023.xml +632 -629
- data/example_files/resources/hpxml-measures/workflow/real_homes/house024.xml +731 -729
- data/example_files/resources/hpxml-measures/workflow/real_homes/house025.xml +672 -669
- data/example_files/resources/hpxml-measures/workflow/real_homes/house026.xml +667 -644
- data/example_files/resources/hpxml-measures/workflow/real_homes/house027.xml +646 -644
- data/example_files/resources/hpxml-measures/workflow/real_homes/house028.xml +690 -688
- data/example_files/resources/hpxml-measures/workflow/real_homes/house029.xml +701 -699
- data/example_files/resources/hpxml-measures/workflow/real_homes/house030.xml +637 -615
- data/example_files/resources/hpxml-measures/workflow/real_homes/house031.xml +690 -688
- data/example_files/resources/hpxml-measures/workflow/real_homes/house032.xml +557 -554
- data/example_files/resources/hpxml-measures/workflow/real_homes/house033.xml +534 -531
- data/example_files/resources/hpxml-measures/workflow/real_homes/house034.xml +636 -635
- data/example_files/resources/hpxml-measures/workflow/real_homes/house035.xml +616 -613
- data/example_files/resources/hpxml-measures/workflow/real_homes/house036.xml +601 -598
- data/example_files/resources/hpxml-measures/workflow/real_homes/house037.xml +581 -578
- data/example_files/resources/hpxml-measures/workflow/real_homes/house038.xml +624 -622
- data/example_files/resources/hpxml-measures/workflow/real_homes/house039.xml +584 -582
- data/example_files/resources/hpxml-measures/workflow/real_homes/house040.xml +631 -629
- data/example_files/resources/hpxml-measures/workflow/real_homes/house041.xml +922 -921
- data/example_files/resources/hpxml-measures/workflow/real_homes/house042.xml +855 -853
- data/example_files/resources/hpxml-measures/workflow/real_homes/house043.xml +739 -737
- data/example_files/resources/hpxml-measures/workflow/real_homes/house044.xml +798 -796
- data/example_files/resources/hpxml-measures/workflow/real_homes/house045.xml +696 -694
- data/example_files/resources/hpxml-measures/workflow/real_homes/house046.xml +487 -483
- data/example_files/resources/hpxml-measures/workflow/real_homes/house047.xml +443 -440
- data/example_files/resources/hpxml-measures/workflow/real_homes/house048.xml +688 -686
- data/example_files/resources/hpxml-measures/workflow/real_homes/house049.xml +722 -720
- data/example_files/resources/hpxml-measures/workflow/real_homes/house050.xml +619 -617
- data/example_files/resources/hpxml-measures/workflow/run_simulation.rb +13 -20
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-coal.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-portable.xml +11 -12
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-whole-home.xml +11 -12
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-multiple.xml +12 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier.xml +11 -12
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-gas.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-modified.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-none.xml +4 -4
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-wood.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-cathedral.xml +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-conditioned.xml +10 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-flat.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-radiant-barrier.xml +10 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-unvented-insulated-roof.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-vented.xml +8 -8
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery-scheduled.xml +571 -569
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-adjacent-to-multifamily-buffer-space.xml → base-bldgtype-mf-unit-adjacent-to-multifamily-buffer-space.xml} +5 -5
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-adjacent-to-multiple.xml → base-bldgtype-mf-unit-adjacent-to-multiple.xml} +17 -17
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-adjacent-to-non-freezing-space.xml → base-bldgtype-mf-unit-adjacent-to-non-freezing-space.xml} +5 -5
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-adjacent-to-other-heated-space.xml → base-bldgtype-mf-unit-adjacent-to-other-heated-space.xml} +5 -5
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-adjacent-to-other-housing-unit.xml → base-bldgtype-mf-unit-adjacent-to-other-housing-unit.xml} +5 -5
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-infil-compartmentalization-test.xml → base-bldgtype-mf-unit-infil-compartmentalization-test.xml} +461 -461
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-residents-1.xml → base-bldgtype-mf-unit-residents-1.xml} +453 -453
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-chiller-baseboard.xml → base-bldgtype-mf-unit-shared-boiler-chiller-baseboard.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-chiller-fan-coil-ducted.xml → base-bldgtype-mf-unit-shared-boiler-chiller-fan-coil-ducted.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-chiller-fan-coil.xml → base-bldgtype-mf-unit-shared-boiler-chiller-fan-coil.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-chiller-water-loop-heat-pump.xml → base-bldgtype-mf-unit-shared-boiler-chiller-water-loop-heat-pump.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-cooling-tower-water-loop-heat-pump.xml → base-bldgtype-mf-unit-shared-boiler-cooling-tower-water-loop-heat-pump.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-only-baseboard.xml → base-bldgtype-mf-unit-shared-boiler-only-baseboard.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-only-fan-coil-ducted.xml → base-bldgtype-mf-unit-shared-boiler-only-fan-coil-ducted.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-only-fan-coil-eae.xml → base-bldgtype-mf-unit-shared-boiler-only-fan-coil-eae.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-mf-unit-shared-boiler-only-fan-coil-fireplace-elec.xml +433 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-only-fan-coil.xml → base-bldgtype-mf-unit-shared-boiler-only-fan-coil.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-only-water-loop-heat-pump.xml → base-bldgtype-mf-unit-shared-boiler-only-water-loop-heat-pump.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-chiller-only-baseboard.xml → base-bldgtype-mf-unit-shared-chiller-only-baseboard.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-chiller-only-fan-coil-ducted.xml → base-bldgtype-mf-unit-shared-chiller-only-fan-coil-ducted.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-chiller-only-fan-coil.xml → base-bldgtype-mf-unit-shared-chiller-only-fan-coil.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-chiller-only-water-loop-heat-pump.xml → base-bldgtype-mf-unit-shared-chiller-only-water-loop-heat-pump.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-cooling-tower-only-water-loop-heat-pump.xml → base-bldgtype-mf-unit-shared-cooling-tower-only-water-loop-heat-pump.xml} +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-generator.xml → base-bldgtype-mf-unit-shared-generator.xml} +13 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-ground-loop-ground-to-air-heat-pump.xml → base-bldgtype-mf-unit-shared-ground-loop-ground-to-air-heat-pump.xml} +13 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-laundry-room-multiple-water-heaters.xml → base-bldgtype-mf-unit-shared-laundry-room-multiple-water-heaters.xml} +480 -480
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-laundry-room.xml → base-bldgtype-mf-unit-shared-laundry-room.xml} +10 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-mechvent-multiple.xml → base-bldgtype-mf-unit-shared-mechvent-multiple.xml} +15 -15
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-mechvent-preconditioning.xml → base-bldgtype-mf-unit-shared-mechvent-preconditioning.xml} +13 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-mechvent.xml → base-bldgtype-mf-unit-shared-mechvent.xml} +13 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-pv.xml → base-bldgtype-mf-unit-shared-pv.xml} +13 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-water-heater-recirc.xml → base-bldgtype-mf-unit-shared-water-heater-recirc.xml} +13 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-water-heater.xml → base-bldgtype-mf-unit-shared-water-heater.xml} +13 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily.xml → base-bldgtype-mf-unit.xml} +13 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-attached-2stories.xml → base-bldgtype-sfa-unit-2stories.xml} +610 -610
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-attached-atticroof-cathedral.xml → base-bldgtype-sfa-unit-atticroof-cathedral.xml} +558 -558
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-attached-infil-compartmentalization-test.xml → base-bldgtype-sfa-unit-infil-compartmentalization-test.xml} +610 -610
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-attached.xml → base-bldgtype-sfa-unit.xml} +610 -610
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless-outside.xml +8 -8
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-2-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-gshp.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-hpwh.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-tankless.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-var-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-dwhr.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-detailed-setpoints.xml +507 -505
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-dse.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-outside.xml +8 -8
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-standbyloss.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-with-solar-fraction.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-electric.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-gas.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-hpwh.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-indirect.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-low-flow-fixtures.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-multiple.xml +14 -14
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-none.xml +5 -5
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-demand.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-manual.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-nocontrol.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-temperature.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-timer.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-evacuated-tube.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-flat-plate.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-ics.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-fraction.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-indirect-flat-plate.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-thermosyphon-flat-plate.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-coal.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-detailed-setpoints.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-elec-uef.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-outside.xml +8 -8
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef-fhr.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-detailed-schedules.xml +13 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-operating-mode-heat-pump-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-outside.xml +8 -8
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-uef.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar-fraction.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified-detailed-occupancy-stochastic.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-oil.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-wood.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-detailed-setpoints.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-outside.xml +8 -8
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-uef.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-uef.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar-fraction.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-propane.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories-garage.xml +13 -14
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories.xml +11 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-1.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-2.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-4.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-5.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-ceilingtypes.xml +576 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-floortypes.xml +519 -519
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-garage.xml +4 -5
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ach-house-pressure.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm-house-pressure.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm50.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ela.xml +548 -548
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-flue.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-ach.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-cfm.xml +551 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-orientations.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-overhangs.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-rooftypes.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-physical-properties.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-shading.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-storms.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-level.xml +10 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-thermal-mass.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-walltypes.xml +19 -19
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-natural-ventilation-availability.xml +555 -553
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-none.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-physical-properties.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-shading-seasons.xml +560 -558
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-shading.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-storms.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-ambient.xml +10 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-basement-garage.xml +10 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-belly-wing-no-skirt.xml +496 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-belly-wing-skirt.xml +496 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-complex.xml +18 -18
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-schedules-simple-power-outage-natvent-unavailable.xml → base-foundation-conditioned-basement-slab-insulation-full.xml} +552 -564
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-slab-insulation.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-wall-insulation.xml +555 -555
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-crawlspace.xml +8 -8
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-multiple.xml +5 -5
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-slab.xml +10 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-above-grade.xml +4 -4
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-assembly-r.xml +4 -4
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-wall-insulation.xml +4 -4
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement.xml +4 -4
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unvented-crawlspace.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace-above-grade.xml +558 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-walkout-basement.xml +15 -15
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-heating-capacity-17f.xml +552 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-heating-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-lockout-temperatures.xml +562 -562
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-seer2-hspf2.xml +557 -557
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-2-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler-hvac-seasons.xml +586 -586
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler-switchover-temperature.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-furnace.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-acca.xml → base-hvac-air-to-air-heat-pump-var-speed-detailed-performance-other-temperatures.xml} +89 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-hers.xml → base-hvac-air-to-air-heat-pump-var-speed-detailed-performance.xml} +107 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-sizing-controls.xml +567 -565
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-coal-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-elec-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-central-ac-1-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only-pilot.xml +512 -512
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-oil-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-propane-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-wood-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed-seer2.xml +536 -536
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-2-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-central-ac-only-var-speed.xml → base-hvac-central-ac-only-var-speed-detailed-performance.xml} +49 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-var-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dse.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-lockout-temperatures.xml +559 -559
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-mini-split-heat-pump-ducted.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-fractions.xml +11 -12
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-multipliers.xml +558 -558
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-buried.xml +554 -554
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-furnace-gas-room-ac.xml → base-hvac-ducts-defaults.xml} +28 -14
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-effective-rvalue.xml +552 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-cfm50.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-percent.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-elec-resistance-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-furnace-gas.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only-ducted.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fireplace-wood-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only.xml +15 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-coal-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-central-ac-1-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-2-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-var-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only-detailed-setpoints.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only-pilot.xml +541 -541
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-room-ac.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-oil-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-propane-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-wood-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-x3-dse.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-cooling-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-heating-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-air-to-air-heat-pump-1-speed-autosized-backup.xml → base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml} +650 -556
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-var-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-1-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-2-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-var-speed.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-ground-to-air-heat-pump.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-air-conditioner-only-ducted.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-heat-pump-ducted.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ducted.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-mini-split-air-conditioner-only-ducted.xml → base-hvac-mini-split-air-conditioner-only-ductless-detailed-performance.xml} +50 -49
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ductless.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-cooling-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-maxload.xml → base-hvac-mini-split-heat-pump-ducted-detailed-performance.xml} +109 -14
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-heating-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-baseboard.xml +524 -524
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-dual-fuel-mini-split-heat-pump-ducted-backup-hardsized.xml → base-hvac-mini-split-heat-pump-ductless-backup-furnace-ducts-defaults.xml} +560 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-furnace.xml +563 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-stove.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-dual-fuel-mini-split-heat-pump-ducted.xml → base-hvac-mini-split-heat-pump-ductless-detailed-performance.xml} +108 -60
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-heating-capacity-17f.xml +505 -505
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-none.xml +10 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac-with-heating-electricity.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac-with-heating-natural-gas.xml +504 -504
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-pthp-heating-capacity-17f.xml +512 -512
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-pthp.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-33percent.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-ceer.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-detailed-setpoints.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-heating.xml +504 -504
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-reverse-cycle.xml +517 -517
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-seasons.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-schedules.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-setbacks.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-fixed-heater-gas-only.xml → base-hvac-space-heater-gas-only.xml} +10 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-oil-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-wood-pellets-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-wall-furnace-elec-only.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-ceiling-fans.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-holiday.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-kwh-per-year.xml +531 -528
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-mixed.xml +536 -536
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none-ceiling-fans.xml +515 -515
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-AMY-2012.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-baltimore-md.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-capetown-zaf.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-dallas-tx.xml +10 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-duluth-mn.xml +4 -4
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-helena-mt.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-honolulu-hi.xml +10 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-miami-fl.xml +10 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-phoenix-az.xml +10 -11
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-portland-or.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-balanced.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-bath-kitchen-fans.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-airflow-fraction-zero.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-dse.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-evap-cooler-only-ducted.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-exhaust.xml +576 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-supply.xml +576 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv-atre-asre.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust-rated-flow-rate.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv-asre.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-multiple.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-supply.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-whole-house-fan.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-additional-properties.xml +21 -19
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-detailed-only.xml +605 -605
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-mixed.xml +587 -587
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-defaults.xml +3 -3
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-emissions.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery-scheduled.xml +587 -585
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery.xml +584 -584
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-ground-conductivity.xml +555 -555
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon.xml +26 -26
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon2.xml +26 -26
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-none.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading-bldgtype-multifamily.xml +508 -508
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-shielding-of-home.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-schedules-simple-power-outage-natvent-available.xml → base-misc-unit-multiplier.xml} +553 -564
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-usage-multiplier.xml +26 -26
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-multiple-mf-units.xml +2755 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-multiple-buildings.xml → base-multiple-sfd-buildings.xml} +31 -22
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-ah.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-garage.xml +4 -5
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-round-trip-efficiency.xml +597 -597
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-scheduled.xml +599 -597
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery-scheduled.xml +615 -613
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery.xml +612 -612
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators.xml +596 -596
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-0-runperiod-1-month.xml +559 -559
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-0.xml +555 -555
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-1-misc-loads-large-uncommon.xml +616 -616
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-1-misc-loads-large-uncommon2.xml +616 -616
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-1.xml +547 -547
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-5.xml +515 -515
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-all-10-mins.xml +14 -12
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-crankcase-heater-40w.xml → base-schedules-detailed-mixed-timesteps-power-outage.xml} +565 -555
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-schedules-detailed-occupancy-stochastic-vacancy-year-round.xml → base-schedules-detailed-mixed-timesteps.xml} +554 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-10-mins.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-power-outage.xml +566 -564
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-vacancy.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-schedules.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-setbacks.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple-power-outage.xml +619 -619
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple-vacancy.xml +618 -618
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-calendar-year-custom.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-custom.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-disabled.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-runperiod-1-month.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-temperature-capacitance-multiplier.xml +553 -553
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-10-mins.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-60-mins.xml +12 -10
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-30-mins.xml +552 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base.xml +9 -9
- data/example_files/resources/hpxml-measures/workflow/template-build-and-run-hpxml-with-stochastic-occupancy.osw +2 -0
- data/example_files/resources/hpxml-measures/workflow/template-run-hpxml-with-stochastic-occupancy-subset.osw +2 -0
- data/example_files/resources/hpxml-measures/workflow/template-run-hpxml-with-stochastic-occupancy.osw +2 -0
- data/example_files/resources/hpxml-measures/workflow/template-run-hpxml.osw +4 -1
- data/example_files/resources/hpxml-measures/workflow/tests/ACCA_Examples/Long_Residence.xml +385 -385
- data/example_files/resources/hpxml-measures/workflow/tests/ACCA_Examples/Vatilo_Residence.xml +378 -380
- data/example_files/resources/hpxml-measures/workflow/tests/ACCA_Examples/Victor_Residence.xml +369 -369
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AC.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AL.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AC.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AL.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AC.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AL.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AC.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AL.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AC.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AL.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AC.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AL.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AC.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AL.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AC.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AL.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AC.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AL.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AC.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AL.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AC.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AL.xml +7 -7
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L302XC.xml +7 -8
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L304XC.xml +7 -8
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L322XC.xml +6 -6
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L324XC.xml +6 -6
- data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_sizing.csv +363 -0
- data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_workflow_simulations1.csv +281 -0
- data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_workflow_simulations1_bills.csv +281 -0
- data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_workflow_simulations2.csv +141 -0
- data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_workflow_simulations2_bills.csv +141 -0
- data/example_files/resources/hpxml-measures/workflow/tests/compare.py +12 -6
- data/example_files/resources/hpxml-measures/workflow/tests/util.rb +1141 -0
- data/example_files/weather/USA_CO_Denver.Intl.AP.725650_TMY3.ddy +536 -0
- data/example_files/weather/USA_CO_Denver.Intl.AP.725650_TMY3.epw +8768 -0
- data/example_files/weather/USA_CO_Denver.Intl.AP.725650_TMY3.stat +554 -0
- data/example_files/weather/USA_FL_MacDill.AFB.747880_TMY3.ddy +536 -0
- data/example_files/weather/USA_FL_MacDill.AFB.747880_TMY3.epw +8768 -0
- data/example_files/weather/USA_FL_MacDill.AFB.747880_TMY3.stat +553 -0
- data/example_files/weather/USA_GA_Atlanta-Hartsfield-Jackson.Intl.AP.722190_TMY3-cache.csv +35 -0
- data/example_files/weather/USA_GA_Atlanta-Hartsfield-Jackson.Intl.AP.722190_TMY3.ddy +536 -0
- data/example_files/weather/USA_GA_Atlanta-Hartsfield-Jackson.Intl.AP.722190_TMY3.epw +8768 -0
- data/example_files/weather/USA_GA_Atlanta-Hartsfield-Jackson.Intl.AP.722190_TMY3.stat +553 -0
- data/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3-cache.csv +35 -0
- data/example_files/xml_building/17/README.md +4 -2
- data/example_files/xml_building/17/feature.xml +2112 -0
- data/lib/uo_cli/version.rb +1 -1
- data/lib/uo_cli.rb +110 -17
- data/uo_cli.gemspec +6 -8
- metadata +130 -177
- data/Jenkinsfile +0 -10
- data/example_files/base_workflow_res.osw +0 -276
- data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/utility_bills_test.rb +0 -1226
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil-location-miami-fl.xml +0 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane-location-portland-or.xml +0 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-cooling-only.xml +0 -544
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-heating-only.xml +0 -550
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-acca.xml +0 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-hers.xml +0 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-maxload-miami-fl.xml +0 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-maxload.xml +0 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-acca.xml +0 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-hers.xml +0 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-maxload.xml +0 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-boiler.xml +0 -569
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-furnace.xml +0 -599
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-maxload.xml +0 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-elec-only.xml +0 -506
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-central-ac-1-speed.xml +0 -560
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-only.xml +0 -507
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-1-speed.xml +0 -536
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-2-speed.xml +0 -536
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-plus-air-to-air-heat-pump-heating.xml +0 -565
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-acca.xml +0 -553
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-hers.xml +0 -553
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-maxload.xml +0 -553
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-elec-resistance-only.xml +0 -497
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-evap-cooler-furnace-gas.xml +0 -544
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-floor-furnace-propane-only.xml +0 -500
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-elec-only.xml +0 -536
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-2-speed.xml +0 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-var-speed.xml +0 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-only.xml +0 -536
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-cooling-only.xml +0 -546
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-heating-only.xml +0 -552
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-acca.xml +0 -554
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-hers.xml +0 -554
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-maxload.xml +0 -554
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-cooling-only.xml +0 -543
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-heating-only.xml +0 -549
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-acca.xml +0 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-hers.xml +0 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ductless-backup-baseboard.xml +0 -519
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ductless-backup-stove.xml +0 -522
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac-with-heating.xml +0 -503
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac.xml +0 -496
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-acca.xml +0 -518
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-hers.xml +0 -518
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-maxload.xml +0 -518
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-only.xml +0 -496
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-heating.xml +0 -503
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-acca.xml +0 -518
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-hers.xml +0 -518
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-maxload.xml +0 -518
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-stove-oil-only.xml +0 -500
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-wall-furnace-elec-only.xml +0 -500
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only-pilot-light.xml +0 -506
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-portable-heater-gas-only.xml +0 -501
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized-allow-increased-fixed-capacities.xml +0 -556
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-none.xml +0 -548
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple-vacancy-year-round.xml +0 -619
- data/example_files/resources/hpxml-measures/workflow/tests/base_results/results.csv +0 -475
- data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_bills.csv +0 -475
- data/example_files/resources/hpxml-measures/workflow/tests/hpxml_translator_test.rb +0 -1313
- data/example_files/resources/measure-info.json +0 -26
- data/example_files/resources/meta_measure.rb +0 -301
- data/example_files/xml_building/17/unit 1.xml +0 -580
- data/example_files/xml_building/17/unit 2.xml +0 -553
- data/example_files/xml_building/17/unit 3.xml +0 -553
- data/example_files/xml_building/17/unit 4.xml +0 -580
- /data/example_files/{residential → mappers/residential/template/iecc}/clothes_dryer.tsv +0 -0
- /data/example_files/{residential → mappers/residential/template/iecc}/clothes_washer.tsv +0 -0
- /data/example_files/{residential → mappers/residential/template/iecc}/cooling_system.tsv +0 -0
- /data/example_files/{residential → mappers/residential/template/iecc}/dishwasher.tsv +0 -0
- /data/example_files/{residential → mappers/residential/template/iecc}/enclosure.tsv +0 -0
- /data/example_files/{residential → mappers/residential/template/iecc}/heat_pump.tsv +0 -0
- /data/example_files/{residential → mappers/residential/template/iecc}/heating_system.tsv +0 -0
- /data/example_files/{residential → mappers/residential/template/iecc}/mechanical_ventilation.tsv +0 -0
- /data/example_files/{residential → mappers/residential/template/iecc}/refrigerator.tsv +0 -0
- /data/example_files/{residential → mappers/residential/template/iecc}/water_heater.tsv +0 -0
- /data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/{JacksonElectricMemberCorp-ResidentialSeniorCitizenLowIncomeAssistance.json → Detailed Rate.json} +0 -0
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
# *********************************************************************************
|
|
2
|
+
# URBANopt (tm), Copyright (c) Alliance for Sustainable Energy, LLC.
|
|
3
|
+
# See also https://github.com/urbanopt/urbanopt-cli/blob/develop/LICENSE.md
|
|
4
|
+
# *********************************************************************************
|
|
5
|
+
|
|
1
6
|
# frozen_string_literal: true
|
|
2
7
|
|
|
3
8
|
# Require all gems up front; this is much faster than multiple resource
|
|
@@ -63,7 +68,7 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
|
|
|
63
68
|
|
|
64
69
|
arg = OpenStudio::Measure::OSArgument.makeStringArgument('building_id', false)
|
|
65
70
|
arg.setDisplayName('BuildingID')
|
|
66
|
-
arg.setDescription(
|
|
71
|
+
arg.setDescription("The ID of the HPXML Building. Only required if there are multiple Building elements in the HPXML file. Use 'ALL' to run all the HPXML Buildings (dwelling units) of a multifamily building in a single model.")
|
|
67
72
|
args << arg
|
|
68
73
|
|
|
69
74
|
return args
|
|
@@ -89,6 +94,7 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
|
|
|
89
94
|
debug = runner.getBoolArgumentValue('debug', user_arguments)
|
|
90
95
|
skip_validation = runner.getBoolArgumentValue('skip_validation', user_arguments)
|
|
91
96
|
building_id = runner.getOptionalStringArgumentValue('building_id', user_arguments)
|
|
97
|
+
building_id = building_id.is_initialized ? building_id.get : nil
|
|
92
98
|
|
|
93
99
|
unless (Pathname.new hpxml_path).absolute?
|
|
94
100
|
hpxml_path = File.expand_path(hpxml_path)
|
|
@@ -101,12 +107,6 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
|
|
|
101
107
|
output_dir = File.expand_path(output_dir)
|
|
102
108
|
end
|
|
103
109
|
|
|
104
|
-
if building_id.is_initialized
|
|
105
|
-
building_id = building_id.get
|
|
106
|
-
else
|
|
107
|
-
building_id = nil
|
|
108
|
-
end
|
|
109
|
-
|
|
110
110
|
begin
|
|
111
111
|
if skip_validation
|
|
112
112
|
schema_validator = nil
|
|
@@ -117,6 +117,7 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
|
|
|
117
117
|
schematron_path = File.join(File.dirname(__FILE__), 'resources', 'hpxml_schematron', 'EPvalidator.xml')
|
|
118
118
|
schematron_validator = XMLValidator.get_schematron_validator(schematron_path)
|
|
119
119
|
end
|
|
120
|
+
|
|
120
121
|
hpxml = HPXML.new(hpxml_path: hpxml_path, schema_validator: schema_validator, schematron_validator: schematron_validator, building_id: building_id)
|
|
121
122
|
hpxml.errors.each do |error|
|
|
122
123
|
runner.registerError(error)
|
|
@@ -126,16 +127,91 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
|
|
|
126
127
|
end
|
|
127
128
|
return false unless hpxml.errors.empty?
|
|
128
129
|
|
|
129
|
-
|
|
130
|
-
|
|
130
|
+
eri_version = hpxml.header.eri_calculation_version # Hidden feature
|
|
131
|
+
eri_version = 'latest' if eri_version.nil?
|
|
132
|
+
eri_version = Constants.ERIVersions[-1] if eri_version == 'latest'
|
|
133
|
+
|
|
134
|
+
# Process weather once upfront
|
|
135
|
+
epw_path = Location.get_epw_path(hpxml.buildings[0], hpxml_path)
|
|
136
|
+
weather = WeatherProcess.new(epw_path: epw_path, runner: runner, hpxml: hpxml)
|
|
137
|
+
epw_file = OpenStudio::EpwFile.new(epw_path)
|
|
138
|
+
hpxml.buildings.each_with_index do |hpxml_bldg, i|
|
|
139
|
+
next if i == 0
|
|
140
|
+
next if Location.get_epw_path(hpxml_bldg, hpxml_path) == epw_path
|
|
141
|
+
|
|
142
|
+
fail 'Weather station EPW filepath has different values across dwelling units.'
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
if (building_id == 'ALL') && (hpxml.buildings.size > 1)
|
|
146
|
+
if hpxml.buildings.map { |hpxml_bldg| hpxml_bldg.batteries.size }.sum > 0
|
|
147
|
+
# FUTURE: Figure out how to allow this. If we allow it, update docs and hpxml_translator_test.rb too.
|
|
148
|
+
# Batteries use "TrackFacilityElectricDemandStoreExcessOnSite"; to support modeling of batteries in whole
|
|
149
|
+
# SFA/MF building simulations, we'd need to create custom meters with electricity usage *for each unit*
|
|
150
|
+
# and switch to "TrackMeterDemandStoreExcessOnSite".
|
|
151
|
+
# https://github.com/NREL/OpenStudio-HPXML/issues/1499
|
|
152
|
+
fail 'Modeling batteries for whole SFA/MF buildings is not currently supported.'
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Apply HPXML defaults upfront; process schedules & emissions
|
|
157
|
+
hpxml_sch_map = {}
|
|
158
|
+
check_emissions_references(hpxml.header, hpxml_path)
|
|
159
|
+
hpxml.buildings.each_with_index do |hpxml_bldg, i|
|
|
160
|
+
check_schedule_references(hpxml_bldg.header, hpxml_path)
|
|
161
|
+
in_schedules_csv = 'in.schedules.csv'
|
|
162
|
+
in_schedules_csv = "in.schedules#{i + 1}.csv" if i > 0
|
|
163
|
+
schedules_file = SchedulesFile.new(runner: runner,
|
|
164
|
+
schedules_paths: hpxml_bldg.header.schedules_filepaths,
|
|
165
|
+
year: Location.get_sim_calendar_year(hpxml.header.sim_calendar_year, epw_file),
|
|
166
|
+
unavailable_periods: hpxml.header.unavailable_periods,
|
|
167
|
+
output_path: File.join(output_dir, in_schedules_csv))
|
|
168
|
+
HPXMLDefaults.apply(runner, hpxml, hpxml_bldg, eri_version, weather, epw_file: epw_file, schedules_file: schedules_file)
|
|
169
|
+
hpxml_sch_map[hpxml_bldg] = schedules_file
|
|
170
|
+
end
|
|
171
|
+
validate_emissions_files(hpxml.header)
|
|
172
|
+
|
|
173
|
+
# Write updated HPXML object (w/ defaults) to file for inspection
|
|
174
|
+
hpxml_defaults_path = File.join(output_dir, 'in.xml')
|
|
175
|
+
XMLHelper.write_file(hpxml.to_doc, hpxml_defaults_path)
|
|
176
|
+
|
|
177
|
+
# Create OpenStudio model
|
|
178
|
+
hpxml_osm_map = {}
|
|
179
|
+
hpxml.buildings.each_with_index do |hpxml_bldg, i|
|
|
180
|
+
schedules_file = hpxml_sch_map[hpxml_bldg]
|
|
181
|
+
if hpxml.buildings.size > 1
|
|
182
|
+
# Create the model for this single unit
|
|
183
|
+
unit_model = OpenStudio::Model::Model.new
|
|
184
|
+
create_unit_model(hpxml, hpxml_bldg, runner, unit_model, epw_path, epw_file, weather, debug, schedules_file, eri_version, i + 1)
|
|
185
|
+
hpxml_osm_map[hpxml_bldg] = unit_model
|
|
186
|
+
else
|
|
187
|
+
create_unit_model(hpxml, hpxml_bldg, runner, model, epw_path, epw_file, weather, debug, schedules_file, eri_version, i + 1)
|
|
188
|
+
hpxml_osm_map[hpxml_bldg] = model
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
# Merge unit models into final model
|
|
193
|
+
if hpxml.buildings.size > 1
|
|
194
|
+
add_unit_model_to_model(model, hpxml_osm_map)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
# Output
|
|
198
|
+
add_unmet_hours_output(model, hpxml_osm_map)
|
|
199
|
+
add_loads_output(model, add_component_loads, hpxml_osm_map)
|
|
200
|
+
set_output_files(model)
|
|
201
|
+
add_additional_properties(model, hpxml, hpxml_osm_map, hpxml_path, building_id, epw_file, hpxml_defaults_path)
|
|
202
|
+
# Uncomment to debug EMS
|
|
203
|
+
# add_ems_debug_output(model)
|
|
131
204
|
|
|
132
205
|
if debug
|
|
206
|
+
# Write OSM file to run dir
|
|
207
|
+
osm_output_path = File.join(output_dir, 'in.osm')
|
|
208
|
+
File.write(osm_output_path, model.to_s)
|
|
209
|
+
runner.registerInfo("Wrote file: #{osm_output_path}")
|
|
210
|
+
|
|
211
|
+
# Copy EPW file to run dir
|
|
133
212
|
epw_output_path = File.join(output_dir, 'in.epw')
|
|
134
213
|
FileUtils.cp(epw_path, epw_output_path)
|
|
135
214
|
end
|
|
136
|
-
|
|
137
|
-
OSModel.create(hpxml, runner, model, hpxml_path, epw_path, weather, output_dir,
|
|
138
|
-
add_component_loads, building_id, debug)
|
|
139
215
|
rescue Exception => e
|
|
140
216
|
runner.registerError("#{e.message}\n#{e.backtrace.join("\n")}")
|
|
141
217
|
return false
|
|
@@ -143,19 +219,198 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
|
|
|
143
219
|
|
|
144
220
|
return true
|
|
145
221
|
end
|
|
146
|
-
end
|
|
147
222
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
223
|
+
def add_unit_model_to_model(model, hpxml_osm_map)
|
|
224
|
+
unique_objects = { 'OS:ConvergenceLimits' => 'ConvergenceLimits',
|
|
225
|
+
'OS:Foundation:Kiva:Settings' => 'FoundationKivaSettings',
|
|
226
|
+
'OS:OutputControl:Files' => 'OutputControlFiles',
|
|
227
|
+
'OS:Output:Diagnostics' => 'OutputDiagnostics',
|
|
228
|
+
'OS:Output:JSON' => 'OutputJSON',
|
|
229
|
+
'OS:PerformancePrecisionTradeoffs' => 'PerformancePrecisionTradeoffs',
|
|
230
|
+
'OS:RunPeriod' => 'RunPeriod',
|
|
231
|
+
'OS:RunPeriodControl:DaylightSavingTime' => 'RunPeriodControlDaylightSavingTime',
|
|
232
|
+
'OS:ShadowCalculation' => 'ShadowCalculation',
|
|
233
|
+
'OS:SimulationControl' => 'SimulationControl',
|
|
234
|
+
'OS:Site' => 'Site',
|
|
235
|
+
'OS:Site:GroundTemperature:Deep' => 'SiteGroundTemperatureDeep',
|
|
236
|
+
'OS:Site:GroundTemperature:Shallow' => 'SiteGroundTemperatureShallow',
|
|
237
|
+
'OS:Site:WaterMainsTemperature' => 'SiteWaterMainsTemperature',
|
|
238
|
+
'OS:SurfaceConvectionAlgorithm:Inside' => 'InsideSurfaceConvectionAlgorithm',
|
|
239
|
+
'OS:SurfaceConvectionAlgorithm:Outside' => 'OutsideSurfaceConvectionAlgorithm',
|
|
240
|
+
'OS:Timestep' => 'Timestep' }
|
|
241
|
+
|
|
242
|
+
# Handle unique objects first: Grab one from the first model we find the
|
|
243
|
+
# object on (may not be the first unit).
|
|
244
|
+
unit_model_objects = []
|
|
245
|
+
unique_handles_to_skip = []
|
|
246
|
+
uuid_regex = /\{(.*?)\}/
|
|
247
|
+
unique_objects.each do |idd_obj, osm_class|
|
|
248
|
+
first_model_object_by_type = nil
|
|
249
|
+
hpxml_osm_map.values.each do |unit_model|
|
|
250
|
+
next if unit_model.getObjectsByType(idd_obj.to_IddObjectType).empty?
|
|
251
|
+
|
|
252
|
+
model_object = unit_model.send("get#{osm_class}")
|
|
253
|
+
|
|
254
|
+
if first_model_object_by_type.nil?
|
|
255
|
+
# Retain object for model
|
|
256
|
+
unit_model_objects << model_object
|
|
257
|
+
first_model_object_by_type = model_object
|
|
258
|
+
if idd_obj == 'OS:Site:WaterMainsTemperature' # Handle referenced child object too
|
|
259
|
+
unit_model_objects << unit_model.getObjectsByName(model_object.temperatureSchedule.get.name.to_s)[0]
|
|
260
|
+
end
|
|
261
|
+
else
|
|
262
|
+
# Throw error if different values between this model_object and first_model_object_by_type
|
|
263
|
+
if model_object.to_s.gsub(uuid_regex, '') != first_model_object_by_type.to_s.gsub(uuid_regex, '')
|
|
264
|
+
fail "Unique object (#{idd_obj}) has different values across dwelling units."
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
if idd_obj == 'OS:Site:WaterMainsTemperature' # Handle referenced child object too
|
|
268
|
+
if model_object.temperatureSchedule.get.to_s.gsub(uuid_regex, '') != first_model_object_by_type.temperatureSchedule.get.to_s.gsub(uuid_regex, '')
|
|
269
|
+
fail "Unique object (#{idd_obj}) has different values across dwelling units."
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
unique_handles_to_skip << model_object.handle.to_s
|
|
275
|
+
if idd_obj == 'OS:Site:WaterMainsTemperature' # Handle referenced child object too
|
|
276
|
+
unique_handles_to_skip << model_object.temperatureSchedule.get.handle.to_s
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
hpxml_osm_map.values.each_with_index do |unit_model, unit_number|
|
|
282
|
+
shift_geometry(unit_model, unit_number)
|
|
283
|
+
prefix_all_unit_model_objects(unit_model, unit_number)
|
|
284
|
+
|
|
285
|
+
# Handle remaining (non-unique) objects now
|
|
286
|
+
unit_model.objects.each do |obj|
|
|
287
|
+
next if unit_number > 0 && obj.to_Building.is_initialized
|
|
288
|
+
next if unique_handles_to_skip.include? obj.handle.to_s
|
|
153
289
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
290
|
+
unit_model_objects << obj
|
|
291
|
+
end
|
|
292
|
+
end
|
|
157
293
|
|
|
158
|
-
|
|
294
|
+
model.addObjects(unit_model_objects, true)
|
|
295
|
+
end
|
|
296
|
+
|
|
297
|
+
def shift_geometry(unit_model, unit_number)
|
|
298
|
+
# Shift units so they aren't right on top and shade each other
|
|
299
|
+
y_shift = 200.0 * unit_number # meters
|
|
300
|
+
|
|
301
|
+
# shift the unit so it's not right on top of the previous one
|
|
302
|
+
unit_model.getSpaces.sort.each do |space|
|
|
303
|
+
space.setYOrigin(y_shift)
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# shift shading surfaces
|
|
307
|
+
m = OpenStudio::Matrix.new(4, 4, 0)
|
|
308
|
+
m[0, 0] = 1
|
|
309
|
+
m[1, 1] = 1
|
|
310
|
+
m[2, 2] = 1
|
|
311
|
+
m[3, 3] = 1
|
|
312
|
+
m[1, 3] = y_shift
|
|
313
|
+
t = OpenStudio::Transformation.new(m)
|
|
314
|
+
|
|
315
|
+
unit_model.getShadingSurfaceGroups.each do |shading_surface_group|
|
|
316
|
+
next if shading_surface_group.space.is_initialized # already got shifted
|
|
317
|
+
|
|
318
|
+
shading_surface_group.shadingSurfaces.each do |shading_surface|
|
|
319
|
+
shading_surface.setVertices(t * shading_surface.vertices)
|
|
320
|
+
end
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
def prefix_all_unit_model_objects(unit_model, unit_number)
|
|
325
|
+
# Prefix all objects with name using unit number
|
|
326
|
+
# FUTURE: Create objects with unique names up front so we don't have to do this
|
|
327
|
+
|
|
328
|
+
# EMS objects
|
|
329
|
+
ems_map = {}
|
|
330
|
+
|
|
331
|
+
unit_model.getEnergyManagementSystemSensors.each do |sensor|
|
|
332
|
+
ems_map[sensor.name.to_s] = make_variable_name(sensor.name, unit_number)
|
|
333
|
+
sensor.setKeyName(make_variable_name(sensor.keyName, unit_number)) unless sensor.keyName.empty? || sensor.keyName.downcase == 'environment'
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
unit_model.getEnergyManagementSystemActuators.each do |actuator|
|
|
337
|
+
ems_map[actuator.name.to_s] = make_variable_name(actuator.name, unit_number)
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
unit_model.getEnergyManagementSystemInternalVariables.each do |internal_variable|
|
|
341
|
+
ems_map[internal_variable.name.to_s] = make_variable_name(internal_variable.name, unit_number)
|
|
342
|
+
internal_variable.setInternalDataIndexKeyName(make_variable_name(internal_variable.internalDataIndexKeyName, unit_number)) unless internal_variable.internalDataIndexKeyName.empty?
|
|
343
|
+
end
|
|
344
|
+
|
|
345
|
+
unit_model.getEnergyManagementSystemGlobalVariables.each do |global_variable|
|
|
346
|
+
ems_map[global_variable.name.to_s] = make_variable_name(global_variable.name, unit_number)
|
|
347
|
+
end
|
|
348
|
+
|
|
349
|
+
unit_model.getEnergyManagementSystemOutputVariables.each do |output_variable|
|
|
350
|
+
next if output_variable.emsVariableObject.is_initialized
|
|
351
|
+
|
|
352
|
+
new_ems_variable_name = make_variable_name(output_variable.emsVariableName, unit_number)
|
|
353
|
+
ems_map[output_variable.emsVariableName.to_s] = new_ems_variable_name
|
|
354
|
+
output_variable.setEMSVariableName(new_ems_variable_name)
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
unit_model.getEnergyManagementSystemSubroutines.each do |subroutine|
|
|
358
|
+
ems_map[subroutine.name.to_s] = make_variable_name(subroutine.name, unit_number)
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
# variables in program lines don't get updated automatically
|
|
362
|
+
lhs_characters = [' ', ',', '(', ')', '+', '-', '*', '/', ';']
|
|
363
|
+
rhs_characters = [''] + lhs_characters
|
|
364
|
+
(unit_model.getEnergyManagementSystemPrograms + unit_model.getEnergyManagementSystemSubroutines).each do |program|
|
|
365
|
+
new_lines = []
|
|
366
|
+
program.lines.each do |line|
|
|
367
|
+
ems_map.each do |old_name, new_name|
|
|
368
|
+
next unless line.include?(old_name)
|
|
369
|
+
|
|
370
|
+
# old_name between at least 1 character, with the exception of '' on left and ' ' on right
|
|
371
|
+
lhs_characters.each do |lhs|
|
|
372
|
+
next unless line.include?("#{lhs}#{old_name}")
|
|
373
|
+
|
|
374
|
+
rhs_characters.each do |rhs|
|
|
375
|
+
next unless line.include?("#{lhs}#{old_name}#{rhs}")
|
|
376
|
+
next if lhs == '' && ['', ' '].include?(rhs)
|
|
377
|
+
|
|
378
|
+
line.gsub!("#{lhs}#{old_name}#{rhs}", "#{lhs}#{new_name}#{rhs}")
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
new_lines << line
|
|
383
|
+
end
|
|
384
|
+
program.setLines(new_lines)
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# All model objects
|
|
388
|
+
unit_model.objects.each do |model_object|
|
|
389
|
+
next if model_object.name.nil?
|
|
390
|
+
|
|
391
|
+
if unit_number == 0
|
|
392
|
+
# OpenStudio is unhappy if these schedules are renamed
|
|
393
|
+
next if model_object.name.to_s == unit_model.alwaysOnContinuousSchedule.name.to_s
|
|
394
|
+
next if model_object.name.to_s == unit_model.alwaysOnDiscreteSchedule.name.to_s
|
|
395
|
+
next if model_object.name.to_s == unit_model.alwaysOffDiscreteSchedule.name.to_s
|
|
396
|
+
end
|
|
397
|
+
|
|
398
|
+
model_object.setName(make_variable_name(model_object.name, unit_number))
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
def make_variable_name(obj_name, unit_number)
|
|
403
|
+
return "unit#{unit_number + 1}_#{obj_name}".gsub(' ', '_').gsub('-', '_')
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def create_unit_model(hpxml, hpxml_bldg, runner, model, epw_path, epw_file, weather, debug, schedules_file, eri_version, unit_num)
|
|
407
|
+
@hpxml_header = hpxml.header
|
|
408
|
+
@hpxml_bldg = hpxml_bldg
|
|
409
|
+
@debug = debug
|
|
410
|
+
@schedules_file = schedules_file
|
|
411
|
+
@eri_version = eri_version
|
|
412
|
+
|
|
413
|
+
@apply_ashrae140_assumptions = @hpxml_header.apply_ashrae140_assumptions # Hidden feature
|
|
159
414
|
@apply_ashrae140_assumptions = false if @apply_ashrae140_assumptions.nil?
|
|
160
415
|
|
|
161
416
|
# Here we turn off OS error-checking so that any invalid values provided
|
|
@@ -167,21 +422,14 @@ class OSModel
|
|
|
167
422
|
model.setStrictnessLevel('None'.to_StrictnessLevel)
|
|
168
423
|
|
|
169
424
|
# Init
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
schedules_paths: @hpxml.header.schedules_filepaths,
|
|
174
|
-
year: Location.get_sim_calendar_year(@hpxml.header.sim_calendar_year, epw_file),
|
|
175
|
-
unavailable_periods: @hpxml.header.unavailable_periods,
|
|
176
|
-
output_path: File.join(output_dir, 'in.schedules.csv'))
|
|
177
|
-
set_defaults_and_globals(runner, output_dir, epw_file, weather, @schedules_file)
|
|
178
|
-
validate_emissions_files()
|
|
179
|
-
Location.apply(model, weather, epw_file, @hpxml)
|
|
425
|
+
OpenStudio::Model::WeatherFile.setWeatherFile(model, epw_file)
|
|
426
|
+
set_defaults_and_globals()
|
|
427
|
+
Location.apply(model, weather, epw_file, @hpxml_header, @hpxml_bldg)
|
|
180
428
|
add_simulation_params(model)
|
|
181
429
|
|
|
182
430
|
# Conditioned space/zone
|
|
183
431
|
spaces = {}
|
|
184
|
-
create_or_get_space(model, spaces, HPXML::
|
|
432
|
+
create_or_get_space(model, spaces, HPXML::LocationConditionedSpace)
|
|
185
433
|
set_foundation_and_walls_top()
|
|
186
434
|
set_heating_and_cooling_seasons()
|
|
187
435
|
add_setpoints(runner, model, weather, spaces)
|
|
@@ -197,16 +445,16 @@ class OSModel
|
|
|
197
445
|
add_skylights(model, spaces)
|
|
198
446
|
add_conditioned_floor_area(model, spaces)
|
|
199
447
|
add_thermal_mass(model, spaces)
|
|
200
|
-
Geometry.set_zone_volumes(spaces, @
|
|
201
|
-
Geometry.explode_surfaces(model, @
|
|
448
|
+
Geometry.set_zone_volumes(spaces, @hpxml_bldg, @apply_ashrae140_assumptions)
|
|
449
|
+
Geometry.explode_surfaces(model, @hpxml_bldg, @walls_top)
|
|
202
450
|
add_num_occupants(model, runner, spaces)
|
|
203
451
|
|
|
204
452
|
# HVAC
|
|
205
|
-
@hvac_unavailable_periods = Schedule.get_unavailable_periods(runner, SchedulesFile::ColumnHVAC, @
|
|
453
|
+
@hvac_unavailable_periods = Schedule.get_unavailable_periods(runner, SchedulesFile::ColumnHVAC, @hpxml_header.unavailable_periods)
|
|
206
454
|
airloop_map = {} # Map of HPXML System ID -> AirLoopHVAC (or ZoneHVACFourPipeFanCoil)
|
|
207
455
|
add_ideal_system(model, spaces, epw_path)
|
|
208
|
-
add_cooling_system(model, spaces, airloop_map)
|
|
209
|
-
add_heating_system(runner, model, spaces, airloop_map)
|
|
456
|
+
add_cooling_system(model, weather, spaces, airloop_map)
|
|
457
|
+
add_heating_system(runner, model, weather, spaces, airloop_map)
|
|
210
458
|
add_heat_pump(runner, model, weather, spaces, airloop_map)
|
|
211
459
|
add_dehumidifiers(runner, model, spaces)
|
|
212
460
|
add_ceiling_fans(runner, model, weather, spaces)
|
|
@@ -219,8 +467,8 @@ class OSModel
|
|
|
219
467
|
add_mfls(runner, model, spaces)
|
|
220
468
|
add_lighting(runner, model, epw_file, spaces)
|
|
221
469
|
|
|
222
|
-
# Pools &
|
|
223
|
-
|
|
470
|
+
# Pools & Permanent Spas
|
|
471
|
+
add_pools_and_permanent_spas(runner, model, spaces)
|
|
224
472
|
|
|
225
473
|
# Other
|
|
226
474
|
add_cooling_season(model, weather)
|
|
@@ -228,34 +476,13 @@ class OSModel
|
|
|
228
476
|
add_photovoltaics(model)
|
|
229
477
|
add_generators(model)
|
|
230
478
|
add_batteries(runner, model, spaces)
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
# Output
|
|
234
|
-
add_unmet_hours_output(model, spaces)
|
|
235
|
-
add_loads_output(model, spaces, add_component_loads)
|
|
236
|
-
set_output_files(model)
|
|
237
|
-
# Uncomment to debug EMS
|
|
238
|
-
# add_ems_debug_output(model)
|
|
239
|
-
|
|
240
|
-
if debug
|
|
241
|
-
osm_output_path = File.join(output_dir, 'in.osm')
|
|
242
|
-
File.write(osm_output_path, model.to_s)
|
|
243
|
-
runner.registerInfo("Wrote file: #{osm_output_path}")
|
|
244
|
-
end
|
|
479
|
+
add_building_unit(model, unit_num)
|
|
245
480
|
end
|
|
246
481
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
def self.check_file_references(hpxml_path)
|
|
482
|
+
def check_emissions_references(hpxml_header, hpxml_path)
|
|
250
483
|
# Check/update file references
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
File.dirname(hpxml_path),
|
|
254
|
-
'Schedules')
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
@hpxml.header.emissions_scenarios.each do |scenario|
|
|
258
|
-
if @hpxml.header.emissions_scenarios.select { |s| s.emissions_type == scenario.emissions_type && s.name == scenario.name }.size > 1
|
|
484
|
+
hpxml_header.emissions_scenarios.each do |scenario|
|
|
485
|
+
if hpxml_header.emissions_scenarios.select { |s| s.emissions_type == scenario.emissions_type && s.name == scenario.name }.size > 1
|
|
259
486
|
fail "Found multiple Emissions Scenarios with the Scenario Name=#{scenario.name} and Emissions Type=#{scenario.emissions_type}."
|
|
260
487
|
end
|
|
261
488
|
next if scenario.elec_schedule_filepath.nil?
|
|
@@ -266,8 +493,17 @@ class OSModel
|
|
|
266
493
|
end
|
|
267
494
|
end
|
|
268
495
|
|
|
269
|
-
def
|
|
270
|
-
|
|
496
|
+
def check_schedule_references(hpxml_bldg_header, hpxml_path)
|
|
497
|
+
# Check/update file references
|
|
498
|
+
hpxml_bldg_header.schedules_filepaths = hpxml_bldg_header.schedules_filepaths.collect { |sfp|
|
|
499
|
+
FilePath.check_path(sfp,
|
|
500
|
+
File.dirname(hpxml_path),
|
|
501
|
+
'Schedules')
|
|
502
|
+
}
|
|
503
|
+
end
|
|
504
|
+
|
|
505
|
+
def validate_emissions_files(hpxml_header)
|
|
506
|
+
hpxml_header.emissions_scenarios.each do |scenario|
|
|
271
507
|
next if scenario.elec_schedule_filepath.nil?
|
|
272
508
|
|
|
273
509
|
data = File.readlines(scenario.elec_schedule_filepath)
|
|
@@ -283,76 +519,69 @@ class OSModel
|
|
|
283
519
|
end
|
|
284
520
|
end
|
|
285
521
|
|
|
286
|
-
def
|
|
522
|
+
def set_defaults_and_globals()
|
|
287
523
|
# Initialize
|
|
288
524
|
@remaining_heat_load_frac = 1.0
|
|
289
525
|
@remaining_cool_load_frac = 1.0
|
|
290
526
|
|
|
291
527
|
# Set globals
|
|
292
|
-
@cfa = @
|
|
293
|
-
@ncfl = @
|
|
294
|
-
@ncfl_ag = @
|
|
295
|
-
@nbeds = @
|
|
296
|
-
@default_azimuths = HPXMLDefaults.get_default_azimuths(@
|
|
297
|
-
|
|
298
|
-
# Apply
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
#
|
|
306
|
-
# are zero in order to prevent potential E+ errors.
|
|
307
|
-
HVAC.ensure_nonzero_sizing_values(@hpxml)
|
|
308
|
-
|
|
309
|
-
# Now that we've written in.xml, make adjustments for modeling purposes.
|
|
310
|
-
@frac_windows_operable = @hpxml.fraction_of_windows_operable()
|
|
311
|
-
@hpxml.collapse_enclosure_surfaces() # Speeds up simulation
|
|
312
|
-
@hpxml.delete_adiabatic_subsurfaces() # EnergyPlus doesn't allow this
|
|
528
|
+
@cfa = @hpxml_bldg.building_construction.conditioned_floor_area
|
|
529
|
+
@ncfl = @hpxml_bldg.building_construction.number_of_conditioned_floors
|
|
530
|
+
@ncfl_ag = @hpxml_bldg.building_construction.number_of_conditioned_floors_above_grade
|
|
531
|
+
@nbeds = @hpxml_bldg.building_construction.number_of_bedrooms
|
|
532
|
+
@default_azimuths = HPXMLDefaults.get_default_azimuths(@hpxml_bldg)
|
|
533
|
+
|
|
534
|
+
# Apply unit multipliers to HVAC systems and water heaters
|
|
535
|
+
HVAC.apply_unit_multiplier(@hpxml_bldg)
|
|
536
|
+
# Ensure that no capacities/airflows are zero in order to prevent potential E+ errors.
|
|
537
|
+
HVAC.ensure_nonzero_sizing_values(@hpxml_bldg)
|
|
538
|
+
# Make adjustments for modeling purposes
|
|
539
|
+
@frac_windows_operable = @hpxml_bldg.fraction_of_windows_operable()
|
|
540
|
+
@hpxml_bldg.collapse_enclosure_surfaces() # Speeds up simulation
|
|
541
|
+
@hpxml_bldg.delete_adiabatic_subsurfaces() # EnergyPlus doesn't allow this
|
|
313
542
|
|
|
314
543
|
# We don't want this to be written to in.xml, because then if you ran the in.xml
|
|
315
544
|
# file, you would get different results (operational calculation) relative to the
|
|
316
545
|
# original file (asset calculation).
|
|
317
|
-
if @
|
|
318
|
-
@
|
|
546
|
+
if @hpxml_bldg.building_occupancy.number_of_residents.nil?
|
|
547
|
+
@hpxml_bldg.building_occupancy.number_of_residents = Geometry.get_occupancy_default_num(@nbeds)
|
|
319
548
|
end
|
|
320
549
|
|
|
321
550
|
# If zero occupants, ensure end uses of interest are zeroed out
|
|
322
|
-
if (@
|
|
323
|
-
@
|
|
324
|
-
begin_month: @
|
|
325
|
-
begin_day: @
|
|
551
|
+
if (@hpxml_bldg.building_occupancy.number_of_residents == 0) && (not @apply_ashrae140_assumptions)
|
|
552
|
+
@hpxml_header.unavailable_periods.add(column_name: 'Vacancy',
|
|
553
|
+
begin_month: @hpxml_header.sim_begin_month,
|
|
554
|
+
begin_day: @hpxml_header.sim_begin_day,
|
|
326
555
|
begin_hour: 0,
|
|
327
|
-
end_month: @
|
|
328
|
-
end_day: @
|
|
556
|
+
end_month: @hpxml_header.sim_end_month,
|
|
557
|
+
end_day: @hpxml_header.sim_end_day,
|
|
329
558
|
end_hour: 24,
|
|
330
559
|
natvent_availability: HPXML::ScheduleUnavailable)
|
|
331
560
|
end
|
|
332
561
|
end
|
|
333
562
|
|
|
334
|
-
def
|
|
335
|
-
SimControls.apply(model, @
|
|
563
|
+
def add_simulation_params(model)
|
|
564
|
+
SimControls.apply(model, @hpxml_header)
|
|
336
565
|
end
|
|
337
566
|
|
|
338
|
-
def
|
|
567
|
+
def add_num_occupants(model, runner, spaces)
|
|
339
568
|
# Occupants
|
|
340
|
-
num_occ = @
|
|
569
|
+
num_occ = @hpxml_bldg.building_occupancy.number_of_residents
|
|
341
570
|
return if num_occ <= 0
|
|
342
571
|
|
|
343
|
-
Geometry.apply_occupants(model, runner, @
|
|
344
|
-
@schedules_file, @
|
|
572
|
+
Geometry.apply_occupants(model, runner, @hpxml_bldg, num_occ, spaces[HPXML::LocationConditionedSpace],
|
|
573
|
+
@schedules_file, @hpxml_header.unavailable_periods)
|
|
345
574
|
end
|
|
346
575
|
|
|
347
|
-
def
|
|
576
|
+
def create_or_get_space(model, spaces, location)
|
|
348
577
|
if spaces[location].nil?
|
|
349
|
-
Geometry.create_space_and_zone(model, spaces, location)
|
|
578
|
+
Geometry.create_space_and_zone(model, spaces, location, @hpxml_bldg.building_construction.number_of_units)
|
|
350
579
|
end
|
|
351
580
|
return spaces[location]
|
|
352
581
|
end
|
|
353
582
|
|
|
354
|
-
def
|
|
355
|
-
@
|
|
583
|
+
def add_roofs(runner, model, spaces)
|
|
584
|
+
@hpxml_bldg.roofs.each do |roof|
|
|
356
585
|
next if roof.net_area < 1.0 # skip modeling net surface area for surfaces comprised entirely of subsurface area
|
|
357
586
|
|
|
358
587
|
if roof.azimuth.nil?
|
|
@@ -463,8 +692,8 @@ class OSModel
|
|
|
463
692
|
end
|
|
464
693
|
end
|
|
465
694
|
|
|
466
|
-
def
|
|
467
|
-
@
|
|
695
|
+
def add_walls(runner, model, spaces)
|
|
696
|
+
@hpxml_bldg.walls.each do |wall|
|
|
468
697
|
next if wall.net_area < 1.0 # skip modeling net surface area for surfaces comprised entirely of subsurface area
|
|
469
698
|
|
|
470
699
|
if wall.azimuth.nil?
|
|
@@ -531,8 +760,8 @@ class OSModel
|
|
|
531
760
|
end
|
|
532
761
|
end
|
|
533
762
|
|
|
534
|
-
def
|
|
535
|
-
@
|
|
763
|
+
def add_rim_joists(runner, model, spaces)
|
|
764
|
+
@hpxml_bldg.rim_joists.each do |rim_joist|
|
|
536
765
|
if rim_joist.azimuth.nil?
|
|
537
766
|
if rim_joist.is_exterior
|
|
538
767
|
azimuths = @default_azimuths # Model as four directions for average exterior incident solar
|
|
@@ -603,8 +832,8 @@ class OSModel
|
|
|
603
832
|
end
|
|
604
833
|
end
|
|
605
834
|
|
|
606
|
-
def
|
|
607
|
-
@
|
|
835
|
+
def add_floors(runner, model, spaces)
|
|
836
|
+
@hpxml_bldg.floors.each do |floor|
|
|
608
837
|
area = floor.area
|
|
609
838
|
width = Math::sqrt(area)
|
|
610
839
|
length = area / width
|
|
@@ -632,6 +861,12 @@ class OSModel
|
|
|
632
861
|
surface.setWindExposure('NoWind')
|
|
633
862
|
elsif floor.is_floor
|
|
634
863
|
surface.setSunExposure('NoSun')
|
|
864
|
+
if floor.exterior_adjacent_to == HPXML::LocationManufacturedHomeUnderBelly
|
|
865
|
+
foundation = @hpxml_bldg.foundations.find { |x| x.to_location == floor.exterior_adjacent_to }
|
|
866
|
+
if foundation.belly_wing_skirt_present
|
|
867
|
+
surface.setWindExposure('NoWind')
|
|
868
|
+
end
|
|
869
|
+
end
|
|
635
870
|
end
|
|
636
871
|
|
|
637
872
|
# Apply construction
|
|
@@ -660,7 +895,7 @@ class OSModel
|
|
|
660
895
|
else
|
|
661
896
|
outside_film = Material.AirFilmFloorReduced
|
|
662
897
|
end
|
|
663
|
-
if floor.interior_adjacent_to == HPXML::
|
|
898
|
+
if floor.interior_adjacent_to == HPXML::LocationConditionedSpace
|
|
664
899
|
mat_int_finish_or_covering = Material.CoveringBare
|
|
665
900
|
end
|
|
666
901
|
end
|
|
@@ -671,116 +906,73 @@ class OSModel
|
|
|
671
906
|
end
|
|
672
907
|
end
|
|
673
908
|
|
|
674
|
-
def
|
|
675
|
-
foundation_types = @
|
|
909
|
+
def add_foundation_walls_slabs(runner, model, weather, spaces)
|
|
910
|
+
foundation_types = @hpxml_bldg.slabs.map { |s| s.interior_adjacent_to }.uniq
|
|
676
911
|
|
|
677
912
|
foundation_types.each do |foundation_type|
|
|
678
|
-
# Get attached foundation walls
|
|
679
|
-
fnd_walls = []
|
|
913
|
+
# Get attached slabs/foundation walls
|
|
680
914
|
slabs = []
|
|
681
|
-
@
|
|
682
|
-
next unless foundation_wall.interior_adjacent_to == foundation_type
|
|
683
|
-
next if foundation_wall.net_area < 1.0 # skip modeling net surface area for surfaces comprised entirely of subsurface area
|
|
684
|
-
|
|
685
|
-
fnd_walls << foundation_wall
|
|
686
|
-
end
|
|
687
|
-
@hpxml.slabs.each do |slab|
|
|
915
|
+
@hpxml_bldg.slabs.each do |slab|
|
|
688
916
|
next unless slab.interior_adjacent_to == foundation_type
|
|
689
917
|
|
|
690
918
|
slabs << slab
|
|
691
919
|
slab.exposed_perimeter = [slab.exposed_perimeter, 1.0].max # minimum value to prevent error if no exposed slab
|
|
692
920
|
end
|
|
693
921
|
|
|
694
|
-
# Calculate combinations of slabs/walls for each Kiva instance
|
|
695
|
-
kiva_instances = get_kiva_instances(fnd_walls, slabs)
|
|
696
|
-
|
|
697
|
-
# Obtain some wall/slab information
|
|
698
|
-
fnd_wall_lengths = {}
|
|
699
|
-
fnd_walls.each do |foundation_wall|
|
|
700
|
-
next unless foundation_wall.is_exterior
|
|
701
|
-
|
|
702
|
-
fnd_wall_lengths[foundation_wall] = foundation_wall.area / foundation_wall.height
|
|
703
|
-
end
|
|
704
|
-
slab_exp_perims = {}
|
|
705
|
-
slab_areas = {}
|
|
706
922
|
slabs.each do |slab|
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
end
|
|
710
|
-
total_slab_exp_perim = slab_exp_perims.values.sum(0.0)
|
|
711
|
-
total_slab_area = slab_areas.values.sum(0.0)
|
|
712
|
-
total_fnd_wall_length = fnd_wall_lengths.values.sum(0.0)
|
|
923
|
+
slab_frac = slab.exposed_perimeter / slabs.map { |s| s.exposed_perimeter }.sum
|
|
924
|
+
ext_fnd_walls = slab.connected_foundation_walls.select { |fw| fw.net_area >= 1.0 && fw.is_exterior }
|
|
713
925
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
# Apportion referenced walls/slabs for this Kiva instance
|
|
718
|
-
slab_frac = slab_exp_perims[slab] / total_slab_exp_perim
|
|
719
|
-
if total_fnd_wall_length > 0
|
|
720
|
-
fnd_wall_frac = fnd_wall_lengths[foundation_wall] / total_fnd_wall_length
|
|
926
|
+
if ext_fnd_walls.empty?
|
|
927
|
+
# Slab w/o foundation walls
|
|
928
|
+
add_foundation_slab(model, weather, spaces, slab, -1 * slab.depth_below_grade.to_f, slab.exposed_perimeter, nil)
|
|
721
929
|
else
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
#
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
930
|
+
# Slab w/ foundation walls
|
|
931
|
+
ext_fnd_walls_length = ext_fnd_walls.map { |fw| fw.area / fw.height }.sum
|
|
932
|
+
remaining_exposed_length = slab.exposed_perimeter
|
|
933
|
+
|
|
934
|
+
# Since we don't know which FoundationWalls are adjacent to which Slabs, we apportion
|
|
935
|
+
# each FoundationWall to each slab.
|
|
936
|
+
ext_fnd_walls.each do |fnd_wall|
|
|
937
|
+
# Both the foundation wall and slab must have same exposed length to prevent Kiva errors.
|
|
938
|
+
# For the foundation wall, we are effectively modeling the net *exposed* area.
|
|
939
|
+
fnd_wall_length = fnd_wall.area / fnd_wall.height
|
|
940
|
+
apportioned_exposed_length = fnd_wall_length / ext_fnd_walls_length * slab.exposed_perimeter # Slab exposed perimeter apportioned to this foundation wall
|
|
941
|
+
apportioned_total_length = fnd_wall_length * slab_frac # Foundation wall length apportioned to this slab
|
|
942
|
+
exposed_length = [apportioned_exposed_length, apportioned_total_length].min
|
|
943
|
+
remaining_exposed_length -= exposed_length
|
|
944
|
+
|
|
945
|
+
kiva_foundation = add_foundation_wall(runner, model, spaces, fnd_wall, exposed_length, fnd_wall_length)
|
|
946
|
+
add_foundation_slab(model, weather, spaces, slab, -1 * fnd_wall.depth_below_grade, exposed_length, kiva_foundation)
|
|
947
|
+
end
|
|
731
948
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
no_wall_slab_exp_perim[slab] += (slab_exp_perim - fnd_wall_lengths[foundation_wall] * slab_frac)
|
|
739
|
-
|
|
740
|
-
# Reduce this slab's exposed perimeter so that EnergyPlus does not automatically
|
|
741
|
-
# create a second no-wall Kiva instance for each of our Kiva instances.
|
|
742
|
-
# Instead, we will later create our own Kiva instance to account for it.
|
|
743
|
-
# This reduces the number of Kiva instances we end up with.
|
|
744
|
-
exp_perim_frac = (fnd_wall_lengths[foundation_wall] * slab_frac) / slab_exp_perim
|
|
745
|
-
slab_exp_perim *= exp_perim_frac
|
|
746
|
-
slab_area *= exp_perim_frac
|
|
747
|
-
end
|
|
748
|
-
if not foundation_wall.nil?
|
|
749
|
-
z_origin = -1 * foundation_wall.depth_below_grade # Position based on adjacent foundation walls
|
|
750
|
-
else
|
|
751
|
-
z_origin = -1 * slab.depth_below_grade
|
|
949
|
+
if remaining_exposed_length > 1 # Skip if a small length (e.g., due to rounding)
|
|
950
|
+
# The slab's exposed perimeter exceeds the sum of attached exterior foundation wall lengths.
|
|
951
|
+
# This may legitimately occur for a walkout basement, where a portion of the slab has no
|
|
952
|
+
# adjacent foundation wall.
|
|
953
|
+
add_foundation_slab(model, weather, spaces, slab, 0, remaining_exposed_length, nil)
|
|
954
|
+
end
|
|
752
955
|
end
|
|
753
|
-
add_foundation_slab(model, weather, spaces, slab, slab_exp_perim,
|
|
754
|
-
slab_area, z_origin, kiva_foundation)
|
|
755
|
-
end
|
|
756
|
-
|
|
757
|
-
# For each slab, create a no-wall Kiva slab instance if needed.
|
|
758
|
-
slabs.each do |slab|
|
|
759
|
-
next unless no_wall_slab_exp_perim[slab] > 1.0
|
|
760
|
-
|
|
761
|
-
z_origin = 0
|
|
762
|
-
slab_area = total_slab_area * no_wall_slab_exp_perim[slab] / total_slab_exp_perim
|
|
763
|
-
add_foundation_slab(model, weather, spaces, slab, no_wall_slab_exp_perim[slab],
|
|
764
|
-
slab_area, z_origin, nil)
|
|
765
956
|
end
|
|
766
957
|
|
|
767
958
|
# Interzonal foundation wall surfaces
|
|
768
959
|
# The above-grade portion of these walls are modeled as EnergyPlus surfaces with standard adjacency.
|
|
769
960
|
# The below-grade portion of these walls (in contact with ground) are not modeled, as Kiva does not
|
|
770
961
|
# calculate heat flow between two zones through the ground.
|
|
771
|
-
|
|
772
|
-
|
|
962
|
+
int_fnd_walls = @hpxml_bldg.foundation_walls.select { |fw| fw.is_interior && fw.interior_adjacent_to == foundation_type }
|
|
963
|
+
int_fnd_walls.each do |fnd_wall|
|
|
964
|
+
next unless fnd_wall.is_interior
|
|
773
965
|
|
|
774
|
-
ag_height =
|
|
775
|
-
ag_net_area =
|
|
966
|
+
ag_height = fnd_wall.height - fnd_wall.depth_below_grade
|
|
967
|
+
ag_net_area = fnd_wall.net_area * ag_height / fnd_wall.height
|
|
776
968
|
next if ag_net_area < 1.0
|
|
777
969
|
|
|
778
970
|
length = ag_net_area / ag_height
|
|
779
971
|
z_origin = -1 * ag_height
|
|
780
|
-
if
|
|
972
|
+
if fnd_wall.azimuth.nil?
|
|
781
973
|
azimuth = @default_azimuths[0] # Arbitrary direction, doesn't receive exterior incident solar
|
|
782
974
|
else
|
|
783
|
-
azimuth =
|
|
975
|
+
azimuth = fnd_wall.azimuth
|
|
784
976
|
end
|
|
785
977
|
|
|
786
978
|
vertices = Geometry.create_wall_vertices(length, ag_height, z_origin, azimuth)
|
|
@@ -789,10 +981,10 @@ class OSModel
|
|
|
789
981
|
surface.additionalProperties.setFeature('Azimuth', azimuth)
|
|
790
982
|
surface.additionalProperties.setFeature('Tilt', 90.0)
|
|
791
983
|
surface.additionalProperties.setFeature('SurfaceType', 'FoundationWall')
|
|
792
|
-
surface.setName(
|
|
984
|
+
surface.setName(fnd_wall.id)
|
|
793
985
|
surface.setSurfaceType('Wall')
|
|
794
|
-
set_surface_interior(model, spaces, surface,
|
|
795
|
-
set_surface_exterior(model, spaces, surface,
|
|
986
|
+
set_surface_interior(model, spaces, surface, fnd_wall)
|
|
987
|
+
set_surface_exterior(model, spaces, surface, fnd_wall)
|
|
796
988
|
surface.setSunExposure('NoSun')
|
|
797
989
|
surface.setWindExposure('NoWind')
|
|
798
990
|
|
|
@@ -801,57 +993,50 @@ class OSModel
|
|
|
801
993
|
wall_type = HPXML::WallTypeConcrete
|
|
802
994
|
inside_film = Material.AirFilmVertical
|
|
803
995
|
outside_film = Material.AirFilmVertical
|
|
804
|
-
assembly_r =
|
|
805
|
-
mat_int_finish = Material.InteriorFinishMaterial(
|
|
996
|
+
assembly_r = fnd_wall.insulation_assembly_r_value
|
|
997
|
+
mat_int_finish = Material.InteriorFinishMaterial(fnd_wall.interior_finish_type, fnd_wall.interior_finish_thickness)
|
|
806
998
|
if assembly_r.nil?
|
|
807
|
-
concrete_thick_in =
|
|
808
|
-
int_r =
|
|
809
|
-
ext_r =
|
|
999
|
+
concrete_thick_in = fnd_wall.thickness
|
|
1000
|
+
int_r = fnd_wall.insulation_interior_r_value
|
|
1001
|
+
ext_r = fnd_wall.insulation_exterior_r_value
|
|
810
1002
|
mat_concrete = Material.Concrete(concrete_thick_in)
|
|
811
1003
|
mat_int_finish_rvalue = mat_int_finish.nil? ? 0.0 : mat_int_finish.rvalue
|
|
812
1004
|
assembly_r = int_r + ext_r + mat_concrete.rvalue + mat_int_finish_rvalue + inside_film.rvalue + outside_film.rvalue
|
|
813
1005
|
end
|
|
814
1006
|
mat_ext_finish = nil
|
|
815
1007
|
|
|
816
|
-
Constructions.apply_wall_construction(runner, model, [surface],
|
|
1008
|
+
Constructions.apply_wall_construction(runner, model, [surface], fnd_wall.id, wall_type, assembly_r,
|
|
817
1009
|
mat_int_finish, inside_film, outside_film, mat_ext_finish, nil, nil)
|
|
818
1010
|
end
|
|
819
1011
|
end
|
|
820
1012
|
end
|
|
821
1013
|
|
|
822
|
-
def
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
gross_area = foundation_wall.area * slab_frac
|
|
1014
|
+
def add_foundation_wall(runner, model, spaces, foundation_wall, exposed_length, fnd_wall_length)
|
|
1015
|
+
exposed_fraction = exposed_length / fnd_wall_length
|
|
1016
|
+
net_exposed_area = foundation_wall.net_area * exposed_fraction
|
|
1017
|
+
gross_exposed_area = foundation_wall.area * exposed_fraction
|
|
827
1018
|
height = foundation_wall.height
|
|
828
1019
|
height_ag = height - foundation_wall.depth_below_grade
|
|
829
1020
|
z_origin = -1 * foundation_wall.depth_below_grade
|
|
830
|
-
length = gross_area / height
|
|
831
1021
|
if foundation_wall.azimuth.nil?
|
|
832
1022
|
azimuth = @default_azimuths[0] # Arbitrary; solar incidence in Kiva is applied as an orientation average (to the above grade portion of the wall)
|
|
833
1023
|
else
|
|
834
1024
|
azimuth = foundation_wall.azimuth
|
|
835
1025
|
end
|
|
836
1026
|
|
|
837
|
-
if
|
|
838
|
-
# Calculate exposed section of wall based on slab's total exposed perimeter.
|
|
839
|
-
length *= total_slab_exp_perim / total_fnd_wall_length
|
|
840
|
-
end
|
|
1027
|
+
return if exposed_length < 0.1 # Avoid Kiva error if exposed wall length is too small
|
|
841
1028
|
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
if gross_area > net_area
|
|
1029
|
+
if gross_exposed_area > net_exposed_area
|
|
845
1030
|
# Create a "notch" in the wall to account for the subsurfaces. This ensures that
|
|
846
1031
|
# we preserve the appropriate wall height, length, and area for Kiva.
|
|
847
|
-
subsurface_area =
|
|
1032
|
+
subsurface_area = gross_exposed_area - net_exposed_area
|
|
848
1033
|
else
|
|
849
1034
|
subsurface_area = 0
|
|
850
1035
|
end
|
|
851
1036
|
|
|
852
|
-
vertices = Geometry.create_wall_vertices(
|
|
1037
|
+
vertices = Geometry.create_wall_vertices(exposed_length, height, z_origin, azimuth, subsurface_area: subsurface_area)
|
|
853
1038
|
surface = OpenStudio::Model::Surface.new(vertices, model)
|
|
854
|
-
surface.additionalProperties.setFeature('Length',
|
|
1039
|
+
surface.additionalProperties.setFeature('Length', exposed_length)
|
|
855
1040
|
surface.additionalProperties.setFeature('Azimuth', azimuth)
|
|
856
1041
|
surface.additionalProperties.setFeature('Tilt', 90.0)
|
|
857
1042
|
surface.additionalProperties.setFeature('SurfaceType', 'FoundationWall')
|
|
@@ -893,7 +1078,7 @@ class OSModel
|
|
|
893
1078
|
int_rigid_r = foundation_wall.insulation_interior_r_value
|
|
894
1079
|
end
|
|
895
1080
|
|
|
896
|
-
soil_k_in = UnitConversions.convert(@
|
|
1081
|
+
soil_k_in = UnitConversions.convert(@hpxml_bldg.site.ground_conductivity, 'ft', 'in')
|
|
897
1082
|
|
|
898
1083
|
Constructions.apply_foundation_wall(model, [surface], "#{foundation_wall.id} construction",
|
|
899
1084
|
ext_rigid_offset, int_rigid_offset, ext_rigid_height, int_rigid_height,
|
|
@@ -907,10 +1092,10 @@ class OSModel
|
|
|
907
1092
|
return surface.adjacentFoundation.get
|
|
908
1093
|
end
|
|
909
1094
|
|
|
910
|
-
def
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1095
|
+
def add_foundation_slab(model, weather, spaces, slab, z_origin, exposed_length, kiva_foundation)
|
|
1096
|
+
exposed_fraction = exposed_length / slab.exposed_perimeter
|
|
1097
|
+
slab_tot_perim = exposed_length
|
|
1098
|
+
slab_area = slab.area * exposed_fraction
|
|
914
1099
|
if slab_tot_perim**2 - 16.0 * slab_area <= 0
|
|
915
1100
|
# Cannot construct rectangle with this perimeter/area. Some of the
|
|
916
1101
|
# perimeter is presumably not exposed, so bump up perimeter value.
|
|
@@ -961,18 +1146,18 @@ class OSModel
|
|
|
961
1146
|
mat_carpet = Material.CoveringBare(slab.carpet_fraction,
|
|
962
1147
|
slab.carpet_r_value)
|
|
963
1148
|
end
|
|
964
|
-
soil_k_in = UnitConversions.convert(@
|
|
1149
|
+
soil_k_in = UnitConversions.convert(@hpxml_bldg.site.ground_conductivity, 'ft', 'in')
|
|
965
1150
|
|
|
966
1151
|
Constructions.apply_foundation_slab(model, surface, "#{slab.id} construction",
|
|
967
1152
|
slab_under_r, slab_under_width, slab_gap_r, slab_perim_r,
|
|
968
1153
|
slab_perim_depth, slab_whole_r, slab.thickness,
|
|
969
|
-
|
|
1154
|
+
exposed_length, mat_carpet, soil_k_in, kiva_foundation)
|
|
970
1155
|
|
|
971
1156
|
kiva_foundation = surface.adjacentFoundation.get
|
|
972
1157
|
|
|
973
1158
|
foundation_walls_insulated = false
|
|
974
1159
|
foundation_ceiling_insulated = false
|
|
975
|
-
@
|
|
1160
|
+
@hpxml_bldg.foundation_walls.each do |fnd_wall|
|
|
976
1161
|
next unless fnd_wall.interior_adjacent_to == slab.interior_adjacent_to
|
|
977
1162
|
next unless fnd_wall.exterior_adjacent_to == HPXML::LocationGround
|
|
978
1163
|
|
|
@@ -982,8 +1167,8 @@ class OSModel
|
|
|
982
1167
|
foundation_walls_insulated = true
|
|
983
1168
|
end
|
|
984
1169
|
end
|
|
985
|
-
@
|
|
986
|
-
next unless floor.interior_adjacent_to == HPXML::
|
|
1170
|
+
@hpxml_bldg.floors.each do |floor|
|
|
1171
|
+
next unless floor.interior_adjacent_to == HPXML::LocationConditionedSpace
|
|
987
1172
|
next unless floor.exterior_adjacent_to == slab.interior_adjacent_to
|
|
988
1173
|
|
|
989
1174
|
if floor.insulation_assembly_r_value > 5
|
|
@@ -992,29 +1177,29 @@ class OSModel
|
|
|
992
1177
|
end
|
|
993
1178
|
|
|
994
1179
|
Constructions.apply_kiva_initial_temp(kiva_foundation, slab, weather,
|
|
995
|
-
spaces[HPXML::
|
|
996
|
-
@
|
|
997
|
-
@
|
|
1180
|
+
spaces[HPXML::LocationConditionedSpace].thermalZone.get,
|
|
1181
|
+
@hpxml_header.sim_begin_month, @hpxml_header.sim_begin_day,
|
|
1182
|
+
@hpxml_header.sim_calendar_year, @schedules_file,
|
|
998
1183
|
foundation_walls_insulated, foundation_ceiling_insulated)
|
|
999
1184
|
|
|
1000
1185
|
return kiva_foundation
|
|
1001
1186
|
end
|
|
1002
1187
|
|
|
1003
|
-
def
|
|
1188
|
+
def add_conditioned_floor_area(model, spaces)
|
|
1004
1189
|
# Check if we need to add floors between conditioned spaces (e.g., between first
|
|
1005
1190
|
# and second story or conditioned basement ceiling).
|
|
1006
1191
|
# This ensures that the E+ reported Conditioned Floor Area is correct.
|
|
1007
1192
|
|
|
1008
1193
|
sum_cfa = 0.0
|
|
1009
|
-
@
|
|
1194
|
+
@hpxml_bldg.floors.each do |floor|
|
|
1010
1195
|
next unless floor.is_floor
|
|
1011
|
-
next unless [HPXML::
|
|
1012
|
-
[HPXML::
|
|
1196
|
+
next unless [HPXML::LocationConditionedSpace, HPXML::LocationBasementConditioned].include?(floor.interior_adjacent_to) ||
|
|
1197
|
+
[HPXML::LocationConditionedSpace, HPXML::LocationBasementConditioned].include?(floor.exterior_adjacent_to)
|
|
1013
1198
|
|
|
1014
1199
|
sum_cfa += floor.area
|
|
1015
1200
|
end
|
|
1016
|
-
@
|
|
1017
|
-
next unless [HPXML::
|
|
1201
|
+
@hpxml_bldg.slabs.each do |slab|
|
|
1202
|
+
next unless [HPXML::LocationConditionedSpace, HPXML::LocationBasementConditioned].include? slab.interior_adjacent_to
|
|
1018
1203
|
|
|
1019
1204
|
sum_cfa += slab.area
|
|
1020
1205
|
end
|
|
@@ -1037,7 +1222,7 @@ class OSModel
|
|
|
1037
1222
|
floor_surface.setWindExposure('NoWind')
|
|
1038
1223
|
floor_surface.setName('inferred conditioned floor')
|
|
1039
1224
|
floor_surface.setSurfaceType('Floor')
|
|
1040
|
-
floor_surface.setSpace(create_or_get_space(model, spaces, HPXML::
|
|
1225
|
+
floor_surface.setSpace(create_or_get_space(model, spaces, HPXML::LocationConditionedSpace))
|
|
1041
1226
|
floor_surface.setOutsideBoundaryCondition('Adiabatic')
|
|
1042
1227
|
floor_surface.additionalProperties.setFeature('SurfaceType', 'InferredFloor')
|
|
1043
1228
|
floor_surface.additionalProperties.setFeature('Tilt', 0.0)
|
|
@@ -1050,7 +1235,7 @@ class OSModel
|
|
|
1050
1235
|
ceiling_surface.setWindExposure('NoWind')
|
|
1051
1236
|
ceiling_surface.setName('inferred conditioned ceiling')
|
|
1052
1237
|
ceiling_surface.setSurfaceType('RoofCeiling')
|
|
1053
|
-
ceiling_surface.setSpace(create_or_get_space(model, spaces, HPXML::
|
|
1238
|
+
ceiling_surface.setSpace(create_or_get_space(model, spaces, HPXML::LocationConditionedSpace))
|
|
1054
1239
|
ceiling_surface.setOutsideBoundaryCondition('Adiabatic')
|
|
1055
1240
|
ceiling_surface.additionalProperties.setFeature('SurfaceType', 'InferredCeiling')
|
|
1056
1241
|
ceiling_surface.additionalProperties.setFeature('Tilt', 0.0)
|
|
@@ -1059,22 +1244,22 @@ class OSModel
|
|
|
1059
1244
|
apply_adiabatic_construction(model, [floor_surface, ceiling_surface], 'floor')
|
|
1060
1245
|
end
|
|
1061
1246
|
|
|
1062
|
-
def
|
|
1247
|
+
def add_thermal_mass(model, spaces)
|
|
1063
1248
|
if @apply_ashrae140_assumptions
|
|
1064
1249
|
# 1024 ft2 of interior partition wall mass, no furniture mass
|
|
1065
1250
|
mat_int_finish = Material.InteriorFinishMaterial(HPXML::InteriorFinishGypsumBoard, 0.5)
|
|
1066
1251
|
partition_wall_area = 1024.0 * 2 # Exposed partition wall area (both sides)
|
|
1067
1252
|
Constructions.apply_partition_walls(model, 'PartitionWallConstruction', mat_int_finish, partition_wall_area, spaces)
|
|
1068
1253
|
else
|
|
1069
|
-
mat_int_finish = Material.InteriorFinishMaterial(@
|
|
1070
|
-
partition_wall_area = @
|
|
1254
|
+
mat_int_finish = Material.InteriorFinishMaterial(@hpxml_bldg.partition_wall_mass.interior_finish_type, @hpxml_bldg.partition_wall_mass.interior_finish_thickness)
|
|
1255
|
+
partition_wall_area = @hpxml_bldg.partition_wall_mass.area_fraction * @cfa # Exposed partition wall area (both sides)
|
|
1071
1256
|
Constructions.apply_partition_walls(model, 'PartitionWallConstruction', mat_int_finish, partition_wall_area, spaces)
|
|
1072
1257
|
|
|
1073
|
-
Constructions.apply_furniture(model, @
|
|
1258
|
+
Constructions.apply_furniture(model, @hpxml_bldg.furniture_mass, spaces)
|
|
1074
1259
|
end
|
|
1075
1260
|
end
|
|
1076
1261
|
|
|
1077
|
-
def
|
|
1262
|
+
def add_cooling_season(model, weather)
|
|
1078
1263
|
# Create cooling season schedule
|
|
1079
1264
|
# Applies to natural ventilation and calculation of component loads, not HVAC equipment
|
|
1080
1265
|
# Uses BAHSP cooling season, not user-specified cooling season (which may be, e.g., year-round)
|
|
@@ -1086,22 +1271,20 @@ class OSModel
|
|
|
1086
1271
|
@clg_ssn_sensor.setKeyName(clg_season_sch.schedule.name.to_s)
|
|
1087
1272
|
end
|
|
1088
1273
|
|
|
1089
|
-
def
|
|
1274
|
+
def add_windows(model, spaces)
|
|
1090
1275
|
# We already stored @fraction_of_windows_operable, so lets remove the
|
|
1091
1276
|
# fraction_operable properties from windows and re-collapse the enclosure
|
|
1092
1277
|
# so as to prevent potentially modeling multiple identical windows in E+,
|
|
1093
1278
|
# which can increase simulation runtime.
|
|
1094
|
-
@
|
|
1279
|
+
@hpxml_bldg.windows.each do |window|
|
|
1095
1280
|
window.fraction_operable = nil
|
|
1096
1281
|
end
|
|
1097
|
-
@
|
|
1282
|
+
@hpxml_bldg.collapse_enclosure_surfaces()
|
|
1098
1283
|
|
|
1099
|
-
shading_group = nil
|
|
1100
1284
|
shading_schedules = {}
|
|
1101
|
-
shading_ems = { sensors: {}, program: nil }
|
|
1102
1285
|
|
|
1103
1286
|
surfaces = []
|
|
1104
|
-
@
|
|
1287
|
+
@hpxml_bldg.windows.each do |window|
|
|
1105
1288
|
window_height = 4.0 # ft, default
|
|
1106
1289
|
|
|
1107
1290
|
overhang_depth = nil
|
|
@@ -1142,16 +1325,14 @@ class OSModel
|
|
|
1142
1325
|
|
|
1143
1326
|
if not overhang_depth.nil?
|
|
1144
1327
|
overhang = sub_surface.addOverhang(UnitConversions.convert(overhang_depth, 'ft', 'm'), UnitConversions.convert(overhang_distance_to_top, 'ft', 'm'))
|
|
1145
|
-
overhang.get.setName("#{sub_surface.name}
|
|
1328
|
+
overhang.get.setName("#{sub_surface.name} overhangs")
|
|
1146
1329
|
end
|
|
1147
1330
|
|
|
1148
1331
|
# Apply construction
|
|
1149
1332
|
Constructions.apply_window(model, sub_surface, 'WindowConstruction', ufactor, shgc)
|
|
1150
1333
|
|
|
1151
1334
|
# Apply interior/exterior shading (as needed)
|
|
1152
|
-
|
|
1153
|
-
shading_group = Constructions.apply_window_skylight_shading(model, window, i, shading_vertices, surface, sub_surface, shading_group,
|
|
1154
|
-
shading_schedules, shading_ems, Constants.ObjectNameWindowShade, @hpxml)
|
|
1335
|
+
Constructions.apply_window_skylight_shading(model, window, sub_surface, shading_schedules, @hpxml_header, @hpxml_bldg)
|
|
1155
1336
|
else
|
|
1156
1337
|
# Window is on an interior surface, which E+ does not allow. Model
|
|
1157
1338
|
# as a door instead so that we can get the appropriate conduction
|
|
@@ -1188,14 +1369,11 @@ class OSModel
|
|
|
1188
1369
|
apply_adiabatic_construction(model, surfaces, 'wall')
|
|
1189
1370
|
end
|
|
1190
1371
|
|
|
1191
|
-
def
|
|
1372
|
+
def add_skylights(model, spaces)
|
|
1192
1373
|
surfaces = []
|
|
1193
|
-
|
|
1194
|
-
shading_group = nil
|
|
1195
1374
|
shading_schedules = {}
|
|
1196
|
-
shading_ems = { sensors: {}, program: nil }
|
|
1197
1375
|
|
|
1198
|
-
@
|
|
1376
|
+
@hpxml_bldg.skylights.each do |skylight|
|
|
1199
1377
|
tilt = skylight.roof.pitch / 12.0
|
|
1200
1378
|
width = Math::sqrt(skylight.area)
|
|
1201
1379
|
length = skylight.area / width
|
|
@@ -1213,7 +1391,7 @@ class OSModel
|
|
|
1213
1391
|
surface.additionalProperties.setFeature('SurfaceType', 'Skylight')
|
|
1214
1392
|
surface.setName("surface #{skylight.id}")
|
|
1215
1393
|
surface.setSurfaceType('RoofCeiling')
|
|
1216
|
-
surface.setSpace(create_or_get_space(model, spaces, HPXML::
|
|
1394
|
+
surface.setSpace(create_or_get_space(model, spaces, HPXML::LocationConditionedSpace)) # Ensures it is included in Manual J sizing
|
|
1217
1395
|
surface.setOutsideBoundaryCondition('Outdoors') # cannot be adiabatic because subsurfaces won't be created
|
|
1218
1396
|
surfaces << surface
|
|
1219
1397
|
|
|
@@ -1227,17 +1405,15 @@ class OSModel
|
|
|
1227
1405
|
Constructions.apply_skylight(model, sub_surface, 'SkylightConstruction', ufactor, shgc)
|
|
1228
1406
|
|
|
1229
1407
|
# Apply interior/exterior shading (as needed)
|
|
1230
|
-
|
|
1231
|
-
shading_group = Constructions.apply_window_skylight_shading(model, skylight, i, shading_vertices, surface, sub_surface, shading_group,
|
|
1232
|
-
shading_schedules, shading_ems, Constants.ObjectNameSkylightShade, @hpxml)
|
|
1408
|
+
Constructions.apply_window_skylight_shading(model, skylight, sub_surface, shading_schedules, @hpxml_header, @hpxml_bldg)
|
|
1233
1409
|
end
|
|
1234
1410
|
|
|
1235
1411
|
apply_adiabatic_construction(model, surfaces, 'roof')
|
|
1236
1412
|
end
|
|
1237
1413
|
|
|
1238
|
-
def
|
|
1414
|
+
def add_doors(model, spaces)
|
|
1239
1415
|
surfaces = []
|
|
1240
|
-
@
|
|
1416
|
+
@hpxml_bldg.doors.each do |door|
|
|
1241
1417
|
door_height = 6.67 # ft
|
|
1242
1418
|
door_length = door.area / door_height
|
|
1243
1419
|
z_origin = @foundation_top
|
|
@@ -1277,7 +1453,7 @@ class OSModel
|
|
|
1277
1453
|
apply_adiabatic_construction(model, surfaces, 'wall')
|
|
1278
1454
|
end
|
|
1279
1455
|
|
|
1280
|
-
def
|
|
1456
|
+
def apply_adiabatic_construction(model, surfaces, type)
|
|
1281
1457
|
# Arbitrary construction for heat capacitance.
|
|
1282
1458
|
# Only applies to surfaces where outside boundary conditioned is
|
|
1283
1459
|
# adiabatic or surface net area is near zero.
|
|
@@ -1302,80 +1478,81 @@ class OSModel
|
|
|
1302
1478
|
end
|
|
1303
1479
|
end
|
|
1304
1480
|
|
|
1305
|
-
def
|
|
1481
|
+
def add_hot_water_and_appliances(runner, model, weather, spaces)
|
|
1306
1482
|
# Assign spaces
|
|
1307
|
-
@
|
|
1483
|
+
@hpxml_bldg.clothes_washers.each do |clothes_washer|
|
|
1308
1484
|
clothes_washer.additional_properties.space = get_space_from_location(clothes_washer.location, spaces)
|
|
1309
1485
|
end
|
|
1310
|
-
@
|
|
1486
|
+
@hpxml_bldg.clothes_dryers.each do |clothes_dryer|
|
|
1311
1487
|
clothes_dryer.additional_properties.space = get_space_from_location(clothes_dryer.location, spaces)
|
|
1312
1488
|
end
|
|
1313
|
-
@
|
|
1489
|
+
@hpxml_bldg.dishwashers.each do |dishwasher|
|
|
1314
1490
|
dishwasher.additional_properties.space = get_space_from_location(dishwasher.location, spaces)
|
|
1315
1491
|
end
|
|
1316
|
-
@
|
|
1492
|
+
@hpxml_bldg.refrigerators.each do |refrigerator|
|
|
1317
1493
|
refrigerator.additional_properties.space = get_space_from_location(refrigerator.location, spaces)
|
|
1318
1494
|
end
|
|
1319
|
-
@
|
|
1495
|
+
@hpxml_bldg.freezers.each do |freezer|
|
|
1320
1496
|
freezer.additional_properties.space = get_space_from_location(freezer.location, spaces)
|
|
1321
1497
|
end
|
|
1322
|
-
@
|
|
1498
|
+
@hpxml_bldg.cooking_ranges.each do |cooking_range|
|
|
1323
1499
|
cooking_range.additional_properties.space = get_space_from_location(cooking_range.location, spaces)
|
|
1324
1500
|
end
|
|
1325
1501
|
|
|
1326
1502
|
# Distribution
|
|
1327
|
-
if @
|
|
1328
|
-
hot_water_distribution = @
|
|
1503
|
+
if @hpxml_bldg.water_heating_systems.size > 0
|
|
1504
|
+
hot_water_distribution = @hpxml_bldg.hot_water_distributions[0]
|
|
1329
1505
|
end
|
|
1330
1506
|
|
|
1331
1507
|
# Solar thermal system
|
|
1332
1508
|
solar_thermal_system = nil
|
|
1333
|
-
if @
|
|
1334
|
-
solar_thermal_system = @
|
|
1509
|
+
if @hpxml_bldg.solar_thermal_systems.size > 0
|
|
1510
|
+
solar_thermal_system = @hpxml_bldg.solar_thermal_systems[0]
|
|
1335
1511
|
end
|
|
1336
1512
|
|
|
1337
1513
|
# Water Heater
|
|
1338
|
-
unavailable_periods = Schedule.get_unavailable_periods(runner, SchedulesFile::ColumnWaterHeater, @
|
|
1339
|
-
|
|
1514
|
+
unavailable_periods = Schedule.get_unavailable_periods(runner, SchedulesFile::ColumnWaterHeater, @hpxml_header.unavailable_periods)
|
|
1515
|
+
unit_multiplier = @hpxml_bldg.building_construction.number_of_units
|
|
1516
|
+
has_uncond_bsmnt = @hpxml_bldg.has_location(HPXML::LocationBasementUnconditioned)
|
|
1340
1517
|
plantloop_map = {}
|
|
1341
|
-
@
|
|
1518
|
+
@hpxml_bldg.water_heating_systems.each do |water_heating_system|
|
|
1342
1519
|
loc_space, loc_schedule = get_space_or_schedule_from_location(water_heating_system.location, model, spaces)
|
|
1343
1520
|
|
|
1344
1521
|
ec_adj = HotWaterAndAppliances.get_dist_energy_consumption_adjustment(has_uncond_bsmnt, @cfa, @ncfl, water_heating_system, hot_water_distribution)
|
|
1345
1522
|
|
|
1346
1523
|
sys_id = water_heating_system.id
|
|
1347
1524
|
if water_heating_system.water_heater_type == HPXML::WaterHeaterTypeStorage
|
|
1348
|
-
plantloop_map[sys_id] = Waterheater.apply_tank(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods)
|
|
1525
|
+
plantloop_map[sys_id] = Waterheater.apply_tank(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods, unit_multiplier)
|
|
1349
1526
|
elsif water_heating_system.water_heater_type == HPXML::WaterHeaterTypeTankless
|
|
1350
|
-
plantloop_map[sys_id] = Waterheater.apply_tankless(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods)
|
|
1527
|
+
plantloop_map[sys_id] = Waterheater.apply_tankless(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods, unit_multiplier)
|
|
1351
1528
|
elsif water_heating_system.water_heater_type == HPXML::WaterHeaterTypeHeatPump
|
|
1352
|
-
|
|
1353
|
-
plantloop_map[sys_id] = Waterheater.apply_heatpump(model, runner, loc_space, loc_schedule, weather, water_heating_system, ec_adj, solar_thermal_system,
|
|
1529
|
+
conditioned_zone = spaces[HPXML::LocationConditionedSpace].thermalZone.get
|
|
1530
|
+
plantloop_map[sys_id] = Waterheater.apply_heatpump(model, runner, loc_space, loc_schedule, weather, water_heating_system, ec_adj, solar_thermal_system, conditioned_zone, @eri_version, @schedules_file, unavailable_periods, unit_multiplier)
|
|
1354
1531
|
elsif [HPXML::WaterHeaterTypeCombiStorage, HPXML::WaterHeaterTypeCombiTankless].include? water_heating_system.water_heater_type
|
|
1355
|
-
plantloop_map[sys_id] = Waterheater.apply_combi(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods)
|
|
1532
|
+
plantloop_map[sys_id] = Waterheater.apply_combi(model, runner, loc_space, loc_schedule, water_heating_system, ec_adj, solar_thermal_system, @eri_version, @schedules_file, unavailable_periods, unit_multiplier)
|
|
1356
1533
|
else
|
|
1357
1534
|
fail "Unhandled water heater (#{water_heating_system.water_heater_type})."
|
|
1358
1535
|
end
|
|
1359
1536
|
end
|
|
1360
1537
|
|
|
1361
1538
|
# Hot water fixtures and appliances
|
|
1362
|
-
HotWaterAndAppliances.apply(model, runner, @
|
|
1539
|
+
HotWaterAndAppliances.apply(model, runner, @hpxml_header, @hpxml_bldg, weather, spaces, hot_water_distribution,
|
|
1363
1540
|
solar_thermal_system, @eri_version, @schedules_file, plantloop_map,
|
|
1364
|
-
@
|
|
1541
|
+
@hpxml_header.unavailable_periods, @hpxml_bldg.building_construction.number_of_units)
|
|
1365
1542
|
|
|
1366
1543
|
if (not solar_thermal_system.nil?) && (not solar_thermal_system.collector_area.nil?) # Detailed solar water heater
|
|
1367
1544
|
loc_space, loc_schedule = get_space_or_schedule_from_location(solar_thermal_system.water_heating_system.location, model, spaces)
|
|
1368
|
-
Waterheater.apply_solar_thermal(model, loc_space, loc_schedule, solar_thermal_system, plantloop_map)
|
|
1545
|
+
Waterheater.apply_solar_thermal(model, loc_space, loc_schedule, solar_thermal_system, plantloop_map, unit_multiplier)
|
|
1369
1546
|
end
|
|
1370
1547
|
|
|
1371
1548
|
# Add combi-system EMS program with water use equipment information
|
|
1372
|
-
Waterheater.apply_combi_system_EMS(model, @
|
|
1549
|
+
Waterheater.apply_combi_system_EMS(model, @hpxml_bldg.water_heating_systems, plantloop_map)
|
|
1373
1550
|
end
|
|
1374
1551
|
|
|
1375
|
-
def
|
|
1376
|
-
|
|
1552
|
+
def add_cooling_system(model, weather, spaces, airloop_map)
|
|
1553
|
+
conditioned_zone = spaces[HPXML::LocationConditionedSpace].thermalZone.get
|
|
1377
1554
|
|
|
1378
|
-
HVAC.get_hpxml_hvac_systems(@
|
|
1555
|
+
HVAC.get_hpxml_hvac_systems(@hpxml_bldg).each do |hvac_system|
|
|
1379
1556
|
next if hvac_system[:cooling].nil?
|
|
1380
1557
|
next unless hvac_system[:cooling].is_a? HPXML::CoolingSystem
|
|
1381
1558
|
|
|
@@ -1405,22 +1582,23 @@ class OSModel
|
|
|
1405
1582
|
HPXML::HVACTypeMiniSplitAirConditioner,
|
|
1406
1583
|
HPXML::HVACTypePTAC].include? cooling_system.cooling_system_type
|
|
1407
1584
|
|
|
1408
|
-
airloop_map[sys_id] = HVAC.apply_air_source_hvac_systems(model, cooling_system, heating_system,
|
|
1409
|
-
|
|
1410
|
-
|
|
1585
|
+
airloop_map[sys_id] = HVAC.apply_air_source_hvac_systems(model, cooling_system, heating_system, sequential_cool_load_fracs, sequential_heat_load_fracs,
|
|
1586
|
+
weather.data.AnnualMaxDrybulb, weather.data.AnnualMinDrybulb,
|
|
1587
|
+
conditioned_zone, @hvac_unavailable_periods)
|
|
1411
1588
|
|
|
1412
1589
|
elsif [HPXML::HVACTypeEvaporativeCooler].include? cooling_system.cooling_system_type
|
|
1413
1590
|
|
|
1414
|
-
airloop_map[sys_id] = HVAC.apply_evaporative_cooler(model, cooling_system,
|
|
1415
|
-
|
|
1591
|
+
airloop_map[sys_id] = HVAC.apply_evaporative_cooler(model, cooling_system, sequential_cool_load_fracs,
|
|
1592
|
+
conditioned_zone, @hvac_unavailable_periods,
|
|
1593
|
+
@hpxml_bldg.building_construction.number_of_units)
|
|
1416
1594
|
end
|
|
1417
1595
|
end
|
|
1418
1596
|
end
|
|
1419
1597
|
|
|
1420
|
-
def
|
|
1421
|
-
|
|
1598
|
+
def add_heating_system(runner, model, weather, spaces, airloop_map)
|
|
1599
|
+
conditioned_zone = spaces[HPXML::LocationConditionedSpace].thermalZone.get
|
|
1422
1600
|
|
|
1423
|
-
HVAC.get_hpxml_hvac_systems(@
|
|
1601
|
+
HVAC.get_hpxml_hvac_systems(@hpxml_bldg).each do |hvac_system|
|
|
1424
1602
|
next if hvac_system[:heating].nil?
|
|
1425
1603
|
next unless hvac_system[:heating].is_a? HPXML::HeatingSystem
|
|
1426
1604
|
|
|
@@ -1449,43 +1627,42 @@ class OSModel
|
|
|
1449
1627
|
sys_id = heating_system.id
|
|
1450
1628
|
if [HPXML::HVACTypeFurnace].include? heating_system.heating_system_type
|
|
1451
1629
|
|
|
1452
|
-
airloop_map[sys_id] = HVAC.apply_air_source_hvac_systems(model, nil, heating_system,
|
|
1453
|
-
|
|
1454
|
-
|
|
1630
|
+
airloop_map[sys_id] = HVAC.apply_air_source_hvac_systems(model, nil, heating_system, [0], sequential_heat_load_fracs,
|
|
1631
|
+
weather.data.AnnualMaxDrybulb, weather.data.AnnualMinDrybulb,
|
|
1632
|
+
conditioned_zone, @hvac_unavailable_periods)
|
|
1455
1633
|
|
|
1456
1634
|
elsif [HPXML::HVACTypeBoiler].include? heating_system.heating_system_type
|
|
1457
1635
|
|
|
1458
|
-
airloop_map[sys_id] = HVAC.apply_boiler(model, runner, heating_system,
|
|
1459
|
-
|
|
1636
|
+
airloop_map[sys_id] = HVAC.apply_boiler(model, runner, heating_system, sequential_heat_load_fracs, conditioned_zone,
|
|
1637
|
+
@hvac_unavailable_periods)
|
|
1460
1638
|
|
|
1461
1639
|
elsif [HPXML::HVACTypeElectricResistance].include? heating_system.heating_system_type
|
|
1462
1640
|
|
|
1463
1641
|
HVAC.apply_electric_baseboard(model, heating_system,
|
|
1464
|
-
sequential_heat_load_fracs,
|
|
1642
|
+
sequential_heat_load_fracs, conditioned_zone, @hvac_unavailable_periods)
|
|
1465
1643
|
|
|
1466
1644
|
elsif [HPXML::HVACTypeStove,
|
|
1467
|
-
HPXML::
|
|
1468
|
-
HPXML::HVACTypeFixedHeater,
|
|
1645
|
+
HPXML::HVACTypeSpaceHeater,
|
|
1469
1646
|
HPXML::HVACTypeWallFurnace,
|
|
1470
1647
|
HPXML::HVACTypeFloorFurnace,
|
|
1471
1648
|
HPXML::HVACTypeFireplace].include? heating_system.heating_system_type
|
|
1472
1649
|
|
|
1473
1650
|
HVAC.apply_unit_heater(model, heating_system,
|
|
1474
|
-
sequential_heat_load_fracs,
|
|
1651
|
+
sequential_heat_load_fracs, conditioned_zone, @hvac_unavailable_periods)
|
|
1475
1652
|
end
|
|
1476
1653
|
|
|
1477
1654
|
next unless heating_system.is_heat_pump_backup_system
|
|
1478
1655
|
|
|
1479
1656
|
# Store OS object for later use
|
|
1480
|
-
equipment_list = model.getZoneHVACEquipmentLists.find { |el| el.thermalZone ==
|
|
1657
|
+
equipment_list = model.getZoneHVACEquipmentLists.find { |el| el.thermalZone == conditioned_zone }
|
|
1481
1658
|
@heat_pump_backup_system_object = equipment_list.equipment[-1]
|
|
1482
1659
|
end
|
|
1483
1660
|
end
|
|
1484
1661
|
|
|
1485
|
-
def
|
|
1486
|
-
|
|
1662
|
+
def add_heat_pump(runner, model, weather, spaces, airloop_map)
|
|
1663
|
+
conditioned_zone = spaces[HPXML::LocationConditionedSpace].thermalZone.get
|
|
1487
1664
|
|
|
1488
|
-
HVAC.get_hpxml_hvac_systems(@
|
|
1665
|
+
HVAC.get_hpxml_hvac_systems(@hpxml_bldg).each do |hvac_system|
|
|
1489
1666
|
next if hvac_system[:cooling].nil?
|
|
1490
1667
|
next unless hvac_system[:cooling].is_a? HPXML::HeatPump
|
|
1491
1668
|
|
|
@@ -1506,26 +1683,27 @@ class OSModel
|
|
|
1506
1683
|
|
|
1507
1684
|
airloop_map[sys_id] = HVAC.apply_water_loop_to_air_heat_pump(model, heat_pump,
|
|
1508
1685
|
sequential_heat_load_fracs, sequential_cool_load_fracs,
|
|
1509
|
-
|
|
1686
|
+
conditioned_zone, @hvac_unavailable_periods)
|
|
1510
1687
|
|
|
1511
1688
|
elsif [HPXML::HVACTypeHeatPumpAirToAir,
|
|
1512
1689
|
HPXML::HVACTypeHeatPumpMiniSplit,
|
|
1513
1690
|
HPXML::HVACTypeHeatPumpPTHP,
|
|
1514
1691
|
HPXML::HVACTypeHeatPumpRoom].include? heat_pump.heat_pump_type
|
|
1515
|
-
airloop_map[sys_id] = HVAC.apply_air_source_hvac_systems(model, heat_pump, heat_pump,
|
|
1516
|
-
|
|
1517
|
-
|
|
1692
|
+
airloop_map[sys_id] = HVAC.apply_air_source_hvac_systems(model, heat_pump, heat_pump, sequential_cool_load_fracs, sequential_heat_load_fracs,
|
|
1693
|
+
weather.data.AnnualMaxDrybulb, weather.data.AnnualMinDrybulb,
|
|
1694
|
+
conditioned_zone, @hvac_unavailable_periods)
|
|
1518
1695
|
elsif [HPXML::HVACTypeHeatPumpGroundToAir].include? heat_pump.heat_pump_type
|
|
1519
1696
|
|
|
1520
1697
|
airloop_map[sys_id] = HVAC.apply_ground_to_air_heat_pump(model, runner, weather, heat_pump,
|
|
1521
1698
|
sequential_heat_load_fracs, sequential_cool_load_fracs,
|
|
1522
|
-
|
|
1699
|
+
conditioned_zone, @hpxml_bldg.site.ground_conductivity, @hvac_unavailable_periods,
|
|
1700
|
+
@hpxml_bldg.building_construction.number_of_units)
|
|
1523
1701
|
|
|
1524
1702
|
end
|
|
1525
1703
|
|
|
1526
|
-
next
|
|
1704
|
+
next if heat_pump.backup_system.nil?
|
|
1527
1705
|
|
|
1528
|
-
equipment_list = model.getZoneHVACEquipmentLists.find { |el| el.thermalZone ==
|
|
1706
|
+
equipment_list = model.getZoneHVACEquipmentLists.find { |el| el.thermalZone == conditioned_zone }
|
|
1529
1707
|
|
|
1530
1708
|
# Set priority to be last (i.e., after the heat pump that it is backup for)
|
|
1531
1709
|
equipment_list.setHeatingPriority(@heat_pump_backup_system_object, 99)
|
|
@@ -1533,14 +1711,13 @@ class OSModel
|
|
|
1533
1711
|
end
|
|
1534
1712
|
end
|
|
1535
1713
|
|
|
1536
|
-
def
|
|
1714
|
+
def add_ideal_system(model, spaces, epw_path)
|
|
1537
1715
|
# Adds an ideal air system as needed to meet the load under certain circumstances:
|
|
1538
1716
|
# 1. the sum of fractions load served is less than 1, or
|
|
1539
1717
|
# 2. we're using an ideal air system for e.g. ASHRAE 140 loads calculation.
|
|
1540
|
-
|
|
1541
|
-
obj_name = Constants.ObjectNameIdealAirSystem
|
|
1718
|
+
conditioned_zone = spaces[HPXML::LocationConditionedSpace].thermalZone.get
|
|
1542
1719
|
|
|
1543
|
-
if @apply_ashrae140_assumptions && (@
|
|
1720
|
+
if @apply_ashrae140_assumptions && (@hpxml_bldg.total_fraction_heat_load_served + @hpxml_bldg.total_fraction_heat_load_served == 0.0)
|
|
1544
1721
|
cooling_load_frac = 1.0
|
|
1545
1722
|
heating_load_frac = 1.0
|
|
1546
1723
|
if @apply_ashrae140_assumptions
|
|
@@ -1552,56 +1729,57 @@ class OSModel
|
|
|
1552
1729
|
fail 'Unexpected weather file for ASHRAE 140 run.'
|
|
1553
1730
|
end
|
|
1554
1731
|
end
|
|
1555
|
-
HVAC.apply_ideal_air_loads(model,
|
|
1556
|
-
|
|
1732
|
+
HVAC.apply_ideal_air_loads(model, [cooling_load_frac], [heating_load_frac],
|
|
1733
|
+
conditioned_zone, @hvac_unavailable_periods)
|
|
1557
1734
|
return
|
|
1558
1735
|
end
|
|
1559
1736
|
|
|
1560
|
-
if (@
|
|
1561
|
-
sequential_heat_load_fracs = HVAC.calc_sequential_load_fractions(@remaining_heat_load_frac - @
|
|
1562
|
-
@remaining_heat_load_frac -= (1.0 - @
|
|
1737
|
+
if (@hpxml_bldg.total_fraction_heat_load_served < 1.0) && (@hpxml_bldg.total_fraction_heat_load_served > 0.0)
|
|
1738
|
+
sequential_heat_load_fracs = HVAC.calc_sequential_load_fractions(@remaining_heat_load_frac - @hpxml_bldg.total_fraction_heat_load_served, @remaining_heat_load_frac, @heating_days)
|
|
1739
|
+
@remaining_heat_load_frac -= (1.0 - @hpxml_bldg.total_fraction_heat_load_served)
|
|
1563
1740
|
else
|
|
1564
1741
|
sequential_heat_load_fracs = [0.0]
|
|
1565
1742
|
end
|
|
1566
1743
|
|
|
1567
|
-
if (@
|
|
1568
|
-
sequential_cool_load_fracs = HVAC.calc_sequential_load_fractions(@remaining_cool_load_frac - @
|
|
1569
|
-
@remaining_cool_load_frac -= (1.0 - @
|
|
1744
|
+
if (@hpxml_bldg.total_fraction_cool_load_served < 1.0) && (@hpxml_bldg.total_fraction_cool_load_served > 0.0)
|
|
1745
|
+
sequential_cool_load_fracs = HVAC.calc_sequential_load_fractions(@remaining_cool_load_frac - @hpxml_bldg.total_fraction_cool_load_served, @remaining_cool_load_frac, @cooling_days)
|
|
1746
|
+
@remaining_cool_load_frac -= (1.0 - @hpxml_bldg.total_fraction_cool_load_served)
|
|
1570
1747
|
else
|
|
1571
1748
|
sequential_cool_load_fracs = [0.0]
|
|
1572
1749
|
end
|
|
1573
1750
|
|
|
1574
1751
|
if (sequential_heat_load_fracs.sum > 0.0) || (sequential_cool_load_fracs.sum > 0.0)
|
|
1575
|
-
HVAC.apply_ideal_air_loads(model,
|
|
1576
|
-
|
|
1752
|
+
HVAC.apply_ideal_air_loads(model, sequential_cool_load_fracs, sequential_heat_load_fracs,
|
|
1753
|
+
conditioned_zone, @hvac_unavailable_periods)
|
|
1577
1754
|
end
|
|
1578
1755
|
end
|
|
1579
1756
|
|
|
1580
|
-
def
|
|
1581
|
-
return if @
|
|
1757
|
+
def add_setpoints(runner, model, weather, spaces)
|
|
1758
|
+
return if @hpxml_bldg.hvac_controls.size == 0
|
|
1582
1759
|
|
|
1583
|
-
hvac_control = @
|
|
1584
|
-
|
|
1585
|
-
has_ceiling_fan = (@
|
|
1760
|
+
hvac_control = @hpxml_bldg.hvac_controls[0]
|
|
1761
|
+
conditioned_zone = spaces[HPXML::LocationConditionedSpace].thermalZone.get
|
|
1762
|
+
has_ceiling_fan = (@hpxml_bldg.ceiling_fans.size > 0)
|
|
1586
1763
|
|
|
1587
|
-
HVAC.apply_setpoints(model, runner, weather, hvac_control,
|
|
1764
|
+
HVAC.apply_setpoints(model, runner, weather, hvac_control, conditioned_zone, has_ceiling_fan, @heating_days, @cooling_days, @hpxml_header.sim_calendar_year, @schedules_file)
|
|
1588
1765
|
end
|
|
1589
1766
|
|
|
1590
|
-
def
|
|
1591
|
-
return if @
|
|
1767
|
+
def add_ceiling_fans(runner, model, weather, spaces)
|
|
1768
|
+
return if @hpxml_bldg.ceiling_fans.size == 0
|
|
1592
1769
|
|
|
1593
|
-
ceiling_fan = @
|
|
1594
|
-
HVAC.apply_ceiling_fans(model, runner, weather, ceiling_fan, spaces[HPXML::
|
|
1595
|
-
@schedules_file, @
|
|
1770
|
+
ceiling_fan = @hpxml_bldg.ceiling_fans[0]
|
|
1771
|
+
HVAC.apply_ceiling_fans(model, runner, weather, ceiling_fan, spaces[HPXML::LocationConditionedSpace],
|
|
1772
|
+
@schedules_file, @hpxml_header.unavailable_periods)
|
|
1596
1773
|
end
|
|
1597
1774
|
|
|
1598
|
-
def
|
|
1599
|
-
return if @
|
|
1775
|
+
def add_dehumidifiers(runner, model, spaces)
|
|
1776
|
+
return if @hpxml_bldg.dehumidifiers.size == 0
|
|
1600
1777
|
|
|
1601
|
-
HVAC.apply_dehumidifiers(runner, model, @
|
|
1778
|
+
HVAC.apply_dehumidifiers(runner, model, @hpxml_bldg.dehumidifiers, spaces[HPXML::LocationConditionedSpace], @hpxml_header.unavailable_periods,
|
|
1779
|
+
@hpxml_bldg.building_construction.number_of_units)
|
|
1602
1780
|
end
|
|
1603
1781
|
|
|
1604
|
-
def
|
|
1782
|
+
def check_distribution_system(hvac_distribution, system_type)
|
|
1605
1783
|
return if hvac_distribution.nil?
|
|
1606
1784
|
|
|
1607
1785
|
hvac_distribution_type_map = { HPXML::HVACTypeFurnace => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
|
|
@@ -1619,9 +1797,9 @@ class OSModel
|
|
|
1619
1797
|
end
|
|
1620
1798
|
end
|
|
1621
1799
|
|
|
1622
|
-
def
|
|
1800
|
+
def add_mels(runner, model, spaces)
|
|
1623
1801
|
# Misc
|
|
1624
|
-
@
|
|
1802
|
+
@hpxml_bldg.plug_loads.each do |plug_load|
|
|
1625
1803
|
if plug_load.plug_load_type == HPXML::PlugLoadTypeOther
|
|
1626
1804
|
obj_name = Constants.ObjectNameMiscPlugLoads
|
|
1627
1805
|
elsif plug_load.plug_load_type == HPXML::PlugLoadTypeTelevision
|
|
@@ -1636,14 +1814,14 @@ class OSModel
|
|
|
1636
1814
|
next
|
|
1637
1815
|
end
|
|
1638
1816
|
|
|
1639
|
-
MiscLoads.apply_plug(model, runner, plug_load, obj_name, spaces[HPXML::
|
|
1640
|
-
@schedules_file, @
|
|
1817
|
+
MiscLoads.apply_plug(model, runner, plug_load, obj_name, spaces[HPXML::LocationConditionedSpace], @apply_ashrae140_assumptions,
|
|
1818
|
+
@schedules_file, @hpxml_header.unavailable_periods)
|
|
1641
1819
|
end
|
|
1642
1820
|
end
|
|
1643
1821
|
|
|
1644
|
-
def
|
|
1822
|
+
def add_mfls(runner, model, spaces)
|
|
1645
1823
|
# Misc
|
|
1646
|
-
@
|
|
1824
|
+
@hpxml_bldg.fuel_loads.each do |fuel_load|
|
|
1647
1825
|
if fuel_load.fuel_load_type == HPXML::FuelLoadTypeGrill
|
|
1648
1826
|
obj_name = Constants.ObjectNameMiscGrill
|
|
1649
1827
|
elsif fuel_load.fuel_load_type == HPXML::FuelLoadTypeLighting
|
|
@@ -1656,44 +1834,33 @@ class OSModel
|
|
|
1656
1834
|
next
|
|
1657
1835
|
end
|
|
1658
1836
|
|
|
1659
|
-
MiscLoads.apply_fuel(model, runner, fuel_load, obj_name, spaces[HPXML::
|
|
1660
|
-
@schedules_file, @
|
|
1837
|
+
MiscLoads.apply_fuel(model, runner, fuel_load, obj_name, spaces[HPXML::LocationConditionedSpace],
|
|
1838
|
+
@schedules_file, @hpxml_header.unavailable_periods)
|
|
1661
1839
|
end
|
|
1662
1840
|
end
|
|
1663
1841
|
|
|
1664
|
-
def
|
|
1665
|
-
Lighting.apply(runner, model, epw_file, spaces, @
|
|
1666
|
-
@schedules_file, @cfa, @
|
|
1842
|
+
def add_lighting(runner, model, epw_file, spaces)
|
|
1843
|
+
Lighting.apply(runner, model, epw_file, spaces, @hpxml_bldg.lighting_groups, @hpxml_bldg.lighting, @eri_version,
|
|
1844
|
+
@schedules_file, @cfa, @hpxml_header.unavailable_periods, @hpxml_bldg.building_construction.number_of_units)
|
|
1667
1845
|
end
|
|
1668
1846
|
|
|
1669
|
-
def
|
|
1670
|
-
@
|
|
1671
|
-
next if
|
|
1847
|
+
def add_pools_and_permanent_spas(runner, model, spaces)
|
|
1848
|
+
(@hpxml_bldg.pools + @hpxml_bldg.permanent_spas).each do |pool_or_spa|
|
|
1849
|
+
next if pool_or_spa.type == HPXML::TypeNone
|
|
1672
1850
|
|
|
1673
|
-
MiscLoads.
|
|
1674
|
-
|
|
1675
|
-
next if
|
|
1851
|
+
MiscLoads.apply_pool_or_permanent_spa_heater(runner, model, pool_or_spa, spaces[HPXML::LocationConditionedSpace],
|
|
1852
|
+
@schedules_file, @hpxml_header.unavailable_periods)
|
|
1853
|
+
next if pool_or_spa.pump_type == HPXML::TypeNone
|
|
1676
1854
|
|
|
1677
|
-
MiscLoads.
|
|
1678
|
-
|
|
1679
|
-
end
|
|
1680
|
-
|
|
1681
|
-
@hpxml.hot_tubs.each do |hot_tub|
|
|
1682
|
-
next if hot_tub.type == HPXML::TypeNone
|
|
1683
|
-
|
|
1684
|
-
MiscLoads.apply_pool_or_hot_tub_heater(runner, model, hot_tub, Constants.ObjectNameMiscHotTubHeater, spaces[HPXML::LocationLivingSpace],
|
|
1685
|
-
@schedules_file, @hpxml.header.unavailable_periods)
|
|
1686
|
-
next if hot_tub.pump_type == HPXML::TypeNone
|
|
1687
|
-
|
|
1688
|
-
MiscLoads.apply_pool_or_hot_tub_pump(runner, model, hot_tub, Constants.ObjectNameMiscHotTubPump, spaces[HPXML::LocationLivingSpace],
|
|
1689
|
-
@schedules_file, @hpxml.header.unavailable_periods)
|
|
1855
|
+
MiscLoads.apply_pool_or_permanent_spa_pump(runner, model, pool_or_spa, spaces[HPXML::LocationConditionedSpace],
|
|
1856
|
+
@schedules_file, @hpxml_header.unavailable_periods)
|
|
1690
1857
|
end
|
|
1691
1858
|
end
|
|
1692
1859
|
|
|
1693
|
-
def
|
|
1860
|
+
def add_airflow(runner, model, weather, spaces, airloop_map)
|
|
1694
1861
|
# Ducts
|
|
1695
1862
|
duct_systems = {}
|
|
1696
|
-
@
|
|
1863
|
+
@hpxml_bldg.hvac_distributions.each do |hvac_distribution|
|
|
1697
1864
|
next unless hvac_distribution.distribution_system_type == HPXML::HVACDistributionTypeAir
|
|
1698
1865
|
|
|
1699
1866
|
air_ducts = create_ducts(model, hvac_distribution, spaces)
|
|
@@ -1721,24 +1888,50 @@ class OSModel
|
|
|
1721
1888
|
end
|
|
1722
1889
|
end
|
|
1723
1890
|
|
|
1891
|
+
# Duct leakage to outside warnings?
|
|
1892
|
+
# Need to check here instead of in schematron in case duct locations are defaulted
|
|
1893
|
+
@hpxml_bldg.hvac_distributions.each do |hvac_distribution|
|
|
1894
|
+
next unless hvac_distribution.distribution_system_type == HPXML::HVACDistributionTypeAir
|
|
1895
|
+
next if hvac_distribution.duct_leakage_measurements.empty?
|
|
1896
|
+
|
|
1897
|
+
# Skip if there's a duct outside conditioned space
|
|
1898
|
+
next if hvac_distribution.ducts.select { |d| !HPXML::conditioned_locations_this_unit.include?(d.duct_location) }.size > 0
|
|
1899
|
+
|
|
1900
|
+
# Issue warning if duct leakage to outside above a certain threshold and ducts completely in conditioned space
|
|
1901
|
+
issue_warning = false
|
|
1902
|
+
units = hvac_distribution.duct_leakage_measurements[0].duct_leakage_units
|
|
1903
|
+
lto_measurements = hvac_distribution.duct_leakage_measurements.select { |dlm| dlm.duct_leakage_total_or_to_outside == HPXML::DuctLeakageToOutside }
|
|
1904
|
+
sum_lto = lto_measurements.map { |dlm| dlm.duct_leakage_value }.sum(0.0)
|
|
1905
|
+
if units == HPXML::UnitsCFM25
|
|
1906
|
+
issue_warning = true if sum_lto > 0.04 * @cfa
|
|
1907
|
+
elsif units == HPXML::UnitsCFM50
|
|
1908
|
+
issue_warning = true if sum_lto > 0.06 * @cfa
|
|
1909
|
+
elsif units == HPXML::UnitsPercent
|
|
1910
|
+
issue_warning = true if sum_lto > 0.05
|
|
1911
|
+
end
|
|
1912
|
+
next unless issue_warning
|
|
1913
|
+
|
|
1914
|
+
runner.registerWarning('Ducts are entirely within conditioned space but there is moderate leakage to the outside. Leakage to the outside is typically zero or near-zero in these situations, consider revising leakage values. Leakage will be modeled as heat lost to the ambient environment.')
|
|
1915
|
+
end
|
|
1916
|
+
|
|
1724
1917
|
# Create HVAC availability sensor
|
|
1725
|
-
|
|
1918
|
+
hvac_availability_sensor = nil
|
|
1726
1919
|
if not @hvac_unavailable_periods.empty?
|
|
1727
1920
|
avail_sch = ScheduleConstant.new(model, SchedulesFile::ColumnHVAC, 1.0, Constants.ScheduleTypeLimitsFraction, unavailable_periods: @hvac_unavailable_periods)
|
|
1728
|
-
avail_sch = avail_sch.schedule
|
|
1729
1921
|
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1922
|
+
hvac_availability_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Schedule Value')
|
|
1923
|
+
hvac_availability_sensor.setName('hvac availability s')
|
|
1924
|
+
hvac_availability_sensor.setKeyName(avail_sch.schedule.name.to_s)
|
|
1925
|
+
hvac_availability_sensor.additionalProperties.setFeature('ObjectType', Constants.ObjectNameHVACAvailabilitySensor)
|
|
1733
1926
|
end
|
|
1734
1927
|
|
|
1735
|
-
Airflow.apply(model, runner, weather, spaces, @
|
|
1928
|
+
Airflow.apply(model, runner, weather, spaces, @hpxml_header, @hpxml_bldg, @cfa, @nbeds,
|
|
1736
1929
|
@ncfl_ag, duct_systems, airloop_map, @clg_ssn_sensor, @eri_version,
|
|
1737
1930
|
@frac_windows_operable, @apply_ashrae140_assumptions, @schedules_file,
|
|
1738
|
-
@
|
|
1931
|
+
@hpxml_header.unavailable_periods, hvac_availability_sensor)
|
|
1739
1932
|
end
|
|
1740
1933
|
|
|
1741
|
-
def
|
|
1934
|
+
def create_ducts(model, hvac_distribution, spaces)
|
|
1742
1935
|
air_ducts = []
|
|
1743
1936
|
|
|
1744
1937
|
# Duct leakage (supply/return => [value, units])
|
|
@@ -1817,96 +2010,131 @@ class OSModel
|
|
|
1817
2010
|
return air_ducts
|
|
1818
2011
|
end
|
|
1819
2012
|
|
|
1820
|
-
def
|
|
1821
|
-
@
|
|
1822
|
-
next if pv_system.inverter.inverter_efficiency == @
|
|
2013
|
+
def add_photovoltaics(model)
|
|
2014
|
+
@hpxml_bldg.pv_systems.each do |pv_system|
|
|
2015
|
+
next if pv_system.inverter.inverter_efficiency == @hpxml_bldg.pv_systems[0].inverter.inverter_efficiency
|
|
1823
2016
|
|
|
1824
2017
|
fail 'Expected all InverterEfficiency values to be equal.'
|
|
1825
2018
|
end
|
|
1826
|
-
@
|
|
1827
|
-
PV.apply(model, @nbeds, pv_system)
|
|
2019
|
+
@hpxml_bldg.pv_systems.each do |pv_system|
|
|
2020
|
+
PV.apply(model, @nbeds, pv_system, @hpxml_bldg.building_construction.number_of_units)
|
|
1828
2021
|
end
|
|
1829
2022
|
end
|
|
1830
2023
|
|
|
1831
|
-
def
|
|
1832
|
-
@
|
|
1833
|
-
Generator.apply(model, @nbeds, generator)
|
|
2024
|
+
def add_generators(model)
|
|
2025
|
+
@hpxml_bldg.generators.each do |generator|
|
|
2026
|
+
Generator.apply(model, @nbeds, generator, @hpxml_bldg.building_construction.number_of_units)
|
|
1834
2027
|
end
|
|
1835
2028
|
end
|
|
1836
2029
|
|
|
1837
|
-
def
|
|
1838
|
-
@
|
|
2030
|
+
def add_batteries(runner, model, spaces)
|
|
2031
|
+
@hpxml_bldg.batteries.each do |battery|
|
|
1839
2032
|
# Assign space
|
|
1840
2033
|
battery.additional_properties.space = get_space_from_location(battery.location, spaces)
|
|
1841
|
-
Battery.apply(runner, model, @
|
|
2034
|
+
Battery.apply(runner, model, @hpxml_bldg.pv_systems, battery, @schedules_file, @hpxml_bldg.building_construction.number_of_units)
|
|
1842
2035
|
end
|
|
1843
2036
|
end
|
|
1844
2037
|
|
|
1845
|
-
def
|
|
2038
|
+
def add_building_unit(model, unit_num)
|
|
2039
|
+
return if unit_num.nil?
|
|
2040
|
+
|
|
2041
|
+
unit = OpenStudio::Model::BuildingUnit.new(model)
|
|
2042
|
+
unit.additionalProperties.setFeature('unit_num', unit_num)
|
|
2043
|
+
model.getSpaces.each do |s|
|
|
2044
|
+
s.setBuildingUnit(unit)
|
|
2045
|
+
end
|
|
2046
|
+
end
|
|
2047
|
+
|
|
2048
|
+
def add_additional_properties(model, hpxml, hpxml_osm_map, hpxml_path, building_id, epw_file, hpxml_defaults_path)
|
|
1846
2049
|
# Store some data for use in reporting measure
|
|
1847
2050
|
additionalProperties = model.getBuilding.additionalProperties
|
|
1848
2051
|
additionalProperties.setFeature('hpxml_path', hpxml_path)
|
|
1849
|
-
additionalProperties.setFeature('hpxml_defaults_path',
|
|
2052
|
+
additionalProperties.setFeature('hpxml_defaults_path', hpxml_defaults_path)
|
|
1850
2053
|
additionalProperties.setFeature('building_id', building_id.to_s)
|
|
1851
|
-
emissions_scenario_names
|
|
1852
|
-
additionalProperties.setFeature('
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
2054
|
+
additionalProperties.setFeature('emissions_scenario_names', hpxml.header.emissions_scenarios.map { |s| s.name }.to_s)
|
|
2055
|
+
additionalProperties.setFeature('emissions_scenario_types', hpxml.header.emissions_scenarios.map { |s| s.emissions_type }.to_s)
|
|
2056
|
+
heated_zones, cooled_zones = [], []
|
|
2057
|
+
hpxml_osm_map.each do |hpxml_bldg, unit_model|
|
|
2058
|
+
conditioned_zone_name = unit_model.getThermalZones.find { |z| z.additionalProperties.getFeatureAsString('ObjectType').to_s == HPXML::LocationConditionedSpace }.name.to_s
|
|
2059
|
+
|
|
2060
|
+
heated_zones << conditioned_zone_name if hpxml_bldg.total_fraction_heat_load_served > 0
|
|
2061
|
+
cooled_zones << conditioned_zone_name if hpxml_bldg.total_fraction_cool_load_served > 0
|
|
2062
|
+
end
|
|
2063
|
+
additionalProperties.setFeature('heated_zones', heated_zones.to_s)
|
|
2064
|
+
additionalProperties.setFeature('cooled_zones', cooled_zones.to_s)
|
|
1857
2065
|
additionalProperties.setFeature('is_southern_hemisphere', epw_file.latitude < 0)
|
|
1858
2066
|
end
|
|
1859
2067
|
|
|
1860
|
-
def
|
|
2068
|
+
def add_unmet_hours_output(model, hpxml_osm_map)
|
|
1861
2069
|
# We do our own unmet hours calculation via EMS so that we can incorporate,
|
|
1862
|
-
# e.g., heating/cooling seasons into the logic.
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
2070
|
+
# e.g., heating/cooling seasons into the logic. The calculation layers on top
|
|
2071
|
+
# of the built-in EnergyPlus unmet hours output.
|
|
2072
|
+
|
|
2073
|
+
# Create sensors and gather data
|
|
2074
|
+
htg_sensors, clg_sensors = {}, {}
|
|
2075
|
+
total_heat_load_serveds, total_cool_load_serveds = {}, {}
|
|
2076
|
+
htg_start_days, htg_end_days, clg_start_days, clg_end_days = {}, {}, {}, {}
|
|
2077
|
+
hpxml_osm_map.each_with_index do |(hpxml_bldg, unit_model), unit|
|
|
2078
|
+
conditioned_zone_name = unit_model.getThermalZones.find { |z| z.additionalProperties.getFeatureAsString('ObjectType').to_s == HPXML::LocationConditionedSpace }.name.to_s
|
|
2079
|
+
|
|
2080
|
+
# EMS sensors
|
|
2081
|
+
htg_sensors[unit] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Heating Setpoint Not Met Time')
|
|
2082
|
+
htg_sensors[unit].setName('zone htg unmet s')
|
|
2083
|
+
htg_sensors[unit].setKeyName(conditioned_zone_name)
|
|
1871
2084
|
|
|
1872
|
-
|
|
2085
|
+
clg_sensors[unit] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Cooling Setpoint Not Met Time')
|
|
2086
|
+
clg_sensors[unit].setName('zone clg unmet s')
|
|
2087
|
+
clg_sensors[unit].setKeyName(conditioned_zone_name)
|
|
1873
2088
|
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
htg_sensor.setName('zone htg unmet s')
|
|
1877
|
-
htg_sensor.setKeyName(living_zone.name.to_s)
|
|
2089
|
+
total_heat_load_serveds[unit] = hpxml_bldg.total_fraction_heat_load_served
|
|
2090
|
+
total_cool_load_serveds[unit] = hpxml_bldg.total_fraction_cool_load_served
|
|
1878
2091
|
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
2092
|
+
hvac_control = hpxml_bldg.hvac_controls[0]
|
|
2093
|
+
next unless not hvac_control.nil?
|
|
2094
|
+
|
|
2095
|
+
sim_year = @hpxml_header.sim_calendar_year
|
|
2096
|
+
htg_start_days[unit] = Schedule.get_day_num_from_month_day(sim_year, hvac_control.seasons_heating_begin_month, hvac_control.seasons_heating_begin_day)
|
|
2097
|
+
htg_end_days[unit] = Schedule.get_day_num_from_month_day(sim_year, hvac_control.seasons_heating_end_month, hvac_control.seasons_heating_end_day)
|
|
2098
|
+
clg_start_days[unit] = Schedule.get_day_num_from_month_day(sim_year, hvac_control.seasons_cooling_begin_month, hvac_control.seasons_cooling_begin_day)
|
|
2099
|
+
clg_end_days[unit] = Schedule.get_day_num_from_month_day(sim_year, hvac_control.seasons_cooling_end_month, hvac_control.seasons_cooling_end_day)
|
|
2100
|
+
end
|
|
2101
|
+
|
|
2102
|
+
hvac_availability_sensor = model.getEnergyManagementSystemSensors.find { |s| s.additionalProperties.getFeatureAsString('ObjectType').to_s == Constants.ObjectNameHVACAvailabilitySensor }
|
|
1882
2103
|
|
|
1883
2104
|
# EMS program
|
|
1884
2105
|
clg_hrs = 'clg_unmet_hours'
|
|
1885
2106
|
htg_hrs = 'htg_unmet_hours'
|
|
1886
2107
|
program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
|
|
1887
|
-
program.setName(
|
|
2108
|
+
program.setName('unmet hours program')
|
|
2109
|
+
program.additionalProperties.setFeature('ObjectType', Constants.ObjectNameUnmetHoursProgram)
|
|
1888
2110
|
program.addLine("Set #{htg_hrs} = 0")
|
|
1889
2111
|
program.addLine("Set #{clg_hrs} = 0")
|
|
1890
|
-
|
|
1891
|
-
if
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
2112
|
+
for unit in 0..hpxml_osm_map.size - 1
|
|
2113
|
+
if total_heat_load_serveds[unit] > 0
|
|
2114
|
+
if htg_end_days[unit] >= htg_start_days[unit]
|
|
2115
|
+
line = "If ((DayOfYear >= #{htg_start_days[unit]}) && (DayOfYear <= #{htg_end_days[unit]}))"
|
|
2116
|
+
else
|
|
2117
|
+
line = "If ((DayOfYear >= #{htg_start_days[unit]}) || (DayOfYear <= #{htg_end_days[unit]}))"
|
|
2118
|
+
end
|
|
2119
|
+
line += " && (#{hvac_availability_sensor.name} == 1)" if not hvac_availability_sensor.nil?
|
|
2120
|
+
program.addLine(line)
|
|
2121
|
+
program.addLine(" If #{htg_sensors[unit].name} > #{htg_hrs}") # Use max hourly value across all units
|
|
2122
|
+
program.addLine(" Set #{htg_hrs} = #{htg_sensors[unit].name}")
|
|
2123
|
+
program.addLine(' EndIf')
|
|
2124
|
+
program.addLine('EndIf')
|
|
1895
2125
|
end
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
end
|
|
1901
|
-
if @hpxml.total_fraction_cool_load_served > 0
|
|
1902
|
-
if clg_end_day >= clg_start_day
|
|
1903
|
-
line = "If ((DayOfYear >= #{clg_start_day}) && (DayOfYear <= #{clg_end_day}))"
|
|
2126
|
+
next unless total_cool_load_serveds[unit] > 0
|
|
2127
|
+
|
|
2128
|
+
if clg_end_days[unit] >= clg_start_days[unit]
|
|
2129
|
+
line = "If ((DayOfYear >= #{clg_start_days[unit]}) && (DayOfYear <= #{clg_end_days[unit]}))"
|
|
1904
2130
|
else
|
|
1905
|
-
line = "If ((DayOfYear >= #{
|
|
2131
|
+
line = "If ((DayOfYear >= #{clg_start_days[unit]}) || (DayOfYear <= #{clg_end_days[unit]}))"
|
|
1906
2132
|
end
|
|
1907
|
-
line += " && (#{
|
|
2133
|
+
line += " && (#{hvac_availability_sensor.name} == 1)" if not hvac_availability_sensor.nil?
|
|
1908
2134
|
program.addLine(line)
|
|
1909
|
-
program.addLine("
|
|
2135
|
+
program.addLine(" If #{clg_sensors[unit].name} > #{clg_hrs}") # Use max hourly value across all units
|
|
2136
|
+
program.addLine(" Set #{clg_hrs} = #{clg_sensors[unit].name}")
|
|
2137
|
+
program.addLine(' EndIf')
|
|
1910
2138
|
program.addLine('EndIf')
|
|
1911
2139
|
end
|
|
1912
2140
|
|
|
@@ -1917,68 +2145,88 @@ class OSModel
|
|
|
1917
2145
|
program_calling_manager.addProgram(program)
|
|
1918
2146
|
end
|
|
1919
2147
|
|
|
1920
|
-
def
|
|
1921
|
-
|
|
1922
|
-
|
|
1923
|
-
if @apply_ashrae140_assumptions
|
|
1924
|
-
total_heat_load_served = 1.0
|
|
1925
|
-
total_cool_load_served = 1.0
|
|
1926
|
-
else
|
|
1927
|
-
total_heat_load_served = @hpxml.total_fraction_heat_load_served
|
|
1928
|
-
total_cool_load_served = @hpxml.total_fraction_cool_load_served
|
|
1929
|
-
end
|
|
1930
|
-
|
|
1931
|
-
liv_load_sensors, intgain_dehumidifier = add_total_loads_output(model, living_zone, total_heat_load_served, total_cool_load_served)
|
|
2148
|
+
def add_loads_output(model, add_component_loads, hpxml_osm_map)
|
|
2149
|
+
loads_data = add_total_loads_output(model, hpxml_osm_map)
|
|
1932
2150
|
return unless add_component_loads
|
|
1933
2151
|
|
|
1934
|
-
add_component_loads_output(model,
|
|
2152
|
+
add_component_loads_output(model, hpxml_osm_map, loads_data)
|
|
1935
2153
|
end
|
|
1936
2154
|
|
|
1937
|
-
def
|
|
1938
|
-
#
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
2155
|
+
def add_total_loads_output(model, hpxml_osm_map)
|
|
2156
|
+
# Create sensors and gather data
|
|
2157
|
+
htg_cond_load_sensors, clg_cond_load_sensors = {}, {}
|
|
2158
|
+
htg_duct_load_sensors, clg_duct_load_sensors = {}, {}
|
|
2159
|
+
total_heat_load_serveds, total_cool_load_serveds = {}, {}
|
|
2160
|
+
dehumidifier_sensors = {}
|
|
2161
|
+
|
|
2162
|
+
hpxml_osm_map.each_with_index do |(hpxml_bldg, unit_model), unit|
|
|
2163
|
+
# Retrieve objects
|
|
2164
|
+
conditioned_zone_name = unit_model.getThermalZones.find { |z| z.additionalProperties.getFeatureAsString('ObjectType').to_s == HPXML::LocationConditionedSpace }.name.to_s
|
|
2165
|
+
duct_zone_names = unit_model.getThermalZones.select { |z| z.isPlenum }.map { |z| z.name.to_s }
|
|
2166
|
+
dehumidifier = unit_model.getZoneHVACDehumidifierDXs
|
|
2167
|
+
dehumidifier_name = dehumidifier[0].name.to_s unless dehumidifier.empty?
|
|
2168
|
+
|
|
2169
|
+
# Fraction heat/cool load served
|
|
2170
|
+
if @hpxml_header.apply_ashrae140_assumptions
|
|
2171
|
+
total_heat_load_serveds[unit] = 1.0
|
|
2172
|
+
total_cool_load_serveds[unit] = 1.0
|
|
2173
|
+
else
|
|
2174
|
+
total_heat_load_serveds[unit] = hpxml_bldg.total_fraction_heat_load_served
|
|
2175
|
+
total_cool_load_serveds[unit] = hpxml_bldg.total_fraction_cool_load_served
|
|
2176
|
+
end
|
|
1951
2177
|
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
2178
|
+
# Energy transferred in conditioned zone, used for determining heating (winter) vs cooling (summer)
|
|
2179
|
+
htg_cond_load_sensors[unit] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Heating:EnergyTransfer:Zone:#{conditioned_zone_name.upcase}")
|
|
2180
|
+
htg_cond_load_sensors[unit].setName('htg_load_cond')
|
|
2181
|
+
clg_cond_load_sensors[unit] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Cooling:EnergyTransfer:Zone:#{conditioned_zone_name.upcase}")
|
|
2182
|
+
clg_cond_load_sensors[unit].setName('clg_load_cond')
|
|
1956
2183
|
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
2184
|
+
# Energy transferred in duct zone(s)
|
|
2185
|
+
htg_duct_load_sensors[unit] = []
|
|
2186
|
+
clg_duct_load_sensors[unit] = []
|
|
2187
|
+
duct_zone_names.each do |duct_zone_name|
|
|
2188
|
+
htg_duct_load_sensors[unit] << OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Heating:EnergyTransfer:Zone:#{duct_zone_name.upcase}")
|
|
2189
|
+
htg_duct_load_sensors[unit][-1].setName('htg_load_duct')
|
|
2190
|
+
clg_duct_load_sensors[unit] << OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Cooling:EnergyTransfer:Zone:#{duct_zone_name.upcase}")
|
|
2191
|
+
clg_duct_load_sensors[unit][-1].setName('clg_load_duct')
|
|
1961
2192
|
end
|
|
2193
|
+
|
|
2194
|
+
# Need to adjusted E+ EnergyTransfer meters for dehumidifier internal gains
|
|
2195
|
+
next if dehumidifier_name.nil?
|
|
2196
|
+
|
|
2197
|
+
dehumidifier_sensors[unit] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Dehumidifier Sensible Heating Energy')
|
|
2198
|
+
dehumidifier_sensors[unit].setName('ig_dehumidifier')
|
|
2199
|
+
dehumidifier_sensors[unit].setKeyName(dehumidifier_name)
|
|
1962
2200
|
end
|
|
1963
2201
|
|
|
1964
2202
|
# EMS program
|
|
1965
2203
|
program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
|
|
1966
|
-
program.setName(
|
|
2204
|
+
program.setName('total loads program')
|
|
2205
|
+
program.additionalProperties.setFeature('ObjectType', Constants.ObjectNameTotalLoadsProgram)
|
|
1967
2206
|
program.addLine('Set loads_htg_tot = 0')
|
|
1968
2207
|
program.addLine('Set loads_clg_tot = 0')
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
2208
|
+
for unit in 0..hpxml_osm_map.size - 1
|
|
2209
|
+
program.addLine("If #{htg_cond_load_sensors[unit].name} > 0")
|
|
2210
|
+
program.addLine(" Set loads_htg_tot = loads_htg_tot + (#{htg_cond_load_sensors[unit].name} - #{clg_cond_load_sensors[unit].name}) * #{total_heat_load_serveds[unit]}")
|
|
2211
|
+
for i in 0..htg_duct_load_sensors[unit].size - 1
|
|
2212
|
+
program.addLine(" Set loads_htg_tot = loads_htg_tot + (#{htg_duct_load_sensors[unit][i].name} - #{clg_duct_load_sensors[unit][i].name}) * #{total_heat_load_serveds[unit]}")
|
|
2213
|
+
end
|
|
2214
|
+
if not dehumidifier_sensors[unit].nil?
|
|
2215
|
+
program.addLine(" Set loads_htg_tot = loads_htg_tot - #{dehumidifier_sensors[unit].name}")
|
|
2216
|
+
end
|
|
2217
|
+
program.addLine('EndIf')
|
|
1973
2218
|
end
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
2219
|
+
for unit in 0..hpxml_osm_map.size - 1
|
|
2220
|
+
program.addLine("If #{clg_cond_load_sensors[unit].name} > 0")
|
|
2221
|
+
program.addLine(" Set loads_clg_tot = loads_clg_tot + (#{clg_cond_load_sensors[unit].name} - #{htg_cond_load_sensors[unit].name}) * #{total_cool_load_serveds[unit]}")
|
|
2222
|
+
for i in 0..clg_duct_load_sensors[unit].size - 1
|
|
2223
|
+
program.addLine(" Set loads_clg_tot = loads_clg_tot + (#{clg_duct_load_sensors[unit][i].name} - #{htg_duct_load_sensors[unit][i].name}) * #{total_cool_load_serveds[unit]}")
|
|
2224
|
+
end
|
|
2225
|
+
if not dehumidifier_sensors[unit].nil?
|
|
2226
|
+
program.addLine(" Set loads_clg_tot = loads_clg_tot + #{dehumidifier_sensors[unit].name}")
|
|
2227
|
+
end
|
|
2228
|
+
program.addLine('EndIf')
|
|
1979
2229
|
end
|
|
1980
|
-
program.addLine(s)
|
|
1981
|
-
program.addLine('EndIf')
|
|
1982
2230
|
|
|
1983
2231
|
# EMS calling manager
|
|
1984
2232
|
program_calling_manager = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
|
|
@@ -1986,27 +2234,11 @@ class OSModel
|
|
|
1986
2234
|
program_calling_manager.setCallingPoint('EndOfZoneTimestepAfterZoneReporting')
|
|
1987
2235
|
program_calling_manager.addProgram(program)
|
|
1988
2236
|
|
|
1989
|
-
return
|
|
2237
|
+
return htg_cond_load_sensors, clg_cond_load_sensors, total_heat_load_serveds, total_cool_load_serveds, dehumidifier_sensors
|
|
1990
2238
|
end
|
|
1991
2239
|
|
|
1992
|
-
def
|
|
1993
|
-
|
|
1994
|
-
objects_already_processed = []
|
|
1995
|
-
|
|
1996
|
-
# EMS Sensors: Surfaces, SubSurfaces, InternalMass
|
|
1997
|
-
surfaces_sensors = { walls: [],
|
|
1998
|
-
rim_joists: [],
|
|
1999
|
-
foundation_walls: [],
|
|
2000
|
-
floors: [],
|
|
2001
|
-
slabs: [],
|
|
2002
|
-
ceilings: [],
|
|
2003
|
-
roofs: [],
|
|
2004
|
-
windows_conduction: [],
|
|
2005
|
-
windows_solar: [],
|
|
2006
|
-
doors: [],
|
|
2007
|
-
skylights_conduction: [],
|
|
2008
|
-
skylights_solar: [],
|
|
2009
|
-
internal_mass: [] }
|
|
2240
|
+
def add_component_loads_output(model, hpxml_osm_map, loads_data)
|
|
2241
|
+
htg_cond_load_sensors, clg_cond_load_sensors, total_heat_load_serveds, total_cool_load_serveds, dehumidifier_sensors = loads_data
|
|
2010
2242
|
|
|
2011
2243
|
# Output diagnostics needed for some output variables used below
|
|
2012
2244
|
output_diagnostics = model.getOutputDiagnostics
|
|
@@ -2014,397 +2246,376 @@ class OSModel
|
|
|
2014
2246
|
|
|
2015
2247
|
area_tolerance = UnitConversions.convert(1.0, 'ft^2', 'm^2')
|
|
2016
2248
|
|
|
2017
|
-
|
|
2018
|
-
|
|
2249
|
+
nonsurf_names = ['intgains', 'lighting', 'infil', 'mechvent', 'natvent', 'whf', 'ducts']
|
|
2250
|
+
surf_names = ['walls', 'rim_joists', 'foundation_walls', 'floors', 'slabs', 'ceilings',
|
|
2251
|
+
'roofs', 'windows_conduction', 'windows_solar', 'doors', 'skylights_conduction',
|
|
2252
|
+
'skylights_solar', 'internal_mass']
|
|
2253
|
+
|
|
2254
|
+
# EMS program
|
|
2255
|
+
program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
|
|
2256
|
+
program.setName('component loads program')
|
|
2257
|
+
program.additionalProperties.setFeature('ObjectType', Constants.ObjectNameComponentLoadsProgram)
|
|
2019
2258
|
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2259
|
+
# Initialize
|
|
2260
|
+
[:htg, :clg].each do |mode|
|
|
2261
|
+
surf_names.each do |surf_name|
|
|
2262
|
+
program.addLine("Set loads_#{mode}_#{surf_name} = 0")
|
|
2263
|
+
end
|
|
2264
|
+
nonsurf_names.each do |nonsurf_name|
|
|
2265
|
+
program.addLine("Set loads_#{mode}_#{nonsurf_name} = 0")
|
|
2023
2266
|
end
|
|
2267
|
+
end
|
|
2024
2268
|
|
|
2025
|
-
|
|
2269
|
+
hpxml_osm_map.values.each_with_index do |unit_model, unit|
|
|
2270
|
+
conditioned_zone = unit_model.getThermalZones.find { |z| z.additionalProperties.getFeatureAsString('ObjectType').to_s == HPXML::LocationConditionedSpace }
|
|
2026
2271
|
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
key = { 'Window' => :windows_conduction,
|
|
2030
|
-
'Door' => :doors,
|
|
2031
|
-
'Skylight' => :skylights_conduction }[surface_type]
|
|
2032
|
-
fail "Unexpected subsurface for component loads: '#{ss.name}'." if key.nil?
|
|
2272
|
+
# Prevent certain objects (e.g., OtherEquipment) from being counted towards both, e.g., ducts and internal gains
|
|
2273
|
+
objects_already_processed = []
|
|
2033
2274
|
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2275
|
+
# EMS Sensors: Surfaces, SubSurfaces, InternalMass
|
|
2276
|
+
surfaces_sensors = {}
|
|
2277
|
+
surf_names.each do |surf_name|
|
|
2278
|
+
surfaces_sensors[surf_name.to_sym] = []
|
|
2279
|
+
end
|
|
2280
|
+
|
|
2281
|
+
unit_model.getSurfaces.sort.each do |s|
|
|
2282
|
+
next unless s.space.get.thermalZone.get.name.to_s == conditioned_zone.name.to_s
|
|
2283
|
+
|
|
2284
|
+
surface_type = s.additionalProperties.getFeatureAsString('SurfaceType')
|
|
2285
|
+
if not surface_type.is_initialized
|
|
2286
|
+
fail "Could not identify surface type for surface: '#{s.name}'."
|
|
2044
2287
|
end
|
|
2045
2288
|
|
|
2046
|
-
|
|
2289
|
+
surface_type = surface_type.get
|
|
2290
|
+
|
|
2291
|
+
s.subSurfaces.each do |ss|
|
|
2292
|
+
# Conduction (windows, skylights, doors)
|
|
2293
|
+
key = { 'Window' => :windows_conduction,
|
|
2294
|
+
'Door' => :doors,
|
|
2295
|
+
'Skylight' => :skylights_conduction }[surface_type]
|
|
2296
|
+
fail "Unexpected subsurface for component loads: '#{ss.name}'." if key.nil?
|
|
2297
|
+
|
|
2298
|
+
if (surface_type == 'Window') || (surface_type == 'Skylight')
|
|
2299
|
+
vars = { 'Surface Inside Face Convection Heat Gain Energy' => 'ss_conv',
|
|
2300
|
+
'Surface Inside Face Internal Gains Radiation Heat Gain Energy' => 'ss_ig',
|
|
2301
|
+
'Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy' => 'ss_surf' }
|
|
2302
|
+
else
|
|
2303
|
+
vars = { 'Surface Inside Face Solar Radiation Heat Gain Energy' => 'ss_sol',
|
|
2304
|
+
'Surface Inside Face Lights Radiation Heat Gain Energy' => 'ss_lgt',
|
|
2305
|
+
'Surface Inside Face Convection Heat Gain Energy' => 'ss_conv',
|
|
2306
|
+
'Surface Inside Face Internal Gains Radiation Heat Gain Energy' => 'ss_ig',
|
|
2307
|
+
'Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy' => 'ss_surf' }
|
|
2308
|
+
end
|
|
2309
|
+
|
|
2310
|
+
vars.each do |var, name|
|
|
2311
|
+
surfaces_sensors[key] << []
|
|
2312
|
+
sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2313
|
+
sensor.setName(name)
|
|
2314
|
+
sensor.setKeyName(ss.name.to_s)
|
|
2315
|
+
surfaces_sensors[key][-1] << sensor
|
|
2316
|
+
end
|
|
2317
|
+
|
|
2318
|
+
# Solar (windows, skylights)
|
|
2319
|
+
next unless (surface_type == 'Window') || (surface_type == 'Skylight')
|
|
2320
|
+
|
|
2321
|
+
key = { 'Window' => :windows_solar,
|
|
2322
|
+
'Skylight' => :skylights_solar }[surface_type]
|
|
2323
|
+
vars = { 'Surface Window Transmitted Solar Radiation Energy' => 'ss_trans_in',
|
|
2324
|
+
'Surface Window Shortwave from Zone Back Out Window Heat Transfer Rate' => 'ss_back_out',
|
|
2325
|
+
'Surface Window Total Glazing Layers Absorbed Shortwave Radiation Rate' => 'ss_sw_abs',
|
|
2326
|
+
'Surface Window Total Glazing Layers Absorbed Solar Radiation Energy' => 'ss_sol_abs',
|
|
2327
|
+
'Surface Inside Face Initial Transmitted Diffuse Transmitted Out Window Solar Radiation Rate' => 'ss_trans_out' }
|
|
2328
|
+
|
|
2047
2329
|
surfaces_sensors[key] << []
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2330
|
+
vars.each do |var, name|
|
|
2331
|
+
sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2332
|
+
sensor.setName(name)
|
|
2333
|
+
sensor.setKeyName(ss.name.to_s)
|
|
2334
|
+
surfaces_sensors[key][-1] << sensor
|
|
2335
|
+
end
|
|
2052
2336
|
end
|
|
2053
2337
|
|
|
2054
|
-
#
|
|
2055
|
-
next unless (surface_type == 'Window') || (surface_type == 'Skylight')
|
|
2338
|
+
next if s.netArea < area_tolerance # Skip parent surfaces (of subsurfaces) that have near zero net area
|
|
2056
2339
|
|
|
2057
|
-
key = { '
|
|
2058
|
-
'
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2340
|
+
key = { 'FoundationWall' => :foundation_walls,
|
|
2341
|
+
'RimJoist' => :rim_joists,
|
|
2342
|
+
'Wall' => :walls,
|
|
2343
|
+
'Slab' => :slabs,
|
|
2344
|
+
'Floor' => :floors,
|
|
2345
|
+
'Ceiling' => :ceilings,
|
|
2346
|
+
'Roof' => :roofs,
|
|
2347
|
+
'InferredCeiling' => :internal_mass,
|
|
2348
|
+
'InferredFloor' => :internal_mass }[surface_type]
|
|
2349
|
+
fail "Unexpected surface for component loads: '#{s.name}'." if key.nil?
|
|
2064
2350
|
|
|
2065
2351
|
surfaces_sensors[key] << []
|
|
2066
|
-
|
|
2352
|
+
{ 'Surface Inside Face Convection Heat Gain Energy' => 's_conv',
|
|
2353
|
+
'Surface Inside Face Internal Gains Radiation Heat Gain Energy' => 's_ig',
|
|
2354
|
+
'Surface Inside Face Solar Radiation Heat Gain Energy' => 's_sol',
|
|
2355
|
+
'Surface Inside Face Lights Radiation Heat Gain Energy' => 's_lgt',
|
|
2356
|
+
'Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy' => 's_surf' }.each do |var, name|
|
|
2067
2357
|
sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2068
2358
|
sensor.setName(name)
|
|
2069
|
-
sensor.setKeyName(
|
|
2359
|
+
sensor.setKeyName(s.name.to_s)
|
|
2070
2360
|
surfaces_sensors[key][-1] << sensor
|
|
2071
2361
|
end
|
|
2072
2362
|
end
|
|
2073
2363
|
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
model.getInternalMasss.sort.each do |m|
|
|
2101
|
-
next unless m.space.get.thermalZone.get.name.to_s == living_zone.name.to_s
|
|
2102
|
-
|
|
2103
|
-
surfaces_sensors[:internal_mass] << []
|
|
2104
|
-
{ 'Surface Inside Face Convection Heat Gain Energy' => 'im_conv',
|
|
2105
|
-
'Surface Inside Face Internal Gains Radiation Heat Gain Energy' => 'im_ig',
|
|
2106
|
-
'Surface Inside Face Solar Radiation Heat Gain Energy' => 'im_sol',
|
|
2107
|
-
'Surface Inside Face Lights Radiation Heat Gain Energy' => 'im_lgt',
|
|
2108
|
-
'Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy' => 'im_surf' }.each do |var, name|
|
|
2109
|
-
sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2110
|
-
sensor.setName(name)
|
|
2111
|
-
sensor.setKeyName(m.name.to_s)
|
|
2112
|
-
surfaces_sensors[:internal_mass][-1] << sensor
|
|
2113
|
-
end
|
|
2114
|
-
end
|
|
2115
|
-
|
|
2116
|
-
# EMS Sensors: Infiltration, Mechanical Ventilation, Natural Ventilation, Whole House Fan
|
|
2117
|
-
infil_sensors = []
|
|
2118
|
-
natvent_sensors = []
|
|
2119
|
-
whf_sensors = []
|
|
2120
|
-
{ Constants.ObjectNameInfiltration => infil_sensors,
|
|
2121
|
-
Constants.ObjectNameNaturalVentilation => natvent_sensors,
|
|
2122
|
-
Constants.ObjectNameWholeHouseFan => whf_sensors }.each do |prefix, array|
|
|
2123
|
-
model.getSpaceInfiltrationDesignFlowRates.sort.each do |i|
|
|
2124
|
-
next unless i.name.to_s.start_with? prefix
|
|
2125
|
-
next unless i.space.get.thermalZone.get.name.to_s == living_zone.name.to_s
|
|
2126
|
-
|
|
2127
|
-
{ 'Infiltration Sensible Heat Gain Energy' => prefix.gsub(' ', '_') + '_' + 'gain',
|
|
2128
|
-
'Infiltration Sensible Heat Loss Energy' => prefix.gsub(' ', '_') + '_' + 'loss' }.each do |var, name|
|
|
2364
|
+
unit_model.getInternalMasss.sort.each do |m|
|
|
2365
|
+
next unless m.space.get.thermalZone.get.name.to_s == conditioned_zone.name.to_s
|
|
2366
|
+
|
|
2367
|
+
surfaces_sensors[:internal_mass] << []
|
|
2368
|
+
{ 'Surface Inside Face Convection Heat Gain Energy' => 'im_conv',
|
|
2369
|
+
'Surface Inside Face Internal Gains Radiation Heat Gain Energy' => 'im_ig',
|
|
2370
|
+
'Surface Inside Face Solar Radiation Heat Gain Energy' => 'im_sol',
|
|
2371
|
+
'Surface Inside Face Lights Radiation Heat Gain Energy' => 'im_lgt',
|
|
2372
|
+
'Surface Inside Face Net Surface Thermal Radiation Heat Gain Energy' => 'im_surf' }.each do |var, name|
|
|
2373
|
+
sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2374
|
+
sensor.setName(name)
|
|
2375
|
+
sensor.setKeyName(m.name.to_s)
|
|
2376
|
+
surfaces_sensors[:internal_mass][-1] << sensor
|
|
2377
|
+
end
|
|
2378
|
+
end
|
|
2379
|
+
|
|
2380
|
+
# EMS Sensors: Infiltration, Natural Ventilation, Whole House Fan
|
|
2381
|
+
infil_sensors, natvent_sensors, whf_sensors = [], [], []
|
|
2382
|
+
unit_model.getSpaceInfiltrationDesignFlowRates.sort.each do |i|
|
|
2383
|
+
next unless i.space.get.thermalZone.get.name.to_s == conditioned_zone.name.to_s
|
|
2384
|
+
|
|
2385
|
+
object_type = i.additionalProperties.getFeatureAsString('ObjectType').get
|
|
2386
|
+
|
|
2387
|
+
{ 'Infiltration Sensible Heat Gain Energy' => 'airflow_gain',
|
|
2388
|
+
'Infiltration Sensible Heat Loss Energy' => 'airflow_loss' }.each do |var, name|
|
|
2129
2389
|
airflow_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2130
2390
|
airflow_sensor.setName(name)
|
|
2131
2391
|
airflow_sensor.setKeyName(i.name.to_s)
|
|
2132
|
-
|
|
2392
|
+
if object_type == Constants.ObjectNameInfiltration
|
|
2393
|
+
infil_sensors << airflow_sensor
|
|
2394
|
+
elsif object_type == Constants.ObjectNameNaturalVentilation
|
|
2395
|
+
natvent_sensors << airflow_sensor
|
|
2396
|
+
elsif object_type == Constants.ObjectNameWholeHouseFan
|
|
2397
|
+
whf_sensors << airflow_sensor
|
|
2398
|
+
end
|
|
2133
2399
|
end
|
|
2134
2400
|
end
|
|
2135
|
-
end
|
|
2136
2401
|
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2402
|
+
# EMS Sensors: Mechanical Ventilation
|
|
2403
|
+
mechvents_sensors = []
|
|
2404
|
+
unit_model.getElectricEquipments.sort.each do |o|
|
|
2405
|
+
next unless o.endUseSubcategory == Constants.ObjectNameMechanicalVentilation
|
|
2140
2406
|
|
|
2141
|
-
mechvents_sensors << []
|
|
2142
|
-
{ 'Electric Equipment Convective Heating Energy' => 'mv_conv',
|
|
2143
|
-
'Electric Equipment Radiant Heating Energy' => 'mv_rad' }.each do |var, name|
|
|
2144
|
-
mechvent_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2145
|
-
mechvent_sensor.setName(name)
|
|
2146
|
-
mechvent_sensor.setKeyName(o.name.to_s)
|
|
2147
|
-
mechvents_sensors[-1] << mechvent_sensor
|
|
2148
2407
|
objects_already_processed << o
|
|
2408
|
+
{ 'Electric Equipment Convective Heating Energy' => 'mv_conv',
|
|
2409
|
+
'Electric Equipment Radiant Heating Energy' => 'mv_rad' }.each do |var, name|
|
|
2410
|
+
mechvent_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2411
|
+
mechvent_sensor.setName(name)
|
|
2412
|
+
mechvent_sensor.setKeyName(o.name.to_s)
|
|
2413
|
+
mechvents_sensors << mechvent_sensor
|
|
2414
|
+
end
|
|
2149
2415
|
end
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
next unless o.name.to_s.start_with? Constants.ObjectNameMechanicalVentilationHouseFan
|
|
2416
|
+
unit_model.getOtherEquipments.sort.each do |o|
|
|
2417
|
+
next unless o.endUseSubcategory == Constants.ObjectNameMechanicalVentilationHouseFan
|
|
2153
2418
|
|
|
2154
|
-
mechvents_sensors << []
|
|
2155
|
-
{ 'Other Equipment Convective Heating Energy' => 'mv_conv',
|
|
2156
|
-
'Other Equipment Radiant Heating Energy' => 'mv_rad' }.each do |var, name|
|
|
2157
|
-
mechvent_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2158
|
-
mechvent_sensor.setName(name)
|
|
2159
|
-
mechvent_sensor.setKeyName(o.name.to_s)
|
|
2160
|
-
mechvents_sensors[-1] << mechvent_sensor
|
|
2161
2419
|
objects_already_processed << o
|
|
2420
|
+
{ 'Other Equipment Convective Heating Energy' => 'mv_conv',
|
|
2421
|
+
'Other Equipment Radiant Heating Energy' => 'mv_rad' }.each do |var, name|
|
|
2422
|
+
mechvent_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2423
|
+
mechvent_sensor.setName(name)
|
|
2424
|
+
mechvent_sensor.setKeyName(o.name.to_s)
|
|
2425
|
+
mechvents_sensors << mechvent_sensor
|
|
2426
|
+
end
|
|
2162
2427
|
end
|
|
2163
|
-
end
|
|
2164
2428
|
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2429
|
+
# EMS Sensors: Ducts
|
|
2430
|
+
ducts_sensors = []
|
|
2431
|
+
ducts_mix_gain_sensor = nil
|
|
2432
|
+
ducts_mix_loss_sensor = nil
|
|
2433
|
+
conditioned_zone.zoneMixing.each do |zone_mix|
|
|
2434
|
+
object_type = zone_mix.additionalProperties.getFeatureAsString('ObjectType').to_s
|
|
2435
|
+
next unless object_type == Constants.ObjectNameDuctLoad
|
|
2169
2436
|
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
next unless zone_mix.name.to_s.start_with? airloop.name.to_s.gsub(' ', '_')
|
|
2437
|
+
ducts_mix_gain_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Mixing Sensible Heat Gain Energy')
|
|
2438
|
+
ducts_mix_gain_sensor.setName('duct_mix_gain')
|
|
2439
|
+
ducts_mix_gain_sensor.setKeyName(conditioned_zone.name.to_s)
|
|
2174
2440
|
|
|
2175
|
-
|
|
2441
|
+
ducts_mix_loss_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Mixing Sensible Heat Loss Energy')
|
|
2442
|
+
ducts_mix_loss_sensor.setName('duct_mix_loss')
|
|
2443
|
+
ducts_mix_loss_sensor.setKeyName(conditioned_zone.name.to_s)
|
|
2176
2444
|
end
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
ducts_mix_gain_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Mixing Sensible Heat Gain Energy')
|
|
2181
|
-
ducts_mix_gain_sensor.setName('duct_mix_gain')
|
|
2182
|
-
ducts_mix_gain_sensor.setKeyName(living_zone.name.to_s)
|
|
2183
|
-
|
|
2184
|
-
ducts_mix_loss_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Mixing Sensible Heat Loss Energy')
|
|
2185
|
-
ducts_mix_loss_sensor.setName('duct_mix_loss')
|
|
2186
|
-
ducts_mix_loss_sensor.setKeyName(living_zone.name.to_s)
|
|
2187
|
-
end
|
|
2188
|
-
|
|
2189
|
-
# Duct losses
|
|
2190
|
-
model.getOtherEquipments.sort.each do |o|
|
|
2191
|
-
next if objects_already_processed.include? o
|
|
2445
|
+
unit_model.getOtherEquipments.sort.each do |o|
|
|
2446
|
+
next if objects_already_processed.include? o
|
|
2447
|
+
next unless o.endUseSubcategory == Constants.ObjectNameDuctLoad
|
|
2192
2448
|
|
|
2193
|
-
|
|
2194
|
-
|
|
2449
|
+
objects_already_processed << o
|
|
2450
|
+
{ 'Other Equipment Convective Heating Energy' => 'ducts_conv',
|
|
2451
|
+
'Other Equipment Radiant Heating Energy' => 'ducts_rad' }.each do |var, name|
|
|
2452
|
+
ducts_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2453
|
+
ducts_sensor.setName(name)
|
|
2454
|
+
ducts_sensor.setKeyName(o.name.to_s)
|
|
2455
|
+
ducts_sensors << ducts_sensor
|
|
2456
|
+
end
|
|
2457
|
+
end
|
|
2195
2458
|
|
|
2196
|
-
|
|
2197
|
-
|
|
2459
|
+
# EMS Sensors: Lighting
|
|
2460
|
+
lightings_sensors = []
|
|
2461
|
+
unit_model.getLightss.sort.each do |e|
|
|
2462
|
+
next unless e.space.get.thermalZone.get.name.to_s == conditioned_zone.name.to_s
|
|
2198
2463
|
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2464
|
+
{ 'Lights Convective Heating Energy' => 'ig_lgt_conv',
|
|
2465
|
+
'Lights Radiant Heating Energy' => 'ig_lgt_rad',
|
|
2466
|
+
'Lights Visible Radiation Heating Energy' => 'ig_lgt_vis' }.each do |var, name|
|
|
2467
|
+
intgains_lights_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2468
|
+
intgains_lights_sensor.setName(name)
|
|
2469
|
+
intgains_lights_sensor.setKeyName(e.name.to_s)
|
|
2470
|
+
lightings_sensors << intgains_lights_sensor
|
|
2471
|
+
end
|
|
2206
2472
|
end
|
|
2207
|
-
end
|
|
2208
2473
|
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2474
|
+
# EMS Sensors: Internal Gains
|
|
2475
|
+
intgains_sensors = []
|
|
2476
|
+
unit_model.getElectricEquipments.sort.each do |o|
|
|
2477
|
+
next if objects_already_processed.include? o
|
|
2478
|
+
next unless o.space.get.thermalZone.get.name.to_s == conditioned_zone.name.to_s
|
|
2214
2479
|
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
lightings_sensors[-1] << intgains_lights_sensor
|
|
2480
|
+
{ 'Electric Equipment Convective Heating Energy' => 'ig_ee_conv',
|
|
2481
|
+
'Electric Equipment Radiant Heating Energy' => 'ig_ee_rad' }.each do |var, name|
|
|
2482
|
+
intgains_elec_equip_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2483
|
+
intgains_elec_equip_sensor.setName(name)
|
|
2484
|
+
intgains_elec_equip_sensor.setKeyName(o.name.to_s)
|
|
2485
|
+
intgains_sensors << intgains_elec_equip_sensor
|
|
2486
|
+
end
|
|
2223
2487
|
end
|
|
2224
|
-
end
|
|
2225
2488
|
|
|
2226
|
-
|
|
2227
|
-
|
|
2489
|
+
unit_model.getOtherEquipments.sort.each do |o|
|
|
2490
|
+
next if objects_already_processed.include? o
|
|
2491
|
+
next unless o.space.get.thermalZone.get.name.to_s == conditioned_zone.name.to_s
|
|
2228
2492
|
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
intgains_elec_equip_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2237
|
-
intgains_elec_equip_sensor.setName(name)
|
|
2238
|
-
intgains_elec_equip_sensor.setKeyName(o.name.to_s)
|
|
2239
|
-
intgains_sensors[-1] << intgains_elec_equip_sensor
|
|
2493
|
+
{ 'Other Equipment Convective Heating Energy' => 'ig_oe_conv',
|
|
2494
|
+
'Other Equipment Radiant Heating Energy' => 'ig_oe_rad' }.each do |var, name|
|
|
2495
|
+
intgains_other_equip_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2496
|
+
intgains_other_equip_sensor.setName(name)
|
|
2497
|
+
intgains_other_equip_sensor.setKeyName(o.name.to_s)
|
|
2498
|
+
intgains_sensors << intgains_other_equip_sensor
|
|
2499
|
+
end
|
|
2240
2500
|
end
|
|
2241
|
-
end
|
|
2242
2501
|
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
next if objects_already_processed.include? o
|
|
2502
|
+
unit_model.getPeoples.sort.each do |e|
|
|
2503
|
+
next unless e.space.get.thermalZone.get.name.to_s == conditioned_zone.name.to_s
|
|
2246
2504
|
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2505
|
+
{ 'People Convective Heating Energy' => 'ig_ppl_conv',
|
|
2506
|
+
'People Radiant Heating Energy' => 'ig_ppl_rad' }.each do |var, name|
|
|
2507
|
+
intgains_people = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2508
|
+
intgains_people.setName(name)
|
|
2509
|
+
intgains_people.setKeyName(e.name.to_s)
|
|
2510
|
+
intgains_sensors << intgains_people
|
|
2511
|
+
end
|
|
2254
2512
|
end
|
|
2255
|
-
end
|
|
2256
2513
|
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
intgains_sensors << []
|
|
2261
|
-
{ 'People Convective Heating Energy' => 'ig_ppl_conv',
|
|
2262
|
-
'People Radiant Heating Energy' => 'ig_ppl_rad' }.each do |var, name|
|
|
2263
|
-
intgains_people = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
|
2264
|
-
intgains_people.setName(name)
|
|
2265
|
-
intgains_people.setKeyName(e.name.to_s)
|
|
2266
|
-
intgains_sensors[-1] << intgains_people
|
|
2514
|
+
if not dehumidifier_sensors[unit].nil?
|
|
2515
|
+
intgains_sensors << dehumidifier_sensors[unit]
|
|
2267
2516
|
end
|
|
2268
|
-
end
|
|
2269
2517
|
|
|
2270
|
-
|
|
2271
|
-
intgains_sensors[-1] << intgain_dehumidifier
|
|
2272
|
-
end
|
|
2518
|
+
intgains_dhw_sensors = {}
|
|
2273
2519
|
|
|
2274
|
-
|
|
2520
|
+
(unit_model.getWaterHeaterMixeds + unit_model.getWaterHeaterStratifieds).sort.each do |wh|
|
|
2521
|
+
next unless wh.ambientTemperatureThermalZone.is_initialized
|
|
2522
|
+
next unless wh.ambientTemperatureThermalZone.get.name.to_s == conditioned_zone.name.to_s
|
|
2275
2523
|
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2524
|
+
dhw_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Water Heater Heat Loss Energy')
|
|
2525
|
+
dhw_sensor.setName('dhw_loss')
|
|
2526
|
+
dhw_sensor.setKeyName(wh.name.to_s)
|
|
2279
2527
|
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2528
|
+
if wh.is_a? OpenStudio::Model::WaterHeaterMixed
|
|
2529
|
+
oncycle_loss = wh.onCycleLossFractiontoThermalZone
|
|
2530
|
+
offcycle_loss = wh.offCycleLossFractiontoThermalZone
|
|
2531
|
+
else
|
|
2532
|
+
oncycle_loss = wh.skinLossFractiontoZone
|
|
2533
|
+
offcycle_loss = wh.offCycleFlueLossFractiontoZone
|
|
2534
|
+
end
|
|
2283
2535
|
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2536
|
+
dhw_rtf_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Water Heater Runtime Fraction')
|
|
2537
|
+
dhw_rtf_sensor.setName('dhw_rtf')
|
|
2538
|
+
dhw_rtf_sensor.setKeyName(wh.name.to_s)
|
|
2539
|
+
|
|
2540
|
+
intgains_dhw_sensors[dhw_sensor] = [offcycle_loss, oncycle_loss, dhw_rtf_sensor]
|
|
2541
|
+
end
|
|
2542
|
+
|
|
2543
|
+
# EMS program: Surfaces
|
|
2544
|
+
surfaces_sensors.each do |k, surface_sensors|
|
|
2545
|
+
program.addLine("Set hr_#{k} = 0")
|
|
2546
|
+
surface_sensors.each do |sensors|
|
|
2547
|
+
s = "Set hr_#{k} = hr_#{k}"
|
|
2548
|
+
sensors.each do |sensor|
|
|
2549
|
+
# remove ss_net if switch
|
|
2550
|
+
if sensor.name.to_s.start_with?('ss_net', 'ss_sol_abs', 'ss_trans_in')
|
|
2551
|
+
s += " - #{sensor.name}"
|
|
2552
|
+
elsif sensor.name.to_s.start_with?('ss_sw_abs', 'ss_trans_out', 'ss_back_out')
|
|
2553
|
+
s += " + #{sensor.name} * ZoneTimestep * 3600"
|
|
2554
|
+
else
|
|
2555
|
+
s += " + #{sensor.name}"
|
|
2556
|
+
end
|
|
2557
|
+
end
|
|
2558
|
+
program.addLine(s) if sensors.size > 0
|
|
2559
|
+
end
|
|
2290
2560
|
end
|
|
2291
2561
|
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2562
|
+
# EMS program: Internal Gains, Lighting, Infiltration, Natural Ventilation, Mechanical Ventilation, Ducts
|
|
2563
|
+
{ 'intgains' => intgains_sensors,
|
|
2564
|
+
'lighting' => lightings_sensors,
|
|
2565
|
+
'infil' => infil_sensors,
|
|
2566
|
+
'natvent' => natvent_sensors,
|
|
2567
|
+
'whf' => whf_sensors,
|
|
2568
|
+
'mechvent' => mechvents_sensors,
|
|
2569
|
+
'ducts' => ducts_sensors }.each do |loadtype, sensors|
|
|
2570
|
+
program.addLine("Set hr_#{loadtype} = 0")
|
|
2571
|
+
next if sensors.empty?
|
|
2295
2572
|
|
|
2296
|
-
|
|
2297
|
-
end
|
|
2298
|
-
|
|
2299
|
-
nonsurf_names = ['intgains', 'lighting', 'infil', 'mechvent', 'natvent', 'whf', 'ducts']
|
|
2300
|
-
|
|
2301
|
-
# EMS program
|
|
2302
|
-
program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
|
|
2303
|
-
program.setName(Constants.ObjectNameComponentLoadsProgram)
|
|
2304
|
-
|
|
2305
|
-
# EMS program: Surfaces
|
|
2306
|
-
surfaces_sensors.each do |k, surface_sensors|
|
|
2307
|
-
program.addLine("Set hr_#{k} = 0")
|
|
2308
|
-
surface_sensors.each do |sensors|
|
|
2309
|
-
s = "Set hr_#{k} = hr_#{k}"
|
|
2573
|
+
s = "Set hr_#{loadtype} = hr_#{loadtype}"
|
|
2310
2574
|
sensors.each do |sensor|
|
|
2311
|
-
|
|
2312
|
-
if sensor.name.to_s.start_with?('ss_net', 'ss_sol_abs', 'ss_trans_in')
|
|
2575
|
+
if ['intgains', 'lighting', 'mechvent', 'ducts'].include? loadtype
|
|
2313
2576
|
s += " - #{sensor.name}"
|
|
2314
|
-
elsif sensor.name.to_s.
|
|
2315
|
-
s += "
|
|
2316
|
-
|
|
2577
|
+
elsif sensor.name.to_s.include? 'gain'
|
|
2578
|
+
s += " - #{sensor.name}"
|
|
2579
|
+
elsif sensor.name.to_s.include? 'loss'
|
|
2317
2580
|
s += " + #{sensor.name}"
|
|
2318
2581
|
end
|
|
2319
2582
|
end
|
|
2320
|
-
program.addLine(s)
|
|
2321
|
-
end
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
program.addLine(
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
program.addLine(
|
|
2342
|
-
end
|
|
2343
|
-
intgains_dhw_sensors.each do |sensor, vals|
|
|
2344
|
-
off_loss, on_loss, rtf_sensor = vals
|
|
2345
|
-
program.addLine("Set hr_intgains = hr_intgains + #{sensor.name} * (#{off_loss}*(1-#{rtf_sensor.name}) + #{on_loss}*#{rtf_sensor.name})") # Water heater tank losses to zone
|
|
2346
|
-
end
|
|
2583
|
+
program.addLine(s)
|
|
2584
|
+
end
|
|
2585
|
+
intgains_dhw_sensors.each do |sensor, vals|
|
|
2586
|
+
off_loss, on_loss, rtf_sensor = vals
|
|
2587
|
+
program.addLine("Set hr_intgains = hr_intgains + #{sensor.name} * (#{off_loss}*(1-#{rtf_sensor.name}) + #{on_loss}*#{rtf_sensor.name})") # Water heater tank losses to zone
|
|
2588
|
+
end
|
|
2589
|
+
if (not ducts_mix_loss_sensor.nil?) && (not ducts_mix_gain_sensor.nil?)
|
|
2590
|
+
program.addLine("Set hr_ducts = hr_ducts + (#{ducts_mix_loss_sensor.name} - #{ducts_mix_gain_sensor.name})")
|
|
2591
|
+
end
|
|
2592
|
+
|
|
2593
|
+
# EMS program: Heating vs Cooling logic
|
|
2594
|
+
program.addLine('Set htg_mode = 0')
|
|
2595
|
+
program.addLine('Set clg_mode = 0')
|
|
2596
|
+
program.addLine("If (#{htg_cond_load_sensors[unit].name} > 0)") # Assign hour to heating if heating load
|
|
2597
|
+
program.addLine(" Set htg_mode = #{total_heat_load_serveds[unit]}")
|
|
2598
|
+
program.addLine("ElseIf (#{clg_cond_load_sensors[unit].name} > 0)") # Assign hour to cooling if cooling load
|
|
2599
|
+
program.addLine(" Set clg_mode = #{total_cool_load_serveds[unit]}")
|
|
2600
|
+
program.addLine("ElseIf (#{@clg_ssn_sensor.name} > 0)") # No load, assign hour to cooling if in cooling season definition (Note: natural ventilation & whole house fan only operate during the cooling season)
|
|
2601
|
+
program.addLine(" Set clg_mode = #{total_cool_load_serveds[unit]}")
|
|
2602
|
+
program.addLine('Else') # No load, assign hour to heating if not in cooling season definition
|
|
2603
|
+
program.addLine(" Set htg_mode = #{total_heat_load_serveds[unit]}")
|
|
2604
|
+
program.addLine('EndIf')
|
|
2347
2605
|
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
sensors.each do |sensor|
|
|
2355
|
-
if sensor.name.to_s.include? 'gain'
|
|
2356
|
-
# FIXME: Workaround for https://github.com/NREL/EnergyPlus/issues/9934
|
|
2357
|
-
# Remove when the issue is resolved
|
|
2358
|
-
if loadtype == 'infil'
|
|
2359
|
-
s += " - (#{sensor.name} * 3600)"
|
|
2360
|
-
else
|
|
2361
|
-
s += " - #{sensor.name}"
|
|
2362
|
-
end
|
|
2363
|
-
elsif sensor.name.to_s.include? 'loss'
|
|
2364
|
-
s += " + #{sensor.name}"
|
|
2606
|
+
unit_multiplier = @hpxml_bldg.building_construction.number_of_units
|
|
2607
|
+
[:htg, :clg].each do |mode|
|
|
2608
|
+
if mode == :htg
|
|
2609
|
+
sign = ''
|
|
2610
|
+
else
|
|
2611
|
+
sign = '-'
|
|
2365
2612
|
end
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
program.addLine("Set hr_#{loadtype} = 0")
|
|
2372
|
-
all_sensors.each do |sensors|
|
|
2373
|
-
s = "Set hr_#{loadtype} = hr_#{loadtype}"
|
|
2374
|
-
sensors.each do |sensor|
|
|
2375
|
-
s += " - #{sensor.name}"
|
|
2613
|
+
surf_names.each do |surf_name|
|
|
2614
|
+
program.addLine("Set loads_#{mode}_#{surf_name} = loads_#{mode}_#{surf_name} + (#{sign}hr_#{surf_name} * #{mode}_mode * #{unit_multiplier})")
|
|
2615
|
+
end
|
|
2616
|
+
nonsurf_names.each do |nonsurf_name|
|
|
2617
|
+
program.addLine("Set loads_#{mode}_#{nonsurf_name} = loads_#{mode}_#{nonsurf_name} + (#{sign}hr_#{nonsurf_name} * #{mode}_mode * #{unit_multiplier})")
|
|
2376
2618
|
end
|
|
2377
|
-
program.addLine(s) if sensors.size > 0
|
|
2378
|
-
end
|
|
2379
|
-
end
|
|
2380
|
-
if (not ducts_mix_loss_sensor.nil?) && (not ducts_mix_gain_sensor.nil?)
|
|
2381
|
-
program.addLine("Set hr_ducts = hr_ducts + (#{ducts_mix_loss_sensor.name} - #{ducts_mix_gain_sensor.name})")
|
|
2382
|
-
end
|
|
2383
|
-
|
|
2384
|
-
# EMS program: Heating vs Cooling logic
|
|
2385
|
-
program.addLine('Set htg_mode = 0')
|
|
2386
|
-
program.addLine('Set clg_mode = 0')
|
|
2387
|
-
program.addLine("If (#{liv_load_sensors[:htg].name} > 0)") # Assign hour to heating if heating load
|
|
2388
|
-
program.addLine(" Set htg_mode = #{total_heat_load_served}")
|
|
2389
|
-
program.addLine("ElseIf (#{liv_load_sensors[:clg].name} > 0)") # Assign hour to cooling if cooling load
|
|
2390
|
-
program.addLine(" Set clg_mode = #{total_cool_load_served}")
|
|
2391
|
-
program.addLine("ElseIf (#{@clg_ssn_sensor.name} > 0)") # No load, assign hour to cooling if in cooling season definition (Note: natural ventilation & whole house fan only operate during the cooling season)
|
|
2392
|
-
program.addLine(" Set clg_mode = #{total_cool_load_served}")
|
|
2393
|
-
program.addLine('Else') # No load, assign hour to heating if not in cooling season definition
|
|
2394
|
-
program.addLine(" Set htg_mode = #{total_heat_load_served}")
|
|
2395
|
-
program.addLine('EndIf')
|
|
2396
|
-
|
|
2397
|
-
[:htg, :clg].each do |mode|
|
|
2398
|
-
if mode == :htg
|
|
2399
|
-
sign = ''
|
|
2400
|
-
else
|
|
2401
|
-
sign = '-'
|
|
2402
|
-
end
|
|
2403
|
-
surfaces_sensors.keys.each do |k|
|
|
2404
|
-
program.addLine("Set loads_#{mode}_#{k} = #{sign}hr_#{k} * #{mode}_mode")
|
|
2405
|
-
end
|
|
2406
|
-
nonsurf_names.each do |nonsurf_name|
|
|
2407
|
-
program.addLine("Set loads_#{mode}_#{nonsurf_name} = #{sign}hr_#{nonsurf_name} * #{mode}_mode")
|
|
2408
2619
|
end
|
|
2409
2620
|
end
|
|
2410
2621
|
|
|
@@ -2415,7 +2626,7 @@ class OSModel
|
|
|
2415
2626
|
program_calling_manager.addProgram(program)
|
|
2416
2627
|
end
|
|
2417
2628
|
|
|
2418
|
-
def
|
|
2629
|
+
def set_output_files(model)
|
|
2419
2630
|
oj = model.getOutputJSON
|
|
2420
2631
|
oj.setOptionType('TimeSeriesAndTabular')
|
|
2421
2632
|
oj.setOutputJSON(false)
|
|
@@ -2423,6 +2634,7 @@ class OSModel
|
|
|
2423
2634
|
|
|
2424
2635
|
ocf = model.getOutputControlFiles
|
|
2425
2636
|
ocf.setOutputAUDIT(@debug)
|
|
2637
|
+
ocf.setOutputCSV(@debug)
|
|
2426
2638
|
ocf.setOutputBND(@debug)
|
|
2427
2639
|
ocf.setOutputEIO(@debug)
|
|
2428
2640
|
ocf.setOutputESO(@debug)
|
|
@@ -2431,30 +2643,31 @@ class OSModel
|
|
|
2431
2643
|
ocf.setOutputMTR(@debug)
|
|
2432
2644
|
ocf.setOutputRDD(@debug)
|
|
2433
2645
|
ocf.setOutputSHD(@debug)
|
|
2646
|
+
ocf.setOutputCSV(@debug)
|
|
2434
2647
|
ocf.setOutputSQLite(@debug)
|
|
2435
2648
|
ocf.setOutputPerfLog(@debug)
|
|
2436
2649
|
end
|
|
2437
2650
|
|
|
2438
|
-
def
|
|
2651
|
+
def add_ems_debug_output(model)
|
|
2439
2652
|
oems = model.getOutputEnergyManagementSystem
|
|
2440
2653
|
oems.setActuatorAvailabilityDictionaryReporting('Verbose')
|
|
2441
2654
|
oems.setInternalVariableAvailabilityDictionaryReporting('Verbose')
|
|
2442
2655
|
oems.setEMSRuntimeLanguageDebugOutputLevel('Verbose')
|
|
2443
2656
|
end
|
|
2444
2657
|
|
|
2445
|
-
def
|
|
2658
|
+
def set_surface_interior(model, spaces, surface, hpxml_surface)
|
|
2446
2659
|
interior_adjacent_to = hpxml_surface.interior_adjacent_to
|
|
2447
2660
|
if HPXML::conditioned_below_grade_locations.include? interior_adjacent_to
|
|
2448
|
-
surface.setSpace(create_or_get_space(model, spaces, HPXML::
|
|
2661
|
+
surface.setSpace(create_or_get_space(model, spaces, HPXML::LocationConditionedSpace))
|
|
2449
2662
|
else
|
|
2450
2663
|
surface.setSpace(create_or_get_space(model, spaces, interior_adjacent_to))
|
|
2451
2664
|
end
|
|
2452
2665
|
end
|
|
2453
2666
|
|
|
2454
|
-
def
|
|
2667
|
+
def set_surface_exterior(model, spaces, surface, hpxml_surface)
|
|
2455
2668
|
exterior_adjacent_to = hpxml_surface.exterior_adjacent_to
|
|
2456
2669
|
is_adiabatic = hpxml_surface.is_adiabatic
|
|
2457
|
-
if
|
|
2670
|
+
if [HPXML::LocationOutside, HPXML::LocationManufacturedHomeUnderBelly].include? exterior_adjacent_to
|
|
2458
2671
|
surface.setOutsideBoundaryCondition('Outdoors')
|
|
2459
2672
|
elsif exterior_adjacent_to == HPXML::LocationGround
|
|
2460
2673
|
surface.setOutsideBoundaryCondition('Foundation')
|
|
@@ -2464,7 +2677,7 @@ class OSModel
|
|
|
2464
2677
|
HPXML::LocationOtherNonFreezingSpace, HPXML::LocationOtherHousingUnit].include? exterior_adjacent_to
|
|
2465
2678
|
set_surface_otherside_coefficients(surface, exterior_adjacent_to, model, spaces)
|
|
2466
2679
|
elsif HPXML::conditioned_below_grade_locations.include? exterior_adjacent_to
|
|
2467
|
-
adjacent_surface = surface.createAdjacentSurface(create_or_get_space(model, spaces, HPXML::
|
|
2680
|
+
adjacent_surface = surface.createAdjacentSurface(create_or_get_space(model, spaces, HPXML::LocationConditionedSpace)).get
|
|
2468
2681
|
adjacent_surface.additionalProperties.setFeature('SurfaceType', surface.additionalProperties.getFeatureAsString('SurfaceType').get)
|
|
2469
2682
|
else
|
|
2470
2683
|
adjacent_surface = surface.createAdjacentSurface(create_or_get_space(model, spaces, exterior_adjacent_to)).get
|
|
@@ -2472,7 +2685,7 @@ class OSModel
|
|
|
2472
2685
|
end
|
|
2473
2686
|
end
|
|
2474
2687
|
|
|
2475
|
-
def
|
|
2688
|
+
def set_surface_otherside_coefficients(surface, exterior_adjacent_to, model, spaces)
|
|
2476
2689
|
otherside_coeffs = nil
|
|
2477
2690
|
model.getSurfacePropertyOtherSideCoefficientss.each do |c|
|
|
2478
2691
|
next unless c.name.to_s == exterior_adjacent_to
|
|
@@ -2493,7 +2706,7 @@ class OSModel
|
|
|
2493
2706
|
surface.setWindExposure('NoWind')
|
|
2494
2707
|
end
|
|
2495
2708
|
|
|
2496
|
-
def
|
|
2709
|
+
def get_space_temperature_schedule(model, location, spaces)
|
|
2497
2710
|
# Create outside boundary schedules to be actuated by EMS,
|
|
2498
2711
|
# can be shared by any surface, duct adjacent to / located in those spaces
|
|
2499
2712
|
|
|
@@ -2506,12 +2719,13 @@ class OSModel
|
|
|
2506
2719
|
|
|
2507
2720
|
sch = OpenStudio::Model::ScheduleConstant.new(model)
|
|
2508
2721
|
sch.setName(location)
|
|
2722
|
+
sch.additionalProperties.setFeature('ObjectType', location)
|
|
2509
2723
|
|
|
2510
2724
|
space_values = Geometry.get_temperature_scheduled_space_values(location)
|
|
2511
2725
|
|
|
2512
2726
|
if location == HPXML::LocationOtherHeatedSpace
|
|
2513
2727
|
# Create a sensor to get dynamic heating setpoint
|
|
2514
|
-
htg_sch = spaces[HPXML::
|
|
2728
|
+
htg_sch = spaces[HPXML::LocationConditionedSpace].thermalZone.get.thermostatSetpointDualSetpoint.get.heatingSetpointTemperatureSchedule.get
|
|
2515
2729
|
sensor_htg_spt = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Schedule Value')
|
|
2516
2730
|
sensor_htg_spt.setName('htg_spt')
|
|
2517
2731
|
sensor_htg_spt.setKeyName(htg_sch.name.to_s)
|
|
@@ -2527,7 +2741,7 @@ class OSModel
|
|
|
2527
2741
|
if space_values[:indoor_weight] > 0
|
|
2528
2742
|
sensor_ia = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Air Temperature')
|
|
2529
2743
|
sensor_ia.setName('cond_zone_temp')
|
|
2530
|
-
sensor_ia.setKeyName(spaces[HPXML::
|
|
2744
|
+
sensor_ia.setKeyName(spaces[HPXML::LocationConditionedSpace].thermalZone.get.name.to_s)
|
|
2531
2745
|
end
|
|
2532
2746
|
|
|
2533
2747
|
if space_values[:outdoor_weight] > 0
|
|
@@ -2578,7 +2792,7 @@ class OSModel
|
|
|
2578
2792
|
# Returns an OS:Space, or temperature OS:Schedule for a MF space, or nil if outside
|
|
2579
2793
|
# Should be called when the object's energy use is sensitive to ambient temperature
|
|
2580
2794
|
# (e.g., water heaters and ducts).
|
|
2581
|
-
def
|
|
2795
|
+
def get_space_or_schedule_from_location(location, model, spaces)
|
|
2582
2796
|
return if [HPXML::LocationOtherExterior,
|
|
2583
2797
|
HPXML::LocationOutside,
|
|
2584
2798
|
HPXML::LocationRoofDeck].include? location
|
|
@@ -2603,7 +2817,7 @@ class OSModel
|
|
|
2603
2817
|
# Returns an OS:Space, or nil if a MF space or outside
|
|
2604
2818
|
# Should be called when the object's energy use is NOT sensitive to ambient temperature
|
|
2605
2819
|
# (e.g., appliances).
|
|
2606
|
-
def
|
|
2820
|
+
def get_space_from_location(location, spaces)
|
|
2607
2821
|
return if [HPXML::LocationOutside,
|
|
2608
2822
|
HPXML::LocationOtherHeatedSpace,
|
|
2609
2823
|
HPXML::LocationOtherHousingUnit,
|
|
@@ -2611,13 +2825,13 @@ class OSModel
|
|
|
2611
2825
|
HPXML::LocationOtherNonFreezingSpace].include? location
|
|
2612
2826
|
|
|
2613
2827
|
if HPXML::conditioned_locations.include? location
|
|
2614
|
-
location = HPXML::
|
|
2828
|
+
location = HPXML::LocationConditionedSpace
|
|
2615
2829
|
end
|
|
2616
2830
|
|
|
2617
2831
|
return spaces[location]
|
|
2618
2832
|
end
|
|
2619
2833
|
|
|
2620
|
-
def
|
|
2834
|
+
def set_subsurface_exterior(surface, spaces, model, hpxml_surface)
|
|
2621
2835
|
# Set its parent surface outside boundary condition, which will be also applied to subsurfaces through OS
|
|
2622
2836
|
# The parent surface is entirely comprised of the subsurface.
|
|
2623
2837
|
|
|
@@ -2629,36 +2843,25 @@ class OSModel
|
|
|
2629
2843
|
end
|
|
2630
2844
|
end
|
|
2631
2845
|
|
|
2632
|
-
def
|
|
2633
|
-
# Identify unique Kiva foundations that are required.
|
|
2634
|
-
kiva_fnd_walls = []
|
|
2635
|
-
fnd_walls.each do |foundation_wall|
|
|
2636
|
-
next unless foundation_wall.is_exterior
|
|
2637
|
-
|
|
2638
|
-
kiva_fnd_walls << foundation_wall
|
|
2639
|
-
end
|
|
2640
|
-
if kiva_fnd_walls.empty? # Handle slab foundation type
|
|
2641
|
-
kiva_fnd_walls << nil
|
|
2642
|
-
end
|
|
2643
|
-
|
|
2644
|
-
kiva_slabs = slabs
|
|
2645
|
-
|
|
2646
|
-
return kiva_fnd_walls.product(kiva_slabs)
|
|
2647
|
-
end
|
|
2648
|
-
|
|
2649
|
-
def self.set_foundation_and_walls_top()
|
|
2846
|
+
def set_foundation_and_walls_top()
|
|
2650
2847
|
@foundation_top = 0
|
|
2651
|
-
@
|
|
2848
|
+
@hpxml_bldg.floors.each do |floor|
|
|
2849
|
+
# Keeping the floor at ground level for ASHRAE 140 tests yields the expected results
|
|
2850
|
+
if floor.is_floor && floor.is_exterior && !@apply_ashrae140_assumptions
|
|
2851
|
+
@foundation_top = 2.0
|
|
2852
|
+
end
|
|
2853
|
+
end
|
|
2854
|
+
@hpxml_bldg.foundation_walls.each do |foundation_wall|
|
|
2652
2855
|
top = -1 * foundation_wall.depth_below_grade + foundation_wall.height
|
|
2653
2856
|
@foundation_top = top if top > @foundation_top
|
|
2654
2857
|
end
|
|
2655
|
-
@walls_top = @foundation_top +
|
|
2858
|
+
@walls_top = @foundation_top + @hpxml_bldg.building_construction.average_ceiling_height * @ncfl_ag
|
|
2656
2859
|
end
|
|
2657
2860
|
|
|
2658
|
-
def
|
|
2659
|
-
return if @
|
|
2861
|
+
def set_heating_and_cooling_seasons()
|
|
2862
|
+
return if @hpxml_bldg.hvac_controls.size == 0
|
|
2660
2863
|
|
|
2661
|
-
hvac_control = @
|
|
2864
|
+
hvac_control = @hpxml_bldg.hvac_controls[0]
|
|
2662
2865
|
|
|
2663
2866
|
htg_start_month = hvac_control.seasons_heating_begin_month
|
|
2664
2867
|
htg_start_day = hvac_control.seasons_heating_begin_day
|
|
@@ -2669,8 +2872,8 @@ class OSModel
|
|
|
2669
2872
|
clg_end_month = hvac_control.seasons_cooling_end_month
|
|
2670
2873
|
clg_end_day = hvac_control.seasons_cooling_end_day
|
|
2671
2874
|
|
|
2672
|
-
@heating_days = Schedule.get_daily_season(@
|
|
2673
|
-
@cooling_days = Schedule.get_daily_season(@
|
|
2875
|
+
@heating_days = Schedule.get_daily_season(@hpxml_header.sim_calendar_year, htg_start_month, htg_start_day, htg_end_month, htg_end_day)
|
|
2876
|
+
@cooling_days = Schedule.get_daily_season(@hpxml_header.sim_calendar_year, clg_start_month, clg_start_day, clg_end_month, clg_end_day)
|
|
2674
2877
|
end
|
|
2675
2878
|
end
|
|
2676
2879
|
|