lora-rb 0.15.0 → 0.16.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +26 -0
- data/lib/config/config.rb +25 -25
- data/lib/config/private.yml +8 -7
- data/lib/lora-rb/a2a/mqtt/call.rb +11 -3
- data/lib/lora-rb/base.rb +10 -2
- data/lib/lora-rb/fractalgarden/mqtt/call.rb +11 -3
- data/lib/lora-rb/fractalgarden/rabbitmq/call.rb +1 -1
- data/lib/lora-rb/loriot/tls/call.rb +1 -1
- data/lib/lora-rb/utility.rb +9 -1
- data/lib/version.rb +2 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13e675828b129c8d27b670935487ff710a8109ff
|
4
|
+
data.tar.gz: 7d559b6b2240436b69f4343648f471caee250cea
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8757592a55411332611df7ebd2b1d69bb8ddd08c59429485b98940322dadad5cb9e7daa7ec4ca08ccdd6fd0c1a1226fa24be7a484dd18cc676ce70b64610591f
|
7
|
+
data.tar.gz: c47ea7135d3ebea9216467fbde51789f2da7ceed90e66bc43a141c67c4154bcb7c84821e59d65d88b23f9c6505d6a23bec903c4c2120a649d8b4c9998242336c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
v0.16.0 [☰](https://bitbucket.org/fractalgarden/loriot-rb/branches/compare/v0.15.0..v0.16.0) November 21th, 2017
|
2
|
+
------------------------------
|
3
|
+
* Encoding / Decoding with Base64:
|
4
|
+
* Now on a new instance is possible to set encoding: true to encode the payload sent and to decode json
|
5
|
+
attribute "payload" or "data"
|
6
|
+
* lora instance object now return provider and protocol
|
7
|
+
* Tests are now devided by provider
|
8
|
+
|
1
9
|
v0.15.0 [☰](https://bitbucket.org/fractalgarden/loriot-rb/branches/compare/v0.14.0..v0.15.0) November 1th, 2017
|
2
10
|
------------------------------
|
3
11
|
* Added new parameter "provider" to connection's configuration
|
data/README.md
CHANGED
@@ -29,6 +29,7 @@ This version supports:
|
|
29
29
|
1. TLS protocol with [Loriot](http://loriot.io) (No longer supported)
|
30
30
|
2. Http push with [Resiot](http://resiot.io) (No longer supported)
|
31
31
|
3. MQTT with [A2aSmartCity](http://www.a2asmartcity.io/)
|
32
|
+
4. MQTT with Fractalgarden (Those who are developing this gem)
|
32
33
|
|
33
34
|
## Configuration
|
34
35
|
|
@@ -115,6 +116,7 @@ LoraRb.configure do |config|
|
|
115
116
|
config.port = 8883
|
116
117
|
config.uplink_url = '/sub/v1/users/{username}/apps/{appid}/devices/+/uplink/+'
|
117
118
|
config.downlink_url = '/api/v1/users/{username}/apps/{appid}/devices/{deveui}/downlink/post/reply/{clientid}/id/{requestid}'
|
119
|
+
config.timeout = 30.0
|
118
120
|
config.downlink_response_urls = {
|
119
121
|
queued: 'reply/{clientid}/id/{requestid}',
|
120
122
|
transmitted: '/sub/v1/users/{username}/apps/{appid}/devices/{deveui}/events/downlink'
|
@@ -124,6 +126,26 @@ LoraRb.configure do |config|
|
|
124
126
|
end
|
125
127
|
```
|
126
128
|
|
129
|
+
### MQTT (with Fractalgarden free lora server)
|
130
|
+
|
131
|
+
Currently, the free network server is under development.
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
LoraRb.configure do |config|
|
135
|
+
config.provider = :fractalgarden
|
136
|
+
config.protocol = :mqtt
|
137
|
+
config.host = 'lora.fractalgarden.com'
|
138
|
+
config.port = 1883
|
139
|
+
config.uplink_url = 'application/{appid}/node/+/rx'
|
140
|
+
config.downlink_url = 'application/{appid}/node/{deveui}/tx'
|
141
|
+
config.timeout = 30.0
|
142
|
+
config.downlink_response_urls = [
|
143
|
+
{ name: :queued, url: 'reply/{clientid}/id/{requestid}'},
|
144
|
+
]
|
145
|
+
config.ssl = false
|
146
|
+
end
|
147
|
+
```
|
148
|
+
|
127
149
|
## Usage
|
128
150
|
|
129
151
|
From irb require the library:
|
@@ -222,6 +244,10 @@ lora.send_cmd(eui: 'Insert here your device eui',
|
|
222
244
|
wait_response: false)
|
223
245
|
```
|
224
246
|
|
247
|
+
#### Only on Mqtt (A2a)
|
248
|
+
|
249
|
+
The a2a network server let you to manage the enqueued messages.
|
250
|
+
|
225
251
|
The param delete_previous_enqueued_commands is true by default as well. It means previous enqueued messages to the node
|
226
252
|
are deleted (the queue is emptied) before sending a new one.
|
227
253
|
|
data/lib/config/config.rb
CHANGED
@@ -8,35 +8,35 @@ LoraRb.configure do |config|
|
|
8
8
|
# config.protocol = :http
|
9
9
|
# config.host = 'eu72.resiot.io'
|
10
10
|
# A2a
|
11
|
-
config.provider = :a2a
|
11
|
+
# config.provider = :a2a
|
12
|
+
# config.protocol = :mqtt
|
13
|
+
# config.host = 'ptnetsuite.a2asmartcity.io'
|
14
|
+
# config.port = 8883
|
15
|
+
# config.uplink_url = '/sub/v1/users/{username}/apps/{appid}/devices/+/uplink/+'
|
16
|
+
# config.downlink_url = '/api/v1/users/{username}/apps/{appid}/devices/{deveui}/downlink/post/reply/{clientid}/id/{requestid}'
|
17
|
+
# config.delete_enqueued_downlink_url = '/api/v1/users/{username}/apps/{appid}/devices/{deveui}/downlink/{id}/delete/reply/{clientid}/id/{requestid}'
|
18
|
+
# config.enqueued_downlinks_url = '/api/v1/users/{username}/apps/{appid}/devices/{deveui}/downlink/get/reply/{clientid}/id/{requestid}'
|
19
|
+
# config.timeout = 60.0
|
20
|
+
# # If you expect more than one response in a topic, add an item with url=nil to not subscribe it newly
|
21
|
+
# config.downlink_response_urls = [
|
22
|
+
# { name: :queued, url: 'reply/{clientid}/id/{requestid}'},
|
23
|
+
# # { name: :transmitted, url: '/sub/v1/users/{username}/apps/{appid}/devices/{deveui}/events/downlink' }
|
24
|
+
# # { name: :confirmed, url: nil },
|
25
|
+
# ]
|
26
|
+
# config.ssl = true
|
27
|
+
# config.ssl_file = 'ssl_certificates/mqtt_ca.crt'
|
28
|
+
# Fractalgarden Free Network Server
|
29
|
+
config.provider = :fractalgarden
|
12
30
|
config.protocol = :mqtt
|
13
|
-
config.host = '
|
14
|
-
config.port =
|
31
|
+
config.host = '192.168.1.106'
|
32
|
+
config.port = 1883
|
15
33
|
config.uplink_url = '/sub/v1/users/{username}/apps/{appid}/devices/+/uplink/+'
|
16
34
|
config.downlink_url = '/api/v1/users/{username}/apps/{appid}/devices/{deveui}/downlink/post/reply/{clientid}/id/{requestid}'
|
17
|
-
config.
|
18
|
-
|
19
|
-
config.timeout = 60.0
|
20
|
-
# If you expect more than one response in a topic, add an item with url=nil to not subscribe it newly
|
35
|
+
config.timeout = 30.0
|
36
|
+
# If you expect more than one response in a topic, ad a item with url=nil to not subscribe it newly
|
21
37
|
config.downlink_response_urls = [
|
22
38
|
{ name: :queued, url: 'reply/{clientid}/id/{requestid}'},
|
23
|
-
# { name: :transmitted, url: '/sub/v1/users/{username}/apps/{appid}/devices/{deveui}/events/downlink' }
|
24
|
-
# { name: :confirmed, url: nil },
|
25
39
|
]
|
26
|
-
config.ssl =
|
27
|
-
config.ssl_file =
|
28
|
-
# Fractalgarden Free Network Server
|
29
|
-
# config.provider = :fractalgarden
|
30
|
-
# config.protocol = :mqtt
|
31
|
-
# config.host = '192.168.1.106'
|
32
|
-
# config.port = 1883
|
33
|
-
# config.uplink_url = 'application/{appid}/node/+/rx'
|
34
|
-
# config.downlink_url = 'application/{appid}/node/{deveui}/tx'
|
35
|
-
# config.timeout = 30.0
|
36
|
-
# # If you expect more than one response in a topic, ad a item with url=nil to not subscribe it newly
|
37
|
-
# config.downlink_response_urls = [
|
38
|
-
# { name: :queued, url: 'reply/{clientid}/id/{requestid}'},
|
39
|
-
# ]
|
40
|
-
# config.ssl = false
|
41
|
-
# # config.ssl_file = "#{Rails.root}/vendor/ssl_certificates/a2a_mqtt_ca.crt"
|
40
|
+
config.ssl = false
|
41
|
+
# config.ssl_file = "#{Rails.root}/vendor/ssl_certificates/a2a_mqtt_ca.crt"
|
42
42
|
end
|
data/lib/config/private.yml
CHANGED
@@ -9,15 +9,16 @@ defaults: &defaults
|
|
9
9
|
# A2a
|
10
10
|
#appid: "a1b2c3d4e5f60001"
|
11
11
|
token: "2B7E151628AED2A6ABF7158809CF4F3C"
|
12
|
-
appid: "9957"
|
13
|
-
username: "fractalgarden"
|
14
|
-
password: "fr4ctalg4rden"
|
12
|
+
# appid: "9957"
|
13
|
+
# username: "fractalgarden"
|
14
|
+
# password: "fr4ctalg4rden"
|
15
15
|
# Fractalgarden
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
appid: "1"
|
17
|
+
username: "loraserver"
|
18
|
+
password: "loraserver"
|
19
19
|
|
20
|
-
test_eui: "be7a00000000123c"
|
20
|
+
# test_eui: "be7a00000000123c"
|
21
|
+
test_eui: "be7a000000001a5f"
|
21
22
|
#foo: add every variable you need and use it with => LoraRb::Settings.foo
|
22
23
|
# bar: sub variable are accessible with hash => LoraRb::Settings.foo[:bar]
|
23
24
|
|
@@ -55,9 +55,9 @@ module LoraRb
|
|
55
55
|
sub_delete_enqueued_messages(eui: options[:eui], debug: options[:debug]) if options[:delete_previous_enqueued_commands]
|
56
56
|
|
57
57
|
h_request = {
|
58
|
-
|
59
|
-
|
60
|
-
|
58
|
+
"port": options[:port], # Port where the message should be sent
|
59
|
+
"payload": (@encoding ? lora_encode(options[:data]) : options[:data]), # Message payload
|
60
|
+
"confirmed": options[:confirmed], # (Optional) Tells whether a confirmed downlink is requested. Default: false
|
61
61
|
}
|
62
62
|
# (Optional) Specifies which rx window should be used: RX1, RX2 or any(BOTH). Default: BOTH
|
63
63
|
h_request['window'] = options[:window] if options[:window]
|
@@ -140,6 +140,10 @@ module LoraRb
|
|
140
140
|
message['eui'] ||= eui if eui
|
141
141
|
port = get_port_from_topic(topic)
|
142
142
|
message['port'] ||= port if port
|
143
|
+
if @encoding
|
144
|
+
payload_key = %w(payload data).find { |tag| message[tag] }
|
145
|
+
message[payload_key] = lora_decode(message[payload_key]) if payload_key
|
146
|
+
end
|
143
147
|
end
|
144
148
|
return topic, message
|
145
149
|
end
|
@@ -161,6 +165,10 @@ module LoraRb
|
|
161
165
|
message['eui'] ||= eui if eui
|
162
166
|
port = get_port_from_topic(topic)
|
163
167
|
message['port'] ||= port if port
|
168
|
+
if @encoding
|
169
|
+
payload_key = %w(payload data).find { |tag| message[tag] }
|
170
|
+
message[payload_key] = lora_decode(message[payload_key]) if payload_key
|
171
|
+
end
|
164
172
|
end
|
165
173
|
puts " #{message}" if options[:debug] #After reworking
|
166
174
|
block.call(topic, message) if block_given?
|
data/lib/lora-rb/base.rb
CHANGED
@@ -7,6 +7,8 @@ require_relative 'utility'
|
|
7
7
|
class LoraClient
|
8
8
|
include LoraRb::Base
|
9
9
|
|
10
|
+
attr_reader :provider, :protocol
|
11
|
+
|
10
12
|
# Establish a secure connection to your account on the cloud
|
11
13
|
def initialize(options = {})
|
12
14
|
options = {debug: false,
|
@@ -23,11 +25,17 @@ class LoraClient
|
|
23
25
|
password: LoraRb::Settings.password,
|
24
26
|
ssl: LoraRb.configuration.ssl,
|
25
27
|
ssl_file: LoraRb.configuration.ssl_file,
|
26
|
-
timeout: LoraRb.configuration.timeout
|
28
|
+
timeout: LoraRb.configuration.timeout,
|
29
|
+
encoding: false}.merge(options)
|
27
30
|
@debug = options[:debug]
|
28
31
|
@token = options[:token]
|
29
32
|
@appid = options[:appid]
|
30
33
|
|
34
|
+
@provider = LoraRb.configuration.provider
|
35
|
+
@protocol = LoraRb.configuration.protocol
|
36
|
+
@encoding = options[:encoding]
|
37
|
+
require 'base64' if @encoding
|
38
|
+
|
31
39
|
require 'philter'
|
32
40
|
require 'securerandom'
|
33
41
|
|
@@ -35,7 +43,7 @@ class LoraClient
|
|
35
43
|
raise "Specify the protocol in the configuration file!" unless LoraRb.configuration.protocol
|
36
44
|
raise "Provider #{LoraRb.configuration.provider} not defined!" unless LoraRb::Protocol.provider_is_valid?
|
37
45
|
raise "Connection protocol #{LoraRb.configuration.protocol} not supported by the provider #{LoraRb.configuration.provider}!" unless LoraRb::Protocol.supported?
|
38
|
-
require_relative "#{
|
46
|
+
require_relative "#{@provider}/#{@protocol}/call"
|
39
47
|
self.extend LoraRb::Call
|
40
48
|
|
41
49
|
welcome_response = sub_initialize(options)
|
@@ -54,9 +54,9 @@ module LoraRb
|
|
54
54
|
|
55
55
|
request_id = generate_request_id
|
56
56
|
h_request = {
|
57
|
-
"fport": options[:port],
|
58
|
-
"data": options[:data],
|
59
|
-
"confirmed": options[:confirmed],
|
57
|
+
"fport": options[:port], # Port where the message should be sent
|
58
|
+
"data": (@encoding ? lora_encode(options[:data]) : options[:data]), # Message payload
|
59
|
+
"confirmed": options[:confirmed], # (Optional) Tells whether a confirmed downlink is requested. Default: false
|
60
60
|
"devEUI": options[:eui],
|
61
61
|
"reference": request_id
|
62
62
|
}
|
@@ -136,6 +136,10 @@ module LoraRb
|
|
136
136
|
message['eui'] ||= eui if eui
|
137
137
|
port = get_port_from_topic(topic)
|
138
138
|
message['port'] ||= port if port
|
139
|
+
if @encoding
|
140
|
+
payload_key = %w(payload data).find { |tag| message[tag] }
|
141
|
+
message[payload_key] = lora_decode(message[payload_key]) if payload_key
|
142
|
+
end
|
139
143
|
end
|
140
144
|
return topic, message
|
141
145
|
end
|
@@ -157,6 +161,10 @@ module LoraRb
|
|
157
161
|
message['eui'] ||= eui if eui
|
158
162
|
port = get_port_from_topic(topic)
|
159
163
|
message['port'] ||= port if port
|
164
|
+
if @encoding
|
165
|
+
payload_key = %w(payload data).find { |tag| message[tag] }
|
166
|
+
message[payload_key] = lora_decode(message[payload_key]) if payload_key
|
167
|
+
end
|
160
168
|
end
|
161
169
|
puts " #{message}" if options[:debug] #After reworking
|
162
170
|
block.call(topic, message) if block_given?
|
@@ -18,7 +18,7 @@ module LoraRb
|
|
18
18
|
|
19
19
|
# Send the request to device
|
20
20
|
def sub_send_cmd(options={})
|
21
|
-
str_request = "{\"cmd\":\"#{options[:cmd]}\",\"EUI\":\"#{options[:eui]}\",\"port\":#{options[:port]},\"confirmed\":#{options[:confirmed]},\"data\":\"#{options[:data]}\"} "
|
21
|
+
str_request = "{\"cmd\":\"#{options[:cmd]}\",\"EUI\":\"#{options[:eui]}\",\"port\":#{options[:port]},\"confirmed\":#{options[:confirmed]},\"data\":\"#{(@encoding ? lora_encode(options[:data]) : options[:data])}\"} "
|
22
22
|
puts "#{Time.now} Cmq request: #{str_request}" if options[:debug]
|
23
23
|
response = @channel.default_exchange.publish(str_request, routing_key: @queue.name)
|
24
24
|
puts " [x] Sent '#{str_request}'" if options[:debug]
|
@@ -25,7 +25,7 @@ module LoraRb
|
|
25
25
|
str_app_token = "{\"appid\":\"#{options[:appid]}\", \"token\":\"#{options[:token]}\"}"
|
26
26
|
puts "#{Time.now} To: #{str_app_token}" if options[:debug]
|
27
27
|
@ssl_socket.puts str_app_token
|
28
|
-
str_request = "{\"cmd\":\"#{options[:cmd]}\",\"EUI\":\"#{options[:eui]}\",\"port\":#{options[:port]},\"confirmed\":#{options[:confirmed]},\"data\":\"#{options[:data]}\"} "
|
28
|
+
str_request = "{\"cmd\":\"#{options[:cmd]}\",\"EUI\":\"#{options[:eui]}\",\"port\":#{options[:port]},\"confirmed\":#{options[:confirmed]},\"data\":\"#{(@encoding ? lora_encode(options[:data]) : options[:data])}\"} "
|
29
29
|
puts "#{Time.now} Cmq request: #{str_request}" if options[:debug]
|
30
30
|
@ssl_socket.puts(str_request)
|
31
31
|
begin
|
data/lib/lora-rb/utility.rb
CHANGED
@@ -3,7 +3,7 @@ module LoraRb
|
|
3
3
|
# It contains generic methods
|
4
4
|
module Base
|
5
5
|
|
6
|
-
#
|
6
|
+
# Substitute tags with data into url
|
7
7
|
def merge_tags_to_url(url, tags={}, options={})
|
8
8
|
url = url.dup
|
9
9
|
puts "merge_tags_to_url: #{url}" if options[:debug] == :full
|
@@ -14,6 +14,14 @@ module LoraRb
|
|
14
14
|
puts "merge_tags_to_url: completed #{url}" if options[:debug] == :full
|
15
15
|
url
|
16
16
|
end
|
17
|
+
|
18
|
+
def lora_encode(payload)
|
19
|
+
Base64.encode64(payload.scan(/.{2}/).map { |b| b.to_i(16).chr }.join)
|
20
|
+
end
|
21
|
+
|
22
|
+
def lora_decode(payload)
|
23
|
+
Base64.decode64(payload).unpack("H*").first
|
24
|
+
end
|
17
25
|
end
|
18
26
|
|
19
27
|
private
|
data/lib/version.rb
CHANGED
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.
|
4
|
+
version: 0.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marco Mastrodonato
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2017-11-
|
14
|
+
date: 2017-11-21 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: json
|