adafruit-io 2.0.0.beta.2 → 2.0.0.beta.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: d4297937d68a3bd1575e457d6b9c9f4d6ed5eb70
4
- data.tar.gz: e65ddd98403a46d3ef723644a46a6d8cdc3a620d
3
+ metadata.gz: 82354463cf584413ee421f62dc087fa182b191a3
4
+ data.tar.gz: 7569063a8a78d7c97189a66bf89894f8c0f089dd
5
5
  SHA512:
6
- metadata.gz: e2a5fa45df7fb98c03a306c9aa4b7c9258fdd4fbe0797aa237dda61db075ffbcf389e2e40c9da075a1db099b0e87fdc6f4e5804caada82813b96f8e07782266b
7
- data.tar.gz: 82d5d3d829434e7c108b155cc6c8d573b62d76d8b48267d85c559e0695098380ce2138b32e0772ab381258a10077fead91597cbef8f3dfd6bc60f35d8d62eb09
6
+ metadata.gz: d3dd1a6feec6e1804a08c0b5a805fb2053d35a4854acd354e018dc5f2815cb57454c7fb433eaf01be3ce1578f4e65a60b5b531aec8bcc69b6811d327c466fc23
7
+ data.tar.gz: 69e5cdb283b4d8d615fc3c575d0df498f82ecd04c1933b90f3d507a1cdd4c6983fcef7506040d226f60d788f3c2f10195351ce77ab31a877c678a838ab6e0db3
data/README.md CHANGED
@@ -25,14 +25,14 @@ It is our goal to eventually support all API V2 methods, but that will happen in
25
25
  - [x] Feeds `2.0.0.beta.1`
26
26
  - [x] Data `2.0.0.beta.1`
27
27
  - [x] Groups `2.0.0.beta.1`
28
- - Activities
29
- - Blocks
30
- - Dashboards
31
- - MQTT
32
- - Permissions
33
- - Sessions
34
- - Tokens
35
- - Triggers
28
+ - [x] MQTT `2.0.0.beta.3`
29
+ - [] Activities
30
+ - [] Blocks
31
+ - [] Dashboards
32
+ - [] Permissions
33
+ - [] Sessions
34
+ - [] Tokens
35
+ - [] Triggers
36
36
 
37
37
  ## Installation
38
38
 
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_dependency "faraday", "~> 0.8"
24
24
  spec.add_dependency "faraday_middleware", "~> 0.9"
25
25
  spec.add_dependency "activesupport", "~> 4.2"
26
+ spec.add_dependency "mqtt", "~> 0.4"
26
27
 
27
28
  spec.add_development_dependency "bundler", "~> 1.5"
28
29
  spec.add_development_dependency "rake", "~> 10.4"
@@ -1,4 +1,5 @@
1
1
  require "adafruit/io/client"
2
+ require "adafruit/io/mqtt"
2
3
  require "adafruit/io/version"
3
4
 
4
5
  module Adafruit
@@ -1,5 +1,4 @@
1
1
  require 'json'
2
- require 'uri'
3
2
 
4
3
  require 'faraday'
5
4
  require 'faraday_middleware'
@@ -71,10 +70,30 @@ module Adafruit
71
70
  end
72
71
 
73
72
  def api_url(username, *args)
74
- to_join = ['api', 'v2', username].concat(args)
73
+ safe_path_join *['api', 'v2', username].concat(args)
74
+ end
75
+
76
+ # safely build URL paths from segments
77
+ def safe_path_join(*paths)
78
+ paths = paths.compact.reject(&:empty?)
79
+ last = paths.length - 1
80
+ paths.each_with_index.map { |path, index|
81
+ safe_path_expand(path, index, last)
82
+ }.join
83
+ end
84
+
85
+ def safe_path_expand(path, current, last)
86
+ if path[0] === '/' && current != 0
87
+ path = path[1..-1]
88
+ end
89
+
90
+ unless path[-1] === '/' || current == last
91
+ path = [path, '/']
92
+ end
75
93
 
76
- File.join(*to_join)
94
+ path
77
95
  end
96
+
78
97
  end
79
98
  end
80
99
  end
@@ -0,0 +1,199 @@
1
+ require 'mqtt'
2
+
3
+ #
4
+ # Adafruit::IO::MQTT provides a simple Adafruit IO aware wrapper around the
5
+ # Ruby MQTT library at https://github.com/njh/ruby-mqtt.
6
+ #
7
+ # Our primary goal is to provide basic MQTT access to feeds.
8
+ #
9
+ # For example, publishing to a feed is as simple as:
10
+ #
11
+ # mqtt = Adafruit::IO::MQTT.new user, key
12
+ # mqtt.publish('feed-key', 1)
13
+ #
14
+ # And subscribing to a feed is just as easy:
15
+ #
16
+ # mqtt = Adafruit::IO::MQTT.new user, key
17
+ # mqtt.subscribe('feed-key')
18
+ # mqtt.get do |topic, value|
19
+ # puts "GOT VALUE FROM #{topic}: #{value}"
20
+ # end
21
+ #
22
+ # If you need to access different MQTT endpoints or data formats (JSON, CSV)
23
+ # you can use the MQTT library directly:
24
+ #
25
+ # mqtt = Adafruit::IO::MQTT.new user, key
26
+ # mqtt.client.get("#{user}/groups/group-key/json") do |topic, message|
27
+ # payload = JSON.parse(message)
28
+ # # etc...
29
+ # end
30
+ #
31
+ # Documentation for Ruby MQTT is available at http://www.rubydoc.info/gems/mqtt/MQTT/Client
32
+ #
33
+ module Adafruit
34
+ module IO
35
+ class MQTT
36
+
37
+ # provide access to the raw MQTT library client
38
+ attr_reader :client
39
+
40
+ def initialize(username, key, opts={})
41
+ @options = {
42
+ uri: 'io.adafruit.com',
43
+ protocol: 'mqtts',
44
+ port: 8883,
45
+ username: username,
46
+ key: key
47
+ }.merge(opts)
48
+
49
+ @connect_uri = "%{protocol}://%{username}:%{key}@%{uri}" % @options
50
+
51
+ connect
52
+ end
53
+
54
+ def connect
55
+ if @client.nil? || !@client.connected?
56
+ @client = ::MQTT::Client.connect @connect_uri, @options[:port], ack_timeout: 10
57
+ end
58
+ end
59
+
60
+ def disconnect
61
+ if @client && @client.connected?
62
+ @client.disconnect
63
+ end
64
+ end
65
+
66
+ # Publish value to feed with given key
67
+ def publish(key, value, location={})
68
+ raise 'client is not connected' unless @client.connected?
69
+
70
+ topic = key_to_feed_topic(key)
71
+ location = indifferent_keys(location)
72
+ payload = payload_from_value_with_location(value, location)
73
+
74
+ @client.publish(topic, payload)
75
+ end
76
+
77
+ # Publish to multiple feeds within a group.
78
+ #
79
+ # - `key` is a group key
80
+ # - `values` is a hash where keys are feed keys and values are the
81
+ # published value.
82
+ # - `location` is the optional { :lat, :lon, :ele } hash specifying the
83
+ # location data for this publish event.
84
+ #
85
+ def publish_group(key, values, location={})
86
+ raise 'client is not connected' unless @client.connected?
87
+ raise 'values must be a hash' unless values.is_a?(Hash)
88
+
89
+ topic = key_to_group_topic(key, false)
90
+ location = indifferent_keys(location)
91
+ payload = payload_from_values_with_location(values, location)
92
+
93
+ @client.publish(topic, payload)
94
+ end
95
+
96
+ # Subscribe to the feed with the given key. Use .get to retrieve messages
97
+ # from subscribed feeds.
98
+ def subscribe(key)
99
+ raise 'client is not connected' unless @client.connected?
100
+
101
+ topic = key_to_feed_topic(key)
102
+ @client.subscribe(topic)
103
+ end
104
+
105
+ def unsubscribe(key)
106
+ raise 'client is not connected' unless @client.connected?
107
+
108
+ topic = key_to_feed_topic(key)
109
+ @client.unsubscribe(topic)
110
+ end
111
+
112
+ # Subscribe to a group with the given key.
113
+ #
114
+ # NOTE: Unlike feed subscriptions, group subscriptions return a JSON
115
+ # representation of the group record with a 'feeds' property containing a
116
+ # JSON object whose keys are feed keys and whose values are the last
117
+ # value received for that feed.
118
+ def subscribe_group(key)
119
+ raise 'client is not connected' unless @client.connected?
120
+
121
+ topic = key_to_group_topic(key)
122
+ @client.subscribe(topic)
123
+ end
124
+
125
+ # Retrieve the last value received from the MQTT connection for any
126
+ # subscribed feeds or groups. This is a blocking method, which means it
127
+ # won't return until a message is retrieved.
128
+ #
129
+ # Returns [topic, message] or yields it into the given block.
130
+ #
131
+ # With no block:
132
+ #
133
+ # mqtt_client.subscribe('feed-key')
134
+ # loop do
135
+ # topic, message = mqtt_client.get
136
+ # # do something
137
+ # end
138
+ #
139
+ # With a block:
140
+ #
141
+ # mqtt_client.subscribe('feed-key')
142
+ # mqtt_client.get do |topic, message|
143
+ # # do something
144
+ # end
145
+ #
146
+ # NOTE: if a feed already has a value, subscribing and calling get will
147
+ # immediately return the most recent value for the subscription,
148
+ # regardless of when it was received by IO.
149
+ def get(&block)
150
+ @client.get(&block)
151
+ end
152
+
153
+ private
154
+
155
+ def key_to_feed_topic(key)
156
+ "%s/f/%s" % [@options[:username], key]
157
+ end
158
+
159
+ def key_to_group_topic(key, json=true)
160
+ "%s/g/%s%s" % [@options[:username], key, (json ? '/json' : '')]
161
+ end
162
+
163
+ def payload_from_value_with_location(value, location)
164
+ payload = { value: value.to_s }
165
+
166
+ if location.has_key?('lat') && location.has_key?['lon']
167
+ %w(lat lon ele).each do |f|
168
+ payload[f] = location[f]
169
+ end
170
+ end
171
+
172
+ JSON.generate payload
173
+ end
174
+
175
+ def payload_from_values_with_location(values, location)
176
+ payload = { feeds: values }
177
+
178
+ if location.has_key?('lat') && location.has_key?['lon']
179
+ payload[:location] = {}
180
+
181
+ %w(lat lon ele).each do |f|
182
+ payload[:location][f] = location[f]
183
+ end
184
+ end
185
+
186
+ JSON.generate payload
187
+ end
188
+
189
+ def indifferent_keys(hash)
190
+ hash.keys.inject({}) {|new_hash, key|
191
+ new_hash[key.to_s] = hash[key]
192
+ new_hash[key.to_sym] = hash[key]
193
+
194
+ new_hash
195
+ }
196
+ end
197
+ end
198
+ end
199
+ end
@@ -1,5 +1,5 @@
1
1
  module Adafruit
2
2
  module IO
3
- VERSION = "2.0.0.beta.2"
3
+ VERSION = "2.0.0.beta.3"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adafruit-io
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta.2
4
+ version: 2.0.0.beta.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Cooper
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-04-12 00:00:00.000000000 Z
12
+ date: 2017-04-13 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
@@ -53,6 +53,20 @@ dependencies:
53
53
  - - "~>"
54
54
  - !ruby/object:Gem::Version
55
55
  version: '4.2'
56
+ - !ruby/object:Gem::Dependency
57
+ name: mqtt
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: '0.4'
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.4'
56
70
  - !ruby/object:Gem::Dependency
57
71
  name: bundler
58
72
  requirement: !ruby/object:Gem::Requirement
@@ -100,6 +114,7 @@ files:
100
114
  - lib/adafruit/io/client/groups.rb
101
115
  - lib/adafruit/io/client/tokens.rb
102
116
  - lib/adafruit/io/configurable.rb
117
+ - lib/adafruit/io/mqtt.rb
103
118
  - lib/adafruit/io/request_handler.rb
104
119
  - lib/adafruit/io/version.rb
105
120
  homepage: https://github.com/adafruit/io-client-ruby