openstudio-calibration 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +29 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +20 -0
- data/Jenkinsfile +6 -0
- data/LICENSE.md +27 -0
- data/README.md +33 -0
- data/Rakefile +50 -0
- data/doc_templates/LICENSE.md +27 -0
- data/doc_templates/README.md.erb +42 -0
- data/doc_templates/copyright_erb.txt +36 -0
- data/doc_templates/copyright_js.txt +4 -0
- data/doc_templates/copyright_ruby.txt +34 -0
- data/lib/files/.gitkeep +0 -0
- data/lib/measures/AddMonthlyJSONUtilityData/LICENSE.md +27 -0
- data/lib/measures/AddMonthlyJSONUtilityData/README.md +96 -0
- data/lib/measures/AddMonthlyJSONUtilityData/README.md.erb +42 -0
- data/lib/measures/AddMonthlyJSONUtilityData/measure.rb +280 -0
- data/lib/measures/AddMonthlyJSONUtilityData/measure.xml +163 -0
- data/lib/measures/AddMonthlyUtilityData/LICENSE.md +27 -0
- data/lib/measures/AddMonthlyUtilityData/README.md +64 -0
- data/lib/measures/AddMonthlyUtilityData/README.md.erb +42 -0
- data/lib/measures/AddMonthlyUtilityData/measure.rb +312 -0
- data/lib/measures/AddMonthlyUtilityData/measure.xml +115 -0
- data/lib/measures/AddMonthlyUtilityData/tests/AddMonthlyUtilityData_Test.rb +88 -0
- data/lib/measures/AddMonthlyUtilityData/tests/electric_billed_usages.json +198 -0
- data/lib/measures/AddMonthlyUtilityData/tests/gas_billed_usages.json +198 -0
- data/lib/measures/CalibrationReports/LICENSE.md +27 -0
- data/lib/measures/CalibrationReports/README.md +26 -0
- data/lib/measures/CalibrationReports/README.md.erb +42 -0
- data/lib/measures/CalibrationReports/measure.rb +511 -0
- data/lib/measures/CalibrationReports/measure.xml +98 -0
- data/lib/measures/CalibrationReports/resources/report.html.in +379 -0
- data/lib/measures/CalibrationReports/tests/CalibrationReports_Test.rb +523 -0
- data/lib/measures/CalibrationReports/tests/ExampleModel.osm +10497 -0
- data/lib/measures/CalibrationReports/tests/ExampleModelNoDemandInput.osm +10560 -0
- data/lib/measures/CalibrationReports/tests/ExampleModelNoGasInput.osm +10456 -0
- data/lib/measures/CalibrationReports/tests/USA_CO_Golden-NREL.724666_TMY3.epw +8768 -0
- data/lib/measures/CalibrationReportsEnhanced/LICENSE.md +27 -0
- data/lib/measures/CalibrationReportsEnhanced/README.md +143 -0
- data/lib/measures/CalibrationReportsEnhanced/README.md.erb +42 -0
- data/lib/measures/CalibrationReportsEnhanced/measure.rb +798 -0
- data/lib/measures/CalibrationReportsEnhanced/measure.xml +372 -0
- data/lib/measures/CalibrationReportsEnhanced/resources/report.html.in +380 -0
- data/lib/measures/CalibrationReportsEnhanced/tests/CalibrationReportsEnhanced_Test.rb +734 -0
- data/lib/measures/CalibrationReportsEnhanced/tests/ExampleModel.osm +10497 -0
- data/lib/measures/CalibrationReportsEnhanced/tests/ExampleModel_FuelOil.osm +12740 -0
- data/lib/measures/CalibrationReportsEnhanced/tests/USA_CO_Golden-NREL.724666_TMY3.epw +8768 -0
- data/lib/measures/CalibrationReportsEnhanced21/LICENSE.md +27 -0
- data/lib/measures/CalibrationReportsEnhanced21/README.md +109 -0
- data/lib/measures/CalibrationReportsEnhanced21/README.md.erb +42 -0
- data/lib/measures/CalibrationReportsEnhanced21/measure.rb +690 -0
- data/lib/measures/CalibrationReportsEnhanced21/measure.xml +269 -0
- data/lib/measures/CalibrationReportsEnhanced21/resources/report.html.in +380 -0
- data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/LICENSE.md +27 -0
- data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/README.md +48 -0
- data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/README.md.erb +42 -0
- data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/measure.rb +237 -0
- data/lib/measures/CoilCoolingDXSingleSpeedMultiplier/measure.xml +93 -0
- data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/LICENSE.md +27 -0
- data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/README.md +48 -0
- data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/README.md.erb +42 -0
- data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/measure.rb +228 -0
- data/lib/measures/CoilCoolingDXSingleSpeedPercentChange/measure.xml +93 -0
- data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/LICENSE.md +27 -0
- data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/README.md +64 -0
- data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/README.md.erb +42 -0
- data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/measure.rb +280 -0
- data/lib/measures/CoilCoolingDXTwoSpeedMultiplier/measure.xml +111 -0
- data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/LICENSE.md +27 -0
- data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/README.md +64 -0
- data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/README.md.erb +42 -0
- data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/measure.rb +270 -0
- data/lib/measures/CoilCoolingDXTwoSpeedPercentChange/measure.xml +111 -0
- data/lib/measures/CoilCoolingWaterMultiplier/LICENSE.md +27 -0
- data/lib/measures/CoilCoolingWaterMultiplier/README.md +80 -0
- data/lib/measures/CoilCoolingWaterMultiplier/README.md.erb +42 -0
- data/lib/measures/CoilCoolingWaterMultiplier/measure.rb +324 -0
- data/lib/measures/CoilCoolingWaterMultiplier/measure.xml +129 -0
- data/lib/measures/CoilCoolingWaterPercentChange/LICENSE.md +27 -0
- data/lib/measures/CoilCoolingWaterPercentChange/README.md +80 -0
- data/lib/measures/CoilCoolingWaterPercentChange/README.md.erb +42 -0
- data/lib/measures/CoilCoolingWaterPercentChange/measure.rb +311 -0
- data/lib/measures/CoilCoolingWaterPercentChange/measure.xml +129 -0
- data/lib/measures/CoilHeatingElectricMultiplier/LICENSE.md +27 -0
- data/lib/measures/CoilHeatingElectricMultiplier/README.md +48 -0
- data/lib/measures/CoilHeatingElectricMultiplier/README.md.erb +42 -0
- data/lib/measures/CoilHeatingElectricMultiplier/measure.rb +240 -0
- data/lib/measures/CoilHeatingElectricMultiplier/measure.xml +93 -0
- data/lib/measures/CoilHeatingElectricPercentChange/LICENSE.md +27 -0
- data/lib/measures/CoilHeatingElectricPercentChange/README.md +48 -0
- data/lib/measures/CoilHeatingElectricPercentChange/README.md.erb +42 -0
- data/lib/measures/CoilHeatingElectricPercentChange/measure.rb +231 -0
- data/lib/measures/CoilHeatingElectricPercentChange/measure.xml +93 -0
- data/lib/measures/CoilHeatingGasMultiplier/LICENSE.md +27 -0
- data/lib/measures/CoilHeatingGasMultiplier/README.md +64 -0
- data/lib/measures/CoilHeatingGasMultiplier/README.md.erb +42 -0
- data/lib/measures/CoilHeatingGasMultiplier/measure.rb +282 -0
- data/lib/measures/CoilHeatingGasMultiplier/measure.xml +111 -0
- data/lib/measures/CoilHeatingGasPercentChange/LICENSE.md +27 -0
- data/lib/measures/CoilHeatingGasPercentChange/README.md +64 -0
- data/lib/measures/CoilHeatingGasPercentChange/README.md.erb +42 -0
- data/lib/measures/CoilHeatingGasPercentChange/measure.rb +271 -0
- data/lib/measures/CoilHeatingGasPercentChange/measure.xml +111 -0
- data/lib/measures/CoilHeatingWaterMultiplier/LICENSE.md +27 -0
- data/lib/measures/CoilHeatingWaterMultiplier/README.md +48 -0
- data/lib/measures/CoilHeatingWaterMultiplier/README.md.erb +42 -0
- data/lib/measures/CoilHeatingWaterMultiplier/measure.rb +235 -0
- data/lib/measures/CoilHeatingWaterMultiplier/measure.xml +93 -0
- data/lib/measures/CoilHeatingWaterPercentChange/LICENSE.md +27 -0
- data/lib/measures/CoilHeatingWaterPercentChange/README.md +48 -0
- data/lib/measures/CoilHeatingWaterPercentChange/README.md.erb +42 -0
- data/lib/measures/CoilHeatingWaterPercentChange/measure.rb +226 -0
- data/lib/measures/CoilHeatingWaterPercentChange/measure.xml +93 -0
- data/lib/measures/ConstructionLayerZeroMaterialProperties/LICENSE.md +27 -0
- data/lib/measures/ConstructionLayerZeroMaterialProperties/README.md +88 -0
- data/lib/measures/ConstructionLayerZeroMaterialProperties/README.md.erb +42 -0
- data/lib/measures/ConstructionLayerZeroMaterialProperties/measure.rb +221 -0
- data/lib/measures/ConstructionLayerZeroMaterialProperties/measure.xml +194 -0
- data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/LICENSE.md +27 -0
- data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/README.md +40 -0
- data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/README.md.erb +42 -0
- data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/measure.rb +102 -0
- data/lib/measures/ElectricBaseboardEfficiencyAndCapacity/measure.xml +78 -0
- data/lib/measures/ExteriorWallThermalPropertiesMultiplier/LICENSE.md +27 -0
- data/lib/measures/ExteriorWallThermalPropertiesMultiplier/README.md +48 -0
- data/lib/measures/ExteriorWallThermalPropertiesMultiplier/README.md.erb +42 -0
- data/lib/measures/ExteriorWallThermalPropertiesMultiplier/measure.rb +263 -0
- data/lib/measures/ExteriorWallThermalPropertiesMultiplier/measure.xml +97 -0
- data/lib/measures/ExteriorWallThermalPropertiesPercentChange/LICENSE.md +27 -0
- data/lib/measures/ExteriorWallThermalPropertiesPercentChange/README.md +48 -0
- data/lib/measures/ExteriorWallThermalPropertiesPercentChange/README.md.erb +42 -0
- data/lib/measures/ExteriorWallThermalPropertiesPercentChange/measure.rb +253 -0
- data/lib/measures/ExteriorWallThermalPropertiesPercentChange/measure.xml +97 -0
- data/lib/measures/FansMultiplier/LICENSE.md +27 -0
- data/lib/measures/FansMultiplier/README.md +64 -0
- data/lib/measures/FansMultiplier/README.md.erb +42 -0
- data/lib/measures/FansMultiplier/measure.rb +297 -0
- data/lib/measures/FansMultiplier/measure.xml +166 -0
- data/lib/measures/FansPercentChange/LICENSE.md +27 -0
- data/lib/measures/FansPercentChange/README.md +64 -0
- data/lib/measures/FansPercentChange/README.md.erb +42 -0
- data/lib/measures/FansPercentChange/measure.rb +286 -0
- data/lib/measures/FansPercentChange/measure.xml +166 -0
- data/lib/measures/GeneralCalibrationMeasureMultiplier/LICENSE.md +27 -0
- data/lib/measures/GeneralCalibrationMeasureMultiplier/README.md +112 -0
- data/lib/measures/GeneralCalibrationMeasureMultiplier/README.md.erb +42 -0
- data/lib/measures/GeneralCalibrationMeasureMultiplier/measure.rb +639 -0
- data/lib/measures/GeneralCalibrationMeasureMultiplier/measure.xml +229 -0
- data/lib/measures/GeneralCalibrationMeasurePercentChange/LICENSE.md +27 -0
- data/lib/measures/GeneralCalibrationMeasurePercentChange/README.md +112 -0
- data/lib/measures/GeneralCalibrationMeasurePercentChange/README.md.erb +42 -0
- data/lib/measures/GeneralCalibrationMeasurePercentChange/measure.rb +756 -0
- data/lib/measures/GeneralCalibrationMeasurePercentChange/measure.xml +229 -0
- data/lib/measures/HardSizeHvac/LICENSE.md +27 -0
- data/lib/measures/HardSizeHvac/README.md +26 -0
- data/lib/measures/HardSizeHvac/README.md.erb +42 -0
- data/lib/measures/HardSizeHvac/measure.rb +88 -0
- data/lib/measures/HardSizeHvac/measure.xml +81 -0
- data/lib/measures/MaalkaMonthlyJSONUtilityData/LICENSE.md +27 -0
- data/lib/measures/MaalkaMonthlyJSONUtilityData/README.md +104 -0
- data/lib/measures/MaalkaMonthlyJSONUtilityData/README.md.erb +42 -0
- data/lib/measures/MaalkaMonthlyJSONUtilityData/measure.rb +304 -0
- data/lib/measures/MaalkaMonthlyJSONUtilityData/measure.xml +216 -0
- data/lib/measures/RValueOfInsulationForConstructionMultiplier/LICENSE.md +27 -0
- data/lib/measures/RValueOfInsulationForConstructionMultiplier/README.md +40 -0
- data/lib/measures/RValueOfInsulationForConstructionMultiplier/README.md.erb +42 -0
- data/lib/measures/RValueOfInsulationForConstructionMultiplier/measure.rb +196 -0
- data/lib/measures/RValueOfInsulationForConstructionMultiplier/measure.xml +132 -0
- data/lib/measures/RValueOfInsulationForConstructionPercentageChange/LICENSE.md +27 -0
- data/lib/measures/RValueOfInsulationForConstructionPercentageChange/README.md +40 -0
- data/lib/measures/RValueOfInsulationForConstructionPercentageChange/README.md.erb +42 -0
- data/lib/measures/RValueOfInsulationForConstructionPercentageChange/measure.rb +189 -0
- data/lib/measures/RValueOfInsulationForConstructionPercentageChange/measure.xml +132 -0
- data/lib/measures/RoofThermalPropertiesMultiplier/LICENSE.md +27 -0
- data/lib/measures/RoofThermalPropertiesMultiplier/README.md +48 -0
- data/lib/measures/RoofThermalPropertiesMultiplier/README.md.erb +42 -0
- data/lib/measures/RoofThermalPropertiesMultiplier/measure.rb +263 -0
- data/lib/measures/RoofThermalPropertiesMultiplier/measure.xml +97 -0
- data/lib/measures/RoofThermalPropertiesPercentChange/LICENSE.md +27 -0
- data/lib/measures/RoofThermalPropertiesPercentChange/README.md +48 -0
- data/lib/measures/RoofThermalPropertiesPercentChange/README.md.erb +42 -0
- data/lib/measures/RoofThermalPropertiesPercentChange/measure.rb +253 -0
- data/lib/measures/RoofThermalPropertiesPercentChange/measure.xml +97 -0
- data/lib/measures/TimeseriesObjectiveFunction/LICENSE.md +27 -0
- data/lib/measures/TimeseriesObjectiveFunction/README.md +207 -0
- data/lib/measures/TimeseriesObjectiveFunction/README.md.erb +42 -0
- data/lib/measures/TimeseriesObjectiveFunction/measure.rb +748 -0
- data/lib/measures/TimeseriesObjectiveFunction/measure.xml +435 -0
- data/lib/measures/TimeseriesObjectiveFunction/resources/report.html.erb +288 -0
- data/lib/measures/TimeseriesPlot/LICENSE.md +27 -0
- data/lib/measures/TimeseriesPlot/README.md +56 -0
- data/lib/measures/TimeseriesPlot/README.md.erb +42 -0
- data/lib/measures/TimeseriesPlot/measure.rb +302 -0
- data/lib/measures/TimeseriesPlot/measure.xml +137 -0
- data/lib/measures/TimeseriesPlot/resources/report.html.erb +270 -0
- data/lib/measures/WaterHeaterMixedMultiplier/LICENSE.md +27 -0
- data/lib/measures/WaterHeaterMixedMultiplier/README.md +64 -0
- data/lib/measures/WaterHeaterMixedMultiplier/README.md.erb +42 -0
- data/lib/measures/WaterHeaterMixedMultiplier/measure.rb +255 -0
- data/lib/measures/WaterHeaterMixedMultiplier/measure.xml +180 -0
- data/lib/measures/WaterHeaterMixedPercentChange/LICENSE.md +27 -0
- data/lib/measures/WaterHeaterMixedPercentChange/README.md +64 -0
- data/lib/measures/WaterHeaterMixedPercentChange/README.md.erb +42 -0
- data/lib/measures/WaterHeaterMixedPercentChange/measure.rb +245 -0
- data/lib/measures/WaterHeaterMixedPercentChange/measure.xml +180 -0
- data/lib/measures/zone_report/LICENSE.md +27 -0
- data/lib/measures/zone_report/README.md +26 -0
- data/lib/measures/zone_report/README.md.erb +42 -0
- data/lib/measures/zone_report/measure.rb +706 -0
- data/lib/measures/zone_report/measure.xml +67 -0
- data/lib/measures/zone_report/resources/report.html.in +342 -0
- data/lib/openstudio-calibration-measures.rb +36 -0
- data/lib/openstudio/calibration_measures.rb +37 -0
- data/lib/openstudio/calibration_measures/extension.rb +49 -0
- data/lib/openstudio/calibration_measures/version.rb +40 -0
- data/openstudio-calibration.gemspec +30 -0
- 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,207 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
###### (Automatically generated documentation)
|
4
|
+
|
5
|
+
# TimeSeries Objective Function
|
6
|
+
|
7
|
+
## Description
|
8
|
+
Creates Objective Function from Timeseries Data
|
9
|
+
|
10
|
+
## Modeler Description
|
11
|
+
Creates Objective Function from Timeseries Data. The measure applies a Norm at each timestep between the difference of CSV metered data and SQL model data. A timeseries plot can also be created. Possible outputs are 'cvrmse', 'nmbe', 'simdata' = sum of the simulated data, 'csvdata' = sum of metered data, 'diff' = P Norm between the metered and simulated data if Norm is 1 or 2, else its just the Difference.
|
12
|
+
|
13
|
+
## Measure Type
|
14
|
+
ReportingMeasure
|
15
|
+
|
16
|
+
## Taxonomy
|
17
|
+
|
18
|
+
|
19
|
+
## Arguments
|
20
|
+
|
21
|
+
|
22
|
+
### Path to CSV file for the metered data
|
23
|
+
Path to CSV file including file name.
|
24
|
+
**Name:** csv_name,
|
25
|
+
**Type:** String,
|
26
|
+
**Units:** ,
|
27
|
+
**Required:** true,
|
28
|
+
**Model Dependent:** false
|
29
|
+
|
30
|
+
### CSV Time Header
|
31
|
+
CSV Time Header Value. Used to determine the timestamp column in the CSV file
|
32
|
+
**Name:** csv_time_header,
|
33
|
+
**Type:** String,
|
34
|
+
**Units:** ,
|
35
|
+
**Required:** true,
|
36
|
+
**Model Dependent:** false
|
37
|
+
|
38
|
+
### CSV variable name
|
39
|
+
CSV variable name. Used to determine the variable column in the CSV file
|
40
|
+
**Name:** csv_var,
|
41
|
+
**Type:** String,
|
42
|
+
**Units:** ,
|
43
|
+
**Required:** true,
|
44
|
+
**Model Dependent:** false
|
45
|
+
|
46
|
+
### Convert Units
|
47
|
+
Convert Units in Metered Data
|
48
|
+
**Name:** convert_data,
|
49
|
+
**Type:** Choice,
|
50
|
+
**Units:** ,
|
51
|
+
**Required:** true,
|
52
|
+
**Model Dependent:** false
|
53
|
+
|
54
|
+
### CSV variable display name
|
55
|
+
CSV variable display name. Not yet Implemented
|
56
|
+
**Name:** csv_var_dn,
|
57
|
+
**Type:** String,
|
58
|
+
**Units:** ,
|
59
|
+
**Required:** true,
|
60
|
+
**Model Dependent:** false
|
61
|
+
|
62
|
+
### Year in csv data timestamp
|
63
|
+
Is the Year in the csv data timestamp => mm:dd:yy or mm:dd (true/false)
|
64
|
+
**Name:** year,
|
65
|
+
**Type:** Boolean,
|
66
|
+
**Units:** ,
|
67
|
+
**Required:** true,
|
68
|
+
**Model Dependent:** false
|
69
|
+
|
70
|
+
### Seconds in csv data timestamp
|
71
|
+
Is the Seconds in the csv data timestamp => hh:mm:ss or hh:mm (true/false)
|
72
|
+
**Name:** seconds,
|
73
|
+
**Type:** Boolean,
|
74
|
+
**Units:** ,
|
75
|
+
**Required:** true,
|
76
|
+
**Model Dependent:** false
|
77
|
+
|
78
|
+
### SQL key value
|
79
|
+
SQL key value for the SQL query to find the variable in the SQL file
|
80
|
+
**Name:** key_value,
|
81
|
+
**Type:** String,
|
82
|
+
**Units:** ,
|
83
|
+
**Required:** true,
|
84
|
+
**Model Dependent:** false
|
85
|
+
|
86
|
+
### TimeSeries Name
|
87
|
+
TimeSeries Name for the SQL query to find the variable in the SQL file
|
88
|
+
**Name:** timeseries_name,
|
89
|
+
**Type:** String,
|
90
|
+
**Units:** ,
|
91
|
+
**Required:** true,
|
92
|
+
**Model Dependent:** false
|
93
|
+
|
94
|
+
### Reporting Frequency
|
95
|
+
Reporting Frequency for SQL Query
|
96
|
+
**Name:** reporting_frequency,
|
97
|
+
**Type:** Choice,
|
98
|
+
**Units:** ,
|
99
|
+
**Required:** true,
|
100
|
+
**Model Dependent:** false
|
101
|
+
|
102
|
+
### Environment Period
|
103
|
+
Environment Period for SQL query
|
104
|
+
**Name:** environment_period,
|
105
|
+
**Type:** String,
|
106
|
+
**Units:** ,
|
107
|
+
**Required:** true,
|
108
|
+
**Model Dependent:** false
|
109
|
+
|
110
|
+
### Norm of the difference of csv and sql
|
111
|
+
Norm of the difference of csv and sql. 1 is absolute value. 2 is euclidean distance. 3 is raw difference.
|
112
|
+
**Name:** norm,
|
113
|
+
**Type:** Double,
|
114
|
+
**Units:** ,
|
115
|
+
**Required:** true,
|
116
|
+
**Model Dependent:** false
|
117
|
+
|
118
|
+
### Scale factor to apply to the difference
|
119
|
+
Scale factor to apply to the difference (1 is no scale)
|
120
|
+
**Name:** scale,
|
121
|
+
**Type:** Double,
|
122
|
+
**Units:** ,
|
123
|
+
**Required:** true,
|
124
|
+
**Model Dependent:** false
|
125
|
+
|
126
|
+
### Find Available data in the SQL file
|
127
|
+
Will RegisterInfo all the 'EnvPeriod', 'ReportingFrequencies', 'VariableNames', 'KeyValues' in the SQL file. Useful for debugging SQL issues.
|
128
|
+
**Name:** find_avail,
|
129
|
+
**Type:** Boolean,
|
130
|
+
**Units:** ,
|
131
|
+
**Required:** true,
|
132
|
+
**Model Dependent:** false
|
133
|
+
|
134
|
+
### algorithm_download
|
135
|
+
Make JSON data available for algorithm_download (true/false)
|
136
|
+
**Name:** algorithm_download,
|
137
|
+
**Type:** Boolean,
|
138
|
+
**Units:** ,
|
139
|
+
**Required:** true,
|
140
|
+
**Model Dependent:** false
|
141
|
+
|
142
|
+
### plot_flag timeseries data
|
143
|
+
Create plot of timeseries data (true/false)
|
144
|
+
**Name:** plot_flag,
|
145
|
+
**Type:** Boolean,
|
146
|
+
**Units:** ,
|
147
|
+
**Required:** true,
|
148
|
+
**Model Dependent:** false
|
149
|
+
|
150
|
+
### Plot name
|
151
|
+
Name to include in reporting file name.
|
152
|
+
**Name:** plot_name,
|
153
|
+
**Type:** String,
|
154
|
+
**Units:** ,
|
155
|
+
**Required:** true,
|
156
|
+
**Model Dependent:** false
|
157
|
+
|
158
|
+
### verbose_messages
|
159
|
+
verbose messages. Useful for debugging but MAJOR Performance Hit.
|
160
|
+
**Name:** verbose_messages,
|
161
|
+
**Type:** Boolean,
|
162
|
+
**Units:** ,
|
163
|
+
**Required:** true,
|
164
|
+
**Model Dependent:** false
|
165
|
+
|
166
|
+
### warning_messages
|
167
|
+
Warn on missing data.
|
168
|
+
**Name:** warning_messages,
|
169
|
+
**Type:** Boolean,
|
170
|
+
**Units:** ,
|
171
|
+
**Required:** true,
|
172
|
+
**Model Dependent:** false
|
173
|
+
|
174
|
+
### add_first_zero_for_plots
|
175
|
+
Add a point of zero value to the plot at the beginning of the runperiod.
|
176
|
+
**Name:** add_first_zero_for_plots,
|
177
|
+
**Type:** Boolean,
|
178
|
+
**Units:** ,
|
179
|
+
**Required:** true,
|
180
|
+
**Model Dependent:** false
|
181
|
+
|
182
|
+
### add_last_zero_for_plots
|
183
|
+
Add a point of zero value to the plot at the end of the runperiod.
|
184
|
+
**Name:** add_last_zero_for_plots,
|
185
|
+
**Type:** Boolean,
|
186
|
+
**Units:** ,
|
187
|
+
**Required:** true,
|
188
|
+
**Model Dependent:** false
|
189
|
+
|
190
|
+
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
## Outputs
|
195
|
+
|
196
|
+
|
197
|
+
|
198
|
+
|
199
|
+
|
200
|
+
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
|
205
|
+
|
206
|
+
|
207
|
+
diff, simdata, csvdata, cvrmse, nmbe
|
@@ -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,748 @@
|
|
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
|
+
# see the URL below for information on how to write OpenStudio measures
|
37
|
+
# http://openstudio.nrel.gov/openstudio-measure-writing-guide
|
38
|
+
|
39
|
+
require 'csv'
|
40
|
+
require 'time'
|
41
|
+
require 'json'
|
42
|
+
require 'erb'
|
43
|
+
|
44
|
+
# start the measure
|
45
|
+
class TimeseriesObjectiveFunction < OpenStudio::Measure::ReportingMeasure
|
46
|
+
# human readable name
|
47
|
+
def name
|
48
|
+
'TimeSeries Objective Function'
|
49
|
+
end
|
50
|
+
|
51
|
+
# human readable description
|
52
|
+
def description
|
53
|
+
'Creates Objective Function from Timeseries Data'
|
54
|
+
end
|
55
|
+
|
56
|
+
# human readable description of modeling approach
|
57
|
+
def modeler_description
|
58
|
+
"Creates Objective Function from Timeseries Data. The measure applies a Norm at each timestep between the difference of CSV metered data and SQL model data. A timeseries plot can also be created. Possible outputs are 'cvrmse', 'nmbe', 'simdata' = sum of the simulated data, 'csvdata' = sum of metered data, 'diff' = P Norm between the metered and simulated data if Norm is 1 or 2, else its just the Difference."
|
59
|
+
end
|
60
|
+
|
61
|
+
# define the arguments that the user will input
|
62
|
+
def arguments
|
63
|
+
args = OpenStudio::Measure::OSArgumentVector.new
|
64
|
+
|
65
|
+
# the name of the sql file
|
66
|
+
csv_name = OpenStudio::Measure::OSArgument.makeStringArgument('csv_name', true)
|
67
|
+
csv_name.setDisplayName('Path to CSV file for the metered data')
|
68
|
+
csv_name.setDescription('Path to CSV file including file name.')
|
69
|
+
csv_name.setDefaultValue('../../../lib/resources/mtr.csv')
|
70
|
+
args << csv_name
|
71
|
+
|
72
|
+
csv_time_header = OpenStudio::Measure::OSArgument.makeStringArgument('csv_time_header', true)
|
73
|
+
csv_time_header.setDisplayName('CSV Time Header')
|
74
|
+
csv_time_header.setDescription('CSV Time Header Value. Used to determine the timestamp column in the CSV file')
|
75
|
+
csv_time_header.setDefaultValue('Date/Time')
|
76
|
+
args << csv_time_header
|
77
|
+
|
78
|
+
csv_var = OpenStudio::Measure::OSArgument.makeStringArgument('csv_var', true)
|
79
|
+
csv_var.setDisplayName('CSV variable name')
|
80
|
+
csv_var.setDescription('CSV variable name. Used to determine the variable column in the CSV file')
|
81
|
+
csv_var.setDefaultValue('Whole Building:Facility Total Electric Demand Power [W](TimeStep)')
|
82
|
+
args << csv_var
|
83
|
+
|
84
|
+
convert_data_chs = OpenStudio::StringVector.new
|
85
|
+
convert_data_chs << 'F to C'
|
86
|
+
convert_data_chs << 'WH to J'
|
87
|
+
convert_data_chs << 'CFM to m3/s'
|
88
|
+
convert_data_chs << 'PSI to Pa'
|
89
|
+
convert_data_chs << 'None'
|
90
|
+
convert_data = OpenStudio::Measure::OSArgument.makeChoiceArgument('convert_data', convert_data_chs, true)
|
91
|
+
convert_data.setDisplayName('Convert Units')
|
92
|
+
convert_data.setDescription('Convert Units in Metered Data')
|
93
|
+
convert_data.setDefaultValue('None')
|
94
|
+
args << convert_data
|
95
|
+
|
96
|
+
csv_var_dn = OpenStudio::Measure::OSArgument.makeStringArgument('csv_var_dn', true)
|
97
|
+
csv_var_dn.setDisplayName('CSV variable display name')
|
98
|
+
csv_var_dn.setDescription('CSV variable display name. Not yet Implemented')
|
99
|
+
csv_var_dn.setDefaultValue('')
|
100
|
+
args << csv_var_dn
|
101
|
+
|
102
|
+
years = OpenStudio::Measure::OSArgument.makeBoolArgument('year', true)
|
103
|
+
years.setDisplayName('Year in csv data timestamp')
|
104
|
+
years.setDescription('Is the Year in the csv data timestamp => mm:dd:yy or mm:dd (true/false)')
|
105
|
+
years.setDefaultValue(true)
|
106
|
+
args << years
|
107
|
+
|
108
|
+
seconds = OpenStudio::Measure::OSArgument.makeBoolArgument('seconds', true)
|
109
|
+
seconds.setDisplayName('Seconds in csv data timestamp')
|
110
|
+
seconds.setDescription('Is the Seconds in the csv data timestamp => hh:mm:ss or hh:mm (true/false)')
|
111
|
+
seconds.setDefaultValue(true)
|
112
|
+
args << seconds
|
113
|
+
|
114
|
+
sql_key = OpenStudio::Measure::OSArgument.makeStringArgument('key_value', true)
|
115
|
+
sql_key.setDisplayName('SQL key value')
|
116
|
+
sql_key.setDescription('SQL key value for the SQL query to find the variable in the SQL file')
|
117
|
+
sql_key.setDefaultValue('')
|
118
|
+
args << sql_key
|
119
|
+
|
120
|
+
sql_var = OpenStudio::Measure::OSArgument.makeStringArgument('timeseries_name', true)
|
121
|
+
sql_var.setDisplayName('TimeSeries Name')
|
122
|
+
sql_var.setDescription('TimeSeries Name for the SQL query to find the variable in the SQL file')
|
123
|
+
sql_var.setDefaultValue('Facility Total Electric Demand Power')
|
124
|
+
args << sql_var
|
125
|
+
|
126
|
+
reportfreq_chs = OpenStudio::StringVector.new
|
127
|
+
reportfreq_chs << 'Detailed'
|
128
|
+
reportfreq_chs << 'Timestep'
|
129
|
+
reportfreq_chs << 'Hourly'
|
130
|
+
reportfreq_chs << 'Daily'
|
131
|
+
reportfreq_chs << 'Monthly'
|
132
|
+
reportfreq_chs << 'RunPeriod'
|
133
|
+
reporting_frequency = OpenStudio::Measure::OSArgument.makeChoiceArgument('reporting_frequency', reportfreq_chs, true)
|
134
|
+
reporting_frequency.setDisplayName('Reporting Frequency')
|
135
|
+
reporting_frequency.setDescription('Reporting Frequency for SQL Query')
|
136
|
+
reporting_frequency.setDefaultValue('Zone Timestep')
|
137
|
+
args << reporting_frequency
|
138
|
+
|
139
|
+
environment_period = OpenStudio::Measure::OSArgument.makeStringArgument('environment_period', true)
|
140
|
+
environment_period.setDisplayName('Environment Period')
|
141
|
+
environment_period.setDescription('Environment Period for SQL query')
|
142
|
+
environment_period.setDefaultValue('RUN PERIOD 1')
|
143
|
+
args << environment_period
|
144
|
+
|
145
|
+
norm = OpenStudio::Measure::OSArgument.makeDoubleArgument('norm', true)
|
146
|
+
norm.setDisplayName('Norm of the difference of csv and sql')
|
147
|
+
norm.setDescription('Norm of the difference of csv and sql. 1 is absolute value. 2 is euclidean distance. 3 is raw difference.')
|
148
|
+
norm.setDefaultValue(1)
|
149
|
+
args << norm
|
150
|
+
|
151
|
+
scale = OpenStudio::Measure::OSArgument.makeDoubleArgument('scale', true)
|
152
|
+
scale.setDisplayName('Scale factor to apply to the difference')
|
153
|
+
scale.setDescription('Scale factor to apply to the difference (1 is no scale)')
|
154
|
+
scale.setDefaultValue(1)
|
155
|
+
args << scale
|
156
|
+
|
157
|
+
find_avail = OpenStudio::Measure::OSArgument.makeBoolArgument('find_avail', true)
|
158
|
+
find_avail.setDisplayName('Find Available data in the SQL file')
|
159
|
+
find_avail.setDescription("Will RegisterInfo all the 'EnvPeriod', 'ReportingFrequencies', 'VariableNames', 'KeyValues' in the SQL file. Useful for debugging SQL issues.")
|
160
|
+
find_avail.setDefaultValue(true)
|
161
|
+
args << find_avail
|
162
|
+
|
163
|
+
algorithm_download = OpenStudio::Measure::OSArgument.makeBoolArgument('algorithm_download', true)
|
164
|
+
algorithm_download.setDisplayName('algorithm_download')
|
165
|
+
algorithm_download.setDescription('Make JSON data available for algorithm_download (true/false)')
|
166
|
+
algorithm_download.setDefaultValue(false)
|
167
|
+
args << algorithm_download
|
168
|
+
|
169
|
+
plot_flag = OpenStudio::Measure::OSArgument.makeBoolArgument('plot_flag', true)
|
170
|
+
plot_flag.setDisplayName('plot_flag timeseries data')
|
171
|
+
plot_flag.setDescription('Create plot of timeseries data (true/false)')
|
172
|
+
plot_flag.setDefaultValue(true)
|
173
|
+
args << plot_flag
|
174
|
+
|
175
|
+
plot_name = OpenStudio::Measure::OSArgument.makeStringArgument('plot_name', true)
|
176
|
+
plot_name.setDisplayName('Plot name')
|
177
|
+
plot_name.setDescription('Name to include in reporting file name.')
|
178
|
+
plot_name.setDefaultValue('')
|
179
|
+
args << plot_name
|
180
|
+
|
181
|
+
verbose_messages = OpenStudio::Measure::OSArgument.makeBoolArgument('verbose_messages', true)
|
182
|
+
verbose_messages.setDisplayName('verbose_messages')
|
183
|
+
verbose_messages.setDescription('verbose messages. Useful for debugging but MAJOR Performance Hit.')
|
184
|
+
verbose_messages.setDefaultValue(false)
|
185
|
+
args << verbose_messages
|
186
|
+
|
187
|
+
warning_messages = OpenStudio::Measure::OSArgument.makeBoolArgument('warning_messages', true)
|
188
|
+
warning_messages.setDisplayName('warning_messages')
|
189
|
+
warning_messages.setDescription('Warn on missing data.')
|
190
|
+
warning_messages.setDefaultValue(true)
|
191
|
+
args << warning_messages
|
192
|
+
|
193
|
+
add_first_zero_for_plots = OpenStudio::Measure::OSArgument.makeBoolArgument('add_first_zero_for_plots', true)
|
194
|
+
add_first_zero_for_plots.setDisplayName('add_first_zero_for_plots')
|
195
|
+
add_first_zero_for_plots.setDescription('Add a point of zero value to the plot at the beginning of the runperiod.')
|
196
|
+
add_first_zero_for_plots.setDefaultValue(false)
|
197
|
+
args << add_first_zero_for_plots
|
198
|
+
|
199
|
+
add_last_zero_for_plots = OpenStudio::Measure::OSArgument.makeBoolArgument('add_last_zero_for_plots', true)
|
200
|
+
add_last_zero_for_plots.setDisplayName('add_last_zero_for_plots')
|
201
|
+
add_last_zero_for_plots.setDescription('Add a point of zero value to the plot at the end of the runperiod.')
|
202
|
+
add_last_zero_for_plots.setDefaultValue(false)
|
203
|
+
args << add_last_zero_for_plots
|
204
|
+
|
205
|
+
args
|
206
|
+
end
|
207
|
+
|
208
|
+
# adds output requests ahead of EnergyPlus simulation
|
209
|
+
def energyPlusOutputRequests(runner, user_arguments)
|
210
|
+
super(runner, user_arguments)
|
211
|
+
|
212
|
+
result = OpenStudio::IdfObjectVector.new
|
213
|
+
|
214
|
+
# use the built-in error checking
|
215
|
+
return result unless runner.validateUserArguments(arguments, user_arguments)
|
216
|
+
|
217
|
+
# gather required values from user arguments
|
218
|
+
key = runner.getStringArgumentValue('key_value', user_arguments)
|
219
|
+
variable = runner.getStringArgumentValue('timeseries_name', user_arguments)
|
220
|
+
timestep = runner.getStringArgumentValue('reporting_frequency', user_arguments)
|
221
|
+
|
222
|
+
# add output request using values from user argument
|
223
|
+
if key == 'no_key' # could also look for variable.include?(":Electricity")
|
224
|
+
result << OpenStudio::IdfObject.load("Output:Meter,#{variable},#{timestep};").get
|
225
|
+
else
|
226
|
+
result << OpenStudio::IdfObject.load("Output:Variable,#{key},#{variable},#{timestep};").get
|
227
|
+
end
|
228
|
+
|
229
|
+
result
|
230
|
+
end
|
231
|
+
|
232
|
+
# outputs for PAT
|
233
|
+
def outputs
|
234
|
+
result = OpenStudio::Measure::OSOutputVector.new
|
235
|
+
|
236
|
+
# calibration metrics
|
237
|
+
result << OpenStudio::Measure::OSOutput.makeDoubleOutput('diff') # kWh
|
238
|
+
result << OpenStudio::Measure::OSOutput.makeDoubleOutput('simdata') # kWh
|
239
|
+
result << OpenStudio::Measure::OSOutput.makeDoubleOutput('csvdata') # %
|
240
|
+
result << OpenStudio::Measure::OSOutput.makeDoubleOutput('cvrmse') # %
|
241
|
+
result << OpenStudio::Measure::OSOutput.makeDoubleOutput('nmbe') # kWh
|
242
|
+
|
243
|
+
result
|
244
|
+
end
|
245
|
+
|
246
|
+
# define what happens when the measure is run
|
247
|
+
def run(runner, user_arguments)
|
248
|
+
super(runner, user_arguments)
|
249
|
+
|
250
|
+
# use the built-in error checking
|
251
|
+
return false unless runner.validateUserArguments(arguments, user_arguments)
|
252
|
+
|
253
|
+
# get the last model and sql file
|
254
|
+
model = runner.lastOpenStudioModel
|
255
|
+
if model.empty?
|
256
|
+
runner.registerError('Cannot find last model.')
|
257
|
+
return false
|
258
|
+
end
|
259
|
+
model = model.get
|
260
|
+
|
261
|
+
sqlFile = runner.lastEnergyPlusSqlFile
|
262
|
+
if sqlFile.empty?
|
263
|
+
runner.registerError('Cannot find last sql file.')
|
264
|
+
return false
|
265
|
+
end
|
266
|
+
sqlFile = sqlFile.get
|
267
|
+
model.setSqlFile(sqlFile)
|
268
|
+
|
269
|
+
# assign the user inputs to variables
|
270
|
+
csv_name = runner.getStringArgumentValue('csv_name', user_arguments)
|
271
|
+
csv_time_header = runner.getStringArgumentValue('csv_time_header', user_arguments)
|
272
|
+
csv_var = runner.getStringArgumentValue('csv_var', user_arguments)
|
273
|
+
csv_var_dn = runner.getStringArgumentValue('csv_var_dn', user_arguments)
|
274
|
+
years = runner.getBoolArgumentValue('year', user_arguments)
|
275
|
+
seconds = runner.getBoolArgumentValue('seconds', user_arguments)
|
276
|
+
|
277
|
+
sql_key = runner.getStringArgumentValue('key_value', user_arguments)
|
278
|
+
# PAT fails on empty string or even a space as string, even though runs fine in OS app, as hack adding "no_key" method which converts to empty string here
|
279
|
+
sql_key = '' if sql_key.include?('no_key')
|
280
|
+
|
281
|
+
sql_var = runner.getStringArgumentValue('timeseries_name', user_arguments)
|
282
|
+
norm = runner.getDoubleArgumentValue('norm', user_arguments)
|
283
|
+
scale = runner.getDoubleArgumentValue('scale', user_arguments)
|
284
|
+
find_avail = runner.getBoolArgumentValue('find_avail', user_arguments)
|
285
|
+
verbose_messages = runner.getBoolArgumentValue('verbose_messages', user_arguments)
|
286
|
+
warning_messages = runner.getBoolArgumentValue('warning_messages', user_arguments)
|
287
|
+
algorithm_download = runner.getBoolArgumentValue('algorithm_download', user_arguments)
|
288
|
+
plot_flag = runner.getBoolArgumentValue('plot_flag', user_arguments)
|
289
|
+
plot_name = runner.getStringArgumentValue('plot_name', user_arguments)
|
290
|
+
environment_period = runner.getStringArgumentValue('environment_period', user_arguments)
|
291
|
+
reporting_frequency = runner.getStringArgumentValue('reporting_frequency', user_arguments)
|
292
|
+
convert_data = runner.getStringArgumentValue('convert_data', user_arguments)
|
293
|
+
last_zero = runner.getBoolArgumentValue('add_last_zero_for_plots', user_arguments)
|
294
|
+
first_zero = runner.getBoolArgumentValue('add_first_zero_for_plots', user_arguments)
|
295
|
+
@name = plot_name
|
296
|
+
# Method to translate from OpenStudio's time formatting
|
297
|
+
# to Javascript time formatting
|
298
|
+
# OpenStudio time
|
299
|
+
# 2009-May-14 00:10:00 Raw string
|
300
|
+
# Javascript time
|
301
|
+
# 2009/07/12 12:34:56
|
302
|
+
def to_JSTime(os_time)
|
303
|
+
js_time = os_time.to_s
|
304
|
+
# Replace the '-' with '/'
|
305
|
+
js_time = js_time.tr('-', '/')
|
306
|
+
# Replace month abbreviations with numbers
|
307
|
+
js_time = js_time.gsub('Jan', '01')
|
308
|
+
js_time = js_time.gsub('Feb', '02')
|
309
|
+
js_time = js_time.gsub('Mar', '03')
|
310
|
+
js_time = js_time.gsub('Apr', '04')
|
311
|
+
js_time = js_time.gsub('May', '05')
|
312
|
+
js_time = js_time.gsub('Jun', '06')
|
313
|
+
js_time = js_time.gsub('Jul', '07')
|
314
|
+
js_time = js_time.gsub('Aug', '08')
|
315
|
+
js_time = js_time.gsub('Sep', '09')
|
316
|
+
js_time = js_time.gsub('Oct', '10')
|
317
|
+
js_time = js_time.gsub('Nov', '11')
|
318
|
+
js_time = js_time.gsub('Dec', '12')
|
319
|
+
|
320
|
+
js_time
|
321
|
+
end
|
322
|
+
|
323
|
+
# setup convert
|
324
|
+
if convert_data == 'F to C'
|
325
|
+
convert = 0.5556
|
326
|
+
elsif convert_data == 'WH to J'
|
327
|
+
convert = 3600
|
328
|
+
elsif convert_data == 'CFM to m3/s'
|
329
|
+
convert = 0.00047
|
330
|
+
elsif convert_data == 'PSI to Pa'
|
331
|
+
convert = 6894.76
|
332
|
+
else convert_data == 'None'
|
333
|
+
convert = 1
|
334
|
+
end
|
335
|
+
|
336
|
+
diff = 0.0
|
337
|
+
simdata = 0.0
|
338
|
+
csvdata = 0.0
|
339
|
+
ySum = 0.0
|
340
|
+
squaredError = 0.0
|
341
|
+
sumError = 0.0
|
342
|
+
n = 0
|
343
|
+
cvrmse = 0
|
344
|
+
nmbe = 0
|
345
|
+
# map = {'Whole Building:Facility Total Electric Demand Power [W](TimeStep)'=>['Whole Building','Facility Total Electric Demand Power'],'OCCUPIED_TZ:Zone Mean Air Temperature [C](TimeStep)'=>['OCCUPIED_TZ','Zone Mean Air Temperature']}
|
346
|
+
|
347
|
+
map = { csv_var.to_s => { key: sql_key, var: sql_var, index: 0 } }
|
348
|
+
cal = { 1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April', 5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August', 9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December' }
|
349
|
+
runner.registerInfo("csv_name: #{csv_name}")
|
350
|
+
|
351
|
+
csv = CSV.read(csv_name, encoding: 'ISO-8859-1')
|
352
|
+
# sql = OpenStudio::SqlFile.new(OpenStudio::Path.new('sim.sql'))
|
353
|
+
sql = sqlFile
|
354
|
+
# environment_period = sql.availableEnvPeriods[3]
|
355
|
+
runner.registerInfo("environment_period: #{environment_period}")
|
356
|
+
environment_periods = environment_period.split(',')
|
357
|
+
runner.registerInfo("environment_periods: #{environment_periods}")
|
358
|
+
runner.registerInfo("map: #{map}")
|
359
|
+
runner.registerInfo('')
|
360
|
+
|
361
|
+
if find_avail
|
362
|
+
ts = sql.availableTimeSeries
|
363
|
+
runner.registerInfo("available timeseries: #{ts}")
|
364
|
+
runner.registerInfo('')
|
365
|
+
envs = sql.availableEnvPeriods
|
366
|
+
envs.each do |env_s|
|
367
|
+
freqs = sql.availableReportingFrequencies(env_s)
|
368
|
+
runner.registerInfo("available EnvPeriod: #{env_s}, available ReportingFrequencies: #{freqs}")
|
369
|
+
freqs.each do |freq|
|
370
|
+
vn = sql.availableVariableNames(env_s, freq.to_s)
|
371
|
+
runner.registerInfo("available variable names: #{vn}")
|
372
|
+
vn.each do |v|
|
373
|
+
kv = sql.availableKeyValues(env_s, freq.to_s, v)
|
374
|
+
runner.registerInfo("variable names: #{v}")
|
375
|
+
runner.registerInfo("available key value: #{kv}")
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
end
|
380
|
+
runner.registerInfo("year: #{years}")
|
381
|
+
runner.registerInfo("seconds: #{seconds}")
|
382
|
+
if !years && seconds
|
383
|
+
# mm:dd hh:mm:ss
|
384
|
+
# check day time splits into two valid parts
|
385
|
+
if !csv[1][0].split(' ')[0].nil? && !csv[1][0].split(' ')[1].nil?
|
386
|
+
# check remaining splits are valid
|
387
|
+
if !csv[1][0].split(' ')[0].split('/')[0].nil? && !csv[1][0].split(' ')[0].split('/')[1].nil? && !csv[1][0].split(' ')[1].split(':')[0].nil? && !csv[1][0].split(' ')[1].split(':')[1].nil? && !csv[1][0].split(' ')[1].split(':')[2].nil?
|
388
|
+
runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm:dd hh:mm:ss")
|
389
|
+
else
|
390
|
+
runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm:dd hh:mm:ss")
|
391
|
+
return false
|
392
|
+
end
|
393
|
+
else
|
394
|
+
runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm:dd hh:mm:ss")
|
395
|
+
return false
|
396
|
+
end
|
397
|
+
elsif !years && !seconds
|
398
|
+
# mm:dd hh:mm
|
399
|
+
# check day time splits into two valid parts
|
400
|
+
if !csv[1][0].split(' ')[0].nil? && !csv[1][0].split(' ')[1].nil?
|
401
|
+
# check remaining splits are valid
|
402
|
+
if !csv[1][0].split(' ')[0].split('/')[0].nil? && !csv[1][0].split(' ')[0].split('/')[1].nil? && !csv[1][0].split(' ')[1].split(':')[0].nil? && !csv[1][0].split(' ')[1].split(':')[1].nil?
|
403
|
+
runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm:dd hh:mm")
|
404
|
+
else
|
405
|
+
runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm:dd hh:mm")
|
406
|
+
return false
|
407
|
+
end
|
408
|
+
else
|
409
|
+
runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm:dd hh:mm")
|
410
|
+
return false
|
411
|
+
end
|
412
|
+
elsif years && !seconds
|
413
|
+
# mm:dd:yy hh:mm
|
414
|
+
# check day time splits into two valid parts
|
415
|
+
if !csv[1][0].split(' ')[0].nil? && !csv[1][0].split(' ')[1].nil?
|
416
|
+
# check remaining splits are valid
|
417
|
+
if !csv[1][0].split(' ')[0].split('/')[0].nil? && !csv[1][0].split(' ')[0].split('/')[1].nil? && !csv[1][0].split(' ')[0].split('/')[2].nil? && !csv[1][0].split(' ')[1].split(':')[0].nil? && !csv[1][0].split(' ')[1].split(':')[1].nil?
|
418
|
+
runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm:dd:yy hh:mm")
|
419
|
+
else
|
420
|
+
runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm:dd:yy hh:mm")
|
421
|
+
return false
|
422
|
+
end
|
423
|
+
else
|
424
|
+
runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm:dd:yy hh:mm")
|
425
|
+
return false
|
426
|
+
end
|
427
|
+
elsif years && seconds
|
428
|
+
# mm:dd:yy hh:mm:ss
|
429
|
+
# check day time splits into two valid parts
|
430
|
+
if !csv[1][0].split(' ')[0].nil? && !csv[1][0].split(' ')[1].nil?
|
431
|
+
# check remaining splits are valid
|
432
|
+
if !csv[1][0].split(' ')[0].split('/')[0].nil? && !csv[1][0].split(' ')[0].split('/')[1].nil? && !csv[1][0].split(' ')[0].split('/')[2].nil? && !csv[1][0].split(' ')[1].split(':')[0].nil? && !csv[1][0].split(' ')[1].split(':')[1].nil? && !csv[1][0].split(' ')[1].split(':')[2].nil?
|
433
|
+
runner.registerInfo("CSV Time format is correct: #{csv[1][0]} mm:dd:yy hh:mm:ss")
|
434
|
+
else
|
435
|
+
runner.registerError("CSV Time format not correct: #{csv[1][0]}. Selected format is mm:dd:yy hh:mm:ss")
|
436
|
+
return false
|
437
|
+
end
|
438
|
+
else
|
439
|
+
runner.registerError("CSV Time format not correct: #{csv[1][0]}. Does not split into 'day time'. Selected format is mm:dd:yy hh:mm:ss")
|
440
|
+
return false
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
444
|
+
temp_sim = []
|
445
|
+
temp_mtr = []
|
446
|
+
temp_norm = []
|
447
|
+
runner.registerInfo('Begin timeseries parsing')
|
448
|
+
# get timezone info
|
449
|
+
tzs = model.getSite.timeZone.to_s
|
450
|
+
runner.registerInfo("timezone = #{tzs}")
|
451
|
+
tz = if tzs.to_i >= 0 # positive number
|
452
|
+
if tzs.to_i < 10 # one digit
|
453
|
+
"+0#{tzs.to_i}:00"
|
454
|
+
else # two digit
|
455
|
+
"+#{tzs.to_i}:00"
|
456
|
+
end
|
457
|
+
else # negative number
|
458
|
+
if tzs.to_i * -1 < 10 # one digit
|
459
|
+
"-0#{tzs.to_i * -1}:00"
|
460
|
+
else # two digit
|
461
|
+
"-#{tzs.to_i * -1}:00"
|
462
|
+
end
|
463
|
+
end
|
464
|
+
runner.registerInfo("timezone = #{tz}")
|
465
|
+
# export for plotting
|
466
|
+
all_series = []
|
467
|
+
csv[0].each do |hdr|
|
468
|
+
if hdr.to_s != csv_time_header.to_s
|
469
|
+
unless map.key? hdr
|
470
|
+
runner.registerInfo("CSV hdr #{hdr} is not in map: #{map}, skipping") if verbose_messages
|
471
|
+
next
|
472
|
+
end
|
473
|
+
runner.registerInfo("hdr is: #{hdr}")
|
474
|
+
runner.registerInfo("csv_var is: #{csv_var}")
|
475
|
+
# next unless map.key? hdr
|
476
|
+
key = map[hdr][:key]
|
477
|
+
var = map[hdr][:var]
|
478
|
+
diff_index = map[hdr][:index]
|
479
|
+
runner.registerInfo("var: #{var}")
|
480
|
+
runner.registerInfo("key: #{key}")
|
481
|
+
|
482
|
+
# Store the timeseries data to hash for later
|
483
|
+
# export to the HTML file
|
484
|
+
series = {}
|
485
|
+
series['name'] = "#{key} Simulated"
|
486
|
+
series['type'] = var.to_s
|
487
|
+
series['color'] = 'blue'
|
488
|
+
data = []
|
489
|
+
series2 = {}
|
490
|
+
series2['name'] = "#{key} Metered"
|
491
|
+
series2['type'] = var.to_s
|
492
|
+
series2['color'] = 'red'
|
493
|
+
data2 = []
|
494
|
+
environment_periods.each do |environment_p|
|
495
|
+
runner.registerInfo("sqlcall: #{environment_p},#{reporting_frequency},#{var},#{key}")
|
496
|
+
if sql.timeSeries(environment_p, reporting_frequency, var, key).is_initialized
|
497
|
+
ser = sql.timeSeries(environment_p, reporting_frequency, var, key).get
|
498
|
+
else
|
499
|
+
runner.registerWarning("sql.timeSeries not initialized environment_p: #{environment_p},reporting_frequency: #{reporting_frequency},var: #{var},key: #{key}.")
|
500
|
+
next
|
501
|
+
end
|
502
|
+
date_times = ser.dateTimes
|
503
|
+
first_date = date_times[0]
|
504
|
+
last_date = date_times[-1]
|
505
|
+
if date_times.size >= 2
|
506
|
+
delta = OpenStudio::Time.new((date_times[1] - date_times[0]).days, (date_times[1] - date_times[0]).hours, (date_times[1] - date_times[0]).minutes, (date_times[1] - date_times[0]).seconds)
|
507
|
+
end
|
508
|
+
runner.registerInfo("first_date: #{first_date}") if verbose_messages
|
509
|
+
runner.registerInfo("last_date: #{last_date}") if verbose_messages
|
510
|
+
# if
|
511
|
+
series['units'] = ser.units
|
512
|
+
series2['units'] = ser.units
|
513
|
+
# end
|
514
|
+
# add 0 for plotting
|
515
|
+
if first_zero
|
516
|
+
runner.registerInfo("adding first_zero: #{first_date - delta}")
|
517
|
+
point = {}
|
518
|
+
point['y'] = 0.0
|
519
|
+
point['time'] = to_JSTime(first_date - delta)
|
520
|
+
data << point
|
521
|
+
point2 = {}
|
522
|
+
point2['y'] = 0.0
|
523
|
+
point2['time'] = to_JSTime(first_date - delta)
|
524
|
+
data2 << point2
|
525
|
+
end
|
526
|
+
|
527
|
+
csv.each_index do |row|
|
528
|
+
next unless row > 0
|
529
|
+
if csv[row][0].nil?
|
530
|
+
if warning_messages
|
531
|
+
runner.registerWarning("empty csv row number #{row}")
|
532
|
+
end
|
533
|
+
next
|
534
|
+
end
|
535
|
+
mon = csv[row][0].split(' ')[0].split('/')[0].to_i
|
536
|
+
day = csv[row][0].split(' ')[0].split('/')[1].to_i
|
537
|
+
year = unless csv[row][0].split(' ')[0].split('/')[2].nil?
|
538
|
+
csv[row][0].split(' ')[0].split('/')[2].to_i
|
539
|
+
end
|
540
|
+
hou = csv[row][0].split(' ')[1].split(':')[0].to_i
|
541
|
+
min = csv[row][0].split(' ')[1].split(':')[1].to_i
|
542
|
+
sec = unless csv[row][0].split(' ')[1].split(':')[2].nil?
|
543
|
+
csv[row][0].split(' ')[1].split(':')[2].to_i
|
544
|
+
end
|
545
|
+
if year.nil?
|
546
|
+
dat = OpenStudio::Date.new(OpenStudio::MonthOfYear.new(cal[mon]), day)
|
547
|
+
else
|
548
|
+
# dat = OpenStudio::Date.new(OpenStudio::MonthOfYear.new(cal[mon]),day,year)
|
549
|
+
# hack since year is not in the sql file correctly
|
550
|
+
dat = OpenStudio::Date.new(OpenStudio::MonthOfYear.new(cal[mon]), day)
|
551
|
+
end
|
552
|
+
tim = if sec.nil?
|
553
|
+
OpenStudio::Time.new(0, hou, min, 0)
|
554
|
+
else
|
555
|
+
OpenStudio::Time.new(0, hou, min, sec)
|
556
|
+
end
|
557
|
+
dtm = OpenStudio::DateTime.new(dat, tim)
|
558
|
+
unless dtm >= first_date && dtm <= last_date
|
559
|
+
if warning_messages
|
560
|
+
runner.registerWarning("CSV DateTime #{dtm} is not in SQL Timeseries Dates")
|
561
|
+
end
|
562
|
+
next
|
563
|
+
end
|
564
|
+
if year.nil?
|
565
|
+
etim = if sec.nil?
|
566
|
+
Time.new(2009, mon, day, hou, min, 0, tz).to_i * 1000
|
567
|
+
else
|
568
|
+
Time.new(2009, mon, day, hou, min, sec, tz).to_i * 1000
|
569
|
+
end
|
570
|
+
else
|
571
|
+
etim = if sec.nil?
|
572
|
+
# HACK: since year is not in the sql file correctly
|
573
|
+
# etim = Time.new(year, mon, day, hou, min, 0, tz).to_i * 1000
|
574
|
+
Time.new(2009, mon, day, hou, min, 0, tz).to_i * 1000
|
575
|
+
else
|
576
|
+
# HACK: since year is not in the sql file correctly
|
577
|
+
# etim = Time.new(year, mon, day, hou, min, sec, tz).to_i * 1000
|
578
|
+
Time.new(2009, mon, day, hou, min, sec, tz).to_i * 1000
|
579
|
+
end
|
580
|
+
end
|
581
|
+
runner.registerInfo("dtm: #{dtm}") if verbose_messages
|
582
|
+
csv[row].each_index do |col|
|
583
|
+
next unless col > 0
|
584
|
+
mtr = csv[row][col].to_s
|
585
|
+
# try converting
|
586
|
+
if convert == 0.5556 # this is a temperature
|
587
|
+
if mtr != 'NAN'
|
588
|
+
mtr = (mtr.to_f - 32) * convert
|
589
|
+
else
|
590
|
+
next
|
591
|
+
# mtr = 0
|
592
|
+
end
|
593
|
+
else
|
594
|
+
if mtr != 'NAN'
|
595
|
+
mtr = mtr.to_f * convert
|
596
|
+
else
|
597
|
+
next
|
598
|
+
# mtr = 0
|
599
|
+
end
|
600
|
+
end
|
601
|
+
next unless csv[0][col] == hdr
|
602
|
+
sim = ser.value(dtm)
|
603
|
+
# store timeseries for plotting
|
604
|
+
point = {}
|
605
|
+
point['y'] = sim.round(6)
|
606
|
+
point['time'] = to_JSTime(dtm)
|
607
|
+
data << point
|
608
|
+
point2 = {}
|
609
|
+
point2['y'] = mtr.to_f.round(6)
|
610
|
+
point2['time'] = to_JSTime(dtm)
|
611
|
+
data2 << point2
|
612
|
+
|
613
|
+
dif = if norm == 1
|
614
|
+
scale.to_f * (mtr.to_f - sim.to_f).abs
|
615
|
+
elsif norm == 2
|
616
|
+
(scale.to_f * (mtr.to_f - sim.to_f))**2
|
617
|
+
else
|
618
|
+
scale.to_f * (mtr.to_f - sim.to_f)
|
619
|
+
end
|
620
|
+
|
621
|
+
squaredError += (mtr.to_f - sim.to_f)**2
|
622
|
+
sumError += (mtr.to_f - sim.to_f)
|
623
|
+
ySum += mtr.to_f
|
624
|
+
n += 1
|
625
|
+
|
626
|
+
temp_sim << [etim, sim.to_f]
|
627
|
+
temp_mtr << [etim, mtr.to_f]
|
628
|
+
# temp_norm << [etim,dif.to_f]
|
629
|
+
diff += dif.to_f
|
630
|
+
simdata += sim.to_f
|
631
|
+
csvdata += mtr.to_f
|
632
|
+
runner.registerInfo("mtr value is #{mtr}") if verbose_messages
|
633
|
+
runner.registerInfo("sim value is #{sim}") if verbose_messages
|
634
|
+
runner.registerInfo("dif value is #{dif}") if verbose_messages
|
635
|
+
runner.registerInfo("diff value is #{diff.inspect}") if verbose_messages
|
636
|
+
end
|
637
|
+
end
|
638
|
+
# add 0 for plotting
|
639
|
+
next unless last_zero
|
640
|
+
runner.registerInfo("add last_zero: #{last_date + delta}")
|
641
|
+
point = {}
|
642
|
+
point['y'] = 0.0
|
643
|
+
point['time'] = to_JSTime(last_date + delta)
|
644
|
+
data << point
|
645
|
+
point2 = {}
|
646
|
+
point2['y'] = 0.0
|
647
|
+
point2['time'] = to_JSTime(last_date + delta)
|
648
|
+
data2 << point2
|
649
|
+
end
|
650
|
+
series['displayname'] = plot_name
|
651
|
+
series2['displayname'] = plot_name
|
652
|
+
series['data'] = data
|
653
|
+
series2['data'] = data2
|
654
|
+
all_series << series
|
655
|
+
all_series << series2
|
656
|
+
yBar = [ySum / n, 1e-19].max
|
657
|
+
cvrmse = 100.0 * Math.sqrt(squaredError / n) / yBar
|
658
|
+
nmbe = 100.0 * (sumError / n) / yBar
|
659
|
+
series['cvrmse'] = cvrmse.round(6)
|
660
|
+
series['nmbe'] = nmbe.round(6)
|
661
|
+
series2['cvrmse'] = cvrmse.round(6)
|
662
|
+
series2['nmbe'] = nmbe.round(6)
|
663
|
+
|
664
|
+
if algorithm_download
|
665
|
+
require 'csv'
|
666
|
+
CSV.open("timeseries#{plot_name}.csv", 'wb') do |csv|
|
667
|
+
csv << ['Simulation Time', 'Simulated Value', 'Metered time', 'Metered Value']
|
668
|
+
data.size.times do |i|
|
669
|
+
csv << [data[i]['time'], data[i]['y'], data2[i]['time'], data2[i]['y']]
|
670
|
+
end
|
671
|
+
end
|
672
|
+
end
|
673
|
+
|
674
|
+
else
|
675
|
+
runner.registerInfo("Found Time Header: #{csv_time_header}")
|
676
|
+
end
|
677
|
+
end
|
678
|
+
|
679
|
+
# results = {"metadata" => {"tz" => tzs.to_i, "variables" => {"variable" => csv_var, "variable_display_name" => csv_var_dn}}, "data_mtr" => temp_mtr, "data_sim" => temp_sim, "data_diff" => temp_norm}
|
680
|
+
# remove diff norm from results json
|
681
|
+
results = { 'metadata' => { 'tz' => tzs.to_i, 'variables' => { 'variable' => csv_var, 'variable_display_name' => csv_var_dn } }, 'data_mtr' => temp_mtr, 'data_sim' => temp_sim }
|
682
|
+
runner.registerInfo("Saving timeseries_#{csv_var}.json")
|
683
|
+
FileUtils.mkdir_p(File.dirname("timeseries_#{csv_var}.json")) unless Dir.exist?(File.dirname("timeseries_#{csv_var}.json"))
|
684
|
+
File.open("timeseries_#{csv_var}.json", 'wb') { |f| f << JSON.pretty_generate(results) }
|
685
|
+
FileUtils.mkdir_p(File.dirname("allseries_#{csv_var}.json")) unless Dir.exist?(File.dirname("allseries_#{csv_var}.json"))
|
686
|
+
File.open("allseries_#{csv_var}.json", 'wb') { |f| f << JSON.pretty_generate(all_series) }
|
687
|
+
# check if analysis directory exists on server
|
688
|
+
if algorithm_download
|
689
|
+
if File.basename(File.expand_path(File.join(Dir.pwd, '../../../'))).split('_')[0] == 'analysis'
|
690
|
+
runner.registerInfo("Copying timeseries_#{csv_var}.json to downloads directory")
|
691
|
+
directory_name = File.expand_path(File.join(Dir.pwd, '../../../downloads'))
|
692
|
+
Dir.mkdir(directory_name) unless File.exist?(directory_name)
|
693
|
+
FileUtils.cp("timeseries_#{csv_var}.json", directory_name)
|
694
|
+
FileUtils.cp("allseries_#{csv_var}.json", directory_name)
|
695
|
+
FileUtils.cp("timeseries#{plot_name}.csv", directory_name)
|
696
|
+
end
|
697
|
+
end
|
698
|
+
diff = Math.sqrt(diff) if norm == 2
|
699
|
+
|
700
|
+
runner.registerInfo("results: #{results}") if verbose_messages
|
701
|
+
runner.registerValue('diff', diff, '')
|
702
|
+
runner.registerValue('simdata', simdata, '')
|
703
|
+
runner.registerValue('csvdata', csvdata, '')
|
704
|
+
runner.registerValue('cvrmse', cvrmse, '')
|
705
|
+
runner.registerValue('nmbe', nmbe, '')
|
706
|
+
|
707
|
+
if plot_flag
|
708
|
+
runner.registerInfo('start plotting')
|
709
|
+
all_series = all_series.to_json
|
710
|
+
# read in template
|
711
|
+
html_in_path = "#{File.dirname(__FILE__)}/resources/report.html.erb"
|
712
|
+
html_in_path = if File.exist?(html_in_path)
|
713
|
+
html_in_path
|
714
|
+
else
|
715
|
+
"#{File.dirname(__FILE__)}/report.html.erb"
|
716
|
+
end
|
717
|
+
html_in = ''
|
718
|
+
File.open(html_in_path, 'r') do |file|
|
719
|
+
html_in = file.read
|
720
|
+
end
|
721
|
+
|
722
|
+
# configure template with variable values
|
723
|
+
renderer = ERB.new(html_in)
|
724
|
+
html_out = renderer.result(binding)
|
725
|
+
|
726
|
+
# write html file
|
727
|
+
html_out_path = if plot_name.empty?
|
728
|
+
"./report_#{csv_var}.html"
|
729
|
+
else
|
730
|
+
"./report_#{plot_name}.html"
|
731
|
+
end
|
732
|
+
File.open(html_out_path, 'w') do |file|
|
733
|
+
file << html_out
|
734
|
+
# make sure data is written to the disk one way or the other
|
735
|
+
begin
|
736
|
+
file.fsync
|
737
|
+
rescue StandardError
|
738
|
+
file.flush
|
739
|
+
end
|
740
|
+
end
|
741
|
+
end
|
742
|
+
sql.close
|
743
|
+
true
|
744
|
+
end
|
745
|
+
end
|
746
|
+
|
747
|
+
# register the measure to be used by the application
|
748
|
+
TimeseriesObjectiveFunction.new.registerWithApplication
|