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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 009d07b7885daf8b78adfde14e6003fc57591ce1
4
- data.tar.gz: 6f0aa59513a98f56305c6c2f24e21ce60c9e9f7d
3
+ metadata.gz: 35edf7c0cb543d0095ff0d45af83739cbedb56e0
4
+ data.tar.gz: 639d254baa0e2cdd31cea8549ff96830992a9a58
5
5
  SHA512:
6
- metadata.gz: 1898993a9a78e6f6bf148d0daffddbf9b928f8168c34179b3184f1408ca38b646572e9fb0b3cba3cac21a24ebb081320f8eab96d1f7b62837e4611088466aae6
7
- data.tar.gz: 2c56a1ca2bb8693d1322bf760c39fb5f0e0b4ef4baeafb77fe5c91fc887616d5e3d87045507e4b26c0028e069c0abcace8a5a44f7c09f923be610826703e3a98
6
+ metadata.gz: 1b20075b2046770c39c864ec1a25d992d612a20aa816a124fa2d42a1845bea57dc80bd3887cb41ea5b9fb587bb513f729cb6af1a8e06020a1a810a8314ba2f73
7
+ data.tar.gz: 31f553b11f8641b2e475c869c58b78daf088d1201151770cbc1ceb1cf85300c5b23eef634c62d09623f8f55bff38fd21c9470ea3d653f43f39bf485c0096c8f9
data/.gitignore CHANGED
@@ -49,3 +49,5 @@ Gemfile.lock
49
49
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
50
50
  .rvmrc
51
51
 
52
+ .idea
53
+
data/README.md CHANGED
@@ -1,30 +1,39 @@
1
1
  <a href="https://codeclimate.com/repos/57d10b3aaee68e0a2d0016b7/feed"><img src="https://codeclimate.com/repos/57d10b3aaee68e0a2d0016b7/badges/aad862afb3ada6425b90/gpa.svg" /></a>
2
2
  [![Dependency Status](https://gemnasium.com/badges/github.com/RubyDevInc/aws-iot-device-sdk-ruby.svg)](https://gemnasium.com/github.com/RubyDevInc/aws-iot-device-sdk-ruby)
3
-
3
+ [![Gem Version](https://badge.fury.io/rb/aws_iot_device.svg)](https://badge.fury.io/rb/aws_iot_device)
4
4
 
5
5
  # AWS IoT Device SDK for Ruby
6
6
 
7
-
8
- ## Requirements
7
+ ## Contents
8
+ * [Dependencies](#dependencies)
9
+ * [Overview](#overview)
10
+ * [Installation](#installation)
11
+ * [Usage](#usage)
12
+ * [Getting started](#getting-started)
13
+ * [Sample files](#sample-files)
14
+ * [API Description](#api-description)
15
+ * [Shadow Client](#shadow-client)
16
+ * [Connection Mode](#connection-mode)
17
+ * [MQTT Adapter](#mqtt-adapter)
18
+ * [License](#license)
19
+ * [Contact](#contact)
20
+
21
+ ## Dependencies
9
22
  Ruby gems:
10
- - ruby ~> 2.2
11
- - mqtt ~> 0.4
12
- - json ~> 1.8
13
- - facets ~> 3.1
14
- - timers ~> 4.1
15
-
16
- ## Introduction
17
- The AWS IoT SDK for Ruby is a gems which enables to manage device registered as shadow/things on the AWS IoT platform. A shadow is a JSON document that describes the state of a associated thing(app, device, sensor,...). The JSON document is divided in two part, the desired and the reported state of the thing. Three operations could be done on the Shadow:
18
- - Get: read the current state of the shadow
19
- - Update: add, change or remove the attribute value of the shadow
20
- - Delete: clear all the attribute value of the shadow
23
+ - ruby >= 2.2
24
+ - mqtt >= 0.0.2
25
+ - json >= 2.0
26
+ - facets >= 3.1
27
+ - timers >= 4.1
28
+ - paho-mqtt >= 0.0.2
21
29
 
22
- The client communicates with the AWS IoT platform through the MQTT protocol. An adapter is provided to enable several implementations of the MQTT protocol and thus make the client independent form its back-end library implementation. In the current version, the default settings are using a client based on the ruby-mqtt gems. According to the shadow management, the operations are performed by sending message on the dedicated MQTT topics. The answer could be read on the corresponding MQTT topics, then some treatments could be processed thanks to a system of callback.
30
+ ## Overview
31
+ `aws_iot_device` is a gem that enables a remote client to communicate with the AWS IoT platform. The AWS IoT platform allows to register a device as a `thing`. The status of each `thing` is stored in a json format, referred as the `shadow` of a `thing`. The SDK uses the MQTT protocol to control the `thing` registered on the AWS IoT platform. The MQTT protocol is a lightweight protocol used to exchange short messages between a client and a message broker. The message broker is located on the AWS IoT platform, and the client is included in the `aws_iot_device` gem, the default client is the `paho-mqtt`. The `paho-mqtt` client has a MQTT API and a callback system to handle the events trigger by the mqtt packages.
23
32
 
24
33
  ## Installation
25
- The gem is still in a beta version. There is two way to install it, from the `gem` command or directly from sources.
26
- - From RubyGems:
27
-
34
+ The gem is currentely in its first version, key features are available but any improvements is welcomed.
35
+ There are two ways to install the gem, from [rubygems](https://rubygems.org/gems/aws_iot_device) or directly from [sources](https://github.com/RubyDevInc/aws-iot-device-sdk-ruby).
36
+ - From RubyGems:
28
37
  The gem may be find on [RubyGems](https://rubygems.org/gems/aws_iot_device) and installed with the following command:
29
38
  ```
30
39
  gem install aws_iot_device
@@ -33,168 +42,166 @@ gem install aws_iot_device
33
42
  - From sources:
34
43
 
35
44
  The gem could be download and installed manually:
45
+
36
46
  ```
37
47
  git clone https://github.com/RubyDevInc/aws-iot-device-sdk-ruby.git
38
48
  cd aws-iot-device-sdk-ruby
39
49
  bundle install
40
50
  ```
51
+ ## Usage
52
+ ### Getting started
53
+ The following example is a strait-forward way for using shadows. Check at the samples files for more detailed usage.
54
+ ```ruby
55
+ require "aws_iot_device"
56
+
57
+ host = "AWS IoT endpoint"
58
+ port = 8883
59
+ thing = "Thing Name"
60
+
61
+ root_ca_path = "Path to your CA certificate"
62
+ private_key_path = "Path to your private key"
63
+ certificate_path = "Path to your certificate"
64
+
65
+ shadow_client = AwsIotDevice::MqttShadowClient::ShadowClient.new
66
+ shadow_client.configure_endpoint(host, port)
67
+ shadow_client.configure_credentials(root_ca_path, private_key_path, certificate_path)
68
+ shadow_client.create_shadow_handler_with_name(thing, true)
69
+
70
+ shadow_client.connect
71
+ shadow_client.get_shadow do |message|
72
+ # Do what you want with the get_shadow's answer
73
+ # ...
74
+ p ":)"
75
+ end
76
+ sleep 2 #Timer to ensure that the answer is received
41
77
 
42
- ## Using the ShadowClient
43
- Some examples files are provided in the samples directory. They could be run by the following commands:
44
- ```bash
45
- ### If the gem have been install with the `gem` command
46
- ruby "sample_file".rb -c "path to certificate" -a "path to authority certificate" -k "path to key" -H "aws endpoint URI" -t "thing name"
78
+ shadow_client.disconnect
79
+ ```
47
80
 
81
+ ### Sample files
82
+ Once you have cloned the current repository the several samples files provide test on the API a multiple levels.
83
+ The shadow examples could be run with the following command :
84
+ ```
85
+ ruby samples/shadow_client_samples/samples_shadow_client_xxx.rb -c "CERTIFICATE PATH" -k "PRIVATE KEY PATH" -a "CA CERTIFICATE PATH" -H "AWS IOT ENDPOINT" -t "THING NAME"
86
+ ```
48
87
 
49
- ### If the gem have been installed from sources
50
- # Including the local libraries
51
- ruby -I lib "sample_file".rb -c "path to certificate" -a "path to authority certificate" -k "path to key" -H "aws endpoint URI" -t "thing name"
88
+ ## API Description
89
+ Thank you very much for your interst in the `aws_iot_device` gem. The following part details all the features available with the SDK.
52
90
 
53
- # Or
91
+ ### Shadow Client
92
+ The shadow client API provide the key functions to control a thing/shadow on the Aws IoT platform. The methods contain in the API could be seperate in three differents roles, the configuration roles, the communication roles, and the treatements roles.
54
93
 
55
- # With the bundle command
56
- bundle exec ruby "sample_file".rb -c "path to certificate" -a "path to authority certificate" -k "path to key" -H "aws endpoint URI" -t "thing name"
94
+ #### Configuration role
95
+ The Shadow client initializer would create the mqtt client used by the shadow client to communicate with the remote host. The parameters available on the initialization depend on the type of the chosen mqtt client. The default mqtt client type is the paho_client, the availables parameters are detailed in `paho-mqtt` gem [page](https://github.com/RubyDevInc/paho.mqtt.ruby#initialization).
96
+
97
+ The remote host(endpoint) and port could be configured with the following method:
98
+ ```
99
+ shaadow_client.configure_endpoint(host, port)
57
100
  ```
58
101
 
59
- ### Shadow Client
60
- The ShadowClient class handles the function that would acts on the shadow. It is way the easiest to manipulate the shadow thanks to the different methods of the API. The following example details step by step how to create a ShadowClient, connect it to a shadow and then execute some basic operations on the shadow :
102
+ The encryption configuration could be done with the following method:
103
+ ```
104
+ shadow_client.configure_credentials(root_ca_path, private_key_path, certificate_path)
105
+ ```
61
106
 
62
- ```ruby
63
- ### Credentials and host information needed to connect
64
- root_ca_path = "PATH_TO_YOUR_ROOT_CA_FILE"
65
- private_key_path = "PATH_TO_YOUR_PRIVATE_KEY"
66
- certificate_path = "PATH_TO_YOUR_CERTIFICATE_FILE"
107
+ The thing where the client would connect is done by the following method. The persitent_subscribe attribute is a boolean that would prevent the client to unsubscribe to the mqtt topic after every action. As the susbcription require a short time, for performace issues it might usefull to keep subscribed (default is `false`).
108
+ ```
109
+ shadow_client.create_shadow_handler_with_name(thing, persistent_subscribe)
67
110
 
68
- # For exemple for Tokyo area: host = "xxx.iot.ap-northeast-1.amazonaws.com"
69
- host = "ENDPOINT_URI_ON_AWS"
111
+ ```
70
112
 
71
- port = 8883 #default port of MQTT protocol
72
- time_out = 5
113
+ Finally, the connect method enable to send a connect request and (re)define some attributes threw a `Hash`. The available parameter are `:host`, `:port`, `:keep_alive`, `:persitent` and `:blocking`. `:persistent` and `:blocking` are detailed in the connection mode [section](#connection-mode)
114
+ ```
115
+ shadow_client.connect
116
+ ```
73
117
 
74
- ### Create and set up a ShadowClient
118
+ #### Communication role
119
+ In the API there are three methods that directely act on the remote shadow. A `timeout` define the time until which the request should be considered as a failure. The default timeout is five second. The `get` and `delete` do not accept a payload where a json format payload is mandatory for the `update` action.
120
+ ```
121
+ timeout = 2
75
122
 
76
- my_shadow_client = AwsIotDevice::MqttShadowClient::ShadowClient.new
77
- my_shadow_client.configure_endpoint(host, port)
78
- my_shadow_client.configure_credentials(root_ca_path, private_key_path, certificate_path)
123
+ shadow_client.get_shadow(timeout)
79
124
 
80
- ### Conect the ShadoaClient and attach it to existing thing
81
- my_shadow_client.connect
82
- my_shadow_client.create_shadow_handler_with_name("YOUR_THING_NAME", false)
125
+ payload = "{\"state: \": \"desired\": ..... }"
126
+ shadow_client.update_shadow(payload)
83
127
 
84
- callback = Proc.new do |message|
85
- puts "Special callback for the topic #{message.topic}"
128
+ shadow_client.delete_shadow
129
+ ```
130
+
131
+ #### Callbacks
132
+ Callbacks are small piece of code that would be executed when the answer of one action is received by the client. The Shadow client API enables to register two kind of callbacks, a generic callback and single usage callback.
133
+ For generic action (get, update, delete), the callback would be executed on every answer of the dedicated generic action. Futhermore, another callback may be executed for a single answer of a dedicated action. The generic callback could be seen as re-usable callback functions when the single usage could be seen as disposable treatment.
134
+ Both kind of callbacks must be registered as a `block`, a `proc` or a `lambda`. The followings lines provide an examples of the different callbacks usage.
135
+ ```ruby
136
+ # Register a callback for the get action as a block
137
+ shadow_client.register_get_callback do
138
+ puts "generic callback for get action"
86
139
  end
87
- ### The three basic AWS Iot operations:
88
- ### time_out is a integer reprensenting the time to keep request alive in second
89
- my_shadow_client.get_shadow(callback, time_out)
90
- # or without special callback
91
- my_shadow_client.get_shadow(nil, time_out)
92
140
 
93
- my_shadow_client.delete_shadow(callback, time_out)
141
+ # Register a callback for the delete action as a proc
142
+ shadow_client.register_delete_callback(proc { puts "generic callback for delete action"})
94
143
 
95
- ### Update need a formated payload:
96
- payload = '{ "state":{ "desired":{ "attr1":"foo" }}}'
97
- my_shadow_client.update_shadow(payload, callback, time_out)
98
- ```
144
+ # Register a callback for the update action as a lambda
145
+ shadow_client.register_update_callback(lambda {|message| puts "genereic callback for update action"})
99
146
 
147
+ # Register a callback for the delta events
148
+ shadow_client.register_delta_callback do
149
+ puts "delta have been catch in a callback"
150
+ end
100
151
 
101
- ### Shadows Topics
102
- The TopicManager class handles the subscribing and plublishing operations for a shadow. Its functions are used by the ShadowClient class during the get, update and delete operations but they also may be called directely. Publish and Subscribe requests are sent on the reserved MQTT topics of the selected shadow. For each operation, those topics have a similar structure:
103
- ```
104
- $aws/things/"SHADOW_NAME"/shadow/"ACTION_NAME"
105
- ```
106
- Depending on the acceptation of the request, the answer would be received either on the accepted or rejected MQTT topics:
107
- ```
108
- $aws/things/"SHADOW_NAME"/shadow/"ACTION_NAME"/accepted
109
- $aws/things/"SHADOW_NAME"/shadow/"ACTION_NAME"/rejected
110
- ```
111
- Another topic is reserved only for some answer of the update action, the delta topic. If the desired attributes and the reported attributes have differents values in the JSON file describing the shadow state, a message would be send on the delta to report those differences.
152
+ # Send a get request with an associated callback in a block
153
+ shadow_client.get_shadow do
154
+ puts "get thing"
155
+ end
156
+
157
+ # Send a delete request with an associated callback in a proc
158
+ shadow_client.delete_shadow(timeout, proc {puts "delete thing"})
159
+
160
+ # Send a udpate request with an associated callback in a lambda
161
+ shadow_client.update_shadow("{\"state\":{\"desired\":{\"message\":\"Hello\"}}}", timeout, lambda {|message| puts "update thing"})
162
+
163
+ # Clear out the previously registered callback for each action
164
+ shadow_client.remove_get_callback
165
+ shadow_client.remove_update_callback
166
+ shadow_client.remove_delete_callback
167
+ shadow_client.remove_delta_callback
112
168
  ```
113
- $aws/things/"SHADOW_NAME"/shadow/update/delta"
169
+
170
+ ### Client persitences
171
+ For performance issues, sometimes subscriptions and (re)connection time would better to saved. This could be done with two different persistences, the subscription persistence and the connection persistence. The subscription persistence keeps the shadow_client subscribed to action topics (get/accepted, get/rejected, update/accepted, update/rejected, delete/accepted and delete/rejected). The subscription process require a short time, the persistent subscription avoid to susbscribe before each and so saved the subscription time. The subscription persistence could be set at the initialization of the shadow handler or directely at the shadow client initialization.
172
+ ```ruby
173
+ shadow_client = AwsIotDevice::MqttShadowClient::ShadowClient.new({:shadow_name => "Thing name", :persistent_subscribe => true})
174
+ # Or
175
+ shadow_client.create_shadow_handler_with_name(shadow_name, persistent_subscribe)
114
176
  ```
115
- The TopicManager class implements the function to publish and subscribed to those reserved topic
177
+ The default subscription persistence if desactivated, so the client might subscribe/unsubscribe to reserved topics before/after every actions.
178
+
179
+ The connection persistence enables the client to keep the mqtt connection alive until the client explicitly requests to disconnect. The basic client would disconnect from the remote host if no activity has been detected for a preset keep_alive timer. There is two ways to configure the connection persistence, at the initialization of the shadow client or at the connection time.
116
180
  ```ruby
117
- root_ca_path = "PATH_TO_YOUR_ROOT_CA_FILE"
118
- private_key_path = "PATH_TO_YOUR_PRIVATE_KEY"
119
- certificate_path = "PATH_TO_YOUR_CERTIFICATE_FILE"
120
- ssl = true
121
-
122
- # For exemple for Tokyo area: host = "xxx.iot.ap-northeast-1.amazonaws.com"
123
- host = "ENDPOINT_URI_ON_AWS"
124
- port = 8883 #default port of MQTT protocol
181
+ shadow_client = AwsIotDevice::MqttShadowClient::ShadowClient.new({:persistent => true})
182
+ # Or
183
+ shadow_client.connect({:persitent => true})
184
+ ```
125
185
 
126
- mqtt_manager = AwsIotDevice::MqttShadowClient::MqttManager.new(host,
127
- port,
128
- ssl,
129
- certificate_path,
130
- private_key_path,
131
- root_ca_path)
132
186
 
133
- mqtt_manager.connect
187
+ ### MQTT Adapter
188
+ The `aws-iot-device` gem is based on a MQTT client (`paho-mqtt`) that enables the usage of basic MQTT operations.
189
+ ```ruby
190
+ mqtt_client = AwsIoTDevice::MqttShadowClient::MqttManager.new
134
191
 
135
- manager = AwsIotDevice::MqttShadowClient::ShadowTopicManager.new(mqtt_manager)
192
+ mqtt_client.config_endpoint(host, port)
193
+ mqtt_client.config_ssl_context(host, port)
194
+ mqtt_client.connect
136
195
 
137
- ### ACTION_NAME among "get", "update", "delete"
138
- manager.shadow_topic_publish(shadow_name, shadow_action, payload)
196
+ mqtt_client.subscribe(topic, qos, callback)
197
+ mqtt_client.publish(topic, "Hello world!", qos, retain)
139
198
 
140
- ### ACTION_NAME among "get", "update", "delete" or "delta"
141
- ### callback is a Proc that would be executed when message is received on the subscribed topic (default is nil)
142
- manager.shadow_topic_subscribe("SHADOW_NAME", "SHADOW_ACTION", callback=nil)
143
- manager.shadow_topic_unsubscribe(shadow_name, shadow_action)
199
+ mqtt_client.unsubscribe(topic)
200
+ mqtt_client.disconnect
144
201
  ```
202
+ For the default paho mqtt_client, some callbacks are available for each event related with the MQTT protocol. We recommend to read the `paho-mqtt` [gem page](https://github.com/RubyDevInc/paho.mqtt.ruby#handlers-and-callbacks) for more details about the mqtt callbacks usage.
145
203
 
146
- ### Shadow Action Manager
147
- The ShadowActionManager enable to the client to perform the basic action on the shadow, and then execute a default callback with the answer. A callback defined be the user and send as parameter with the action may also been executed. For each operation a task counter is set to hold the number of task which are waiting answer. The ShadowActionManager class could be initialized with two mode, persistent and not-persistent. In the not-persistent case, the client will automatically unsubscribe to action topic when its corresponding task counter go back to 0. The persistent mode will keep the client subscribed to the topic even if the task counter is 0. In the current version, subscribe to a topic require 2 second to assert the subscription is completed. The persistent mode enable to run that waiting timer only one for each operation(for the first one).
148
- ```ruby
149
- ### Directly create the ShadowManagerAction
150
- ### SUBSRIBE_MODE is a boolean, 'true' for persistent mode and (default)'false' for not-persistent
151
- client = AwsIotDevice::MqttShadowClient::ShadowActionManager.new("THING_NAME", "TOPIC_MANGER", "SUBSCRIBE_MODE")
152
-
153
- ### Or through a ShadowClient object
154
- my_shadow_client = AwsIotDevice::MqttShadowClient::ShadowClient.new
155
- client = my_shadow_client.create_shadow_handler_with_name("THING_NAME", "SUBSCRIBE_MODE")
204
+ ## License
205
+ This SDK is distributed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0).
156
206
 
157
- ### The three basic action:
158
- client.shadow_get("YOUR_CALLBACK_OR_NIL", "TIME_OUT")#TIME_OUT is a integer reprensenting the time to keep request alive in second
159
- client.shadow_update("UPDATE_PAYLOAD", "YOUR_CALLBACK_OR_NIL", "TIME_OUT")
160
- client.shadow_delete("YOUR_CALLBACK_OR_NIL", "TIME_OUT")
161
- ```
162
- ## The MQTT Manager
163
- The MqttManager class supports the operations related with the MQTT protocol, it is a customized MQTT client. According to the MQTT protocol, the MqttManager may connect, publish, subscribe and disconnect. It holds a callbacks system which are triggered by MQTT events, for exemple when a message is received on a subscribed topic. Currently (September 2016), the callback system only support the message(PUBLISH) event, other events (CONNACK, SUBACK, ...) should be supported in the future version. It is possible to perform the previous AWS Iot operation through the MqttManager, by simply typing the desired topics in the publish request. The following example details how to sent a AWS Iot get request at the MQTT level.
164
- ```ruby
165
- ### There two way to initiate the object :
166
- # 1) Send parameter when creating the object and connect
167
- client = AwsIotDevice::MqttShadowClient::MqttManager.new(host: "YOUR_AWS_ENDPOINT",
168
- port: 8883,
169
- ssl: true,
170
- cert_file: "YOUR_CERT_FILE_PATH",
171
- key_file: "YOUR_KEY_FILE_PATH",
172
- ca_file: "YOUR_ROOT_CA_FILE_PATH")
173
-
174
- # 2) A step by step initialization
175
- client = AwsIotDevice::MqttShadowClient::MqttManager.new()
176
- client.host = "YOUR_AWS_ENDPOINT"
177
- client.ssl = true
178
- client.port = 8883
179
- client.cert_file = "YOUR_CERT_FILE_PATH"
180
- client.key_file = "YOUR_KEY_FILE_PATH"
181
- client.ca_file = "YOUR_ROOT_CA_FILE_PATH"
182
-
183
- ### Then send a MQTT connect request
184
- client.connect()
185
-
186
- client.subscribe("THING_TOPIC_GET_ACCEPTED")
187
- sleep 2 # Assert the subscription is completed
188
- ### An example of AWS Iot get operation
189
- client.publish("THING_TOPIC_GET", "")
190
- sleep 2 # Assert the answer is received to execute the callback
191
- client.unsubscribe("THING_TOPIC_GET_ACCEPTED")
192
-
193
- client.disconnect()
194
- ```
195
-
196
- ## MQTT Adapters modules
197
- The previously detailed MqttManager class is said to be based on a MQTT client, in this project the MQTT client is implemented as an adapters design pattern named the MqttAdapter. The adapter design pattern enables the client implementation to be independent from the back-end MQTT library. Thanks to this design pattern, the MqttAdapter can work over several implementations of the MQTT protocol. The default implementation used in the project is the [ruby-mqtt](https://github.com/njh/ruby-mqtt) module, where some new features have been added. The adapters defined the method that should be accessible to higher level classes (ex. MqttManager).
198
-
199
- ### Ruby MQTT Adapter
200
- The [ruby-mqtt](https://github.com/njh/ruby-mqtt) gem provides a client which does the basic MQTT operation(connect, subscribe, publish ....) by reading the packets directly from the sockets. It adapts the method of the [ruby-mqtt](https://github.com/njh/ruby-mqtt) gem in order to match with the definition in the MqttAdapter. Inspired by the [Paho](http://www.eclipse.org/paho/) library, a system of (infinite)loop in background is added to this class. This loop system enables a not blocking and automated message reading. Also, a callback system is enabled to make some treatment when message are received on a subscribed MQTT topic. If no specific callback is registered for the topic a default callback is executed.
207
+ ## Contact
@@ -9,10 +9,10 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Pierre Goudet"]
10
10
  spec.email = ["p-goudet@ruby-dev.jp"]
11
11
 
12
- spec.summary = %q{A gem use to communicates with the Aws Iot platform through the MQTT protocol}
13
- spec.description = %q{A gem use to communicates with the Aws Iot platform through the MQTT protocol}
12
+ spec.summary = %q{The ruby version of the AWS IoT Device SDK. It enables to connect to AWS IoT platform and manage Things.}
13
+ spec.description = %q{The gem is using the MQTT protocol to execute the command defined by the AWS IoT platform. A default MQTT client is included in the gem, however an adapter system enables to plug another MQTT client.}
14
14
  spec.homepage = "https://github.com/RubyDevInc/aws-iot-device-sdk-ruby"
15
- spec.license = "Apache 2.0"
15
+ spec.license = "Apache-2.0"
16
16
 
17
17
  # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
18
  # delete this section to allow pushing this gem to any host.
@@ -27,13 +27,13 @@ Gem::Specification.new do |spec|
27
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
28
  spec.require_paths = ["lib"]
29
29
 
30
- spec.add_development_dependency "bundler", "~> 1.10"
31
- spec.add_development_dependency "pry"
32
- spec.add_development_dependency "rake", "~> 10.0"
33
- spec.add_development_dependency "rspec"
30
+ spec.add_development_dependency "bundler", "~> 1.10", ">= 1.10"
31
+ spec.add_development_dependency "pry", "~> 0.10.4", ">= 0.10.4"
32
+ spec.add_development_dependency "rake", "~> 10.0", ">= 1.10"
33
+ spec.add_development_dependency "rspec", "~> 3.5.0", ">= 3.5.0"
34
34
 
35
- spec.add_runtime_dependency "facets", "~> 3.1.0"
36
- spec.add_runtime_dependency "json", "~> 1.8.3"
37
- spec.add_runtime_dependency "mqtt", "~> 0.4.0"
38
- spec.add_runtime_dependency "timers", "~> 4.1.1"
35
+ spec.add_runtime_dependency "facets", "~> 3.1.0", ">= 3.1.0"
36
+ spec.add_runtime_dependency "json", "~> 2.0.2", ">= 2.0.2"
37
+ spec.add_runtime_dependency "paho-mqtt", "~> 1.0.0", ">= 1.0.0"
38
+ spec.add_runtime_dependency "timers", "~> 4.1.1", ">= 4.1.1"
39
39
  end
@@ -0,0 +1,6 @@
1
+ languages:
2
+ Ruby: true
3
+ exclude_paths:
4
+ - "samples/"
5
+
6
+
@@ -3,5 +3,6 @@ require "aws_iot_device/mqtt_adapter"
3
3
  require "aws_iot_device/mqtt_shadow_client"
4
4
 
5
5
  module AwsIotDevice
6
- # Your code goes here...
6
+ class Exception < ::Exception
7
+ end
7
8
  end
@@ -9,7 +9,7 @@ module AwsIotDevice
9
9
  def adapter
10
10
  return @adapter if @adapter
11
11
  ### Calling the setter method with the default symbol 'RubyMqttAdapter' and return it.
12
- self.adapter = :ruby_mqtt_adapter
12
+ self.adapter = :paho_mqtt_adapter
13
13
  @adapter
14
14
  end
15
15
 
@@ -21,7 +21,6 @@ module AwsIotDevice
21
21
  require "aws_iot_device/mqtt_adapter/#{adapter_lib}"
22
22
  rescue LoadError
23
23
  raise "LoadError: Could find adapters for the lib #{adapter_lib}"
24
- exit
25
24
  end
26
25
  @adapter = MqttAdapter.const_get("#{adapter_lib.to_s.camelcase(:upper)}")
27
26
  else
@@ -48,9 +48,9 @@ module AwsIotDevice
48
48
  end
49
49
 
50
50
  def mqtt_loop
51
- @adapter.loop
51
+ @adapter.mqtt_loop
52
52
  end
53
-
53
+
54
54
  def loop_read
55
55
  @adapter.loop_read
56
56
  end
@@ -83,30 +83,98 @@ module AwsIotDevice
83
83
  @adapter.connected?
84
84
  end
85
85
 
86
- def subscribe(topic)
87
- @adapter.subscribe(topic)
86
+ def subscribe(topic, qos)
87
+ @adapter.subscribe(topic, qos)
88
88
  end
89
89
 
90
+ def subscribe_bunch(*topics)
91
+ @adapter.subscribe_bunch(topics)
92
+ end
93
+
90
94
  def unsubscribe(topic)
91
95
  @adapter.unsubscribe(topic)
92
96
  end
93
97
 
98
+ def unsubscribe_bunch(*topics)
99
+ @adapter.unsubscribe_bunch(topics)
100
+ end
101
+
94
102
  def set_tls_ssl_context(ca_cert, cert=nil, key=nil)
95
103
  @adapter.set_tls_ssl_context(ca_cert, cert, key)
96
104
  end
97
105
 
98
- def add_callback_filter_topic(topic, callback)
99
- @adapter.add_callback_filter_topic(topic, callback)
106
+ def add_callback_filter_topic(topic, callback=nil, &block)
107
+ @adapter.add_callback_filter_topic(topic, callback, &block)
100
108
  end
101
109
 
102
110
  def remove_callback_filter_topic(topic)
103
111
  @adapter.remove_callback_filter_topic(topic)
104
112
  end
105
113
 
114
+ def on_connack=(callback)
115
+ @adapter.on_connack = callback
116
+ end
117
+
118
+ def on_suback=(callback)
119
+ @adapter.on_suback = callback
120
+ end
121
+
122
+ def on_unsuback=(callback)
123
+ @adapter.on_unsuback = callback
124
+ end
125
+
126
+ def on_puback=(callback)
127
+ @adapter.on_puback = callback
128
+ end
129
+
130
+ def on_pubrec=(callback)
131
+ @adapter.on_pubrec = callback
132
+ end
133
+
134
+ def on_pubrel=(callback)
135
+ @adapter.on_pubrel = callback
136
+ end
137
+
138
+ def on_pubcomp=(callback)
139
+ @adapter.on_pubcomp = callback
140
+ end
141
+
106
142
  def on_message=(callback)
107
143
  @adapter.on_message = callback
108
144
  end
145
+
146
+ def on_connack(&block)
147
+ @adapter.on_connack(&block)
148
+ end
149
+
150
+ def on_suback(&block)
151
+ @adapter.on_suback(&block)
152
+ end
153
+
154
+ def on_unsuback(&block)
155
+ @adapter.on_unsuback(&block)
156
+ end
157
+
158
+ def on_puback(&block)
159
+ @adapter.on_puback(&block)
160
+ end
161
+
162
+ def on_pubrec(&block)
163
+ @adapter.on_pubrec(&block)
164
+ end
109
165
 
166
+ def on_pubrel(&block)
167
+ @adapter.on_pubrel(&block)
168
+ end
169
+
170
+ def on_pubcomp(&block)
171
+ @adapter.on_pubcomp(&block)
172
+ end
173
+
174
+ def on_message(&block)
175
+ @adapter.on_message(&block)
176
+ end
177
+
110
178
  ### The following attributes should exists in every MQTT third party librairy.
111
179
  ### They are necessary (or really usefull and common) for the establishement of the connection and/or the basic Mqtt actions.
112
180
  ### The setter directely change the third party client value when the getter remote the actual SharedClient instance's attribute value