tef-furcoms 0.1.0 → 0.1.1
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/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
|