lora-rb 0.8.0 → 0.9.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2e741ccd715377f07a8ffbbb22fe91f833ccec4a
4
- data.tar.gz: 4d02bcf8d4b566e6c182ed2f63cb6a99080a8cc2
3
+ metadata.gz: 213844df0c3f518068ec280585bcd4c3a8d6b5df
4
+ data.tar.gz: 6ab538fa6d2dfdccc730908be73c580793900894
5
5
  SHA512:
6
- metadata.gz: c37b0380a04d8bc486e5269d4910c416564ab2c35b8838f35ff4d649cbf90661980a40c22ae16c4b8c0c7932ac92abee486058853e606a569e37e68bfe296423
7
- data.tar.gz: 7d2d70038ada006a99eeefd2322905c756c4adb9f0b6e48160c104724263fdb0eea5a479127b9c2e758c6d1c8e00fcad2b1ae0011d894b85fb8f67bd406984c7
6
+ metadata.gz: f726dc55bed3ee0c18a15e62132216161aa55506a2eddaec0a0025c15c899016724d1fc8d000573f1090ac8f91ff5b28700f32f04d796287a0e3f561b104280c
7
+ data.tar.gz: b87fca2f73d4e4d5a5092bf197f4fcbaa83c2ee8f12c65537a9d472a97cb3ff8c91de8b8e000d270e840929ffa7373efde4290bec4718f1a44904b6f8bab6dad
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ v0.9.0 [☰](https://bitbucket.org/fractalgarden/loriot-rb/branches/compare/v0.8.0..v0.9.0) August 7th, 2017
2
+ ------------------------------
3
+ * Mqtt protocol renamed to Rabbitmq and new generic mqtt protocol added
4
+ * Mqtt protocol now support tls
5
+ * Now support the italian lora network A2a Smart City
6
+ * Configuration params updated to meet the mqtt requirements
7
+ * Updated readme
8
+
1
9
  v0.8.0 [☰](https://bitbucket.org/fractalgarden/loriot-rb/branches/compare/v0.7.0..v0.8.0) July 11th, 2017
2
10
  ------------------------------
3
11
  * Send_cmd now accept param confirmed true/false
data/README.md CHANGED
@@ -23,7 +23,94 @@ To use it in a bundle, add to gem file `gem 'lora-rb'` and run `bundle install`
23
23
 
24
24
  Establish a secure connection to your `Lora Application` on the cloud.
25
25
 
26
- This version only support the TLS protocol.
26
+ This version supports:
27
+ 1. TLS protocol with [Loriot](http://loriot.io)
28
+ 1. Http push with [Resiot](http://resiot.io)
29
+ 1. MQTT with [A2aSmartCity](http://www.a2asmartcity.io/)
30
+
31
+ ## Configuration
32
+
33
+ Insert private information in the yaml:
34
+
35
+ lib/config/private.yml
36
+
37
+ and the configuration's parameter in the config file.
38
+
39
+ lib/config/config.rb
40
+
41
+ If you are using rails you can use the generator:
42
+
43
+ bundle exec rails generate lora_rb:install
44
+
45
+ Every provider assign you a token and an appkey or an appid. Insert your secret data in the yaml:
46
+
47
+ ```yaml
48
+ defaults:
49
+ appid:
50
+ token:
51
+ # Some provider may use it
52
+ username:
53
+ password:
54
+ connector_id:
55
+ ```
56
+
57
+ If you are using Rails 5.1 you can do something like this:
58
+
59
+ ```yaml
60
+ defaults: &defaults
61
+ appid: <%= Rails.application.secrets.lora_appid %>
62
+ token: <%= Rails.application.secrets.lora_token %>
63
+ # etc ...
64
+ ```
65
+
66
+ ### TLS (with Loriot)
67
+
68
+ ```ruby
69
+ LoraRb.configure do |config|
70
+ # These informations are shared for all environments
71
+ config.protocol = :tls
72
+ config.host = 'eu1.loriot.io'
73
+ config.port = 737
74
+ end
75
+ ```
76
+
77
+ ### HTTP (with Resiot)
78
+
79
+ ```ruby
80
+ LoraRb.configure do |config|
81
+ # These informations are shared for all environments
82
+ config.protocol = :http
83
+ config.host = 'eu72.resiot.io'
84
+ config.port = 80
85
+ end
86
+ ```
87
+
88
+ ### RABBITMQ
89
+
90
+ ```ruby
91
+ LoraRb.configure do |config|
92
+ # These informations are shared for all environments
93
+ config.protocol = :rabbitmq
94
+ config.host = 'localhost'
95
+ end
96
+ ```
97
+
98
+ ### MQTT (with A2a)
99
+
100
+ ```ruby
101
+ LoraRb.configure do |config|
102
+ # These informations are shared for all environments
103
+ config.protocol = :mqtt
104
+ config.host = 'ptnetsuite.a2asmartcity.io'
105
+ config.port = 8883
106
+ config.uplink_url = '/sub/v1/users/{username}/apps/{appid}/devices/+/uplink/+'
107
+ config.downlink_url = '/api/v1/users/{username}/apps/{appid}/devices/{deveui}/downlink/post/reply/{clientid}/id/{requestid}'
108
+ config.ssl = true
109
+ config.ssl_file = 'ssl_certificates/mqtt_ca.crt'
110
+ end
111
+ ```
112
+
113
+ ## Usage
27
114
 
28
115
  From irb require the library:
29
116
 
@@ -37,10 +124,10 @@ then create an instance
37
124
  lora = LoraClient.new
38
125
  ```
39
126
 
40
- if you are in debug mode you should also receive a json:
127
+ you should receive the instance with variables depending on protocol:
41
128
 
42
- ```json
43
- { "hello":"LORIOT.io TLS Server", "version":"1.0.4" }
129
+ ```
130
+ #<LoraClient:0x0056318ad8e048 ...
44
131
  ```
45
132
 
46
133
  ### Send data to a device
@@ -102,6 +189,9 @@ To use it in a bundle, add to gem file `gem 'lora-rb'` and run `bundle install`
102
189
  - [x] Organization in modules to support new protocols `v0.2.0`
103
190
  - [x] Add a configuration `v0.3.0`
104
191
  - [x] Add a rails generator `v0.3.0`
192
+ - [x] Add http push support `v0.5.0`
193
+ - [x] Add RabbitMq support `v0.6.0`
194
+ - [x] Add Mqtt support `v0.9.0`
105
195
  - [ ] Test with many devices
106
196
 
107
197
  ## Contributing
data/lib/config/config.rb CHANGED
@@ -3,8 +3,15 @@ LoraRb.configure do |config|
3
3
  # config.protocol = :tls
4
4
  # config.host = 'eu1.loriot.io'
5
5
  # config.port = 737
6
- # config.protocol = :mqtt
6
+ # config.protocol = :rabbitmq
7
7
  # config.host = 'localhost'
8
- config.protocol = :http
9
- config.host = 'eu72.resiot.io'
8
+ # config.protocol = :http
9
+ # config.host = 'eu72.resiot.io'
10
+ config.protocol = :mqtt
11
+ config.host = 'ptnetsuite.a2asmartcity.io'
12
+ config.port = 8883
13
+ config.uplink_url = '/sub/v1/users/{username}/apps/{appid}/devices/+/uplink/+'
14
+ config.downlink_url = '/api/v1/users/{username}/apps/{appid}/devices/{deveui}/downlink/post/reply/{clientid}/id/{requestid}'
15
+ config.ssl = true
16
+ config.ssl_file = 'ssl_certificates/mqtt_ca.crt'
10
17
  end
@@ -1,11 +1,19 @@
1
1
  defaults: &defaults
2
+ # Loriot
2
3
  #appid: "BE7A02C1"
3
- appid: "a1b2c3d4e5f60001"
4
4
  #token: "zHcD-1ouz3ytyOLE6SMhwA"
5
- token: "17e3ce759c444b3977f4adbf9dd0e010"
6
- # Some provider may use it
7
- connector_id: "69643d32"
8
- test_eui: "BE7A00000000123C"
5
+ # Resiot
6
+ #appid: "a1b2c3d4e5f60001"
7
+ #token: "17e3ce759c444b3977f4adbf9dd0e010"
8
+ #connector_id: "69643d32"
9
+ # A2a
10
+ #appid: "a1b2c3d4e5f60001"
11
+ appid: "9955"
12
+ token: "2B7E151628AED2A6ABF7158809CF4F3C"
13
+ username: "fractalgarden"
14
+ password: "fr4ctalg4rden"
15
+
16
+ test_eui: "be7a00000000123c"
9
17
  #foo: add every variable you need and use it with => LoraRb::Settings.foo
10
18
  # bar: sub variable are accessible with hash => LoraRb::Settings.foo[:bar]
11
19
 
@@ -3,6 +3,8 @@ defaults: &defaults
3
3
  appid:
4
4
  token:
5
5
  # Some provider may use it
6
+ username:
7
+ password:
6
8
  connector_id:
7
9
  # Insert your device for test purpose
8
10
  test_eui:
data/lib/core/base.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  require 'json'
2
2
  require 'socket'
3
3
  require 'openssl'
4
- require 'http'
5
- require 'bunny'
6
4
 
7
5
  require_relative 'configuration'
8
6
  require_relative 'configuration_dynamic'
@@ -2,12 +2,15 @@ module LoraRb
2
2
  class Configuration
3
3
  # attr_writer :allow_sign_up
4
4
 
5
- attr_accessor :protocol, :host, :port, :env
5
+ attr_accessor :protocol, :host, :port, :uplink_url, :downlink_url, :ssl, :ssl_file, :env
6
6
 
7
7
  def initialize
8
8
  @protocol = nil
9
9
  @host = nil
10
10
  @port = nil
11
+ @url = nil
12
+ @ssl = nil # True if uses tls
13
+ @ssl_file = nil # The certificate's path
11
14
  @env = 'development'
12
15
  end
13
16
 
data/lib/core/protocol.rb CHANGED
@@ -5,7 +5,7 @@ module LoraRb
5
5
 
6
6
  # Show tips on usage
7
7
  def self.supported_protocols
8
- %w(tls http mqtt)
8
+ %w(tls http rabbitmq mqtt)
9
9
  end
10
10
  end
11
11
  end
@@ -16,7 +16,7 @@ module LoraRb
16
16
  <<-FILE.gsub(/^ /, '')
17
17
  connection_protocol = LoraRb.configuration.protocol
18
18
  raise 'Define your protocol in the configuration file!' unless connection_protocol
19
- raise "Connection protocol #{connection_protocol} not recognized!" unless %w(tls).include?(connection_protocol.to_s)
19
+ raise "Connection protocol #{connection_protocol} not recognized!" unless LoraRb::Protocol.supported_protocols.include?(connection_protocol.to_s)
20
20
  require "lora-rb/#{connection_protocol}/call"
21
21
  LoraClient.include LoraRb::Call
22
22
 
data/lib/lora-rb/base.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require_relative 'help'
2
+ require_relative 'utility'
2
3
 
3
4
  ###################################
4
5
  # An interface to Lora Service from Ruby
@@ -8,11 +9,16 @@ class LoraClient
8
9
 
9
10
  # Establish a secure connection to your account on the cloud
10
11
  def initialize(options = {})
11
- options = { debug: false,
12
- token: LoraRb::Settings.token,
13
- appid: LoraRb::Settings.appid,
14
- host: LoraRb.configuration.host,
15
- port: LoraRb.configuration.port }.merge(options)
12
+ options = {debug: false,
13
+ token: LoraRb::Settings.token,
14
+ appid: LoraRb::Settings.appid,
15
+ host: LoraRb.configuration.host,
16
+ port: LoraRb.configuration.port,
17
+ uplink_url: LoraRb.configuration.uplink_url,
18
+ downlink_url: LoraRb.configuration.downlink_url,
19
+ ssl: LoraRb.configuration.ssl,
20
+ ssl_file: LoraRb.configuration.ssl_file
21
+ }.merge(options)
16
22
  @debug = options[:debug]
17
23
  @token = options[:token]
18
24
  @appid = options[:appid]
@@ -54,7 +60,7 @@ class LoraClient
54
60
  def listen(options = {}, &block)
55
61
  options = { debug: @debug }.merge(options)
56
62
 
57
- puts "#{Time.now} Starting Listen #{@appid}. To exit press CTRL+C" if options[:debug]
63
+ puts "#{Time.now} Starting Listen app #{@appid}. To exit press CTRL+C" if options[:debug]
58
64
  sub_listen(options)
59
65
  end
60
66
 
@@ -6,6 +6,7 @@ module LoraRb
6
6
  private
7
7
 
8
8
  def sub_initialize(options={})
9
+ require 'http'
9
10
  @host = options[:host]
10
11
  {'hello' => 'Lora-Rb: Ready to start!'}
11
12
  end
@@ -8,48 +8,117 @@ module LoraRb
8
8
  private
9
9
 
10
10
  def sub_initialize(options={})
11
- @connection = Bunny.new(hostname: options[:host])
12
- @connection.start
13
- @channel = @connection.create_channel
14
- @queue = @channel.queue(options[:queue])
11
+ require 'mqtt'
12
+
13
+ raise 'Specify aaa to continue!' unless options[:uplink_url]
14
+ raise 'Specify aaa to continue!' unless options[:downlink_url]
15
+ raise 'Specify aaa to continue!' unless options[:host]
16
+ raise 'Specify aaa to continue!' unless options[:port]
17
+ raise 'Specify ssl_file to continue!' if options[:ssl] && !options[:ssl_file]
18
+
19
+ @username = LoraRb::Settings.username
20
+ password = LoraRb::Settings.password
21
+ @client_id = "#{@username}::ssg#{generate_request_id}"
22
+
23
+ @client = MQTT::Client.connect(
24
+ host: options[:host],
25
+ port: options[:port],
26
+ ssl: options[:ssl],
27
+ cert_file: options[:ssl_file],
28
+ username: @username,
29
+ password: password,
30
+ client_id: @client_id
31
+ )
32
+
33
+ @topic = merge_tags_to_url(options[:uplink_url],
34
+ { username: @username,
35
+ appid: @appid },
36
+ { debug: options[:debug] })
37
+
38
+ @downlink_url = merge_tags_to_url(options[:downlink_url])
15
39
  {'hello' => 'Lora-Rb: Ready to start!'}
16
40
  end
17
41
 
18
42
  # Send the request to device
19
43
  def sub_send_cmd(options={})
20
- str_request = "{\"cmd\":\"#{options[:cmd]}\",\"EUI\":\"#{options[:eui]}\",\"port\":#{options[:port]},\"confirmed\":#{options[:confirmed]},\"data\":\"#{options[:data]}\"} "
21
- puts "#{Time.now} Cmq request: #{str_request}" if options[:debug]
22
- response = @channel.default_exchange.publish(str_request, routing_key: @queue.name)
23
- puts " [x] Sent '#{str_request}'" if options[:debug]
44
+ h_request = {
45
+ "port": options[:port], # Port where the message should be sent
46
+ "payload": options[:data], # Message payload
47
+ "confirmed": options[:confirmed], # (Optional) Tells whether a confirmed downlink is requested. Default: false
48
+ "window": options[:window] || "BOTH", # (Optional) Specifies which rx window should be used: RX1, RX2 or any(BOTH). Default: BOTH
49
+ "priority": options[:priority] || 0, # (Optional) Message priority, used to sort messages in the queue. Default: 0
50
+ "qos": options[:qos] || 1 # (Optional) Quality Of Service:
51
+ # 0 - Best effort. The message will be transmitted to the devices
52
+ # of the group that satisfy the multicast profile requirements
53
+ # (they should have been activated and have sent at least one
54
+ # uplink, they should be class C devices, etc..).
55
+ # 1 - Transmission guaranteed. No message will be transmitted if
56
+ # some devices do not satisfy the multicast profile requirements.
57
+ # Default: 1 */
58
+ }
59
+ request_id = generate_request_id
60
+ publish_url = merge_tags_to_url(@downlink_url,
61
+ username: @username,
62
+ appid: @appid,
63
+ deveui: options[:eui],
64
+ clientid: @client_id,
65
+ requestid: request_id)
66
+
67
+ puts "#{Time.now} publish #{h_request.to_json} to #{publish_url}" if options[:debug]
68
+
69
+ response = @client.publish(publish_url, h_request.to_json, false)
70
+ puts " [x] publish response: #{response}" if options[:debug]
71
+
72
+ if options[:confirmed]
73
+ response_topic = "reply/#{@client_id}/id/#{request_id}"
74
+ puts " [x] Waiting response on #{response_topic} ..." if options[:debug]
75
+ response_topic, response = sub_read_data(topic: response_topic)
76
+ puts " [x] Topic response: #{response}" if options[:debug]
77
+ end
24
78
  response
25
79
  end
26
80
 
27
81
  # Receive the payload from the network
28
82
  def sub_read_data(options={})
29
- delivery_info, metadata, payload = @queue.pop
30
- puts " [x] Received #{delivery_info} #{metadata} #{payload}" if options[:debug]
83
+ topic = options[:topic] || @topic
84
+ puts " [x] Reading topic #{topic}..." if options[:debug]
85
+ topic, message = @client.get(topic)
86
+ message = JSON.parse(message)
87
+ message['EUI'] ||= get_eui_from_topic(topic) if message.respond_to? '[]'
88
+ puts " [x] #{topic}: #{message}" if options[:debug]
89
+ return topic, message
31
90
  end
32
91
 
33
92
  # Waiting for message in the queue
34
93
  def sub_listen(options={}, &block)
35
- puts " [*] Waiting for messages in #{@queue.name}. To exit press CTRL+C" if options[:debug]
36
- @queue.subscribe(block: true) do |delivery_info, properties, body|
37
- puts " [x] Received #{body}" if options[:debug]
38
- block.call(delivery_info, properties, body) if block
39
- # cancel the consumer to exit
40
- delivery_info.consumer.cancel
94
+ topic = options[:topic] || @topic
95
+ puts " [*] Waiting for messages in #{topic}. To exit press CTRL+C" if options[:debug]
96
+
97
+ @client.get(topic) do |topic, message|
98
+ # Block is executed for every message received
99
+ puts " [x] #{topic}: #{message}" if options[:debug]
100
+ message = JSON.parse(message)
101
+ message['EUI'] ||= get_eui_from_topic(topic) if message.respond_to? '[]'
102
+ puts " [x] after rework: #{message}" if options[:debug]
103
+ block.call(topic, message) if block
104
+ break if options[:test]
41
105
  end
42
106
  end
43
107
 
44
108
  # Close the connection
45
109
  def sub_quit
46
- @connection.close
110
+ @client.disconnect
47
111
  end
48
112
 
49
- end
50
- end
113
+ private
114
+
115
+ def get_eui_from_topic(topic)
116
+ topic&.match(/(?!devices\/)\w{16}/)&.to_s
117
+ end
118
+
119
+ def generate_request_id
120
+ Time.now.strftime('%y%m%d%H%M%S')
121
+ end
51
122
 
52
- # Monkey patch since Bunny use the rails method .empty?
53
- class NilClass
54
- def empty?; true end
123
+ end
55
124
  end
@@ -0,0 +1,57 @@
1
+ # LoraRb calling methods
2
+ module LoraRb
3
+ # It contains all the methods for selecting the items
4
+ module Call
5
+
6
+ attr_reader :client
7
+
8
+ private
9
+
10
+ def sub_initialize(options={})
11
+ require 'bunny'
12
+ @connection = Bunny.new(hostname: options[:host])
13
+ @connection.start
14
+ @channel = @connection.create_channel
15
+ @queue = @channel.queue(options[:queue])
16
+ {'hello' => 'Lora-Rb: Ready to start!'}
17
+ end
18
+
19
+ # Send the request to device
20
+ def sub_send_cmd(options={})
21
+ str_request = "{\"cmd\":\"#{options[:cmd]}\",\"EUI\":\"#{options[:eui]}\",\"port\":#{options[:port]},\"confirmed\":#{options[:confirmed]},\"data\":\"#{options[:data]}\"} "
22
+ puts "#{Time.now} Cmq request: #{str_request}" if options[:debug]
23
+ response = @channel.default_exchange.publish(str_request, routing_key: @queue.name)
24
+ puts " [x] Sent '#{str_request}'" if options[:debug]
25
+ response
26
+ end
27
+
28
+ # Receive the payload from the network
29
+ def sub_read_data(options={})
30
+ delivery_info, metadata, payload = @queue.pop
31
+ puts " [x] Received #{delivery_info} #{metadata} #{payload}" if options[:debug]
32
+ return delivery_info, metadata, payload
33
+ end
34
+
35
+ # Waiting for message in the queue
36
+ def sub_listen(options={}, &block)
37
+ puts " [*] Waiting for messages in #{@queue.name}. To exit press CTRL+C" if options[:debug]
38
+ @queue.subscribe(block: true) do |delivery_info, properties, body|
39
+ puts " [x] Received #{body}" if options[:debug]
40
+ block.call(delivery_info, properties, body) if block
41
+ # cancel the consumer to exit
42
+ delivery_info.consumer.cancel
43
+ end
44
+ end
45
+
46
+ # Close the connection
47
+ def sub_quit
48
+ @connection.close
49
+ end
50
+
51
+ end
52
+ end
53
+
54
+ # Monkey patch since Bunny use the rails method .empty?
55
+ class NilClass
56
+ def empty?; true end
57
+ end
@@ -0,0 +1,18 @@
1
+ # LoraRb methods
2
+ module LoraRb
3
+ # It contains generic methods
4
+ module Base
5
+ private
6
+
7
+ # Show tips on usage
8
+ def merge_tags_to_url(url, tags={}, options={})
9
+ puts "merge_tags_to_url: #{url}" if options[:debug]
10
+ tags.each do |tag, value|
11
+ puts " replace {#{tag}} with #{value}" if options[:debug]
12
+ url.gsub!("{#{tag}}", value.to_s)
13
+ end
14
+ puts "merge_tags_to_url: completed #{url}" if options[:debug]
15
+ url
16
+ end
17
+ end
18
+ end
data/lib/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module LoraRb
2
2
  def self.version
3
- "0.8.0"
3
+ "0.9.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lora-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marco Mastrodonato
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2017-06-29 00:00:00.000000000 Z
13
+ date: 2017-08-02 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: json
@@ -26,48 +26,6 @@ dependencies:
26
26
  - - "~>"
27
27
  - !ruby/object:Gem::Version
28
28
  version: '2.1'
29
- - !ruby/object:Gem::Dependency
30
- name: openssl
31
- requirement: !ruby/object:Gem::Requirement
32
- requirements:
33
- - - "~>"
34
- - !ruby/object:Gem::Version
35
- version: '2.0'
36
- type: :runtime
37
- prerelease: false
38
- version_requirements: !ruby/object:Gem::Requirement
39
- requirements:
40
- - - "~>"
41
- - !ruby/object:Gem::Version
42
- version: '2.0'
43
- - !ruby/object:Gem::Dependency
44
- name: http
45
- requirement: !ruby/object:Gem::Requirement
46
- requirements:
47
- - - "~>"
48
- - !ruby/object:Gem::Version
49
- version: '2.2'
50
- type: :runtime
51
- prerelease: false
52
- version_requirements: !ruby/object:Gem::Requirement
53
- requirements:
54
- - - "~>"
55
- - !ruby/object:Gem::Version
56
- version: '2.2'
57
- - !ruby/object:Gem::Dependency
58
- name: bunny
59
- requirement: !ruby/object:Gem::Requirement
60
- requirements:
61
- - - "~>"
62
- - !ruby/object:Gem::Version
63
- version: '2.7'
64
- type: :runtime
65
- prerelease: false
66
- version_requirements: !ruby/object:Gem::Requirement
67
- requirements:
68
- - - "~>"
69
- - !ruby/object:Gem::Version
70
- version: '2.7'
71
29
  - !ruby/object:Gem::Dependency
72
30
  name: test-unit
73
31
  requirement: !ruby/object:Gem::Requirement
@@ -108,7 +66,9 @@ files:
108
66
  - lib/lora-rb/help.rb
109
67
  - lib/lora-rb/http/call.rb
110
68
  - lib/lora-rb/mqtt/call.rb
69
+ - lib/lora-rb/rabbitmq/call.rb
111
70
  - lib/lora-rb/tls/call.rb
71
+ - lib/lora-rb/utility.rb
112
72
  - lib/vendor/deep_symbolize.rb
113
73
  - lib/version.rb
114
74
  homepage: https://github.com/marcomd/lora-rb