openstudio-calibration 0.1.3 → 0.5.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 +5 -5
- data/.gitignore +1 -0
- data/.rubocop.yml +7 -0
- data/CHANGELOG.md +40 -8
- data/Gemfile +6 -3
- data/Jenkinsfile +7 -2
- data/LICENSE.md +1 -1
- data/README.md +15 -4
- data/Rakefile +6 -6
- data/doc_templates/LICENSE.md +1 -1
- data/doc_templates/copyright_erb.txt +1 -1
- data/doc_templates/copyright_js.txt +1 -1
- data/doc_templates/copyright_ruby.txt +1 -1
- data/lib/measures/AddMonthlyJSONUtilityData/LICENSE.md +1 -1
- data/lib/measures/AddMonthlyJSONUtilityData/measure.rb +1 -1
- data/lib/measures/AddMonthlyJSONUtilityData/measure.xml +12 -11
- data/lib/measures/AddMonthlyUtilityData/LICENSE.md +1 -1
- data/lib/measures/AddMonthlyUtilityData/measure.rb +1 -1
- data/lib/measures/AddMonthlyUtilityData/measure.xml +13 -12
- data/lib/measures/CalibrationReports/LICENSE.md +1 -1
- data/lib/measures/CalibrationReports/README.md +2 -2
- data/lib/measures/CalibrationReports/measure.rb +1 -1
- data/lib/measures/CalibrationReports/measure.xml +11 -11
- data/lib/measures/CalibrationReportsEnhanced/LICENSE.md +1 -1
- data/lib/measures/CalibrationReportsEnhanced/measure.rb +2 -2
- data/lib/measures/CalibrationReportsEnhanced/measure.xml +18 -17
- data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/LICENSE.md +1 -1
- data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/measure.rb +1 -1
- data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/measure.xml +14 -13
- data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/LICENSE.md +1 -1
- data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/measure.rb +1 -1
- data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/measure.xml +14 -13
- data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/LICENSE.md +1 -1
- data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/measure.rb +1 -1
- data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/measure.xml +14 -13
- data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/LICENSE.md +1 -1
- data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/measure.rb +1 -1
- data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/measure.xml +14 -13
- data/lib/measures/CoilCoolingWaterMultiplier/LICENSE.md +1 -1
- data/lib/measures/CoilCoolingWaterMultiplier/measure.rb +1 -1
- data/lib/measures/CoilCoolingWaterMultiplier/measure.xml +14 -13
- data/lib/measures/CoilCoolingWaterPercentChange/LICENSE.md +1 -1
- data/lib/measures/CoilCoolingWaterPercentChange/measure.rb +1 -1
- data/lib/measures/CoilCoolingWaterPercentChange/measure.xml +14 -13
- data/lib/measures/CoilHeatingElectricMultiplier/LICENSE.md +1 -1
- data/lib/measures/CoilHeatingElectricMultiplier/measure.rb +1 -1
- data/lib/measures/CoilHeatingElectricMultiplier/measure.xml +14 -13
- data/lib/measures/CoilHeatingElectricPercentChange/LICENSE.md +1 -1
- data/lib/measures/CoilHeatingElectricPercentChange/measure.rb +1 -1
- data/lib/measures/CoilHeatingElectricPercentChange/measure.xml +14 -13
- data/lib/measures/CoilHeatingGasMultiplier/LICENSE.md +1 -1
- data/lib/measures/CoilHeatingGasMultiplier/measure.rb +1 -1
- data/lib/measures/CoilHeatingGasMultiplier/measure.xml +14 -13
- data/lib/measures/CoilHeatingGasPercentChange/LICENSE.md +1 -1
- data/lib/measures/CoilHeatingGasPercentChange/measure.rb +1 -1
- data/lib/measures/CoilHeatingGasPercentChange/measure.xml +14 -13
- data/lib/measures/CoilHeatingWaterMultiplier/LICENSE.md +1 -1
- data/lib/measures/CoilHeatingWaterMultiplier/measure.rb +1 -1
- data/lib/measures/CoilHeatingWaterMultiplier/measure.xml +14 -13
- data/lib/measures/CoilHeatingWaterPercentChange/LICENSE.md +1 -1
- data/lib/measures/CoilHeatingWaterPercentChange/measure.rb +1 -1
- data/lib/measures/CoilHeatingWaterPercentChange/measure.xml +14 -13
- data/lib/measures/ConstructionLayerZeroMaterialProperties/LICENSE.md +1 -1
- data/lib/measures/ConstructionLayerZeroMaterialProperties/measure.rb +1 -1
- data/lib/measures/ConstructionLayerZeroMaterialProperties/measure.xml +12 -11
- data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/LICENSE.md +1 -1
- data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/measure.rb +1 -1
- data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/measure.xml +12 -11
- data/lib/measures/ExteriorWallThermalPropertiesMultiplier/LICENSE.md +1 -1
- data/lib/measures/ExteriorWallThermalPropertiesMultiplier/measure.rb +3 -3
- data/lib/measures/ExteriorWallThermalPropertiesMultiplier/measure.xml +24 -11
- data/lib/measures/ExteriorWallThermalPropertiesPercentChange/LICENSE.md +1 -1
- data/lib/measures/ExteriorWallThermalPropertiesPercentChange/measure.rb +3 -3
- data/lib/measures/ExteriorWallThermalPropertiesPercentChange/measure.xml +24 -11
- data/lib/measures/FansMultiplier/LICENSE.md +1 -1
- data/lib/measures/FansMultiplier/measure.rb +1 -1
- data/lib/measures/FansMultiplier/measure.xml +14 -13
- data/lib/measures/FansPercentChange/LICENSE.md +1 -1
- data/lib/measures/FansPercentChange/measure.rb +1 -1
- data/lib/measures/FansPercentChange/measure.xml +14 -13
- data/lib/measures/GeneralCalibrationMeasureMultiplier/LICENSE.md +1 -1
- data/lib/measures/GeneralCalibrationMeasureMultiplier/measure.rb +1 -1
- data/lib/measures/GeneralCalibrationMeasureMultiplier/measure.xml +16 -15
- data/lib/measures/GeneralCalibrationMeasurePercentChange/LICENSE.md +1 -1
- data/lib/measures/GeneralCalibrationMeasurePercentChange/measure.rb +1 -1
- data/lib/measures/GeneralCalibrationMeasurePercentChange/measure.xml +16 -15
- data/lib/measures/HardSizeHvac/LICENSE.md +1 -1
- data/lib/measures/HardSizeHvac/measure.rb +1 -1
- data/lib/measures/HardSizeHvac/measure.xml +13 -12
- data/lib/measures/RValueOfInsulationForConstructionMultiplier/LICENSE.md +1 -1
- data/lib/measures/RValueOfInsulationForConstructionMultiplier/measure.rb +1 -1
- data/lib/measures/RValueOfInsulationForConstructionMultiplier/measure.xml +12 -11
- data/lib/measures/RValueOfInsulationForConstructionPercentageChange/LICENSE.md +1 -1
- data/lib/measures/RValueOfInsulationForConstructionPercentageChange/measure.rb +1 -1
- data/lib/measures/RValueOfInsulationForConstructionPercentageChange/measure.xml +12 -11
- data/lib/measures/RoofThermalPropertiesMultiplier/LICENSE.md +1 -1
- data/lib/measures/RoofThermalPropertiesMultiplier/measure.rb +3 -3
- data/lib/measures/RoofThermalPropertiesMultiplier/measure.xml +24 -11
- data/lib/measures/RoofThermalPropertiesPercentChange/LICENSE.md +1 -1
- data/lib/measures/RoofThermalPropertiesPercentChange/measure.rb +3 -3
- data/lib/measures/RoofThermalPropertiesPercentChange/measure.xml +24 -11
- data/lib/measures/TimeseriesObjectiveFunction/LICENSE.md +1 -1
- data/lib/measures/TimeseriesObjectiveFunction/README.md +5 -171
- data/lib/measures/TimeseriesObjectiveFunction/measure.rb +3 -7
- data/lib/measures/TimeseriesObjectiveFunction/measure.xml +84 -9
- data/lib/measures/TimeseriesObjectiveFunction/resources/report.html.erb +6 -1
- data/lib/measures/TimeseriesPlot/LICENSE.md +1 -1
- data/lib/measures/TimeseriesPlot/README.md +5 -35
- data/lib/measures/TimeseriesPlot/measure.rb +1 -1
- data/lib/measures/TimeseriesPlot/measure.xml +28 -13
- data/lib/measures/TimeseriesPlot/resources/report.html.erb +6 -1
- data/lib/measures/WaterHeaterMixedMultiplier/LICENSE.md +1 -1
- data/lib/measures/WaterHeaterMixedMultiplier/measure.rb +1 -1
- data/lib/measures/WaterHeaterMixedMultiplier/measure.xml +14 -13
- data/lib/measures/WaterHeaterMixedPercentChange/LICENSE.md +1 -1
- data/lib/measures/WaterHeaterMixedPercentChange/measure.rb +1 -1
- data/lib/measures/WaterHeaterMixedPercentChange/measure.xml +14 -13
- data/lib/measures/{CalibrationReportsEnhanced21 → inspect_and_edit_parametric_schedules}/LICENSE.md +1 -1
- data/lib/measures/inspect_and_edit_parametric_schedules/README.md +41 -0
- data/lib/measures/{zone_report → inspect_and_edit_parametric_schedules}/README.md.erb +12 -1
- data/lib/measures/inspect_and_edit_parametric_schedules/docs/.gitkeep +0 -0
- data/lib/measures/inspect_and_edit_parametric_schedules/docs/apply_measures_now.png +0 -0
- data/lib/measures/inspect_and_edit_parametric_schedules/measure.rb +224 -0
- data/lib/measures/inspect_and_edit_parametric_schedules/measure.xml +125 -0
- data/lib/measures/{zone_report → shift_hours_of_operation}/LICENSE.md +1 -1
- data/lib/measures/shift_hours_of_operation/README.md +147 -0
- data/lib/measures/{MaalkaMonthlyJSONUtilityData → shift_hours_of_operation}/README.md.erb +5 -0
- data/lib/measures/shift_hours_of_operation/docs/.gitkeep +0 -0
- data/lib/measures/shift_hours_of_operation/measure.rb +525 -0
- data/lib/measures/shift_hours_of_operation/measure.xml +280 -0
- data/lib/openstudio/{calibration_measures → calibration}/extension.rb +2 -2
- data/lib/openstudio/{calibration_measures → calibration}/version.rb +3 -3
- data/lib/openstudio/{calibration_measures.rb → calibration.rb} +3 -3
- data/lib/{openstudio-calibration-measures.rb → openstudio-calibration.rb} +2 -2
- data/openstudio-calibration.gemspec +38 -0
- metadata +50 -61
- data/lib/measures/AddMonthlyUtilityData/tests/AddMonthlyUtilityData_Test.rb +0 -88
- data/lib/measures/AddMonthlyUtilityData/tests/electric_billed_usages.json +0 -198
- data/lib/measures/AddMonthlyUtilityData/tests/gas_billed_usages.json +0 -198
- data/lib/measures/CalibrationReports/tests/CalibrationReports_Test.rb +0 -523
- data/lib/measures/CalibrationReports/tests/ExampleModel.osm +0 -10497
- data/lib/measures/CalibrationReports/tests/ExampleModelNoDemandInput.osm +0 -10560
- data/lib/measures/CalibrationReports/tests/ExampleModelNoGasInput.osm +0 -10456
- data/lib/measures/CalibrationReports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +0 -8768
- data/lib/measures/CalibrationReportsEnhanced/tests/CalibrationReportsEnhanced_Test.rb +0 -734
- data/lib/measures/CalibrationReportsEnhanced/tests/ExampleModel.osm +0 -10497
- data/lib/measures/CalibrationReportsEnhanced/tests/ExampleModel_FuelOil.osm +0 -12740
- data/lib/measures/CalibrationReportsEnhanced/tests/USA_CO_Golden-NREL.724666_TMY3.epw +0 -8768
- data/lib/measures/CalibrationReportsEnhanced21/README.md +0 -109
- data/lib/measures/CalibrationReportsEnhanced21/README.md.erb +0 -42
- data/lib/measures/CalibrationReportsEnhanced21/measure.rb +0 -690
- data/lib/measures/CalibrationReportsEnhanced21/measure.xml +0 -269
- data/lib/measures/CalibrationReportsEnhanced21/resources/report.html.in +0 -380
- data/lib/measures/MaalkaMonthlyJSONUtilityData/LICENSE.md +0 -27
- data/lib/measures/MaalkaMonthlyJSONUtilityData/README.md +0 -104
- data/lib/measures/MaalkaMonthlyJSONUtilityData/measure.rb +0 -304
- data/lib/measures/MaalkaMonthlyJSONUtilityData/measure.xml +0 -216
- data/lib/measures/zone_report/README.md +0 -26
- data/lib/measures/zone_report/measure.rb +0 -706
- data/lib/measures/zone_report/measure.xml +0 -67
- data/lib/measures/zone_report/resources/report.html.in +0 -342
- data/openstudio-calibration-measures.gemspec +0 -30
@@ -1,706 +0,0 @@
|
|
1
|
-
# *******************************************************************************
|
2
|
-
# OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
|
3
|
-
# All rights reserved.
|
4
|
-
# Redistribution and use in source and binary forms, with or without
|
5
|
-
# modification, are permitted provided that the following conditions are met:
|
6
|
-
#
|
7
|
-
# (1) Redistributions of source code must retain the above copyright notice,
|
8
|
-
# this list of conditions and the following disclaimer.
|
9
|
-
#
|
10
|
-
# (2) Redistributions in binary form must reproduce the above copyright notice,
|
11
|
-
# this list of conditions and the following disclaimer in the documentation
|
12
|
-
# and/or other materials provided with the distribution.
|
13
|
-
#
|
14
|
-
# (3) Neither the name of the copyright holder nor the names of any contributors
|
15
|
-
# may be used to endorse or promote products derived from this software without
|
16
|
-
# specific prior written permission from the respective party.
|
17
|
-
#
|
18
|
-
# (4) Other than as required in clauses (1) and (2), distributions in any form
|
19
|
-
# of modifications or other derivative works may not use the "OpenStudio"
|
20
|
-
# trademark, "OS", "os", or any other confusingly similar designation without
|
21
|
-
# specific prior written permission from Alliance for Sustainable Energy, LLC.
|
22
|
-
#
|
23
|
-
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
|
24
|
-
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
25
|
-
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
26
|
-
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
|
27
|
-
# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
|
28
|
-
# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
29
|
-
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
30
|
-
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
31
|
-
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
32
|
-
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
33
|
-
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
34
|
-
# *******************************************************************************
|
35
|
-
|
36
|
-
require 'erb'
|
37
|
-
# require 'pry'
|
38
|
-
|
39
|
-
# start the measure
|
40
|
-
class ZoneReport < OpenStudio::Measure::ReportingMeasure
|
41
|
-
# define the name that a user will see, this method may be deprecated as
|
42
|
-
# the display name in PAT comes from the name field in measure.xml
|
43
|
-
def name
|
44
|
-
'Zone Report'
|
45
|
-
end
|
46
|
-
|
47
|
-
# define the arguments that the user will input
|
48
|
-
def arguments
|
49
|
-
args = OpenStudio::Measure::OSArgumentVector.new
|
50
|
-
args
|
51
|
-
end # end the arguments method
|
52
|
-
|
53
|
-
# return a vector of IdfObject's to request EnergyPlus objects needed by the run method
|
54
|
-
def energyPlusOutputRequests(runner, user_arguments)
|
55
|
-
super(runner, user_arguments)
|
56
|
-
|
57
|
-
result = OpenStudio::IdfObjectVector.new
|
58
|
-
|
59
|
-
# use the built-in error checking
|
60
|
-
return result unless runner.validateUserArguments(arguments, user_arguments)
|
61
|
-
|
62
|
-
request = OpenStudio::IdfObject.load('Output:Table:SummaryReports,AllSummaryAndSizingPeriod;').get
|
63
|
-
result << request
|
64
|
-
|
65
|
-
result
|
66
|
-
end
|
67
|
-
|
68
|
-
# Method to make class names nicer (remove OS and _)
|
69
|
-
def niceClassName(class_name)
|
70
|
-
class_name = class_name.gsub('OS_', '')
|
71
|
-
class_name = class_name.tr('_', ' ')
|
72
|
-
class_name
|
73
|
-
end
|
74
|
-
|
75
|
-
# Convert a value from the view TabularDataWithStrings from the unit represented there to the given unit.
|
76
|
-
# We make a bunch of special cases for unit aliases used by EnergyPlus which are not in the default
|
77
|
-
# list of OpenStudio conversions
|
78
|
-
# We also special case a few conversions for unitless 'units' so that our final display makes more sense to the user.
|
79
|
-
# When the property is not present (for instance, cooled beams don't have properties in the sql file under 1.5)
|
80
|
-
# this method will return "-" as a placeholder.
|
81
|
-
def eplus_to_openstudio(unitstr)
|
82
|
-
unitstr.gsub('m3', 'm^3').gsub('pa', 'Pa').gsub('m2', 'm^2').gsub(' per ', '/')
|
83
|
-
end
|
84
|
-
|
85
|
-
def convert_prop(property, final_units)
|
86
|
-
return ['-', '-'] unless property
|
87
|
-
|
88
|
-
return [property[0].to_f.round(2), ''] if final_units.empty?
|
89
|
-
return [(property[0].to_f * 100).round(2), '%'] if final_units == '%'
|
90
|
-
return [property[0].to_f.round(2), 'COP'] if final_units == 'COP'
|
91
|
-
|
92
|
-
initial_units = eplus_to_openstudio(property[1])
|
93
|
-
converted = OpenStudio.convert(property[0].to_f, initial_units, final_units)
|
94
|
-
if converted.empty?
|
95
|
-
"Could not convert from #{initial_units} to #{final_units}"
|
96
|
-
else
|
97
|
-
final_units = final_units.gsub('inH_{2}O', 'in. w.c.')
|
98
|
-
[converted.get.round(2), final_units]
|
99
|
-
end
|
100
|
-
end
|
101
|
-
|
102
|
-
def properties_for_cooling_coil(e, props, parent)
|
103
|
-
autosized = case e.iddObjectType
|
104
|
-
when OpenStudio::Model::CoilCoolingDXSingleSpeed.iddObjectType
|
105
|
-
coil = e.to_CoilCoolingDXSingleSpeed.get
|
106
|
-
coil.isRatedTotalCoolingCapacityAutosized && coil.isRatedSensibleHeatRatioAutosized && coil.isRatedAirFlowRateAutosized ? 'Yes' : 'No'
|
107
|
-
when OpenStudio::Model::CoilCoolingWater.iddObjectType
|
108
|
-
coil = e.to_CoilCoolingWater.get
|
109
|
-
coil.isDesignWaterFlowRateAutosized && coil.isDesignAirFlowRateAutosized && coil.isDesignInletWaterTemperatureAutosized ? 'Yes' : 'No'
|
110
|
-
when OpenStudio::Model::CoilCoolingWaterToAirHeatPumpEquationFit.iddObjectType
|
111
|
-
coil = e.to_CoilCoolingWaterToAirHeatPumpEquationFit.get
|
112
|
-
coil.isRatedTotalCoolingCapacityAutosized && coil.isRatedSensibleHeatRatioAutosized && coil.isRatedAirFlowRateAutosized ? 'Yes' : 'No'
|
113
|
-
else
|
114
|
-
'?'
|
115
|
-
end
|
116
|
-
|
117
|
-
coolingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
|
118
|
-
coolingeff = convert_prop(props['Nominal Efficiency'], 'COP')
|
119
|
-
sensibleheatratio = convert_prop(props['Nominal Sensible Heat Ratio'], '')
|
120
|
-
parent_name = parent.name.get
|
121
|
-
name = e.name.get
|
122
|
-
coiltype = niceClassName(e.iddObjectType.valueName)
|
123
|
-
|
124
|
-
{ 'Terminal/Zone Equip Name' => parent_name, 'Coil Type' => coiltype, 'Name' => name, 'Autosized' => autosized, 'Nominal Capacity' => coolingcap, 'Nominal Efficiency' => coolingeff, 'Nominal SHR' => sensibleheatratio }
|
125
|
-
end
|
126
|
-
|
127
|
-
def properties_for_heating_coil(e, props, parent)
|
128
|
-
autosized = '-'
|
129
|
-
eff_units = 'COP'
|
130
|
-
heatingcap = ['-', '-']
|
131
|
-
heatingeff = ['-', '-']
|
132
|
-
case e.iddObjectType
|
133
|
-
when OpenStudio::Model::CoilHeatingElectric.iddObjectType
|
134
|
-
coil = e.to_CoilHeatingElectric.get
|
135
|
-
autosized = coil.isNominalCapacityAutosized ? 'Yes' : 'No'
|
136
|
-
heatingcap = convert_prop(props['Nominal Total Capacity'], 'kW')
|
137
|
-
heatingeff = convert_prop(props['Nominal Efficiency'], '%')
|
138
|
-
when OpenStudio::Model::CoilHeatingGas.iddObjectType
|
139
|
-
coil = e.to_CoilHeatingGas.get
|
140
|
-
autosized = coil.isNominalCapacityAutosized ? 'Yes' : 'No'
|
141
|
-
heatingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
|
142
|
-
heatingeff = convert_prop(props['Nominal Efficiency'], 'COP')
|
143
|
-
when OpenStudio::Model::CoilHeatingDXSingleSpeed.iddObjectType
|
144
|
-
coil = e.to_CoilHeatingDXSingleSpeed.get
|
145
|
-
autosized = coil.isRatedTotalHeatingCapacityAutosized && coil.isRatedAirFlowRateAutosized ? 'Yes' : 'No'
|
146
|
-
heatingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
|
147
|
-
heatingeff = convert_prop(props['Nominal Efficiency'], 'COP')
|
148
|
-
when OpenStudio::Model::CoilHeatingWater.iddObjectType
|
149
|
-
coil = e.to_CoilHeatingWater.get
|
150
|
-
autosized = coil.isMaximumWaterFlowRateAutosized && coil.isRatedCapacityAutosized && coil.isUFactorTimesAreaValueAutosized ? 'Yes' : 'No'
|
151
|
-
heatingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
|
152
|
-
heatingeff = ['-', '-']
|
153
|
-
when OpenStudio::Model::CoilHeatingWaterBaseboard.iddObjectType
|
154
|
-
coil = e.to_CoilHeatingWaterBaseboard.get
|
155
|
-
autosized = coil.isMaximumWaterFlowRateAutosized && coil.isUFactorTimesAreaValueAutosized ? 'Yes' : 'No'
|
156
|
-
heatingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
|
157
|
-
heatingeff = ['-', '-']
|
158
|
-
when OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit.iddObjectType
|
159
|
-
coil = e.to_CoilHeatingWaterToAirHeatPumpEquationFit.get
|
160
|
-
autosized = coil.isRatedHeatingCapacityAutosized && coil.isRatedAirFlowRateAutosized && coil.isRatedWaterFlowRateAutosized ? 'Yes' : 'No'
|
161
|
-
heatingcap = convert_prop(props['Nominal Total Capacity'], 'kBtu/hr')
|
162
|
-
heatingeff = convert_prop(props['Nominal Efficiency'], 'COP')
|
163
|
-
else
|
164
|
-
autosized = '?'
|
165
|
-
end
|
166
|
-
|
167
|
-
parent_name = parent.name.get
|
168
|
-
name = e.name.get
|
169
|
-
coiltype = niceClassName(e.iddObjectType.valueName)
|
170
|
-
|
171
|
-
{ 'Terminal/Zone Equip Name' => parent_name, 'Coil Type' => coiltype, 'Name' => name, 'Autosized' => autosized, 'Nominal Capacity' => heatingcap, 'Nominal Efficiency' => heatingeff }
|
172
|
-
end
|
173
|
-
|
174
|
-
def properties_for_fan(equipment, properties, parent)
|
175
|
-
autosized = case equipment.iddObjectType
|
176
|
-
when OpenStudio::Model::FanConstantVolume.iddObjectType
|
177
|
-
fan = equipment.to_FanConstantVolume.get
|
178
|
-
fan.isMaximumFlowRateAutosized ? 'Yes' : 'No'
|
179
|
-
when OpenStudio::Model::FanVariableVolume.iddObjectType
|
180
|
-
fan = equipment.to_FanVariableVolume.get
|
181
|
-
fan.isMaximumFlowRateAutosized ? 'Yes' : 'No'
|
182
|
-
when OpenStudio::Model::FanOnOff.iddObjectType
|
183
|
-
fan = equipment.to_FanOnOff.get
|
184
|
-
fan.isMaximumFlowRateAutosized ? 'Yes' : 'No'
|
185
|
-
when OpenStudio::Model::FanZoneExhaust.iddObjectType
|
186
|
-
'N/A'
|
187
|
-
else
|
188
|
-
'?'
|
189
|
-
end
|
190
|
-
|
191
|
-
name = equipment.name.get
|
192
|
-
parent_name = parent.name.get
|
193
|
-
maxflowrate = convert_prop(properties['Max Air Flow Rate'], 'cfm')
|
194
|
-
fanpressure = convert_prop(properties['Delta Pressure'], 'inH_{2}O')
|
195
|
-
totalefficiency = convert_prop(properties['Total Efficiency'], '%')
|
196
|
-
ratedfanpower = convert_prop(properties['Rated Electric Power'], 'W')
|
197
|
-
{ 'Terminal/Zone Equip Name' => parent_name, 'Fan Type' => niceClassName(equipment.iddObjectType.valueName), 'Name' => name, 'Autosized' => autosized, 'Max Flow' => maxflowrate, 'Efficiency' => totalefficiency, 'Pressure' => fanpressure, 'Power' => ratedfanpower }
|
198
|
-
end
|
199
|
-
|
200
|
-
# Each equipment is grouped into Heating, Cooling or Fans and has properties extracted appropriate for that group.
|
201
|
-
# This method returns a tuple [equipment group, properties] where properties is a hash of name, value or name, [value, units] pairs
|
202
|
-
def properties_for_zone_equipment(equipment, equipment_properties, parent)
|
203
|
-
# Make properties an empty hash if it was nil
|
204
|
-
equipment_properties ||= {}
|
205
|
-
if /^OS_Coil_Cooling/ =~ equipment.iddObjectType.valueName
|
206
|
-
return 'Cooling', properties_for_cooling_coil(equipment, equipment_properties, parent)
|
207
|
-
elsif /^OS_Coil_Heating/ =~ equipment.iddObjectType.valueName
|
208
|
-
return 'Heating', properties_for_heating_coil(equipment, equipment_properties, parent)
|
209
|
-
elsif /^OS_Fan/ =~ equipment.iddObjectType.valueName
|
210
|
-
return 'Fans', properties_for_fan(equipment, equipment_properties, parent)
|
211
|
-
elsif OpenStudio::Model::ZoneHVACBaseboardConvectiveElectric.iddObjectType == equipment.iddObjectType
|
212
|
-
baseboard = equipment.to_ZoneHVACBaseboardConvectiveElectric.get
|
213
|
-
autosized = baseboard.isNominalCapacityAutosized ? 'Yes' : 'No'
|
214
|
-
heatingcap = convert_prop(equipment_properties['Design Size Nominal Capacity'], 'kW')
|
215
|
-
name = baseboard.name.get
|
216
|
-
coiltype = niceClassName(baseboard.iddObjectType.valueName)
|
217
|
-
return 'Heating', { 'Terminal/Zone Equip Name' => name, 'Coil Type' => coiltype, 'Name' => name, 'Autosized' => autosized, 'Nominal Capacity' => heatingcap, 'Nominal Efficiency' => [100, '%'] }
|
218
|
-
else
|
219
|
-
return nil, nil
|
220
|
-
end
|
221
|
-
end
|
222
|
-
|
223
|
-
# define what happens when the measure is run
|
224
|
-
def run(runner, user_arguments)
|
225
|
-
super(runner, user_arguments)
|
226
|
-
|
227
|
-
# use the built-in error checking
|
228
|
-
return false unless runner.validateUserArguments(arguments, user_arguments)
|
229
|
-
|
230
|
-
@runner = runner
|
231
|
-
|
232
|
-
# get the last model and sql file
|
233
|
-
|
234
|
-
model = runner.lastOpenStudioModel
|
235
|
-
if model.empty?
|
236
|
-
runner.registerError('Cannot find last model.')
|
237
|
-
return false
|
238
|
-
end
|
239
|
-
model = model.get
|
240
|
-
|
241
|
-
@sqlFile = runner.lastEnergyPlusSqlFile
|
242
|
-
if @sqlFile.empty?
|
243
|
-
runner.registerError('Cannot find last sql file.')
|
244
|
-
return false
|
245
|
-
end
|
246
|
-
@sqlFile = @sqlFile.get
|
247
|
-
model.setSqlFile(@sqlFile)
|
248
|
-
|
249
|
-
@graph_data = []
|
250
|
-
|
251
|
-
# Collect and collate information about the hvac equipment
|
252
|
-
# When we are done we will have a hash of equipment keyed by equipment name
|
253
|
-
# who's values are hashes keyed by the property name. The values of the
|
254
|
-
# property hashes are [value, unit] pairs
|
255
|
-
# Some types of equipment (for instance CoilCoolingCooledBeams) are not present
|
256
|
-
# in the database as of OS 1.5
|
257
|
-
|
258
|
-
# find table names, etc. in the SupportZoneHVACEquipFields
|
259
|
-
tableNames = getDataByColumn('TableName')
|
260
|
-
columnNames = getDataByColumn('ColumnName')
|
261
|
-
rowNames = getDataByColumn('RowName')
|
262
|
-
units = getDataByColumn('Units')
|
263
|
-
values = getDataByColumn('Value')
|
264
|
-
equipment_rows = tableNames.zip(columnNames, rowNames, units, values)
|
265
|
-
equipment = {}
|
266
|
-
equipment_rows.each do |r|
|
267
|
-
_, field, name, units, value = r
|
268
|
-
next unless name != 'None'
|
269
|
-
eh = equipment[name] || {}
|
270
|
-
eh[field] = [value, units]
|
271
|
-
equipment[name] = eh
|
272
|
-
end
|
273
|
-
|
274
|
-
@zone_collection = []
|
275
|
-
|
276
|
-
@testData = {}
|
277
|
-
|
278
|
-
# Go through each zone in the model and collect all the zone equipment
|
279
|
-
model.getThermalZones.sort.each do |thermalZone|
|
280
|
-
# Skip unconditioned zones
|
281
|
-
if thermalZone.thermostatSetpointDualSetpoint.empty?
|
282
|
-
@runner.registerInfo("Skipping #{thermalZone.name} because it is unconditioned.")
|
283
|
-
next
|
284
|
-
end
|
285
|
-
|
286
|
-
# Skip plenums
|
287
|
-
if thermalZone.isPlenum == true
|
288
|
-
@runner.registerInfo("Skipping #{thermalZone.name} because it is a plenum.")
|
289
|
-
next
|
290
|
-
end
|
291
|
-
|
292
|
-
zone_equipment = {}
|
293
|
-
|
294
|
-
thermalZone.equipment.each do |e|
|
295
|
-
childquipment = e.to_ParentObject.get.children
|
296
|
-
# Look for data on the top level equipment and each of that equipment's children
|
297
|
-
found_primary_heat = false
|
298
|
-
([e] + childquipment).each do |ce|
|
299
|
-
ename = ce.name.get.upcase
|
300
|
-
reporting_type, equipment_properties = properties_for_zone_equipment(ce, equipment[ename], e)
|
301
|
-
next unless equipment_properties
|
302
|
-
# The first heating coil in a zone equipment chain will be primary heating; all
|
303
|
-
# following heating coils will be marked as Backup Heating.
|
304
|
-
if reporting_type == 'Heating'
|
305
|
-
reporting_type = 'Backup Heating' if found_primary_heat
|
306
|
-
found_primary_heat = true
|
307
|
-
end
|
308
|
-
# Find the priority for heating or cooling equipment - the priority is based on the 'parent' zone equipment priority
|
309
|
-
if reporting_type == 'Heating'
|
310
|
-
equipment_properties['Priority'] = (thermalZone.equipmentInHeatingOrder.index { |ze| ze.name.get == e.name.get && ze.iddObjectType == e.iddObjectType }) + 1
|
311
|
-
end
|
312
|
-
if reporting_type == 'Cooling'
|
313
|
-
equipment_properties['Priority'] = (thermalZone.equipmentInCoolingOrder.index { |ze| ze.name.get == e.name.get && ze.iddObjectType == e.iddObjectType }) + 1
|
314
|
-
end
|
315
|
-
# If we don't yet have equipment of this type, make a new array. Then add
|
316
|
-
# our equipment information to the array and update our zone equipment hash.
|
317
|
-
equip_of_type = zone_equipment[reporting_type] || []
|
318
|
-
equip_of_type << equipment_properties
|
319
|
-
zone_equipment[reporting_type] = equip_of_type
|
320
|
-
end
|
321
|
-
end
|
322
|
-
|
323
|
-
zoneMetrics = {}
|
324
|
-
zoneMetrics[:name] = !thermalZone.name.empty? ? thermalZone.name.get : ''
|
325
|
-
zoneMetrics[:equipment] = zone_equipment
|
326
|
-
zoneMetrics[:area] = OpenStudio.convert(thermalZone.floorArea, 'm^2', 'ft^2').get.round(2)
|
327
|
-
|
328
|
-
@currentZoneName = zoneMetrics[:name]
|
329
|
-
|
330
|
-
vals = {}
|
331
|
-
|
332
|
-
vals[:va] = getDetailsData('LightingSummary', 'Entire Facility', 'Interior Lighting', "#{zoneMetrics[:name]}%", 'Lighting Power Density', 'W/m2', 'W/ft^2').round(2)
|
333
|
-
vals[:vb] = getDetailsData('LightingSummary', 'Entire Facility', 'Interior Lighting', "#{zoneMetrics[:name]}%", 'Full Load Hours/Week', 'hr', 'hr').round(2)
|
334
|
-
|
335
|
-
vals[:vc] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorLights:Electricity:Zone:#{zoneMetrics[:name]}", 'Electricity Annual Value', 'GJ', 'kWh').round(2)
|
336
|
-
|
337
|
-
vals[:vd] = getDetailsData('InputVerificationandResultsSummary', 'Entire Facility', 'Zone Summary', zoneMetrics[:name], 'Plug and Process', 'W/m2', 'W/ft^2').round(2)
|
338
|
-
|
339
|
-
vals[:ve] = getDetailsData('InputVerificationandResultsSummary', 'Entire Facility', 'Zone Summary', zoneMetrics[:name], 'Area', 'm2', 'ft^2').round(2)
|
340
|
-
|
341
|
-
vals[:vf] = getDetailsData('InputVerificationandResultsSummary', 'Entire Facility', 'Zone Summary', zoneMetrics[:name], 'Conditioned (Y/N)', '', 's')
|
342
|
-
vals[:vf] = 'No' if vals[:vf] == ''
|
343
|
-
|
344
|
-
vals[:vg] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Heating', zoneMetrics[:name], 'User Design Load', 'W', 'kBtu/hr').round(2)
|
345
|
-
vals[:vh] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Heating', zoneMetrics[:name], 'User Design Air Flow', 'm3/s', 'ft^3/s').round(2)
|
346
|
-
vals[:vi] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Cooling', zoneMetrics[:name], 'User Design Load', 'W', 'kBtu/hr').round(2)
|
347
|
-
vals[:vj] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Cooling', zoneMetrics[:name], 'User Design Air Flow', 'm3/s', 'ft^3/s').round(2)
|
348
|
-
|
349
|
-
vals[:vk] = getDetailsData('OutdoorAirSummary', 'Entire Facility', 'Average Outdoor Air During Occupied Hours', zoneMetrics[:name], 'Mechanical Ventilation', 'ach', 'ach').round(2)
|
350
|
-
vals[:vl] = getDetailsData('OutdoorAirSummary', 'Entire Facility', 'Average Outdoor Air During Occupied Hours', zoneMetrics[:name], 'Infiltration', 'ach', 'ach').round(2)
|
351
|
-
|
352
|
-
vals[:vm] = getDetailsData('InputVerificationandResultsSummary', 'Entire Facility', 'Zone Summary', zoneMetrics[:name], 'People', 'm2 per person', 'ft^2/person').round(2)
|
353
|
-
|
354
|
-
vals[:vn] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Cooling', zoneMetrics[:name], 'Date/Time Of Peak', '', 's')
|
355
|
-
vals[:vo] = getDetailsData('HVACSizingSummary', 'Entire Facility', 'Zone Heating', zoneMetrics[:name], 'Date/Time Of Peak', '', 's')
|
356
|
-
|
357
|
-
vals[:vp] = getDetailsData('SystemSummary', 'Entire Facility', 'Time Setpoint Not Met', zoneMetrics[:name], 'During Heating', 'hr', 'hr')
|
358
|
-
vals[:vq] = getDetailsData('SystemSummary', 'Entire Facility', 'Time Setpoint Not Met', zoneMetrics[:name], 'During Cooling', 'hr', 'hr')
|
359
|
-
|
360
|
-
vals[:vr] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Gas', "InteriorEquipment:Gas:Zone:#{zoneMetrics[:name]}", 'Electricity Annual Value', 'GJ', 'Therm').round(2)
|
361
|
-
vals[:vs] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorEquipment:Electricity:Zone:#{zoneMetrics[:name]}", 'Electricity Annual Value', 'GJ', 'kWh').round(2)
|
362
|
-
|
363
|
-
vals[:vt] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Gas', "InteriorEquipment:Gas:Zone:#{zoneMetrics[:name]}", 'Gas Maximum Value', 'W', 'kBtu/hr').round(2)
|
364
|
-
vals[:vu] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Gas', "InteriorEquipment:Gas:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
|
365
|
-
|
366
|
-
vals[:vv] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorLights:Electricity:Zone:#{zoneMetrics[:name]}", 'Electricity Maximum Value', 'W', 'kW').round(2)
|
367
|
-
vals[:vw] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorLights:Electricity:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
|
368
|
-
|
369
|
-
# X unused
|
370
|
-
|
371
|
-
vals[:vy] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorEquipment:Electricity:Zone:#{zoneMetrics[:name]}", 'Electricity Maximum Value', 'W', 'kW').round(2)
|
372
|
-
vals[:vz] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Electricity', "InteriorEquipment:Electricity:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
|
373
|
-
|
374
|
-
vals[:vaa] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "InteriorEquipment:DistrictHeating:Zone:#{zoneMetrics[:name]}", 'Annual Value', 'GJ', 'kBtu').round(2)
|
375
|
-
vals[:vab] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "InteriorEquipment:DistrictHeating:Zone:#{zoneMetrics[:name]}", 'Maximum Value', 'W', 'kBtu/hr').round(2)
|
376
|
-
vals[:vac] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "InteriorEquipment:DistrictHeating:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
|
377
|
-
|
378
|
-
vals[:vad] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Heating:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Annual Value', 'GJ', 'kBtu').round(2)
|
379
|
-
vals[:vae] = (getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Heating:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Maximum Value', 'W', 'kBtu/hr') / zoneMetrics[:area]).round(2)
|
380
|
-
vals[:vaf] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Heating:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
|
381
|
-
|
382
|
-
vals[:vag] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Cooling:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Annual Value', 'GJ', 'kBtu').round(2)
|
383
|
-
vals[:vah] = (getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Cooling:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Maximum Value', 'W', 'kBtu/hr') / zoneMetrics[:area]).round(2)
|
384
|
-
vals[:vai] = getDetailsData('EnergyMeters', 'Entire Facility', 'Annual and Peak Values - Other', "Cooling:EnergyTransfer:Zone:#{zoneMetrics[:name]}", 'Timestamp of Maximum', '', 's')
|
385
|
-
|
386
|
-
vals[:vaj] = zoneHeatComponentCalc('People', zoneMetrics)
|
387
|
-
vals[:vak] = zoneHeatComponentCalc('Lights', zoneMetrics)
|
388
|
-
vals[:val] = zoneHeatComponentCalc('Equipment', zoneMetrics)
|
389
|
-
vals[:vam] = zoneHeatComponentCalc('Refrigeration', zoneMetrics)
|
390
|
-
vals[:van] = zoneHeatComponentCalc('Water Use Equipment', zoneMetrics)
|
391
|
-
vals[:vao] = zoneHeatComponentCalc('HVAC Equipment Losses', zoneMetrics)
|
392
|
-
vals[:vap] = zoneHeatComponentCalc('Power Generation Equipment', zoneMetrics)
|
393
|
-
vals[:vaq] = zoneHeatComponentCalc('Infiltration', zoneMetrics)
|
394
|
-
vals[:var] = zoneHeatComponentCalc('Zone Ventilation', zoneMetrics)
|
395
|
-
vals[:vas] = zoneHeatComponentCalc('Interzone Mixing', zoneMetrics)
|
396
|
-
vals[:vat] = zoneHeatComponentCalc('Exterior Wall', zoneMetrics)
|
397
|
-
vals[:vau] = zoneHeatComponentCalc('Interzone Wall', zoneMetrics)
|
398
|
-
vals[:vav] = zoneHeatComponentCalc('Ground Contact Wall', zoneMetrics)
|
399
|
-
vals[:vaw] = zoneHeatComponentCalc('Other Wall', zoneMetrics)
|
400
|
-
vals[:vax] = zoneHeatComponentCalc('Opaque Door', zoneMetrics)
|
401
|
-
vals[:vay] = zoneHeatComponentCalc('Roof', zoneMetrics)
|
402
|
-
vals[:vaz] = zoneHeatComponentCalc('Interzone Ceiling', zoneMetrics)
|
403
|
-
vals[:vba] = zoneHeatComponentCalc('Other Roof', zoneMetrics)
|
404
|
-
vals[:vbb] = zoneHeatComponentCalc('Exterior Floor', zoneMetrics)
|
405
|
-
vals[:vbc] = zoneHeatComponentCalc('Interzone Floor', zoneMetrics)
|
406
|
-
vals[:vbd] = zoneHeatComponentCalc('Ground Contact Floor', zoneMetrics)
|
407
|
-
vals[:vbe] = zoneHeatComponentCalc('Other Floor', zoneMetrics)
|
408
|
-
vals[:vbf] = zoneHeatComponentCalc('Fenestration Conduction', zoneMetrics)
|
409
|
-
vals[:vbg] = zoneHeatComponentCalc('Fenestration Solar', zoneMetrics)
|
410
|
-
|
411
|
-
vals[:vbh] = getDetailsData('ZoneComponentLoadSummary', (zoneMetrics[:name]).to_s, 'Heating Peak Conditions', 'Time of Peak Load', 'Value', '', 's')
|
412
|
-
|
413
|
-
vals[:vbi] = zoneCoolComponentCalc('People', zoneMetrics)
|
414
|
-
vals[:vbj] = zoneCoolComponentCalc('Lights', zoneMetrics)
|
415
|
-
vals[:vbk] = zoneCoolComponentCalc('Equipment', zoneMetrics)
|
416
|
-
vals[:vbl] = zoneCoolComponentCalc('Refrigeration', zoneMetrics)
|
417
|
-
vals[:vbm] = zoneCoolComponentCalc('Water Use Equipment', zoneMetrics)
|
418
|
-
vals[:vbn] = zoneCoolComponentCalc('HVAC Equipment Losses', zoneMetrics)
|
419
|
-
vals[:vbo] = zoneCoolComponentCalc('Power Generation Equipment', zoneMetrics)
|
420
|
-
vals[:vbp] = zoneCoolComponentCalc('Infiltration', zoneMetrics)
|
421
|
-
vals[:vbq] = zoneCoolComponentCalc('Zone Ventilation', zoneMetrics)
|
422
|
-
vals[:vbr] = zoneCoolComponentCalc('Interzone Mixing', zoneMetrics)
|
423
|
-
vals[:vbs] = zoneCoolComponentCalc('Exterior Wall', zoneMetrics)
|
424
|
-
vals[:vbt] = zoneCoolComponentCalc('Interzone Wall', zoneMetrics)
|
425
|
-
vals[:vbu] = zoneCoolComponentCalc('Ground Contact Wall', zoneMetrics)
|
426
|
-
vals[:vbv] = zoneCoolComponentCalc('Other Wall', zoneMetrics)
|
427
|
-
vals[:vbw] = zoneCoolComponentCalc('Opaque Door', zoneMetrics)
|
428
|
-
vals[:vbx] = zoneCoolComponentCalc('Roof', zoneMetrics)
|
429
|
-
vals[:vby] = zoneCoolComponentCalc('Interzone Ceiling', zoneMetrics)
|
430
|
-
vals[:vbz] = zoneCoolComponentCalc('Other Roof', zoneMetrics)
|
431
|
-
vals[:vca] = zoneCoolComponentCalc('Exterior Floor', zoneMetrics)
|
432
|
-
vals[:vcb] = zoneCoolComponentCalc('Interzone Floor', zoneMetrics)
|
433
|
-
vals[:vcc] = zoneCoolComponentCalc('Ground Contact Floor', zoneMetrics)
|
434
|
-
vals[:vcd] = zoneCoolComponentCalc('Other Floor', zoneMetrics)
|
435
|
-
vals[:vce] = zoneCoolComponentCalc('Fenestration Conduction', zoneMetrics)
|
436
|
-
vals[:vcf] = zoneCoolComponentCalc('Fenestration Solar', zoneMetrics)
|
437
|
-
|
438
|
-
vals[:vcg] = getDetailsData('ZoneComponentLoadSummary', (zoneMetrics[:name]).to_s, 'Cooling Peak Conditions', 'Time of Peak Load', 'Value', '', 's')
|
439
|
-
|
440
|
-
# vals = loadTestVals( vals )
|
441
|
-
|
442
|
-
vals[:sumBasicHeating] = (vals[:vaj] + vals[:vak] + vals[:val] + vals[:vam] + vals[:vaq] + vals[:var] + vals[:vas]).round(2)
|
443
|
-
vals[:sumBasicCooling] = (vals[:vbi] + vals[:vbj] + vals[:vbk] + vals[:vbl] + vals[:vbp] + vals[:vbq] + vals[:vbr]).round(2)
|
444
|
-
|
445
|
-
vals[:sumOtherHeating] = (vals[:van] + vals[:vao] + vals[:vap]).round(2)
|
446
|
-
vals[:sumOtherCooling] = (vals[:vbm] + vals[:vbn] + vals[:vbo]).round(2)
|
447
|
-
|
448
|
-
vals[:sumWallDoorHeating] = (vals[:vat] + vals[:vau] + vals[:vav] + vals[:vaw] + vals[:vax]).round(2)
|
449
|
-
vals[:sumWallDoorCooling] = (vals[:vbs] + vals[:vbt] + vals[:vbu] + vals[:vbv] + vals[:vbw]).round(2)
|
450
|
-
|
451
|
-
vals[:sumRoofCeilingHeating] = (vals[:vay] + vals[:vaz] + vals[:vba]).round(2)
|
452
|
-
vals[:sumRoofCeilingCooling] = (vals[:vbx] + vals[:vby] + vals[:vbz]).round(2)
|
453
|
-
|
454
|
-
vals[:sumFloorHeating] = (vals[:vbb] + vals[:vbc] + vals[:vbd] + vals[:vbe]).round(2)
|
455
|
-
vals[:sumFloorCooling] = (vals[:vca] + vals[:vcb] + vals[:vcc] + vals[:vcd]).round(2)
|
456
|
-
|
457
|
-
vals[:sumWindowsHeating] = (vals[:vbf] + vals[:vbg]).round(2)
|
458
|
-
vals[:sumWindowsCooling] = (vals[:vce] + vals[:vcf]).round(2)
|
459
|
-
|
460
|
-
vals[:sumHeatingTotal] = (vals[:sumBasicHeating] + vals[:sumOtherHeating] + vals[:sumWallDoorHeating] + vals[:sumRoofCeilingHeating] + vals[:sumFloorHeating] + vals[:sumWindowsHeating]).round(2)
|
461
|
-
vals[:sumCoolingTotal] = (vals[:sumBasicCooling] + vals[:sumOtherCooling] + vals[:sumWallDoorCooling] + vals[:sumRoofCeilingCooling] + vals[:sumFloorCooling] + vals[:sumWindowsCooling]).round(2)
|
462
|
-
|
463
|
-
zoneMetrics[:vals] = vals
|
464
|
-
|
465
|
-
@zone_collection.push(zoneMetrics)
|
466
|
-
|
467
|
-
stacked_bars(zoneMetrics)
|
468
|
-
end
|
469
|
-
|
470
|
-
@zone_collection = @zone_collection.sort_by { |z| z[:name] }
|
471
|
-
|
472
|
-
equipment_lengths = @zone_collection.map { |z| z[:equipment].values.map(&:length) }
|
473
|
-
max_zone_equipments = equipment_lengths.flatten.max
|
474
|
-
|
475
|
-
# Convert the graph data to JSON
|
476
|
-
# This measure requires ruby 2.0.0 to create the JSON for the report graph
|
477
|
-
if RUBY_VERSION >= '2.0.0'
|
478
|
-
require 'json'
|
479
|
-
@graph_data = @graph_data.to_json
|
480
|
-
else
|
481
|
-
runner.registerInfo("This Measure needs Ruby 2.0.0 to generate timeseries graphs on the report. You have Ruby #{RUBY_VERSION}. OpenStudio 1.4.2 and higher user Ruby 2.0.0.")
|
482
|
-
end
|
483
|
-
|
484
|
-
web_asset_path = OpenStudio.getSharedResourcesPath / OpenStudio::Path.new('web_assets')
|
485
|
-
|
486
|
-
html_in = getResourceFileData('report.html.in')
|
487
|
-
|
488
|
-
# configure template with variable values
|
489
|
-
renderer = ERB.new(html_in)
|
490
|
-
html_out = renderer.result(binding)
|
491
|
-
|
492
|
-
writeResourceFileData('report.html', html_out)
|
493
|
-
# copyResourceFile( "graph_resource.js" )
|
494
|
-
# copyResourceFile( "style_resource.css" )
|
495
|
-
|
496
|
-
# closing the sql file
|
497
|
-
@sqlFile.close
|
498
|
-
|
499
|
-
# reporting final condition
|
500
|
-
runner.registerFinalCondition("Successfully finished writing 'Zone Report'.")
|
501
|
-
|
502
|
-
true
|
503
|
-
end # end the run method
|
504
|
-
|
505
|
-
def zoneHeatComponentCalc(component, zoneMetrics)
|
506
|
-
(getDetailsData('ZoneComponentLoadSummary', (zoneMetrics[:name]).to_s, 'Estimated Heating Peak Load Components', component, 'Total', 'W', 'Btu/hr') / zoneMetrics[:area]).round(2)
|
507
|
-
end
|
508
|
-
|
509
|
-
def zoneCoolComponentCalc(component, zoneMetrics)
|
510
|
-
(getDetailsData('ZoneComponentLoadSummary', (zoneMetrics[:name]).to_s, 'Estimated Cooling Peak Load Components', component, 'Total', 'W', 'Btu/hr') / zoneMetrics[:area]).round(2)
|
511
|
-
end
|
512
|
-
|
513
|
-
def stacked_bars(zoneMetrics)
|
514
|
-
# people, lights, equipment, refrigeration, other, infiltration, zone ventilation,
|
515
|
-
# interzone mixing, walls/doors, roof/ceiling, floor, windows
|
516
|
-
|
517
|
-
vals = zoneMetrics[:vals]
|
518
|
-
|
519
|
-
heatingVals = [vals[:vaj],
|
520
|
-
vals[:vak],
|
521
|
-
vals[:val],
|
522
|
-
vals[:vam],
|
523
|
-
vals[:sumOtherHeating],
|
524
|
-
vals[:vaq],
|
525
|
-
vals[:var],
|
526
|
-
vals[:vas],
|
527
|
-
vals[:sumWallDoorHeating],
|
528
|
-
vals[:sumRoofCeilingHeating],
|
529
|
-
vals[:sumFloorHeating],
|
530
|
-
vals[:sumWindowsHeating]]
|
531
|
-
|
532
|
-
coolingVals = [vals[:vbi],
|
533
|
-
vals[:vbj],
|
534
|
-
vals[:vbk],
|
535
|
-
vals[:vbl],
|
536
|
-
vals[:sumOtherCooling],
|
537
|
-
vals[:vbp],
|
538
|
-
vals[:vbq],
|
539
|
-
vals[:vbr],
|
540
|
-
vals[:sumWallDoorCooling],
|
541
|
-
vals[:sumRoofCeilingCooling],
|
542
|
-
vals[:sumFloorCooling],
|
543
|
-
vals[:sumWindowsCooling]]
|
544
|
-
|
545
|
-
positiveHeating = heatingVals.select { |v| v >= 0 }.inject { |sum, x| sum + x } || 0
|
546
|
-
negativeHeating = heatingVals.select { |v| v < 0 }.inject { |sum, x| sum + x } || 0
|
547
|
-
|
548
|
-
positiveCooling = coolingVals.select { |v| v >= 0 }.inject { |sum, x| sum + x } || 0
|
549
|
-
negativeCooling = coolingVals.select { |v| v < 0 }.inject { |sum, x| sum + x } || 0
|
550
|
-
|
551
|
-
maxPositive = positiveHeating > positiveCooling ? positiveHeating : positiveCooling
|
552
|
-
maxNegative = negativeHeating < negativeCooling ? negativeHeating : negativeCooling
|
553
|
-
|
554
|
-
maxPositive = maxPositive == 0 ? maxNegative * -0.20 : maxPositive
|
555
|
-
maxNegative = maxNegative == 0 ? maxPositive * -0.10 : maxNegative
|
556
|
-
|
557
|
-
maxPositive += (maxPositive * 0.20).round(2)
|
558
|
-
maxNegative += (maxNegative * 0.10).round(2)
|
559
|
-
|
560
|
-
stacked_vals = [[0, maxPositive, maxNegative, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
561
|
-
[1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, vals[:sumHeatingTotal], 0],
|
562
|
-
[2,
|
563
|
-
vals[:vaj],
|
564
|
-
vals[:vak],
|
565
|
-
vals[:val],
|
566
|
-
vals[:vam],
|
567
|
-
vals[:sumOtherHeating],
|
568
|
-
vals[:vaq],
|
569
|
-
vals[:var],
|
570
|
-
vals[:vas],
|
571
|
-
vals[:sumWallDoorHeating],
|
572
|
-
vals[:sumRoofCeilingHeating],
|
573
|
-
vals[:sumFloorHeating],
|
574
|
-
vals[:sumWindowsHeating],
|
575
|
-
0,
|
576
|
-
0],
|
577
|
-
[3,
|
578
|
-
vals[:vbi],
|
579
|
-
vals[:vbj],
|
580
|
-
vals[:vbk],
|
581
|
-
vals[:vbl],
|
582
|
-
vals[:sumOtherCooling],
|
583
|
-
vals[:vbp],
|
584
|
-
vals[:vbq],
|
585
|
-
vals[:vbr],
|
586
|
-
vals[:sumWallDoorCooling],
|
587
|
-
vals[:sumRoofCeilingCooling],
|
588
|
-
vals[:sumFloorCooling],
|
589
|
-
vals[:sumWindowsCooling],
|
590
|
-
0,
|
591
|
-
0],
|
592
|
-
[4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, vals[:sumCoolingTotal]],
|
593
|
-
[5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
|
594
|
-
|
595
|
-
# Add the hourly load data to JSON for the report.html
|
596
|
-
graph = {}
|
597
|
-
graph['title'] = ''
|
598
|
-
graph['xaxislabel'] = ''
|
599
|
-
graph['yaxislabel'] = 'Contribution Btu/hr/ft2'
|
600
|
-
graph['labels'] = %w[index people lights equipment refrigeration other infiltration zone_ventilation interzone_mixing walls/doors roof/ceiling floor windows net/heating net/cooling]
|
601
|
-
graph['colors'] = ['#888855', '#AAAA55', '#3333AA', '#8888FF', '#888888', '#9999FF', '#AAAAFF', '#AA6666', '#777733', '#888833', '#999933', '#9999FF', '#FF9999', '#9999FF']
|
602
|
-
graph['data'] = stacked_vals
|
603
|
-
|
604
|
-
@graph_data << graph
|
605
|
-
end
|
606
|
-
|
607
|
-
def getPctLoad(val, total)
|
608
|
-
if val != '' && total != 0
|
609
|
-
(val * 100 / total).round(2)
|
610
|
-
else
|
611
|
-
0
|
612
|
-
end
|
613
|
-
end
|
614
|
-
|
615
|
-
def getResourceFileData(fileName)
|
616
|
-
data_in_path = "#{File.dirname(__FILE__)}/resources/#{fileName}"
|
617
|
-
unless File.exist?(data_in_path)
|
618
|
-
data_in_path = "#{File.dirname(__FILE__)}/#{fileName}"
|
619
|
-
end
|
620
|
-
|
621
|
-
html_in = ''
|
622
|
-
File.open(data_in_path, 'r') do |file|
|
623
|
-
html_in = file.read
|
624
|
-
end
|
625
|
-
|
626
|
-
html_in
|
627
|
-
end
|
628
|
-
|
629
|
-
def writeResourceFileData(fileName, data)
|
630
|
-
File.open("./#{fileName}", 'w') do |file|
|
631
|
-
file << data
|
632
|
-
# make sure data is written to the disk one way or the other
|
633
|
-
begin
|
634
|
-
file.fsync
|
635
|
-
rescue StandardError
|
636
|
-
file.flush
|
637
|
-
end
|
638
|
-
end
|
639
|
-
end
|
640
|
-
|
641
|
-
# Fetch a value from the tabulardatawithstrings database view
|
642
|
-
# If final_units is "s" the value is returned unchanged as a string
|
643
|
-
# Otherwise the value is converted from units to final_units - units is specified in energy plus style (m2, m3, etc)
|
644
|
-
# and final_units should be open studio style (m^2, m^3, ...)
|
645
|
-
# If the data is not found or cannot be converted a warning is registered and "" or 0.0 is returned.
|
646
|
-
def getDetailsData(report, forstring, table, row, column, units, final_units)
|
647
|
-
forstring.upcase! if report == 'ZoneComponentLoadSummary'
|
648
|
-
|
649
|
-
str_HVACEquipment_query = 'SELECT Value FROM tabulardatawithstrings WHERE '
|
650
|
-
str_HVACEquipment_query << "ReportName='#{report}' AND "
|
651
|
-
str_HVACEquipment_query << "ReportForString='#{forstring}' AND "
|
652
|
-
str_HVACEquipment_query << "TableName='#{table}' AND "
|
653
|
-
str_HVACEquipment_query << "RowName LIKE '#{row}' AND "
|
654
|
-
str_HVACEquipment_query << "ColumnName='#{column}' AND "
|
655
|
-
str_HVACEquipment_query << "Units='#{units}'"
|
656
|
-
|
657
|
-
query_results = @sqlFile.execAndReturnFirstString(str_HVACEquipment_query)
|
658
|
-
|
659
|
-
if query_results.empty?
|
660
|
-
|
661
|
-
@runner.registerWarning("Could not get data for #{report} #{forstring} #{table} #{row} #{column}.")
|
662
|
-
return final_units == 's' ? '' : 0.0
|
663
|
-
|
664
|
-
else
|
665
|
-
r = query_results.get
|
666
|
-
if report == 'ZoneComponentLoadSummary'
|
667
|
-
@testData["#{@currentZoneName}_#{table}_#{row}"] = r
|
668
|
-
end
|
669
|
-
|
670
|
-
if final_units == 's'
|
671
|
-
return r
|
672
|
-
else
|
673
|
-
converted = OpenStudio.convert(r.to_f, eplus_to_openstudio(units), final_units)
|
674
|
-
if converted.empty?
|
675
|
-
@runner.registerError("Could not convert #{r} from #{units} to #{final_units}")
|
676
|
-
return 0.0
|
677
|
-
else
|
678
|
-
return converted.get.round(2)
|
679
|
-
end
|
680
|
-
end
|
681
|
-
|
682
|
-
end
|
683
|
-
end
|
684
|
-
|
685
|
-
def getDataByColumn(colName)
|
686
|
-
strvec_HVACEquipment_query = "SELECT #{colName} FROM tabulardatawithstrings WHERE "
|
687
|
-
strvec_HVACEquipment_query << "ReportName='EquipmentSummary' and "
|
688
|
-
strvec_HVACEquipment_query << "ReportForString='Entire Facility'"
|
689
|
-
strvec_HVACEquipment_query << 'ORDER BY TableName, ColumnName, RowName, Units, Value'
|
690
|
-
|
691
|
-
query_results = @sqlFile.execAndReturnVectorOfString(strvec_HVACEquipment_query).get
|
692
|
-
|
693
|
-
if query_results.empty?
|
694
|
-
@runner.registerError("Could not get data for requested Column #{colName}.")
|
695
|
-
return []
|
696
|
-
else
|
697
|
-
return query_results
|
698
|
-
end
|
699
|
-
end
|
700
|
-
|
701
|
-
# Accessor to support unit tests
|
702
|
-
attr_reader :zone_collection
|
703
|
-
end # end the measure
|
704
|
-
|
705
|
-
# this allows the measure to be use by the application
|
706
|
-
ZoneReport.new.registerWithApplication
|