aws_iot_device 0.1.5 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/README.md +155 -148
  4. data/aws_iot_device.gemspec +11 -11
  5. data/codeclimate.yml +6 -0
  6. data/lib/aws_iot_device.rb +2 -1
  7. data/lib/aws_iot_device/mqtt_adapter.rb +1 -2
  8. data/lib/aws_iot_device/mqtt_adapter/client.rb +74 -6
  9. data/lib/aws_iot_device/mqtt_adapter/paho_mqtt_adapter.rb +207 -0
  10. data/lib/aws_iot_device/mqtt_adapter/ruby_mqtt_adapter.rb +10 -4
  11. data/lib/aws_iot_device/mqtt_shadow_client.rb +1 -0
  12. data/lib/aws_iot_device/mqtt_shadow_client/mqtt_manager.rb +133 -67
  13. data/lib/aws_iot_device/mqtt_shadow_client/shadow_action_manager.rb +229 -146
  14. data/lib/aws_iot_device/mqtt_shadow_client/shadow_client.rb +78 -20
  15. data/lib/aws_iot_device/mqtt_shadow_client/shadow_topic_manager.rb +51 -26
  16. data/lib/aws_iot_device/mqtt_shadow_client/topic_builder.rb +15 -30
  17. data/lib/aws_iot_device/version.rb +1 -1
  18. data/samples/config_shadow.rb +72 -0
  19. data/samples/mqtt_client_samples/mqtt_client_samples.rb +7 -59
  20. data/samples/shadow_action_samples/sample_shadow_action_update.rb +7 -61
  21. data/samples/shadow_client_samples/samples_shadow_client_block.rb +25 -0
  22. data/samples/shadow_client_samples/samples_shadow_client_delete.rb +9 -58
  23. data/samples/shadow_client_samples/samples_shadow_client_description.rb +64 -0
  24. data/samples/shadow_client_samples/samples_shadow_client_get.rb +11 -62
  25. data/samples/shadow_client_samples/samples_shadow_client_getting_started.rb +22 -0
  26. data/samples/shadow_client_samples/samples_shadow_client_update.rb +7 -58
  27. data/samples/shadow_topic_samples/sample_topic_manager.rb +10 -61
  28. metadata +71 -16
  29. 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? Proc
163
+ if @on_message.is_a?(Proc) || @on_message.lambda?
158
164
  @on_message.call(message)
159
165
  end
160
166
  end
@@ -2,5 +2,6 @@ require 'aws_iot_device/mqtt_shadow_client/shadow_client'
2
2
 
3
3
  module AwsIotDevice
4
4
  module MqttShadowClient
5
+ ACTION_NAME = %w(get update delete delta).freeze
5
6
  end
6
7
  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 cert_file=(path)
45
- @cert = path
23
+ def host=(host)
24
+ @client.host = host
46
25
  end
47
26
 
48
- def key_file=(path)
49
- @key = path
27
+ def host
28
+ @client.host
50
29
  end
51
30
 
52
- def ca_file=(path)
53
- @ca_file = path
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
- raise "config_endpoint error: either host || port is undefined error"
73
- end
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
- @ca_file = ca_file
80
- @key = key
81
- @cert = cert
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(keep_alive_interval=30, &block)
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="", qos=0, retain=nil)
101
- if topic.nil?
102
- raise "publish error: topic cannot be nil"
103
- end
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 need_ssl_configure?
131
- !( @ca_file.nil? || @cert.nil? || @key.nil? ) && @ssl
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