aws_iot_device 0.1.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.
Files changed (31) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +51 -0
  3. data/CODE_OF_CONDUCT.md +13 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE +201 -0
  6. data/README.md +175 -0
  7. data/Rakefile +6 -0
  8. data/aws_iot_device.gemspec +39 -0
  9. data/bin/console +11 -0
  10. data/bin/setup +7 -0
  11. data/lib/aws_iot_device.rb +7 -0
  12. data/lib/aws_iot_device/mqtt_adapter.rb +32 -0
  13. data/lib/aws_iot_device/mqtt_adapter/client.rb +139 -0
  14. data/lib/aws_iot_device/mqtt_adapter/mqtt_adapter.rb +139 -0
  15. data/lib/aws_iot_device/mqtt_adapter/ruby_mqtt_adapter.rb +176 -0
  16. data/lib/aws_iot_device/mqtt_shadow_client.rb +6 -0
  17. data/lib/aws_iot_device/mqtt_shadow_client/json_payload_parser.rb +34 -0
  18. data/lib/aws_iot_device/mqtt_shadow_client/mqtt_manager.rb +135 -0
  19. data/lib/aws_iot_device/mqtt_shadow_client/shadow_action_manager.rb +235 -0
  20. data/lib/aws_iot_device/mqtt_shadow_client/shadow_client.rb +60 -0
  21. data/lib/aws_iot_device/mqtt_shadow_client/shadow_topic_manager.rb +50 -0
  22. data/lib/aws_iot_device/mqtt_shadow_client/token_creator.rb +32 -0
  23. data/lib/aws_iot_device/mqtt_shadow_client/topic_builder.rb +50 -0
  24. data/lib/aws_iot_device/version.rb +3 -0
  25. data/samples/mqtt_client_samples/mqtt_client_samples.rb +90 -0
  26. data/samples/shadow_action_samples/sample_shadow_action_update.rb +79 -0
  27. data/samples/shadow_client_samples/samples_shadow_client_delete.rb +73 -0
  28. data/samples/shadow_client_samples/samples_shadow_client_get.rb +74 -0
  29. data/samples/shadow_client_samples/samples_shadow_client_update.rb +81 -0
  30. data/samples/shadow_topic_samples/sample_topic_manager.rb +77 -0
  31. metadata +186 -0
@@ -0,0 +1,50 @@
1
+ require 'aws_iot_device/mqtt_shadow_client/topic_builder'
2
+
3
+ module AwsIotDevice
4
+ module MqttShadowClient
5
+ class ShadowTopicManager
6
+
7
+ def initialize(mqtt_manager)
8
+ if mqtt_manager.nil?
9
+ raise "TopicAction_error: TopicAction should be initialized with a mqtt_manager but was undefined"
10
+ end
11
+ @mqtt_manager = mqtt_manager
12
+ @sub_unsub_mutex = Mutex.new()
13
+ end
14
+
15
+ def client_id
16
+ @mqtt_manager.client_id
17
+ end
18
+
19
+ def shadow_topic_publish(shadow_name, shadow_action, payload)
20
+ topic = TopicBuilder.new(shadow_name, shadow_action)
21
+ @mqtt_manager.publish(topic.get_topic_general, payload, false, 0)
22
+ end
23
+
24
+ def shadow_topic_subscribe(shadow_name, shadow_action, callback=nil)
25
+ @sub_unsub_mutex.synchronize(){
26
+ topic = TopicBuilder.new(shadow_name, shadow_action)
27
+ if topic.is_delta?(shadow_action)
28
+ @mqtt_manager.subscribe(topic.get_topic_delta, 0, callback)
29
+ else
30
+ @mqtt_manager.subscribe(topic.get_topic_accepted, 0, callback)
31
+ @mqtt_manager.subscribe(topic.get_topic_rejected, 0, callback)
32
+ end
33
+ }
34
+ sleep 2
35
+ end
36
+
37
+ def shadow_topic_unsubscribe(shadow_name, shadow_action)
38
+ @sub_unsub_mutex.synchronize(){
39
+ topic = TopicBuilder.new(shadow_name, shadow_action)
40
+ if topic.is_delta?(shadow_name)
41
+ @mqtt_manager.unsubscribe(topic.get_topic_delta)
42
+ else
43
+ @mqtt_manager.unsubscribe(topic.get_topic_accepted)
44
+ @mqtt_manager.unsubscribe(topic.get_topic_rejected)
45
+ end
46
+ }
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,32 @@
1
+ require 'securerandom'
2
+ require 'timers'
3
+ require 'thread'
4
+ require 'json'
5
+
6
+ module AwsIotDevice
7
+ module MqttShadowClient
8
+ class TokenCreator
9
+ ### This class manage the clients token.
10
+ ### Every actions receive a token for a certian interval, meaning that action is waiting to be proceed.
11
+ ### When token time run out or the actions have been treated token should deleted.
12
+
13
+ def initialize(shadow_name, client_id)
14
+ @shadow_name = shadow_name
15
+ @client_id = client_id
16
+ @sequence_number = 0
17
+ end
18
+
19
+ def create_next_token
20
+ token = ""
21
+ token << "#{@client_id}" << "_" << "#{@shadow_name}" << "_" << "#{@sequence_number}" << "_" << "#{random_token_string(5)}"
22
+ end
23
+
24
+ private
25
+
26
+ def random_token_string(lenght)
27
+ charset = Array('A'..'Z') + Array('a'..'z') + Array('0'..'9')
28
+ Array.new(lenght) { charset.sample }.join
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,50 @@
1
+ module AwsIotDevice
2
+ module MqttShadowClient
3
+ class TopicBuilder
4
+ ACTION_NAME = %w(get update delete delta).freeze
5
+
6
+ def initialize(shadow_name, action_name)
7
+ unless ACTION_NAME.include?(action_name)
8
+ raise "action_name_error: unreconized action_name \"#{action_name}\""
9
+ end
10
+
11
+ if shadow_name.nil?
12
+ raise "shadow_name_error: shadow_name is required but undefined"
13
+
14
+ end
15
+
16
+ @shadow_name = shadow_name
17
+ @action_name = action_name
18
+
19
+ ### The case of delta's action
20
+ if is_delta?(action_name)
21
+ @topic_delta = "$aws/things/#{shadow_name}/shadow/update/delta"
22
+ else
23
+ @topic_general = "$aws/things/#{shadow_name}/shadow/#{action_name}"
24
+ @topic_accepted = "$aws/things/#{shadow_name}/shadow/#{action_name}/accepted"
25
+ @topic_rejected = "$aws/things/#{shadow_name}/shadow/#{action_name}/rejected"
26
+ end
27
+ end
28
+
29
+ def is_delta?(action_name)
30
+ action_name == ACTION_NAME[3]
31
+ end
32
+
33
+ def get_topic_general
34
+ @topic_general
35
+ end
36
+
37
+ def get_topic_accepted
38
+ @topic_accepted
39
+ end
40
+
41
+ def get_topic_rejected
42
+ @topic_rejected
43
+ end
44
+
45
+ def get_topic_delta
46
+ @topic_delta
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,3 @@
1
+ module AwsIotDevice
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,90 @@
1
+ require 'aws_iot_device'
2
+ require 'optparse'
3
+
4
+ options = {}
5
+
6
+ OptionParser.new do |opts|
7
+ opts.banner = "Basic usage basic_greeting.rb -c \"YOUR_CERTIFICATE_PATH\" -k \"YOUR_KEY_FILE_PATH\" -ca \"YOUR_ROOT_CA_PATH -H \"YOUR_ENDPOINT\" -p 8883\n"
8
+
9
+ opts.separator ""
10
+ opts.separator "Common options"
11
+ opts.on_tail("-h", "--help", "--usage", "Show this message") do
12
+ puts opts
13
+ exit
14
+ end
15
+
16
+ opts.on("-H", "--host [END_POINT]", "The endpoint where you want to connect") do |host|
17
+ options[:host] = host
18
+ end
19
+
20
+ opts.on("-p", "--port [MQTT_PORT]", "The port used for the connection Default is 8883") do |port|
21
+ options[:port] = port
22
+ end
23
+
24
+ opts.on("-c", "--cert [CERT_FILE_PATH]", "The path to the certificate file of the private key.") do |cert|
25
+ options[:cert] = cert
26
+ end
27
+
28
+ opts.on("-k", "--key [KEY_FILE_PATH]", "The path to private key file that would be used for encryption") do |key|
29
+ options[:key] = key
30
+ end
31
+
32
+ opts.on("-a", "--root_ca [ROOT_CA_PATH]", "The path to the authority certification file") do |root_ca|
33
+ options[:root_ca] = root_ca
34
+ end
35
+ end.parse!(ARGV)
36
+
37
+
38
+ host = options[:host]
39
+ port = options[:port] || 8883
40
+ cert_file_path = options[:cert]
41
+ key_file_path = options[:key]
42
+ ca_file_path = options[:root_ca]
43
+
44
+ client = AwsIotDevice::MqttShadowClient::MqttManager.new(host: host,
45
+ port: port,
46
+ ssl: true,
47
+ cert_file: cert_file_path,
48
+ key_file: key_file_path,
49
+ ca_file: ca_file_path)
50
+
51
+ client2 = AwsIotDevice::MqttShadowClient::MqttManager.new
52
+
53
+ client2.config_endpoint(host, port)
54
+ client2.ssl = true
55
+ client2.config_ssl_context(ca_file_path, key_file_path, cert_file_path)
56
+
57
+ client.connect()
58
+ client2.connect()
59
+
60
+ callback = Proc.new do |message|
61
+ p " Client1 catch message event"
62
+ p "--- Topic: #{message.topic}"
63
+ p "--- Payload: #{message.payload}"
64
+ end
65
+
66
+ callback2 = Proc.new do |message|
67
+ p " Client2 catch message event"
68
+ p "--- Topic: #{message.topic}"
69
+ p "--- Payload: #{message.payload}"
70
+ end
71
+
72
+ client.subscribe("topic_2", 0, callback)
73
+ client2.subscribe("topic_1", 0,callback2)
74
+
75
+
76
+ puts "# STARTING EXAMPLE #"
77
+ sleep 2
78
+ client.publish("topic_1", "Hello Sir. My name is client 1. How do you do? ")
79
+ sleep 2
80
+ client2.publish("topic_2", "Hello Mister Client 1. My name is client 2. How do you do?")
81
+
82
+ 2.times do
83
+ client.publish("topic_1", "How do you do?")
84
+ sleep 1
85
+ client2.publish("topic_2", "How do you do?")
86
+ sleep 1
87
+ end
88
+
89
+ client.disconnect
90
+ client2.disconnect
@@ -0,0 +1,79 @@
1
+ require 'aws_iot_device'
2
+ require 'optparse'
3
+
4
+ options = {}
5
+
6
+ OptionParser.new do |opts|
7
+ opts.banner = "Basic usage basic_greeting.rb -c \"YOUR_CERTIFICATE_PATH\" -k \"YOUR_KEY_FILE_PATH\" -ca \"YOUR_ROOT_CA_PATH -H \"YOUR_ENDPOINT\" -p 8883\n"
8
+ opts.separator ""
9
+ opts.separator "Common options"
10
+ opts.on_tail("-h", "--help", "--usage", "Show this message") do
11
+ puts opts
12
+ exit
13
+ end
14
+
15
+ opts.on("-H", "--host [END_POINT]", "The endpoint where you want to connect") do |host|
16
+ options[:host] = host
17
+ end
18
+
19
+ opts.on("-p", "--port [MQTT_PORT]", "The port used for the connection Default is 8883") do |port|
20
+ options[:port] = port
21
+ end
22
+
23
+ opts.on("-c", "--cert [CERT_FILE_PATH]", "The path to the certificate file of the private key.") do |cert|
24
+ options[:cert] = cert
25
+ end
26
+
27
+ opts.on("-k", "--key [KEY_FILE_PATH]", "The path to private key file that would be used for encryption") do |key|
28
+ options[:key] = key
29
+ end
30
+
31
+ opts.on("-a", "--root_ca [ROOT_CA_PATH]", "The path to the authority certification file") do |root_ca|
32
+ options[:root_ca] = root_ca
33
+ end
34
+
35
+ opts.on("-t", "--thing [THING_NAME]", "The Thing name on which the action would be done") do |thing|
36
+ options[:things] = thing
37
+ end
38
+ end.parse!(ARGV)
39
+
40
+
41
+ host = options[:host]
42
+ port = options[:port] || 8883
43
+ cert_file_path = options[:cert]
44
+ key_file_path = options[:key]
45
+ ca_file_path = options[:root_ca]
46
+ thing = options[:things]
47
+
48
+ mqtt_client = AwsIotDevice::MqttShadowClient::MqttManager.new(host: host,
49
+ port: port,
50
+ ssl: true,
51
+ cert_file: cert_file_path,
52
+ key_file: key_file_path,
53
+ ca_file: ca_file_path)
54
+
55
+ mqtt_client.connect
56
+
57
+ filter_callback = Proc.new do |message|
58
+ puts "Executing the specific callback for topic: #{message.topic}\n##########################################\n"
59
+ end
60
+
61
+ timeout = 5
62
+
63
+ topic_manager = AwsIotDevice::MqttShadowClient::ShadowTopicManager.new(mqtt_client)
64
+
65
+ client = AwsIotDevice::MqttShadowClient::ShadowActionManager.new(thing, topic_manager, false)
66
+
67
+ client.register_shadow_delta_callback(filter_callback)
68
+
69
+ n = 1
70
+
71
+ 5.times do
72
+ json_payload = "{\"state\":{\"desired\":{\"property\":\"RubySDK\",\"count\":#{n}}}}"
73
+ client.shadow_update(json_payload, filter_callback, timeout)
74
+ n += 1
75
+ end
76
+
77
+ sleep timeout
78
+
79
+ mqtt_client.disconnect
@@ -0,0 +1,73 @@
1
+ require 'aws_iot_device'
2
+ require 'optparse'
3
+
4
+ options = {}
5
+
6
+ OptionParser.new do |opts|
7
+ opts.banner = "Basic usage basic_greeting.rb -c \"YOUR_CERTIFICATE_PATH\" -k \"YOUR_KEY_FILE_PATH\" -ca \"YOUR_ROOT_CA_PATH -H \"YOUR_ENDPOINT\" -p 8883\n"
8
+
9
+ opts.separator ""
10
+ opts.separator "Common options"
11
+ opts.on_tail("-h", "--help", "--usage", "Show this message") do
12
+ puts opts
13
+ exit
14
+ end
15
+
16
+ opts.on("-H", "--host [END_POINT]", "The endpoint where you want to connect") do |host|
17
+ options[:host] = host
18
+ end
19
+
20
+ opts.on("-p", "--port [MQTT_PORT]", "The port used for the connection Default is 8883") do |port|
21
+ options[:port] = port
22
+ end
23
+
24
+ opts.on("-c", "--cert [CERT_FILE_PATH]", "The path to the certificate file of the private key.") do |cert|
25
+ options[:cert] = cert
26
+ end
27
+
28
+ opts.on("-k", "--key [KEY_FILE_PATH]", "The path to private key file that would be used for encryption") do |key|
29
+ options[:key] = key
30
+ end
31
+
32
+ opts.on("-a", "--root_ca [ROOT_CA_PATH]", "The path to the authority certification file") do |root_ca|
33
+ options[:root_ca] = root_ca
34
+ end
35
+
36
+ opts.on("-t", "--thing [THING_NAME]", "The Thing name on which the action would be done") do |thing|
37
+ options[:things] = thing
38
+ end
39
+ end.parse!(ARGV)
40
+
41
+
42
+ host = options[:host]
43
+ port = options[:port] || 8883
44
+ certificate_path = options[:cert]
45
+ private_key_path = options[:key]
46
+ root_ca_path = options[:root_ca]
47
+ thing = options[:things]
48
+
49
+ my_shadow_client = AwsIotDevice::MqttShadowClient::ShadowClient.new
50
+ my_shadow_client.configure_endpoint(host, port)
51
+ my_shadow_client.configure_credentials(root_ca_path, private_key_path, certificate_path)
52
+
53
+ my_shadow_client.connect
54
+
55
+ my_shadow_client.create_shadow_handler_with_name(thing ,false)
56
+
57
+ filter_callback = Proc.new do |message|
58
+ puts "Executing the specific callback for topic: #{message.topic}\n##########################################\n"
59
+ end
60
+
61
+ n = 1
62
+
63
+ 3.times do
64
+ puts "Start shadow_delete\n"
65
+ my_shadow_client.delete_shadow(filter_callback, 5)
66
+ json_payload = '{"state":{"desired":{"property":"RubySDK"}}}'
67
+ my_shadow_client.update_shadow(json_payload, nil, 5)
68
+ n += 1
69
+ end
70
+
71
+ sleep 5
72
+
73
+ my_shadow_client.disconnect
@@ -0,0 +1,74 @@
1
+ require 'aws_iot_device'
2
+ require 'optparse'
3
+
4
+ options = {}
5
+
6
+ OptionParser.new do |opts|
7
+ opts.banner = "Basic usage basic_greeting.rb -c \"YOUR_CERTIFICATE_PATH\" -k \"YOUR_KEY_FILE_PATH\" -ca \"YOUR_ROOT_CA_PATH -H \"YOUR_ENDPOINT\" -p 8883\n"
8
+
9
+ opts.separator ""
10
+ opts.separator "Common options"
11
+ opts.on_tail("-h", "--help", "--usage", "Show this message") do
12
+ puts opts
13
+ exit
14
+ end
15
+
16
+ opts.on("-H", "--host [END_POINT]", "The endpoint where you want to connect") do |host|
17
+ options[:host] = host
18
+ end
19
+
20
+ opts.on("-p", "--port [MQTT_PORT]", "The port used for the connection Default is 8883") do |port|
21
+ options[:port] = port
22
+ end
23
+
24
+ opts.on("-c", "--cert [CERT_FILE_PATH]", "The path to the certificate file of the private key.") do |cert|
25
+ options[:cert] = cert
26
+ end
27
+
28
+ opts.on("-k", "--key [KEY_FILE_PATH]", "The path to private key file that would be used for encryption") do |key|
29
+ options[:key] = key
30
+ end
31
+
32
+ opts.on("-a", "--root_ca [ROOT_CA_PATH]", "The path to the authority certification file") do |root_ca|
33
+ options[:root_ca] = root_ca
34
+ end
35
+
36
+ opts.on("-t", "--thing [THING_NAME]", "The Thing name on which the action would be done") do |thing|
37
+ options[:things] = thing
38
+ end
39
+ end.parse!(ARGV)
40
+
41
+
42
+ host = options[:host]
43
+ port = options[:port] || 8883
44
+ certificate_path = options[:cert]
45
+ private_key_path = options[:key]
46
+ root_ca_path = options[:root_ca]
47
+ thing = options[:things]
48
+
49
+ my_shadow_client = AwsIotDevice::MqttShadowClient::ShadowClient.new
50
+ my_shadow_client.configure_endpoint(host, port)
51
+ my_shadow_client.configure_credentials(root_ca_path, private_key_path, certificate_path)
52
+
53
+ my_shadow_client.connect
54
+
55
+ my_shadow_client.create_shadow_handler_with_name(thing ,false)
56
+
57
+
58
+ filter_callback = Proc.new do |message|
59
+ puts "Executing the specific callback for topic: #{message.topic}\n##########################################\n"
60
+ end
61
+
62
+ puts "##### Starting test_shadow_client_get ######"
63
+ my_shadow_client.get_shadow(filter_callback, 4)
64
+ sleep 5
65
+
66
+ puts "##### Starting test_shadow_client_get ######"
67
+ my_shadow_client.get_shadow(nil, 4)
68
+ sleep 5
69
+
70
+ puts "##### Starting test_shadow_client_get ######"
71
+ my_shadow_client.get_shadow(filter_callback, 4)
72
+ sleep 5
73
+
74
+ my_shadow_client.disconnect