tef-furcoms 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +47 -3
- data/lib/tef/furcoms.rb +2 -2
- data/lib/tef/furcoms/base.rb +78 -0
- data/lib/tef/furcoms/mqtt.rb +60 -0
- data/lib/tef/furcoms/{Serial.rb → serial.rb} +45 -14
- data/lib/tef/furcoms/serial_to_mqtt.rb +58 -0
- metadata +14 -14
- data/lib/tef/furcoms/Base.rb +0 -48
- data/lib/tef/furcoms/MQTT.rb +0 -41
- data/lib/tef/furcoms/SerialToMQTT.rb +0 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d1cff2d52f453c7c95ed031309ad6d24c397f84
|
4
|
+
data.tar.gz: d61410a2fe3d4618b8619a658505e56804c6e732
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 26ca8a0c9c65b4069bcd93a93a351c9a18453ebea0ef2f58fdd8d1c8537507eac7499c56e91e6d246f0bdb720df1e8f8d5d9aa4bd111fde50bb757cc9ce30fd2
|
7
|
+
data.tar.gz: 15d07676bf346fc3f096cd681425b9a44948fec6726d5e3cf6aaf0efadc48b8df5b98f850c001704ede71dc5dec35e792e962a4496f477630e82383bdefefd9b
|
data/README.md
CHANGED
@@ -1,6 +1,50 @@
|
|
1
1
|
|
2
2
|
# TheElectricFursuit FurComs
|
3
3
|
|
4
|
-
This
|
5
|
-
|
6
|
-
|
4
|
+
This gem is the link between a FurComs hardware bus and your ruby code!
|
5
|
+
It provides a standardized interface for sending and receiving messages, using
|
6
|
+
a large variety of channels to connect to a FurComs bus.
|
7
|
+
|
8
|
+
In its current state, it provides the following options:
|
9
|
+
- A direct FurComs connection via a USB to UART adapter.
|
10
|
+
This does not provide arbitration, but is perfect for testing, as
|
11
|
+
well as read-only access.
|
12
|
+
- Two MQTT Briding classes to connect a Serial FurComs connection
|
13
|
+
to a broker, and to access the FurComs bus via MQTT.
|
14
|
+
|
15
|
+
In upcoming versions there will be other options available, such as
|
16
|
+
using a STM32 as translator to the computer, providing true arbitration.
|
17
|
+
|
18
|
+
### Quickstart:
|
19
|
+
|
20
|
+
Let's give a short and sweet example. Here, we will try to connect to a FurComs bus using a USB to UART adapter connected to `/dev/ttyACM0` and send and receive a few messages.
|
21
|
+
|
22
|
+
```Ruby
|
23
|
+
require 'tef/furcoms.rb'
|
24
|
+
|
25
|
+
coms_interface = TEF::FurComs::Serial.new('/dev/ttyACM0');
|
26
|
+
|
27
|
+
coms_interface.on_message /^Topic_Regexp(\d)/ do |data, topic|
|
28
|
+
puts "Got some data on #{topic}!"
|
29
|
+
end
|
30
|
+
|
31
|
+
coms_interface.send_message 'Topic_Regexp1234', 'Henlo yes!'
|
32
|
+
```
|
33
|
+
|
34
|
+
And that's all you need!
|
35
|
+
|
36
|
+
If you want to use MQTT you'll need to do the following instead:
|
37
|
+
```Ruby
|
38
|
+
require 'mqtt/sub_handler.rb' # Comes from the mqtt-sub_handler gem, which is not a dependency of this FurComs gem!
|
39
|
+
|
40
|
+
require 'tef/furcoms.rb'
|
41
|
+
|
42
|
+
mqtt = MQTT::SubHandler.new('your.broker.address');
|
43
|
+
|
44
|
+
coms_interface = TEF::FurComs::SerialToMQTT.new('/dev/ttyACM0', mqtt, 'FurComs/MyTopic/');
|
45
|
+
# Leaving out the topic will instead use 'FurComs/DEVNAME', in this case FurComs/ttyACM0
|
46
|
+
|
47
|
+
coms_over_mqtt = TEF::FurComs::MQTT.new(mqtt, 'FurComs/MyTopic/');
|
48
|
+
```
|
49
|
+
|
50
|
+
The SerialToMQTT and MQTT classes have the same interface functions as the Serial class, and can be used interchangeably!
|
data/lib/tef/furcoms.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
|
2
|
-
require_relative 'furcoms/
|
3
|
-
require_relative 'furcoms/
|
2
|
+
require_relative 'furcoms/serial_to_mqtt.rb'
|
3
|
+
require_relative 'furcoms/mqtt.rb'
|
@@ -0,0 +1,78 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
# TheElectricFursuits Ruby namespace.
|
4
|
+
# @see https://github.com/TheElectricFursuits/
|
5
|
+
module TEF
|
6
|
+
# Module for all classes related to the FurComs communication bus.
|
7
|
+
# @see https://github.com/TheElectricFursuits/tef-FurComs
|
8
|
+
module FurComs
|
9
|
+
# Base class for a FurComs bus.
|
10
|
+
#
|
11
|
+
# This base class represents a single, bidirectional connection
|
12
|
+
# point to a FurComs bus. It provides function prototypes for sending
|
13
|
+
# and receiving messages that shall be overloaded by actual implementations.
|
14
|
+
#
|
15
|
+
# @author The System (Neira)
|
16
|
+
#
|
17
|
+
# @see Serial
|
18
|
+
# @see MQTT
|
19
|
+
class Base
|
20
|
+
# Initialize an empty base class.
|
21
|
+
#
|
22
|
+
# Note that this class cannot be used for communication!
|
23
|
+
def initialize()
|
24
|
+
@message_procs = [];
|
25
|
+
end
|
26
|
+
|
27
|
+
# Send a message to the FurComs bus.
|
28
|
+
#
|
29
|
+
# This will send a message onto topic, using the given
|
30
|
+
# priority and chip_id (defaulting both to 0).
|
31
|
+
#
|
32
|
+
# @param topic [String] Topic to send the message onto
|
33
|
+
# @param message [String] Binary string of data to send, expected
|
34
|
+
# to be ASCII-8 encoded, can contain any character (including null)
|
35
|
+
def send_message(topic, message, priority: 0, chip_id: 0) end
|
36
|
+
|
37
|
+
# Add a message callback.
|
38
|
+
#
|
39
|
+
# Calling this function with a block will add a callback to received
|
40
|
+
# messages. Any new message that is received will be passed to the
|
41
|
+
# callback.
|
42
|
+
# @param topic_filter [String, RegExp] Optional topic filter to use,
|
43
|
+
# either a String (for exact match) or Regexp
|
44
|
+
# @yieldparam data [String] Raw data received from the FurComs bus.
|
45
|
+
# ASCII-8 encoded, may contain any binary character.
|
46
|
+
# @yieldparam topic [String] Topic string that this message was received on.
|
47
|
+
def on_message(topic_filter = nil, &block)
|
48
|
+
o_msg = { topic: topic_filter, block: block };
|
49
|
+
@message_procs << o_msg;
|
50
|
+
|
51
|
+
o_msg
|
52
|
+
end
|
53
|
+
|
54
|
+
# @private
|
55
|
+
# Internal function used merely to cleanly hand out received data
|
56
|
+
# to message callbacks.
|
57
|
+
private def handout_data(topic, data)
|
58
|
+
x_logd("Data received on #{topic}: #{data}")
|
59
|
+
|
60
|
+
@message_procs.each do |callback|
|
61
|
+
begin
|
62
|
+
if (filter = callback[:topic])
|
63
|
+
if filter.is_a? String
|
64
|
+
next unless topic == filter
|
65
|
+
elsif filter.is_a? RegExp
|
66
|
+
next unless filter.match(topic)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
callback[:block].call(data, topic)
|
71
|
+
rescue => e
|
72
|
+
x_logf("Error in callback #{callback[:block]}: #{e}");
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
require_relative 'base.rb'
|
3
|
+
|
4
|
+
require 'xasin_logger'
|
5
|
+
|
6
|
+
module TEF
|
7
|
+
module FurComs
|
8
|
+
# FurComs MQTT wrapper
|
9
|
+
#
|
10
|
+
# This class will connect to a MQTT Broker, and use it as a bridge
|
11
|
+
# to a FurComs hardware connection.
|
12
|
+
# This allows multiple different systems to access different busses remotely,
|
13
|
+
# and has the added benefit of allowing Read/Write restrictions using
|
14
|
+
# the MQTT built-in authentication.
|
15
|
+
class MQTT < Base
|
16
|
+
include XasLogger::Mix
|
17
|
+
|
18
|
+
# Initialize a new FurComs MQTT Bridge.
|
19
|
+
#
|
20
|
+
# This will subscribe to the topic: topic + 'Received/#', and will
|
21
|
+
# being relaying messages to the attached callbacks immediately.
|
22
|
+
# Messages it wants to send will be sent to topic + 'Send/#{msg_topic}'
|
23
|
+
#
|
24
|
+
# If no MQTT to FurComs is attached to the bus, the message will be lost!
|
25
|
+
#
|
26
|
+
# @param mqtt The MQTT handler. Must support subscribe_to and publish_to.
|
27
|
+
# A fitting gem would be mqtt-sub_handler.
|
28
|
+
# @param topic [String] Topic base. Must end with /
|
29
|
+
def initialize(mqtt, topic = 'FurComs/ttyACM0/')
|
30
|
+
super();
|
31
|
+
|
32
|
+
@mqtt = mqtt;
|
33
|
+
@mqtt_topic = topic;
|
34
|
+
|
35
|
+
@mqtt.subscribe_to topic + 'Received/#' do |data, msg_topic|
|
36
|
+
msg_topic = msg_topic.join('/')
|
37
|
+
next unless msg_topic =~ /^[\w\s\/]*$/
|
38
|
+
|
39
|
+
handout_data(msg_topic, data);
|
40
|
+
end
|
41
|
+
|
42
|
+
init_x_log(@mqtt_topic)
|
43
|
+
end
|
44
|
+
|
45
|
+
# (see Base#send_message)
|
46
|
+
def send_message(topic, data, priority: 0, chip_id: 0)
|
47
|
+
unless topic =~ /^[\w\s\/]*$/
|
48
|
+
raise ArgumentError, 'Topic includes invalid characters!'
|
49
|
+
end
|
50
|
+
if (topic.length + data.length) > 250
|
51
|
+
raise ArgumentError, 'Message packet length exceeded!'
|
52
|
+
end
|
53
|
+
|
54
|
+
x_logd("Sending '#{topic}': '#{data}'")
|
55
|
+
|
56
|
+
@mqtt.publish_to @mqtt_topic + "Send/#{topic}", data
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -1,29 +1,47 @@
|
|
1
1
|
|
2
|
-
require_relative '
|
2
|
+
require_relative 'base.rb'
|
3
3
|
|
4
4
|
require 'serialport'
|
5
5
|
require 'xasin_logger'
|
6
6
|
|
7
7
|
module TEF
|
8
8
|
module FurComs
|
9
|
+
# USB-To-Serial FurComs Bridge.
|
10
|
+
#
|
11
|
+
# This class will handle connecting to a FurComs bus using a standard
|
12
|
+
# USB-To-UART adapter, such as an FTDI-Chip, in order to send and
|
13
|
+
# receive messages.
|
14
|
+
#
|
15
|
+
# @note This class provides limited FurComs compatibility. Arbitration
|
16
|
+
# handling is not possible, which may cause frequent collisions in busy
|
17
|
+
# bus conditions. It is recommended to use a STM32 processor
|
18
|
+
# that provides translation between FurComs and the computer.
|
9
19
|
class Serial < Base
|
10
20
|
include XasLogger::Mix
|
11
21
|
|
12
|
-
|
22
|
+
# Initialize a Serial bridge class.
|
23
|
+
#
|
24
|
+
# This will open the given Serial port and begin reading/writing
|
25
|
+
# onto the FurComs bus.
|
26
|
+
# @note This class can not provide full arbitration handling. This may
|
27
|
+
# cause issues in busy bus conditions!
|
28
|
+
# @todo Add graceful handling of controller disconnect/reconnect.
|
29
|
+
def initialize(port = '/dev/ttyACM0', baudrate = 115_200)
|
13
30
|
super();
|
14
31
|
|
15
32
|
@port = SerialPort.new(port);
|
16
|
-
@port.baud =
|
33
|
+
@port.baud = baudrate;
|
17
34
|
@port.sync = true;
|
18
35
|
|
19
36
|
start_thread();
|
20
37
|
|
21
38
|
init_x_log("FurComs #{port}")
|
22
|
-
x_logi(
|
39
|
+
x_logi('Ready!');
|
23
40
|
end
|
24
41
|
|
25
42
|
private def decode_data_string(data)
|
26
|
-
return if
|
43
|
+
return if data.length() < 9
|
44
|
+
|
27
45
|
payload = data[8..-1]
|
28
46
|
topic, _sep, payload = payload.partition("\0")
|
29
47
|
|
@@ -40,11 +58,12 @@ module TEF
|
|
40
58
|
c = 0;
|
41
59
|
|
42
60
|
loop do
|
43
|
-
c = @port.getbyte
|
44
|
-
|
61
|
+
c = @port.getbyte # Blocks until byte is available on bus.
|
62
|
+
|
63
|
+
if c.zero? # 0x00 Indicates STOP
|
45
64
|
decode_data_string rx_buffer
|
46
65
|
rx_buffer = ''
|
47
|
-
elsif had_esc
|
66
|
+
elsif had_esc # ESC had been received, decode next byte.
|
48
67
|
case c
|
49
68
|
when 0xDC
|
50
69
|
rx_buffer += "\0"
|
@@ -52,9 +71,9 @@ module TEF
|
|
52
71
|
rx_buffer += "\xDB"
|
53
72
|
end
|
54
73
|
had_esc = false
|
55
|
-
elsif c == 0xDB
|
74
|
+
elsif c == 0xDB # SLIP ESC
|
56
75
|
had_esc = true
|
57
|
-
else
|
76
|
+
else # No special treatment needed, add byte.
|
58
77
|
rx_buffer += c.chr
|
59
78
|
end
|
60
79
|
end
|
@@ -65,7 +84,7 @@ module TEF
|
|
65
84
|
|
66
85
|
private def slip_encode_data(data_str)
|
67
86
|
data_str.bytes.map do |b|
|
68
|
-
if b
|
87
|
+
if b.zero?
|
69
88
|
[0xDB, 0xDC]
|
70
89
|
elsif b == 0xDB
|
71
90
|
[0xDB, 0xDD]
|
@@ -75,6 +94,17 @@ module TEF
|
|
75
94
|
end.flatten
|
76
95
|
end
|
77
96
|
|
97
|
+
# @private
|
98
|
+
# Internal function to append/prepend the neccessary framing
|
99
|
+
# to be a FurComs message.
|
100
|
+
# This framing is:
|
101
|
+
# - 0x00 START
|
102
|
+
# - priority and chip_id fields
|
103
|
+
# - 0xFF latency
|
104
|
+
# - 24-bit arbitration collission map.
|
105
|
+
# - 0xFF latency
|
106
|
+
# - Modified SLIP-Encoded message data
|
107
|
+
# - 0x00 STOP
|
78
108
|
private def generate_furcom_message(priority, chip_id, data_str)
|
79
109
|
priority = ([[-60, priority].max, 60].min + 64) * 2 + 1;
|
80
110
|
chip_id = 0x1 | 0x100 | ((chip_id & 0xEF) << 9) | ((chip_id >> 6) & 0xEF);
|
@@ -85,12 +115,13 @@ module TEF
|
|
85
115
|
out_data
|
86
116
|
end
|
87
117
|
|
118
|
+
# (see Base#send_message)
|
88
119
|
def send_message(topic, message, priority: 0, chip_id: 0)
|
89
120
|
unless topic =~ /^[\w\s\/]*$/
|
90
|
-
raise ArgumentError,
|
121
|
+
raise ArgumentError, 'Topic includes invalid characters!'
|
91
122
|
end
|
92
123
|
if (topic.length + message.length) > 250
|
93
|
-
raise ArgumentError,
|
124
|
+
raise ArgumentError, 'Message packet length exceeded!'
|
94
125
|
end
|
95
126
|
|
96
127
|
x_logd("Sending '#{topic}': '#{message}'")
|
@@ -98,7 +129,7 @@ module TEF
|
|
98
129
|
escaped_str = slip_encode_data "#{topic}\0#{message}"
|
99
130
|
out_data = generate_furcom_message priority, chip_id, escaped_str;
|
100
131
|
|
101
|
-
@port.write(out_data.pack(
|
132
|
+
@port.write(out_data.pack('C2S<C*'))
|
102
133
|
|
103
134
|
@port.flush
|
104
135
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
require_relative 'serial.rb'
|
3
|
+
|
4
|
+
module TEF
|
5
|
+
module FurComs
|
6
|
+
# FurComs SerialToMQTT Bridge.
|
7
|
+
#
|
8
|
+
# This class will extend {FurComs::Serial} with a few internal functions
|
9
|
+
# to bridge the FurComs bus connection to MQTT.
|
10
|
+
#
|
11
|
+
# @note This class suffers from the same restrictions as the {Serial} class.
|
12
|
+
# Use a different PC to FurComs connection if possible!
|
13
|
+
#
|
14
|
+
# @see Serial
|
15
|
+
class SerialToMQTT < Serial
|
16
|
+
# Initialize a Serial To MQTT bridge instance.
|
17
|
+
#
|
18
|
+
# This will open the given Serial port and begin reading/writing
|
19
|
+
# onto the FurComs bus.
|
20
|
+
# It will additionally subscribe to the MQTT 'topic',
|
21
|
+
# or 'FurComs/#{topic}/Send/#' using the /dev/DEVICE part of the port
|
22
|
+
# argument if topic is left nil.
|
23
|
+
# Any message received on this topic will be sent as FurComs messages.
|
24
|
+
#
|
25
|
+
# Received messages are first handed out to internal callbacks,
|
26
|
+
# and will then be sent off to 'FurComs/#{topic}/Received/#{msg_topic}'
|
27
|
+
#
|
28
|
+
# @note This class can not provide full arbitration handling. This may
|
29
|
+
# cause issues in busy bus conditions!
|
30
|
+
# @param port [String] Device port to use for the FurComs connection
|
31
|
+
# @param mqtt MQTT Handler class. Must support subscribe_to
|
32
|
+
# and publish_to
|
33
|
+
# @param topic [nil, String] MQTT topic to use for receiving and sending.
|
34
|
+
# must end with a '/'
|
35
|
+
def initialize(port, mqtt, topic = nil)
|
36
|
+
super(port);
|
37
|
+
|
38
|
+
@mqtt = mqtt;
|
39
|
+
@mqtt_topic = topic || "FurComs/#{port.sub('/dev/', '')}/";
|
40
|
+
|
41
|
+
@mqtt.subscribe_to @mqtt_topic + 'Send/#' do |data, msg_topic|
|
42
|
+
msg_topic = msg_topic.join('/')
|
43
|
+
|
44
|
+
next if data.length + msg_topic.length > 250
|
45
|
+
next unless msg_topic =~ /^[\w\s\/]*$/
|
46
|
+
|
47
|
+
send_message msg_topic, data
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
private def handout_data(topic, data)
|
52
|
+
super(topic, data);
|
53
|
+
|
54
|
+
@mqtt.publish_to @mqtt_topic + "Received/#{topic}", data
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
metadata
CHANGED
@@ -1,46 +1,46 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tef-furcoms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- TheSystem
|
8
|
-
-
|
8
|
+
- Neira
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
date: 2020-05-19 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
15
|
+
name: mqtt-sub_handler
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
18
|
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: '1
|
20
|
+
version: '0.1'
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: '1
|
27
|
+
version: '0.1'
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
|
-
name:
|
29
|
+
name: serialport
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '
|
34
|
+
version: '1.3'
|
35
35
|
type: :runtime
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '
|
41
|
+
version: '1.3'
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
|
-
name:
|
43
|
+
name: xasin-logger
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
45
45
|
requirements:
|
46
46
|
- - "~>"
|
@@ -75,11 +75,11 @@ extra_rdoc_files: []
|
|
75
75
|
files:
|
76
76
|
- README.md
|
77
77
|
- lib/tef/furcoms.rb
|
78
|
-
- lib/tef/furcoms/
|
79
|
-
- lib/tef/furcoms/
|
80
|
-
- lib/tef/furcoms/
|
81
|
-
- lib/tef/furcoms/
|
82
|
-
homepage:
|
78
|
+
- lib/tef/furcoms/base.rb
|
79
|
+
- lib/tef/furcoms/mqtt.rb
|
80
|
+
- lib/tef/furcoms/serial.rb
|
81
|
+
- lib/tef/furcoms/serial_to_mqtt.rb
|
82
|
+
homepage: https://github.com/TheElectricFursuits/tef-FurComs
|
83
83
|
licenses:
|
84
84
|
- GPL-3.0
|
85
85
|
metadata: {}
|
data/lib/tef/furcoms/Base.rb
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
module TEF
|
4
|
-
module FurComs
|
5
|
-
class Message
|
6
|
-
attr_reader :priority
|
7
|
-
attr_reader :source_id
|
8
|
-
|
9
|
-
attr_reader :topic
|
10
|
-
attr_reader :data
|
11
|
-
|
12
|
-
def initialize()
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
class Base
|
17
|
-
def initialize()
|
18
|
-
@message_procs = [];
|
19
|
-
end
|
20
|
-
|
21
|
-
def send_message(topic, message, priority: 0, chip_id: 0) end
|
22
|
-
|
23
|
-
def on_message(topic_filter = nil, &block)
|
24
|
-
@message_procs << { topic: topic_filter, block: block };
|
25
|
-
end
|
26
|
-
|
27
|
-
private def handout_data(topic, data)
|
28
|
-
x_logd("Data received on #{topic}: #{data}")
|
29
|
-
|
30
|
-
@message_procs.each do |callback|
|
31
|
-
begin
|
32
|
-
if filter = callback[:topic]
|
33
|
-
if filter.is_a? String
|
34
|
-
next unless topic == filter
|
35
|
-
elsif filter.is_a? RegExp
|
36
|
-
next unless filter.match(topic)
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
callback[:block].call(data, topic)
|
41
|
-
rescue => e
|
42
|
-
x_logf("Error in callback #{callback[:block]}: #{e}");
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
data/lib/tef/furcoms/MQTT.rb
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
|
2
|
-
require_relative 'Base.rb'
|
3
|
-
|
4
|
-
require 'xasin_logger'
|
5
|
-
|
6
|
-
module TEF
|
7
|
-
module FurComs
|
8
|
-
class MQTT < Base
|
9
|
-
include XasLogger::Mix
|
10
|
-
|
11
|
-
def initialize(mqtt, topic = 'FurComs/ttyACM0/')
|
12
|
-
super();
|
13
|
-
|
14
|
-
@mqtt = mqtt;
|
15
|
-
@mqtt_topic = topic;
|
16
|
-
|
17
|
-
@mqtt.subscribe_to topic + 'Received/#' do |data, topic|
|
18
|
-
topic = topic.join('/')
|
19
|
-
next unless topic =~ /^[\w\s\/]*$/
|
20
|
-
|
21
|
-
handout_data(topic, data);
|
22
|
-
end
|
23
|
-
|
24
|
-
init_x_log(@mqtt_topic)
|
25
|
-
end
|
26
|
-
|
27
|
-
def send_message(topic, data, priority: 0, chip_id: 0)
|
28
|
-
unless topic =~ /^[\w\s\/]*$/
|
29
|
-
raise ArgumentError, "Topic includes invalid characters!"
|
30
|
-
end
|
31
|
-
if (topic.length + data.length) > 250
|
32
|
-
raise ArgumentError, "Message packet length exceeded!"
|
33
|
-
end
|
34
|
-
|
35
|
-
x_logd("Sending '#{topic}': '#{data}'")
|
36
|
-
|
37
|
-
@mqtt.publish_to @mqtt_topic + "Send/#{topic}", data
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
|
2
|
-
require_relative 'Serial.rb'
|
3
|
-
|
4
|
-
module TEF
|
5
|
-
module FurComs
|
6
|
-
class SerialToMQTT < Serial
|
7
|
-
def initialize(port, mqtt, topic = nil)
|
8
|
-
super(port);
|
9
|
-
|
10
|
-
@mqtt = mqtt;
|
11
|
-
@mqtt_topic = topic || "FurComs/#{port.sub('/dev/', '')}/";
|
12
|
-
|
13
|
-
@mqtt.subscribe_to @mqtt_topic + 'Send/#' do |data, topic|
|
14
|
-
topic = topic.join('/')
|
15
|
-
|
16
|
-
next if data.length + topic.length > 250
|
17
|
-
next unless topic =~ /^[\w\s\/]*$/
|
18
|
-
|
19
|
-
self.send_message topic, data
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def handout_data(topic, data)
|
24
|
-
super(topic, data);
|
25
|
-
|
26
|
-
@mqtt.publish_to @mqtt_topic + "Received/#{topic}", data
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|