ce-greenbutton 0.1.0

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: 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