openstudio-calibration 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (218) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +29 -0
  3. data/CHANGELOG.md +14 -0
  4. data/Gemfile +20 -0
  5. data/Jenkinsfile +6 -0
  6. data/LICENSE.md +27 -0
  7. data/README.md +33 -0
  8. data/Rakefile +50 -0
  9. data/doc_templates/LICENSE.md +27 -0
  10. data/doc_templates/README.md.erb +42 -0
  11. data/doc_templates/copyright_erb.txt +36 -0
  12. data/doc_templates/copyright_js.txt +4 -0
  13. data/doc_templates/copyright_ruby.txt +34 -0
  14. data/lib/files/.gitkeep +0 -0
  15. data/lib/measures/AddMonthlyJSONUtilityData/LICENSE.md +27 -0
  16. data/lib/measures/AddMonthlyJSONUtilityData/README.md +96 -0
  17. data/lib/measures/AddMonthlyJSONUtilityData/README.md.erb +42 -0
  18. data/lib/measures/AddMonthlyJSONUtilityData/measure.rb +280 -0
  19. data/lib/measures/AddMonthlyJSONUtilityData/measure.xml +163 -0
  20. data/lib/measures/AddMonthlyUtilityData/LICENSE.md +27 -0
  21. data/lib/measures/AddMonthlyUtilityData/README.md +64 -0
  22. data/lib/measures/AddMonthlyUtilityData/README.md.erb +42 -0
  23. data/lib/measures/AddMonthlyUtilityData/measure.rb +312 -0
  24. data/lib/measures/AddMonthlyUtilityData/measure.xml +115 -0
  25. data/lib/measures/AddMonthlyUtilityData/tests/AddMonthlyUtilityData_Test.rb +88 -0
  26. data/lib/measures/AddMonthlyUtilityData/tests/electric_billed_usages.json +198 -0
  27. data/lib/measures/AddMonthlyUtilityData/tests/gas_billed_usages.json +198 -0
  28. data/lib/measures/CalibrationReports/LICENSE.md +27 -0
  29. data/lib/measures/CalibrationReports/README.md +26 -0
  30. data/lib/measures/CalibrationReports/README.md.erb +42 -0
  31. data/lib/measures/CalibrationReports/measure.rb +511 -0
  32. data/lib/measures/CalibrationReports/measure.xml +98 -0
  33. data/lib/measures/CalibrationReports/resources/report.html.in +379 -0
  34. data/lib/measures/CalibrationReports/tests/CalibrationReports_Test.rb +523 -0
  35. data/lib/measures/CalibrationReports/tests/ExampleModel.osm +10497 -0
  36. data/lib/measures/CalibrationReports/tests/ExampleModelNoDemandInput.osm +10560 -0
  37. data/lib/measures/CalibrationReports/tests/ExampleModelNoGasInput.osm +10456 -0
  38. data/lib/measures/CalibrationReports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +8768 -0
  39. data/lib/measures/CalibrationReportsEnhanced/LICENSE.md +27 -0
  40. data/lib/measures/CalibrationReportsEnhanced/README.md +143 -0
  41. data/lib/measures/CalibrationReportsEnhanced/README.md.erb +42 -0
  42. data/lib/measures/CalibrationReportsEnhanced/measure.rb +798 -0
  43. data/lib/measures/CalibrationReportsEnhanced/measure.xml +372 -0
  44. data/lib/measures/CalibrationReportsEnhanced/resources/report.html.in +380 -0
  45. data/lib/measures/CalibrationReportsEnhanced/tests/CalibrationReportsEnhanced_Test.rb +734 -0
  46. data/lib/measures/CalibrationReportsEnhanced/tests/ExampleModel.osm +10497 -0
  47. data/lib/measures/CalibrationReportsEnhanced/tests/ExampleModel_FuelOil.osm +12740 -0
  48. data/lib/measures/CalibrationReportsEnhanced/tests/USA_CO_Golden-NREL.724666_TMY3.epw +8768 -0
  49. data/lib/measures/CalibrationReportsEnhanced21/LICENSE.md +27 -0
  50. data/lib/measures/CalibrationReportsEnhanced21/README.md +109 -0
  51. data/lib/measures/CalibrationReportsEnhanced21/README.md.erb +42 -0
  52. data/lib/measures/CalibrationReportsEnhanced21/measure.rb +690 -0
  53. data/lib/measures/CalibrationReportsEnhanced21/measure.xml +269 -0
  54. data/lib/measures/CalibrationReportsEnhanced21/resources/report.html.in +380 -0
  55. data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/LICENSE.md +27 -0
  56. data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/README.md +48 -0
  57. data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/README.md.erb +42 -0
  58. data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/measure.rb +237 -0
  59. data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/measure.xml +93 -0
  60. data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/LICENSE.md +27 -0
  61. data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/README.md +48 -0
  62. data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/README.md.erb +42 -0
  63. data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/measure.rb +228 -0
  64. data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/measure.xml +93 -0
  65. data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/LICENSE.md +27 -0
  66. data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/README.md +64 -0
  67. data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/README.md.erb +42 -0
  68. data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/measure.rb +280 -0
  69. data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/measure.xml +111 -0
  70. data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/LICENSE.md +27 -0
  71. data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/README.md +64 -0
  72. data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/README.md.erb +42 -0
  73. data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/measure.rb +270 -0
  74. data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/measure.xml +111 -0
  75. data/lib/measures/CoilCoolingWaterMultiplier/LICENSE.md +27 -0
  76. data/lib/measures/CoilCoolingWaterMultiplier/README.md +80 -0
  77. data/lib/measures/CoilCoolingWaterMultiplier/README.md.erb +42 -0
  78. data/lib/measures/CoilCoolingWaterMultiplier/measure.rb +324 -0
  79. data/lib/measures/CoilCoolingWaterMultiplier/measure.xml +129 -0
  80. data/lib/measures/CoilCoolingWaterPercentChange/LICENSE.md +27 -0
  81. data/lib/measures/CoilCoolingWaterPercentChange/README.md +80 -0
  82. data/lib/measures/CoilCoolingWaterPercentChange/README.md.erb +42 -0
  83. data/lib/measures/CoilCoolingWaterPercentChange/measure.rb +311 -0
  84. data/lib/measures/CoilCoolingWaterPercentChange/measure.xml +129 -0
  85. data/lib/measures/CoilHeatingElectricMultiplier/LICENSE.md +27 -0
  86. data/lib/measures/CoilHeatingElectricMultiplier/README.md +48 -0
  87. data/lib/measures/CoilHeatingElectricMultiplier/README.md.erb +42 -0
  88. data/lib/measures/CoilHeatingElectricMultiplier/measure.rb +240 -0
  89. data/lib/measures/CoilHeatingElectricMultiplier/measure.xml +93 -0
  90. data/lib/measures/CoilHeatingElectricPercentChange/LICENSE.md +27 -0
  91. data/lib/measures/CoilHeatingElectricPercentChange/README.md +48 -0
  92. data/lib/measures/CoilHeatingElectricPercentChange/README.md.erb +42 -0
  93. data/lib/measures/CoilHeatingElectricPercentChange/measure.rb +231 -0
  94. data/lib/measures/CoilHeatingElectricPercentChange/measure.xml +93 -0
  95. data/lib/measures/CoilHeatingGasMultiplier/LICENSE.md +27 -0
  96. data/lib/measures/CoilHeatingGasMultiplier/README.md +64 -0
  97. data/lib/measures/CoilHeatingGasMultiplier/README.md.erb +42 -0
  98. data/lib/measures/CoilHeatingGasMultiplier/measure.rb +282 -0
  99. data/lib/measures/CoilHeatingGasMultiplier/measure.xml +111 -0
  100. data/lib/measures/CoilHeatingGasPercentChange/LICENSE.md +27 -0
  101. data/lib/measures/CoilHeatingGasPercentChange/README.md +64 -0
  102. data/lib/measures/CoilHeatingGasPercentChange/README.md.erb +42 -0
  103. data/lib/measures/CoilHeatingGasPercentChange/measure.rb +271 -0
  104. data/lib/measures/CoilHeatingGasPercentChange/measure.xml +111 -0
  105. data/lib/measures/CoilHeatingWaterMultiplier/LICENSE.md +27 -0
  106. data/lib/measures/CoilHeatingWaterMultiplier/README.md +48 -0
  107. data/lib/measures/CoilHeatingWaterMultiplier/README.md.erb +42 -0
  108. data/lib/measures/CoilHeatingWaterMultiplier/measure.rb +235 -0
  109. data/lib/measures/CoilHeatingWaterMultiplier/measure.xml +93 -0
  110. data/lib/measures/CoilHeatingWaterPercentChange/LICENSE.md +27 -0
  111. data/lib/measures/CoilHeatingWaterPercentChange/README.md +48 -0
  112. data/lib/measures/CoilHeatingWaterPercentChange/README.md.erb +42 -0
  113. data/lib/measures/CoilHeatingWaterPercentChange/measure.rb +226 -0
  114. data/lib/measures/CoilHeatingWaterPercentChange/measure.xml +93 -0
  115. data/lib/measures/ConstructionLayerZeroMaterialProperties/LICENSE.md +27 -0
  116. data/lib/measures/ConstructionLayerZeroMaterialProperties/README.md +88 -0
  117. data/lib/measures/ConstructionLayerZeroMaterialProperties/README.md.erb +42 -0
  118. data/lib/measures/ConstructionLayerZeroMaterialProperties/measure.rb +221 -0
  119. data/lib/measures/ConstructionLayerZeroMaterialProperties/measure.xml +194 -0
  120. data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/LICENSE.md +27 -0
  121. data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/README.md +40 -0
  122. data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/README.md.erb +42 -0
  123. data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/measure.rb +102 -0
  124. data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/measure.xml +78 -0
  125. data/lib/measures/ExteriorWallThermalPropertiesMultiplier/LICENSE.md +27 -0
  126. data/lib/measures/ExteriorWallThermalPropertiesMultiplier/README.md +48 -0
  127. data/lib/measures/ExteriorWallThermalPropertiesMultiplier/README.md.erb +42 -0
  128. data/lib/measures/ExteriorWallThermalPropertiesMultiplier/measure.rb +263 -0
  129. data/lib/measures/ExteriorWallThermalPropertiesMultiplier/measure.xml +97 -0
  130. data/lib/measures/ExteriorWallThermalPropertiesPercentChange/LICENSE.md +27 -0
  131. data/lib/measures/ExteriorWallThermalPropertiesPercentChange/README.md +48 -0
  132. data/lib/measures/ExteriorWallThermalPropertiesPercentChange/README.md.erb +42 -0
  133. data/lib/measures/ExteriorWallThermalPropertiesPercentChange/measure.rb +253 -0
  134. data/lib/measures/ExteriorWallThermalPropertiesPercentChange/measure.xml +97 -0
  135. data/lib/measures/FansMultiplier/LICENSE.md +27 -0
  136. data/lib/measures/FansMultiplier/README.md +64 -0
  137. data/lib/measures/FansMultiplier/README.md.erb +42 -0
  138. data/lib/measures/FansMultiplier/measure.rb +297 -0
  139. data/lib/measures/FansMultiplier/measure.xml +166 -0
  140. data/lib/measures/FansPercentChange/LICENSE.md +27 -0
  141. data/lib/measures/FansPercentChange/README.md +64 -0
  142. data/lib/measures/FansPercentChange/README.md.erb +42 -0
  143. data/lib/measures/FansPercentChange/measure.rb +286 -0
  144. data/lib/measures/FansPercentChange/measure.xml +166 -0
  145. data/lib/measures/GeneralCalibrationMeasureMultiplier/LICENSE.md +27 -0
  146. data/lib/measures/GeneralCalibrationMeasureMultiplier/README.md +112 -0
  147. data/lib/measures/GeneralCalibrationMeasureMultiplier/README.md.erb +42 -0
  148. data/lib/measures/GeneralCalibrationMeasureMultiplier/measure.rb +639 -0
  149. data/lib/measures/GeneralCalibrationMeasureMultiplier/measure.xml +229 -0
  150. data/lib/measures/GeneralCalibrationMeasurePercentChange/LICENSE.md +27 -0
  151. data/lib/measures/GeneralCalibrationMeasurePercentChange/README.md +112 -0
  152. data/lib/measures/GeneralCalibrationMeasurePercentChange/README.md.erb +42 -0
  153. data/lib/measures/GeneralCalibrationMeasurePercentChange/measure.rb +756 -0
  154. data/lib/measures/GeneralCalibrationMeasurePercentChange/measure.xml +229 -0
  155. data/lib/measures/HardSizeHvac/LICENSE.md +27 -0
  156. data/lib/measures/HardSizeHvac/README.md +26 -0
  157. data/lib/measures/HardSizeHvac/README.md.erb +42 -0
  158. data/lib/measures/HardSizeHvac/measure.rb +88 -0
  159. data/lib/measures/HardSizeHvac/measure.xml +81 -0
  160. data/lib/measures/MaalkaMonthlyJSONUtilityData/LICENSE.md +27 -0
  161. data/lib/measures/MaalkaMonthlyJSONUtilityData/README.md +104 -0
  162. data/lib/measures/MaalkaMonthlyJSONUtilityData/README.md.erb +42 -0
  163. data/lib/measures/MaalkaMonthlyJSONUtilityData/measure.rb +304 -0
  164. data/lib/measures/MaalkaMonthlyJSONUtilityData/measure.xml +216 -0
  165. data/lib/measures/RValueOfInsulationForConstructionMultiplier/LICENSE.md +27 -0
  166. data/lib/measures/RValueOfInsulationForConstructionMultiplier/README.md +40 -0
  167. data/lib/measures/RValueOfInsulationForConstructionMultiplier/README.md.erb +42 -0
  168. data/lib/measures/RValueOfInsulationForConstructionMultiplier/measure.rb +196 -0
  169. data/lib/measures/RValueOfInsulationForConstructionMultiplier/measure.xml +132 -0
  170. data/lib/measures/RValueOfInsulationForConstructionPercentageChange/LICENSE.md +27 -0
  171. data/lib/measures/RValueOfInsulationForConstructionPercentageChange/README.md +40 -0
  172. data/lib/measures/RValueOfInsulationForConstructionPercentageChange/README.md.erb +42 -0
  173. data/lib/measures/RValueOfInsulationForConstructionPercentageChange/measure.rb +189 -0
  174. data/lib/measures/RValueOfInsulationForConstructionPercentageChange/measure.xml +132 -0
  175. data/lib/measures/RoofThermalPropertiesMultiplier/LICENSE.md +27 -0
  176. data/lib/measures/RoofThermalPropertiesMultiplier/README.md +48 -0
  177. data/lib/measures/RoofThermalPropertiesMultiplier/README.md.erb +42 -0
  178. data/lib/measures/RoofThermalPropertiesMultiplier/measure.rb +263 -0
  179. data/lib/measures/RoofThermalPropertiesMultiplier/measure.xml +97 -0
  180. data/lib/measures/RoofThermalPropertiesPercentChange/LICENSE.md +27 -0
  181. data/lib/measures/RoofThermalPropertiesPercentChange/README.md +48 -0
  182. data/lib/measures/RoofThermalPropertiesPercentChange/README.md.erb +42 -0
  183. data/lib/measures/RoofThermalPropertiesPercentChange/measure.rb +253 -0
  184. data/lib/measures/RoofThermalPropertiesPercentChange/measure.xml +97 -0
  185. data/lib/measures/TimeseriesObjectiveFunction/LICENSE.md +27 -0
  186. data/lib/measures/TimeseriesObjectiveFunction/README.md +207 -0
  187. data/lib/measures/TimeseriesObjectiveFunction/README.md.erb +42 -0
  188. data/lib/measures/TimeseriesObjectiveFunction/measure.rb +748 -0
  189. data/lib/measures/TimeseriesObjectiveFunction/measure.xml +435 -0
  190. data/lib/measures/TimeseriesObjectiveFunction/resources/report.html.erb +288 -0
  191. data/lib/measures/TimeseriesPlot/LICENSE.md +27 -0
  192. data/lib/measures/TimeseriesPlot/README.md +56 -0
  193. data/lib/measures/TimeseriesPlot/README.md.erb +42 -0
  194. data/lib/measures/TimeseriesPlot/measure.rb +302 -0
  195. data/lib/measures/TimeseriesPlot/measure.xml +137 -0
  196. data/lib/measures/TimeseriesPlot/resources/report.html.erb +270 -0
  197. data/lib/measures/WaterHeaterMixedMultiplier/LICENSE.md +27 -0
  198. data/lib/measures/WaterHeaterMixedMultiplier/README.md +64 -0
  199. data/lib/measures/WaterHeaterMixedMultiplier/README.md.erb +42 -0
  200. data/lib/measures/WaterHeaterMixedMultiplier/measure.rb +255 -0
  201. data/lib/measures/WaterHeaterMixedMultiplier/measure.xml +180 -0
  202. data/lib/measures/WaterHeaterMixedPercentChange/LICENSE.md +27 -0
  203. data/lib/measures/WaterHeaterMixedPercentChange/README.md +64 -0
  204. data/lib/measures/WaterHeaterMixedPercentChange/README.md.erb +42 -0
  205. data/lib/measures/WaterHeaterMixedPercentChange/measure.rb +245 -0
  206. data/lib/measures/WaterHeaterMixedPercentChange/measure.xml +180 -0
  207. data/lib/measures/zone_report/LICENSE.md +27 -0
  208. data/lib/measures/zone_report/README.md +26 -0
  209. data/lib/measures/zone_report/README.md.erb +42 -0
  210. data/lib/measures/zone_report/measure.rb +706 -0
  211. data/lib/measures/zone_report/measure.xml +67 -0
  212. data/lib/measures/zone_report/resources/report.html.in +342 -0
  213. data/lib/openstudio-calibration-measures.rb +36 -0
  214. data/lib/openstudio/calibration_measures.rb +37 -0
  215. data/lib/openstudio/calibration_measures/extension.rb +49 -0
  216. data/lib/openstudio/calibration_measures/version.rb +40 -0
  217. data/openstudio-calibration.gemspec +30 -0
  218. metadata +331 -0
@@ -0,0 +1,27 @@
1
+ OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC. All rights reserved.
2
+
3
+ Redistribution and use in source and binary forms, with or without modification, are permitted
4
+ provided that the following conditions are met:
5
+
6
+ (1) Redistributions of source code must retain the above copyright notice, this list of conditions
7
+ and the following disclaimer.
8
+
9
+ (2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions
10
+ and the following disclaimer in the documentation and/or other materials provided with the distribution.
11
+
12
+ (3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse
13
+ or promote products derived from this software without specific prior written permission from the
14
+ respective party.
15
+
16
+ (4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other
17
+ derivative works may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar
18
+ designation without specific prior written permission from Alliance for Sustainable Energy, LLC.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
21
+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES GOVERNMENT,
23
+ OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
25
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,143 @@
1
+
2
+
3
+ ###### (Automatically generated documentation)
4
+
5
+ # Calibration Reports Enhanced
6
+
7
+ ## Description
8
+ This measure is intended for calibibration of modeled results against user entered utility bill.
9
+
10
+ ## Modeler Description
11
+ Measure looks at consumption for electricity and natural gas, and demand for electricity. It is inteneded to be used with no more than one gas an electric bills. Each bill can have multiple billing periods. Make sure ot use an AMY matching the utility data time frame.
12
+
13
+ ## Measure Type
14
+ ReportingMeasure
15
+
16
+ ## Taxonomy
17
+
18
+
19
+ ## Arguments
20
+
21
+
22
+ ### Electric NMBE limit (%)
23
+
24
+ **Name:** electric_nmbe_limit,
25
+ **Type:** Double,
26
+ **Units:** ,
27
+ **Required:** true,
28
+ **Model Dependent:** false
29
+
30
+ ### Electric CVRMSE limit (%)
31
+
32
+ **Name:** electric_cvrmse_limit,
33
+ **Type:** Double,
34
+ **Units:** ,
35
+ **Required:** true,
36
+ **Model Dependent:** false
37
+
38
+ ### Gas NMBE limit (%)
39
+
40
+ **Name:** gas_nmbe_limit,
41
+ **Type:** Double,
42
+ **Units:** ,
43
+ **Required:** true,
44
+ **Model Dependent:** false
45
+
46
+ ### Gas CVRMSE limit (%)
47
+
48
+ **Name:** gas_cvrmse_limit,
49
+ **Type:** Double,
50
+ **Units:** ,
51
+ **Required:** true,
52
+ **Model Dependent:** false
53
+
54
+ ### Fuel Oil#2 NMBE limit (%)
55
+
56
+ **Name:** fuel_oil_nmbe_limit,
57
+ **Type:** Double,
58
+ **Units:** ,
59
+ **Required:** true,
60
+ **Model Dependent:** false
61
+
62
+ ### Fuel Oil#2 CVRMSE limit (%)
63
+
64
+ **Name:** fuel_oil_cvrmse_limit,
65
+ **Type:** Double,
66
+ **Units:** ,
67
+ **Required:** true,
68
+ **Model Dependent:** false
69
+
70
+
71
+
72
+
73
+
74
+ ## Outputs
75
+
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+
103
+
104
+
105
+
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+
114
+
115
+
116
+
117
+
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+
134
+
135
+
136
+
137
+
138
+
139
+
140
+
141
+
142
+
143
+ electricity_consumption_actual, electricity_consumption_modeled, electricity_consumption_cvrmse, electricity_consumption_nmbe, electricity_sum_of_squares, electricity_dof, electricity_rmse, electricity_peak_demand_nmbe, electricity_peak_demand_actual, electricity_peak_demand_modeled, natural_gas_consumption_actual, natural_gas_consumption_modeled, natural_gas_consumption_cvrmse, natural_gas_consumption_nmbe, natural_gas_sum_of_squares, natural_gas_dof, natural_gas_rmse, fuel_oil_2_consumption_actual, fuel_oil_2_consumption_modeled, fuel_oil_2_consumption_cvrmse, fuel_oil_2_consumption_nmbe, fuel_oil_2_sum_of_squares, fuel_oil_2_dof, fuel_oil_2_rmse, total_sum_of_squares, total_dof, total_rmse, electricity_cvrmse_within_limit, electricity_nmbe_within_limit, natural_gas_cvrmse_within_limit, natural_gas_nmbe_within_limit, fuel_oil_2_cvrmse_within_limit, fuel_oil_2_nmbe_within_limit
@@ -0,0 +1,42 @@
1
+ <%#= README.md.erb is used to auto-generate README.md. %>
2
+ <%#= To manually maintain README.md throw away README.md.erb and manually edit README.md %>
3
+ ###### (Automatically generated documentation)
4
+
5
+ # <%= name %>
6
+
7
+ ## Description
8
+ <%= description %>
9
+
10
+ ## Modeler Description
11
+ <%= modelerDescription %>
12
+
13
+ ## Measure Type
14
+ <%= measureType %>
15
+
16
+ ## Taxonomy
17
+ <%= taxonomy %>
18
+
19
+ ## Arguments
20
+
21
+ <% arguments.each do |argument| %>
22
+ ### <%= argument[:display_name] %>
23
+ <%= argument[:description] %>
24
+ **Name:** <%= argument[:name] %>,
25
+ **Type:** <%= argument[:type] %>,
26
+ **Units:** <%= argument[:units] %>,
27
+ **Required:** <%= argument[:required] %>,
28
+ **Model Dependent:** <%= argument[:model_dependent] %>
29
+ <% end %>
30
+
31
+ <% if arguments.size == 0 %>
32
+ <%= "This measure does not have any user arguments" %>
33
+ <% end %>
34
+
35
+ <% if outputs.size > 0 %>
36
+ ## Outputs
37
+ <% output_names = [] %>
38
+ <% outputs.each do |output| %>
39
+ <% output_names << output[:display_name] %>
40
+ <% end %>
41
+ <%= output_names.join(", ") %>
42
+ <% end %>
@@ -0,0 +1,798 @@
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 'json'
38
+
39
+ # start the measure
40
+ class CalibrationReportsEnhanced < 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
+ 'Calibration Reports Enhanced'
45
+ end
46
+
47
+ # human readable description
48
+ def description
49
+ 'This measure is intended for calibibration of modeled results against user entered utility bill.'
50
+ end
51
+
52
+ # human readable description of modeling approach
53
+ def modeler_description
54
+ 'Measure looks at consumption for electricity and natural gas, and demand for electricity. It is inteneded to be used with no more than one gas an electric bills. Each bill can have multiple billing periods. Make sure ot use an AMY matching the utility data time frame.'
55
+ end
56
+
57
+ # define the arguments that the user will input
58
+ def arguments
59
+ args = OpenStudio::Measure::OSArgumentVector.new
60
+
61
+ # Electric NMBE limit
62
+ electric_nmbe_limit = OpenStudio::Measure::OSArgument.makeDoubleArgument('electric_nmbe_limit', true)
63
+ electric_nmbe_limit.setDisplayName('Electric NMBE limit (%)')
64
+ electric_nmbe_limit.setDefaultValue(5.0)
65
+ args << electric_nmbe_limit
66
+
67
+ # Electric CVRMSE limit
68
+ electric_cvrmse_limit = OpenStudio::Measure::OSArgument.makeDoubleArgument('electric_cvrmse_limit', true)
69
+ electric_cvrmse_limit.setDisplayName('Electric CVRMSE limit (%)')
70
+ electric_cvrmse_limit.setDefaultValue(15.0)
71
+ args << electric_cvrmse_limit
72
+
73
+ # Gas NMBE limit
74
+ gas_nmbe_limit = OpenStudio::Measure::OSArgument.makeDoubleArgument('gas_nmbe_limit', true)
75
+ gas_nmbe_limit.setDisplayName('Gas NMBE limit (%)')
76
+ gas_nmbe_limit.setDefaultValue(5.0)
77
+ args << gas_nmbe_limit
78
+
79
+ # Gas CVRMSE limit
80
+ gas_cvrmse_limit = OpenStudio::Measure::OSArgument.makeDoubleArgument('gas_cvrmse_limit', true)
81
+ gas_cvrmse_limit.setDisplayName('Gas CVRMSE limit (%)')
82
+ gas_cvrmse_limit.setDefaultValue(15.0)
83
+ args << gas_cvrmse_limit
84
+
85
+ # Fuel Oil NMBE limit
86
+ fuel_oil_nmbe_limit = OpenStudio::Measure::OSArgument.makeDoubleArgument('fuel_oil_nmbe_limit', true)
87
+ fuel_oil_nmbe_limit.setDisplayName('Fuel Oil#2 NMBE limit (%)')
88
+ fuel_oil_nmbe_limit.setDefaultValue(5.0)
89
+ args << fuel_oil_nmbe_limit
90
+
91
+ # Fuel Oil CVRMSE limit
92
+ fuel_oil_cvrmse_limit = OpenStudio::Measure::OSArgument.makeDoubleArgument('fuel_oil_cvrmse_limit', true)
93
+ fuel_oil_cvrmse_limit.setDisplayName('Fuel Oil#2 CVRMSE limit (%)')
94
+ fuel_oil_cvrmse_limit.setDefaultValue(15.0)
95
+ args << fuel_oil_cvrmse_limit
96
+
97
+ args
98
+ end # end the arguments method
99
+
100
+ def outputs
101
+ result = OpenStudio::Measure::OSOutputVector.new
102
+
103
+ # electric consumption values
104
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_consumption_actual') # kWh
105
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_consumption_modeled') # kWh
106
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_consumption_cvrmse') # %
107
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_consumption_nmbe') # %
108
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_sum_of_squares') # kWh
109
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_dof') # na
110
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_rmse') # kWh^0.5
111
+
112
+ # electric peak values
113
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_peak_demand_nmbe') # %
114
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_peak_demand_actual') # kW
115
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_peak_demand_modeled') # kW
116
+
117
+ # gas consumption values
118
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('natural_gas_consumption_actual') # therms
119
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('natural_gas_consumption_modeled') # therms
120
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('natural_gas_consumption_cvrmse') # %
121
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('natural_gas_consumption_nmbe') # %
122
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('natural_gas_sum_of_squares') # therms
123
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('natural_gas_dof') # na
124
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('natural_gas_rmse') # therms^0.5
125
+
126
+ # fuel oil #2 consumption values
127
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('fuel_oil_2_consumption_actual') # gals
128
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('fuel_oil_2_consumption_modeled') # gals
129
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('fuel_oil_2_consumption_cvrmse') # %
130
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('fuel_oil_2_consumption_nmbe') # %
131
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('fuel_oil_2_sum_of_squares') # gals
132
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('fuel_oil_2_dof') # na
133
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('fuel_oil_2_rmse') # gals^0.5
134
+
135
+ # total fuel values (gas plus electric only? not district?)
136
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('total_sum_of_squares') # kBtu
137
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('total_dof') # na
138
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('total_rmse') # kBtu^0.5
139
+
140
+ # within limit check values
141
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_cvrmse_within_limit') # na
142
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('electricity_nmbe_within_limit') # na
143
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('natural_gas_cvrmse_within_limit') # na
144
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('natural_gas_nmbe_within_limit') # na
145
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('fuel_oil_2_cvrmse_within_limit') # na
146
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput('fuel_oil_2_nmbe_within_limit') # na
147
+
148
+ result
149
+ end
150
+
151
+ # define what happens when the measure is run
152
+ def run(runner, user_arguments)
153
+ super(runner, user_arguments)
154
+
155
+ # use the built-in error checking
156
+ return false unless runner.validateUserArguments(arguments, user_arguments)
157
+
158
+ electric_nmbe_limit = runner.getDoubleArgumentValue('electric_nmbe_limit', user_arguments)
159
+ electric_cvrmse_limit = runner.getDoubleArgumentValue('electric_cvrmse_limit', user_arguments)
160
+ gas_nmbe_limit = runner.getDoubleArgumentValue('gas_nmbe_limit', user_arguments)
161
+ gas_cvrmse_limit = runner.getDoubleArgumentValue('gas_cvrmse_limit', user_arguments)
162
+ fuel_oil_nmbe_limit = runner.getDoubleArgumentValue('fuel_oil_nmbe_limit', user_arguments)
163
+ fuel_oil_cvrmse_limit = runner.getDoubleArgumentValue('fuel_oil_cvrmse_limit', user_arguments)
164
+
165
+ os_version = OpenStudio::VersionString.new(OpenStudio.openStudioVersion)
166
+ min_version_feature1 = OpenStudio::VersionString.new('1.2.2')
167
+
168
+ # get the last model and sql file
169
+
170
+ model = runner.lastOpenStudioModel
171
+ if model.empty?
172
+ runner.registerError('Cannot find last model.')
173
+ return false
174
+ end
175
+ model = model.get
176
+
177
+ sqlFile = runner.lastEnergyPlusSqlFile
178
+ if sqlFile.empty?
179
+ runner.registerError('Cannot find last sql file.')
180
+ return false
181
+ end
182
+ sqlFile = sqlFile.get
183
+ model.setSqlFile(sqlFile)
184
+
185
+ # put data into variables, these are available in the local scope binding
186
+ # building_name = model.getBuilding.name.get
187
+
188
+ web_asset_path = OpenStudio.getSharedResourcesPath / OpenStudio::Path.new('web_assets')
189
+
190
+ energy = ''
191
+
192
+ calibrationGuidelines = OpenStudio::Model::UtilityBill.calibrationGuidelines
193
+ energy << 'var calibrationGuidelines = ['
194
+ calibrationGuidelines.each do |calibrationGuideline|
195
+ energy << '"' << calibrationGuideline << '",'
196
+ end
197
+ energy = energy[0..-2]
198
+ energy << "];\n"
199
+
200
+ maxNMBE = OpenStudio::Model::UtilityBill.maxNMBE(calibrationGuidelines[0])
201
+ energy << 'var ashraeMaxNMBE = '
202
+ energy << if !maxNMBE.empty?
203
+ maxNMBE.get.to_s
204
+ else
205
+ 'N/A'
206
+ end
207
+ energy << ";\n"
208
+ if os_version >= min_version_feature1
209
+ runner.registerValue('ashrae_max_nmbe', maxNMBE.get, '%')
210
+ end
211
+
212
+ maxCVRMSE = OpenStudio::Model::UtilityBill.maxCVRMSE(calibrationGuidelines[0])
213
+ energy << 'var ashraeMaxCVRMSE = '
214
+ energy << if !maxCVRMSE.empty?
215
+ maxCVRMSE.get.to_s
216
+ else
217
+ 'N/A'
218
+ end
219
+ energy << ";\n"
220
+ if os_version >= min_version_feature1
221
+ runner.registerValue('ashrae_max_cvrmse', maxCVRMSE.get, '%')
222
+ end
223
+
224
+ maxNMBE = OpenStudio::Model::UtilityBill.maxNMBE(calibrationGuidelines[1])
225
+ energy << 'var fempMaxNMBE = '
226
+ energy << if !maxNMBE.empty?
227
+ maxNMBE.get.to_s
228
+ else
229
+ 'N/A'
230
+ end
231
+ energy << ";\n"
232
+ if os_version >= min_version_feature1
233
+ runner.registerValue('femp_max_nmbe', maxNMBE.get, '%')
234
+ end
235
+
236
+ maxCVRMSE = OpenStudio::Model::UtilityBill.maxCVRMSE(calibrationGuidelines[1])
237
+ energy << 'var fempMaxCVRMSE = '
238
+ energy << if !maxCVRMSE.empty?
239
+ maxCVRMSE.get.to_s
240
+ else
241
+ 'N/A'
242
+ end
243
+ energy << ";\n"
244
+ if os_version >= min_version_feature1
245
+ runner.registerValue('femp_max_cvrmse', maxCVRMSE.get, '%')
246
+ end
247
+
248
+ energyElec = "\t\"Electricity Consumption\":{\n\t\t\"units\":\"kWh\",\n"
249
+ energyDemand = "\t\"Electricity Demand\":{\n\t\t\"units\":\"kW\",\n"
250
+ energyGas = "\t\"Natural Gas Consumption\":{\n\t\t\"units\":\"therms\",\n"
251
+ energyFuelOil = "\t\"Fuel Oil 2 Consumption\":{\n\t\t\"units\":\"gals\",\n"
252
+ tempStartDate = ''
253
+ tempEndDate = ''
254
+ elecStartDate = "\t\t\t\t\"Start\":["
255
+ elecEndDate = "\t\t\t\t\"End\":["
256
+ gasStartDate = "\t\t\t\t\"Start\":["
257
+ gasEndDate = "\t\t\t\t\"End\":["
258
+ fuelOilStartDate = "\t\t\t\t\"Start\":["
259
+ fuelOilEndDate = "\t\t\t\t\"End\":["
260
+ elecActualConsumption = "\t\t\t\t\"Actual\":["
261
+ elecModelConsumption = "\t\t\t\t\"Model\":["
262
+ actualPeakDemand = "\t\t\t\t\"Actual\":["
263
+ modelPeakDemand = "\t\t\t\t\"Model\":["
264
+ gasActualConsumption = "\t\t\t\t\"Actual\":["
265
+ gasModelConsumption = "\t\t\t\t\"Model\":["
266
+ fuelOilActualConsumption = "\t\t\t\t\"Actual\":["
267
+ fuelOilModelConsumption = "\t\t\t\t\"Model\":["
268
+ elecNMBE = "\t\t\t\t\"NMBE\":["
269
+ demandNMBE = "\t\t\t\t\"NMBE\":["
270
+ gasNMBE = "\t\t\t\t\"NMBE\":["
271
+ fuelOilNMBE = "\t\t\t\t\"NMBE\":["
272
+ peakDemandUnitConversionFactor = 1.0
273
+ consumptionUnitConversionFactor = 1.0
274
+ hasElec = false
275
+ hasDemand = false
276
+ hasGas = false
277
+ hasFuelOil = false
278
+
279
+ missingData = false
280
+ # must have a runPeriod
281
+ runPeriod = model.runPeriod
282
+ if runPeriod.empty?
283
+ missingData = true
284
+ runner.registerWarning('Model has no run period and cannot generate all data.')
285
+ end
286
+
287
+ # must have a calendarYear to generate model data
288
+ yearDescription = model.yearDescription
289
+ if yearDescription.empty?
290
+ missingData = true
291
+ runner.registerWarning('Model has no year description and cannot generate all data.')
292
+ end
293
+ calendarYear = yearDescription.get.calendarYear
294
+ if calendarYear.empty?
295
+ missingData = true
296
+ runner.registerWarning('Model has no calendar year and cannot generate all data.')
297
+ end
298
+
299
+ all_actual_consumption_values = []
300
+ all_modeled_consumption_values = []
301
+
302
+ # sort bills by fuel type and name
303
+ utilityBills = model.getUtilityBills.sort { |x, y| (x.fuelType.valueDescription + x.name.get) <=> (y.fuelType.valueDescription + y.name.get) }
304
+ registered_fuel_types = []
305
+
306
+ utilityBills.each do |utilityBill|
307
+ fuel_type = utilityBill.fuelType.to_s
308
+ utility_bill_name = OpenStudio.toUnderscoreCase(utilityBill.name.get)
309
+ utility_bill_fuel_type = OpenStudio.toUnderscoreCase(utilityBill.fuelType.valueDescription)
310
+ if registered_fuel_types.include?(utility_bill_fuel_type)
311
+ runner.registerWarning("More than one utility bill of fuel type #{utility_bill_fuel_type} is in the model. Skipping #{utility_bill_name}.")
312
+ next
313
+ else
314
+ registered_fuel_types << utility_bill_fuel_type
315
+ end
316
+
317
+ cvrsme = 0.0
318
+ unless utilityBill.CVRMSE.empty?
319
+ cvrsme = utilityBill.CVRMSE.get
320
+ if os_version >= min_version_feature1
321
+ runner.registerValue("#{utility_bill_fuel_type}_consumption_cvrmse", cvrsme, '%')
322
+ end
323
+ cvrsme = format '%.2f', cvrsme
324
+ end
325
+
326
+ nmbe = 0.0
327
+ unless utilityBill.NMBE.empty?
328
+ nmbe = utilityBill.NMBE.get
329
+ if os_version >= min_version_feature1
330
+ runner.registerValue("#{utility_bill_fuel_type}_consumption_nmbe", nmbe, '%')
331
+ end
332
+ nmbe = format '%.2f', nmbe
333
+ end
334
+
335
+ string = ''
336
+ string << "\t\t\"cvrsme\":\"" << cvrsme.to_s << "\",\n\t\t\"nmbe\":\"" << nmbe.to_s << "\",\n\t\t\t\"data\":{\n"
337
+
338
+ hasDemandValues = false
339
+ if !utilityBill.peakDemandUnitConversionFactor.empty?
340
+ hasDemandValues = true
341
+ energyElec << string
342
+ energyDemand << string
343
+ peakDemandUnitConversionFactor = utilityBill.peakDemandUnitConversionFactor.get
344
+ elsif utility_bill_fuel_type == 'natural_gas' # NaturalGas
345
+ hasDemandValues = false
346
+ energyGas << string
347
+ elsif utility_bill_fuel_type == 'fuel_oil_2' # FuelOil_2
348
+ hasDemandValues = false
349
+ energyFuelOil << string
350
+ else
351
+ runner.registerWarning("#{utility_bill_fuel_type} is an unsupported fuel type.")
352
+ end
353
+
354
+ consumptionUnitConversionFactor = utilityBill.consumptionUnitConversionFactor
355
+
356
+ period_index = 1
357
+ actual_consumption = 0.0
358
+ modeled_consumption = 0.0
359
+ actual_consumption_values = []
360
+ modeled_consumption_values = []
361
+ actual_demand = 0.0
362
+ modeled_demand = 0.0
363
+
364
+ utilityBill.billingPeriods.each do |billingPeriod|
365
+ tempStartDate = '"' << billingPeriod.startDate.monthOfYear.value.to_s
366
+ tempStartDate << '/'
367
+ tempStartDate << billingPeriod.startDate.dayOfMonth.to_s << '"'
368
+ tempEndDate = '"' << billingPeriod.endDate.monthOfYear.value.to_s
369
+ tempEndDate << '/'
370
+ tempEndDate << billingPeriod.endDate.dayOfMonth.to_s << '"'
371
+ if os_version >= min_version_feature1
372
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_start_date", billingPeriod.startDate.to_s)
373
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_end_date", billingPeriod.endDate.to_s)
374
+ end
375
+
376
+ if hasDemandValues
377
+ elecStartDate << tempStartDate << ','
378
+ elecEndDate << tempEndDate << ','
379
+
380
+ consumption = billingPeriod.consumption
381
+ if !consumption.empty?
382
+ hasElec = true
383
+ elecActualConsumption << consumption.get.to_s
384
+ actual_consumption += consumption.get
385
+ actual_consumption_values << consumption.get
386
+ all_actual_consumption_values << consumption.get * utilityBill.consumptionUnitConversionFactor
387
+ if os_version >= min_version_feature1
388
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_consumption_actual",
389
+ consumption.get,
390
+ utilityBill.consumptionUnit)
391
+ end
392
+ else
393
+ elecActualConsumption << '0'
394
+ end
395
+ elecActualConsumption << ','
396
+
397
+ consumption = billingPeriod.modelConsumption
398
+ if !consumption.empty?
399
+ hasElec = true
400
+ temp = consumption.get / consumptionUnitConversionFactor
401
+ elecModelConsumption << temp.round(2).to_s
402
+ modeled_consumption += temp
403
+ modeled_consumption_values << temp
404
+ all_modeled_consumption_values << consumption.get
405
+ if os_version >= min_version_feature1
406
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_consumption_modeled",
407
+ temp,
408
+ utilityBill.consumptionUnit)
409
+ end
410
+ else
411
+ elecModelConsumption << '0'
412
+ end
413
+ elecModelConsumption << ','
414
+
415
+ peakDemand = billingPeriod.peakDemand
416
+ if !peakDemand.empty?
417
+ hasDemand = true
418
+ actualPeakDemand << peakDemand.get.to_s
419
+ actual_demand = peakDemand.get if peakDemand.get > actual_demand
420
+ if os_version >= min_version_feature1
421
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_peak_demand_actual",
422
+ peakDemand.get,
423
+ utilityBill.peakDemandUnit.get)
424
+ end
425
+ else
426
+ actualPeakDemand << '0'
427
+ end
428
+ actualPeakDemand << ','
429
+
430
+ peakDemand = billingPeriod.modelPeakDemand
431
+ if !peakDemand.empty?
432
+ hasDemand = true
433
+ temp = peakDemand.get / 1000
434
+ temp_str = format '%.1f', temp
435
+ modelPeakDemand << temp_str.to_s
436
+ modeled_demand = temp if temp > modeled_demand
437
+ if os_version >= min_version_feature1
438
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_peak_demand_modeled",
439
+ temp,
440
+ utilityBill.peakDemandUnit.get)
441
+ end
442
+ else
443
+ modelPeakDemand << '0'
444
+ end
445
+ modelPeakDemand << ','
446
+
447
+ if !billingPeriod.peakDemand.empty? && !billingPeriod.modelPeakDemand.empty? && (billingPeriod.consumption.get != 0)
448
+ percent = 100 * ((billingPeriod.modelPeakDemand.get / 1000) - billingPeriod.peakDemand.get) / billingPeriod.peakDemand.get
449
+ percent_str = format '%.2f', percent
450
+ demandNMBE << percent_str.to_s
451
+ if os_version >= min_version_feature1
452
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_peak_demand_nmbe",
453
+ percent,
454
+ '%')
455
+ end
456
+ else
457
+ demandNMBE << '0'
458
+ end
459
+ demandNMBE << ','
460
+
461
+ if !billingPeriod.consumption.empty? && !billingPeriod.modelConsumption.empty? && (billingPeriod.consumption.get != 0)
462
+ percent = 100 * ((billingPeriod.modelConsumption.get / consumptionUnitConversionFactor) - billingPeriod.consumption.get) / billingPeriod.consumption.get
463
+ percent_str = format '%.2f', percent
464
+ elecNMBE << percent_str.to_s
465
+ if os_version >= min_version_feature1
466
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_consumption_nmbe",
467
+ percent,
468
+ '%')
469
+ end
470
+ else
471
+ elecNMBE << '0'
472
+ end
473
+ elecNMBE << ','
474
+
475
+ elsif utility_bill_fuel_type == 'natural_gas' # NaturalGas
476
+ gasStartDate << tempStartDate << ','
477
+ gasEndDate << tempEndDate << ','
478
+
479
+ consumption = billingPeriod.consumption
480
+ if !consumption.empty?
481
+ hasGas = true
482
+ gasActualConsumption << consumption.get.to_s
483
+ actual_consumption += consumption.get
484
+ actual_consumption_values << consumption.get
485
+ all_actual_consumption_values << consumption.get * utilityBill.consumptionUnitConversionFactor
486
+ if os_version >= min_version_feature1
487
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_consumption_actual",
488
+ consumption.get,
489
+ utilityBill.consumptionUnit)
490
+ end
491
+ else
492
+ gasActualConsumption << '0'
493
+ end
494
+ gasActualConsumption << ','
495
+
496
+ consumption = billingPeriod.modelConsumption
497
+ if !consumption.empty?
498
+ hasGas = true
499
+ temp = consumption.get / consumptionUnitConversionFactor
500
+ gasModelConsumption << temp.round(2).to_s
501
+ modeled_consumption += temp
502
+ modeled_consumption_values << temp
503
+ all_modeled_consumption_values << consumption.get
504
+ if os_version >= min_version_feature1
505
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_consumption_modeled",
506
+ temp,
507
+ utilityBill.consumptionUnit)
508
+ end
509
+ else
510
+ gasModelConsumption << '0'
511
+ end
512
+ gasModelConsumption << ','
513
+
514
+ if !billingPeriod.consumption.empty? && !billingPeriod.modelConsumption.empty? && (billingPeriod.consumption.get != 0)
515
+ percent = 100 * ((billingPeriod.modelConsumption.get / consumptionUnitConversionFactor) - billingPeriod.consumption.get) / billingPeriod.consumption.get
516
+ percent_str = format '%.2f', percent
517
+ gasNMBE << percent_str.to_s
518
+ if os_version >= min_version_feature1
519
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_consumption_nmbe",
520
+ percent,
521
+ '%')
522
+ end
523
+ else
524
+ gasNMBE << '0'
525
+ end
526
+ gasNMBE << ','
527
+
528
+ elsif utility_bill_fuel_type == 'fuel_oil_2' # FuelOil_2
529
+ fuelOilStartDate << tempStartDate << ','
530
+ fuelOilEndDate << tempEndDate << ','
531
+
532
+ consumption = billingPeriod.consumption
533
+ if !consumption.empty?
534
+ hasFuelOil = true
535
+ fuelOilActualConsumption << consumption.get.to_s
536
+ actual_consumption += consumption.get
537
+ actual_consumption_values << consumption.get
538
+ all_actual_consumption_values << consumption.get * utilityBill.consumptionUnitConversionFactor
539
+ if os_version >= min_version_feature1
540
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_consumption_actual",
541
+ consumption.get,
542
+ utilityBill.consumptionUnit)
543
+ end
544
+ else
545
+ fuelOilActualConsumption << '0'
546
+ end
547
+ fuelOilActualConsumption << ','
548
+
549
+ consumption = billingPeriod.modelConsumption
550
+
551
+ if !consumption.empty?
552
+ hasFuelOil = true
553
+ temp = consumption.get / consumptionUnitConversionFactor
554
+ fuelOilModelConsumption << temp.round(2).to_s
555
+ modeled_consumption += temp
556
+ modeled_consumption_values << temp
557
+ all_modeled_consumption_values << consumption.get
558
+ if os_version >= min_version_feature1
559
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_consumption_modeled",
560
+ temp,
561
+ utilityBill.consumptionUnit)
562
+ end
563
+ else
564
+ fuelOilModelConsumption << '0'
565
+ # TODO: - test after https://github.com/NREL/OpenStudio/issues 3316 is fixed
566
+ runner.registerWarning("In OpenStudio 2.7.0 Fuel Oil modeled consumption by billing period isn't properly represented.")
567
+ end
568
+ fuelOilModelConsumption << ','
569
+
570
+ if !billingPeriod.consumption.empty? && !billingPeriod.modelConsumption.empty? && (billingPeriod.consumption.get != 0)
571
+ percent = 100 * ((billingPeriod.modelConsumption.get / consumptionUnitConversionFactor) - billingPeriod.consumption.get) / billingPeriod.consumption.get
572
+ percent_str = format '%.2f', percent
573
+ fuelOilNMBE << percent_str.to_s
574
+ if os_version >= min_version_feature1
575
+ runner.registerValue("#{utility_bill_fuel_type}_period_#{period_index}_consumption_nmbe",
576
+ percent,
577
+ '%')
578
+ end
579
+ else
580
+ fuelOilNMBE << '0'
581
+ end
582
+ fuelOilNMBE << ','
583
+
584
+ else
585
+ runner.registerWarning("#{utility_bill_fuel_type} isn't a currently supported fuel type for this measure.")
586
+
587
+ end
588
+ period_index += 1
589
+ end
590
+
591
+ next unless os_version >= min_version_feature1
592
+ if actual_consumption > 0.0
593
+ runner.registerValue("#{utility_bill_fuel_type}_consumption_actual",
594
+ actual_consumption,
595
+ utilityBill.consumptionUnit)
596
+ runner.registerValue("#{utility_bill_fuel_type}_consumption_modeled",
597
+ modeled_consumption,
598
+ utilityBill.consumptionUnit)
599
+ end
600
+ if actual_demand > 0.0
601
+ runner.registerValue("#{utility_bill_fuel_type}_peak_demand_actual",
602
+ actual_demand,
603
+ utilityBill.peakDemandUnit.get)
604
+ runner.registerValue("#{utility_bill_fuel_type}_peak_demand_modeled",
605
+ modeled_demand,
606
+ utilityBill.peakDemandUnit.get)
607
+ runner.registerValue("#{utility_bill_fuel_type}_peak_demand_nmbe",
608
+ 100.0 * (modeled_demand - actual_demand) / actual_demand,
609
+ '%')
610
+ end
611
+ next unless !actual_consumption_values.empty? && (actual_consumption_values.size == modeled_consumption_values.size)
612
+ sum_squares = 0.0
613
+ actual_consumption_values.each_index do |i|
614
+ sum_squares += (actual_consumption_values[i] - modeled_consumption_values[i])**2
615
+ end
616
+ rmse = Math.sqrt(sum_squares / actual_consumption_values.size)
617
+ runner.registerValue("#{utility_bill_fuel_type}_sum_of_squares",
618
+ sum_squares,
619
+ utilityBill.consumptionUnit)
620
+ runner.registerValue("#{utility_bill_fuel_type}_dof",
621
+ actual_consumption_values.size)
622
+ runner.registerValue("#{utility_bill_fuel_type}_rmse",
623
+ rmse,
624
+ utilityBill.consumptionUnit + '^0.5')
625
+ end
626
+
627
+ if os_version >= min_version_feature1
628
+ if !all_actual_consumption_values.empty? && (all_actual_consumption_values.size == all_modeled_consumption_values.size)
629
+ sum_squares = 0.0
630
+ all_actual_consumption_values.each_index do |i|
631
+ sum_squares += (all_actual_consumption_values[i] - all_modeled_consumption_values[i])**2
632
+ end
633
+ rmse = Math.sqrt(sum_squares / all_actual_consumption_values.size)
634
+ runner.registerValue('total_sum_of_squares',
635
+ sum_squares,
636
+ 'kBtu')
637
+ runner.registerValue('total_dof',
638
+ all_actual_consumption_values.size)
639
+ runner.registerValue('total_rmse',
640
+ rmse,
641
+ 'kBtu^0.5')
642
+ end
643
+
644
+ end
645
+
646
+ elecStartDate = elecStartDate[0..-2]
647
+ elecStartDate << "],\n"
648
+ elecEndDate = elecEndDate[0..-2]
649
+ elecEndDate << "],\n"
650
+ elecActualConsumption = elecActualConsumption[0..-2]
651
+ elecActualConsumption << "],\n"
652
+ elecModelConsumption = elecModelConsumption[0..-2]
653
+ elecModelConsumption << "],\n"
654
+ actualPeakDemand = actualPeakDemand[0..-2]
655
+ actualPeakDemand << "],\n"
656
+ modelPeakDemand = modelPeakDemand[0..-2]
657
+ modelPeakDemand << "],\n"
658
+ elecNMBE = elecNMBE[0..-2]
659
+ elecNMBE << "]\n"
660
+ demandNMBE = demandNMBE[0..-2]
661
+ demandNMBE << "]\n"
662
+ energyElec << elecStartDate << elecEndDate << elecActualConsumption << elecModelConsumption << elecNMBE
663
+ energyElec << "\t\t}\n" << "\t},\n"
664
+
665
+ energyDemand << elecStartDate << elecEndDate << actualPeakDemand << modelPeakDemand << demandNMBE
666
+ energyDemand << "\t\t}\n" << "\t},\n"
667
+
668
+ gasStartDate = gasStartDate[0..-2]
669
+ gasStartDate << "],\n"
670
+ gasEndDate = gasEndDate[0..-2]
671
+ gasEndDate << "],\n"
672
+ gasActualConsumption = gasActualConsumption[0..-2]
673
+ gasActualConsumption << "],\n"
674
+ gasModelConsumption = gasModelConsumption[0..-2]
675
+ gasModelConsumption << "],\n"
676
+ gasNMBE = gasNMBE[0..-2]
677
+ gasNMBE << "]\n"
678
+ energyGas << gasStartDate << gasEndDate << gasActualConsumption << gasModelConsumption << gasNMBE
679
+ energyGas << "\t\t}\n" << "\t},\n"
680
+
681
+ fuelOilStartDate = fuelOilStartDate[0..-2]
682
+ fuelOilStartDate << "],\n"
683
+ fuelOilEndDate = fuelOilEndDate[0..-2]
684
+ fuelOilEndDate << "],\n"
685
+ fuelOilActualConsumption = fuelOilActualConsumption[0..-2]
686
+ fuelOilActualConsumption << "],\n"
687
+ fuelOilModelConsumption = fuelOilModelConsumption[0..-2]
688
+ fuelOilModelConsumption << "],\n"
689
+ fuelOilNMBE = fuelOilNMBE[0..-2]
690
+ fuelOilNMBE << "]\n"
691
+ energyFuelOil << fuelOilStartDate << fuelOilEndDate << fuelOilActualConsumption << fuelOilModelConsumption << fuelOilNMBE
692
+ energyFuelOil << "\t\t}\n" << "\t},\n"
693
+
694
+ energy << "var consumption = {\n"
695
+
696
+ energy << energyElec if hasElec
697
+
698
+ energy << energyDemand if hasDemand
699
+
700
+ energy << energyGas if hasGas
701
+
702
+ energy << energyFuelOil if hasFuelOil
703
+ energy << '};'
704
+
705
+ # read in template
706
+ html_in_path = "#{File.dirname(__FILE__)}/resources/report.html.in"
707
+ html_in_path = if File.exist?(html_in_path)
708
+ html_in_path
709
+ else
710
+ "#{File.dirname(__FILE__)}/report.html.in"
711
+ end
712
+ html_in = ''
713
+ File.open(html_in_path, 'r') do |file|
714
+ html_in = file.read
715
+ end
716
+
717
+ # configure template with variable values
718
+ renderer = ERB.new(html_in)
719
+ html_out = renderer.result(binding)
720
+
721
+ # write html file
722
+ html_out_path = './report.html'
723
+ File.open(html_out_path, 'w') do |file|
724
+ file << html_out
725
+ # make sure data is written to the disk one way or the other
726
+ begin
727
+ file.fsync
728
+ rescue StandardError
729
+ file.flush
730
+ end
731
+ end
732
+
733
+ # closing the sql file
734
+ sqlFile.close
735
+
736
+ # reporting final condition
737
+ if missingData == true
738
+ runner.registerFinalCondition('Calibration Report was not generated successfully.')
739
+ else
740
+ runner.registerFinalCondition('Calibration Report generated successfully.')
741
+ end
742
+
743
+ # write json specific file format, everything can be derived from reported attributes
744
+ result_hash = {}
745
+ runner.result.attributes.each do |attribute|
746
+ # skip individual period metrics
747
+ next if /period_\d+_consumption/.match(attribute.name)
748
+
749
+ if match_data = /(.*)_consumption_cvrmse/.match(attribute.name)
750
+ cvrmse = attribute.valueAsDouble
751
+
752
+ # this is a hack
753
+ is_electric = /electric/i.match(match_data[1])
754
+
755
+ within_limit = false
756
+ within_limit = if is_electric
757
+ (cvrmse <= electric_cvrmse_limit)
758
+ else
759
+ (cvrmse <= gas_cvrmse_limit)
760
+ end
761
+ result_hash[match_data[1] + '_cvrmse_within_limit'] = within_limit
762
+ within_limit_i = if within_limit
763
+ 1
764
+ else
765
+ 0
766
+ end
767
+ runner.registerValue("#{match_data[1]}_cvrmse_within_limit", within_limit_i)
768
+ elsif match_data = /(.*)_consumption_nmbe/i.match(attribute.name)
769
+ nmbe = attribute.valueAsDouble
770
+
771
+ # this is a hack
772
+ is_electric = /electric/i.match(match_data[1])
773
+
774
+ within_limit = false
775
+ within_limit = if is_electric
776
+ (nmbe.abs <= electric_nmbe_limit)
777
+ else
778
+ (nmbe.abs <= gas_nmbe_limit)
779
+ end
780
+ result_hash[match_data[1] + '_nmbe_within_limit'] = within_limit
781
+ within_limit_i = if within_limit
782
+ 1
783
+ else
784
+ 0
785
+ end
786
+ runner.registerValue("#{match_data[1]}_nmbe_within_limit", within_limit_i)
787
+ end
788
+ end
789
+ File.open('./report_guideline.json', 'w') do |f|
790
+ f.write(result_hash.to_json)
791
+ end
792
+
793
+ true
794
+ end # end the run method
795
+ end # end the measure
796
+
797
+ # this allows the measure to be use by the application
798
+ CalibrationReportsEnhanced.new.registerWithApplication