smartermeter 0.4.3 → 0.4.4

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 03cc91b45b18c8f1cfeb5058ccfa2092c9ef7a99
4
+ data.tar.gz: 0640d4504f35dc79e9f7d21cd49241cd128722c2
5
+ SHA512:
6
+ metadata.gz: a231a022e37106b9d242779de2df78aa0b912073a1efa0b37f4b35ed6a1ea1e1428c81d20d2ac35b46da8668c292831f7e041029be625471efd7de215593725c
7
+ data.tar.gz: 58240dac95f623ad466f29b7595459bb04afa4522b815d11a5d73e6fa203aeec30d969351e18d638ba4694b92e3094a5939dcfb761ddea3bb09682edb6829aee
data/CHANGELOG.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.4.4 (May 17, 2014)
4
+ * Fixed an issue with downloading data from PG&E.
5
+
3
6
  ## 0.4.3 (August 18, 2012)
4
7
  * Fixed an issue with downloading data from PG&E.
5
8
 
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
  gemspec
3
3
 
4
4
  # Used only in the Java client, which isn't distributed as a gem
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  SmarterMeter - the smarter way to read your PG&E SmartMeter
2
2
  =========================================================
3
3
 
4
+ [![Build Status](https://travis-ci.org/mcolyer/smartermeter.png?branch=master)](https://travis-ci.org/mcolyer/smartermeter)
5
+
4
6
  So I have PG&E SmartMeter and I like playing with data. However I didn't
5
7
  really want to jump through 37 hoops to see the data on PG&E's website.
6
8
  So I made this.
data/lib/smartermeter.rb CHANGED
@@ -7,5 +7,5 @@ require 'smartermeter/services/brighterplanet'
7
7
  require 'smartermeter/interfaces/cli'
8
8
 
9
9
  module SmarterMeter
10
- VERSION = "0.4.3"
10
+ VERSION = "0.4.4"
11
11
  end
@@ -191,7 +191,7 @@ module SmarterMeter
191
191
  f.write(data)
192
192
  end
193
193
 
194
- upload(date, samples[date])
194
+ upload(date, samples.on(date))
195
195
 
196
196
  @ui.log.info("Completed #{date}")
197
197
  completed << date
@@ -5,34 +5,23 @@ require 'nokogiri'
5
5
  module SmarterMeter
6
6
  # Represents a collection of samples. In some cases it's useful to operate on
7
7
  # groups of samples and this class provides that functionality.
8
- class Samples < Hash
8
+ class Samples < Array
9
9
  # Parses the XML returned by PG&E and creates a Samples collection.
10
10
  #
11
11
  # @param [String] data the string containing the XML returned by PG&E
12
12
  # @return [Samples] creates a Samples collection from the given data.
13
13
  def self.parse_espi(data)
14
14
  samples = Samples.new
15
-
16
15
  doc = Nokogiri::HTML(data)
17
16
 
18
17
  doc.xpath("//intervalreading").each do |reading|
19
- # NOTE: This is a hack, the ESPI data seems to be assuming that
20
- # all users live in the Eastern Time Zone. The timestamps
21
- # returned in the ESPI should really be in UTC and not in local
22
- # time. I'm going to assume all PG&E customers are in the
23
- # pacific timezone and since the eastern timezone has the same
24
- # daylight savings time rules then we can use a constant
25
- # difference to correct the problem.
26
- pacific_timezone_correction = 60*60*3
27
-
28
- timestamp = Time.at(reading.xpath("./timeperiod/start").first.content.to_i + pacific_timezone_correction)
29
- value = reading.xpath("./value").first.content.to_i / 900.0
18
+ timestamp = reading.xpath("./timeperiod/start").first.content.to_i
19
+ timestamp = Time.at(timestamp).utc
30
20
 
31
- year = timestamp.year
32
- month = timestamp.month
33
- day = timestamp.day
21
+ value = reading.xpath("./value").first.content.to_i / 900.0
22
+ value = ((value * 100).truncate / 100.0)
34
23
 
35
- (samples[Date.new(year, month, day)] ||= []) << Sample.new(timestamp, value)
24
+ samples << Sample.new(timestamp, value)
36
25
  end
37
26
 
38
27
  samples
@@ -42,20 +31,27 @@ module SmarterMeter
42
31
  #
43
32
  # @return [Float] the sum of kilowatt hours for all samples within this collection. If no samples are found 0 is returned.
44
33
  def total_kwh
45
- self.keys.reduce(0) { |sum, d| sum + total_kwh_on(d) }
34
+ map { |s| s.kwh || 0 }.reduce(:+) || 0
35
+ end
36
+
37
+ # Selects all samples starting from the given time until 24 hours into the future.
38
+ #
39
+ # @param [DateTime] date_time The start date of the samples to include within the total.
40
+ #
41
+ # @return [Samples] a sample collection containing only the selected samples. If none are found, a samples object with no samples is returned.
42
+ def on(date_time)
43
+ start_time = date_time.to_time
44
+ end_time = (date_time + 1).to_time
45
+ Samples.new(select { |s| start_time <= s.time && s.time < end_time })
46
46
  end
47
47
 
48
48
  # Calculates the total number of kilowatt hours
49
49
  #
50
- # @param [Date] date The date of the samples to include within the total.
50
+ # @param [DateTime] date_time The start date of the samples to include within the total.
51
51
  #
52
52
  # @return [Float] the sum of kilowatt hours for samples made of the given day. If none are found 0 is returned.
53
- def total_kwh_on(date)
54
- if self[date]
55
- self[date].reduce(0) { |sum, s| sum + (s.kwh or 0) }
56
- else
57
- 0
58
- end
53
+ def total_kwh_on(date_time)
54
+ on(date_time).total_kwh
59
55
  end
60
56
  end
61
57
  end
@@ -44,7 +44,7 @@ module SmarterMeter
44
44
  end.submit
45
45
  token = saml_page.form_with(:action => SAML_URL).submit
46
46
  usage_page = token.form_with(:action => MY_ENERGY_USE_URL).submit
47
- @data_page = usage_page.link_with(:text => "Green Button").click
47
+ @data_page = usage_page.link_with(:text => "Green Button - Download my data").click
48
48
  end
49
49
  @authenticated = true
50
50
  rescue Exception => e
@@ -23,7 +23,7 @@ module SmarterMeter
23
23
  http.verify_mode = OpenSSL::SSL::VERIFY_PEER
24
24
  http.ca_file = File.join(File.dirname(__FILE__), "cacert.pem")
25
25
  res, body = http.post(url.path, request_body(samples), {"X-PachubeApiKey" => @config[:api_key], "Content-Type" => "text/csv"})
26
- @ui.log.debug("Pacube Response: #{res}")
26
+ @ui.log.debug("Pachube Response: #{res}")
27
27
  case res
28
28
  when Net::HTTPSuccess
29
29
  true
data/smartermeter.gemspec CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
13
13
  ## If your rubyforge_project name is different, then edit it and comment out
14
14
  ## the sub! line in the Rakefile
15
15
  s.name = 'smartermeter'
16
- s.version = '0.4.3'
17
- s.date = '2012-08-18'
16
+ s.version = '0.4.4'
17
+ s.date = '2014-05-17'
18
18
  s.rubyforge_project = 'smartermeter'
19
19
 
20
20
  ## Make sure your summary is short. The description may be as long
@@ -48,19 +48,20 @@ Gem::Specification.new do |s|
48
48
 
49
49
  ## List your runtime dependencies here. Runtime dependencies are those
50
50
  ## that are needed for an end user to actually USE your code.
51
- s.add_dependency('mechanize', ["= 1.0.0"])
52
- s.add_dependency('crypt19', ["= 1.2.1"])
53
- s.add_dependency('rest-client', ["= 1.6.1"])
54
- s.add_dependency('json_pure', ["= 1.5.1"])
55
- s.add_dependency('rubyzip', ["= 0.9.5"])
56
- s.add_dependency('trollop', ["= 1.16.2"])
51
+ s.add_dependency('mechanize', ["= 2.6.0"])
52
+ s.add_dependency('crypt19-rb', ["= 1.3.1"])
53
+ s.add_dependency('rest-client', ["= 1.6.7"])
54
+ s.add_dependency('json_pure', ["= 1.7.7"])
55
+ s.add_dependency('rubyzip', ["= 0.9.9"])
56
+ s.add_dependency('trollop', ["= 2.0"])
57
57
 
58
58
  ## List your development dependencies here. Development dependencies are
59
59
  ## those that are only needed during development
60
- s.add_development_dependency('rspec', ["~> 2.8.0"])
61
- s.add_development_dependency('vcr', ["~> 1.11.3"])
62
- s.add_development_dependency('webmock', ["~> 1.7.10"])
63
- s.add_development_dependency('minitar', ["~> 0.5.2"])
60
+ s.add_development_dependency('rake', ["~> 10.0.0"])
61
+ s.add_development_dependency('rspec', ["~> 2.13.0"])
62
+ s.add_development_dependency('vcr', ["~> 2.4.0"])
63
+ s.add_development_dependency('webmock', ["~> 1.9.0"])
64
+ s.add_development_dependency('minitar', ["~> 0.5.4"])
64
65
 
65
66
  ## Leave this section as-is. It will be automatically generated from the
66
67
  ## contents of your Git repository via the gemspec task. DO NOT REMOVE
metadata CHANGED
@@ -1,176 +1,169 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smartermeter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
5
- prerelease:
4
+ version: 0.4.4
6
5
  platform: ruby
7
6
  authors:
8
7
  - Matt Colyer
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-08-18 00:00:00.000000000 Z
11
+ date: 2014-05-17 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: mechanize
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - '='
20
18
  - !ruby/object:Gem::Version
21
- version: 1.0.0
19
+ version: 2.6.0
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - '='
28
25
  - !ruby/object:Gem::Version
29
- version: 1.0.0
26
+ version: 2.6.0
30
27
  - !ruby/object:Gem::Dependency
31
- name: crypt19
28
+ name: crypt19-rb
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - '='
36
32
  - !ruby/object:Gem::Version
37
- version: 1.2.1
33
+ version: 1.3.1
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - '='
44
39
  - !ruby/object:Gem::Version
45
- version: 1.2.1
40
+ version: 1.3.1
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rest-client
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - '='
52
46
  - !ruby/object:Gem::Version
53
- version: 1.6.1
47
+ version: 1.6.7
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
52
  - - '='
60
53
  - !ruby/object:Gem::Version
61
- version: 1.6.1
54
+ version: 1.6.7
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: json_pure
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
59
  - - '='
68
60
  - !ruby/object:Gem::Version
69
- version: 1.5.1
61
+ version: 1.7.7
70
62
  type: :runtime
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
66
  - - '='
76
67
  - !ruby/object:Gem::Version
77
- version: 1.5.1
68
+ version: 1.7.7
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: rubyzip
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
73
  - - '='
84
74
  - !ruby/object:Gem::Version
85
- version: 0.9.5
75
+ version: 0.9.9
86
76
  type: :runtime
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
80
  - - '='
92
81
  - !ruby/object:Gem::Version
93
- version: 0.9.5
82
+ version: 0.9.9
94
83
  - !ruby/object:Gem::Dependency
95
84
  name: trollop
96
85
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
86
  requirements:
99
87
  - - '='
100
88
  - !ruby/object:Gem::Version
101
- version: 1.16.2
89
+ version: '2.0'
102
90
  type: :runtime
103
91
  prerelease: false
104
92
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
93
  requirements:
107
94
  - - '='
108
95
  - !ruby/object:Gem::Version
109
- version: 1.16.2
96
+ version: '2.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ~>
102
+ - !ruby/object:Gem::Version
103
+ version: 10.0.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ~>
109
+ - !ruby/object:Gem::Version
110
+ version: 10.0.0
110
111
  - !ruby/object:Gem::Dependency
111
112
  name: rspec
112
113
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
114
  requirements:
115
115
  - - ~>
116
116
  - !ruby/object:Gem::Version
117
- version: 2.8.0
117
+ version: 2.13.0
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
121
  requirements:
123
122
  - - ~>
124
123
  - !ruby/object:Gem::Version
125
- version: 2.8.0
124
+ version: 2.13.0
126
125
  - !ruby/object:Gem::Dependency
127
126
  name: vcr
128
127
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
128
  requirements:
131
129
  - - ~>
132
130
  - !ruby/object:Gem::Version
133
- version: 1.11.3
131
+ version: 2.4.0
134
132
  type: :development
135
133
  prerelease: false
136
134
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
135
  requirements:
139
136
  - - ~>
140
137
  - !ruby/object:Gem::Version
141
- version: 1.11.3
138
+ version: 2.4.0
142
139
  - !ruby/object:Gem::Dependency
143
140
  name: webmock
144
141
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
142
  requirements:
147
143
  - - ~>
148
144
  - !ruby/object:Gem::Version
149
- version: 1.7.10
145
+ version: 1.9.0
150
146
  type: :development
151
147
  prerelease: false
152
148
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
149
  requirements:
155
150
  - - ~>
156
151
  - !ruby/object:Gem::Version
157
- version: 1.7.10
152
+ version: 1.9.0
158
153
  - !ruby/object:Gem::Dependency
159
154
  name: minitar
160
155
  requirement: !ruby/object:Gem::Requirement
161
- none: false
162
156
  requirements:
163
157
  - - ~>
164
158
  - !ruby/object:Gem::Version
165
- version: 0.5.2
159
+ version: 0.5.4
166
160
  type: :development
167
161
  prerelease: false
168
162
  version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
163
  requirements:
171
164
  - - ~>
172
165
  - !ruby/object:Gem::Version
173
- version: 0.5.2
166
+ version: 0.5.4
174
167
  description: Fetches SmartMeter data from PG&E and can upload to Pachube
175
168
  email: matt.removethis@nospam.colyer.name
176
169
  executables:
@@ -205,25 +198,24 @@ files:
205
198
  - smartermeter.gemspec
206
199
  homepage: http://github.com/mcolyer/smartermeter
207
200
  licenses: []
201
+ metadata: {}
208
202
  post_install_message:
209
203
  rdoc_options: []
210
204
  require_paths:
211
205
  - lib
212
206
  required_ruby_version: !ruby/object:Gem::Requirement
213
- none: false
214
207
  requirements:
215
- - - ! '>='
208
+ - - '>='
216
209
  - !ruby/object:Gem::Version
217
210
  version: '0'
218
211
  required_rubygems_version: !ruby/object:Gem::Requirement
219
- none: false
220
212
  requirements:
221
- - - ! '>='
213
+ - - '>='
222
214
  - !ruby/object:Gem::Version
223
215
  version: '0'
224
216
  requirements: []
225
217
  rubyforge_project: smartermeter
226
- rubygems_version: 1.8.23
218
+ rubygems_version: 2.0.14
227
219
  signing_key:
228
220
  specification_version: 2
229
221
  summary: Fetches SmartMeter data from PG&E