urbanopt-reporting 0.1.0 → 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6205d1365f248754c777e239f169baa1afc044feb96395140bb8afb954870edb
4
- data.tar.gz: 25aa3729072d869f6198b9988c9181430aa33cbeea1285b66e9b9e8b89306578
3
+ metadata.gz: eae158ffc7f5239454037c578719bc38263a2991b0597ea1654ff682c875dbf0
4
+ data.tar.gz: 83f93741c0f85426fd02132cc57c245b1f38967f1e4f02712447c8c0ad8e4ca6
5
5
  SHA512:
6
- metadata.gz: 643acfe0c5894ebebcd342d0eaecb5574b09f30899b7276024058fdd8803677fdbae17a1109fd51805d6384da2869101f4b946760b1abb5073b56e52913e0b91
7
- data.tar.gz: 7cdc12b353473ccce4cd1d8547fdd1ae9f90f8f5413818016ed40a44f88b28f1bb282cfcff4fcb2851bdc30db3ffafe95516c83d2c0827de23983f288565fe70
6
+ metadata.gz: ffcc7a5f81d1bc56569a74cfecfc14593125faacede9f5e52256a568392eec8cb0a8e02d0ba2ce4ae3f9d4d52f7d00cf60720f30d7d66b2a8d38dcef898e0cac
7
+ data.tar.gz: 685fcf61b239616865a48b4cdf1f3179f246b07fceeed4be9f240dee44eefba3fac32b4b52afeb564675873a5bef5eb72a60a3b64b411e151b21eb7b5423ba5b
@@ -1,5 +1,12 @@
1
1
  # URBANopt Reporting Gem
2
2
 
3
+ ## Version 0.1.1
4
+
5
+ 08/26/2020
6
+
7
+ - Adding thermal storage reporting
8
+ - Fix paths for reporting and scenario gems split
9
+
3
10
  ## Version 0.1.0
4
11
 
5
12
  08/17/2020
@@ -71,6 +71,11 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
71
71
  feature_type.setDefaultValue('Building')
72
72
  args << feature_type
73
73
 
74
+ feature_location = OpenStudio::Measure::OSArgument.makeStringArgument('feature_location', false)
75
+ feature_location.setDisplayName('URBANopt Feature Location')
76
+ feature_location.setDefaultValue('0')
77
+ args << feature_location
78
+
74
79
  # make an argument for the frequency
75
80
  reporting_frequency_chs = OpenStudio::StringVector.new
76
81
  reporting_frequency_chs << 'Detailed'
@@ -193,6 +198,9 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
193
198
  'District Heating Inlet Temperature', 'District Heating Outlet Temperature', 'Cooling Coil Total Cooling Rate',
194
199
  'Heating Coil Heating Rate']
195
200
 
201
+ tes_timeseries_data = ['Ice Thermal Storage End Fraction', 'Cooling coil Ice Thermal Storage End Fraction']
202
+ timeseries_data += tes_timeseries_data
203
+
196
204
  timeseries_data.each do |ts|
197
205
  result << OpenStudio::IdfObject.load("Output:Variable,*,#{ts},#{reporting_frequency};").get
198
206
  end
@@ -254,6 +262,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
254
262
  feature_id = runner.getStringArgumentValue('feature_id', user_arguments)
255
263
  feature_name = runner.getStringArgumentValue('feature_name', user_arguments)
256
264
  feature_type = runner.getStringArgumentValue('feature_type', user_arguments)
265
+ feature_location = runner.getStringArgumentValue('feature_location', user_arguments)
257
266
 
258
267
  # Assign the user inputs to variables
259
268
  reporting_frequency = runner.getStringArgumentValue('reporting_frequency', user_arguments)
@@ -318,13 +327,16 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
318
327
  # Get Location information and store in the feature_report
319
328
  ##
320
329
 
321
- # latitude
322
- latitude = epw_file.latitude
323
- feature_report.location.latitude = latitude
324
-
325
- # longitude
326
- longitude = epw_file.longitude
327
- feature_report.location.longitude = longitude
330
+ if feature_location.include? '['
331
+ # get latitude from feature_location
332
+ latitude = (feature_location.split(',')[0].delete! '[]').to_f
333
+ # get longitude from feature_location
334
+ longitude = (feature_location.split(',')[1].delete! '[]').to_f
335
+ # latitude
336
+ feature_report.location.latitude = latitude
337
+ # longitude
338
+ feature_report.location.longitude = longitude
339
+ end
328
340
 
329
341
  # surface_elevation
330
342
  elev = sql_query(runner, sql_file, 'InputVerificationandResultsSummary', "TableName='General' AND RowName='Elevation' AND ColumnName='Value'")
@@ -332,6 +344,7 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
332
344
 
333
345
  ##########################################################################
334
346
  ##
347
+
335
348
  # Get program information and store in the feature_report
336
349
  ##
337
350
 
@@ -475,6 +488,39 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
475
488
  total_construction_cost = sql_query(runner, sql_file, 'Life-Cycle Cost Report', "TableName='Present Value for Recurring, Nonrecurring and Energy Costs (Before Tax)' AND RowName='LCC_MAT - BUILDING - LIFE CYCLE COSTS' AND ColumnName='Cost'")
476
489
  feature_report.program.total_construction_cost = total_construction_cost
477
490
 
491
+ # packaged thermal storage capacities by cooling coil
492
+ ptes_keys = sql_file.availableKeyValues('RUN Period 1', 'Zone Timestep', 'Cooling Coil Ice Thermal Storage End Fraction')
493
+ if ptes_keys.empty?
494
+ ptes_size = nil
495
+ runner.registerWarning('Query failed for Packaged Ice Thermal Storage Capacity')
496
+ else
497
+ begin
498
+ ptes_size = 0
499
+ ptes_keys.each do |pk|
500
+ ptes_size += sql_query(runner, sql_file, 'ComponentSizingSummary', "TableName='Coil:Cooling:DX:SingleSpeed:ThermalStorage' AND RowName='#{pk}' AND ColumnName='Ice Storage Capacity'").to_f
501
+ end
502
+ ptes_size = convert_units(ptes_size, 'GJ', 'kWh')
503
+ rescue StandardError
504
+ runner.registerWarning('Query ptes_size.get failed')
505
+ end
506
+ end
507
+ feature_report.thermal_storage.ptes_size = ptes_size
508
+
509
+ # get the central tank thermal storage capacity
510
+ its_size = nil
511
+ its_size_index = sql_file.execAndReturnFirstDouble("SELECT ReportVariableDataDictionaryIndex FROM ReportVariableDataDictionary WHERE VariableName='Ice Thermal Storage Capacity'")
512
+ if its_size_index.empty?
513
+ runner.registerWarning('Query failed for Ice Thermal Storage Capacity')
514
+ else
515
+ begin
516
+ its_size = sql_file.execAndReturnFirstDouble("SELECT VariableValue FROM ReportVariableData WHERE ReportVariableDataDictionaryIndex=#{its_size_index}").get
517
+ its_size = convert_units(its_size.to_f, 'GJ', 'kWh')
518
+ rescue StandardError
519
+ runner.registerWarning('Query its_size.get failed')
520
+ end
521
+ end
522
+ feature_report.thermal_storage.its_size = its_size
523
+
478
524
  ############################################################################
479
525
  ##
480
526
  # Get Reporting Periods information and store in the feature_report
@@ -669,6 +715,10 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
669
715
  powerTimeseries = ['Net Electric Energy', 'Electricity:Facility Power', 'ElectricityProduced:Facility Power', 'Electricity:Facility Apparent Power', 'ElectricityProduced:Facility Apparent Power', 'Net Power', 'Net Apparent Power']
670
716
  requested_timeseries_names += powerTimeseries
671
717
 
718
+ # add additional thermal storage timeseries
719
+ tesTimeseries = ['Ice Thermal Storage End Fraction', 'Cooling Coil Ice Thermal Storage End Fraction']
720
+ requested_timeseries_names += tesTimeseries
721
+
672
722
  # register info all timeseries
673
723
  runner.registerInfo("All timeseries: #{requested_timeseries_names}")
674
724
 
@@ -870,6 +920,22 @@ class DefaultFeatureReports < OpenStudio::Measure::ReportingMeasure
870
920
  # puts "units = #{new_unit}"
871
921
  # end
872
922
 
923
+ # thermal storage ice end fractions have multiple timeseries, aggregate into a single series with consistent name and use the average value at each timestep
924
+ if tesTimeseries.include? timeseries_name
925
+
926
+ # set up array if 1st key_value
927
+ if key_i == 0
928
+ runner.registerInfo("SETTING UP NEW ARRAY FOR: #{timeseries_name}")
929
+ tmpArray = Array.new(n, 1)
930
+ end
931
+
932
+ # add to array (keep min value at each timestep)
933
+ (0..(n - 1)).each do |ind|
934
+ tVal = values[key_cnt][ind].to_f
935
+ tmpArray[ind] = [tVal, tmpArray[ind]].min
936
+ end
937
+ end
938
+
873
939
  # comfort results usually have multiple timeseries (per zone), aggregate into a single series with consistent name and use worst value at each timestep
874
940
  if comfortTimeseries.include? timeseries_name
875
941
 
@@ -36,6 +36,7 @@ require_relative 'timeseries_csv'
36
36
  require_relative 'distributed_generation'
37
37
  require_relative 'power_distribution'
38
38
  require_relative 'validator'
39
+ require_relative 'thermal_storage'
39
40
 
40
41
  require 'json-schema'
41
42
  require 'json'
@@ -52,7 +53,7 @@ module URBANopt
52
53
  ##
53
54
  class FeatureReport
54
55
  attr_accessor :id, :name, :directory_name, :feature_type, :timesteps_per_hour, :simulation_status,
55
- :timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation, :power_distribution # :nodoc:
56
+ :timeseries_csv, :location, :program, :design_parameters, :construction_costs, :reporting_periods, :distributed_generation, :power_distribution, :thermal_storage # :nodoc:
56
57
  ##
57
58
  # Each FeatureReport object corresponds to a single Feature.
58
59
  ##
@@ -88,6 +89,8 @@ module URBANopt
88
89
 
89
90
  @power_distribution = PowerDistribution.new(hash[:power_distribution])
90
91
 
92
+ @thermal_storage = ThermalStorage.new(hash[:thermal_storage])
93
+
91
94
  # initialize class variables @@validator and @@schema
92
95
  @@validator ||= Validator.new
93
96
  @@schema ||= @@validator.schema
@@ -108,6 +111,7 @@ module URBANopt
108
111
  hash[:reporting_periods] = []
109
112
  hash[:distributed_generation] = {}
110
113
  hash[:power_distribution] = {}
114
+ hash[:thermal_storage] = {}
111
115
  return hash
112
116
  end
113
117
 
@@ -209,6 +213,8 @@ module URBANopt
209
213
 
210
214
  result[:power_distribution] = @power_distribution.to_hash if @power_distribution
211
215
 
216
+ result[:thermal_storage] = @thermal_storage.to_hash if @thermal_storage
217
+
212
218
  # validate feature_report properties against schema
213
219
  if @@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result).any?
214
220
  raise "feature_report properties does not match schema: #{@@validator.validate(@@schema[:definitions][:FeatureReport][:properties], result)}"
@@ -31,4 +31,6 @@ ElectricityProduced:Facility Power
31
31
  Electricity:Facility Apparent Power
32
32
  ElectricityProduced:Facility Apparent Power
33
33
  Net Power
34
- Net Apparent Power
34
+ Net Apparent Power
35
+ Ice Thermal Storage End Fraction
36
+ Cooling Coil Ice Thermal Storage End Fraction
@@ -63,6 +63,9 @@
63
63
  },
64
64
  "distributed_generation": {
65
65
  "$ref": "#/definitions/DistributedGeneration"
66
+ },
67
+ "thermal_storage": {
68
+ "$ref": "#/definitions/ThermalStorage"
66
69
  }
67
70
  },
68
71
  "required": [
@@ -216,6 +219,9 @@
216
219
  },
217
220
  "power_distribution": {
218
221
  "$ref": "#/definitions/PowerDistribution"
222
+ },
223
+ "thermal_storage": {
224
+ "$ref": "#/definitions/ThermalStorage"
219
225
  }
220
226
  },
221
227
  "required": [
@@ -541,11 +547,11 @@
541
547
  "type": "object",
542
548
  "properties": {
543
549
  "latitude": {
544
- "description": "(deg)",
550
+ "description": "latitude for the centroid of the feature (deg)",
545
551
  "type": "number"
546
552
  },
547
553
  "longitude": {
548
- "description": "(deg)",
554
+ "description": "longitude for the centroid of the feature (deg)",
549
555
  "type": "number"
550
556
  },
551
557
  "surface_elevation": {
@@ -852,6 +858,19 @@
852
858
  "type": "number"
853
859
  }
854
860
  }
861
+ },
862
+ "ThermalStorage": {
863
+ "type": "object",
864
+ "properties": {
865
+ "its_size": {
866
+ "description": "Total central plant TES capacity in kWh",
867
+ "type": "number"
868
+ },
869
+ "ptes_size": {
870
+ "description": "Total distributed/packaged TES capacity in kWh",
871
+ "type": "number"
872
+ }
873
+ }
855
874
  }
856
875
  }
857
- }
876
+ }
@@ -0,0 +1,111 @@
1
+ # *********************************************************************************
2
+ # URBANopt, Copyright (c) 2019-2020, 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
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
+ # IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
23
+ # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24
+ # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26
+ # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
+ # OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28
+ # OF THE POSSIBILITY OF SUCH DAMAGE.
29
+ # *********************************************************************************
30
+
31
+ require 'json'
32
+ require 'urbanopt/reporting/default_reports/validator'
33
+ require 'json-schema'
34
+
35
+ module URBANopt
36
+ module Reporting
37
+ module DefaultReports
38
+ ##
39
+ # Ice Thermal Storage Systems
40
+ ##
41
+ class ThermalStorage
42
+ ##
43
+ # _Float_ - Total ice storage capacity on central plant loop in kWh
44
+ #
45
+ attr_accessor :its_size
46
+
47
+ # _Float_ - Total ice storage capacity distributed to packaged systems in kWh
48
+ #
49
+ attr_accessor :ptes_size
50
+
51
+ def initialize(hash = {})
52
+ hash.delete_if { |k, v| v.nil? }
53
+
54
+ @its_size = hash[:its_size]
55
+ @ptes_size = hash[:ptes_size]
56
+
57
+ # initialize class variables @@validator and @@schema
58
+ @@validator ||= Validator.new
59
+ @@schema ||= @@validator.schema
60
+
61
+ # initialize @@logger
62
+ @@logger ||= URBANopt::Reporting::DefaultReports.logger
63
+ end
64
+
65
+ ##
66
+ # Assigns default values if attribute values do not exist.
67
+ ##
68
+ def defaults
69
+ hash = {}
70
+ hash[:its_size] = nil
71
+ hash[:ptes_size] = nil
72
+
73
+ return hash
74
+ end
75
+
76
+ ##
77
+ # Convert to hash equivalent for JSON serialization
78
+ ##
79
+ def to_hash
80
+ result = {}
81
+ result[:its_size] = @its_size if @its_size
82
+ result[:ptes_size] = @ptes_size if @ptes_size
83
+
84
+ return result
85
+ end
86
+
87
+ ##
88
+ # Add up old and new values
89
+ ##
90
+ def self.add_values(existing_value, new_value) #:nodoc:
91
+ if existing_value && new_value
92
+ existing_value += new_value
93
+ elsif new_value
94
+ existing_value = new_value
95
+ end
96
+ return existing_value
97
+ end
98
+
99
+ ##
100
+ # Merge thermal storage
101
+ ##
102
+ def self.merge_thermal_storage(existing_tes, new_tes)
103
+ existing_tes.its_size = add_values(existing_tes.its_size, new_tes.its_size)
104
+ existing_tes.ptes_size = add_values(existing_tes.ptes_size, new_tes.ptes_size)
105
+
106
+ return existing_tes
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
@@ -30,6 +30,6 @@
30
30
 
31
31
  module URBANopt
32
32
  module Reporting
33
- VERSION = '0.1.0'.freeze
33
+ VERSION = '0.1.1'.freeze
34
34
  end
35
35
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: urbanopt-reporting
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rawad El Kontar
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2020-08-18 00:00:00.000000000 Z
12
+ date: 2020-08-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -144,6 +144,7 @@ files:
144
144
  - lib/urbanopt/reporting/default_reports/schema/scenario_schema.json
145
145
  - lib/urbanopt/reporting/default_reports/solar_pv.rb
146
146
  - lib/urbanopt/reporting/default_reports/storage.rb
147
+ - lib/urbanopt/reporting/default_reports/thermal_storage.rb
147
148
  - lib/urbanopt/reporting/default_reports/timeseries_csv.rb
148
149
  - lib/urbanopt/reporting/default_reports/validator.rb
149
150
  - lib/urbanopt/reporting/default_reports/wind.rb
@@ -168,8 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
168
169
  - !ruby/object:Gem::Version
169
170
  version: '0'
170
171
  requirements: []
171
- rubyforge_project:
172
- rubygems_version: 2.7.6
172
+ rubygems_version: 3.1.4
173
173
  signing_key:
174
174
  specification_version: 4
175
175
  summary: Library to report URBANopt results