helium-ruby 0.3.0 → 0.4.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.
@@ -102,7 +102,7 @@
102
102
  </div>
103
103
 
104
104
  <div id="footer">
105
- Generated on Thu Aug 18 10:50:33 2016 by
105
+ Generated on Mon Aug 22 15:52:19 2016 by
106
106
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
107
107
  0.9.3 (ruby-2.3.1).
108
108
  </div>
data/lib/helium.rb CHANGED
@@ -6,10 +6,13 @@ require "helium/version"
6
6
  require "helium/utils"
7
7
  require "helium/client"
8
8
  require "helium/cursor"
9
+ require "helium/resource"
9
10
  require "helium/user"
10
11
  require "helium/organization"
11
12
  require "helium/sensor"
13
+ require "helium/label"
12
14
  require "helium/data_point"
15
+ require "helium/element"
13
16
 
14
17
  module Helium
15
18
  end
data/lib/helium/client.rb CHANGED
@@ -2,6 +2,8 @@ require 'helium/client/http'
2
2
  require 'helium/client/users'
3
3
  require 'helium/client/organizations'
4
4
  require 'helium/client/sensors'
5
+ require 'helium/client/labels'
6
+ require 'helium/client/elements'
5
7
 
6
8
  module Helium
7
9
  class Client
@@ -10,6 +12,8 @@ module Helium
10
12
  include Helium::Client::Users
11
13
  include Helium::Client::Organizations
12
14
  include Helium::Client::Sensors
15
+ include Helium::Client::Labels
16
+ include Helium::Client::Elements
13
17
 
14
18
  attr_accessor :api_key
15
19
 
@@ -0,0 +1,42 @@
1
+ module Helium
2
+ class Client
3
+ module Elements
4
+ def elements
5
+ response = get('/element')
6
+ elements_data = JSON.parse(response.body)["data"]
7
+
8
+ elements = elements_data.map do |element_data|
9
+ Element.new(client: self, params: element_data)
10
+ end
11
+
12
+ return elements
13
+ end
14
+
15
+ def element(id)
16
+ response = get("/element/#{id}")
17
+ element_data = JSON.parse(response.body)["data"]
18
+
19
+ return Element.new(client: self, params: element_data)
20
+ end
21
+
22
+ def update_element(element, name:)
23
+ path = "/element/#{element.id}"
24
+
25
+ body = {
26
+ data: {
27
+ attributes: {
28
+ name: name
29
+ },
30
+ id: element.id,
31
+ type: "element"
32
+ }
33
+ }
34
+
35
+ response = patch(path, body: body)
36
+ element_data = JSON.parse(response.body)["data"]
37
+
38
+ return Element.new(client: self, params: element_data)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,105 @@
1
+ module Helium
2
+ class Client
3
+ module Labels
4
+ def labels
5
+ response = get('/label')
6
+ labels_data = JSON.parse(response.body)["data"]
7
+
8
+ labels = labels_data.map do |label_data|
9
+ Label.new(client: self, params: label_data)
10
+ end
11
+
12
+ return labels
13
+ end
14
+
15
+ def label(id)
16
+ response = get("/label/#{id}")
17
+ label_data = JSON.parse(response.body)["data"]
18
+
19
+ return Label.new(client: self, params: label_data)
20
+ end
21
+
22
+ def new_label(name:)
23
+ path = "/label"
24
+
25
+ body = {
26
+ data: {
27
+ attributes: {
28
+ name: name
29
+ },
30
+ type: "label"
31
+ }
32
+ }
33
+
34
+ response = post(path, body: body)
35
+ label_data = JSON.parse(response.body)["data"]
36
+
37
+ return Label.new(client: self, params: label_data)
38
+ end
39
+
40
+ def update_label(label, name:)
41
+ path = "/label/#{label.id}"
42
+
43
+ body = {
44
+ data: {
45
+ attributes: {
46
+ name: name
47
+ },
48
+ id: label.id,
49
+ type: "label"
50
+ }
51
+ }
52
+
53
+ response = patch(path, body: body)
54
+ label_data = JSON.parse(response.body)["data"]
55
+
56
+ return Label.new(client: self, params: label_data)
57
+ end
58
+
59
+ def delete_label(label)
60
+ path = "/label/#{label.id}"
61
+ delete(path)
62
+ end
63
+
64
+ def label_sensors(label)
65
+ path = "/label/#{label.id}/sensor"
66
+ response = get(path)
67
+ sensors_data = JSON.parse(response.body)["data"]
68
+
69
+ sensors = sensors_data.map do |sensor_data|
70
+ Sensor.new(client: self, params: sensor_data)
71
+ end
72
+
73
+ return sensors
74
+ end
75
+
76
+ def update_label_sensors(label, sensors: [])
77
+ path = "/label/#{label.id}/relationships/sensor"
78
+
79
+ sensors = Array(sensors)
80
+
81
+ new_sensor_data = sensors.map do |sensor|
82
+ {
83
+ id: sensor.id,
84
+ type: 'sensor'
85
+ }
86
+ end
87
+
88
+ body = {
89
+ data: new_sensor_data
90
+ }
91
+
92
+ response = patch(path, body: body)
93
+ sensors_data = JSON.parse(response.body)["data"]
94
+
95
+ # TODO: these come back deflated. need to either inflate at this point or
96
+ # when needed
97
+ sensors = sensors_data.map do |sensor_data|
98
+ Sensor.new(client: self, params: sensor_data)
99
+ end
100
+
101
+ return sensors
102
+ end
103
+ end
104
+ end
105
+ end
data/lib/helium/cursor.rb CHANGED
@@ -29,6 +29,10 @@ module Helium
29
29
  end
30
30
  end
31
31
 
32
+ def to_json(*options)
33
+ self.map(&:as_json).to_json(*options)
34
+ end
35
+
32
36
  private
33
37
 
34
38
  def fetch_next_page
@@ -1,10 +1,10 @@
1
1
  module Helium
2
- class DataPoint
3
- attr_accessor :id, :timestamp, :value, :port
2
+ class DataPoint < Resource
3
+ attr_reader :timestamp, :value, :port
4
4
 
5
5
  def initialize(client:, params:)
6
- @client = client
7
- @id = params["id"]
6
+ super(client: client, params: params)
7
+
8
8
  @timestamp = params.dig("attributes", "timestamp")
9
9
  @value = params.dig("attributes", "value")
10
10
  @port = params.dig("attributes", "port")
@@ -14,20 +14,40 @@ module Helium
14
14
  DateTime.parse(@timestamp)
15
15
  end
16
16
 
17
- def ==(other)
18
- self.id == other.id
19
- end
20
-
21
17
  def max
18
+ return nil unless @value.is_a?(Hash)
22
19
  @value["max"]
23
20
  end
24
21
 
25
22
  def min
23
+ return nil unless @value.is_a?(Hash)
26
24
  @value["min"]
27
25
  end
28
26
 
29
27
  def avg
28
+ return nil unless @value.is_a?(Hash)
30
29
  @value["avg"]
31
30
  end
31
+
32
+ def aggregate?
33
+ [max, min, avg].none? { |agg_value| agg_value.nil? }
34
+ end
35
+
36
+ def as_json
37
+ j = super.merge({
38
+ timestamp: timestamp,
39
+ port: port
40
+ })
41
+
42
+ if aggregate?
43
+ j[:max] = max
44
+ j[:min] = min
45
+ j[:avg] = avg
46
+ else
47
+ j[:value] = value
48
+ end
49
+
50
+ j
51
+ end
32
52
  end
33
53
  end
@@ -0,0 +1,27 @@
1
+ module Helium
2
+ class Element < Resource
3
+ attr_reader :name, :mac, :versions
4
+
5
+ def initialize(client:, params:)
6
+ super(client: client, params: params)
7
+
8
+ @name = params.dig("attributes", "name")
9
+ @mac = params.dig("meta", "mac")
10
+ @versions = params.dig("meta", "versions")
11
+ end
12
+
13
+ # TODO these kinds of methods should be generalized into a Resource object
14
+ def update(name:)
15
+ @client.update_element(self, name: name)
16
+ end
17
+
18
+ # TODO can probably generalize this a bit more
19
+ def as_json
20
+ super.merge({
21
+ name: name,
22
+ mac: mac,
23
+ versions: versions
24
+ })
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,44 @@
1
+ module Helium
2
+ class Label < Resource
3
+ attr_reader :name
4
+
5
+ def initialize(client:, params:)
6
+ super(client: client, params: params)
7
+
8
+ @name = params.dig("attributes", "name")
9
+ end
10
+
11
+ def update(name:)
12
+ @client.update_label(self, name: name)
13
+ end
14
+
15
+ def destroy
16
+ @client.delete_label(self)
17
+ end
18
+
19
+ # TODO: would be nice to wrap this in a proxy collection, that way
20
+ # we could do something like label.sensors << new_sensor
21
+ def sensors
22
+ @client.label_sensors(self)
23
+ end
24
+
25
+ def add_sensors(sensors_to_add = [])
26
+ sensors_to_add = Array(sensors_to_add)
27
+
28
+ @client.update_label_sensors(self, sensors: sensors + sensors_to_add)
29
+ end
30
+
31
+ def remove_sensors(sensors_to_remove = [])
32
+ sensors_to_remove = Array(sensors_to_remove)
33
+
34
+ @client.update_label_sensors(self, sensors: sensors - sensors_to_remove)
35
+ end
36
+
37
+ # TODO can probably generalize this a bit more
38
+ def as_json
39
+ super.merge({
40
+ name: name
41
+ })
42
+ end
43
+ end
44
+ end
@@ -1,27 +1,24 @@
1
1
  module Helium
2
- class Organization
3
- attr_accessor :id, :name, :timezone, :created_at, :updated_at
2
+ class Organization < Resource
3
+ attr_reader :name, :timezone
4
4
 
5
5
  def initialize(client:, params:)
6
- @client = client
7
- @id = params["id"]
8
- @name = params["attributes"]["name"]
9
- @timezone = params["attributes"]["timezone"]
10
- @created_at = params["meta"]["created"]
11
- @updated_at = params["meta"]["updated"]
12
- end
13
-
14
- def created_at
15
- DateTime.parse(@created_at)
16
- end
6
+ super(client: client, params: params)
17
7
 
18
- def updated_at
19
- DateTime.parse(@updated_at)
8
+ @name = params.dig('attributes', 'name')
9
+ @timezone = params.dig('attributes', 'timezone')
20
10
  end
21
11
 
22
12
  # TODO refactor into relationships
23
13
  def users
24
14
  @client.organization_users
25
15
  end
16
+
17
+ def as_json
18
+ super.merge({
19
+ name: name,
20
+ timezone: timezone
21
+ })
22
+ end
26
23
  end
27
24
  end
@@ -0,0 +1,58 @@
1
+ module Helium
2
+ # Abstract base class for Helium Resources returned by the API
3
+ class Resource
4
+ attr_reader :id
5
+
6
+ def initialize(client:, params:)
7
+ @client = client
8
+ @id = params["id"]
9
+ @created_at = params.dig('meta', 'created')
10
+ @updated_at = params.dig('meta', 'updated')
11
+ end
12
+
13
+ # Override equality to use id for comparisons
14
+ # @return [Boolean]
15
+ def ==(other)
16
+ self.id == other.id
17
+ end
18
+
19
+ # Override equality to use id for comparisons
20
+ # @return [Boolean]
21
+ def eql?(other)
22
+ self == other
23
+ end
24
+
25
+ # Override equality to use id for comparisons
26
+ # @return [Integer]
27
+ def hash
28
+ id.hash
29
+ end
30
+
31
+ # @return [DateTime, nil] when the resource was created
32
+ def created_at
33
+ return nil if @created_at.nil?
34
+ @_created_at ||= DateTime.parse(@created_at)
35
+ end
36
+
37
+ # @return [DateTime, nil] when the resource was last updated
38
+ def updated_at
39
+ return nil if @updated_at.nil?
40
+ @_updated_at ||= DateTime.parse(@updated_at)
41
+ end
42
+
43
+ # Inheriting resources should implement this with super
44
+ # @return [Hash] a Hash of the object's attributes for JSON
45
+ def as_json
46
+ {
47
+ id: id,
48
+ created_at: created_at,
49
+ updated_at: updated_at
50
+ }
51
+ end
52
+
53
+ # @return [String] a JSON-encoded String representing the resource
54
+ def to_json(*options)
55
+ as_json.to_json(*options)
56
+ end
57
+ end
58
+ end
data/lib/helium/sensor.rb CHANGED
@@ -1,23 +1,13 @@
1
1
  module Helium
2
- class Sensor
3
- attr_accessor :id, :name, :mac, :ports, :created_at, :updated_at
2
+ class Sensor < Resource
3
+ attr_reader :name, :mac, :ports
4
4
 
5
5
  def initialize(client:, params:)
6
- @client = client
7
- @id = params["id"]
8
- @name = params["attributes"]["name"]
9
- @mac = params["meta"]["mac"]
10
- @ports = params["meta"]["ports"]
11
- @created_at = params["meta"]["created"]
12
- @updated_at = params["meta"]["updated"]
13
- end
14
-
15
- def created_at
16
- DateTime.parse(@created_at)
17
- end
6
+ super(client: client, params: params)
18
7
 
19
- def updated_at
20
- DateTime.parse(@updated_at)
8
+ @name = params.dig('attributes', 'name')
9
+ @mac = params.dig('meta', 'mac')
10
+ @ports = params.dig('meta', 'ports')
21
11
  end
22
12
 
23
13
  def timeseries(size: 1000, port: nil, start_time: nil, end_time: nil, aggtype: nil, aggsize: nil)
@@ -31,7 +21,7 @@ module Helium
31
21
  )
32
22
  end
33
23
 
34
- # TODO these kinds of methods should be generalized into a Resource object
24
+ # TODO CRUD methods will be generalized into the Resource object
35
25
  def update(name:)
36
26
  @client.update_sensor(self, name: name)
37
27
  end
@@ -39,5 +29,14 @@ module Helium
39
29
  def destroy
40
30
  @client.delete_sensor(self)
41
31
  end
32
+
33
+ # TODO can probably generalize this a bit more
34
+ def as_json
35
+ super.merge({
36
+ name: name,
37
+ mac: mac,
38
+ ports: ports
39
+ })
40
+ end
42
41
  end
43
42
  end