urbanopt-reporting 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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