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 +4 -4
- data/README.md +8 -8
- data/adafruit-io.gemspec +1 -0
- data/lib/adafruit/io.rb +1 -0
- data/lib/adafruit/io/client.rb +22 -3
- data/lib/adafruit/io/mqtt.rb +199 -0
- data/lib/adafruit/io/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82354463cf584413ee421f62dc087fa182b191a3
|
4
|
+
data.tar.gz: 7569063a8a78d7c97189a66bf89894f8c0f089dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
-
|
29
|
-
-
|
30
|
-
-
|
31
|
-
-
|
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
|
|
data/adafruit-io.gemspec
CHANGED
@@ -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"
|
data/lib/adafruit/io.rb
CHANGED
data/lib/adafruit/io/client.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
data/lib/adafruit/io/version.rb
CHANGED
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.
|
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
|
+
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
|