amon 0.3.0 → 0.4.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.
- 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
|