aws_iot_device 0.1.5 → 1.0.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +155 -148
- data/aws_iot_device.gemspec +11 -11
- data/codeclimate.yml +6 -0
- data/lib/aws_iot_device.rb +2 -1
- data/lib/aws_iot_device/mqtt_adapter.rb +1 -2
- data/lib/aws_iot_device/mqtt_adapter/client.rb +74 -6
- data/lib/aws_iot_device/mqtt_adapter/paho_mqtt_adapter.rb +207 -0
- data/lib/aws_iot_device/mqtt_adapter/ruby_mqtt_adapter.rb +10 -4
- data/lib/aws_iot_device/mqtt_shadow_client.rb +1 -0
- data/lib/aws_iot_device/mqtt_shadow_client/mqtt_manager.rb +133 -67
- data/lib/aws_iot_device/mqtt_shadow_client/shadow_action_manager.rb +229 -146
- data/lib/aws_iot_device/mqtt_shadow_client/shadow_client.rb +78 -20
- data/lib/aws_iot_device/mqtt_shadow_client/shadow_topic_manager.rb +51 -26
- data/lib/aws_iot_device/mqtt_shadow_client/topic_builder.rb +15 -30
- data/lib/aws_iot_device/version.rb +1 -1
- data/samples/config_shadow.rb +72 -0
- data/samples/mqtt_client_samples/mqtt_client_samples.rb +7 -59
- data/samples/shadow_action_samples/sample_shadow_action_update.rb +7 -61
- data/samples/shadow_client_samples/samples_shadow_client_block.rb +25 -0
- data/samples/shadow_client_samples/samples_shadow_client_delete.rb +9 -58
- data/samples/shadow_client_samples/samples_shadow_client_description.rb +64 -0
- data/samples/shadow_client_samples/samples_shadow_client_get.rb +11 -62
- data/samples/shadow_client_samples/samples_shadow_client_getting_started.rb +22 -0
- data/samples/shadow_client_samples/samples_shadow_client_update.rb +7 -58
- data/samples/shadow_topic_samples/sample_topic_manager.rb +10 -61
- metadata +71 -16
- data/lib/aws_iot_device/mqtt_adapter/mqtt_adapter.rb +0 -139
@@ -0,0 +1,207 @@
|
|
1
|
+
require 'paho-mqtt'
|
2
|
+
|
3
|
+
module AwsIotDevice
|
4
|
+
module MqttAdapter
|
5
|
+
class PahoMqttAdapter
|
6
|
+
|
7
|
+
def initialize(*args)
|
8
|
+
@client = PahoMqtt::Client.new(*args)
|
9
|
+
end
|
10
|
+
|
11
|
+
def client_id
|
12
|
+
@client.client_id
|
13
|
+
end
|
14
|
+
|
15
|
+
def connect(*args, &block)
|
16
|
+
if args.last.is_a?(Hash)
|
17
|
+
attr = args.last
|
18
|
+
attr.each_pair do |k, v|
|
19
|
+
if [:host, :port, :keep_alive, :persistent].include?(k)
|
20
|
+
@client.send("#{k}=", v)
|
21
|
+
else
|
22
|
+
raise ArgumentError, "Parameter error, invalid paramater \"#{k}\" for connect with paho-mqtt"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
@client.connect
|
27
|
+
if block_given?
|
28
|
+
begin
|
29
|
+
yield(self)
|
30
|
+
ensure
|
31
|
+
@mqtt_client.disconnect
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def publish(topic, payload="", retain=false, qos=0)
|
37
|
+
@client.publish(topic, payload, retain, qos)
|
38
|
+
end
|
39
|
+
|
40
|
+
def loop_start
|
41
|
+
Thread.new { loop_forever }
|
42
|
+
end
|
43
|
+
|
44
|
+
def loop_stop(thread)
|
45
|
+
thread.join
|
46
|
+
end
|
47
|
+
|
48
|
+
def loop_forever
|
49
|
+
loop do
|
50
|
+
@client.mqtt_loop
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def mqtt_loop
|
55
|
+
@client.mqtt_loop
|
56
|
+
end
|
57
|
+
|
58
|
+
def loop_read
|
59
|
+
@client.loop_read
|
60
|
+
end
|
61
|
+
|
62
|
+
def loop_write
|
63
|
+
@client.loop_write
|
64
|
+
end
|
65
|
+
|
66
|
+
def loop_misc
|
67
|
+
@client.loop_misc
|
68
|
+
end
|
69
|
+
|
70
|
+
def get(topic=nil, &block)
|
71
|
+
@client.loop_read(1)
|
72
|
+
end
|
73
|
+
|
74
|
+
def get_packet(topic=nil, &block)
|
75
|
+
@client.loop_read(1)
|
76
|
+
end
|
77
|
+
|
78
|
+
def generate_client_id
|
79
|
+
@client.generate_client_id
|
80
|
+
end
|
81
|
+
|
82
|
+
def disconnect(send_msg)
|
83
|
+
@client.disconnect(send_msg)
|
84
|
+
end
|
85
|
+
|
86
|
+
def connected?
|
87
|
+
@client.connected?
|
88
|
+
end
|
89
|
+
|
90
|
+
def subscribe(topic, qos)
|
91
|
+
@client.subscribe([topic, qos])
|
92
|
+
end
|
93
|
+
|
94
|
+
def subscribe_bunch(topics)
|
95
|
+
@client.subscribe(topics)
|
96
|
+
end
|
97
|
+
|
98
|
+
def unsubscribe(topic)
|
99
|
+
@client.unsubscribe(topic)
|
100
|
+
end
|
101
|
+
|
102
|
+
def unsubscribe_bunch(topics)
|
103
|
+
@client.unsubscribe(topics)
|
104
|
+
end
|
105
|
+
|
106
|
+
def set_tls_ssl_context(ca_cert=nil, cert=nil, key=nil)
|
107
|
+
@client.config_ssl_context(cert, key, ca_cert)
|
108
|
+
end
|
109
|
+
|
110
|
+
def add_callback_filter_topic(topic, callback=nil, &block)
|
111
|
+
@client.add_topic_callback(topic, callback, &block)
|
112
|
+
end
|
113
|
+
|
114
|
+
def remove_callback_filter_topic(topic)
|
115
|
+
@client.remove_topic_callback(topic)
|
116
|
+
end
|
117
|
+
|
118
|
+
def on_connack=(callback)
|
119
|
+
@client.on_connack = callback
|
120
|
+
end
|
121
|
+
|
122
|
+
def on_suback=(callback)
|
123
|
+
@client.on_suback = callback
|
124
|
+
end
|
125
|
+
|
126
|
+
def on_unsuback=(callback)
|
127
|
+
@client.on_unsuback = callback
|
128
|
+
end
|
129
|
+
|
130
|
+
def on_puback=(callback)
|
131
|
+
@client.on_puback = callback
|
132
|
+
end
|
133
|
+
|
134
|
+
def on_pubrec=(callback)
|
135
|
+
@client.on_pubrec = callback
|
136
|
+
end
|
137
|
+
|
138
|
+
def on_pubrel=(callback)
|
139
|
+
@client.on_pubrel = callback
|
140
|
+
end
|
141
|
+
|
142
|
+
def on_pubcomp=(callback)
|
143
|
+
@client.on_pubcomp = callback
|
144
|
+
end
|
145
|
+
|
146
|
+
def on_message=(callback)
|
147
|
+
@client.on_message = callback
|
148
|
+
end
|
149
|
+
|
150
|
+
def on_connack(&block)
|
151
|
+
@client.on_connack(&block)
|
152
|
+
end
|
153
|
+
|
154
|
+
def on_suback(&block)
|
155
|
+
@client.on_suback(&block)
|
156
|
+
end
|
157
|
+
|
158
|
+
def on_unsuback(&block)
|
159
|
+
@client.on_unsuback(&block)
|
160
|
+
end
|
161
|
+
|
162
|
+
def on_puback(&block)
|
163
|
+
@client.on_puback(&block)
|
164
|
+
end
|
165
|
+
|
166
|
+
def on_pubrec(&block)
|
167
|
+
@client.on_pubrec(&block)
|
168
|
+
end
|
169
|
+
|
170
|
+
def on_pubrel(&block)
|
171
|
+
@client.on_pubrel(&block)
|
172
|
+
end
|
173
|
+
|
174
|
+
def on_pubcomp(&block)
|
175
|
+
@client.on_pubcomp(&block)
|
176
|
+
end
|
177
|
+
|
178
|
+
def on_message(&block)
|
179
|
+
@client.on_message(&block)
|
180
|
+
end
|
181
|
+
|
182
|
+
def host
|
183
|
+
@client.host
|
184
|
+
end
|
185
|
+
|
186
|
+
def host=(host)
|
187
|
+
@client.host = host
|
188
|
+
end
|
189
|
+
|
190
|
+
def port
|
191
|
+
@client.port
|
192
|
+
end
|
193
|
+
|
194
|
+
def port=(port)
|
195
|
+
@client.port = port
|
196
|
+
end
|
197
|
+
|
198
|
+
def ssl
|
199
|
+
@client.ssl
|
200
|
+
end
|
201
|
+
|
202
|
+
def ssl=(ssl)
|
203
|
+
@client.ssl = ssl
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -29,7 +29,7 @@ module AwsIotDevice
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def connect(*args, &block)
|
32
|
-
client = create_client(*args) if @client.nil?
|
32
|
+
@client = create_client(*args) if @client.nil?
|
33
33
|
@client.connect(&block)
|
34
34
|
loop_start
|
35
35
|
end
|
@@ -87,7 +87,6 @@ module AwsIotDevice
|
|
87
87
|
@client.port
|
88
88
|
end
|
89
89
|
|
90
|
-
|
91
90
|
def port=(port)
|
92
91
|
@client.port = port
|
93
92
|
end
|
@@ -134,7 +133,7 @@ module AwsIotDevice
|
|
134
133
|
### Fitlering message if matching to filtered topic
|
135
134
|
topic = message.topic
|
136
135
|
if @filtered_topics.key?(topic)
|
137
|
-
callback = @filtered_topics[topic]
|
136
|
+
callback = @filtered_topics[topic]
|
138
137
|
callback.call(message)
|
139
138
|
else
|
140
139
|
on_message_callback(message)
|
@@ -144,17 +143,24 @@ module AwsIotDevice
|
|
144
143
|
end
|
145
144
|
|
146
145
|
def loop_write
|
146
|
+
puts "loop_write is unavailable for ruby-mqtt client's"
|
147
147
|
end
|
148
148
|
|
149
149
|
def loop_misc
|
150
|
+
puts "loop_misc is unavailable for ruby-mqtt client's"
|
150
151
|
end
|
151
152
|
|
152
153
|
def on_message=(callback)
|
153
154
|
@on_message = callback
|
154
155
|
end
|
155
156
|
|
157
|
+
def on_message(&block)
|
158
|
+
@on_message = block if block_given?
|
159
|
+
@on_message
|
160
|
+
end
|
161
|
+
|
156
162
|
def on_message_callback(message)
|
157
|
-
if @on_message.is_a?
|
163
|
+
if @on_message.is_a?(Proc) || @on_message.lambda?
|
158
164
|
@on_message.call(message)
|
159
165
|
end
|
160
166
|
end
|
@@ -10,49 +10,32 @@ module AwsIotDevice
|
|
10
10
|
|
11
11
|
attr_accessor :mqtt_operation_timeout_s
|
12
12
|
|
13
|
-
attr_accessor :host
|
14
|
-
|
15
|
-
attr_accessor :port
|
16
|
-
|
17
13
|
attr_accessor :ssl
|
18
14
|
|
19
15
|
def initialize(*args)
|
20
16
|
@client = create_mqtt_adapter(*args)
|
17
|
+
@mqtt_operation_timeout_s = 2
|
21
18
|
@mutex_publish = Mutex.new()
|
22
19
|
@mutex_subscribe = Mutex.new()
|
23
20
|
@mutex_unsubscribe = Mutex.new()
|
24
|
-
@ssl_configured = false
|
25
|
-
|
26
|
-
if args.last.is_a?(Hash)
|
27
|
-
attr = args.pop
|
28
|
-
attr.each_pair do |k, v|
|
29
|
-
self.send("#{k}=", v)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
if need_ssl_configure?
|
34
|
-
@client.set_tls_ssl_context(@ca_file, @cert, @key)
|
35
|
-
@ssl_configured = true
|
36
|
-
end
|
37
|
-
|
38
|
-
### Set the on_message's callback
|
39
|
-
@client.on_message = Proc.new do |message|
|
40
|
-
on_message_callback(message)
|
41
|
-
end
|
42
21
|
end
|
43
22
|
|
44
|
-
def
|
45
|
-
@
|
23
|
+
def host=(host)
|
24
|
+
@client.host = host
|
46
25
|
end
|
47
26
|
|
48
|
-
def
|
49
|
-
@
|
27
|
+
def host
|
28
|
+
@client.host
|
50
29
|
end
|
51
30
|
|
52
|
-
def
|
53
|
-
|
31
|
+
def port=(port)
|
32
|
+
@client.port = port
|
54
33
|
end
|
55
34
|
|
35
|
+
def port
|
36
|
+
@client.port
|
37
|
+
end
|
38
|
+
|
56
39
|
def client_id
|
57
40
|
@client.client_id
|
58
41
|
end
|
@@ -61,74 +44,157 @@ module AwsIotDevice
|
|
61
44
|
@client = MqttAdapter::Client.new(*args)
|
62
45
|
end
|
63
46
|
|
64
|
-
def on_message_callback(message)
|
65
|
-
puts "Received (with no custom callback registred) : "
|
66
|
-
puts "------------------- Topic: #{message.topic}"
|
67
|
-
puts "------------------- Payload: #{message.payload}"
|
68
|
-
end
|
69
|
-
|
70
47
|
def config_endpoint(host, port)
|
71
|
-
if host.nil? || port.nil?
|
72
|
-
|
73
|
-
|
74
|
-
@host = host
|
75
|
-
@port = port
|
48
|
+
raise ArgumentError, "configure endpoint either host or port is nil" if host.nil? || port.nil?
|
49
|
+
@client.host = host
|
50
|
+
@client.port = port
|
76
51
|
end
|
77
52
|
|
78
53
|
def config_ssl_context(ca_file, key, cert)
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
@client.set_tls_ssl_context(ca_file, cert, key)
|
54
|
+
self.ca_file = ca_file
|
55
|
+
self.key = key
|
56
|
+
self.cert = cert
|
57
|
+
@client.set_tls_ssl_context(@ca_file, @cert, @key)
|
83
58
|
end
|
84
59
|
|
85
|
-
def connect(
|
86
|
-
if keep_alive_interval.nil? && keep_alive_interval.is_a(Integer)
|
87
|
-
raise "connect error: keep_alive_interval cannot be a not nil Interger"
|
88
|
-
end
|
89
|
-
|
90
|
-
@client.host=(@host)
|
91
|
-
@client.port=(@port)
|
60
|
+
def connect(*args, &block)
|
92
61
|
### Execute a mqtt opration loop in background for time period defined by mqtt_connection_timeout
|
93
|
-
@client.connect(block)
|
62
|
+
@client.connect(*args, &block)
|
94
63
|
end
|
95
64
|
|
96
65
|
def disconnect
|
97
66
|
@client.disconnect
|
98
67
|
end
|
99
68
|
|
100
|
-
def publish(topic, payload="",
|
101
|
-
if topic.nil?
|
102
|
-
|
103
|
-
|
104
|
-
@mutex_publish.synchronize{
|
105
|
-
@client.publish(topic,payload,qos,retain)
|
69
|
+
def publish(topic, payload="", retain=nil, qos=0)
|
70
|
+
raise ArgumentError, "publish topic cannot be nil" if topic.nil?
|
71
|
+
@mutex_publish.synchronize {
|
72
|
+
@client.publish(topic, payload, retain, qos)
|
106
73
|
}
|
107
74
|
end
|
108
75
|
|
109
76
|
def subscribe(topic, qos=0, callback=nil)
|
110
|
-
if topic.nil?
|
111
|
-
raise "subscribe error: topic cannot be nil"
|
112
|
-
end
|
113
|
-
ret = false
|
77
|
+
raise ArgumentError, "subscribe topic cannot be nil" if topic.nil?
|
114
78
|
@mutex_subscribe.synchronize {
|
115
79
|
@client.add_callback_filter_topic(topic, callback)
|
116
|
-
@client.subscribe(topic)
|
80
|
+
@client.subscribe(topic, qos)
|
117
81
|
}
|
118
82
|
end
|
119
83
|
|
84
|
+
def subscribe_bunch(*topics)
|
85
|
+
@mutex_subscribe.synchronize {
|
86
|
+
topics.each do |topic|
|
87
|
+
@client.add_callback_filter_topic(topic.first, topic.pop) if !topic[2].nil? && topic[2].is_a?(Proc)
|
88
|
+
end
|
89
|
+
@client.subscribe_bunch(topics)
|
90
|
+
}
|
91
|
+
end
|
92
|
+
|
120
93
|
def unsubscribe(topic)
|
121
|
-
if topic.nil?
|
122
|
-
raise "unsubscribe error: topic cannot be nil"
|
123
|
-
end
|
94
|
+
raise ArgumentError, "unsubscribe topic cannot be nil" if topic.nil?
|
124
95
|
@mutex_unsubscribe.synchronize{
|
125
96
|
@client.remove_callback_filter_topic(topic)
|
126
97
|
@client.unsubscribe(topic)
|
127
98
|
}
|
128
99
|
end
|
129
100
|
|
130
|
-
def
|
131
|
-
|
101
|
+
def unsubscribe_bunch(*topics)
|
102
|
+
@mutex_unsubscribe.synchronize {
|
103
|
+
topics.each do |topic|
|
104
|
+
@client.remove_callback_filter_topic(topic)
|
105
|
+
end
|
106
|
+
@client.unsubscribe_bunch(topics)
|
107
|
+
}
|
108
|
+
end
|
109
|
+
|
110
|
+
def on_connack=(callback)
|
111
|
+
@client.on_connack = callback if paho_client?
|
112
|
+
end
|
113
|
+
|
114
|
+
def on_suback=(callback)
|
115
|
+
@client.on_suback = callback if paho_client?
|
116
|
+
end
|
117
|
+
|
118
|
+
def on_unsuback=(callback)
|
119
|
+
@client.on_unsuback = callback if paho_client?
|
120
|
+
end
|
121
|
+
|
122
|
+
def on_puback=(callback)
|
123
|
+
@client.on_puback = callback if paho_client?
|
124
|
+
end
|
125
|
+
|
126
|
+
def on_pubrec=(callback)
|
127
|
+
@client.on_pubrec = callback if paho_client?
|
128
|
+
end
|
129
|
+
|
130
|
+
def on_pubrel=(callback)
|
131
|
+
@client.on_pubrel = callback if paho_client?
|
132
|
+
end
|
133
|
+
|
134
|
+
def on_pubcomp=(callback)
|
135
|
+
@client.on_pubcomp = callback if paho_client?
|
136
|
+
end
|
137
|
+
|
138
|
+
def on_message=(callback)
|
139
|
+
@client.on_message = callback
|
140
|
+
end
|
141
|
+
|
142
|
+
def on_connack(&block)
|
143
|
+
@client.on_connack(&block) if paho_client?
|
144
|
+
end
|
145
|
+
|
146
|
+
def on_suback(&block)
|
147
|
+
@client.on_suback(&block) if paho_client?
|
148
|
+
end
|
149
|
+
|
150
|
+
def on_unsuback(&block)
|
151
|
+
@client.on_unsuback(&block) if paho_client?
|
152
|
+
end
|
153
|
+
|
154
|
+
def on_puback(&block)
|
155
|
+
@client.on_puback(&block) if paho_client?
|
156
|
+
end
|
157
|
+
|
158
|
+
def on_pubrec(&block)
|
159
|
+
@client.on_pubrec(&block) if paho_client?
|
160
|
+
end
|
161
|
+
|
162
|
+
def on_pubrel(&block)
|
163
|
+
@client.on_pubrel(&block) if paho_client?
|
164
|
+
end
|
165
|
+
|
166
|
+
def on_pubcomp(&block)
|
167
|
+
@client.on_pubcomp(&block) if paho_client?
|
168
|
+
end
|
169
|
+
|
170
|
+
def on_message(&block)
|
171
|
+
@client.on_message(&block)
|
172
|
+
end
|
173
|
+
|
174
|
+
def add_topic_callback(topic, callback, &block)
|
175
|
+
@client.add_callback_filter_topic(topic, callback, &block)
|
176
|
+
end
|
177
|
+
|
178
|
+
def remove_topic_callback(topic)
|
179
|
+
@client.remove_callback_filter_topic(topic)
|
180
|
+
end
|
181
|
+
|
182
|
+
def paho_client?
|
183
|
+
@client.adapter.class == MqttAdapter::PahoMqttAdapter
|
184
|
+
end
|
185
|
+
|
186
|
+
private
|
187
|
+
|
188
|
+
def cert=(path)
|
189
|
+
@cert = path
|
190
|
+
end
|
191
|
+
|
192
|
+
def key=(path)
|
193
|
+
@key = path
|
194
|
+
end
|
195
|
+
|
196
|
+
def ca_file=(path)
|
197
|
+
@ca_file = path
|
132
198
|
end
|
133
199
|
end
|
134
200
|
end
|