tef-furcoms 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c612206f7e17733552bcca965b3e2684a5ba17c9
4
+ data.tar.gz: 6bde1a400cb7e6f6fedbe93f50a0ae0550830e1e
5
+ SHA512:
6
+ metadata.gz: bc921df1642b8f5ac7cea97fae3080f40c107621c9ae70a7e51fb42a21e14416a67ff64a2e3899d594da5e6721f688e3e2a1322875c6488d293d8b2280b8becd
7
+ data.tar.gz: 6a1508a0ec5f87fb9c51e43344987f707faa767caebb3095967eba446fe80d3a8dc539a5da8ee9ab0fa9f74d36cf736c1bd5d0200429dc7673ce34905d6babf1
data/README.md ADDED
@@ -0,0 +1,6 @@
1
+
2
+ # TheElectricFursuit FurComs
3
+
4
+ This... Is a stub for now. Stay tuned for documentation!
5
+ OR!
6
+ Head to github.com/Xasin/system-synth-suit/Ruby/VoiceControl and see how this works.
@@ -0,0 +1,48 @@
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
@@ -0,0 +1,41 @@
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
@@ -0,0 +1,107 @@
1
+
2
+ require_relative 'Base.rb'
3
+
4
+ require 'serialport'
5
+ require 'xasin_logger'
6
+
7
+ module TEF
8
+ module FurComs
9
+ class Serial < Base
10
+ include XasLogger::Mix
11
+
12
+ def initialize(port)
13
+ super();
14
+
15
+ @port = SerialPort.new(port);
16
+ @port.baud = 115200;
17
+ @port.sync = true;
18
+
19
+ start_thread();
20
+
21
+ init_x_log("FurComs #{port}")
22
+ x_logi("Ready!");
23
+ end
24
+
25
+ private def decode_data_string(data)
26
+ return if(data.length() < 9)
27
+ payload = data[8..-1]
28
+ topic, _sep, payload = payload.partition("\0")
29
+
30
+ # Filter out unsafe topics
31
+ return unless topic =~ /^[\w\s\/]*$/
32
+
33
+ handout_data(topic, payload);
34
+ end
35
+
36
+ private def start_thread()
37
+ @rx_thread = Thread.new() do
38
+ had_esc = false;
39
+ rx_buffer = '';
40
+ c = 0;
41
+
42
+ loop do
43
+ c = @port.getbyte
44
+ if c == 0
45
+ decode_data_string rx_buffer
46
+ rx_buffer = ''
47
+ elsif had_esc
48
+ case c
49
+ when 0xDC
50
+ rx_buffer += "\0"
51
+ when 0xDD
52
+ rx_buffer += "\xDB"
53
+ end
54
+ had_esc = false
55
+ elsif c == 0xDB
56
+ had_esc = true
57
+ else
58
+ rx_buffer += c.chr
59
+ end
60
+ end
61
+ end
62
+
63
+ @rx_thread.abort_on_exception = true
64
+ end
65
+
66
+ private def slip_encode_data(data_str)
67
+ data_str.bytes.map do |b|
68
+ if b == 0
69
+ [0xDB, 0xDC]
70
+ elsif b == 0xDB
71
+ [0xDB, 0xDD]
72
+ else
73
+ b
74
+ end
75
+ end.flatten
76
+ end
77
+
78
+ private def generate_furcom_message(priority, chip_id, data_str)
79
+ priority = ([[-60, priority].max, 60].min + 64) * 2 + 1;
80
+ chip_id = 0x1 | 0x100 | ((chip_id & 0xEF) << 9) | ((chip_id >> 6) & 0xEF);
81
+
82
+ out_data = [0x00, priority, chip_id, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF]
83
+ out_data += data_str + [0]
84
+
85
+ out_data
86
+ end
87
+
88
+ def send_message(topic, message, priority: 0, chip_id: 0)
89
+ unless topic =~ /^[\w\s\/]*$/
90
+ raise ArgumentError, "Topic includes invalid characters!"
91
+ end
92
+ if (topic.length + message.length) > 250
93
+ raise ArgumentError, "Message packet length exceeded!"
94
+ end
95
+
96
+ x_logd("Sending '#{topic}': '#{message}'")
97
+
98
+ escaped_str = slip_encode_data "#{topic}\0#{message}"
99
+ out_data = generate_furcom_message priority, chip_id, escaped_str;
100
+
101
+ @port.write(out_data.pack("C2S<C*"))
102
+
103
+ @port.flush
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,30 @@
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
@@ -0,0 +1,3 @@
1
+
2
+ require_relative 'furcoms/SerialToMQTT.rb'
3
+ require_relative 'furcoms/MQTT.rb'
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tef-furcoms
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - TheSystem
8
+ - Xasin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2020-05-19 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: serialport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '1.3'
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '1.3'
28
+ - !ruby/object:Gem::Dependency
29
+ name: xasin-logger
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: '0.1'
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: '0.1'
42
+ - !ruby/object:Gem::Dependency
43
+ name: mqtt-sub_handler
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '0.1'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '0.1'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rubocop
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: 0.77.0
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 0.77.0
70
+ description: Communication interfaces for TEF FurComs-compatible lines
71
+ email:
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - README.md
77
+ - lib/tef/furcoms.rb
78
+ - lib/tef/furcoms/Base.rb
79
+ - lib/tef/furcoms/MQTT.rb
80
+ - lib/tef/furcoms/Serial.rb
81
+ - lib/tef/furcoms/SerialToMQTT.rb
82
+ homepage:
83
+ licenses:
84
+ - GPL-3.0
85
+ metadata: {}
86
+ post_install_message:
87
+ rdoc_options: []
88
+ require_paths:
89
+ - lib
90
+ required_ruby_version: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 2.5.2.1
103
+ signing_key:
104
+ specification_version: 4
105
+ summary: Ruby-Gem for TheElectricFursuit FurComs
106
+ test_files: []