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 +7 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +1 -1
- data/README.md +2 -0
- data/lib/smartermeter.rb +1 -1
- data/lib/smartermeter/daemon.rb +1 -1
- data/lib/smartermeter/samples.rb +21 -25
- data/lib/smartermeter/service.rb +1 -1
- data/lib/smartermeter/services/pachube.rb +1 -1
- data/smartermeter.gemspec +13 -12
- metadata +41 -49
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
data/Gemfile
CHANGED
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
|
+
[](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
data/lib/smartermeter/daemon.rb
CHANGED
data/lib/smartermeter/samples.rb
CHANGED
@@ -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 <
|
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
|
-
|
20
|
-
|
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
|
-
|
32
|
-
|
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
|
-
|
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
|
-
|
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 [
|
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(
|
54
|
-
|
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
|
data/lib/smartermeter/service.rb
CHANGED
@@ -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("
|
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.
|
17
|
-
s.date = '
|
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', ["=
|
52
|
-
s.add_dependency('crypt19', ["= 1.
|
53
|
-
s.add_dependency('rest-client', ["= 1.6.
|
54
|
-
s.add_dependency('json_pure', ["= 1.
|
55
|
-
s.add_dependency('rubyzip', ["= 0.9.
|
56
|
-
s.add_dependency('trollop', ["=
|
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('
|
61
|
-
s.add_development_dependency('
|
62
|
-
s.add_development_dependency('
|
63
|
-
s.add_development_dependency('
|
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.
|
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:
|
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:
|
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:
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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:
|
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:
|
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.
|
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.
|
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:
|
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:
|
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.
|
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.
|
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.
|
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.
|
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:
|
218
|
+
rubygems_version: 2.0.14
|
227
219
|
signing_key:
|
228
220
|
specification_version: 2
|
229
221
|
summary: Fetches SmartMeter data from PG&E
|