adafruit-io 2.0.0.beta.2 → 2.0.0.beta.3

Sign up to get free protection for your applications and to get access to all the features.
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