diff --git a/CHANGELOG.md b/CHANGELOG.md
index 949e4e69..7d7ca10f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,38 @@
# URBANopt Scenario Gem
-
+
+## Version 0.2.0
+
+
+Date Range: 01/15/20 - 03/30/20:
+
+- Fixed [#27]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/27 ), FeatureReports are not initialized with location information.
+- Fixed [#38]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/38 ), Write documentation on how to configure ScenarioRunner to run multiple OSWs in parallel
+- Fixed [#42]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/42 ), Scenario Report Instantiation from Hash
+- Fixed [#43]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/43 ), Add timestep column to timeseries csv or add start and end timestep to feature and scenario reports
+- Fixed [#46]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/46 ), add Validator class
+- Fixed [#52]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/52 ), create a save as method that takes a file name
+- Fixed [#54]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/54 ), Add constraint on the versions of ruby in the gemspec file
+- Fixed [#56]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/56 ), Add folder for mapper csv files
+- Fixed [#58]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/58 ), post process results
+- Fixed [#59]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/59 ), figure out how UrbanOpt will select tariff structure for REopt
+- Fixed [#65]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/65 ), make default timeseries csv for scenario; update adding feature timeseries
+- Fixed [#67]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/67 ), update vuepress version
+- Fixed [#70]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/70 ), updates to Scenario Gem to Support REopt Release
+- Fixed [#74]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/74 ), Update copyrights
+- Fixed [#75]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/75 ), make github_api a development dependency
+- Fixed [#81]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/81 ), add thermal comfort results and timestamp to reports
+- Fixed [#83]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/83 ), add multiple pV
+- Fixed [#88]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/88 ), add units to CSV reports
+- Fixed [#89]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/89 ), created Save feature report method
+- Fixed [#91]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/91 ), add total_costruction_cost to reports
+- Fixed [#95]( https://github.com/urbanopt/urbanopt-scenario-gem/issues/95 ), list datapoint failures
+- Fixed [#98]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/98 ), add power, net power, net energy and apparent power to timeseries results
+- Fixed [#101]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/101 ), fix for unit conversion when timeseries doe not exist
+- Fixed [#102]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/102 ), add opendss post_processor
+- Fixed [#104]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/104 ), add power distribution results to schema and reports
+- Fixed [#110]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/110 ), save transformer features CSV and JSON reports
+- Fixed [#112]( https://github.com/urbanopt/urbanopt-scenario-gem/pull/112 ), added additional timeseries results to CSV reports
+
## Version 0.1.1
Date Range: 10/16/19 - 01/14/20
diff --git a/Gemfile b/Gemfile
index ebd9d50c..e76896f0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -40,6 +40,3 @@ end
# simplecov has an unnecessary dependency on native json gem, use fork that does not require this
gem 'simplecov', github: 'NREL/simplecov'
-
-# Fix rack version temporarily to work with Ruby 2.2.4
-gem 'rack', '2.1.2'
diff --git a/lib/measures/default_feature_reports/measure.rb b/lib/measures/default_feature_reports/measure.rb
index f9b43d8e..6c407243 100644
--- a/lib/measures/default_feature_reports/measure.rb
+++ b/lib/measures/default_feature_reports/measure.rb
@@ -174,6 +174,17 @@ def energyPlusOutputRequests(runner, user_arguments)
result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Gas:Facility,#{reporting_frequency};").get
result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,DistrictCooling:Facility,#{reporting_frequency};").get
result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,DistrictHeating:Facility,#{reporting_frequency};").get
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Cooling:Electricity,#{reporting_frequency};").get
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Heating:Electricity,#{reporting_frequency};").get
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,InteriorLights:Electricity,#{reporting_frequency};").get
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,ExteriorLights:Electricity,#{reporting_frequency};").get
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,InteriorEquipment:Electricity,#{reporting_frequency};").get
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Fans:Electricity,#{reporting_frequency};").get
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Pumps:Electricity,#{reporting_frequency};").get
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,WaterSystems:Electricity,#{reporting_frequency};").get
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,Heating:Gas,#{reporting_frequency};").get
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,WaterSystems:Gas,#{reporting_frequency};").get
+ # result << OpenStudio::IdfObject.load("Output:Meter:MeterFileOnly,InteriorEquipment:Gas,#{reporting_frequency};").get
timeseries_data = ['District Cooling Chilled Water Rate', 'District Cooling Mass Flow Rate',
'District Cooling Inlet Temperature', 'District Cooling Outlet Temperature',
@@ -608,6 +619,17 @@ def run(runner, user_arguments)
'Electricity:Facility',
'ElectricityProduced:Facility',
'Gas:Facility',
+ 'Cooling:Electricity',
+ 'Heating:Electricity',
+ 'InteriorLights:Electricity',
+ 'ExteriorLights:Electricity',
+ 'InteriorEquipment:Electricity',
+ 'Fans:Electricity',
+ 'Pumps:Electricity',
+ 'WaterSystems:Electricity',
+ 'Heating:Gas',
+ 'WaterSystems:Gas',
+ 'InteriorEquipment:Gas',
'DistrictCooling:Facility',
'DistrictHeating:Facility',
'District Cooling Chilled Water Rate',
@@ -646,7 +668,7 @@ def run(runner, user_arguments)
total_seconds = (60 / timesteps_per_hour.to_f) * 60 # make sure timesteps_per_hour is a float in the division
total_hours = 1 / timesteps_per_hour.to_f # make sure timesteps_per_hour is a float in the division
# set power_conversion
- power_conversion = total_hours
+ power_conversion = total_hours # we set the power conversio to total_hours since we want to convert lWh to kW
puts "Power Converion: to convert kWh to kW values will be divided by #{power_conversion}"
# number of values in each timeseries
@@ -768,7 +790,7 @@ def run(runner, user_arguments)
newVals[j] = (values[tsToKeepIndexes['Electricity:Facility']][j].to_f - values[tsToKeepIndexes['ElectricityProduced:Facility']][j].to_f) / power_conversion / powerFactor
j += 1
end
- new_unit = 'kW'
+ new_unit = 'kVA'
elsif timeseries_name.include? 'Net Electric Energy'
(0..n - 1).each do |j|
newVals[j] = (values[tsToKeepIndexes['Electricity:Facility']][j].to_f - values[tsToKeepIndexes['ElectricityProduced:Facility']][j].to_f)
@@ -798,7 +820,7 @@ def run(runner, user_arguments)
newVals[j] = values[indexValue][j].to_f / power_conversion / powerFactor
j += 1
end
- new_unit = 'kW'
+ new_unit = 'kVA'
else
# Power calculation
(0..n - 1).each do |j|
diff --git a/lib/measures/default_feature_reports/measure.xml b/lib/measures/default_feature_reports/measure.xml
index bf6463a7..4c317f09 100644
--- a/lib/measures/default_feature_reports/measure.xml
+++ b/lib/measures/default_feature_reports/measure.xml
@@ -2,8 +2,8 @@
3.0
default_feature_reports
9ee3135a-8070-4408-bfa1-b75fecf9dd4f
- 607df4a0-d1ff-4c14-8d2f-93cde078dc47
- 20200308T020104Z
+ dcf043ff-d992-4835-893d-8658a6365eb3
+ 20200329T155122Z
FB304155
DefaultFeatureReports
DefaultFeatureReports
@@ -137,7 +137,7 @@
measure.rb
rb
script
- DC29E5E6
+ DF6AAD06
diff --git a/lib/urbanopt/scenario.rb b/lib/urbanopt/scenario.rb
index f51dd0c5..43b5c14e 100644
--- a/lib/urbanopt/scenario.rb
+++ b/lib/urbanopt/scenario.rb
@@ -36,6 +36,7 @@
require 'urbanopt/scenario/scenario_csv'
require 'urbanopt/scenario/scenario_post_processor_base'
require 'urbanopt/scenario/scenario_post_processor_default'
+require 'urbanopt/scenario/scenario_post_processor_opendss'
require 'urbanopt/scenario/scenario_runner_base'
require 'urbanopt/scenario/scenario_runner_osw'
require 'urbanopt/scenario/simulation_dir_base'
diff --git a/lib/urbanopt/scenario/default_reports/distributed_generation.rb b/lib/urbanopt/scenario/default_reports/distributed_generation.rb
index 942ea701..aeba188e 100644
--- a/lib/urbanopt/scenario/default_reports/distributed_generation.rb
+++ b/lib/urbanopt/scenario/default_reports/distributed_generation.rb
@@ -107,6 +107,11 @@ class DistributedGeneration
#
attr_accessor :total_storage_kw
+ ##
+ # _Float_ - Installed storage capacity
+ #
+ attr_accessor :total_storage_kwh
+
##
# _Float_ - Installed generator capacity
#
@@ -286,15 +291,15 @@ def to_hash
result[:solar_pv].push pv.to_hash
end
result[:wind] = []
- @wind.each do |pv|
+ @wind.each do |wind|
result[:wind].push wind.to_hash
end
result[:generator] = []
- @generator.each do |pv|
+ @generator.each do |generator|
result[:generator].push generator.to_hash
end
result[:storage] = []
- @storage.each do |pv|
+ @storage.each do |storage|
result[:storage].push storage.to_hash
end
return result
diff --git a/lib/urbanopt/scenario/default_reports/feature_report.rb b/lib/urbanopt/scenario/default_reports/feature_report.rb
index 809c8449..7e5c6e76 100644
--- a/lib/urbanopt/scenario/default_reports/feature_report.rb
+++ b/lib/urbanopt/scenario/default_reports/feature_report.rb
@@ -33,9 +33,10 @@
require 'urbanopt/scenario/default_reports/location'
require 'urbanopt/scenario/default_reports/reporting_period'
require 'urbanopt/scenario/default_reports/timeseries_csv'
-require 'urbanopt/scenario/default_reports/validator'
require 'urbanopt/scenario/default_reports/distributed_generation'
+require 'urbanopt/scenario/default_reports/power_distribution'
+require 'urbanopt/scenario/default_reports/validator'
require 'json-schema'
require 'json'
@@ -52,7 +53,7 @@ module DefaultReports
##
class FeatureReport
attr_accessor :id, :name, :directory_name, :feature_type, :timesteps_per_hour, :simulation_status,
- :timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation # :nodoc:
+ :timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation, :power_distribution # :nodoc:
##
# Each FeatureReport object corresponds to a single Feature.
##
@@ -84,7 +85,9 @@ def initialize(hash = {})
@reporting_periods << ReportingPeriod.new(rp)
end
- @distributed_generation = DistributedGeneration.new(hash[:distributed_generation] || {})
+ @distributed_generation = DistributedGeneration.new(hash[:distributed_generation])
+
+ @power_distribution = PowerDistribution.new(hash[:power_distribution])
# initialize class variables @@validator and @@schema
@@validator ||= Validator.new
@@ -104,6 +107,8 @@ def defaults
hash[:program] = {}
hash[:construction_costs] = []
hash[:reporting_periods] = []
+ hash[:distributed_generation] = {}
+ hash[:power_distribution] = {}
return hash
end
@@ -203,6 +208,8 @@ def to_hash
result[:distributed_generation] = @distributed_generation.to_hash if @distributed_generation
+ result[:power_distribution] = @power_distribution.to_hash if @power_distribution
+
# validate feature_report properties against schema
if @@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result).any?
raise "feature_report properties does not match schema: #{@@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result)}"
@@ -216,7 +223,7 @@ def to_hash
##
# [parameters]:
# +file_name+ - _String_ - Assign a name to the saved feature report results file without an extension
- def save_feature_report(file_name = 'updated_default_feature_report')
+ def save_feature_report(file_name = 'default_feature_report')
# reassign the initialize local variable @file_name to the file name input.
@file_name = file_name
@@ -232,13 +239,13 @@ def save_feature_report(file_name = 'updated_default_feature_report')
@timeseries_csv.path = File.join(@directory_name, 'feature_reports', file_name + '.csv')
@timeseries_csv.save_data
- hash = {}
- hash[:feature_report] = to_hash
+ # feature_hash
+ feature_hash = to_hash
json_name_path = File.join(@directory_name, 'feature_reports', file_name + '.json')
File.open(json_name_path, 'w') do |f|
- f.puts JSON.pretty_generate(hash)
+ f.puts JSON.pretty_generate(feature_hash)
# make sure data is written to the disk one way or the other
begin
f.fsync
diff --git a/lib/urbanopt/scenario/default_reports/power_distribution.rb b/lib/urbanopt/scenario/default_reports/power_distribution.rb
new file mode 100644
index 00000000..b0d25b7a
--- /dev/null
+++ b/lib/urbanopt/scenario/default_reports/power_distribution.rb
@@ -0,0 +1,102 @@
+# *********************************************************************************
+# URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
+# contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this list
+# of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice, this
+# list of conditions and the following disclaimer in the documentation and/or other
+# materials provided with the distribution.
+#
+# Neither the name of the copyright holder nor the names of its contributors may be
+# used to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+# *********************************************************************************
+
+require 'json'
+require 'urbanopt/scenario/default_reports/validator'
+require 'json-schema'
+
+module URBANopt
+ module Scenario
+ module DefaultReports
+ ##
+ # power_distributio include eletrical power distribution systems information.
+ ##
+ class PowerDistribution
+ attr_accessor :under_voltage_hours, :over_voltage_hours # :nodoc:
+ ##
+ # PowerDistrinution class intialize all power_distribution attributes:
+ # +:under_voltage_hours+ , +:over_voltage_hours+
+ ##
+ # [parameters:]
+ # +hash+ - _Hash_ - A hash which may contain a deserialized power_distribution.
+ ##
+ def initialize(hash = {})
+ hash.delete_if { |k, v| v.nil? }
+ hash = defaults.merge(hash)
+
+ @under_voltage_hours = hash[:under_voltage_hours]
+ @over_voltage_hours = hash[:over_voltage_hours]
+
+ # initialize class variables @@validator and @@schema
+ @@validator ||= Validator.new
+ @@schema ||= @@validator.schema
+ end
+
+ ##
+ # Assigns default values if attribute values do not exist.
+ ##
+ def defaults
+ hash = {}
+ hash[:under_voltage_hours] = nil
+ hash[:over_voltage_hours] = nil
+
+ return hash
+ end
+
+ ##
+ # Converts to a Hash equivalent for JSON serialization.
+ ##
+ # - Exclude attributes with nil values.
+ # - Validate power_distribution hash properties against schema.
+ ##
+ def to_hash
+ result = {}
+ result[:under_voltage_hours] = @under_voltage_hours if @under_voltage_hours
+ result[:over_voltage_hours] = @over_voltage_hours if @over_voltage_hours
+
+ # validate power_distribution properties against schema
+ if @@validator.validate(@@schema[:definitions][:PowerDistribution][:properties], result).any?
+ raise "power_distribution properties does not match schema: #{@@validator.validate(@@schema[:definitions][:PowerDistribution][:properties], result)}"
+ end
+
+ return result
+ end
+
+ ##
+ # Merges muliple power distribution results together.
+ ##
+ # +new_costs+ - _Array_ - An array of ConstructionCost objects.
+ def merge_power_distribition
+ # method to be developed for any attributes to be aggregated or merged
+ end
+ end
+ end
+ end
+end
diff --git a/lib/urbanopt/scenario/default_reports/scenario_report.rb b/lib/urbanopt/scenario/default_reports/scenario_report.rb
index a276bd8d..3f32d2ec 100644
--- a/lib/urbanopt/scenario/default_reports/scenario_report.rb
+++ b/lib/urbanopt/scenario/default_reports/scenario_report.rb
@@ -151,7 +151,7 @@ def save(file_name = 'default_scenario_report')
# reassign the initialize local variable @file_name to the file name input.
@file_name = file_name
- # save the csv data
+ # save the scenario reports csv and json data
old_timeseries_path = nil
if !@timeseries_csv.path.nil?
old_timeseries_path = @timeseries_csv.path
@@ -184,6 +184,12 @@ def save(file_name = 'default_scenario_report')
else
@timeseries_csv.path = File.join(@directory_name, file_name + '.csv')
end
+
+ # save the feature reports csv and json data
+ # @feature_reports.each do |feature_report|
+ # feature_report.save_feature_report()
+ # end
+
return true
end
diff --git a/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt b/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt
index 0ee859d3..68b5d531 100644
--- a/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt
+++ b/lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt
@@ -1,13 +1,24 @@
Datetime
Electricity:Facility
-ElectricityProduced:Facility
+ElectricityProduced:Facility
Gas:Facility
-DistrictCooling:Facility
-DistrictHeating:Facility
-District Cooling Chilled Water Rate
+Cooling:Electricity
+Heating:Electricity
+InteriorLights:Electricity
+ExteriorLights:Electricity
+InteriorEquipment:Electricity
+Fans:Electricity
+Pumps:Electricity
+WaterSystems:Electricity
+Heating:Gas
+WaterSystems:Gas
+InteriorEquipment:Gas
+DistrictCooling:Facility
+DistrictHeating:Facility
+District Cooling Chilled Water Rate
District Cooling Mass Flow Rate
-District Cooling Inlet Temperature
-District Cooling Outlet Temperature
+District Cooling Inlet Temperature
+District Cooling Outlet Temperature
District Heating Hot Water Rate
District Heating Mass Flow Rate
District Heating Inlet Temperature
diff --git a/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json b/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json
index f9b68621..fb399b4e 100644
--- a/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json
+++ b/lib/urbanopt/scenario/default_reports/schema/scenario_schema.json
@@ -213,6 +213,9 @@
},
"distributed_generation": {
"$ref": "#/definitions/DistributedGeneration"
+ },
+ "power_distribution": {
+ "$ref": "#/definitions/PowerDistribution"
}
},
"required": [
@@ -834,6 +837,17 @@
"column_names"
],
"additionalProperties": false
+ },
+ "PowerDistribution": {
+ "type": "object",
+ "properties": {
+ "over_voltage_hours": {
+ "type": "number"
+ },
+ "under_voltage_hours": {
+ "type": "number"
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/lib/urbanopt/scenario/default_reports/timeseries_csv.rb b/lib/urbanopt/scenario/default_reports/timeseries_csv.rb
index 92eb31e3..119420f1 100644
--- a/lib/urbanopt/scenario/default_reports/timeseries_csv.rb
+++ b/lib/urbanopt/scenario/default_reports/timeseries_csv.rb
@@ -87,7 +87,8 @@ def load_scenario_csv_schema_headers
File.readlines(scenario_csv_schema).each do |line|
l = line.delete("\n")
a = l.delete("\t")
- scenario_csv_schema_headers << a
+ r = a.delete("\r")
+ scenario_csv_schema_headers << r
end
return scenario_csv_schema_headers
end
@@ -152,7 +153,11 @@ def reload_data(new_data)
end
else
row.each_with_index do |value, i|
- @data[@column_names[i]] << value.to_f
+ if i == 0
+ @data[@column_names[i]] << value
+ else
+ @data[@column_names[i]] << value.to_f
+ end
end
end
end
@@ -204,6 +209,7 @@ def save_data(path = nil)
if path.nil?
path = @path
end
+
File.open(path, 'w') do |f|
f.puts @column_names.join(',')
n = @data[@column_names[0]].size - 1
@@ -246,35 +252,44 @@ def add_timeseries_csv(other)
end
# merge the column names
- @column_names = @column_names.concat(other.column_names).uniq
+ other_column_names = []
+ other.column_names.each do |n|
+ if !n[0, 4].casecmp('ZONE').zero?
+ other_column_names << n
+ end
+ end
+
+ @column_names = @column_names.concat(other_column_names).uniq
# merge the column data
other.column_names.each do |column_name|
- if !@column_names.include? column_name
- @column_names.push column_name
- end
+ if !column_name[0, 4].casecmp('ZONE').zero?
+ if !@column_names.include? column_name
+ @column_names.push column_name
+ end
- new_values = other.get_data(column_name)
+ new_values = other.get_data(column_name)
- if @data.nil?
- @data = {}
- end
+ if @data.nil?
+ @data = {}
+ end
- current_values = @data[column_name]
+ current_values = @data[column_name]
- if current_values
- if current_values.size != new_values.size
- raise 'Values of different sizes in add_timeseries_csv'
- end
- new_values.each_with_index do |value, i|
- # aggregate all columns except Datime column
- if column_name != 'Datetime'
- new_values[i] = value.to_f + current_values[i].to_f
+ if current_values
+ if current_values.size != new_values.size
+ raise 'Values of different sizes in add_timeseries_csv'
+ end
+ new_values.each_with_index do |value, i|
+ # aggregate all columns except Datime column
+ if column_name != 'Datetime'
+ new_values[i] = value.to_f + current_values[i].to_f
+ end
end
+ @data[column_name] = new_values
+ else
+ @data[column_name] = new_values
end
- @data[column_name] = new_values
- else
- @data[column_name] = new_values
end
end
end
diff --git a/lib/urbanopt/scenario/scenario_post_processor_opendss.rb b/lib/urbanopt/scenario/scenario_post_processor_opendss.rb
new file mode 100644
index 00000000..34085d44
--- /dev/null
+++ b/lib/urbanopt/scenario/scenario_post_processor_opendss.rb
@@ -0,0 +1,276 @@
+# *********************************************************************************
+# URBANopt, Copyright (c) 2019-2020, Alliance for Sustainable Energy, LLC, and other
+# contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without modification,
+# are permitted provided that the following conditions are met:
+#
+# Redistributions of source code must retain the above copyright notice, this list
+# of conditions and the following disclaimer.
+#
+# Redistributions in binary form must reproduce the above copyright notice, this
+# list of conditions and the following disclaimer in the documentation and/or other
+# materials provided with the distribution.
+#
+# Neither the name of the copyright holder nor the names of its contributors may be
+# used to endorse or promote products derived from this software without specific
+# prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+# OF THE POSSIBILITY OF SUCH DAMAGE.
+# *********************************************************************************
+
+# require 'urbanopt/scenario/scenario_post_processor_base'
+require 'urbanopt/scenario/default_reports'
+require 'urbanopt/scenario/default_reports/logger'
+
+require 'csv'
+require 'json'
+require 'fileutils'
+require 'pathname'
+
+module URBANopt
+ module Scenario
+ class OpenDSSPostProcessor
+ ##
+ # OpenDSSPostProcessor post-processes OpenDSS results to selected OpenDSS results and integrate them in scenario and feature reports.
+ ##
+ # [parameters:]
+ # +scenario_report+ - _ScenarioBase_ - An object of Scenario_report class.
+ # +opendss_results_dir_name+ - _directory name of opendss results
+ def initialize(scenario_report, opendss_results_dir_name = 'opendss')
+ if !scenario_report.nil?
+ @scenario_report = scenario_report
+ @opendss_results_dir = File.join(@scenario_report.directory_name, opendss_results_dir_name)
+ else
+ raise 'scenario_report is not valid'
+ end
+
+ # hash of column_name to array of values, does not get serialized to hash
+ @mutex = Mutex.new
+
+ # initialize opendss data
+ @opendss_data = {}
+
+ # initialize feature_reports data
+ @feature_reports_data = {}
+
+ # initialize logger
+ @@logger ||= URBANopt::Scenario::DefaultReports.logger
+ end
+
+ # load opendss data
+ def load_opendss_data
+ # load building features data
+ @scenario_report.feature_reports.each do |feature_report|
+ # read results from opendss
+ opendss_csv = CSV.read(File.join(@opendss_results_dir, 'results', 'Features', feature_report.id + '.csv'))
+ # add results to data
+ @opendss_data[feature_report.id] = opendss_csv
+ end
+
+ ## load transformers data
+
+ # transformers results directory path
+ tf_results_path = File.join(@opendss_results_dir, 'results', 'Transformers')
+
+ # get transformer ids
+ transformer_ids = []
+ Dir.entries(tf_results_path.to_s).select do |f|
+ if !File.directory? f
+ fn = File.basename(f, '.csv')
+ transformer_ids << fn
+ end
+ end
+
+ # add transformer results to @opendss_data
+ transformer_ids.each do |id|
+ # read results from transformers
+ transformer_csv = CSV.read(File.join(tf_results_path, id + '.csv'))
+ # add results to data
+ @opendss_data[id] = transformer_csv
+ end
+ end
+
+ # load feature report data
+ def load_feature_report_data
+ @scenario_report.feature_reports.each do |feature_report|
+ # read feature results
+ feature_csv = CSV.read(File.join(feature_report.timeseries_csv.path))
+ # add results to data
+ @feature_reports_data[feature_report.id] = feature_csv
+ end
+ end
+
+ # load feature report data and opendss data
+ def load_data
+ # load selected opendss data
+ load_opendss_data
+ # load selected feature reports data
+ load_feature_report_data
+ end
+
+ # merge data
+ def merge_data(feature_report_data, opendss_data)
+ output = CSV.generate do |csv|
+ opendss_data.each_with_index do |row, i|
+ if row.include? 'Datetime'
+ row.map { |header| header.prepend('opendss_') }
+ end
+ csv << (feature_report_data[i] + row[1..-1])
+ end
+ end
+
+ return output
+ end
+
+ # add feature reports for transformers
+ def save_transformers_reports
+ @opendss_data.keys.each do |k|
+ if k.include? 'Transformer'
+
+ # create transformer directory
+ transformer_dir = File.join(@scenario_report.directory_name, k)
+ FileUtils.mkdir_p(File.join(transformer_dir, 'feature_reports'))
+
+ # write data to csv
+ # store under voltages and over voltages
+ under_voltage_hrs = 0
+ over_voltage_hrs = 0
+
+ transformer_csv = CSV.generate do |csv|
+ @opendss_data[k].each_with_index do |row, i|
+ csv << row
+
+ if !row[1].include? 'loading'
+ if row[1].to_f > 1.05
+ over_voltage_hrs += 1
+ end
+
+ if row[1].to_f < 0.95
+ under_voltage_hrs += 1
+ end
+ end
+ end
+ end
+
+ # save transformer CSV report
+ File.write(File.join(transformer_dir, 'feature_reports', 'default_feature_report_opendss' + '.csv'), transformer_csv)
+
+ # create transformer report
+ transformer_report = URBANopt::Scenario::DefaultReports::FeatureReport.new(id: k, name: k, directory_name: transformer_dir, feature_type: 'Transformer',
+ timesteps_per_hour: @scenario_report.timesteps_per_hour,
+ simulation_status: 'complete')
+
+ # assign results to transfomrer report
+ transformer_report.power_distribution.over_voltage_hours = over_voltage_hrs
+ transformer_report.power_distribution.under_voltage_hours = under_voltage_hrs
+
+ ## save transformer JSON file
+ # transformer_hash
+ transformer_hash = transformer_report.to_hash
+ # transformer_hash.delete_if { |k, v| v.nil? }
+
+ json_name_path = File.join(transformer_dir, 'feature_reports', 'default_feature_report_opendss' + '.json')
+
+ # save the json file
+ File.open(json_name_path, 'w') do |f|
+ f.puts JSON.pretty_generate(transformer_hash)
+ # make sure data is written to the disk one way or the other
+ begin
+ f.fsync
+ rescue StandardError
+ f.flush
+ end
+ end
+
+ # add transformers reports to scenario_report
+ @scenario_report.feature_reports << transformer_report
+
+ end
+ end
+ end
+
+ ##
+ # Save csv report method
+ ##
+ # [parameters:]
+ # +feature_report+ - _feature report object_ - An onject of the feature report
+ # +updated_feature_report_csv+ - _CSV_ - An updated feature report csv
+ # +file_name+ - _String_ - Assigned name to save the file with no extension
+ def save_csv(feature_report, updated_feature_report_csv, file_name = 'default_feature_report')
+ File.write(File.join(feature_report.directory_name, 'feature_reports', "#{file_name}.csv"), updated_feature_report_csv)
+ end
+
+ ##
+ # create opendss json report results
+ ##
+ # [parameters:]
+ # +feature_report+ - _feature report object_ - An onject of the feature report
+ def add_summary_results(feature_report)
+ under_voltage_hrs = 0
+ over_voltage_hrs = 0
+
+ id = feature_report.id
+ @opendss_data[id].each_with_index do |row, i|
+ if !row[1].include? 'voltage'
+
+ if row[1].to_f > 1.05
+ over_voltage_hrs += 1
+ end
+
+ if row[1].to_f < 0.95
+ under_voltage_hrs += 1
+ end
+
+ end
+ end
+
+ # assign results to feature report
+ feature_report.power_distribution.over_voltage_hours = over_voltage_hrs
+ feature_report.power_distribution.under_voltage_hours = under_voltage_hrs
+
+ return feature_report
+ end
+
+ ##
+ # run opendss post_processor
+ ##
+ def run
+ @scenario_report.feature_reports.each do |feature_report|
+ # load data
+ load_data
+
+ # puts " @opendss data = #{@opendss_data}"
+
+ # get summary results
+ add_summary_results(feature_report)
+
+ # merge csv data
+ id = feature_report.id
+ updated_feature_csv = merge_data(@feature_reports_data[id], @opendss_data[id])
+
+ # save fetaure reports
+ feature_report.save_feature_report('default_feature_report_opendss')
+
+ # resave updated csv report
+ save_csv(feature_report, updated_feature_csv, 'default_feature_report_opendss')
+ end
+
+ # add transformer reports
+ save_transformers_reports
+
+ # save the updated scenario reports
+ @scenario_report.save(file_name = 'scenario_report_opendss')
+ end
+ end
+ end
+end
diff --git a/lib/urbanopt/scenario/version.rb b/lib/urbanopt/scenario/version.rb
index e99fcc3f..82d0eefa 100644
--- a/lib/urbanopt/scenario/version.rb
+++ b/lib/urbanopt/scenario/version.rb
@@ -30,6 +30,6 @@
module URBANopt
module Scenario
- VERSION = '0.2.0.pre2'.freeze
+ VERSION = '0.2.0'.freeze
end
end
diff --git a/spec/files/opendss_outputs/opendss/results/Features/1.csv b/spec/files/opendss_outputs/opendss/results/Features/1.csv
new file mode 100644
index 00000000..48c57c41
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Features/1.csv
@@ -0,0 +1,25 @@
+Datetime,p.u. voltage,overvoltage,undervoltage
+6/1/2012 1:00,4.555190233,TRUE,FALSE
+6/1/2012 2:00,4.576724363,TRUE,FALSE
+6/1/2012 3:00,4.575198032,TRUE,FALSE
+6/1/2012 4:00,4.58951716,TRUE,FALSE
+6/1/2012 5:00,4.576724363,TRUE,FALSE
+6/1/2012 6:00,4.575198032,TRUE,FALSE
+6/1/2012 7:00,4.58951716,TRUE,FALSE
+6/1/2012 8:00,4.740247423,TRUE,FALSE
+6/1/2012 9:00,4.575198032,TRUE,FALSE
+6/1/2012 10:00,4.58951716,TRUE,FALSE
+6/1/2012 11:00,4.740247423,TRUE,FALSE
+6/1/2012 12:00,4.555190233,TRUE,FALSE
+6/1/2012 13:00,4.576724363,TRUE,FALSE
+6/1/2012 14:00,4.575198032,TRUE,FALSE
+6/1/2012 15:00,4.58951716,TRUE,FALSE
+6/1/2012 16:00,4.576724363,TRUE,FALSE
+6/1/2012 17:00,4.575198032,TRUE,FALSE
+6/1/2012 18:00,4.58951716,TRUE,FALSE
+6/1/2012 19:00,4.740247423,TRUE,FALSE
+6/1/2012 20:00,4.575198032,TRUE,FALSE
+6/1/2012 21:00,4.58951716,TRUE,FALSE
+6/1/2012 22:00,4.740247423,TRUE,FALSE
+6/1/2012 23:00,4.58951716,TRUE,FALSE
+6/2/2012 0:00,4.576724363,TRUE,FALSE
diff --git a/spec/files/opendss_outputs/opendss/results/Features/2.csv b/spec/files/opendss_outputs/opendss/results/Features/2.csv
new file mode 100644
index 00000000..caa4197a
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Features/2.csv
@@ -0,0 +1,25 @@
+Datetime,p.u. voltage,overvoltage,undervoltage
+6/1/2012 1:00,0.207776119,FALSE,TRUE
+6/1/2012 2:00,0.207561748,FALSE,TRUE
+6/1/2012 3:00,0.207828168,FALSE,TRUE
+6/1/2012 4:00,0.200926181,FALSE,TRUE
+6/1/2012 5:00,0.207561748,FALSE,TRUE
+6/1/2012 6:00,0.207828168,FALSE,TRUE
+6/1/2012 7:00,0.200926181,FALSE,TRUE
+6/1/2012 8:00,0.19949719,FALSE,TRUE
+6/1/2012 9:00,0.207828168,FALSE,TRUE
+6/1/2012 10:00,0.200926181,FALSE,TRUE
+6/1/2012 11:00,0.19949719,FALSE,TRUE
+6/1/2012 12:00,0.207776119,FALSE,TRUE
+6/1/2012 13:00,0.207561748,FALSE,TRUE
+6/1/2012 14:00,0.207828168,FALSE,TRUE
+6/1/2012 15:00,0.200926181,FALSE,TRUE
+6/1/2012 16:00,0.207561748,FALSE,TRUE
+6/1/2012 17:00,0.207828168,FALSE,TRUE
+6/1/2012 18:00,0.200926181,FALSE,TRUE
+6/1/2012 19:00,0.19949719,FALSE,TRUE
+6/1/2012 20:00,0.207828168,FALSE,TRUE
+6/1/2012 21:00,0.200926181,FALSE,TRUE
+6/1/2012 22:00,0.19949719,FALSE,TRUE
+6/1/2012 23:00,0.194419535,FALSE,TRUE
+6/2/2012 0:00,0.190254047,FALSE,TRUE
diff --git a/spec/files/opendss_outputs/opendss/results/Features/3.csv b/spec/files/opendss_outputs/opendss/results/Features/3.csv
new file mode 100644
index 00000000..b60d0b9f
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Features/3.csv
@@ -0,0 +1,25 @@
+Datetime,p.u. voltage,overvoltage,undervoltage
+6/1/2012 1:00,4.555190233,TRUE,FALSE
+6/1/2012 2:00,4.576724363,TRUE,FALSE
+6/1/2012 3:00,4.575198032,TRUE,FALSE
+6/1/2012 4:00,4.58951716,TRUE,FALSE
+6/1/2012 5:00,4.576724363,TRUE,FALSE
+6/1/2012 6:00,4.575198032,TRUE,FALSE
+6/1/2012 7:00,4.58951716,TRUE,FALSE
+6/1/2012 8:00,4.740247423,TRUE,FALSE
+6/1/2012 9:00,4.575198032,TRUE,FALSE
+6/1/2012 10:00,4.58951716,TRUE,FALSE
+6/1/2012 11:00,4.740247423,TRUE,FALSE
+6/1/2012 12:00,4.555190233,TRUE,FALSE
+6/1/2012 13:00,0.207561748,FALSE,TRUE
+6/1/2012 14:00,0.207828168,FALSE,TRUE
+6/1/2012 15:00,0.200926181,FALSE,TRUE
+6/1/2012 16:00,0.207561748,FALSE,TRUE
+6/1/2012 17:00,0.207828168,FALSE,TRUE
+6/1/2012 18:00,0.200926181,FALSE,TRUE
+6/1/2012 19:00,0.19949719,FALSE,TRUE
+6/1/2012 20:00,0.207828168,FALSE,TRUE
+6/1/2012 21:00,0.200926181,FALSE,TRUE
+6/1/2012 22:00,0.19949719,FALSE,TRUE
+6/1/2012 23:00,0.194419535,FALSE,TRUE
+6/2/2012 0:00,0.190254047,FALSE,TRUE
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.10e9de09-902c-4373-8fa3-06a3e19e8b38.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.10e9de09-902c-4373-8fa3-06a3e19e8b38.csv
new file mode 100644
index 00000000..648afa17
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.10e9de09-902c-4373-8fa3-06a3e19e8b38.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.0003881576008966183,False
+2019/06/01 00:30:00,0.0003246387244612409,False
+2019/06/01 00:45:00,0.0003221156439635388,False
+2019/06/01 01:00:00,0.0003183032111099563,False
+2019/06/01 01:15:00,0.0003246387244612409,False
+2019/06/01 01:30:00,0.0003221156439635388,False
+2019/06/01 01:45:00,0.0003183032111099563,False
+2019/06/01 02:00:00,0.0003599974412840784,False
+2019/06/01 02:15:00,0.0003221156439635388,False
+2019/06/01 02:30:00,0.0003183032111099563,False
+2019/06/01 02:45:00,0.0003599974412840784,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.11abf04c-1002-4d48-9f1d-edb4872cf9c3.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.11abf04c-1002-4d48-9f1d-edb4872cf9c3.csv
new file mode 100644
index 00000000..347808fb
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.11abf04c-1002-4d48-9f1d-edb4872cf9c3.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,61.154421680750666,True
+2019/06/01 00:30:00,61.19619439723044,True
+2019/06/01 00:45:00,61.15331585437514,True
+2019/06/01 01:00:00,61.65091448709588,True
+2019/06/01 01:15:00,61.19619439723044,True
+2019/06/01 01:30:00,61.15331585437514,True
+2019/06/01 01:45:00,61.65091448709588,True
+2019/06/01 02:00:00,61.752976255089905,True
+2019/06/01 02:15:00,61.15331585437514,True
+2019/06/01 02:30:00,61.65091448709588,True
+2019/06/01 02:45:00,61.752976255089905,True
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.1324f2a2-4fc9-4020-b144-b027f2633991.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.1324f2a2-4fc9-4020-b144-b027f2633991.csv
new file mode 100644
index 00000000..901b6c6c
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.1324f2a2-4fc9-4020-b144-b027f2633991.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,40.762545952058495,True
+2019/06/01 00:30:00,40.76743483501793,True
+2019/06/01 00:45:00,40.76173552898731,True
+2019/06/01 01:00:00,40.88997663263541,True
+2019/06/01 01:15:00,40.76743483501793,True
+2019/06/01 01:30:00,40.76173552898731,True
+2019/06/01 01:45:00,40.88997663263541,True
+2019/06/01 02:00:00,40.91545906991567,True
+2019/06/01 02:15:00,40.76173552898731,True
+2019/06/01 02:30:00,40.88997663263541,True
+2019/06/01 02:45:00,40.91545906991567,True
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.16e5aef9-56d0-478e-a9b2-903c7e6f7222.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.16e5aef9-56d0-478e-a9b2-903c7e6f7222.csv
new file mode 100644
index 00000000..2f8b9e2b
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.16e5aef9-56d0-478e-a9b2-903c7e6f7222.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,33.78291963595312,True
+2019/06/01 00:30:00,33.760188722701734,True
+2019/06/01 00:45:00,33.78499250832337,True
+2019/06/01 01:00:00,33.34560209244707,True
+2019/06/01 01:15:00,33.760188722701734,True
+2019/06/01 01:30:00,33.78499250832337,True
+2019/06/01 01:45:00,33.34560209244707,True
+2019/06/01 02:00:00,33.24901846655432,True
+2019/06/01 02:15:00,33.78499250832337,True
+2019/06/01 02:30:00,33.34560209244707,True
+2019/06/01 02:45:00,33.24901846655432,True
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.17f547a3-aad9-4cc3-98be-327aefe6a1d6.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.17f547a3-aad9-4cc3-98be-327aefe6a1d6.csv
new file mode 100644
index 00000000..202e53ae
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.17f547a3-aad9-4cc3-98be-327aefe6a1d6.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,40.76253874147287,True
+2019/06/01 00:30:00,40.76742762661302,True
+2019/06/01 00:45:00,40.761728317860275,True
+2019/06/01 01:00:00,40.889969496588044,True
+2019/06/01 01:15:00,40.76742762661302,True
+2019/06/01 01:30:00,40.761728317860275,True
+2019/06/01 01:45:00,40.889969496588044,True
+2019/06/01 02:00:00,40.91545194859233,True
+2019/06/01 02:15:00,40.761728317860275,True
+2019/06/01 02:30:00,40.889969496588044,True
+2019/06/01 02:45:00,40.91545194859233,True
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.36fd2f4e-8305-4f45-ae4a-5a7a3cc95013.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.36fd2f4e-8305-4f45-ae4a-5a7a3cc95013.csv
new file mode 100644
index 00000000..fdfd66eb
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.36fd2f4e-8305-4f45-ae4a-5a7a3cc95013.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,33.78290102110617,True
+2019/06/01 00:30:00,33.760170149896084,True
+2019/06/01 00:45:00,33.784973661367005,True
+2019/06/01 01:00:00,33.34558497888935,True
+2019/06/01 01:15:00,33.760170149896084,True
+2019/06/01 01:30:00,33.784973661367005,True
+2019/06/01 01:45:00,33.34558497888935,True
+2019/06/01 02:00:00,33.24900176895076,True
+2019/06/01 02:15:00,33.784973661367005,True
+2019/06/01 02:30:00,33.34558497888935,True
+2019/06/01 02:45:00,33.24900176895076,True
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.40c59858-58c3-4b8c-8521-f7a251f06740.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.40c59858-58c3-4b8c-8521-f7a251f06740.csv
new file mode 100644
index 00000000..0e9cff91
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.40c59858-58c3-4b8c-8521-f7a251f06740.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.5406728899740245,False
+2019/06/01 00:30:00,0.540863758921489,False
+2019/06/01 00:45:00,0.5430364131838421,False
+2019/06/01 01:00:00,0.5377316600654587,False
+2019/06/01 01:15:00,0.540863758921489,False
+2019/06/01 01:30:00,0.5430364131838421,False
+2019/06/01 01:45:00,0.5377316600654587,False
+2019/06/01 02:00:00,0.5363869723798321,False
+2019/06/01 02:15:00,0.5430364131838421,False
+2019/06/01 02:30:00,0.5377316600654587,False
+2019/06/01 02:45:00,0.5363869723798321,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.44c05d80-7a90-4229-94f7-0ef2787b2cc7.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.44c05d80-7a90-4229-94f7-0ef2787b2cc7.csv
new file mode 100644
index 00000000..4e8f4151
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.44c05d80-7a90-4229-94f7-0ef2787b2cc7.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.09236984552530263,False
+2019/06/01 00:30:00,0.09281000038243281,False
+2019/06/01 00:45:00,0.09007496335449869,False
+2019/06/01 01:00:00,0.09308944731014279,False
+2019/06/01 01:15:00,0.09281000038243281,False
+2019/06/01 01:30:00,0.09007496335449869,False
+2019/06/01 01:45:00,0.09308944731014279,False
+2019/06/01 02:00:00,0.09345558983360461,False
+2019/06/01 02:15:00,0.09007496335449869,False
+2019/06/01 02:30:00,0.09308944731014279,False
+2019/06/01 02:45:00,0.09345558983360461,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.59f65367-c852-40ab-9d7f-dc30822570f7.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.59f65367-c852-40ab-9d7f-dc30822570f7.csv
new file mode 100644
index 00000000..53d060a6
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.59f65367-c852-40ab-9d7f-dc30822570f7.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.0002332110312419084,False
+2019/06/01 00:30:00,0.00023248674300960958,False
+2019/06/01 00:45:00,0.0002331804137368649,False
+2019/06/01 01:00:00,0.00020472502359997633,False
+2019/06/01 01:15:00,0.00023248674300960958,False
+2019/06/01 01:30:00,0.0002331804137368649,False
+2019/06/01 01:45:00,0.00020472502359997633,False
+2019/06/01 02:00:00,0.00020664891873504367,False
+2019/06/01 02:15:00,0.0002331804137368649,False
+2019/06/01 02:30:00,0.00020472502359997633,False
+2019/06/01 02:45:00,0.00020664891873504367,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.5b3d3f0c-0c14-4c3d-9080-0fb5bbea5470.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.5b3d3f0c-0c14-4c3d-9080-0fb5bbea5470.csv
new file mode 100644
index 00000000..0b187915
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.5b3d3f0c-0c14-4c3d-9080-0fb5bbea5470.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,22.316483896454272,True
+2019/06/01 00:30:00,21.111590821812953,True
+2019/06/01 00:45:00,22.297097848523077,True
+2019/06/01 01:00:00,16.949676340249898,True
+2019/06/01 01:15:00,21.111590821812953,True
+2019/06/01 01:30:00,22.297097848523077,True
+2019/06/01 01:45:00,16.949676340249898,True
+2019/06/01 02:00:00,16.64657433340466,True
+2019/06/01 02:15:00,22.297097848523077,True
+2019/06/01 02:30:00,16.949676340249898,True
+2019/06/01 02:45:00,16.64657433340466,True
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.68c17aed-1c16-4a75-b0a7-7cf2db5d605d.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.68c17aed-1c16-4a75-b0a7-7cf2db5d605d.csv
new file mode 100644
index 00000000..7fe26a9c
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.68c17aed-1c16-4a75-b0a7-7cf2db5d605d.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.02790970306750502,False
+2019/06/01 00:30:00,0.02561712217720309,False
+2019/06/01 00:45:00,0.027801776504403054,False
+2019/06/01 01:00:00,0.03281313679697618,False
+2019/06/01 01:15:00,0.02561712217720309,False
+2019/06/01 01:30:00,0.027801776504403054,False
+2019/06/01 01:45:00,0.03281313679697618,False
+2019/06/01 02:00:00,0.021915087492895474,False
+2019/06/01 02:15:00,0.027801776504403054,False
+2019/06/01 02:30:00,0.03281313679697618,False
+2019/06/01 02:45:00,0.021915087492895474,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.6cdda038-b853-4a8e-bf6d-304c49d93688.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.6cdda038-b853-4a8e-bf6d-304c49d93688.csv
new file mode 100644
index 00000000..57e66ed1
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.6cdda038-b853-4a8e-bf6d-304c49d93688.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.00013574421312050842,False
+2019/06/01 00:30:00,0.00013741495394791443,False
+2019/06/01 00:45:00,0.00013760941523850001,False
+2019/06/01 01:00:00,0.00013448867777673615,False
+2019/06/01 01:15:00,0.00013741495394791443,False
+2019/06/01 01:30:00,0.00013760941523850001,False
+2019/06/01 01:45:00,0.00013448867777673615,False
+2019/06/01 02:00:00,0.00012263124346418295,False
+2019/06/01 02:15:00,0.00013760941523850001,False
+2019/06/01 02:30:00,0.00013448867777673615,False
+2019/06/01 02:45:00,0.00012263124346418295,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.861ae659-79c7-45f7-9933-bed0a2560e7c.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.861ae659-79c7-45f7-9933-bed0a2560e7c.csv
new file mode 100644
index 00000000..8e21db74
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.861ae659-79c7-45f7-9933-bed0a2560e7c.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.0002478938224916952,False
+2019/06/01 00:30:00,0.00024999965072799177,False
+2019/06/01 00:45:00,0.00025002559928595416,False
+2019/06/01 01:00:00,0.0002497202624742827,False
+2019/06/01 01:15:00,0.00024999965072799177,False
+2019/06/01 01:30:00,0.00025002559928595416,False
+2019/06/01 01:45:00,0.0002497202624742827,False
+2019/06/01 02:00:00,0.00024826376224806646,False
+2019/06/01 02:15:00,0.00025002559928595416,False
+2019/06/01 02:30:00,0.0002497202624742827,False
+2019/06/01 02:45:00,0.00024826376224806646,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.96ac00ff-1369-472b-b8cd-d8721355f4c5.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.96ac00ff-1369-472b-b8cd-d8721355f4c5.csv
new file mode 100644
index 00000000..b802cd99
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.96ac00ff-1369-472b-b8cd-d8721355f4c5.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.8176430638920928,False
+2019/06/01 00:30:00,0.8233757154222654,False
+2019/06/01 00:45:00,0.8454098537209395,False
+2019/06/01 01:00:00,0.8206228753058639,False
+2019/06/01 01:15:00,0.8233757154222654,False
+2019/06/01 01:30:00,0.8454098537209395,False
+2019/06/01 01:45:00,0.8206228753058639,False
+2019/06/01 02:00:00,0.8249488391105355,False
+2019/06/01 02:15:00,0.8454098537209395,False
+2019/06/01 02:30:00,0.8206228753058639,False
+2019/06/01 02:45:00,0.8249488391105355,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.9e3fff1f-2625-4f3f-b510-f4e51683c941.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.9e3fff1f-2625-4f3f-b510-f4e51683c941.csv
new file mode 100644
index 00000000..83d2dd7e
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.9e3fff1f-2625-4f3f-b510-f4e51683c941.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.16267837021247192,False
+2019/06/01 00:30:00,0.15268452589518644,False
+2019/06/01 00:45:00,0.16210995637157377,False
+2019/06/01 01:00:00,0.011530123007345048,False
+2019/06/01 01:15:00,0.15268452589518644,False
+2019/06/01 01:30:00,0.16210995637157377,False
+2019/06/01 01:45:00,0.011530123007345048,False
+2019/06/01 02:00:00,0.10291679915350609,False
+2019/06/01 02:15:00,0.16210995637157377,False
+2019/06/01 02:30:00,0.011530123007345048,False
+2019/06/01 02:45:00,0.10291679915350609,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.a0ba7300-0264-4450-8a1b-6f8045ee7cfe.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.a0ba7300-0264-4450-8a1b-6f8045ee7cfe.csv
new file mode 100644
index 00000000..61dd3fdf
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.a0ba7300-0264-4450-8a1b-6f8045ee7cfe.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.14300654373003865,False
+2019/06/01 00:30:00,0.1313747655068514,False
+2019/06/01 00:45:00,0.14311125781104844,False
+2019/06/01 01:00:00,0.1352482523139778,False
+2019/06/01 01:15:00,0.1313747655068514,False
+2019/06/01 01:30:00,0.14311125781104844,False
+2019/06/01 01:45:00,0.1352482523139778,False
+2019/06/01 02:00:00,0.09062897866870054,False
+2019/06/01 02:15:00,0.14311125781104844,False
+2019/06/01 02:30:00,0.1352482523139778,False
+2019/06/01 02:45:00,0.09062897866870054,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.bbb1f6a0-394e-4b38-bd51-1fa8f70d89dd.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.bbb1f6a0-394e-4b38-bd51-1fa8f70d89dd.csv
new file mode 100644
index 00000000..31cc2681
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.bbb1f6a0-394e-4b38-bd51-1fa8f70d89dd.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.01999090583342565,False
+2019/06/01 00:30:00,0.01637889289057861,False
+2019/06/01 00:45:00,0.01994142241779324,False
+2019/06/01 01:00:00,0.0854083607286207,False
+2019/06/01 01:15:00,0.01637889289057861,False
+2019/06/01 01:30:00,0.01994142241779324,False
+2019/06/01 01:45:00,0.0854083607286207,False
+2019/06/01 02:00:00,0.057416815207186875,False
+2019/06/01 02:15:00,0.01994142241779324,False
+2019/06/01 02:30:00,0.0854083607286207,False
+2019/06/01 02:45:00,0.057416815207186875,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.bf23c675-d787-4994-803b-18d8d4900699.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.bf23c675-d787-4994-803b-18d8d4900699.csv
new file mode 100644
index 00000000..5caaf671
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.bf23c675-d787-4994-803b-18d8d4900699.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.01957955926327284,False
+2019/06/01 00:30:00,0.016091314620048182,False
+2019/06/01 00:45:00,0.01960238980286143,False
+2019/06/01 01:00:00,0.02325547687399226,False
+2019/06/01 01:15:00,0.016091314620048182,False
+2019/06/01 01:30:00,0.01960238980286143,False
+2019/06/01 01:45:00,0.02325547687399226,False
+2019/06/01 02:00:00,0.014657311898480107,False
+2019/06/01 02:15:00,0.01960238980286143,False
+2019/06/01 02:30:00,0.02325547687399226,False
+2019/06/01 02:45:00,0.014657311898480107,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.bfdf4e28-5baf-4d54-9d0a-5a7dc3fbd4f3.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.bfdf4e28-5baf-4d54-9d0a-5a7dc3fbd4f3.csv
new file mode 100644
index 00000000..ddd4da8a
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.bfdf4e28-5baf-4d54-9d0a-5a7dc3fbd4f3.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,22.31648389645426,True
+2019/06/01 00:30:00,21.111590874230032,True
+2019/06/01 00:45:00,22.297097848523055,True
+2019/06/01 01:00:00,16.949676577378025,True
+2019/06/01 01:15:00,21.111590874230032,True
+2019/06/01 01:30:00,22.297097848523055,True
+2019/06/01 01:45:00,16.949676577378025,True
+2019/06/01 02:00:00,16.64657454813445,True
+2019/06/01 02:15:00,22.297097848523055,True
+2019/06/01 02:30:00,16.949676577378025,True
+2019/06/01 02:45:00,16.64657454813445,True
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.db1a87fb-d770-4939-b747-7cadf1f304f8.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.db1a87fb-d770-4939-b747-7cadf1f304f8.csv
new file mode 100644
index 00000000..d2635f35
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.db1a87fb-d770-4939-b747-7cadf1f304f8.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,33.782920097221535,True
+2019/06/01 00:30:00,33.760189179625335,True
+2019/06/01 00:45:00,33.78499296950095,True
+2019/06/01 01:00:00,33.3456025287354,True
+2019/06/01 01:15:00,33.760189179625335,True
+2019/06/01 01:30:00,33.78499296950095,True
+2019/06/01 01:45:00,33.3456025287354,True
+2019/06/01 02:00:00,33.249018899385014,True
+2019/06/01 02:15:00,33.78499296950095,True
+2019/06/01 02:30:00,33.3456025287354,True
+2019/06/01 02:45:00,33.249018899385014,True
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.de88d8f3-d596-4088-8ee7-d96326ab083c.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.de88d8f3-d596-4088-8ee7-d96326ab083c.csv
new file mode 100644
index 00000000..32532f62
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.de88d8f3-d596-4088-8ee7-d96326ab083c.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.007871161472699246,False
+2019/06/01 00:30:00,0.007873089360972783,False
+2019/06/01 00:45:00,0.007871428445214821,False
+2019/06/01 01:00:00,0.007858456444897322,False
+2019/06/01 01:15:00,0.007873089360972783,False
+2019/06/01 01:30:00,0.007871428445214821,False
+2019/06/01 01:45:00,0.007858456444897322,False
+2019/06/01 02:00:00,0.00785495265141455,False
+2019/06/01 02:15:00,0.007871428445214821,False
+2019/06/01 02:30:00,0.007858456444897322,False
+2019/06/01 02:45:00,0.00785495265141455,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.e2dcff78-1f88-496b-9111-66ea2cc6c889.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.e2dcff78-1f88-496b-9111-66ea2cc6c889.csv
new file mode 100644
index 00000000..32307924
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.e2dcff78-1f88-496b-9111-66ea2cc6c889.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.8180636642297237,False
+2019/06/01 00:30:00,0.8073249069721483,False
+2019/06/01 00:45:00,0.787421495488698,False
+2019/06/01 01:00:00,0.8149858988039503,False
+2019/06/01 01:15:00,0.8073249069721483,False
+2019/06/01 01:30:00,0.787421495488698,False
+2019/06/01 01:45:00,0.8149858988039503,False
+2019/06/01 02:00:00,0.8116740332788329,False
+2019/06/01 02:15:00,0.787421495488698,False
+2019/06/01 02:30:00,0.8149858988039503,False
+2019/06/01 02:45:00,0.8116740332788329,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.f2d0448f-aab3-4da0-8aca-17564c8e3a58.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.f2d0448f-aab3-4da0-8aca-17564c8e3a58.csv
new file mode 100644
index 00000000..dfcad658
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.f2d0448f-aab3-4da0-8aca-17564c8e3a58.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,0.0038731476658697217,False
+2019/06/01 00:30:00,0.003924386596964254,False
+2019/06/01 00:45:00,0.003929577215236253,False
+2019/06/01 01:00:00,0.003863557286874198,False
+2019/06/01 01:15:00,0.003924386596964254,False
+2019/06/01 01:30:00,0.003929577215236253,False
+2019/06/01 01:45:00,0.003863557286874198,False
+2019/06/01 02:00:00,0.003503018448803092,False
+2019/06/01 02:15:00,0.003929577215236253,False
+2019/06/01 02:30:00,0.003863557286874198,False
+2019/06/01 02:45:00,0.003503018448803092,False
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.f57d88d3-925f-4d5d-b25c-b3b9475f1ea7.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.f57d88d3-925f-4d5d-b25c-b3b9475f1ea7.csv
new file mode 100644
index 00000000..21a06bd7
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.f57d88d3-925f-4d5d-b25c-b3b9475f1ea7.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,40.779447683686826,True
+2019/06/01 00:30:00,40.767397968777416,True
+2019/06/01 00:45:00,40.761699248916194,True
+2019/06/01 01:00:00,40.889940418073856,True
+2019/06/01 01:15:00,40.767397968777416,True
+2019/06/01 01:30:00,40.761699248916194,True
+2019/06/01 01:45:00,40.889940418073856,True
+2019/06/01 02:00:00,40.91542400926487,True
+2019/06/01 02:15:00,40.761699248916194,True
+2019/06/01 02:30:00,40.889940418073856,True
+2019/06/01 02:45:00,40.91542400926487,True
diff --git a/spec/files/opendss_outputs/opendss/results/Lines/Line.f912d33f-f017-4ba5-b2fd-2ed2eec38b71.csv b/spec/files/opendss_outputs/opendss/results/Lines/Line.f912d33f-f017-4ba5-b2fd-2ed2eec38b71.csv
new file mode 100644
index 00000000..ebad8919
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Lines/Line.f912d33f-f017-4ba5-b2fd-2ed2eec38b71.csv
@@ -0,0 +1,12 @@
+Datetime,p.u. loading,overloaded
+2019/06/01 00:15:00,40.76250820083001,True
+2019/06/01 00:30:00,40.76739629862129,True
+2019/06/01 00:45:00,40.76169757438438,True
+2019/06/01 01:00:00,40.889938882726746,True
+2019/06/01 01:15:00,40.76739629862129,True
+2019/06/01 01:30:00,40.76169757438438,True
+2019/06/01 01:45:00,40.889938882726746,True
+2019/06/01 02:00:00,40.915422501275195,True
+2019/06/01 02:15:00,40.76169757438438,True
+2019/06/01 02:30:00,40.889938882726746,True
+2019/06/01 02:45:00,40.915422501275195,True
diff --git a/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.1b4b5dcf-8d18-4954-b655-a93634542733.csv b/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.1b4b5dcf-8d18-4954-b655-a93634542733.csv
new file mode 100644
index 00000000..cb1810be
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.1b4b5dcf-8d18-4954-b655-a93634542733.csv
@@ -0,0 +1,25 @@
+Datetime,p.u. loading,overloaded
+6/1/2012 1:00,149.1749429,TRUE
+6/1/2012 2:00,149.1308639,TRUE
+6/1/2012 3:00,149.1100175,TRUE
+6/1/2012 4:00,149.5791354,TRUE
+6/1/2012 5:00,149.1308639,TRUE
+6/1/2012 6:00,149.1100175,TRUE
+6/1/2012 7:00,149.5791354,TRUE
+6/1/2012 8:00,149.6723567,TRUE
+6/1/2012 9:00,149.1100175,TRUE
+6/1/2012 10:00,149.5791354,TRUE
+6/1/2012 11:00,149.6723567,TRUE
+6/1/2012 12:00,149.1749429,TRUE
+6/1/2012 13:00,149.1308639,TRUE
+6/1/2012 14:00,149.1100175,TRUE
+6/1/2012 15:00,149.5791354,TRUE
+6/1/2012 16:00,149.1308639,TRUE
+6/1/2012 17:00,149.1100175,TRUE
+6/1/2012 18:00,149.5791354,TRUE
+6/1/2012 19:00,149.6723567,TRUE
+6/1/2012 20:00,149.1100175,TRUE
+6/1/2012 21:00,149.5791354,TRUE
+6/1/2012 22:00,149.6723567,TRUE
+6/1/2012 23:00,149.6723567,TRUE
+6/2/2012 0:00,149.6723567,TRUE
diff --git a/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.502e96e3-853a-4b3d-b88d-fe59af4d7b65.csv b/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.502e96e3-853a-4b3d-b88d-fe59af4d7b65.csv
new file mode 100644
index 00000000..4c5f344c
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.502e96e3-853a-4b3d-b88d-fe59af4d7b65.csv
@@ -0,0 +1,25 @@
+Datetime,p.u. loading,overloaded
+6/1/2012 1:00,17.30321915,TRUE
+6/1/2012 2:00,16.22341634,TRUE
+6/1/2012 3:00,17.28360263,TRUE
+6/1/2012 4:00,14.67874647,TRUE
+6/1/2012 5:00,16.22341634,TRUE
+6/1/2012 6:00,17.28360263,TRUE
+6/1/2012 7:00,14.67874647,TRUE
+6/1/2012 8:00,15.11325504,TRUE
+6/1/2012 9:00,17.28360263,TRUE
+6/1/2012 10:00,14.67874647,TRUE
+6/1/2012 11:00,15.11325504,TRUE
+6/1/2012 12:00,15.01646523,TRUE
+6/1/2012 13:00,14.8546093,TRUE
+6/1/2012 14:00,14.69275337,TRUE
+6/1/2012 15:00,14.53089743,TRUE
+6/1/2012 16:00,14.3690415,TRUE
+6/1/2012 17:00,14.20718557,TRUE
+6/1/2012 18:00,14.04532963,TRUE
+6/1/2012 19:00,13.8834737,TRUE
+6/1/2012 20:00,13.72161776,TRUE
+6/1/2012 21:00,13.55976183,TRUE
+6/1/2012 22:00,13.3979059,TRUE
+6/1/2012 23:00,13.23604996,TRUE
+6/2/2012 0:00,13.07419403,TRUE
diff --git a/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.54cd0a5a-2ebe-4b39-936a-f238b503c221.csv b/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.54cd0a5a-2ebe-4b39-936a-f238b503c221.csv
new file mode 100644
index 00000000..a0aac97a
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.54cd0a5a-2ebe-4b39-936a-f238b503c221.csv
@@ -0,0 +1,25 @@
+Datetime,p.u. loading,overloaded
+6/1/2012 1:00,0.006827765,FALSE
+6/1/2012 2:00,0.006911801,FALSE
+6/1/2012 3:00,0.006921582,FALSE
+6/1/2012 4:00,0.006764613,FALSE
+6/1/2012 5:00,0.006911801,FALSE
+6/1/2012 6:00,0.006921582,FALSE
+6/1/2012 7:00,0.006764613,FALSE
+6/1/2012 8:00,0.006168199,FALSE
+6/1/2012 9:00,0.006921582,FALSE
+6/1/2012 10:00,0.006764613,FALSE
+6/1/2012 11:00,0.006168199,FALSE
+6/1/2012 12:00,0.006446399,FALSE
+6/1/2012 13:00,0.006398885,FALSE
+6/1/2012 14:00,0.00635137,FALSE
+6/1/2012 15:00,0.006303856,FALSE
+6/1/2012 16:00,0.006256341,FALSE
+6/1/2012 17:00,0.006208827,FALSE
+6/1/2012 18:00,0.006161312,FALSE
+6/1/2012 19:00,0.006113798,FALSE
+6/1/2012 20:00,0.006066283,FALSE
+6/1/2012 21:00,0.006018768,FALSE
+6/1/2012 22:00,0.005971254,FALSE
+6/1/2012 23:00,0.005923739,FALSE
+6/2/2012 0:00,0.005876225,FALSE
diff --git a/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.897530f5-a6d6-446f-94fd-4087196fceaf.csv b/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.897530f5-a6d6-446f-94fd-4087196fceaf.csv
new file mode 100644
index 00000000..57ba0dec
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.897530f5-a6d6-446f-94fd-4087196fceaf.csv
@@ -0,0 +1,25 @@
+Datetime,p.u. loading,overloaded
+6/1/2012 1:00,0.016625001,FALSE
+6/1/2012 2:00,0.016766228,FALSE
+6/1/2012 3:00,0.016767969,FALSE
+6/1/2012 4:00,0.016747491,FALSE
+6/1/2012 5:00,0.016766228,FALSE
+6/1/2012 6:00,0.016767969,FALSE
+6/1/2012 7:00,0.016747491,FALSE
+6/1/2012 8:00,0.016649811,FALSE
+6/1/2012 9:00,0.016767969,FALSE
+6/1/2012 10:00,0.016747491,FALSE
+6/1/2012 11:00,0.016649811,FALSE
+6/1/2012 12:00,0.016718587,FALSE
+6/1/2012 13:00,0.016717087,FALSE
+6/1/2012 14:00,0.016715587,FALSE
+6/1/2012 15:00,0.016714088,FALSE
+6/1/2012 16:00,0.016712588,FALSE
+6/1/2012 17:00,0.016711088,FALSE
+6/1/2012 18:00,0.016709588,FALSE
+6/1/2012 19:00,0.016708088,FALSE
+6/1/2012 20:00,0.016706588,FALSE
+6/1/2012 21:00,0.016705088,FALSE
+6/1/2012 22:00,0.016703588,FALSE
+6/1/2012 23:00,0.016702088,FALSE
+6/2/2012 0:00,0.016700588,FALSE
diff --git a/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.b02e3fe9-77d0-47f9-86cb-e4db960afd62.csv b/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.b02e3fe9-77d0-47f9-86cb-e4db960afd62.csv
new file mode 100644
index 00000000..ea479951
--- /dev/null
+++ b/spec/files/opendss_outputs/opendss/results/Transformers/Transformer.b02e3fe9-77d0-47f9-86cb-e4db960afd62.csv
@@ -0,0 +1,25 @@
+Datetime,p.u. loading,overloaded
+6/1/2012 1:00,22.28309274,TRUE
+6/1/2012 2:00,22.30531032,TRUE
+6/1/2012 3:00,22.28538152,TRUE
+6/1/2012 4:00,22.2049006,TRUE
+6/1/2012 5:00,22.30531032,TRUE
+6/1/2012 6:00,22.28538152,TRUE
+6/1/2012 7:00,22.2049006,TRUE
+6/1/2012 8:00,22.1704519,TRUE
+6/1/2012 9:00,22.28538152,TRUE
+6/1/2012 10:00,22.2049006,TRUE
+6/1/2012 11:00,22.1704519,TRUE
+6/1/2012 12:00,22.18408849,TRUE
+6/1/2012 13:00,22.17377804,TRUE
+6/1/2012 14:00,22.16346758,TRUE
+6/1/2012 15:00,22.15315712,TRUE
+6/1/2012 16:00,22.14284667,TRUE
+6/1/2012 17:00,22.13253621,TRUE
+6/1/2012 18:00,22.12222575,TRUE
+6/1/2012 19:00,22.1119153,TRUE
+6/1/2012 20:00,22.10160484,TRUE
+6/1/2012 21:00,22.09129438,TRUE
+6/1/2012 22:00,22.08098393,TRUE
+6/1/2012 23:00,22.07067347,TRUE
+6/2/2012 0:00,22.06036302,TRUE
diff --git a/spec/urbanopt/urbanopt_scenario_spec.rb b/spec/urbanopt/urbanopt_scenario_spec.rb
index 26646087..fcac095a 100644
--- a/spec/urbanopt/urbanopt_scenario_spec.rb
+++ b/spec/urbanopt/urbanopt_scenario_spec.rb
@@ -121,21 +121,19 @@
expect(failures).to be_empty, "the following directories failed to run [#{failures.join(', ')}]"
default_post_processor = URBANopt::Scenario::ScenarioDefaultPostProcessor.new(scenario)
- scenario_result = default_post_processor.run
+ $scenario_result = default_post_processor.run
# save scenario result
- scenario_result.save()
+ $scenario_result.save
- # save feature reports
- scenario_result.feature_reports.each do |feature_report|
- feature_report.save_feature_report()
- end
+ ### save feature reports
+ $scenario_result.feature_reports.each(&:save_feature_report)
## Add test assertions on scenario_result
# Check scenario_report JSON file
# Read json file
- scenario_json_file = File.open(scenario_result.json_path)
+ scenario_json_file = File.open($scenario_result.json_path)
data = JSON.parse(File.read(scenario_json_file))
# Program results check
@@ -194,7 +192,7 @@
scenario_json_file.close
# Read scenario csv file and validate against schema
- scenario_csv_headers = CSV.open(File.expand_path(scenario_result.csv_path, File.dirname(__FILE__)), &:readline)
+ scenario_csv_headers = CSV.open(File.expand_path($scenario_result.csv_path, File.dirname(__FILE__)), &:readline)
# strip the units partial string from the scenario_csv_header since these units can change
scenario_csv_headers_with_no_units = []
scenario_csv_headers.each do |x|
@@ -205,14 +203,14 @@
# read scenario csv schema headers
scenario_csv_schema = open(File.expand_path('../../lib/urbanopt/scenario/default_reports/schema/scenario_csv_columns.txt', File.dirname(__FILE__))) # .read()
-
+
scenario_csv_schema_headers = []
File.readlines(scenario_csv_schema).each do |line|
l = line.delete("\n")
a = l.delete("\t")
scenario_csv_schema_headers << a
end
-
+
# rubocop: enable Security/Open
expect(scenario_csv_headers_with_no_units).to eq(scenario_csv_schema_headers)
@@ -226,5 +224,15 @@
# close schema file
schema_json.close
end
+
+ it 'can integrate opendss results' do
+ # generate opendssreults for testing
+ opendss_results_source = File.join(File.dirname(__FILE__), '../files/opendss_outputs/')
+ opendss_results_destination = File.join(File.dirname(__FILE__), '../test/example_scenario')
+ FileUtils.copy_entry opendss_results_source, opendss_results_destination
+ # post_process opendss results
+ opendss_post_processor = URBANopt::Scenario::OpenDSSPostProcessor.new($scenario_result, 'opendss')
+ opendss_post_processor.run
+ end
end
# rubocop:enable Metrics/BlockLength
diff --git a/urbanopt-scenario-gem.gemspec b/urbanopt-scenario-gem.gemspec
index 574549a9..11ddde35 100644
--- a/urbanopt-scenario-gem.gemspec
+++ b/urbanopt-scenario-gem.gemspec
@@ -24,17 +24,17 @@ Gem::Specification.new do |spec|
spec.required_ruby_version = '~> 2.2.4'
spec.add_development_dependency 'bundler', '~> 1.14'
- spec.add_development_dependency 'rake', '12.3.1'
- spec.add_development_dependency 'rspec', '3.7.0'
spec.add_development_dependency 'github_api', '~> 0.18.0'
- # Fix rack version temporarily to work with Ruby 2.2.4
- spec.add_development_dependency 'rack', '2.1.2'
+ spec.add_development_dependency 'rake', '~> 12.3'
+ spec.add_development_dependency 'rspec', '~> 3.7'
spec.add_dependency 'json-schema'
spec.add_dependency 'json_pure'
spec.add_dependency 'openstudio-model-articulation', '~> 0.1.1'
- spec.add_dependency 'urbanopt-core', '~> 0.1.0'
+ spec.add_dependency 'urbanopt-core', '~> 0.2.0'
# lock the version of these dependencies due to using older version of Ruby.
spec.add_dependency 'public_suffix', '3.1.1'
+ spec.add_development_dependency 'rack', '2.1.2'
+
end