openstudio-extension 0.1.6 → 0.2.0

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
- SHA1:
3
- metadata.gz: 3faa07577e5a2980e7cacc747e5fb9f3ceb5cdb7
4
- data.tar.gz: b4e220c8aca2e0227e65866ded3d1af1b7b19958
2
+ SHA256:
3
+ metadata.gz: 4d0b42ef4c9c5ee88e2e750956e7147ec1971614d9bc46b0f8926332937aabbb
4
+ data.tar.gz: 2177f877389dcc3587c575f361d10d0228269d875c59f22ba7f03bd5fa829d06
5
5
  SHA512:
6
- metadata.gz: 23ec9c229a5618bc27932844884998bb41fac6f57c5753d2d79f2c2702652e37e7836d42e75e9f3c78a2e0321729284fec4a012e80995dee89359f3b7a7fa440
7
- data.tar.gz: da121f8ec77b913ec6d61c528ffb78841ec645dcd0fb7b126df4668f87f3df74e56f7ef8bf9068d6b81b4e02ae4aa17922a9d33abba4fc94a52dc509cae28ff3
6
+ metadata.gz: a6796c88ae5bdd6a269377c4d9845421aa36318f60297dc55bba600f4ebc83143f0ed21fbae5d6ea0c1c05be3363dfdc97f4109866959070fb86dcbe27174dbe
7
+ data.tar.gz: a96dd4fc093da1528f39b4401b0cab6a0ca195877dd979ace7e285fdb83674b19885a901f5df8d18c77a3a37a19f40a4683bbdf82e3181df4e575bb92dec97b5
data/CHANGELOG.md CHANGED
@@ -1,12 +1,11 @@
1
1
  # OpenStudio Extension Gem
2
2
 
3
- ## Version 0.1.6
3
+ ## Version 0.2.0
4
4
 
5
- * Update core library methods with what was in OpenStudio-measures
6
-
7
- ## Version 0.1.5
8
-
9
- * Fix bug to respect the runner.conf file when using Extension::Runner with no options
5
+ * Upgrade Bundler to 2.1.x
6
+ * Restrict to Ruby ~> 2.5.0
7
+ * Remove json_pure gem
8
+ * Update measure tester to 0.2.0 (removes need for github checkout)
10
9
 
11
10
  ## Version 0.1.4
12
11
 
data/Gemfile CHANGED
@@ -2,5 +2,3 @@ source 'http://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in openstudio-extension.gemspec
4
4
  gemspec
5
-
6
- gem 'simplecov', github: 'NREL/simplecov'
data/Jenkinsfile CHANGED
@@ -5,6 +5,6 @@
5
5
  // Build for PR to develop branch only.
6
6
  if ((env.CHANGE_ID) && (env.CHANGE_TARGET) ) { // check if set
7
7
 
8
- openstudio_extension_gems()
8
+ openstudio_extension_gems_3_x()
9
9
 
10
10
  }
data/README.md CHANGED
@@ -150,7 +150,7 @@ Common Rake Tasks that are available to derivative extension gems include:
150
150
  | openstudio:measures:add_readme | Add README.md.erb file if it and the README markdown file do not already exist for a measure |
151
151
  | openstudio:measures:copy_resources | Copy the resources files to individual measures in the calling gem |
152
152
  | openstudio:measures:update_copyright | Update copyright on measure files in the calling gem |
153
- | openstudio`:runner:`init | Create a runner.conf file running simulations |
153
+ | openstudio`:runner:`init | Create a runner.conf file running simulations |
154
154
  | openstudio:stage_bcl | Copy the measures to a location that can be uploaded to BCL |
155
155
  | openstudio:push_bcl | Upload measures from the specified location to the BCL |
156
156
  | openstudio:test_with_docker | Use openstudio docker image to run tests |
@@ -235,11 +235,22 @@ Or install it yourself as:
235
235
 
236
236
  # TODO
237
237
 
238
+ - [X] Finalize documentation on naming conventions, etc
239
+ - [X] Add test measure
240
+ - [X] Rake task ```openstudio:update_measures```
241
+ - [X] Rake task ```openstudio:test_with_openstudio```
238
242
  - [ ] Rake task ```stage_bcl``` _DLM: BCL gem should be a development dependency only until we can reduce its dependencies and remove native dependencies? should probably put it into a special group so we can bundle without it in openstudio-gems._
239
243
  - [ ] Rake task ```push_bcl``` _DLM: how do we want to test this?
244
+ - [X] Get all rake tasks working on Travis
240
245
  - [ ] Capture useful output from Travis (measure dashboard results, log files, zip of build products, etc) and put it somewhere (s3? naming convention?)
246
+ - [X] ```Extension::openstudio_extension_version``` _DLM: should we rename? should people overwrite this in their class?_
247
+ - [X] ```Extension::measures_dir``` _DLM: I think this can have a default implementation, right? If something does not need to be overridden should it be a module method rather than a class one? KAF: this is in rake task for now
248
+ - [X] ```Extension::list_measures``` _DLM: I think this can have a default implementation, right?_KAF: In Rake task for now
241
249
  - [ ] ```Extension::files_dir``` _DLM: I think this can have a default implementation, right?_
242
250
  - [ ] ```Extension::minimum_openstudio_version``` _DLM: should we rename? should people overwrite this in their class?_
251
+ - [X] ```Runner::initialize``` _DLM: should say that the path argument should be for a dir with a Gemfile right?_
252
+ - [X] ```Runner::configure_osw``` _DLM: should take in an OSW, add paths to all measure and file dirs for loaded OpenStudio Extensions, write out configured OSW_
243
253
  - [ ] Run rubocop on all of the core files and remove exclusion from .rubocop.yml file.
244
254
  - [ ] Cleanup task after running tests (may need to be in the OpenStudio Measure Tester)
255
+ - [X] Add a `rake init new_ext_gem` to Rakefile
245
256
  - [ ] Add tests to the extension/core
data/lib/change_log.rb ADDED
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'github_api'
4
+ require 'date'
5
+ require 'optparse'
6
+ require 'optparse/date'
7
+
8
+ # Instructions:
9
+ # Get a token from github's settings (https://github.com/settings/tokens)
10
+ #
11
+ # Example:
12
+ # ruby change_log.rb -t abcdefghijklmnopqrstuvwxyz -s 2017-09-06
13
+ #
14
+
15
+ options = {}
16
+ OptionParser.new do |opts|
17
+ opts.banner = "Usage: change_log.rb [options]\n" +
18
+ "Prints New, Open, Closed Issues, and number of accepted PRs"
19
+ opts.separator ""
20
+
21
+ # defaults, go back 90 days
22
+ options[:start_date] = Date.today - 90
23
+ options[:end_date] = Date.today
24
+
25
+ opts.on('-s', '--start-date [DATE]', Date, 'Start of data (e.g. 2017-09-06)') do |v|
26
+ options[:start_date] = v
27
+ end
28
+ opts.on('-e', '--end-date [DATE]', Date, 'End of data (e.g. 2017-09-13)') do |v|
29
+ options[:end_date] = v
30
+ end
31
+ opts.on('-t', '--token [String]', String, 'Github API Token') do |v|
32
+ options[:token] = v
33
+ end
34
+ end.parse!
35
+
36
+ # Convert dates to time objects
37
+ options[:start_date] = Time.parse(options[:start_date].to_s)
38
+ options[:end_date] = Time.parse(options[:end_date].to_s)
39
+ puts options
40
+
41
+ ### Repository options
42
+ repo_owner = 'NREL'
43
+ repo = 'openstudio-extension-gem'
44
+
45
+ github = Github.new
46
+ if options[:token]
47
+ puts 'Using github token'
48
+ github = Github.new oauth_token: options[:token]
49
+ end
50
+
51
+ total_open_issues = []
52
+ total_open_pull_requests = []
53
+ new_issues = []
54
+ closed_issues = []
55
+ accepted_pull_requests = []
56
+
57
+ def get_num(issue)
58
+ issue.html_url.split('/')[-1].to_i
59
+ end
60
+
61
+ def get_issue_num(issue)
62
+ "\##{get_num(issue)}"
63
+ end
64
+
65
+ def get_html_url(issue)
66
+ issue.html_url
67
+ end
68
+
69
+ def get_title(issue)
70
+ issue.title
71
+ end
72
+
73
+ def print_issue(issue)
74
+ is_feature = false
75
+ issue.labels.each { |label| is_feature = true if label.name == 'Feature Request' }
76
+
77
+ if is_feature
78
+ "- Improved [#{get_issue_num(issue)}]( #{get_html_url(issue)} ), #{get_title(issue)}"
79
+ else
80
+ "- Fixed [#{get_issue_num(issue)}]( #{get_html_url(issue)} ), #{get_title(issue)}"
81
+ end
82
+ end
83
+
84
+ # Process Open Issues
85
+ results = -1
86
+ page = 1
87
+ while results != 0
88
+ resp = github.issues.list user: repo_owner, repo: repo, sort: 'created', direction: 'asc',
89
+ state: 'open', per_page: 100, page: page
90
+ results = resp.length
91
+ resp.env[:body].each do |issue, _index|
92
+ created = Time.parse(issue.created_at)
93
+ if !issue.key?(:pull_request)
94
+ total_open_issues << issue
95
+ if created >= options[:start_date] && created <= options[:end_date]
96
+ new_issues << issue
97
+ end
98
+ else
99
+ total_open_pull_requests << issue
100
+ end
101
+ end
102
+
103
+ page += 1
104
+ end
105
+
106
+ # Process Closed Issues
107
+ results = -1
108
+ page = 1
109
+ while results != 0
110
+ resp = github.issues.list user: repo_owner, repo: repo, sort: 'created', direction: 'asc',
111
+ state: 'closed', per_page: 100, page: page
112
+ results = resp.length
113
+ resp.env[:body].each do |issue, _index|
114
+ created = Time.parse(issue.created_at)
115
+ closed = Time.parse(issue.closed_at)
116
+ if !issue.key?(:pull_request)
117
+ if created >= options[:start_date] && created <= options[:end_date]
118
+ new_issues << issue
119
+ end
120
+ if closed >= options[:start_date] && closed <= options[:end_date]
121
+ closed_issues << issue
122
+ end
123
+ elsif closed >= options[:start_date] && closed <= options[:end_date]
124
+ accepted_pull_requests << issue
125
+ end
126
+ end
127
+
128
+ page += 1
129
+ end
130
+
131
+ closed_issues.sort! { |x, y| get_num(x) <=> get_num(y) }
132
+ new_issues.sort! { |x, y| get_num(x) <=> get_num(y) }
133
+ accepted_pull_requests.sort! { |x, y| get_num(x) <=> get_num(y) }
134
+ total_open_pull_requests.sort! { |x, y| get_num(x) <=> get_num(y) }
135
+
136
+ puts "Total Open Issues: #{total_open_issues.length}"
137
+ puts "Total Open Pull Requests: #{total_open_pull_requests.length}"
138
+ puts "\nDate Range: #{options[:start_date].strftime('%m/%d/%y')} - #{options[:end_date].strftime('%m/%d/%y')}:"
139
+ puts "\nNew Issues: #{new_issues.length} (" + new_issues.map { |issue| get_issue_num(issue) }.join(', ') + ')'
140
+
141
+ puts "\nClosed Issues: #{closed_issues.length}"
142
+ closed_issues.each { |issue| puts print_issue(issue) }
143
+
144
+ puts "\nAccepted Pull Requests: #{accepted_pull_requests.length}"
145
+ accepted_pull_requests.each { |issue| puts print_issue(issue) }
146
+
147
+ puts "\nAll Open Issues: #{total_open_issues.length} (" + total_open_issues.map { |issue| get_issue_num(issue) }.join(', ') + ')'
@@ -45,23 +45,6 @@ module OsLib_CreateResults
45
45
  # @param end_mo [String] the end month for the peak demand window
46
46
  # @param end_day [Integer] the end day for the peak demand window
47
47
  # @param end_hr [Integer] the end hour for the peak demand window, using 24-hr clock
48
- # @param electricity_consumption_tou_periods [Array<Hash>] optional array of hashes to add
49
- # time-of-use electricity consumption values to the annual consumption information.
50
- # Periods may overlap, but should be listed in the order in which they must be checked,
51
- # where the value will be assigned to the first encountered period it falls into.
52
- # An example hash looks like this:
53
- # {
54
- # 'tou_name' => 'system_peak',
55
- # 'tou_id' => 1,
56
- # 'skip_weekends' => true,
57
- # 'skip_holidays' => true,
58
- # 'start_mo' => 'July',
59
- # 'start_day' => 1,
60
- # 'start_hr' => 14,
61
- # 'end_mo' => 'August',
62
- # 'end_day' => 31,
63
- # 'end_hr' => 18
64
- # }
65
48
  # @return [OpenStudio::AttributeVector] a vector of results needed by EDAPT
66
49
  def create_results(skip_weekends = true,
67
50
  skip_holidays = true,
@@ -70,8 +53,7 @@ module OsLib_CreateResults
70
53
  start_hr = 14,
71
54
  end_mo = 'September',
72
55
  end_day = 30,
73
- end_hr = 18,
74
- electricity_consumption_tou_periods = [])
56
+ end_hr = 18)
75
57
 
76
58
  # get the current version of OS being used to determine if sql query
77
59
  # changes are needed (for when E+ changes).
@@ -515,83 +497,6 @@ module OsLib_CreateResults
515
497
  @runner.registerValue('annual_demand_electricity_peak_demand', 0.0, 'kW')
516
498
  end
517
499
 
518
- # Describe the TOU periods
519
- electricity_consumption_tou_periods.each do |tou_pd|
520
- @runner.registerInfo("TOU period #{tou_pd['tou_id']} represents #{tou_pd['tou_name']} and covers #{tou_pd['start_mo']}-#{tou_pd['start_day']} to #{tou_pd['end_mo']}-#{tou_pd['end_day']} from #{tou_pd['start_hr']} to #{tou_pd['end_hr']}, skip weekends = #{tou_pd['skip_weekends']}, skip holidays = #{tou_pd['skip_holidays']}")
521
- end
522
-
523
- # electricity time-of-use periods
524
- elec = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'Electricity:Facility', '')
525
- if elec.is_initialized && day_types
526
- elec = elec.get
527
- # Put timeseries into array
528
- elec_vals = []
529
- ann_elec_vals = elec.values
530
- for i in 0..(ann_elec_vals.size - 1)
531
- elec_vals << ann_elec_vals[i]
532
- end
533
-
534
- # Put values into array
535
- elec_times = []
536
- ann_elec_times = elec.dateTimes
537
- for i in 0..(ann_elec_times.size - 1)
538
- elec_times << ann_elec_times[i]
539
- end
540
-
541
- # Loop through the time/value pairs and find the peak
542
- # excluding the times outside of the Xcel peak demand window
543
- electricity_tou_vals = Hash.new(0)
544
- elec_times.zip(elec_vals).each_with_index do |vs, ind|
545
- date_time = vs[0]
546
- joules = vs[1]
547
- day_type = day_types[ind]
548
- time = date_time.time
549
- date = date_time.date
550
-
551
- # puts("#{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
552
-
553
- # Determine which TOU period this hour falls into
554
- tou_period_assigned = false
555
- electricity_consumption_tou_periods.each do |tou_pd|
556
- pd_start_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['start_mo']), tou_pd['start_day'], timeseries_yr), OpenStudio::Time.new(0, 0, 0, 0))
557
- pd_end_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['end_mo']), tou_pd['end_day'], timeseries_yr), OpenStudio::Time.new(0, 24, 0, 0))
558
- pd_start_time = OpenStudio::Time.new(0, tou_pd['start_hr'], 0, 0)
559
- pd_end_time = OpenStudio::Time.new(0, tou_pd['end_hr'], 0, 0)
560
- # Skip times outside of the correct months
561
- next if date_time < pd_start_date || date_time > pd_end_date
562
- # Skip times before some time and after another time
563
- next if time < pd_start_time || time > pd_end_time
564
- # Skip weekends if asked
565
- if tou_pd['skip_weekends']
566
- # Sunday = 1, Saturday = 7
567
- next if day_type == 1 || day_type == 7
568
- end
569
- # Skip holidays if asked
570
- if tou_pd['skip_holidays']
571
- # Holiday = 8
572
- next if day_type == 8
573
- end
574
- # If here, this hour falls into the specified period
575
- tou_period_assigned = true
576
- electricity_tou_vals[tou_pd['tou_id']] += joules
577
- break
578
- end
579
- # Ensure that the value fell into a period
580
- unless tou_period_assigned
581
- @runner.registerError("Did not find a TOU period covering #{time} on #{date}, kWh will not be included in any TOU period.")
582
- end
583
- end
584
- # Register values for any time-of-use period with kWh
585
- electricity_tou_vals.each do |tou_pd_id, joules_in_pd|
586
- gj_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'GJ').get
587
- kwh_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'kWh').get
588
- @runner.registerValue("annual_consumption_electricity_tou_#{tou_pd_id}", gj_in_pd, 'GJ')
589
- @runner.registerInfo("TOU period #{tou_pd_id} annual electricity consumption = #{kwh_in_pd} kWh.")
590
- end
591
- else
592
- @runner.registerError('Electricity timeseries (Electricity:Facility at zone timestep) could not be found, cannot determine the information needed to calculate savings or incentives.')
593
- end
594
-
595
500
  # electricity_annual_avg_peak_demand
596
501
  val = @sql.electricityTotalEndUses
597
502
  if val.is_initialized
@@ -682,88 +587,6 @@ module OsLib_CreateResults
682
587
  @runner.registerValue('annual_demand_district_cooling_peak_demand', 0.0, 'kW')
683
588
  end
684
589
 
685
- # district cooling time-of-use periods
686
- dist_clg = @sql.timeSeries(ann_env_pd, 'Zone Timestep', 'DistrictCooling:Facility', '')
687
- if dist_clg.is_initialized && day_types
688
- dist_clg = dist_clg.get
689
- # Put timeseries into array
690
- dist_clg_vals = []
691
- ann_dist_clg_vals = dist_clg.values
692
- for i in 0..(ann_dist_clg_vals.size - 1)
693
- dist_clg_vals << ann_dist_clg_vals[i]
694
- end
695
-
696
- # Put values into array
697
- dist_clg_times = []
698
- ann_dist_clg_times = dist_clg.dateTimes
699
- for i in 0..(ann_dist_clg_times.size - 1)
700
- dist_clg_times << ann_dist_clg_times[i]
701
- end
702
-
703
- # Loop through the time/value pairs and find the peak
704
- # excluding the times outside of the Xcel peak demand window
705
- dist_clg_tou_vals = Hash.new(0)
706
- dist_clg_times.zip(dist_clg_vals).each_with_index do |vs, ind|
707
- date_time = vs[0]
708
- joules = vs[1]
709
- day_type = day_types[ind]
710
- time = date_time.time
711
- date = date_time.date
712
-
713
- # puts("#{val_kW}kW; #{date}; #{time}; #{day_of_week.valueName}")
714
-
715
- # Determine which TOU period this hour falls into
716
- tou_period_assigned = false
717
- electricity_consumption_tou_periods.each do |tou_pd|
718
- pd_start_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['start_mo']), tou_pd['start_day'], timeseries_yr), OpenStudio::Time.new(0, 0, 0, 0))
719
- pd_end_date = OpenStudio::DateTime.new(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(tou_pd['end_mo']), tou_pd['end_day'], timeseries_yr), OpenStudio::Time.new(0, 24, 0, 0))
720
- pd_start_time = OpenStudio::Time.new(0, tou_pd['start_hr'], 0, 0)
721
- pd_end_time = OpenStudio::Time.new(0, tou_pd['end_hr'], 0, 0)
722
- # Skip times outside of the correct months
723
- next if date_time < pd_start_date || date_time > pd_end_date
724
- # Skip times before some time and after another time
725
- next if time < pd_start_time || time > pd_end_time
726
- # Skip weekends if asked
727
- if tou_pd['skip_weekends']
728
- # Sunday = 1, Saturday = 7
729
- next if day_type == 1 || day_type == 7
730
- end
731
- # Skip holidays if asked
732
- if tou_pd['skip_holidays']
733
- # Holiday = 8
734
- next if day_type == 8
735
- end
736
- # If here, this hour falls into the specified period
737
- tou_period_assigned = true
738
- dist_clg_tou_vals[tou_pd['tou_id']] += joules
739
- break
740
- end
741
- # Ensure that the value fell into a period
742
- unless tou_period_assigned
743
- @runner.registerError("Did not find a TOU period covering #{time} on #{date}, kWh will not be included in any TOU period.")
744
- end
745
- end
746
- # Register values for any time-of-use period with kWh
747
- dist_clg_tou_vals.each do |tou_pd_id, joules_in_pd|
748
- gj_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'GJ').get
749
- kwh_in_pd = OpenStudio.convert(joules_in_pd, 'J', 'kWh').get
750
- @runner.registerValue("annual_consumption_district_cooling_tou_#{tou_pd_id}", gj_in_pd, 'GJ')
751
- @runner.registerInfo("TOU period #{tou_pd_id} annual district cooling consumption = #{kwh_in_pd} kWh.")
752
- end
753
- else
754
- # If TOU periods were specified but this model has no district cooling, report zeroes
755
- if electricity_consumption_tou_periods.size > 0
756
- # Get the TOU ids
757
- tou_ids = []
758
- electricity_consumption_tou_periods.each do |tou_pd|
759
- tou_ids << tou_pd['tou_id']
760
- end
761
- tou_ids.uniq.each do |tou_id|
762
- @runner.registerValue("annual_consumption_district_cooling_tou_#{tou_id}", 0.0, 'GJ')
763
- end
764
- end
765
- end
766
-
767
590
  else
768
591
  @runner.registerError('Could not find an annual run period')
769
592
  return OpenStudio::Attribute.new('report', result_elems)