ce-greenbutton 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b411fe5d5b0acdab84cbf12802c81c41925f4003
4
+ data.tar.gz: 90fedbb838bf0ff0afad023f0b9adba288c23728
5
+ SHA512:
6
+ metadata.gz: 067ceefd90b3d862db54711d73206119a024cbdb19225bfc956a35ba1ae5aca10f8c7e068119002412d02eff8fc02121d022dc661a878db4ee92bfa3a7442790
7
+ data.tar.gz: 9a010716a45917e24cc70900bb040ff0a3b2f14b40dc26d9e57470e2c1ac2e6554935ae7e961d9dfe8e53c730e710d8b462346083b42ef0cc005b3db3b162a5b
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in greenbutton.gemspec
4
+ gemspec
5
+ gem 'simplecov', :require => false, :group => :test
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 TODO: Write your name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,162 @@
1
+ # Overview
2
+ GreenButton gem is a Ruby wrapper for the [Green Button](http://www.greenbuttondata.org) Data. It allows third-party applications to retrieve the GreenButton data in the form of handy Ruby objects hiding the details of the XML representation and parsing.
3
+
4
+ ## About the module
5
+ The GreenButton gem is designed for extendability and scalability. It provides a framework for processing the GreenButton data. It currently supports only the electricity consumption data, but plugins can be easily adapted to support new kinds of data.
6
+
7
+ The increased size of data by time was a significant factor in designing this module. To support this expected size of data, the [SAX parsing technique] is leveraged in this module.
8
+
9
+ ### Why SAX and why sax-machine?
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 featchers of DOM like XPath for example, so SAX is ideal for data size scalability.
12
+
13
+
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.
15
+
16
+ ## Setup Prerequisites
17
+ 1. [Latest Ruby SDK] (https://www.ruby-lang.org/en/)
18
+ [bundler](http://bundler.io/) is used to build and manage dependency.
19
+ 2. [bundler](http://bundler.io/) is used to build and manage dependency.
20
+ 3. [TomDoc](http://www.rubydoc.info/gems/tomdoc/0.2.5/frames#Installation) is used
21
+
22
+
23
+
24
+
25
+ ## Installation
26
+
27
+ Using [bundler](http://bundler.io/), add this line to your application's Gemfile:
28
+
29
+ ```ruby
30
+ gem 'greenbutton'
31
+ ```
32
+
33
+ And then execute:
34
+
35
+ $ bundle
36
+
37
+ Or install it yourself as:
38
+
39
+ $ gem install greenbutton
40
+
41
+ The parser uses [SAX Machine](https://github.com/pauldix/sax-machine) and will install it as dependency.
42
+
43
+ ## Usage
44
+ A typical scenario of the module usage will be like this
45
+
46
+ The following will download and parse all data for subscription
47
+
48
+ ```ruby
49
+ require 'greenbutton'
50
+ GreenButton.config(reg_access_token: "your access token",
51
+ application_information_url: "http://app_info_url")
52
+ gb = GreenButton.download_data('your access token', 'http://greenbutton.data.url')
53
+ ```
54
+
55
+ The following will download and parse all 2013 data for subscription
56
+
57
+ ```ruby
58
+ require 'greenbutton'
59
+ GreenButton.config(reg_access_token: "your access token",
60
+ application_information_url: "http://app_info_url")
61
+ gb = GreenButton.download_data('your access token', 'http://greenbutton.data.url'
62
+ Date.new(2013,1,1), Date.new(2013,12,31))
63
+ ```
64
+ ### Notes on usage
65
+ 1. The access token is an OAuth2 access token.
66
+ 2. The GreenButton.config must be called before the first call to download_data
67
+ 3. You can test real data with the following values
68
+ * registration access token: d89bb056-0f02-4d47-9fd2-ec6a19ba8d0c
69
+ * application information url: https://services.greenbuttondata.org:443/DataCustodian/espi/1_1/resource/ApplicationInformation/2
70
+ * access_token: 688b026c-665f-4994-9139-6b21b13fbeee
71
+ * data url (resource): https://services.greenbuttondata.org/DataCustodian/espi/1_1/resource/Batch/Subscription/6
72
+
73
+
74
+ **Note, the call to `config` is mandatory before the first usage of the module.**
75
+
76
+ the returning result of the download_data call is an array of GbDataDescription
77
+ and it can be accessed like that.
78
+
79
+ ```ruby
80
+ gb_data_descriptions.each do |gb_data_desc|
81
+ gb_data = gb_data_desc.gb_data_array.first
82
+ gb_data_reading = gb_data.interval_readings.first
83
+ puts gb_data_reading.cost
84
+ end
85
+ ```
86
+
87
+
88
+ ## Limitations
89
+ 1. Only the electricity consumption data is supported.
90
+ 2. Only required data is extracted from the XML. For full list of required data,
91
+ check the `GbDataDescription`, `GbData` and `GbDataReading` classes in the
92
+ `model` directory.
93
+
94
+ ## Extending Notes
95
+ The module is designed to ease extension in the following paths
96
+
97
+ 1. Extract more information: that will be done by adding more elements to the
98
+ parser in "greenbutton/elements"
99
+ 2. Support more interpreters for different GreenButton data (like 'gas' for
100
+ example). This will be done by adding the interpreter implementation in the
101
+ "greenbutton/interpreters" directory.
102
+
103
+ ### Supporting new kind of GreenButton data
104
+ 1. Implement the new interpreter. Name the file as <service kind name>_interpreter.rb and put it in the interpreters folder.
105
+ **NOTE that this is very important as without this naming convention, the module may not be loaded as expected.**
106
+ 2. Take the provided electricity_interpreter as a guide for the expected data.
107
+ 3. It is preferred to use the following names for the different data kinds.
108
+ Using those names will make the interpreter loaded automatically.
109
+
110
+ ```ruby
111
+ SERVICEKIND_NAMES = {
112
+ 0 => 'electricity',
113
+ 1 => 'gas',
114
+ 2 => 'water',
115
+ 3 => 'time',
116
+ 4 => 'heat',
117
+ 5 => 'refuse',
118
+ 6 => 'sewerage',
119
+ 7 => 'rates',
120
+ 8 => 'tvLicence',
121
+ 9 => 'internet'
122
+ }
123
+ ```
124
+ ## Code Documentation
125
+ [TomDoc Notation](http://tomdoc.org/) was used to document code in this gem.
126
+
127
+ ### TomDoc generation
128
+ To generate the docs:
129
+
130
+ * The latest development version of the [TomDoc tool](https://github.com/defunkt/tomdoc) should be used as the published version seems to be out-dated. Refer to [TomDoc Local Development] (https://github.com/defunkt/tomdoc#local-dev) for instructions.
131
+ * Use the console format (default), the HTML generator will not detect all docs.
132
+ * To generate the console docs, just issue the following command for each file
133
+
134
+ $ruby -rubygems /path/to/cloned/tomdoc/bin/tomdoc /path/to/tomdoced/code.rb
135
+
136
+ ## Test
137
+ ### Local data
138
+ Run a local web server on port 8123 and serve files under the `test_files` directory.
139
+ Using [NodeJS] (www.nodejs.org)
140
+
141
+ $ npm install http-server -g
142
+ $ cd test_files
143
+ $ http-server -p 8123
144
+ **Note** You may need admin (root) privilege to install node/http-server
145
+
146
+ From the base directory of the module (the directory containing the .gemspec file.
147
+
148
+ $ bundle install
149
+ $ bundle exec rspec
150
+
151
+ Coverage reports will be found under the `coverage` subfolder.
152
+
153
+ ## GreenButton API reference
154
+ - [Green Button Home](http://www.greenbuttondata.org)
155
+ - [Green Button API sandbox](http://energyos.github.io/OpenESPI-GreenButton-API-Documentation/API/)
156
+ - [GReen Button Concept overview](http://www.greenbuttondata.org/developers/)
157
+
158
+
159
+ ### Reference this Ruby Gem Documentation
160
+ `tomdoc` was used to generate documentation files for this gem. The generated files are included in `docs` directory.
161
+
162
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,17 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+ require 'sax-machine'
3
+ module GreenButton
4
+ module Parser
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
+ include SAXMachine
14
+ element :'espi:dataCustodianId', as: :data_custodian_id
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+ require 'sax-machine'
3
+ require 'ce-greenbutton/elements/gb_interval_block'
4
+ require 'ce-greenbutton/elements/gb_usage_point'
5
+ require 'ce-greenbutton/elements/gb_local_time_parameters'
6
+ require 'ce-greenbutton/elements/gb_reading_type'
7
+
8
+ module GreenButton
9
+ module Parser
10
+ # a sax-machine mapping for the Content structure
11
+ #
12
+ # For example:
13
+ # content = GbContent.parse(open(content.xml))
14
+ #
15
+ #
16
+ # Author: ahmed.seddiq
17
+ # Version: 1.0
18
+ class GbContent
19
+ include SAXMachine
20
+ element :'espi:UsagePoint', class: GbUsagePoint, as: :usage_point
21
+ element :'espi:IntervalBlock', class: GbIntervalBlock, as: :interval_block
22
+ element :'espi:LocalTimeParameters', class: GbLocalTimeParameters, as: :local_time_parameters
23
+ element :'espi:ReadingType', class: GbReadingType, as: :reading_type
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,34 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+ require 'sax-machine'
3
+ require 'ce-greenbutton/elements/gb_entry'
4
+
5
+ module GreenButton
6
+ module Parser
7
+ # a sax-machine mapping for the espi:DataFeed structure
8
+ #
9
+ # For example:
10
+ # data_feed = GbDataFeed.parse(open(data_feed.xml))
11
+ #
12
+ #
13
+ # Author: ahmed.seddiq
14
+ # Version: 1.0
15
+ class GbDataFeed
16
+ include SAXMachine
17
+ elements :entry, class: GbEntry, as: :entries
18
+
19
+ # Get the related entry to the given entry of the given type
20
+ #
21
+ # entry - the parent entry.
22
+ # type - the type of the required entry,e.g. 'MeterReading'
23
+ #
24
+ # Note: This method should be only called on instances returned from Parser.parse
25
+ # method.
26
+ #
27
+ # Returns the related GbEntry
28
+ def get_related (entry, type)
29
+ related_entry_key = entry.related[type] unless entry.related.nil?
30
+ self.entries[related_entry_key]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,68 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+ require 'sax-machine'
3
+ require 'ce-greenbutton/elements/gb_content'
4
+ module GreenButton
5
+ module Parser
6
+ # a sax-machine mapping for the Entry structure
7
+ #
8
+ # For example:
9
+ # entry = GbEntry.parse(open(entry.xml))
10
+ #
11
+ #
12
+ # Author: ahmed.seddiq
13
+ # Version: 1.0
14
+ class GbEntry
15
+ include SAXMachine
16
+
17
+ # The related entries. It is a hash {entry_type => entry_url}
18
+ # entry_urls are the href value of the link element with type "related"
19
+ attr_accessor :related
20
+
21
+ # The entry type, e.g. UsagePoint, IntervalBlock,...etc
22
+ attr_accessor :type
23
+
24
+ # Extract the href of the parent Entry
25
+ element :link, as: :up, value: :href, with: {rel: 'up'}
26
+
27
+ # Extract the href of this Entry
28
+ # The type is inferred from this href
29
+ element :link, as: :self, value: :href, with: {rel: 'self'} do |url|
30
+ self.type = entry_type url
31
+ url
32
+ end
33
+
34
+ # Extract the related Entries to the :related hash.
35
+ elements :link, value: :href, with: {rel: 'related'} do |url|
36
+ if self.related.nil?
37
+ self.related = {}
38
+ end
39
+ type = entry_type url
40
+ unless type.nil?
41
+ self.related[type] = url
42
+ end
43
+ end
44
+
45
+ element :content, class: GbContent
46
+
47
+ element :updated do |updated|
48
+ DateTime.parse(updated).to_time
49
+ end
50
+
51
+ # Helper method to infer the entry type from the given url.
52
+ #
53
+ # url - the url
54
+ #
55
+ # Returns the entry type, e.g. UsagePoint, IntervalBlock,...etc
56
+ private
57
+ def entry_type(url)
58
+ match = /\/(\w+)(\/(\d+))*$/.match(url)
59
+ if match.nil?
60
+ nil
61
+ else
62
+ match[1]
63
+ end
64
+ end
65
+
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,21 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+ require 'sax-machine'
3
+
4
+ module GreenButton
5
+ module Parser
6
+ # a sax-machine mapping for the espi:Interval structure
7
+ #
8
+ # For example:
9
+ # interval = GbInterval.parse(open(interval.xml))
10
+ #
11
+ #
12
+ # Author: ahmed.seddiq
13
+ # Version: 1.0
14
+ class GbInterval
15
+ include SAXMachine
16
+ element :'espi:duration', class: Integer, as: :duration
17
+ element :'espi:start', class: Integer, as: :start
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,24 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+
3
+ require 'sax-machine'
4
+ require 'ce-greenbutton/elements/gb_interval'
5
+ require 'ce-greenbutton/elements/gb_interval_reading'
6
+
7
+ module GreenButton
8
+ module Parser
9
+ # a sax-machine mapping for the espi:IntervalBlock structure
10
+ #
11
+ # For example:
12
+ # interval_block = GbIntervalBlock.parse(open(interval_block.xml))
13
+ #
14
+ #
15
+ # Author: ahmed.seddiq
16
+ # Version: 1.0
17
+ class GbIntervalBlock
18
+ include SAXMachine
19
+ element :'espi:interval', class: GbInterval, as: :interval
20
+ elements :'espi:IntervalReading', class: GbIntervalReading, as: :readings
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,22 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+
3
+ require 'sax-machine'
4
+ require 'ce-greenbutton/elements/gb_interval'
5
+
6
+ module GreenButton
7
+ module Parser
8
+ # a sax-machine mapping for the espi:IntervalReading structure
9
+ #
10
+ # For example:
11
+ # interval_reading = GbIntervalReading.parse(open(interval_reading.xml))
12
+ #
13
+ #
14
+ # Author: ahmed.seddiq
15
+ # Version: 1.0
16
+ class GbIntervalReading < GbInterval
17
+ include SAXMachine
18
+ element :'espi:value', class: Integer, as: :value
19
+ element :'espi:cost', class: Integer, as: :cost
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,50 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+
3
+ require 'sax-machine'
4
+ require 'ce-greenbutton/utils'
5
+
6
+ module GreenButton
7
+ module Parser
8
+ # a sax-machine mapping for the espi:LocalTimeParameters structure
9
+ #
10
+ # For example:
11
+ # local_time_parameters = GbLocalTimeParameters.parse(open(local_time_parameters.xml))
12
+ #
13
+ #
14
+ # Author: ahmed.seddiq
15
+ # Version: 1.0
16
+ class GbLocalTimeParameters
17
+ include SAXMachine
18
+ include Utils::DSTRule
19
+
20
+ attr_accessor :dst_start_time
21
+ attr_accessor :dst_end_time
22
+
23
+ element :'espi:dstEndRule', as: :dst_end_rule do |rule|
24
+ @dst_end_time = to_time(rule)
25
+ rule
26
+ end
27
+ element :'espi:dstStartRule', as: :dst_start_rule do |rule|
28
+ @dst_start_time = to_time(rule)
29
+ rule
30
+ end
31
+ element :'espi:dstOffset', class: Integer, as: :dst_offset
32
+ element :'espi:tzOffset', class: Integer, as: :tz_offset
33
+
34
+ # Converts time to local based on the given time configuration.
35
+ #
36
+ # The time after applying the rules in the time_config
37
+ #
38
+ def local_time(time)
39
+ # apply timezone offset
40
+ time += self.tz_offset
41
+ # apply dst offset
42
+ if Time.now.between?(@dst_start_time, @dst_end_time)
43
+ time += self.dst_offset
44
+ end
45
+ Time.at(time)
46
+ end
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,23 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+
3
+ require 'sax-machine'
4
+
5
+ module GreenButton
6
+ module Parser
7
+ # a sax-machine mapping for the espi:ReadingType structure
8
+ #
9
+ # For example:
10
+ # reading_type = GbReadingType.parse(open(reading_type.xml))
11
+ #
12
+ #
13
+ # Author: ahmed.seddiq
14
+ # Version: 1.0
15
+ class GbReadingType
16
+ include SAXMachine
17
+ element :'espi:commodity', class: Integer, as: :commodity
18
+ element :'espi:currency', class: Integer, as: :currency
19
+ element :'espi:uom', class: Integer, as: :uom
20
+ element :'espi:powerOfTenMultiplier', class: Integer, as: :power_of_ten_multiplier
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+
3
+ require 'sax-machine'
4
+
5
+ module GreenButton
6
+ module Parser
7
+ # a sax-machine mapping for the espi:UsagePoint structure
8
+ #
9
+ # For example:
10
+ # usage_point = GbUsagePoint.parse(open(usage_point.xml))
11
+ #
12
+ #
13
+ # Author: ahmed.seddiq
14
+ # Version: 1.0
15
+ class GbUsagePoint
16
+ include SAXMachine
17
+ element :'espi:kind', class: Integer, as: :kind
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,114 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+
3
+ require 'date'
4
+ require 'ce-greenbutton'
5
+ require 'ce-greenbutton/model/gb_data_description'
6
+ require 'ce-greenbutton/model/gb_data'
7
+ require 'ce-greenbutton/model/gb_data_reading'
8
+
9
+ module GreenButton
10
+ module Interpreters
11
+ # An interpreter for the Electricity GreenButton data. It can be registered
12
+ # to the GreenButton module by calling GreenButton.register_interpreter.
13
+ #
14
+ # The interpreter will be called by the GreenButton module to interpret the
15
+ # electricity GreenButton data (kind = 0)
16
+ #
17
+ # For example:
18
+ # # This call will bind this interpreter to the GreenButton data of kind=0
19
+ # GreenButton.register_interpreter(0,:electricity)
20
+ #
21
+ # Author: ahmed.seddiq
22
+ # Version: 1.0
23
+ #
24
+ module ElectricityInterpreter
25
+
26
+ # Maps the parsed GbUsagePoint to the equivalent GbDataDescription.
27
+ #
28
+ # usage_point - The parsed GbUsagePoint.
29
+ # feed - The parsed GbDataFeed. It is used to resolve related
30
+ # entries in the usage_point hierarchy.
31
+ #
32
+ # Returns the newly created GbDataDescription instance.
33
+ #
34
+ def self.get_gb_data_description (usage_point, feed)
35
+ gb_data_description = GbDataDescription.new
36
+ gb_data_description.updated = usage_point.updated
37
+
38
+ meter_readings = feed.get_related(usage_point, 'MeterReading')
39
+ raise GreenButton::InvalidGbDataError, 'Missing MeterReading data' if meter_readings.nil?
40
+
41
+ time_config = feed.get_related(usage_point, 'LocalTimeParameters')
42
+ raise GreenButton::InvalidGbDataError, 'Missing LocalTimeParameters data' if time_config.nil?
43
+
44
+ # get the actual time parameters from the entry.content
45
+ time_config = time_config.content.local_time_parameters
46
+
47
+ # We can have multiple meter readings per usage point.
48
+ unless meter_readings.is_a? Array
49
+ meter_readings = [meter_readings]
50
+ end
51
+ meter_readings.each do |meter_reading|
52
+ interpret_meter_reading(gb_data_description, meter_reading,
53
+ time_config, feed)
54
+ end
55
+
56
+ gb_data_description
57
+ end
58
+
59
+ # Interprets a single MeterReading structure. It will append all interpreted
60
+ # GbData instances to gb_data_description.gb_data_array.
61
+ #
62
+ # gb_data_description - the GbDataDescription under construction now.
63
+ # meter_reading - the GbEntry describing the MeterReading structure.
64
+ # time_config - the GbLocalTimeParameters used to convert time
65
+ # values to local.
66
+ # feed - the parsed GbDataFeed, used to resolve any related
67
+ # GbEntries
68
+ #
69
+ # Returns Nothing.
70
+ #
71
+ private
72
+ def self.interpret_meter_reading(gb_data_description, meter_reading,
73
+ time_config, feed)
74
+ reading_type = feed.get_related(meter_reading, 'ReadingType')
75
+ raise GreenButton::InvalidGbDataError, 'Missing ReadingType data' if reading_type.nil?
76
+
77
+ reading_type = reading_type.content.reading_type
78
+ gb_data_description.commodity = reading_type.commodity
79
+ gb_data_description.currency = reading_type.currency
80
+ gb_data_description.unit_of_measure = reading_type.uom
81
+ gb_data_description.power_of_ten_multiplier =
82
+ reading_type.power_of_ten_multiplier
83
+
84
+ # interval blocks
85
+ interval_blocks = feed.get_related(meter_reading, 'IntervalBlock') || []
86
+
87
+ if gb_data_description.gb_data_array.nil?
88
+ gb_data_description.gb_data_array = []
89
+ end
90
+ updated = gb_data_description.updated
91
+ interval_blocks.each do |interval_block|
92
+ updated = interval_block.updated if interval_block.updated > updated
93
+ interval_block = interval_block.content.interval_block
94
+ gb_data = GbData.new
95
+ gb_data.gb_data_description = gb_data_description
96
+ gb_data.time_duration = interval_block.interval.duration
97
+ gb_data.time_start = time_config.local_time(interval_block.interval.start)
98
+ gb_data.interval_readings = []
99
+ interval_block.readings.each do |reading|
100
+ gb_data_reading = GbDataReading.new
101
+ gb_data_reading.time_duration = reading.duration
102
+ gb_data_reading.time_start = time_config.local_time(reading.start)
103
+ gb_data_reading.value = reading.value
104
+ gb_data_reading.cost = reading.cost
105
+ gb_data.interval_readings << gb_data_reading
106
+ end
107
+ gb_data_description.gb_data_array << gb_data
108
+ end
109
+ gb_data_description.updated = time_config.local_time(updated.to_time.to_i)
110
+ end
111
+
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,30 @@
1
+ # Copyright (C) 2015 TopCoder Inc., All Rights Reserved.
2
+ require 'ce-greenbutton/utils'
3
+
4
+ # Represents an IntervalBlock structure.
5
+ #
6
+ # Author TCSASSEMBLER
7
+ # Version 1.0
8
+ class GbData
9
+ include Utils::Hash
10
+
11
+ # A reference to the owner GbDataDescription
12
+ attr_accessor :gb_data_description
13
+
14
+ # Represents the start time (local) value from the IntervalBlock -> Interval
15
+ # structure
16
+ attr_accessor :time_start
17
+
18
+ # Represents the duration value from the IntervalBlock -> Interval structure
19
+ attr_accessor :time_duration
20
+
21
+ # An array of GbDataReading
22
+ attr_accessor :interval_readings
23
+
24
+ # Returns the parsed elements as a hash with key equals the property name and
25
+ # value equals the parsed value.
26
+ def _parse
27
+ to_hash
28
+ end
29
+
30
+ end