aws_iot_device 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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