amon 0.3.0 → 0.4.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +5 -3
- data/lib/amon/default_session.rb +8 -8
- data/lib/amon/device.rb +61 -0
- data/lib/amon/document.rb +4 -4
- data/lib/amon/document_part.rb +4 -4
- data/lib/amon/entity.rb +9 -9
- data/lib/amon/json_helper.rb +4 -4
- data/lib/amon/measurement.rb +16 -15
- data/lib/amon/metadata.rb +8 -8
- data/lib/amon/reading.rb +23 -23
- data/lib/amon/session.rb +35 -34
- data/lib/amon/version.rb +3 -3
- data/lib/amon.rb +2 -2
- metadata +5 -5
- data/lib/amon/meter.rb +0 -53
data/README.md
CHANGED
@@ -3,6 +3,8 @@ Ruby Client for the AMEE AMON API
|
|
3
3
|
|
4
4
|
This is a Ruby client library for the [AMEE](http://www.amee.com/) <abbr title="AMEE Monitoring Object Notation">AMON</abbr> <abbr title="Application Programming Interface">API</abbr>. _More details and links to be inserted once information about the API is publicly available_.
|
5
5
|
|
6
|
+
This is version 0.4.3 and is built to support AMON V3: https://github.com/AMEE/amon
|
7
|
+
|
6
8
|
## Installation ##
|
7
9
|
|
8
10
|
### Dependencies ###
|
@@ -54,13 +56,13 @@ Methods which can be called on a {AMON::Session Session} can be called directly
|
|
54
56
|
|
55
57
|
### Simple usage example ###
|
56
58
|
|
57
|
-
This example gets some measurements from an electricity
|
59
|
+
This example gets some measurements from an electricity device over a 1 month period.
|
58
60
|
|
59
61
|
start_date = Time.local(2010, 3)
|
60
62
|
end_date = Time.local(2010, 4)
|
61
|
-
|
63
|
+
|
62
64
|
property = AMON.entity("da3906c0-7c6b-012d-a6d5-001c23973687")
|
63
|
-
concentrator = property.
|
65
|
+
concentrator = property.devices.first
|
64
66
|
electricity_reading = concentrator.readings_by_type["electricalInput"]
|
65
67
|
electricity_reading.measurements(start_date, end_date) # => Array of measurements
|
66
68
|
|
data/lib/amon/default_session.rb
CHANGED
@@ -3,17 +3,17 @@ require 'forwardable'
|
|
3
3
|
# The AMON module responds to the same method names as an {AMON::Session}. When called,
|
4
4
|
# these methods use a 'default' session returned by {create_default_session}. So the following
|
5
5
|
# method calls are all equivalent:
|
6
|
-
#
|
6
|
+
#
|
7
7
|
# AMON::Session.new(AMON.default_session_options).entity("77e50660-93e7-012d-b57d-001c23973687")
|
8
8
|
# AMON.create_default_session.entity("77e50660-93e7-012d-b57d-001c23973687")
|
9
9
|
# AMON.entity("77e50660-93e7-012d-b57d-001c23973687")
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# Note that using a default session implicitly (as in the final line above) will cause a new
|
12
12
|
# session to be created each time the method is called. This means caching will not be used.
|
13
|
-
#
|
13
|
+
#
|
14
14
|
# If you are likely to be requesting the same resources in short succession, it is advisable to
|
15
15
|
# hold on to a session object yourself. For example:
|
16
|
-
#
|
16
|
+
#
|
17
17
|
# @session = AMON.create_default_session
|
18
18
|
# @session.entity("77e50660-93e7-012d-b57d-001c23973687") # => <AMON::Entity> (from HTTP)
|
19
19
|
# @session.entity("77e50660-93e7-012d-b57d-001c23973687") # => <AMON::Entity> (from cache)
|
@@ -25,21 +25,21 @@ module AMON
|
|
25
25
|
def default_session_options
|
26
26
|
@default_session_options ||= {}
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
# Assigns a new options hash as the {default_session_options}.
|
30
30
|
# @param [Hash] options the options hash
|
31
31
|
# @return [Hash] the options hash
|
32
32
|
def default_session_options=(options)
|
33
33
|
@default_session_options = options
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
# Creates a new session using the {default_session_options}.
|
37
37
|
# @return [Session]
|
38
38
|
def create_default_session
|
39
39
|
Session.new(default_session_options)
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
extend Forwardable
|
43
|
-
def_delegators :create_default_session, :entity, :
|
43
|
+
def_delegators :create_default_session, :entity, :device, :metering_point, :measurements
|
44
44
|
end
|
45
45
|
end
|
data/lib/amon/device.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
module AMON
|
2
|
+
# An AMON device, containing any number of {Reading readings}, and {Measurement measurements} for those readings.
|
3
|
+
class Device < Document
|
4
|
+
# @return [String] The id of the device
|
5
|
+
field :id, :name => 'deviceId'
|
6
|
+
|
7
|
+
# @return [Time] The latest measurement start date, if provided
|
8
|
+
field :latest_measurement, :name => 'latestMeasurement', :as => Time
|
9
|
+
|
10
|
+
# @return <String> The deviceId for the device
|
11
|
+
def uuid
|
12
|
+
@uuid ||= json['deviceId']
|
13
|
+
end
|
14
|
+
|
15
|
+
# @return <String> The description for the device
|
16
|
+
def description
|
17
|
+
@description ||= json['description']
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return <String> The location for the device
|
21
|
+
def location_name
|
22
|
+
@location_name ||= json['location']['name']
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Metadata] The metadata for the device
|
26
|
+
def metadata
|
27
|
+
@metadata ||= Metadata.new(self, json['metadata'])
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Array<Reading>] The readings for the device
|
31
|
+
def readings
|
32
|
+
@readings ||= json['readings'].map { |reading| Reading.new(self, reading) }
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Hash<String => Reading>] A hash allowing {Device#readings} to be retrieved by their
|
36
|
+
# {Reading#type}
|
37
|
+
def readings_by_type
|
38
|
+
readings.inject({}) do |readings_by_type, reading|
|
39
|
+
readings_by_type[reading.type] = reading
|
40
|
+
readings_by_type
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# @return [Array<Measurement>] Measurements for this device
|
45
|
+
# @see Session#measurements
|
46
|
+
def measurements(entity_id, start_date, end_date, raw = false)
|
47
|
+
session.measurements(entity_id, id, start_date, end_date, raw)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @return [Hash<String => Measurement>] A hash allowing {Device#measurements} to be retrieved
|
51
|
+
# by their {Measurement#name}
|
52
|
+
# @see Device#measurements
|
53
|
+
def measurements_by_name(entity_id, start_date, end_date, raw = false)
|
54
|
+
measurements(entity_id, start_date, end_date, raw).inject({}) do |measurements_by_name, measurement|
|
55
|
+
measurements_by_name[measurement.name] ||= []
|
56
|
+
measurements_by_name[measurement.name] << measurement
|
57
|
+
measurements_by_name
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/amon/document.rb
CHANGED
@@ -3,23 +3,23 @@ module AMON
|
|
3
3
|
# @abstract
|
4
4
|
class Document
|
5
5
|
include JSONHelper
|
6
|
-
|
6
|
+
|
7
7
|
# @return [Session] The session associated with this document
|
8
8
|
attr_reader :session
|
9
|
-
|
9
|
+
|
10
10
|
# @param [Session] session The session
|
11
11
|
# @param [Hash] json The JSON data as a Hash
|
12
12
|
def initialize(session, json)
|
13
13
|
@session, @json = session, json
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
# This should be implemented in subclasses, returning the UUID for the document
|
17
17
|
# @abstract
|
18
18
|
# @private
|
19
19
|
def id
|
20
20
|
raise NotImplementedError
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
# Two documents are equal if they have the same class and their id fields are equal
|
24
24
|
# @param [Document] other
|
25
25
|
# @return [Boolean]
|
data/lib/amon/document_part.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module AMON
|
2
2
|
# An object representing part of an AMON {Document}. For example, a {Reading} is part of a
|
3
|
-
# {
|
4
|
-
#
|
3
|
+
# {Device}, and cannot exist outside of it.
|
4
|
+
#
|
5
5
|
# @abstract
|
6
6
|
class DocumentPart
|
7
7
|
include JSONHelper
|
8
|
-
|
8
|
+
|
9
9
|
# @return [Document] The parent document of which this object is a part
|
10
10
|
attr_reader :parent
|
11
|
-
|
11
|
+
|
12
12
|
# @param [Document] parent The parent document
|
13
13
|
# @param [Hash] json The JSON data as a Hash
|
14
14
|
def initialize(parent, json)
|
data/lib/amon/entity.rb
CHANGED
@@ -3,19 +3,19 @@ module AMON
|
|
3
3
|
class Entity < Document
|
4
4
|
# @return [String] The id for this entity
|
5
5
|
field :id, :name => 'entityId'
|
6
|
-
|
7
|
-
# @return [Array<String>] The ids of all the
|
8
|
-
field :
|
9
|
-
|
6
|
+
|
7
|
+
# @return [Array<String>] The ids of all the devices associated with this entity
|
8
|
+
field :device_ids, :name => 'deviceIds', :default => []
|
9
|
+
|
10
10
|
# @return [Array<String>] The qualified ids of all the metering points associated with this entity
|
11
11
|
# @todo Rename to qualified_metering_point_ids
|
12
12
|
field :metering_point_ids, :name => 'qualifiedMeteringPointIds', :default => []
|
13
|
-
|
14
|
-
# @return [Array<
|
15
|
-
def
|
16
|
-
@
|
13
|
+
|
14
|
+
# @return [Array<Device>] The devices associated with this entity
|
15
|
+
def devices
|
16
|
+
@devices ||= device_ids.map { |device_id| session.device(id, device_id) }
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
# @return [Array<MeteringPoint>] The metering points associated with this entity
|
20
20
|
def metering_points
|
21
21
|
@metering_points ||= metering_point_ids.map { |id| session.metering_point(id) }
|
data/lib/amon/json_helper.rb
CHANGED
@@ -2,22 +2,22 @@ module AMON
|
|
2
2
|
module JSONHelper
|
3
3
|
# @return [Hash] The raw JSON data for this object, represented as a Hash
|
4
4
|
attr_reader :json
|
5
|
-
|
5
|
+
|
6
6
|
private
|
7
|
-
|
7
|
+
|
8
8
|
def self.included(base)
|
9
9
|
base.class_eval do
|
10
10
|
extend ClassMethods
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
# @private
|
15
15
|
module ClassMethods
|
16
16
|
def field(name, options = {})
|
17
17
|
class_eval do
|
18
18
|
define_method(name) do
|
19
19
|
original_value = json[(options[:name] || name).to_s]
|
20
|
-
|
20
|
+
|
21
21
|
if original_value.nil?
|
22
22
|
options[:default]
|
23
23
|
else
|
data/lib/amon/measurement.rb
CHANGED
@@ -1,24 +1,25 @@
|
|
1
1
|
module AMON
|
2
|
-
# A measurement corresponding to a {Reading} of a {
|
2
|
+
# A measurement corresponding to a {Reading} of a {Device}
|
3
3
|
class Measurement < DocumentPart
|
4
4
|
# @return [String] The measurement's name
|
5
|
-
field :
|
6
|
-
|
5
|
+
field :type
|
6
|
+
alias :name :type
|
7
|
+
|
7
8
|
# @return [Numeric] The measurement's value
|
8
9
|
field :value
|
9
|
-
|
10
|
+
|
10
11
|
# @return [Time] The measurement's timestamp, if provided
|
11
12
|
field :timestamp, :as => Time
|
12
|
-
|
13
|
+
|
13
14
|
# @return [Time] The measurement's start date, if provided
|
14
15
|
field :start_date, :name => 'startDate', :as => Time
|
15
|
-
|
16
|
+
|
16
17
|
# @return [Time] The measurement's end date, if provided
|
17
18
|
field :end_date, :name => 'endDate', :as => Time
|
18
|
-
|
19
|
-
# @attr_reader [
|
20
|
-
alias_method :
|
21
|
-
|
19
|
+
|
20
|
+
# @attr_reader [Device] device The device which took this measurement
|
21
|
+
alias_method :device, :parent
|
22
|
+
|
22
23
|
# A measurement is instantaneous if it is given with a single timestamp. If, on the other hand,
|
23
24
|
# start and end dates are provided, it is durational.
|
24
25
|
# @return [Boolean]
|
@@ -26,20 +27,20 @@ module AMON
|
|
26
27
|
def instantaneous?
|
27
28
|
!timestamp.nil?
|
28
29
|
end
|
29
|
-
|
30
|
+
|
30
31
|
# The opposite of {Measurement#instantaneous? instantaneous?}
|
31
32
|
# @return [Boolean]
|
32
33
|
# @see Measurement#instantaneous?
|
33
34
|
def durational?
|
34
35
|
!instantaneous?
|
35
36
|
end
|
36
|
-
|
37
|
-
# The {
|
37
|
+
|
38
|
+
# The {Device device} {Reading reading} associated with this measurement.
|
38
39
|
# @return [Reading]
|
39
40
|
def reading
|
40
|
-
|
41
|
+
device.readings_by_type[name]
|
41
42
|
end
|
42
|
-
|
43
|
+
|
43
44
|
# A single timestamp in the 'middle' of this measurement. If the measurement is instantaneous,
|
44
45
|
# then the mid timestamp is identical to the {Measurement#timestamp timestamp}. However, if it
|
45
46
|
# is durational then the mid timestamp is the halfway point between the {Measurement#start_date}
|
data/lib/amon/metadata.rb
CHANGED
@@ -1,25 +1,25 @@
|
|
1
1
|
module AMON
|
2
|
-
# Metadata associated with a {
|
2
|
+
# Metadata associated with a {Device}. The metadata section of an AMON document can have an
|
3
3
|
# arbitrary number of fields, so this class uses `method_missing` to look them up and respond
|
4
4
|
# appropriately.
|
5
|
-
#
|
5
|
+
#
|
6
6
|
# @todo
|
7
7
|
# This doesn't yet support arbitrarily nested metadata, so you can't have JSON like so:
|
8
|
-
#
|
8
|
+
#
|
9
9
|
# "metadata": {
|
10
10
|
# "foo": {
|
11
11
|
# "bar": "baz"
|
12
12
|
# }
|
13
13
|
# }
|
14
|
-
#
|
14
|
+
#
|
15
15
|
# And then access:
|
16
|
-
#
|
16
|
+
#
|
17
17
|
# object.metadata.foo.bar # => "baz"
|
18
|
-
#
|
18
|
+
#
|
19
19
|
# However, in the meantime you could do:
|
20
|
-
#
|
20
|
+
#
|
21
21
|
# object.metadata.foo[:bar] # => "baz"
|
22
|
-
#
|
22
|
+
#
|
23
23
|
# (As the JSON is full parsed into a nested hash.)
|
24
24
|
|
25
25
|
class Metadata < DocumentPart
|
data/lib/amon/reading.rb
CHANGED
@@ -1,59 +1,59 @@
|
|
1
1
|
module AMON
|
2
|
-
# AMON readings are 'categories' of {Measurement measurements} which are taken by {
|
2
|
+
# AMON readings are 'categories' of {Measurement measurements} which are taken by {Device devices}.
|
3
3
|
# For example, one reading may be 'electricalInput' with the unit 'kWh'.
|
4
4
|
class Reading < DocumentPart
|
5
|
-
# @return [String] The type of reading, which is unique within the parent {
|
5
|
+
# @return [String] The type of reading, which is unique within the parent {Device device}
|
6
6
|
field :type
|
7
|
-
|
7
|
+
|
8
8
|
# @return [String] An arbitrary name for the reading
|
9
9
|
field :name
|
10
|
-
|
10
|
+
|
11
11
|
# @return [String] The units this reading records {Measurement measurements} in
|
12
12
|
field :unit
|
13
|
-
|
13
|
+
|
14
14
|
# @return [Numeric] The resolution of the reading
|
15
15
|
field :resolution
|
16
|
-
|
16
|
+
|
17
17
|
# @return [Numeric] The accuracy of the reading
|
18
18
|
field :accuracy
|
19
|
-
|
19
|
+
|
20
20
|
# @return ["instant", "duration"] Whether this reading records measurement values taken at a
|
21
21
|
# specific point in time ('instant'), or taken as an average over a period of time ('duration')
|
22
22
|
field :period, :default => "instant"
|
23
|
-
|
24
|
-
# @attr_reader [
|
25
|
-
alias_method :
|
26
|
-
|
23
|
+
|
24
|
+
# @attr_reader [Device device] The device which took this measurement
|
25
|
+
alias_method :device, :parent
|
26
|
+
|
27
27
|
# @return [Array<Measurement>] Measurements for this reading
|
28
|
-
# @see
|
29
|
-
def measurements(start_date, end_date, raw = false)
|
30
|
-
|
28
|
+
# @see Device#measurements
|
29
|
+
def measurements(entity_id, start_date, end_date, raw = false)
|
30
|
+
device.measurements_by_name(entity_id, start_date, end_date, raw)[type] || []
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
# @return [true] if the {#period} is 'instant'
|
34
34
|
# @return [false] if the {#period} is 'duration'
|
35
35
|
def instantaneous?
|
36
36
|
period == "instant"
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
# @return [Boolean] The opposite of {#instantaneous?}
|
40
40
|
def durational?
|
41
41
|
!instantaneous?
|
42
42
|
end
|
43
|
-
|
44
|
-
# One reading is equal to another if the
|
43
|
+
|
44
|
+
# One reading is equal to another if the devices are equal and they are the same type
|
45
45
|
# @return [Boolean]
|
46
46
|
# @param [Reading] other The other reading to compare with.
|
47
47
|
def ==(other)
|
48
|
-
|
48
|
+
device == other.device && type == other.type
|
49
49
|
end
|
50
|
-
|
51
|
-
# A unique id for the reading, composed of the {
|
52
|
-
# '<code>electricalInput</code>' reading for a
|
50
|
+
|
51
|
+
# A unique id for the reading, composed of the {Device device} id, and the {#type}. So an
|
52
|
+
# '<code>electricalInput</code>' reading for a device with id '<code>b7ddac00-9415-012d-b57e-001c23973687</code>' would
|
53
53
|
# have the id '<code>b7ddac00-9415-012d-b57e-001c23973687-electricalInput</code>'.
|
54
54
|
# @return [String] the id
|
55
55
|
def id
|
56
|
-
"#{
|
56
|
+
"#{device.id}-#{type}"
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
data/lib/amon/session.rb
CHANGED
@@ -2,28 +2,28 @@ require 'uri'
|
|
2
2
|
|
3
3
|
module AMON
|
4
4
|
# Session objects take care of making the actual HTTP requests to the AMON API
|
5
|
-
#
|
5
|
+
#
|
6
6
|
# ## Caching ##
|
7
|
-
#
|
8
|
-
# Sessions support caching which is enabled by default, but can be optionally turned off. When
|
7
|
+
#
|
8
|
+
# Sessions support caching which is enabled by default, but can be optionally turned off. When
|
9
9
|
# caching is enabled, the same request will not be performed twice in a session. Be aware that
|
10
10
|
# this has some important implications:
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# * If a long running process uses the same session, the cache may become stale as the backend
|
13
13
|
# data changes, but new API requests are not made.
|
14
14
|
# * There is no mechanism for automatically expiring the cache; this is left up to users of the
|
15
15
|
# library.
|
16
|
-
# * The cache stores the AMON objects, rather than the raw response data. In this sense it
|
16
|
+
# * The cache stores the AMON objects, rather than the raw response data. In this sense it
|
17
17
|
# functions as a sort of identity map - getting the same entity twice will return exactly the
|
18
18
|
# same object twice, rather than two different objects representing the same data.
|
19
|
-
#
|
19
|
+
#
|
20
20
|
# Often the most natural way to 'expire the cache' is to discard the session and use a new one
|
21
|
-
# at regular intervals. Alternatively, you can use {Session#clear_cache} and keep the same
|
21
|
+
# at regular intervals. Alternatively, you can use {Session#clear_cache} and keep the same
|
22
22
|
# session.
|
23
23
|
class Session
|
24
24
|
# @return [Hash] The hash of configuration options to be used when making requests
|
25
25
|
attr_reader :options
|
26
|
-
|
26
|
+
|
27
27
|
# The default options for a session
|
28
28
|
DEFAULT_OPTIONS = {
|
29
29
|
:base_uri => nil,
|
@@ -31,7 +31,7 @@ module AMON
|
|
31
31
|
:password => nil,
|
32
32
|
:cache => true
|
33
33
|
}.freeze
|
34
|
-
|
34
|
+
|
35
35
|
# @param [Hash] options the options for the session
|
36
36
|
# @option options [String] :base_uri The base URI for the AMON API, e.g. "http://amon.amee.com/1"
|
37
37
|
# (note that this includes the API version, as this library only knows about version 1 of the API)
|
@@ -42,7 +42,7 @@ module AMON
|
|
42
42
|
@options = DEFAULT_OPTIONS.merge(options)
|
43
43
|
@options.freeze
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
# Retrieves an entity from the API
|
47
47
|
# @param [String] entity_id the ID of the entity to be requested
|
48
48
|
# @return [Entity]
|
@@ -52,17 +52,17 @@ module AMON
|
|
52
52
|
Entity.new(self, json)
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
56
|
-
# Retrieves a
|
57
|
-
# @param [String]
|
58
|
-
# @return [
|
59
|
-
def
|
60
|
-
cache(:
|
61
|
-
json = get("/
|
62
|
-
|
55
|
+
|
56
|
+
# Retrieves a device from the API
|
57
|
+
# @param [String] device_id the ID of the device to be requested
|
58
|
+
# @return [Device]
|
59
|
+
def device(entity_id, device_id)
|
60
|
+
cache(:devices, device_id) do
|
61
|
+
json = get("/entities/#{ URI.escape(entity_id )}/devices/#{URI.escape(device_id)};latest")['device']
|
62
|
+
Device.new(self, json)
|
63
63
|
end
|
64
64
|
end
|
65
|
-
|
65
|
+
|
66
66
|
# Retrieves a metering point from the API
|
67
67
|
# @param [String] metering_point_id the ID of the metering point to be requested
|
68
68
|
# @return [MeteringPoint]
|
@@ -72,33 +72,34 @@ module AMON
|
|
72
72
|
MeteringPoint.new(self, json)
|
73
73
|
end
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
# Retrieves measurements from the API
|
77
|
-
# @param [String]
|
77
|
+
# @param [String] entity_id The ID of the entity
|
78
|
+
# @param [String] device_id The ID of the device to get the measurements from
|
78
79
|
# @param [Time] start_date The starting point for the measurements
|
79
80
|
# @param [Time] end_date The ending point for the measurements
|
80
|
-
# @param [Boolean] raw Whether to return raw measurements as submitted by the hardware (may
|
81
|
+
# @param [Boolean] raw Whether to return raw measurements as submitted by the hardware (may
|
81
82
|
# contain a lot of data), or appropriate aggregations over the time period
|
82
|
-
def measurements(
|
83
|
-
cache(:measurements, [
|
84
|
-
|
83
|
+
def measurements(entity_id, device_id, start_date, end_date, raw = false)
|
84
|
+
cache(:measurements, [device_id, start_date, end_date, raw]) do
|
85
|
+
device = device(entity_id, device_id)
|
85
86
|
measurements = get(
|
86
|
-
"/
|
87
|
+
"/entities/#{ URI.escape(entity_id) }/devices/#{ URI.escape(device.id) }/measurements?" +
|
87
88
|
"raw=" + raw.to_s + "&" +
|
88
89
|
"startDate=" + start_date.utc.xmlschema + "&" +
|
89
90
|
"endDate=" + end_date.utc.xmlschema
|
90
91
|
)['measurements']
|
91
|
-
measurements.map { |measurement| Measurement.new(
|
92
|
+
measurements.map { |measurement| Measurement.new(device, measurement) }
|
92
93
|
end
|
93
94
|
end
|
94
|
-
|
95
|
+
|
95
96
|
# Completely clears the cache
|
96
97
|
def clear_cache
|
97
98
|
@cache = nil
|
98
99
|
end
|
99
|
-
|
100
|
+
|
100
101
|
private
|
101
|
-
|
102
|
+
|
102
103
|
def cache(group, id, &block)
|
103
104
|
if options[:cache]
|
104
105
|
@cache ||= {}
|
@@ -108,16 +109,16 @@ module AMON
|
|
108
109
|
block.call
|
109
110
|
end
|
110
111
|
end
|
111
|
-
|
112
|
+
|
112
113
|
def get(url, params = {})
|
113
114
|
JSON.parse(client[url].get(:params => params))
|
114
115
|
end
|
115
|
-
|
116
|
+
|
116
117
|
def client
|
117
118
|
raise ArgumentError, "Can't make a request without :base_uri option" unless options[:base_uri]
|
118
|
-
|
119
|
+
|
119
120
|
@client ||= RestClient::Resource.new(
|
120
|
-
options[:base_uri],
|
121
|
+
options[:base_uri],
|
121
122
|
:user => options[:user],
|
122
123
|
:password => options[:password],
|
123
124
|
:headers => {
|
data/lib/amon/version.rb
CHANGED
data/lib/amon.rb
CHANGED
@@ -6,13 +6,13 @@ module AMON
|
|
6
6
|
autoload :Document, 'amon/document'
|
7
7
|
autoload :DocumentPart, 'amon/document_part'
|
8
8
|
autoload :Entity, 'amon/entity'
|
9
|
-
autoload :
|
9
|
+
autoload :Device, 'amon/device'
|
10
10
|
autoload :MeteringPoint, 'amon/metering_point'
|
11
11
|
autoload :Metadata, 'amon/metadata'
|
12
12
|
autoload :Reading, 'amon/reading'
|
13
13
|
autoload :Measurement, 'amon/measurement'
|
14
14
|
autoload :Version, 'amon/version'
|
15
15
|
autoload :Session, 'amon/session'
|
16
|
-
|
16
|
+
|
17
17
|
require 'amon/default_session'
|
18
18
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 9
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
+
- 4
|
8
9
|
- 3
|
9
|
-
|
10
|
-
version: 0.3.0
|
10
|
+
version: 0.4.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- AMEE
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date:
|
18
|
+
date: 2012-07-25 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: json
|
@@ -107,13 +107,13 @@ extra_rdoc_files: []
|
|
107
107
|
|
108
108
|
files:
|
109
109
|
- lib/amon/default_session.rb
|
110
|
+
- lib/amon/device.rb
|
110
111
|
- lib/amon/document.rb
|
111
112
|
- lib/amon/document_part.rb
|
112
113
|
- lib/amon/entity.rb
|
113
114
|
- lib/amon/json_helper.rb
|
114
115
|
- lib/amon/measurement.rb
|
115
116
|
- lib/amon/metadata.rb
|
116
|
-
- lib/amon/meter.rb
|
117
117
|
- lib/amon/metering_point.rb
|
118
118
|
- lib/amon/reading.rb
|
119
119
|
- lib/amon/session.rb
|
data/lib/amon/meter.rb
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
module AMON
|
2
|
-
# An AMON meter, containing any number of {Reading readings}, and {Measurement measurements} for those readings.
|
3
|
-
class Meter < Document
|
4
|
-
# @return [String] The id of the meter
|
5
|
-
field :id, :name => 'meterId'
|
6
|
-
|
7
|
-
# @return <String> The description for the meter
|
8
|
-
def description
|
9
|
-
@description ||= json['description']
|
10
|
-
end
|
11
|
-
|
12
|
-
# @return <String> The location for the meter
|
13
|
-
def location_name
|
14
|
-
@location_name ||= json['location']['name']
|
15
|
-
end
|
16
|
-
|
17
|
-
# @return [Metadata] The metadata for the meter
|
18
|
-
def metadata
|
19
|
-
@metadata ||= Metadata.new(self, json['metadata'])
|
20
|
-
end
|
21
|
-
|
22
|
-
# @return [Array<Reading>] The readings for the meter
|
23
|
-
def readings
|
24
|
-
@readings ||= json['readings'].map { |reading| Reading.new(self, reading) }
|
25
|
-
end
|
26
|
-
|
27
|
-
# @return [Hash<String => Reading>] A hash allowing {Meter#readings} to be retrieved by their
|
28
|
-
# {Reading#type}
|
29
|
-
def readings_by_type
|
30
|
-
readings.inject({}) do |readings_by_type, reading|
|
31
|
-
readings_by_type[reading.type] = reading
|
32
|
-
readings_by_type
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# @return [Array<Measurement>] Measurements for this meter
|
37
|
-
# @see Session#measurements
|
38
|
-
def measurements(start_date, end_date, raw = false)
|
39
|
-
session.measurements(id, start_date, end_date, raw)
|
40
|
-
end
|
41
|
-
|
42
|
-
# @return [Hash<String => Measurement>] A hash allowing {Meter#measurements} to be retrieved
|
43
|
-
# by their {Measurement#name}
|
44
|
-
# @see Meter#measurements
|
45
|
-
def measurements_by_name(start_date, end_date, raw = false)
|
46
|
-
measurements(start_date, end_date, raw).inject({}) do |measurements_by_name, measurement|
|
47
|
-
measurements_by_name[measurement.name] ||= []
|
48
|
-
measurements_by_name[measurement.name] << measurement
|
49
|
-
measurements_by_name
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|