apiotics_aws_iot_client 1.0.1

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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/CODE_OF_CONDUCT.md +13 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE +201 -0
  5. data/README.md +207 -0
  6. data/Rakefile +6 -0
  7. data/apiotics-aws-iot-client-1.0.0.gem +0 -0
  8. data/apiotics_aws_client-1.0.1.gem +0 -0
  9. data/apiotics_aws_iot_client.gemspec +40 -0
  10. data/bin/console +11 -0
  11. data/bin/setup +7 -0
  12. data/codeclimate.yml +6 -0
  13. data/lib/aws_iot_device.rb +8 -0
  14. data/lib/aws_iot_device/mqtt_adapter.rb +31 -0
  15. data/lib/aws_iot_device/mqtt_adapter/client.rb +207 -0
  16. data/lib/aws_iot_device/mqtt_adapter/paho_mqtt_adapter.rb +207 -0
  17. data/lib/aws_iot_device/mqtt_adapter/ruby_mqtt_adapter.rb +183 -0
  18. data/lib/aws_iot_device/mqtt_shadow_client.rb +7 -0
  19. data/lib/aws_iot_device/mqtt_shadow_client/json_payload_parser.rb +34 -0
  20. data/lib/aws_iot_device/mqtt_shadow_client/mqtt_manager.rb +201 -0
  21. data/lib/aws_iot_device/mqtt_shadow_client/shadow_action_manager.rb +318 -0
  22. data/lib/aws_iot_device/mqtt_shadow_client/shadow_client.rb +118 -0
  23. data/lib/aws_iot_device/mqtt_shadow_client/shadow_topic_manager.rb +75 -0
  24. data/lib/aws_iot_device/mqtt_shadow_client/token_creator.rb +36 -0
  25. data/lib/aws_iot_device/mqtt_shadow_client/topic_builder.rb +35 -0
  26. data/lib/aws_iot_device/version.rb +3 -0
  27. data/samples/config_shadow.rb +72 -0
  28. data/samples/mqtt_client_samples/mqtt_client_samples.rb +38 -0
  29. data/samples/shadow_action_samples/sample_shadow_action_update.rb +25 -0
  30. data/samples/shadow_client_samples/samples_shadow_client_block.rb +25 -0
  31. data/samples/shadow_client_samples/samples_shadow_client_delete.rb +24 -0
  32. data/samples/shadow_client_samples/samples_shadow_client_description.rb +64 -0
  33. data/samples/shadow_client_samples/samples_shadow_client_get.rb +23 -0
  34. data/samples/shadow_client_samples/samples_shadow_client_getting_started.rb +22 -0
  35. data/samples/shadow_client_samples/samples_shadow_client_update.rb +30 -0
  36. data/samples/shadow_topic_samples/sample_topic_manager.rb +26 -0
  37. metadata +217 -0
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aws_iot_device/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "apiotics_aws_iot_client"
8
+ spec.version = AwsIotDevice::VERSION
9
+ spec.authors = ["Mac Dougherty", "Pierre Goudet"]
10
+ spec.email = ["info@apiotics.com"]
11
+
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
+ spec.homepage = "https://portal.apiotics.com"
15
+ spec.license = "Apache-2.0"
16
+
17
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
18
+ # delete this section to allow pushing this gem to any host.
19
+ if spec.respond_to?(:metadata)
20
+ # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
23
+ end
24
+
25
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
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
+
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 "apiotics-paho-mqtt", "~> 1.0.0"
39
+ spec.add_runtime_dependency "timers", "~> 4.1.1", ">= 4.1.1"
40
+ end
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "aws_iot"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ require "pry"
11
+ Pry.start
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,6 @@
1
+ languages:
2
+ Ruby: true
3
+ exclude_paths:
4
+ - "samples/"
5
+
6
+
@@ -0,0 +1,8 @@
1
+ require "aws_iot_device/version"
2
+ require "aws_iot_device/mqtt_adapter"
3
+ require "aws_iot_device/mqtt_shadow_client"
4
+
5
+ module AwsIotDevice
6
+ class Exception < ::Exception
7
+ end
8
+ end
@@ -0,0 +1,31 @@
1
+ #require 'facets'
2
+ require 'aws_iot_device/mqtt_adapter/client'
3
+
4
+ module AwsIotDevice
5
+ module MqttAdapter
6
+ extend self
7
+
8
+ ### Return the adapter selected for the module with either a pre-setted value or a default value
9
+ def adapter
10
+ return @adapter if @adapter
11
+ ### Calling the setter method with the default symbol 'RubyMqttAdapter' and return it.
12
+ self.adapter = :paho_mqtt_adapter
13
+ @adapter
14
+ end
15
+
16
+ ### The setter of the module's adapter attributes
17
+ def adapter=(adapter_lib)
18
+ case adapter_lib
19
+ when Symbol, String
20
+ begin
21
+ require "aws_iot_device/mqtt_adapter/#{adapter_lib}"
22
+ rescue LoadError
23
+ raise "LoadError: Could find adapters for the lib #{adapter_lib}"
24
+ end
25
+ @adapter = MqttAdapter.const_get("#{adapter_lib.to_s.camelcase(:upper)}")
26
+ else
27
+ raise "TypeError: Library name should be a String or Symbol"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,207 @@
1
+ module AwsIotDevice
2
+ module MqttAdapter
3
+ class Client
4
+
5
+ attr_reader :client_id
6
+
7
+ ### @adapter contains the name of the adapter that should be module as a third party librairy
8
+ ### The method call by the shared client are implemented by the third party or the adapter module itself.
9
+ ### @adapter default value is MqttShareLib::Adapters::RubyMqttAdapter
10
+ attr_accessor :adapter
11
+
12
+ ### @on_'event' contains the callback's [block, Proc, lambda] that should be called when 'event' is catched
13
+ ### Callbacks should be customized in the higher level class (ex. MqttManger or upper)
14
+ ### Callback should be called by some (private) handlers define in the third party librairy
15
+
16
+ ### On a MqttAdapter's create, the client adapter is set as the previously define module adapter
17
+ ### The client is then initialize with the client type of the third librairy of the adapter.
18
+ ### @client default type is MQTT::Client
19
+ def initialize(*args)
20
+ @adapter = MqttAdapter.adapter.new(*args)
21
+ end
22
+
23
+ def client_id
24
+ @adapter.client_id
25
+ end
26
+
27
+ ### The following method represent the basics common MQTT actions.
28
+ ### As possible, they should be implemented in the third party librairy
29
+ ### If not, the adpater should implement them or throw and excpetion
30
+ def connect(*args, &block)
31
+ @adapter.connect(*args, &block)
32
+ end
33
+
34
+ def publish(topic, payload='', retain=false, qos=0)
35
+ @adapter.publish(topic, payload, retain, qos)
36
+ end
37
+
38
+ def loop_start
39
+ @thread = @adapter.loop_start
40
+ end
41
+
42
+ def loop_stop
43
+ @adapter.loop_stop(@thread)
44
+ end
45
+
46
+ def loop_forever
47
+ @adapter.loop_forever
48
+ end
49
+
50
+ def mqtt_loop
51
+ @adapter.mqtt_loop
52
+ end
53
+
54
+ def loop_read
55
+ @adapter.loop_read
56
+ end
57
+
58
+ def loop_write
59
+ @adapter.loop_write
60
+ end
61
+
62
+ def loop_misc
63
+ @adapter.loop_misc
64
+ end
65
+
66
+ def get(topic=nil, &block)
67
+ @adapter.get(topic, &block)
68
+ end
69
+
70
+ def get_packet(topic=nil, &block)
71
+ @adapter.get_packet(topic, &block)
72
+ end
73
+
74
+ def generate_client_id
75
+ @adapter.generate_client_id
76
+ end
77
+
78
+ def disconnect(send_msg=true)
79
+ @adapter.disconnect(send_msg)
80
+ end
81
+
82
+ def connected?
83
+ @adapter.connected?
84
+ end
85
+
86
+ def subscribe(topic, qos)
87
+ @adapter.subscribe(topic, qos)
88
+ end
89
+
90
+ def subscribe_bunch(*topics)
91
+ @adapter.subscribe_bunch(topics)
92
+ end
93
+
94
+ def unsubscribe(topic)
95
+ @adapter.unsubscribe(topic)
96
+ end
97
+
98
+ def unsubscribe_bunch(*topics)
99
+ @adapter.unsubscribe_bunch(topics)
100
+ end
101
+
102
+ def set_tls_ssl_context(ca_cert, cert=nil, key=nil)
103
+ @adapter.set_tls_ssl_context(ca_cert, cert, key)
104
+ end
105
+
106
+ def add_callback_filter_topic(topic, callback=nil, &block)
107
+ @adapter.add_callback_filter_topic(topic, callback, &block)
108
+ end
109
+
110
+ def remove_callback_filter_topic(topic)
111
+ @adapter.remove_callback_filter_topic(topic)
112
+ end
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
+
142
+ def on_message=(callback)
143
+ @adapter.on_message = callback
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
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
+
178
+ ### The following attributes should exists in every MQTT third party librairy.
179
+ ### They are necessary (or really usefull and common) for the establishement of the connection and/or the basic Mqtt actions.
180
+ ### The setter directely change the third party client value when the getter remote the actual SharedClient instance's attribute value
181
+ def host
182
+ @adapter.host
183
+ end
184
+
185
+ def host=(host)
186
+ @adapter.host = host
187
+ end
188
+
189
+ def port
190
+ @adapter.port
191
+ end
192
+
193
+ def port=(port)
194
+ @adapter.port = port
195
+ end
196
+
197
+ # Boolean for the encrypted mode (true = ssl/tls | false = no encryption)
198
+ def ssl
199
+ @adapter.ssl
200
+ end
201
+
202
+ def ssl=(ssl)
203
+ @adapter.ssl = ssl
204
+ end
205
+ end
206
+ end
207
+ end
@@ -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