lbt-measures 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ci.yaml +63 -0
  3. data/.gitignore +34 -0
  4. data/.releaserc.json +7 -0
  5. data/Gemfile +11 -0
  6. data/LICENSE.md +23 -0
  7. data/README.md +13 -0
  8. data/lbt-measures.gemspec +31 -0
  9. data/lib/efficiency_standard/LICENSE.md +27 -0
  10. data/lib/efficiency_standard/README.md +32 -0
  11. data/lib/efficiency_standard/README.md.erb +42 -0
  12. data/lib/efficiency_standard/measure.rb +142 -0
  13. data/lib/efficiency_standard/measure.xml +70 -0
  14. data/lib/inject_idf/LICENSE.md +27 -0
  15. data/lib/inject_idf/README.md +32 -0
  16. data/lib/inject_idf/README.md.erb +42 -0
  17. data/lib/inject_idf/measure.rb +107 -0
  18. data/lib/inject_idf/measure.xml +72 -0
  19. data/lib/openstudio_results/LICENSE.md +13 -0
  20. data/lib/openstudio_results/README.md +266 -0
  21. data/lib/openstudio_results/README.md.erb +46 -0
  22. data/lib/openstudio_results/measure.rb +384 -0
  23. data/lib/openstudio_results/measure.xml +1546 -0
  24. data/lib/openstudio_results/resources/Siz.AirConditionerVariableRefrigerantFlow.rb +82 -0
  25. data/lib/openstudio_results/resources/Siz.AirLoopHVAC.rb +23 -0
  26. data/lib/openstudio_results/resources/Siz.AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.rb +66 -0
  27. data/lib/openstudio_results/resources/Siz.AirLoopHVACUnitaryHeatPumpAirToAir.rb +66 -0
  28. data/lib/openstudio_results/resources/Siz.AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.rb +108 -0
  29. data/lib/openstudio_results/resources/Siz.AirLoopHVACUnitarySystem.rb +84 -0
  30. data/lib/openstudio_results/resources/Siz.AirTerminalDualDuctVAV.rb +23 -0
  31. data/lib/openstudio_results/resources/Siz.AirTerminalSingleDuctConstantVolumeCooledBeam.rb +40 -0
  32. data/lib/openstudio_results/resources/Siz.AirTerminalSingleDuctConstantVolumeFourPipeInduction.rb +84 -0
  33. data/lib/openstudio_results/resources/Siz.AirTerminalSingleDuctConstantVolumeReheat.rb +45 -0
  34. data/lib/openstudio_results/resources/Siz.AirTerminalSingleDuctParallelPIUReheat.rb +46 -0
  35. data/lib/openstudio_results/resources/Siz.AirTerminalSingleDuctSeriesPIUReheat.rb +46 -0
  36. data/lib/openstudio_results/resources/Siz.AirTerminalSingleDuctUncontrolled.rb +23 -0
  37. data/lib/openstudio_results/resources/Siz.AirTerminalSingleDuctVAVHeatAndCoolNoReheat.rb +23 -0
  38. data/lib/openstudio_results/resources/Siz.AirTerminalSingleDuctVAVHeatAndCoolReheat.rb +45 -0
  39. data/lib/openstudio_results/resources/Siz.AirTerminalSingleDuctVAVNoReheat.rb +23 -0
  40. data/lib/openstudio_results/resources/Siz.AirTerminalSingleDuctVAVReheat.rb +45 -0
  41. data/lib/openstudio_results/resources/Siz.BoilerHotWater.rb +46 -0
  42. data/lib/openstudio_results/resources/Siz.BoilerSteam.rb +29 -0
  43. data/lib/openstudio_results/resources/Siz.ChillerAbsorption.rb +40 -0
  44. data/lib/openstudio_results/resources/Siz.ChillerAbsorptionIndirect.rb +40 -0
  45. data/lib/openstudio_results/resources/Siz.ChillerElectricEIR.rb +69 -0
  46. data/lib/openstudio_results/resources/Siz.ChillerHeaterPerformanceElectricEIR.rb +52 -0
  47. data/lib/openstudio_results/resources/Siz.CoilCoolingDXMultiSpeed.rb +32 -0
  48. data/lib/openstudio_results/resources/Siz.CoilCoolingDXMultiSpeedStageData.rb +49 -0
  49. data/lib/openstudio_results/resources/Siz.CoilCoolingDXSingleSpeed.rb +47 -0
  50. data/lib/openstudio_results/resources/Siz.CoilCoolingDXTwoSpeed.rb +50 -0
  51. data/lib/openstudio_results/resources/Siz.CoilCoolingDXTwoStageWithHumidityControlMode.rb +100 -0
  52. data/lib/openstudio_results/resources/Siz.CoilCoolingDXVariableRefrigerantFlow.rb +40 -0
  53. data/lib/openstudio_results/resources/Siz.CoilCoolingDXVariableSpeed.rb +40 -0
  54. data/lib/openstudio_results/resources/Siz.CoilCoolingDXVariableSpeedSpeedData.rb +13 -0
  55. data/lib/openstudio_results/resources/Siz.CoilCoolingLowTempRadiantVarFlow.rb +18 -0
  56. data/lib/openstudio_results/resources/Siz.CoilCoolingWater.rb +40 -0
  57. data/lib/openstudio_results/resources/Siz.CoilCoolingWaterToAirHeatPumpEquationFit.rb +63 -0
  58. data/lib/openstudio_results/resources/Siz.CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.rb +67 -0
  59. data/lib/openstudio_results/resources/Siz.CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData.rb +12 -0
  60. data/lib/openstudio_results/resources/Siz.CoilHeatingDXMultiSpeed.rb +32 -0
  61. data/lib/openstudio_results/resources/Siz.CoilHeatingDXMultiSpeedStageData.rb +46 -0
  62. data/lib/openstudio_results/resources/Siz.CoilHeatingDXSingleSpeed.rb +46 -0
  63. data/lib/openstudio_results/resources/Siz.CoilHeatingDXVariableRefrigerantFlow.rb +40 -0
  64. data/lib/openstudio_results/resources/Siz.CoilHeatingDXVariableSpeed.rb +40 -0
  65. data/lib/openstudio_results/resources/Siz.CoilHeatingDXVariableSpeedSpeedData.rb +12 -0
  66. data/lib/openstudio_results/resources/Siz.CoilHeatingDesuperheater.rb +12 -0
  67. data/lib/openstudio_results/resources/Siz.CoilHeatingElectric.rb +29 -0
  68. data/lib/openstudio_results/resources/Siz.CoilHeatingGas.rb +29 -0
  69. data/lib/openstudio_results/resources/Siz.CoilHeatingGasMultiStage.rb +14 -0
  70. data/lib/openstudio_results/resources/Siz.CoilHeatingGasMultiStageStageData.rb +29 -0
  71. data/lib/openstudio_results/resources/Siz.CoilHeatingLowTempRadiantVarFlow.rb +18 -0
  72. data/lib/openstudio_results/resources/Siz.CoilHeatingWater.rb +40 -0
  73. data/lib/openstudio_results/resources/Siz.CoilHeatingWaterBaseboard.rb +40 -0
  74. data/lib/openstudio_results/resources/Siz.CoilHeatingWaterBaseboardRadiant.rb +40 -0
  75. data/lib/openstudio_results/resources/Siz.CoilHeatingWaterToAirHeatPumpEquationFit.rb +63 -0
  76. data/lib/openstudio_results/resources/Siz.CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.rb +67 -0
  77. data/lib/openstudio_results/resources/Siz.CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData.rb +12 -0
  78. data/lib/openstudio_results/resources/Siz.CoilPerformanceDXCooling.rb +47 -0
  79. data/lib/openstudio_results/resources/Siz.CoilSystemCoolingDXHeatExchangerAssisted.rb +12 -0
  80. data/lib/openstudio_results/resources/Siz.CoilSystemCoolingWaterHeatExchangerAssisted.rb +12 -0
  81. data/lib/openstudio_results/resources/Siz.CoilWaterHeatingAirToWaterHeatPump.rb +46 -0
  82. data/lib/openstudio_results/resources/Siz.CoilWaterHeatingAirToWaterHeatPumpWrapped.rb +12 -0
  83. data/lib/openstudio_results/resources/Siz.CoilWaterHeatingDesuperheater.rb +12 -0
  84. data/lib/openstudio_results/resources/Siz.ControllerOutdoorAir.rb +23 -0
  85. data/lib/openstudio_results/resources/Siz.CoolingTowerSingleSpeed.rb +40 -0
  86. data/lib/openstudio_results/resources/Siz.CoolingTowerTwoSpeed.rb +40 -0
  87. data/lib/openstudio_results/resources/Siz.CoolingTowerVariableSpeed.rb +40 -0
  88. data/lib/openstudio_results/resources/Siz.DistrictCooling.rb +23 -0
  89. data/lib/openstudio_results/resources/Siz.DistrictHeating.rb +23 -0
  90. data/lib/openstudio_results/resources/Siz.ElectricLoadCenterInverterLookUpTable.rb +17 -0
  91. data/lib/openstudio_results/resources/Siz.ElectricLoadCenterInverterSimple.rb +12 -0
  92. data/lib/openstudio_results/resources/Siz.ElectricLoadCenterStorageConverter.rb +12 -0
  93. data/lib/openstudio_results/resources/Siz.ElectricLoadCenterStorageSimple.rb +13 -0
  94. data/lib/openstudio_results/resources/Siz.EvaporativeCoolerDirectResearchSpecial.rb +29 -0
  95. data/lib/openstudio_results/resources/Siz.EvaporativeCoolerIndirectResearchSpecial.rb +32 -0
  96. data/lib/openstudio_results/resources/Siz.EvaporativeFluidCoolerSingleSpeed.rb +40 -0
  97. data/lib/openstudio_results/resources/Siz.EvaporativeFluidCoolerTwoSpeed.rb +40 -0
  98. data/lib/openstudio_results/resources/Siz.FanConstantVolume.rb +31 -0
  99. data/lib/openstudio_results/resources/Siz.FanOnOff.rb +31 -0
  100. data/lib/openstudio_results/resources/Siz.FanSystemModel.rb +31 -0
  101. data/lib/openstudio_results/resources/Siz.FanVariableVolume.rb +31 -0
  102. data/lib/openstudio_results/resources/Siz.FanZoneExhaust.rb +13 -0
  103. data/lib/openstudio_results/resources/Siz.FluidCoolerSingleSpeed.rb +40 -0
  104. data/lib/openstudio_results/resources/Siz.FluidCoolerTwoSpeed.rb +40 -0
  105. data/lib/openstudio_results/resources/Siz.GeneratorFuelCellElectricalStorage.rb +13 -0
  106. data/lib/openstudio_results/resources/Siz.GeneratorFuelCellInverter.rb +12 -0
  107. data/lib/openstudio_results/resources/Siz.GeneratorFuelCellPowerModule.rb +12 -0
  108. data/lib/openstudio_results/resources/Siz.GeneratorMicroTurbine.rb +12 -0
  109. data/lib/openstudio_results/resources/Siz.GeneratorMicroTurbineHeatRecovery.rb +12 -0
  110. data/lib/openstudio_results/resources/Siz.HVACComponent.rb +127 -0
  111. data/lib/openstudio_results/resources/Siz.HeaderedPumpsConstantSpeed.rb +30 -0
  112. data/lib/openstudio_results/resources/Siz.HeaderedPumpsVariableSpeed.rb +30 -0
  113. data/lib/openstudio_results/resources/Siz.HeatExchangerAirToAirSensibleAndLatent.rb +36 -0
  114. data/lib/openstudio_results/resources/Siz.HeatExchangerFluidToFluid.rb +23 -0
  115. data/lib/openstudio_results/resources/Siz.HeatPumpWaterToWaterEquationFitCooling.rb +40 -0
  116. data/lib/openstudio_results/resources/Siz.HeatPumpWaterToWaterEquationFitHeating.rb +40 -0
  117. data/lib/openstudio_results/resources/Siz.HumidifierSteamElectric.rb +23 -0
  118. data/lib/openstudio_results/resources/Siz.Model.rb +134 -0
  119. data/lib/openstudio_results/resources/Siz.ModelObject.rb +40 -0
  120. data/lib/openstudio_results/resources/Siz.PhotovoltaicPerformanceSimple.rb +12 -0
  121. data/lib/openstudio_results/resources/Siz.PlantComponentTemperatureSource.rb +23 -0
  122. data/lib/openstudio_results/resources/Siz.PlantLoop.rb +40 -0
  123. data/lib/openstudio_results/resources/Siz.PumpConstantSpeed.rb +30 -0
  124. data/lib/openstudio_results/resources/Siz.PumpVariableSpeed.rb +30 -0
  125. data/lib/openstudio_results/resources/Siz.RefrigerationSecondarySystem.rb +12 -0
  126. data/lib/openstudio_results/resources/Siz.RefrigerationSystem.rb +12 -0
  127. data/lib/openstudio_results/resources/Siz.RefrigerationTranscriticalSystem.rb +13 -0
  128. data/lib/openstudio_results/resources/Siz.SizingSystem.rb +57 -0
  129. data/lib/openstudio_results/resources/Siz.SolarCollectorFlatPlatePhotovoltaicThermal.rb +23 -0
  130. data/lib/openstudio_results/resources/Siz.SolarCollectorPerformancePhotovoltaicThermalSimple.rb +12 -0
  131. data/lib/openstudio_results/resources/Siz.ThermalStorageChilledWaterStratified.rb +30 -0
  132. data/lib/openstudio_results/resources/Siz.WaterHeaterHeatPump.rb +29 -0
  133. data/lib/openstudio_results/resources/Siz.WaterHeaterHeatPumpWrappedCondenser.rb +12 -0
  134. data/lib/openstudio_results/resources/Siz.WaterHeaterMixed.rb +48 -0
  135. data/lib/openstudio_results/resources/Siz.WaterHeaterStratified.rb +48 -0
  136. data/lib/openstudio_results/resources/Siz.ZoneHVACBaseboardConvectiveElectric.rb +29 -0
  137. data/lib/openstudio_results/resources/Siz.ZoneHVACBaseboardConvectiveWater.rb +28 -0
  138. data/lib/openstudio_results/resources/Siz.ZoneHVACBaseboardRadiantConvectiveElectric.rb +29 -0
  139. data/lib/openstudio_results/resources/Siz.ZoneHVACBaseboardRadiantConvectiveWater.rb +28 -0
  140. data/lib/openstudio_results/resources/Siz.ZoneHVACEnergyRecoveryVentilator.rb +29 -0
  141. data/lib/openstudio_results/resources/Siz.ZoneHVACFourPipeFanCoil.rb +72 -0
  142. data/lib/openstudio_results/resources/Siz.ZoneHVACHighTemperatureRadiant.rb +12 -0
  143. data/lib/openstudio_results/resources/Siz.ZoneHVACIdealLoadsAirSystem.rb +64 -0
  144. data/lib/openstudio_results/resources/Siz.ZoneHVACLowTempRadiantConstFlow.rb +20 -0
  145. data/lib/openstudio_results/resources/Siz.ZoneHVACLowTempRadiantVarFlow.rb +38 -0
  146. data/lib/openstudio_results/resources/Siz.ZoneHVACPackagedTerminalAirConditioner.rb +91 -0
  147. data/lib/openstudio_results/resources/Siz.ZoneHVACPackagedTerminalHeatPump.rb +91 -0
  148. data/lib/openstudio_results/resources/Siz.ZoneHVACTerminalUnitVariableRefrigerantFlow.rb +122 -0
  149. data/lib/openstudio_results/resources/Siz.ZoneHVACUnitHeater.rb +46 -0
  150. data/lib/openstudio_results/resources/Siz.ZoneHVACUnitVentilator.rb +98 -0
  151. data/lib/openstudio_results/resources/Siz.ZoneHVACWaterToAirHeatPump.rb +91 -0
  152. data/lib/openstudio_results/resources/Siz.ZoneVentilationDesignFlowRate.rb +13 -0
  153. data/lib/openstudio_results/resources/bootstrap.min.css +5 -0
  154. data/lib/openstudio_results/resources/bootstrap.min.js +6 -0
  155. data/lib/openstudio_results/resources/d3.min.js +5 -0
  156. data/lib/openstudio_results/resources/dimple.v2.1.2.min.js +3 -0
  157. data/lib/openstudio_results/resources/jquery.min.js +6 -0
  158. data/lib/openstudio_results/resources/os_lib_reporting.rb +4891 -0
  159. data/lib/openstudio_results/resources/report.html.erb +501 -0
  160. data/lib/view_data/LICENSE.md +13 -0
  161. data/lib/view_data/README.md +72 -0
  162. data/lib/view_data/README.md.erb +42 -0
  163. data/lib/view_data/measure.rb +449 -0
  164. data/lib/view_data/measure.xml +202 -0
  165. data/lib/view_data/resources/js/TweenLite.2.1.3.min.js +12 -0
  166. data/lib/view_data/resources/js/dat.gui.0.7.9.min.js +13 -0
  167. data/lib/view_data/resources/js/three.orbitcontrols.js +706 -0
  168. data/lib/view_data/resources/js/three.r98.min.js +964 -0
  169. data/lib/view_data/resources/report.html.in +1577 -0
  170. data/lib/view_data/resources/va3c.rb +996 -0
  171. metadata +227 -0
@@ -0,0 +1,449 @@
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://openstudio.net/license
4
+ # *******************************************************************************
5
+
6
+ require 'rubygems'
7
+ require 'json'
8
+ require 'erb'
9
+ require 'date'
10
+
11
+ require_relative 'resources/va3c'
12
+
13
+ # start the measure
14
+ class ViewData < OpenStudio::Measure::ReportingMeasure
15
+ # define the name that a user will see
16
+ def name
17
+ return 'ViewData'
18
+ end
19
+
20
+ # human readable description
21
+ def description
22
+ return 'Visualize energy simulation data plotted on an OpenStudio model in a web based viewer'
23
+ end
24
+
25
+ # human readable description of modeling approach
26
+ def modeler_description
27
+ return 'Converts the OpenStudio model to vA3C JSON format and renders using Three.js, simulation data is applied to surfaces of the model'
28
+ end
29
+
30
+ def energyPlusOutputRequests(runner, user_arguments)
31
+ super(runner, user_arguments)
32
+
33
+ result = OpenStudio::IdfObjectVector.new
34
+
35
+ # use the built-in error checking
36
+ if !runner.validateUserArguments(arguments, user_arguments)
37
+ return result
38
+ end
39
+
40
+ reporting_frequency = runner.getStringArgumentValue('reporting_frequency', user_arguments)
41
+
42
+ variable1_name = runner.getStringArgumentValue('variable1_name', user_arguments)
43
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{variable1_name},#{reporting_frequency};").get
44
+
45
+ variable2_name = runner.getStringArgumentValue('variable2_name', user_arguments)
46
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{variable2_name},#{reporting_frequency};").get
47
+
48
+ variable3_name = runner.getStringArgumentValue('variable3_name', user_arguments)
49
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{variable3_name},#{reporting_frequency};").get
50
+
51
+ return result
52
+ end
53
+
54
+ # define the arguments that the user will input
55
+ def arguments(model = nil)
56
+ args = OpenStudio::Measure::OSArgumentVector.new
57
+
58
+ chs = OpenStudio::StringVector.new
59
+ chs << 'Last OSM'
60
+ chs << 'Last IDF'
61
+ file_source = OpenStudio::Measure::OSArgument.makeChoiceArgument('file_source', chs, true)
62
+ file_source.setDisplayName('Model Source')
63
+ file_source.setDefaultValue('Last OSM')
64
+ args << file_source
65
+
66
+ chs = OpenStudio::StringVector.new
67
+ chs << 'Timestep'
68
+ chs << 'Hourly'
69
+ reporting_frequency = OpenStudio::Measure::OSArgument.makeChoiceArgument('reporting_frequency', chs, true)
70
+ reporting_frequency.setDisplayName('Reporting Frequency')
71
+ reporting_frequency.setDefaultValue('Hourly')
72
+ args << reporting_frequency
73
+
74
+ variable1_name = OpenStudio::Measure::OSArgument.makeStringArgument('variable1_name', true)
75
+ variable1_name.setDisplayName('Variable 1 Name')
76
+ variable1_name.setDefaultValue('Surface Outside Face Temperature')
77
+ args << variable1_name
78
+
79
+ variable2_name = OpenStudio::Measure::OSArgument.makeStringArgument('variable2_name', true)
80
+ variable2_name.setDisplayName('Variable 2 Name')
81
+ variable2_name.setDefaultValue('Surface Inside Face Temperature')
82
+ args << variable2_name
83
+
84
+ variable3_name = OpenStudio::Measure::OSArgument.makeStringArgument('variable3_name', true)
85
+ variable3_name.setDisplayName('Variable 3 Name')
86
+ variable3_name.setDefaultValue('Zone Mean Radiant Temperature')
87
+ args << variable3_name
88
+
89
+ if Gem::Version.new(OpenStudio.openStudioVersion) > Gem::Version.new('3.6.1')
90
+ use_geometry_diagnostics = OpenStudio::Measure::OSArgument.makeBoolArgument('use_geometry_diagnostics', true)
91
+ use_geometry_diagnostics.setDisplayName("Enable Geometry Diagnostics")
92
+ use_geometry_diagnostics.setDescription("Enables checks for Surface/Space Convexity. The ThreeJS export is slightly slower.")
93
+ use_geometry_diagnostics.setDefaultValue(false)
94
+ args << use_geometry_diagnostics
95
+ end
96
+
97
+ return args
98
+ end
99
+
100
+ def datetimes_to_array(dateTimes)
101
+ result = []
102
+
103
+ dateTimes.each do |d|
104
+ date = d.date
105
+ time = d.time
106
+ result << DateTime.new(date.year, date.monthOfYear.value, date.dayOfMonth, time.hours, time.minutes, time.seconds).strftime('%s').to_i
107
+ end
108
+ return result
109
+ end
110
+
111
+ def vector_to_array(vector)
112
+ result = []
113
+ (0...vector.size).each do |i|
114
+ result << vector[i]
115
+ end
116
+ return result
117
+ end
118
+
119
+ def format_array(vector)
120
+ result = []
121
+ vector.each do |x|
122
+ result << format('%.6g', x).to_f
123
+ end
124
+ return result
125
+ end
126
+
127
+ # define what happens when the measure is run
128
+ def run(runner, user_arguments)
129
+ super(runner, user_arguments)
130
+
131
+ # use the built-in error checking
132
+ if !runner.validateUserArguments(arguments, user_arguments)
133
+ return false
134
+ end
135
+
136
+ file_source = runner.getStringArgumentValue('file_source', user_arguments)
137
+ from_idf = (file_source == 'Last IDF')
138
+ reporting_frequency = runner.getStringArgumentValue('reporting_frequency', user_arguments)
139
+ variable1_name = runner.getStringArgumentValue('variable1_name', user_arguments)
140
+ variable2_name = runner.getStringArgumentValue('variable2_name', user_arguments)
141
+ variable3_name = runner.getStringArgumentValue('variable3_name', user_arguments)
142
+ if Gem::Version.new(OpenStudio.openStudioVersion) > Gem::Version.new('3.6.1')
143
+ use_geometry_diagnostics = runner.getBoolArgumentValue('use_geometry_diagnostics', user_arguments)
144
+ end
145
+
146
+ # 'Timestep' is the key in the input file, 'Zone Timestep' is the key in the SqlFile
147
+ if reporting_frequency == 'Timestep'
148
+ reporting_frequency = 'Zone Timestep'
149
+ end
150
+
151
+ variable_names = []
152
+
153
+ if /Zone/.match(variable1_name) || /Surface/.match(variable1_name)
154
+ variable_names << variable1_name
155
+ else
156
+ if !variable1_name.empty?
157
+ runner.registerWarning("Variable '#{variable1_name}' is not a zone or surface variable, skipping")
158
+ end
159
+ end
160
+
161
+ if variable_names.include?(variable2_name)
162
+ runner.registerWarning("Variable '#{variable2_name}' already requested, skipping")
163
+ elsif /Zone/.match(variable2_name) || /Surface/.match(variable2_name)
164
+ variable_names << variable2_name
165
+ else
166
+ if !variable2_name.empty?
167
+ runner.registerWarning("Variable '#{variable2_name}' is not a zone or surface variable, skipping")
168
+ end
169
+ end
170
+
171
+ if variable_names.include?(variable3_name)
172
+ runner.registerWarning("Variable '#{variable3_name}' already requested, skipping")
173
+ elsif /Zone/.match(variable3_name) || /Surface/.match(variable3_name)
174
+ variable_names << variable3_name
175
+ else
176
+ if !variable3_name.empty?
177
+ runner.registerWarning("Variable '#{variable3_name}' is not a zone or surface variable, skipping")
178
+ end
179
+ end
180
+
181
+ model = nil
182
+ if from_idf
183
+ # get the last workspace
184
+ workspace = runner.lastEnergyPlusWorkspace
185
+ if workspace.empty?
186
+ runner.registerError('Cannot find last workspace.')
187
+ return false
188
+ end
189
+ workspace = workspace.get
190
+ rt = OpenStudio::EnergyPlus::ReverseTranslator.new
191
+ model = rt.translateWorkspace(workspace)
192
+ runner.registerInfo("Loaded model with '#{model.getSpaces.size}' spaces")
193
+ else
194
+ # get the last model
195
+ model = runner.lastOpenStudioModel
196
+ if model.empty?
197
+ runner.registerError('Cannot find last model.')
198
+ return false
199
+ end
200
+ model = model.get
201
+ runner.registerInfo("Loaded model with '#{model.getSpaces.size}' spaces")
202
+ end
203
+
204
+ # get the last sql file
205
+ sqlFile = runner.lastEnergyPlusSqlFile
206
+ if sqlFile.empty?
207
+ runner.registerError('Cannot find last sql file.')
208
+ return false
209
+ end
210
+ sqlFile = sqlFile.get
211
+ model.setSqlFile(sqlFile)
212
+
213
+ # find the environment period
214
+ env_period = nil
215
+ sqlFile.availableEnvPeriods.each do |p|
216
+ if 'WeatherRunPeriod'.to_EnvironmentType == sqlFile.environmentType(p).get
217
+ env_period = p
218
+ break
219
+ end
220
+ end
221
+
222
+ if !env_period
223
+ runner.registerError('No WeatherRunPeriods found in results')
224
+ return false
225
+ end
226
+ runner.registerInfo("Gathering results for run period '#{env_period}'")
227
+
228
+ start_time = Time.now
229
+ # puts "printing variables"
230
+ # print all variables for reference
231
+ sqlFile.availableVariableNames(env_period, reporting_frequency).each do |variable|
232
+ runner.registerInfo("Available variable name '#{variable}'")
233
+ end
234
+ # puts "done printing variables, elapsed time #{Time.now-start_time}"
235
+
236
+ # start_time = Time.now
237
+ # puts "computing surface_data"
238
+ # list surface and thermal zone name for each surface
239
+ # surface_data is a temporary variable, it is not written to JSON
240
+ surface_data = []
241
+ model.getPlanarSurfaces.each do |surface|
242
+ surface_name = surface.name.to_s.upcase
243
+ thermal_zone_name = nil
244
+ if (space = surface.space) && !space.empty?
245
+ if from_idf
246
+ # if we translated from IDF, the space name will be the E+ zone name
247
+ thermal_zone_name = space.get.name.to_s.upcase
248
+ else
249
+ if (thermal_zone = space.get.thermalZone) && !thermal_zone.empty?
250
+ thermal_zone_name = thermal_zone.get.name.to_s.upcase
251
+ end
252
+ end
253
+ end
254
+
255
+ surface_data << { surface_name: surface_name, thermal_zone_name: thermal_zone_name, variables: [] }
256
+ end
257
+ # puts "done computing surface_data, elapsed time #{Time.now-start_time}"
258
+
259
+ # same across all variables for given timestep
260
+ times = nil
261
+ hoursPerInterval = nil
262
+ intervalsPerHour = nil
263
+ intervalsPerDay = nil
264
+ numDays = nil
265
+
266
+ # changes for each variable
267
+ start_time = Time.now
268
+ meta_variables = []
269
+ variables = []
270
+ variable_names.each do |variable_name|
271
+ units = nil
272
+ values = []
273
+ data_range = [Float::MAX, Float::MIN] # data max, data min
274
+
275
+ # puts "getting keys for variable, #{variable_name}"
276
+ keys = sqlFile.availableKeyValues(env_period, reporting_frequency, variable_name)
277
+ # puts "done getting #{keys.size} keys, elapsed time #{Time.now-start_time}"
278
+
279
+ if keys.empty?
280
+ runner.registerWarning("No data available for variable '#{variable_name}', skipping")
281
+ next
282
+ end
283
+
284
+ keys.each do |key|
285
+ runner.registerInfo("Available key '#{key}' for variable name '#{variable_name}'")
286
+
287
+ # puts "getting timeseries for key, #{key}"
288
+ ts = sqlFile.timeSeries(env_period, reporting_frequency, variable_name, key).get
289
+ units = ts.units
290
+ # puts "done getting timeseries, elapsed time #{Time.now-start_time}"
291
+
292
+ if times.nil?
293
+ times = datetimes_to_array(ts.dateTimes)
294
+ if !ts.intervalLength.empty?
295
+ hoursPerInterval = ts.intervalLength.get.totalHours
296
+ intervalsPerHour = 1.0 / hoursPerInterval.to_f
297
+ intervalsPerDay = 1.0 / ts.intervalLength.get.totalDays
298
+ numDays = times.size * ts.intervalLength.get.totalDays
299
+ end
300
+ end
301
+
302
+ this_values = vector_to_array(ts.values)
303
+
304
+ min = this_values.min
305
+ max = this_values.max
306
+ if min < data_range[0]
307
+ data_range[0] = min
308
+ end
309
+ if max > data_range[1]
310
+ data_range[1] = max
311
+ end
312
+
313
+ valueIndex = values.length
314
+ values << format_array(this_values)
315
+
316
+ if i = surface_data.index { |s| s[:surface_name] == key }
317
+ surface_data[i][:variables] << { name: variable_name, valueIndex: valueIndex, keyName: key }
318
+ else
319
+ surface_data.each do |s|
320
+ if s[:thermal_zone_name] == key
321
+ s[:variables] << { name: variable_name, valueIndex: valueIndex, keyName: key }
322
+ end
323
+ end
324
+ end
325
+
326
+ # puts "finished with key #{key}, elapsed time #{Time.now-start_time}"
327
+ end
328
+
329
+ meta_variables << { name: variable_name, intervalsPerHour: intervalsPerHour, intervalsPerDay: intervalsPerDay,
330
+ hoursPerInterval: hoursPerInterval, numDays: numDays, units: units,
331
+ valueMin: data_range[0], valueMax: data_range[1] }
332
+
333
+ variables << { name: variable_name, intervalsPerHour: intervalsPerHour, intervalsPerDay: intervalsPerDay,
334
+ hoursPerInterval: hoursPerInterval, numDays: numDays, units: units,
335
+ valueMin: data_range[0], valueMax: data_range[1], timeIndex: 0, values: values }
336
+
337
+ # puts "finished with variable #{variable_name}, elapsed time #{Time.now-start_time}"
338
+ end
339
+
340
+ # convert the model to vA3C JSON format
341
+ start_time = Time.now
342
+ # puts "converting model to vA3C"
343
+ json = nil
344
+ model_clone = model.clone(true).to_Model
345
+ begin
346
+ # try to use new implementation
347
+ ft = OpenStudio::Model::ThreeJSForwardTranslator.new
348
+ if Gem::Version.new(OpenStudio.openStudioVersion) > Gem::Version.new('3.6.1')
349
+ ft.setIncludeGeometryDiagnostics(use_geometry_diagnostics)
350
+ end
351
+ three_scene = ft.modelToThreeJS(model_clone, true)
352
+ json = JSON.parse(three_scene.toJSON(false), symbolize_names: true)
353
+ runner.registerInfo('Used new ThreeScene translator.')
354
+ rescue NameError, StandardError
355
+ # use old Ruby implementation
356
+ runner.registerInfo('Using Ruby VA3C translator.')
357
+ json = VA3C.convert_model(model_clone)
358
+ end
359
+ # puts "finished converting model, elapsed time #{Time.now-start_time}"
360
+
361
+ json[:metadata][:variables] = meta_variables
362
+ json[:times] = [times]
363
+ json[:variables] = variables
364
+
365
+ json[:object][:children].each do |child|
366
+ name = child[:userData][:name].upcase
367
+
368
+ surface = surface_data.find { |x| x[:surface_name] == name }
369
+
370
+ valueIndex = nil
371
+ keyName = nil
372
+ if surface
373
+ child[:userData][:variables] = surface[:variables]
374
+ end
375
+ end
376
+
377
+ # write json file
378
+ # start_time = Time.now
379
+ # puts "writing JSON"
380
+ json_out_path = './report.json'
381
+ File.open(json_out_path, 'w') do |file|
382
+ file << JSON.generate(json, object_nl: "\n", array_nl: '', indent: ' ')
383
+ # file << JSON::generate(json, {:object_nl=>"", :array_nl=>"", :indent=>""})
384
+ # make sure data is written to the disk one way or the other
385
+ begin
386
+ file.fsync
387
+ rescue StandardError
388
+ file.flush
389
+ end
390
+ end
391
+ # puts "finished writing JSON, elapsed time #{Time.now-start_time}"
392
+
393
+ # read in template
394
+ # start_time = Time.now
395
+ # puts "writing html"
396
+ html_in_path = "#{File.dirname(__FILE__)}/resources/report.html.in"
397
+ if File.exist?(html_in_path)
398
+ html_in_path = html_in_path
399
+ else
400
+ html_in_path = "#{File.dirname(__FILE__)}/report.html.in"
401
+ end
402
+ html_in = ''
403
+ File.open(html_in_path, 'r') do |file|
404
+ html_in = file.read
405
+ end
406
+
407
+ # configure template with variable values
408
+ os_data = JSON.generate(json, object_nl: '', array_nl: '', indent: '')
409
+ title = 'View Data'
410
+
411
+ # Embed js
412
+ js_in_path = "#{File.dirname(__FILE__)}/resources/js"
413
+ if !File.directory?(js_in_path)
414
+ js_in_path = "#{File.dirname(__FILE__)}/js"
415
+ end
416
+ three_js = File.read(File.join(js_in_path, 'three.r98.min.js'))
417
+ three_orbitcontrol_js = File.read(File.join(js_in_path, 'three.orbitcontrols.js'))
418
+ dat_gui_js = File.read(File.join(js_in_path, 'dat.gui.0.7.9.min.js'))
419
+ tweenlite_js = File.read(File.join(js_in_path, 'TweenLite.2.1.3.min.js'))
420
+
421
+ renderer = ERB.new(html_in)
422
+ html_out = renderer.result(binding)
423
+
424
+ # write html file
425
+ html_out_path = './report.html'
426
+ File.open(html_out_path, 'w') do |file|
427
+ file << html_out
428
+
429
+ # make sure data is written to the disk one way or the other
430
+ begin
431
+ file.fsync
432
+ rescue StandardError
433
+ file.flush
434
+ end
435
+ end
436
+ # puts "finished writing html, elapsed time #{Time.now-start_time}"
437
+
438
+ # closing the sql file
439
+ # sqlFile.close()
440
+
441
+ # reporting final condition
442
+ # runner.registerFinalCondition("Model written.")
443
+
444
+ return true
445
+ end # end the run method
446
+ end # end the measure
447
+
448
+ # this allows the measure to be use by the application
449
+ ViewData.new.registerWithApplication
@@ -0,0 +1,202 @@
1
+ <?xml version="1.0"?>
2
+ <measure>
3
+ <schema_version>3.1</schema_version>
4
+ <name>view_data</name>
5
+ <uid>18cf0de7-48b8-48dc-ab68-0dd29f0b8bd0</uid>
6
+ <version_id>9af36467-4063-4f61-87de-c425f09bda61</version_id>
7
+ <version_modified>2024-11-16T23:54:14Z</version_modified>
8
+ <xml_checksum>2C8A3EEF</xml_checksum>
9
+ <class_name>ViewData</class_name>
10
+ <display_name>ViewData</display_name>
11
+ <description>Visualize energy simulation data plotted on an OpenStudio model in a web based viewer</description>
12
+ <modeler_description>Converts the OpenStudio model to vA3C JSON format and renders using Three.js, simulation data is applied to surfaces of the model</modeler_description>
13
+ <arguments>
14
+ <argument>
15
+ <name>file_source</name>
16
+ <display_name>Model Source</display_name>
17
+ <type>Choice</type>
18
+ <required>true</required>
19
+ <model_dependent>false</model_dependent>
20
+ <default_value>Last OSM</default_value>
21
+ <choices>
22
+ <choice>
23
+ <value>Last OSM</value>
24
+ <display_name>Last OSM</display_name>
25
+ </choice>
26
+ <choice>
27
+ <value>Last IDF</value>
28
+ <display_name>Last IDF</display_name>
29
+ </choice>
30
+ </choices>
31
+ </argument>
32
+ <argument>
33
+ <name>reporting_frequency</name>
34
+ <display_name>Reporting Frequency</display_name>
35
+ <type>Choice</type>
36
+ <required>true</required>
37
+ <model_dependent>false</model_dependent>
38
+ <default_value>Hourly</default_value>
39
+ <choices>
40
+ <choice>
41
+ <value>Timestep</value>
42
+ <display_name>Timestep</display_name>
43
+ </choice>
44
+ <choice>
45
+ <value>Hourly</value>
46
+ <display_name>Hourly</display_name>
47
+ </choice>
48
+ </choices>
49
+ </argument>
50
+ <argument>
51
+ <name>variable1_name</name>
52
+ <display_name>Variable 1 Name</display_name>
53
+ <type>String</type>
54
+ <required>true</required>
55
+ <model_dependent>false</model_dependent>
56
+ <default_value>Surface Outside Face Temperature</default_value>
57
+ </argument>
58
+ <argument>
59
+ <name>variable2_name</name>
60
+ <display_name>Variable 2 Name</display_name>
61
+ <type>String</type>
62
+ <required>true</required>
63
+ <model_dependent>false</model_dependent>
64
+ <default_value>Surface Inside Face Temperature</default_value>
65
+ </argument>
66
+ <argument>
67
+ <name>variable3_name</name>
68
+ <display_name>Variable 3 Name</display_name>
69
+ <type>String</type>
70
+ <required>true</required>
71
+ <model_dependent>false</model_dependent>
72
+ <default_value>Zone Mean Radiant Temperature</default_value>
73
+ </argument>
74
+ <argument>
75
+ <name>use_geometry_diagnostics</name>
76
+ <display_name>Enable Geometry Diagnostics</display_name>
77
+ <description>Enables checks for Surface/Space Convexity. The ThreeJS export is slightly slower.</description>
78
+ <type>Boolean</type>
79
+ <required>true</required>
80
+ <model_dependent>false</model_dependent>
81
+ <default_value>false</default_value>
82
+ <choices>
83
+ <choice>
84
+ <value>true</value>
85
+ <display_name>true</display_name>
86
+ </choice>
87
+ <choice>
88
+ <value>false</value>
89
+ <display_name>false</display_name>
90
+ </choice>
91
+ </choices>
92
+ </argument>
93
+ </arguments>
94
+ <outputs />
95
+ <provenances />
96
+ <tags>
97
+ <tag>Reporting.QAQC</tag>
98
+ </tags>
99
+ <attributes>
100
+ <attribute>
101
+ <name>Measure Type</name>
102
+ <value>ReportingMeasure</value>
103
+ <datatype>string</datatype>
104
+ </attribute>
105
+ <attribute>
106
+ <name>Uses SketchUp API</name>
107
+ <value>false</value>
108
+ <datatype>boolean</datatype>
109
+ </attribute>
110
+ </attributes>
111
+ <files>
112
+ <file>
113
+ <filename>LICENSE.md</filename>
114
+ <filetype>md</filetype>
115
+ <usage_type>license</usage_type>
116
+ <checksum>8696A072</checksum>
117
+ </file>
118
+ <file>
119
+ <filename>README.md</filename>
120
+ <filetype>md</filetype>
121
+ <usage_type>readme</usage_type>
122
+ <checksum>B766BA7B</checksum>
123
+ </file>
124
+ <file>
125
+ <filename>README.md.erb</filename>
126
+ <filetype>erb</filetype>
127
+ <usage_type>readmeerb</usage_type>
128
+ <checksum>703C9964</checksum>
129
+ </file>
130
+ <file>
131
+ <version>
132
+ <software_program>OpenStudio</software_program>
133
+ <identifier>1.6.3</identifier>
134
+ <min_compatible>1.6.3</min_compatible>
135
+ </version>
136
+ <filename>measure.rb</filename>
137
+ <filetype>rb</filetype>
138
+ <usage_type>script</usage_type>
139
+ <checksum>9481087F</checksum>
140
+ </file>
141
+ <file>
142
+ <filename>js/TweenLite.2.1.3.min.js</filename>
143
+ <filetype>js</filetype>
144
+ <usage_type>resource</usage_type>
145
+ <checksum>7C0ACD45</checksum>
146
+ </file>
147
+ <file>
148
+ <filename>js/dat.gui.0.7.9.min.js</filename>
149
+ <filetype>js</filetype>
150
+ <usage_type>resource</usage_type>
151
+ <checksum>8A880134</checksum>
152
+ </file>
153
+ <file>
154
+ <filename>js/three.orbitcontrols.js</filename>
155
+ <filetype>js</filetype>
156
+ <usage_type>resource</usage_type>
157
+ <checksum>35EF4A95</checksum>
158
+ </file>
159
+ <file>
160
+ <filename>js/three.r98.min.js</filename>
161
+ <filetype>js</filetype>
162
+ <usage_type>resource</usage_type>
163
+ <checksum>8296FEEA</checksum>
164
+ </file>
165
+ <file>
166
+ <filename>report.html.in</filename>
167
+ <filetype>in</filetype>
168
+ <usage_type>resource</usage_type>
169
+ <checksum>1F7B79F1</checksum>
170
+ </file>
171
+ <file>
172
+ <filename>va3c.rb</filename>
173
+ <filetype>rb</filetype>
174
+ <usage_type>resource</usage_type>
175
+ <checksum>7B8C67AE</checksum>
176
+ </file>
177
+ <file>
178
+ <filename>ExampleModel.osm</filename>
179
+ <filetype>osm</filetype>
180
+ <usage_type>test</usage_type>
181
+ <checksum>FFFE0281</checksum>
182
+ </file>
183
+ <file>
184
+ <filename>SimpleModel.osm</filename>
185
+ <filetype>osm</filetype>
186
+ <usage_type>test</usage_type>
187
+ <checksum>AC094EF8</checksum>
188
+ </file>
189
+ <file>
190
+ <filename>USA_CO_Golden-NREL.724666_TMY3.epw</filename>
191
+ <filetype>epw</filetype>
192
+ <usage_type>test</usage_type>
193
+ <checksum>BDF687C1</checksum>
194
+ </file>
195
+ <file>
196
+ <filename>ViewData_Test.rb</filename>
197
+ <filetype>rb</filetype>
198
+ <usage_type>test</usage_type>
199
+ <checksum>7AA273EF</checksum>
200
+ </file>
201
+ </files>
202
+ </measure>