urbanopt-reporting 0.4.3 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -1
- data/LICENSE.md +17 -17
- data/doc_templates/LICENSE.md +17 -17
- data/doc_templates/copyright_erb.txt +2 -2
- data/doc_templates/copyright_js.txt +2 -2
- data/doc_templates/copyright_ruby.txt +1 -1
- data/docs/package-lock.json +15720 -1410
- data/lib/measures/.rubocop.yml +4 -2
- data/lib/measures/default_feature_reports/measure.rb +242 -36
- data/lib/measures/export_modelica_loads/measure.rb +2 -1
- data/lib/measures/export_time_series_modelica/measure.rb +58 -59
- data/lib/measures/export_time_series_modelica/resources/os_lib_helper_methods.rb +3 -5
- data/lib/urbanopt/reporting/default_reports/construction_cost.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/date.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/distributed_generation.rb +24 -6
- data/lib/urbanopt/reporting/default_reports/end_use.rb +1 -1
- data/lib/urbanopt/reporting/default_reports/end_uses.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/extension.rb +1 -1
- data/lib/urbanopt/reporting/default_reports/feature_report.rb +9 -8
- data/lib/urbanopt/reporting/default_reports/generator.rb +1 -2
- data/lib/urbanopt/reporting/default_reports/location.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/logger.rb +2 -2
- data/lib/urbanopt/reporting/default_reports/power_distribution.rb +22 -6
- data/lib/urbanopt/reporting/default_reports/program.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/reporting_period.rb +47 -7
- data/lib/urbanopt/reporting/default_reports/scenario_power_distribution.rb +148 -0
- data/lib/urbanopt/reporting/default_reports/scenario_report.rb +20 -14
- data/lib/urbanopt/reporting/default_reports/schema/scenario_csv_columns.txt +24 -0
- data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +265 -6
- data/lib/urbanopt/reporting/default_reports/solar_pv.rb +42 -3
- data/lib/urbanopt/reporting/default_reports/storage.rb +1 -1
- data/lib/urbanopt/reporting/default_reports/thermal_storage.rb +1 -1
- data/lib/urbanopt/reporting/default_reports/timeseries_csv.rb +2 -1
- data/lib/urbanopt/reporting/default_reports/validator.rb +1 -1
- data/lib/urbanopt/reporting/default_reports/wind.rb +11 -2
- data/lib/urbanopt/reporting/default_reports.rb +1 -1
- data/lib/urbanopt/reporting/derived_extension.rb +1 -1
- data/lib/urbanopt/reporting/version.rb +2 -2
- data/lib/urbanopt/reporting.rb +1 -1
- data/urbanopt-reporting-gem.gemspec +3 -4
- metadata +16 -15
@@ -1,5 +1,5 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt™, Copyright (c) 2019-
|
2
|
+
# URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
|
3
3
|
# contributors. All rights reserved.
|
4
4
|
|
5
5
|
# Redistribution and use in source and binary forms, with or without modification,
|
@@ -57,13 +57,22 @@ module URBANopt
|
|
57
57
|
:net_site_energy_kwh, :net_source_energy_kwh, :total_utility_cost_dollar, :net_utility_cost_dollar, :utility_costs_dollar, :electricity_kwh, :natural_gas_kwh, :propane_kwh, :fuel_oil_kwh, :other_fuels_kwh, :district_cooling_kwh,
|
58
58
|
:district_heating_kwh, :water_qbft, :electricity_produced_kwh, :end_uses, :energy_production_kwh, :photovoltaic,
|
59
59
|
:fuel_type, :total_cost_dollar, :usage_cost_dollar, :demand_cost_dollar, :comfort_result, :time_setpoint_not_met_during_occupied_cooling,
|
60
|
-
:time_setpoint_not_met_during_occupied_heating, :time_setpoint_not_met_during_occupied_hours, :hours_out_of_comfort_bounds_PMV, :hours_out_of_comfort_bounds_PPD
|
60
|
+
:time_setpoint_not_met_during_occupied_heating, :time_setpoint_not_met_during_occupied_hours, :hours_out_of_comfort_bounds_PMV, :hours_out_of_comfort_bounds_PPD,
|
61
|
+
:emissions, :future_annual_electricity_emissions_mt, :future_hourly_electricity_emissions_mt, :historical_annual_electricity_emissions_mt, :historical_hourly_electricity_emissions_mt,
|
62
|
+
:future_annual_electricity_emissions_intensity_kg_per_ft2, :future_hourly_electricity_emissions_intensity_kg_per_ft2, :historical_annual_electricity_emissions_intensity_kg_per_ft2, :historical_hourly_electricity_emissions_intensity_kg_per_ft2 ,
|
63
|
+
:natural_gas_emissions_mt, :natural_gas_emissions_intensity_kg_per_ft2, :propane_emissions_mt, :propane_emissions_intensity_kg_per_ft2,
|
64
|
+
:fueloil_no2_emissions_mt, :fueloil_no2_emissions_intensity_kg_per_ft2 #:nodoc:
|
65
|
+
|
61
66
|
# ReportingPeriod class initializes the reporting period attributes:
|
62
67
|
# +:id+ , +:name+ , +:multiplier+ , +:start_date+ , +:end_date+ , +:month+ , +:day_of_month+ , +:year+ , +:total_site_energy_kwh+ , +:total_source_energy_kwh+ , +:site_EUI_kwh_per_m2+, +:site_EUI_kbtu_per_ft2+, +:source_EUI_kwh_per_m2+, +:source_EUI_kbtu_per_ft2+,
|
63
68
|
# +:net_site_energy_kwh+ , +:net_source_energy_kwh+ , +:total_utility_cost_dollar , +:net_utility_cost_dollar+ , +:utility_costs_dollar+ , +:electricity_kwh+ , +:natural_gas_kwh+ , +:propane_kwh+ , +:fuel_oil_kwh+ , +:other_fuels_kwh+ , +:district_cooling_kwh+ ,
|
64
69
|
# +:district_heating_kwh+ , +:water_qbft+ , +:electricity_produced_kwh+ , +:end_uses+ , +:energy_production_kwh+ , +:photovoltaic_kwh+ ,
|
65
70
|
# +:fuel_type+ , +:total_cost_dollar+ , +:usage_cost_dollar+ , +:demand_cost_dollar+ , +:comfort_result+ , +:time_setpoint_not_met_during_occupied_cooling+ ,
|
66
|
-
# +:time_setpoint_not_met_during_occupied_heating+ , +:time_setpoint_not_met_during_occupied_hours+
|
71
|
+
# +:time_setpoint_not_met_during_occupied_heating+ , +:time_setpoint_not_met_during_occupied_hours+ , +:hours_out_of_comfort_bounds_PMV+ , +:hours_out_of_comfort_bounds_PPD+ ,
|
72
|
+
# +:emissions, +:future_annual_electricity_emissions_mt+, +:future_hourly_electricity_emissions_mt+, +:historical_annual_electricity_emissions_mt+, +:historical_hourly_electricity_emissions_mt+,
|
73
|
+
# +:future_annual_electricity_emissions_intensity_kg_per_ft2+, +:future_hourly_electricity_emissions_intensity_kg_per_ft2+, +:historical_annual_electricity_emissions_intensity_kg_per_ft2+, +:historical_hourly_electricity_emissions_intensity_kg_per_ft2+,
|
74
|
+
# +:natural_gas_emissions_mt+, +:natural_gas_emissions_intensity_kg_per_ft2+, +:propane_emissions_mt+, +:propane_emissions_intensity_kg_per_ft2+,
|
75
|
+
# +:fueloil_no2_emissions_mt+, +:fueloil_no2_emissions_intensity_kg_per_ft2+
|
67
76
|
##
|
68
77
|
# [parameters:]
|
69
78
|
# +hash+ - _Hash_ - A hash which may contain a deserialized reporting_period.
|
@@ -105,6 +114,8 @@ module URBANopt
|
|
105
114
|
|
106
115
|
@comfort_result = hash[:comfort_result]
|
107
116
|
|
117
|
+
@emissions = hash[:emissions]
|
118
|
+
|
108
119
|
# initialize class variables @@validator and @@schema
|
109
120
|
@@validator ||= Validator.new
|
110
121
|
@@schema ||= @@validator.schema
|
@@ -146,6 +157,12 @@ module URBANopt
|
|
146
157
|
hash[:utility_costs_dollar] = [{ fuel_type: nil, total_cost_dollar: nil, usage_cost_dollar: nil, demand_cost_dollar: nil }]
|
147
158
|
hash[:comfort_result] = { time_setpoint_not_met_during_occupied_cooling: nil, time_setpoint_not_met_during_occupied_heating: nil,
|
148
159
|
time_setpoint_not_met_during_occupied_hours: nil, hours_out_of_comfort_bounds_PMV: nil, hours_out_of_comfort_bounds_PPD: nil }
|
160
|
+
hash[:emissions] = { future_annual_electricity_emissions_mt: nil, future_hourly_electricity_emissions_mt: nil, historical_annual_electricity_emissions_mt: nil,
|
161
|
+
historical_hourly_electricity_emissions_mt: nil, future_annual_electricity_emissions_intensity_kg_per_ft2: nil,
|
162
|
+
future_hourly_electricity_emissions_intensity_kg_per_ft2: nil, historical_annual_electricity_emissions_intensity_kg_per_ft2: nil,
|
163
|
+
historical_hourly_electricity_emissions_intensity_kg_per_ft2: nil, natural_gas_emissions_mt: nil,
|
164
|
+
natural_gas_emissions_intensity_kg_per_ft2: nil, propane_emissions_mt: nil, propane_emissions_intensity_kg_per_ft2: nil,
|
165
|
+
fueloil_no2_emissions_mt: nil, fueloil_no2_emissions_intensity_kg_per_ft2: nil }
|
149
166
|
|
150
167
|
return hash
|
151
168
|
end
|
@@ -204,6 +221,10 @@ module URBANopt
|
|
204
221
|
comfort_result_hash.delete_if { |k, v| v.nil? }
|
205
222
|
result[:comfort_result] = comfort_result_hash if @comfort_result
|
206
223
|
|
224
|
+
emissions_hash = @emissions if @emissions
|
225
|
+
#emissions_hash.delete_if { |k, v| v.nil? }
|
226
|
+
result[:emissions] = emissions_hash if @emissions
|
227
|
+
|
207
228
|
# validates +reporting_period+ properties against schema for reporting period.
|
208
229
|
if @@validator.validate(@@schema[:definitions][:ReportingPeriod][:properties], result).any?
|
209
230
|
raise "feature_report properties does not match schema: #{@@validator.validate(@@schema[:definitions][:ReportingPeriod][:properties], result)}"
|
@@ -258,10 +279,8 @@ module URBANopt
|
|
258
279
|
new_end_uses = new_period.end_uses
|
259
280
|
existing_period.end_uses&.merge_end_uses!(new_end_uses)
|
260
281
|
|
261
|
-
if existing_period.energy_production_kwh
|
262
|
-
|
263
|
-
existing_period.energy_production_kwh[:electricity_produced_kwh][:photovoltaic_kwh] = add_values(existing_period.energy_production_kwh[:electricity_produced][:photovoltaic], new_period.energy_production_kwh[:electricity_produced_kwh][:photovoltaic_kwh])
|
264
|
-
end
|
282
|
+
if existing_period.energy_production_kwh && existing_period.energy_production_kwh[:electricity_produced_kwh]
|
283
|
+
existing_period.energy_production_kwh[:electricity_produced_kwh][:photovoltaic_kwh] = add_values(existing_period.energy_production_kwh[:electricity_produced][:photovoltaic], new_period.energy_production_kwh[:electricity_produced_kwh][:photovoltaic_kwh])
|
265
284
|
end
|
266
285
|
|
267
286
|
existing_period.utility_costs_dollar&.each_with_index do |item, i|
|
@@ -279,6 +298,27 @@ module URBANopt
|
|
279
298
|
existing_period.comfort_result[:hours_out_of_comfort_bounds_PPD] = add_values(existing_period.comfort_result[:hours_out_of_comfort_bounds_PPD], new_period.comfort_result[:hours_out_of_comfort_bounds_PPD])
|
280
299
|
end
|
281
300
|
|
301
|
+
if existing_period.emissions
|
302
|
+
existing_period.emissions[:future_annual_electricity_emissions_mt] = add_values(existing_period.emissions[:future_annual_electricity_emissions_mt], new_period.emissions[:future_annual_electricity_emissions_mt])
|
303
|
+
existing_period.emissions[:future_hourly_electricity_emissions_mt] = add_values(existing_period.emissions[:future_hourly_electricity_emissions_mt], new_period.emissions[:future_hourly_electricity_emissions_mt])
|
304
|
+
existing_period.emissions[:historical_annual_electricity_emissions_mt] = add_values(existing_period.emissions[:historical_annual_electricity_emissions_mt], new_period.emissions[:historical_annual_electricity_emissions_mt])
|
305
|
+
existing_period.emissions[:historical_hourly_electricity_emissions_mt] = add_values(existing_period.emissions[:historical_hourly_electricity_emissions_mt], new_period.emissions[:historical_hourly_electricity_emissions_mt])
|
306
|
+
|
307
|
+
existing_period.emissions[:natural_gas_emissions_mt] = add_values(existing_period.emissions[:natural_gas_emissions_mt], new_period.emissions[:natural_gas_emissions_mt])
|
308
|
+
existing_period.emissions[:propane_emissions_mt] = add_values(existing_period.emissions[:propane_emissions_mt], new_period.emissions[:propane_emissions_mt])
|
309
|
+
existing_period.emissions[:fueloil_no2_emissions_mt] = add_values(existing_period.emissions[:fueloil_no2_emissions_mt], new_period.emissions[:fueloil_no2_emissions_mt])
|
310
|
+
|
311
|
+
existing_period.emissions[:future_annual_electricity_emissions_intensity_kg_per_ft2] = add_values(existing_period.emissions[:future_annual_electricity_emissions_intensity_kg_per_ft2], new_period.emissions[:future_annual_electricity_emissions_intensity_kg_per_ft2])
|
312
|
+
existing_period.emissions[:future_hourly_electricity_emissions_intensity_kg_per_ft2] = add_values(existing_period.emissions[:future_hourly_electricity_emissions_intensity_kg_per_ft2], new_period.emissions[:future_hourly_electricity_emissions_intensity_kg_per_ft2])
|
313
|
+
existing_period.emissions[:historical_annual_electricity_emissions_intensity_kg_per_ft2] = add_values(existing_period.emissions[:historical_annual_electricity_emissions_intensity_kg_per_ft2], new_period.emissions[:historical_annual_electricity_emissions_intensity_kg_per_ft2])
|
314
|
+
existing_period.emissions[:historical_hourly_electricity_emissions_intensity_kg_per_ft2] = add_values(existing_period.emissions[:historical_hourly_electricity_emissions_intensity_kg_per_ft2], new_period.emissions[:historical_hourly_electricity_emissions_intensity_kg_per_ft2])
|
315
|
+
|
316
|
+
existing_period.emissions[:natural_gas_emissions_intensity_kg_per_ft2] = add_values(existing_period.emissions[:natural_gas_emissions_intensity_kg_per_ft2], new_period.emissions[:natural_gas_emissions_intensity_kg_per_ft2])
|
317
|
+
existing_period.emissions[:propane_emissions_intensity_kg_per_ft2] = add_values(existing_period.emissions[:propane_emissions_intensity_kg_per_ft2], new_period.emissions[:propane_emissions_intensity_kg_per_ft2])
|
318
|
+
existing_period.emissions[:fueloil_no2_emissions_intensity_kg_per_ft2] = add_values(existing_period.emissions[:fueloil_no2_emissions_intensity_kg_per_ft2], new_period.emissions[:fueloil_no2_emissions_intensity_kg_per_ft2])
|
319
|
+
|
320
|
+
end
|
321
|
+
|
282
322
|
return existing_period
|
283
323
|
end
|
284
324
|
|
@@ -0,0 +1,148 @@
|
|
1
|
+
# *********************************************************************************
|
2
|
+
# URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
|
3
|
+
# contributors. All rights reserved.
|
4
|
+
|
5
|
+
# Redistribution and use in source and binary forms, with or without modification,
|
6
|
+
# are permitted provided that the following conditions are met:
|
7
|
+
|
8
|
+
# Redistributions of source code must retain the above copyright notice, this list
|
9
|
+
# of conditions and the following disclaimer.
|
10
|
+
|
11
|
+
# Redistributions in binary form must reproduce the above copyright notice, this
|
12
|
+
# list of conditions and the following disclaimer in the documentation and/or other
|
13
|
+
# materials provided with the distribution.
|
14
|
+
|
15
|
+
# Neither the name of the copyright holder nor the names of its contributors may be
|
16
|
+
# used to endorse or promote products derived from this software without specific
|
17
|
+
# prior written permission.
|
18
|
+
|
19
|
+
# Redistribution of this software, without modification, must refer to the software
|
20
|
+
# by the same designation. Redistribution of a modified version of this software
|
21
|
+
# (i) may not refer to the modified version by the same designation, or by any
|
22
|
+
# confusingly similar designation, and (ii) must refer to the underlying software
|
23
|
+
# originally provided by Alliance as “URBANopt”. Except to comply with the foregoing,
|
24
|
+
# the term “URBANopt”, or any confusingly similar designation may not be used to
|
25
|
+
# refer to any modified version of this software or any modified version of the
|
26
|
+
# underlying software originally provided by Alliance without the prior written
|
27
|
+
# consent of Alliance.
|
28
|
+
|
29
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
30
|
+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
31
|
+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
32
|
+
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
33
|
+
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
34
|
+
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
35
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
36
|
+
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
37
|
+
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
38
|
+
# OF THE POSSIBILITY OF SUCH DAMAGE.
|
39
|
+
# *********************************************************************************
|
40
|
+
|
41
|
+
require_relative 'validator'
|
42
|
+
|
43
|
+
require 'json'
|
44
|
+
require 'json-schema'
|
45
|
+
|
46
|
+
module URBANopt
|
47
|
+
module Reporting
|
48
|
+
module DefaultReports
|
49
|
+
##
|
50
|
+
# scenario_power_distribution include eletrical power distribution systems information.
|
51
|
+
##
|
52
|
+
class ScenarioPowerDistribution
|
53
|
+
attr_accessor :substations, :distribution_lines, :capacitors
|
54
|
+
|
55
|
+
##
|
56
|
+
# ScenarioPowerDistribution class initialize all scenario_power_distribution attributes:
|
57
|
+
# +:substations+ , +:distribution_lines+
|
58
|
+
##
|
59
|
+
# [parameters:]
|
60
|
+
# +hash+ - _Hash_ - A hash which may contain a deserialized power_distribution.
|
61
|
+
##
|
62
|
+
def initialize(hash = {})
|
63
|
+
hash.delete_if { |k, v| v.nil? }
|
64
|
+
hash = defaults.merge(hash)
|
65
|
+
|
66
|
+
@substations = hash[:substations]
|
67
|
+
@distribution_lines = hash[:distribution_lines]
|
68
|
+
@capacitors = hash[:capacitors]
|
69
|
+
|
70
|
+
# initialize class variables @@validator and @@schema
|
71
|
+
@@validator ||= Validator.new
|
72
|
+
@@schema ||= @@validator.schema
|
73
|
+
end
|
74
|
+
|
75
|
+
##
|
76
|
+
# Assigns default values if attribute values do not exist.
|
77
|
+
##
|
78
|
+
def defaults
|
79
|
+
hash = {}
|
80
|
+
hash[:substations] = []
|
81
|
+
hash[:distribution_lines] = []
|
82
|
+
hash[:capacitors] = []
|
83
|
+
|
84
|
+
return hash
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Converts to a Hash equivalent for JSON serialization.
|
89
|
+
##
|
90
|
+
# - Exclude attributes with nil values.
|
91
|
+
# - Validate power_distribution hash properties against schema.
|
92
|
+
##
|
93
|
+
def to_hash
|
94
|
+
result = {}
|
95
|
+
result[:substations] = @substations if @substations
|
96
|
+
result[:distribution_lines] = @distribution_lines if @distribution_lines
|
97
|
+
result[:capacitors] = @capacitors if @capacitors
|
98
|
+
|
99
|
+
# validate power_distribution properties against schema
|
100
|
+
if @@validator.validate(@@schema[:definitions][:ScenarioPowerDistribution][:properties], result).any?
|
101
|
+
raise "scenario_power_distribution properties does not match schema: #{@@validator.validate(@@schema[:definitions][:ScenarioPowerDistribution][:properties], result)}"
|
102
|
+
end
|
103
|
+
|
104
|
+
return result
|
105
|
+
end
|
106
|
+
|
107
|
+
##
|
108
|
+
# Add a substation
|
109
|
+
##
|
110
|
+
def add_substation(hash = {})
|
111
|
+
hash.delete_if { |k, v| v.nil? }
|
112
|
+
hash = defaults.merge(hash)
|
113
|
+
# field: nominal_voltage
|
114
|
+
substation = {}
|
115
|
+
substation['nominal_voltage'] = hash[:nominal_voltage]
|
116
|
+
@substations << substation
|
117
|
+
end
|
118
|
+
|
119
|
+
##
|
120
|
+
# Add a line
|
121
|
+
##
|
122
|
+
def add_line(hash = {})
|
123
|
+
hash.delete_if { |k, v| v.nil? }
|
124
|
+
hash = defaults.merge(hash)
|
125
|
+
# fields: length, ampacity, commercial_line_type
|
126
|
+
line = {}
|
127
|
+
line['length'] = hash[:length]
|
128
|
+
line['ampacity'] = hash[:ampacity]
|
129
|
+
line['commercial_line_type'] = hash[:commercial_line_type]
|
130
|
+
|
131
|
+
@distribution_lines << line
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# Add a capacitor
|
136
|
+
##
|
137
|
+
def add_capacitor(hash = {})
|
138
|
+
hash.delete_if { |k, v| v.nil? }
|
139
|
+
hash = defaults.merge(hash)
|
140
|
+
# fields: nominal_capacity
|
141
|
+
cap = {}
|
142
|
+
cap['nominal_capacity'] = hash[:nominal_capacity]
|
143
|
+
cap
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# *********************************************************************************
|
2
|
-
# URBANopt™, Copyright (c) 2019-
|
2
|
+
# URBANopt™, Copyright (c) 2019-2022, Alliance for Sustainable Energy, LLC, and other
|
3
3
|
# contributors. All rights reserved.
|
4
4
|
|
5
5
|
# Redistribution and use in source and binary forms, with or without modification,
|
@@ -46,6 +46,7 @@ require_relative 'reporting_period'
|
|
46
46
|
require_relative 'timeseries_csv'
|
47
47
|
require_relative 'distributed_generation'
|
48
48
|
require_relative 'validator'
|
49
|
+
require_relative 'scenario_power_distribution'
|
49
50
|
|
50
51
|
require 'json'
|
51
52
|
require 'json-schema'
|
@@ -62,7 +63,9 @@ module URBANopt
|
|
62
63
|
class ScenarioReport
|
63
64
|
attr_accessor :id, :name, :directory_name, :timesteps_per_hour, :number_of_not_started_simulations,
|
64
65
|
:number_of_started_simulations, :number_of_complete_simulations, :number_of_failed_simulations,
|
65
|
-
:timeseries_csv, :location, :program, :construction_costs, :reporting_periods, :feature_reports, :distributed_generation
|
66
|
+
:timeseries_csv, :location, :program, :construction_costs, :reporting_periods, :feature_reports, :distributed_generation,
|
67
|
+
:scenario_power_distribution # :nodoc:
|
68
|
+
|
66
69
|
# ScenarioReport class intializes the scenario report attributes:
|
67
70
|
# +:id+ , +:name+ , +:directory_name+, +:timesteps_per_hour+ , +:number_of_not_started_simulations+ ,
|
68
71
|
# +:number_of_started_simulations+ , +:number_of_complete_simulations+ , +:number_of_failed_simulations+ ,
|
@@ -89,10 +92,11 @@ module URBANopt
|
|
89
92
|
@location = Location.new(hash[:location])
|
90
93
|
@program = Program.new(hash[:program])
|
91
94
|
@distributed_generation = DistributedGeneration.new(hash[:distributed_generation] || {})
|
95
|
+
@scenario_power_distribution = ScenarioPowerDistribution.new(hash[:scenario_power_distribution] || {})
|
92
96
|
|
93
97
|
@construction_costs = []
|
94
98
|
hash[:construction_costs].each do |cc|
|
95
|
-
@
|
99
|
+
@construction_costs << ConstructionCost.new(cc)
|
96
100
|
end
|
97
101
|
|
98
102
|
@reporting_periods = []
|
@@ -142,14 +146,14 @@ module URBANopt
|
|
142
146
|
# Gets the saved JSON file path.
|
143
147
|
##
|
144
148
|
def json_path
|
145
|
-
File.join(@directory_name, @file_name
|
149
|
+
File.join(@directory_name, "#{@file_name}.json")
|
146
150
|
end
|
147
151
|
|
148
152
|
##
|
149
153
|
# Gets the saved CSV file path.
|
150
154
|
##
|
151
155
|
def csv_path
|
152
|
-
File.join(@directory_name, @file_name
|
156
|
+
File.join(@directory_name, "#{@file_name}.csv")
|
153
157
|
end
|
154
158
|
|
155
159
|
##
|
@@ -167,7 +171,7 @@ module URBANopt
|
|
167
171
|
old_timeseries_path = @timeseries_csv.path
|
168
172
|
end
|
169
173
|
|
170
|
-
@timeseries_csv.path = File.join(@directory_name, file_name
|
174
|
+
@timeseries_csv.path = File.join(@directory_name, "#{file_name}.csv")
|
171
175
|
@timeseries_csv.save_data
|
172
176
|
|
173
177
|
hash = {}
|
@@ -177,7 +181,7 @@ module URBANopt
|
|
177
181
|
hash[:feature_reports] << feature_report.to_hash
|
178
182
|
end
|
179
183
|
|
180
|
-
json_name_path = File.join(@directory_name, file_name
|
184
|
+
json_name_path = File.join(@directory_name, "#{file_name}.json")
|
181
185
|
|
182
186
|
File.open(json_name_path, 'w') do |f|
|
183
187
|
f.puts JSON.pretty_generate(hash)
|
@@ -192,16 +196,16 @@ module URBANopt
|
|
192
196
|
if !old_timeseries_path.nil?
|
193
197
|
@timeseries_csv.path = old_timeseries_path
|
194
198
|
else
|
195
|
-
@timeseries_csv.path = File.join(@directory_name, file_name
|
199
|
+
@timeseries_csv.path = File.join(@directory_name, "#{file_name}.csv")
|
196
200
|
end
|
197
201
|
|
198
202
|
if save_feature_reports
|
199
203
|
if file_name == 'default_scenario_report'
|
200
204
|
file_name = 'default_feature_report'
|
201
205
|
end
|
202
|
-
#save the feature reports csv and json data
|
206
|
+
# save the feature reports csv and json data
|
203
207
|
@feature_reports.each do |feature_report|
|
204
|
-
|
208
|
+
feature_report.save file_name
|
205
209
|
end
|
206
210
|
end
|
207
211
|
|
@@ -228,6 +232,7 @@ module URBANopt
|
|
228
232
|
result[:location] = @location.to_hash if @location
|
229
233
|
result[:program] = @program.to_hash if @program
|
230
234
|
result[:distributed_generation] = @distributed_generation.to_hash if @distributed_generation
|
235
|
+
result[:scenario_power_distribution] = @scenario_power_distribution.to_hash if @scenario_power_distribution
|
231
236
|
|
232
237
|
result[:construction_costs] = []
|
233
238
|
@construction_costs&.each { |cc| result[:construction_costs] << cc.to_hash }
|
@@ -292,13 +297,14 @@ module URBANopt
|
|
292
297
|
end
|
293
298
|
|
294
299
|
# check feature simulation status
|
295
|
-
|
300
|
+
case feature_report.simulation_status
|
301
|
+
when 'Not Started'
|
296
302
|
@number_of_not_started_simulations += 1
|
297
|
-
|
303
|
+
when 'Started'
|
298
304
|
@number_of_started_simulations += 1
|
299
|
-
|
305
|
+
when 'Complete'
|
300
306
|
@number_of_complete_simulations += 1
|
301
|
-
|
307
|
+
when 'Failed'
|
302
308
|
@number_of_failed_simulations += 1
|
303
309
|
else
|
304
310
|
raise "Unknown feature_report simulation_status = '#{feature_report.simulation_status}'"
|
@@ -50,3 +50,27 @@ Net Power
|
|
50
50
|
Net Apparent Power
|
51
51
|
Ice Thermal Storage End Fraction
|
52
52
|
Cooling Coil Ice Thermal Storage End Fraction
|
53
|
+
Future_Annual_Electricity_Emissions
|
54
|
+
Future_Hourly_Electricity_Emissions
|
55
|
+
Historical_Annual_Electricity_Emissions
|
56
|
+
Historical_Hourly_Electricity_Emissions
|
57
|
+
Future_Annual_Electricity_Emissions_Intensity
|
58
|
+
Future_Hourly_Electricity_Emissions_Intensity
|
59
|
+
Historical_Annual_Electricity_Emissions_Intensity
|
60
|
+
Historical_Hourly_Electricity_Emissions_Intensity
|
61
|
+
Natural_Gas_Emissions
|
62
|
+
Natural_Gas_Emissions_Intensity
|
63
|
+
Propane_Emissions
|
64
|
+
Propane_Emissions_Intensity
|
65
|
+
FuelOilNo2_Emissions
|
66
|
+
FuelOilNo2_Emissions_Intensity
|
67
|
+
Curtailed EV Power
|
68
|
+
Daily EV Charge Energy Capacity
|
69
|
+
EV Charge Ratio
|
70
|
+
Total Charged EV Energy
|
71
|
+
Total Curtailed EV Energy
|
72
|
+
Total Scheduled EV Energy
|
73
|
+
Emission Intensity Schedule Output
|
74
|
+
EV Charging Effective Schedule
|
75
|
+
EV Charging Original Schedule
|
76
|
+
EV Charging Original Load
|