ce-greenbutton 0.1.2 → 0.1.3
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 +4 -4
- data/README.md +32 -13
- data/lib/ce-greenbutton/elements/gb_application_information.rb +12 -8
- data/lib/ce-greenbutton/elements/gb_content.rb +9 -0
- data/lib/ce-greenbutton/elements/gb_interval.rb +6 -0
- data/lib/ce-greenbutton/elements/gb_interval_block.rb +6 -0
- data/lib/ce-greenbutton/elements/gb_interval_reading.rb +6 -0
- data/lib/ce-greenbutton/elements/gb_local_time_parameters.rb +22 -2
- data/lib/ce-greenbutton/elements/gb_reading_type.rb +8 -0
- data/lib/ce-greenbutton/elements/gb_usage_point.rb +5 -0
- data/lib/ce-greenbutton/interpreters/electricity_interpreter.rb +7 -2
- data/lib/ce-greenbutton/parser.rb +12 -3
- data/lib/ce-greenbutton/version.rb +1 -1
- data/lib/ce-greenbutton.rb +3 -33
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ba4f33d5d5e82159337dce595af28f30ebe75961
|
4
|
+
data.tar.gz: b579aed9fe338345181f20428f0f6bb3ebfad9e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 660404ef29fc51b9bd63ea193e3f8f07d9f9c0cbd5f35c7ef473957f1849f16d2176c25d8d80bfda7c465570d38b833be036e1c02792f506c55691e1cbac6b2d
|
7
|
+
data.tar.gz: 2a63974c5daf497f890d175c9165de4ee9c9ceee3bf0d941df7ea4c8985cd8cacfa855faa89009eda7dc9a1fe62889d3a796050aa80788175ba24d9c19a1d513
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@ The increased size of data by time was a significant factor in designing this mo
|
|
8
8
|
|
9
9
|
### Why SAX and why sax-machine?
|
10
10
|
Unlike [DOM](http://en.wikipedia.org/wiki/Document_Object_Model), SAX need not to load the whole file into memory for parsing. It is an event driven parsing.
|
11
|
-
As we don't need power
|
11
|
+
As we don't need power features of DOM like XPath for example, so SAX is ideal for data size scalability.
|
12
12
|
|
13
13
|
|
14
14
|
The [SAX Machine](https://github.com/pauldix/sax-machine) provides a simple and elegant binding interface that binds xml elements to Ruby objects and properties.
|
@@ -20,14 +20,12 @@ The [SAX Machine](https://github.com/pauldix/sax-machine) provides a simple and
|
|
20
20
|
3. [TomDoc](http://www.rubydoc.info/gems/tomdoc/0.2.5/frames#Installation) is used
|
21
21
|
|
22
22
|
|
23
|
-
|
24
|
-
|
25
23
|
## Installation
|
26
24
|
|
27
25
|
Using [bundler](http://bundler.io/), add this line to your application's Gemfile:
|
28
26
|
|
29
27
|
```ruby
|
30
|
-
gem 'greenbutton'
|
28
|
+
gem 'ce-greenbutton'
|
31
29
|
```
|
32
30
|
|
33
31
|
And then execute:
|
@@ -36,7 +34,7 @@ And then execute:
|
|
36
34
|
|
37
35
|
Or install it yourself as:
|
38
36
|
|
39
|
-
$ gem install greenbutton
|
37
|
+
$ gem install ce-greenbutton
|
40
38
|
|
41
39
|
The parser uses [SAX Machine](https://github.com/pauldix/sax-machine) and will install it as dependency.
|
42
40
|
|
@@ -54,13 +52,27 @@ gb = GreenButton.download_data('your access token', 'http://greenbutton.data.url
|
|
54
52
|
|
55
53
|
The following will download and parse all 2013 data for subscription
|
56
54
|
|
57
|
-
```ruby
|
58
|
-
require 'greenbutton'
|
59
|
-
GreenButton.config(reg_access_token: "your access token",
|
60
|
-
|
61
|
-
gb = GreenButton.download_data('your access token', 'http://greenbutton.data.url'
|
62
|
-
|
63
|
-
|
55
|
+
```ruby
|
56
|
+
require 'ce-greenbutton'
|
57
|
+
GreenButton.config(reg_access_token: "your access token",
|
58
|
+
application_information_url: "http://app_info_url")
|
59
|
+
gb = GreenButton.download_data('your access token', 'http://greenbutton.data.url'
|
60
|
+
Date.new(2013,1,1), Date.new(2013,12,31))
|
61
|
+
|
62
|
+
```
|
63
|
+
The following will download and parse data from FTP
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
require 'ce-greenbutton'
|
67
|
+
GreenButton.config(reg_access_token: "your access token",
|
68
|
+
application_information_url: "http://app_info_url",
|
69
|
+
ftp_host: "your ftp host",
|
70
|
+
ftp_user: "your ftp user name",
|
71
|
+
ftp_password: "your ftp password",
|
72
|
+
ftp_path: "your ftp directory containing data")
|
73
|
+
gb = GreenButton.download_data_ftp('your application id', Time.new(2015,3,19,1,1,1,0), "your utility name")
|
74
|
+
```
|
75
|
+
|
64
76
|
### Notes on usage
|
65
77
|
1. The access token is an OAuth2 access token.
|
66
78
|
2. The GreenButton.config must be called before the first call to download_data
|
@@ -69,11 +81,18 @@ gb = GreenButton.download_data('your access token', 'http://greenbutton.data.url
|
|
69
81
|
* application information url: https://services.greenbuttondata.org:443/DataCustodian/espi/1_1/resource/ApplicationInformation/2
|
70
82
|
* access_token: 688b026c-665f-4994-9139-6b21b13fbeee
|
71
83
|
* data url (resource): https://services.greenbuttondata.org/DataCustodian/espi/1_1/resource/Batch/Subscription/6
|
84
|
+
* ftp_host: us1.hostedftp.com
|
85
|
+
* ftp_user: clearlyenergy
|
86
|
+
* ftp_password: store_clearly
|
87
|
+
* ftp_path : SDGETest
|
88
|
+
* application_id: 10066_CONSUMPTION
|
89
|
+
* utility_name: CLEARLY
|
90
|
+
* time (for ftp): Time.new(2015,3,19,1,1,1,0)
|
72
91
|
|
73
92
|
|
74
93
|
**Note, the call to `config` is mandatory before the first usage of the module.**
|
75
94
|
|
76
|
-
the returning result of the download_data call is an array of GbDataDescription
|
95
|
+
the returning result of the download_data or download_data_ftp call is an array of GbDataDescription
|
77
96
|
and it can be accessed like that.
|
78
97
|
|
79
98
|
```ruby
|
@@ -2,16 +2,20 @@
|
|
2
2
|
require 'sax-machine'
|
3
3
|
module GreenButton
|
4
4
|
module Parser
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
# a sax-machine mapping for the ApplicationInformation structure.
|
6
|
+
#
|
7
|
+
# For example
|
8
|
+
# app_info = GbApplicationInformation.parse(open(application_information.xml))
|
9
|
+
#
|
10
|
+
# Author ahmed.seddiq
|
11
|
+
# Version 1.0
|
12
|
+
class GbApplicationInformation
|
13
13
|
include SAXMachine
|
14
|
+
# Elements with "espi" namespace
|
14
15
|
element :'espi:dataCustodianId', as: :data_custodian_id
|
16
|
+
|
17
|
+
# Elements without namespace
|
18
|
+
element :dataCustodianId, as: :data_custodian_id
|
15
19
|
end
|
16
20
|
end
|
17
21
|
end
|
@@ -17,10 +17,19 @@ module GreenButton
|
|
17
17
|
# Version: 1.0
|
18
18
|
class GbContent
|
19
19
|
include SAXMachine
|
20
|
+
|
21
|
+
# Elements with "espi" namespace
|
20
22
|
element :'espi:UsagePoint', class: GbUsagePoint, as: :usage_point
|
21
23
|
element :'espi:IntervalBlock', class: GbIntervalBlock, as: :interval_block
|
22
24
|
element :'espi:LocalTimeParameters', class: GbLocalTimeParameters, as: :local_time_parameters
|
23
25
|
element :'espi:ReadingType', class: GbReadingType, as: :reading_type
|
26
|
+
|
27
|
+
# Elements without namespace
|
28
|
+
element :UsagePoint, class: GbUsagePoint, as: :usage_point
|
29
|
+
element :IntervalBlock, class: GbIntervalBlock, as: :interval_block
|
30
|
+
element :LocalTimeParameters, class: GbLocalTimeParameters, as: :local_time_parameters
|
31
|
+
element :ReadingType, class: GbReadingType, as: :reading_type
|
32
|
+
|
24
33
|
end
|
25
34
|
end
|
26
35
|
end
|
@@ -13,8 +13,14 @@ module GreenButton
|
|
13
13
|
# Version: 1.0
|
14
14
|
class GbInterval
|
15
15
|
include SAXMachine
|
16
|
+
|
17
|
+
# Elements with "espi" namespace
|
16
18
|
element :'espi:duration', class: Integer, as: :duration
|
17
19
|
element :'espi:start', class: Integer, as: :start
|
20
|
+
|
21
|
+
# Elements without namespace
|
22
|
+
element :duration, class: Integer, as: :duration
|
23
|
+
element :start, class: Integer, as: :start
|
18
24
|
end
|
19
25
|
|
20
26
|
end
|
@@ -16,8 +16,14 @@ module GreenButton
|
|
16
16
|
# Version: 1.0
|
17
17
|
class GbIntervalBlock
|
18
18
|
include SAXMachine
|
19
|
+
|
20
|
+
# Elements with "espi" namespace
|
19
21
|
element :'espi:interval', class: GbInterval, as: :interval
|
20
22
|
elements :'espi:IntervalReading', class: GbIntervalReading, as: :readings
|
23
|
+
|
24
|
+
# Elements without namespace
|
25
|
+
element :interval, class: GbInterval, as: :interval
|
26
|
+
elements :IntervalReading, class: GbIntervalReading, as: :readings
|
21
27
|
end
|
22
28
|
|
23
29
|
end
|
@@ -15,8 +15,14 @@ module GreenButton
|
|
15
15
|
# Version: 1.0
|
16
16
|
class GbIntervalReading < GbInterval
|
17
17
|
include SAXMachine
|
18
|
+
|
19
|
+
# Elements with "espi" namespace
|
18
20
|
element :'espi:value', class: Integer, as: :value
|
19
21
|
element :'espi:cost', class: Integer, as: :cost
|
22
|
+
|
23
|
+
# Elements without namespace
|
24
|
+
element :value, class: Integer, as: :value
|
25
|
+
element :cost, class: Integer, as: :cost
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
@@ -19,7 +19,12 @@ module GreenButton
|
|
19
19
|
|
20
20
|
attr_accessor :dst_start_time
|
21
21
|
attr_accessor :dst_end_time
|
22
|
+
attr_accessor :tz_offset
|
22
23
|
|
24
|
+
# an instance representing the EDT timezone
|
25
|
+
EDT = GbLocalTimeParameters.new(tz_offset: -14400)
|
26
|
+
|
27
|
+
# Elements with "espi" namespace
|
23
28
|
element :'espi:dstEndRule', as: :dst_end_rule do |rule|
|
24
29
|
@dst_end_time = to_time(rule)
|
25
30
|
rule
|
@@ -31,6 +36,19 @@ module GreenButton
|
|
31
36
|
element :'espi:dstOffset', class: Integer, as: :dst_offset
|
32
37
|
element :'espi:tzOffset', class: Integer, as: :tz_offset
|
33
38
|
|
39
|
+
|
40
|
+
# Elements without namespace
|
41
|
+
element :dstEndRule, as: :dst_end_rule do |rule|
|
42
|
+
@dst_end_time = to_time(rule)
|
43
|
+
rule
|
44
|
+
end
|
45
|
+
element :dstStartRule, as: :dst_start_rule do |rule|
|
46
|
+
@dst_start_time = to_time(rule)
|
47
|
+
rule
|
48
|
+
end
|
49
|
+
element :dstOffset, class: Integer, as: :dst_offset
|
50
|
+
element :tzOffset, class: Integer, as: :tz_offset
|
51
|
+
|
34
52
|
# Converts time to local based on the given time configuration.
|
35
53
|
#
|
36
54
|
# The time after applying the rules in the time_config
|
@@ -39,8 +57,10 @@ module GreenButton
|
|
39
57
|
# apply timezone offset
|
40
58
|
time += self.tz_offset
|
41
59
|
# apply dst offset
|
42
|
-
|
43
|
-
|
60
|
+
unless @dst_start_time.nil? or @dst_end_time.nil?
|
61
|
+
if Time.now.between?(@dst_start_time, @dst_end_time)
|
62
|
+
time += self.dst_offset
|
63
|
+
end
|
44
64
|
end
|
45
65
|
Time.at(time)
|
46
66
|
end
|
@@ -14,10 +14,18 @@ module GreenButton
|
|
14
14
|
# Version: 1.0
|
15
15
|
class GbReadingType
|
16
16
|
include SAXMachine
|
17
|
+
|
18
|
+
# Elements with "espi" namespace
|
17
19
|
element :'espi:commodity', class: Integer, as: :commodity
|
18
20
|
element :'espi:currency', class: Integer, as: :currency
|
19
21
|
element :'espi:uom', class: Integer, as: :uom
|
20
22
|
element :'espi:powerOfTenMultiplier', class: Integer, as: :power_of_ten_multiplier
|
23
|
+
|
24
|
+
# Elements without namespace
|
25
|
+
element :commodity, class: Integer, as: :commodity
|
26
|
+
element :currency, class: Integer, as: :currency
|
27
|
+
element :uom, class: Integer, as: :uom
|
28
|
+
element :powerOfTenMultiplier, class: Integer, as: :power_of_ten_multiplier
|
21
29
|
end
|
22
30
|
end
|
23
31
|
end
|
@@ -14,7 +14,12 @@ module GreenButton
|
|
14
14
|
# Version: 1.0
|
15
15
|
class GbUsagePoint
|
16
16
|
include SAXMachine
|
17
|
+
|
18
|
+
# Elements with "espi" namespace
|
17
19
|
element :'espi:kind', class: Integer, as: :kind
|
20
|
+
|
21
|
+
# Elements without namespace
|
22
|
+
element :kind, class: Integer, as: :kind
|
18
23
|
end
|
19
24
|
end
|
20
25
|
end
|
@@ -5,6 +5,7 @@ require 'ce-greenbutton'
|
|
5
5
|
require 'ce-greenbutton/model/gb_data_description'
|
6
6
|
require 'ce-greenbutton/model/gb_data'
|
7
7
|
require 'ce-greenbutton/model/gb_data_reading'
|
8
|
+
require 'ce-greenbutton/elements/gb_local_time_parameters'
|
8
9
|
|
9
10
|
module GreenButton
|
10
11
|
module Interpreters
|
@@ -39,10 +40,14 @@ module GreenButton
|
|
39
40
|
raise GreenButton::InvalidGbDataError, 'Missing MeterReading data' if meter_readings.nil?
|
40
41
|
|
41
42
|
time_config = feed.get_related(usage_point, 'LocalTimeParameters')
|
42
|
-
raise GreenButton::InvalidGbDataError, 'Missing LocalTimeParameters data' if time_config.nil?
|
43
|
+
# raise GreenButton::InvalidGbDataError, 'Missing LocalTimeParameters data' if time_config.nil?
|
43
44
|
|
44
45
|
# get the actual time parameters from the entry.content
|
45
|
-
|
46
|
+
if time_config.nil?
|
47
|
+
time_config = GreenButton::Parser::GbLocalTimeParameters::EDT
|
48
|
+
else
|
49
|
+
time_config = time_config.content.local_time_parameters
|
50
|
+
end
|
46
51
|
|
47
52
|
# We can have multiple meter readings per usage point.
|
48
53
|
unless meter_readings.is_a? Array
|
@@ -31,11 +31,20 @@ module GreenButton
|
|
31
31
|
feed = Parser::GbDataFeed.parse(input)
|
32
32
|
entries = {}
|
33
33
|
feed.entries.each do |entry|
|
34
|
+
# map self link to this entry
|
34
35
|
entries[entry.self] = entry
|
35
|
-
|
36
|
-
|
36
|
+
|
37
|
+
# add this entry to the up link
|
38
|
+
|
39
|
+
# the "up" link will be the "self" link after removing the id part
|
40
|
+
# if there is no id part in the "self" link, the "up" link is used.
|
41
|
+
up_link = /(.*)\/\d+$/.match(entry.self)[1]
|
42
|
+
up_link = entry.up if up_link.nil?
|
43
|
+
|
44
|
+
if entries[up_link].nil?
|
45
|
+
entries[up_link] = []
|
37
46
|
end
|
38
|
-
entries[
|
47
|
+
entries[up_link] << entry
|
39
48
|
entry.link = nil
|
40
49
|
end
|
41
50
|
|
data/lib/ce-greenbutton.rb
CHANGED
@@ -127,39 +127,9 @@ module GreenButton
|
|
127
127
|
ftp_url = "ftp://#{@ftp_user}:#{@ftp_password}@#{@ftp_host}/#{@ftp_path}/" +
|
128
128
|
"D_#{utility_name}_#{application_id}_#{time.strftime('%Y%m%d%H%M%S')}.XML"
|
129
129
|
|
130
|
-
parse_data(
|
130
|
+
parse_data(open(ftp_url))
|
131
131
|
end
|
132
132
|
|
133
|
-
|
134
|
-
def self.parse_file_data(data)
|
135
|
-
feed = GreenButton::Parser.parse(data)
|
136
|
-
gb = []
|
137
|
-
unsupported_kinds = []
|
138
|
-
feed.entries.each_pair do |key, entry|
|
139
|
-
if entry.is_a? GreenButton::Parser::GbEntry
|
140
|
-
if entry.type == 'UsagePoint'
|
141
|
-
usage_point = entry.content.usage_point
|
142
|
-
if @interpreters[usage_point.kind].nil?
|
143
|
-
unsupported_kinds << usage_point.kind
|
144
|
-
else
|
145
|
-
gb_data_description = @interpreters[usage_point.kind]
|
146
|
-
.get_gb_data_description(entry, feed)
|
147
|
-
gb_data_description.custodian = nil
|
148
|
-
gb_data_description.user_id = nil
|
149
|
-
gb << gb_data_description
|
150
|
-
end
|
151
|
-
|
152
|
-
end
|
153
|
-
end
|
154
|
-
end
|
155
|
-
if gb.length == 0 and unsupported_kinds.length > 0
|
156
|
-
raise InvalidGbDataError, "Received unsupported GreenButton data #{unsupported_kinds.to_s}
|
157
|
-
Only Electricity (kind = 0) is supported."
|
158
|
-
end
|
159
|
-
gb
|
160
|
-
end
|
161
|
-
|
162
|
-
|
163
133
|
# Parses the given greenbutton data to the corresponding ruby objects.
|
164
134
|
#
|
165
135
|
# user_id - identifies the owner of the data.
|
@@ -168,7 +138,7 @@ module GreenButton
|
|
168
138
|
#
|
169
139
|
# Returns the parsed array of gb_data_description
|
170
140
|
private
|
171
|
-
def self.parse_data(user_id, data)
|
141
|
+
def self.parse_data(user_id = nil, data)
|
172
142
|
# get ApplicationInformation
|
173
143
|
app_info = GreenButton::Parser::GbApplicationInformation.
|
174
144
|
parse(open(@application_information_url,
|
@@ -187,7 +157,7 @@ module GreenButton
|
|
187
157
|
gb_data_description = @interpreters[usage_point.kind]
|
188
158
|
.get_gb_data_description(entry, feed)
|
189
159
|
gb_data_description.custodian = app_info.data_custodian_id
|
190
|
-
gb_data_description.user_id = user_id
|
160
|
+
gb_data_description.user_id = user_id unless user_id.nil?
|
191
161
|
gb << gb_data_description
|
192
162
|
end
|
193
163
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ce-greenbutton
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- ahmed.seddiq
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-04-
|
11
|
+
date: 2015-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|