seriamp 0.1.14 → 0.2.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/Gemfile +8 -0
- data/Gemfile.lock +55 -0
- data/README.md +30 -4
- data/bin/integra +12 -0
- data/bin/sonamp +1 -1
- data/bin/sonamp-auto-power +56 -0
- data/bin/yamaha +1 -1
- data/lib/seriamp/all.rb +4 -0
- data/lib/seriamp/backend/serial_port.rb +1 -1
- data/lib/seriamp/backend.rb +6 -0
- data/lib/seriamp/faraday_facade.rb +89 -0
- data/lib/seriamp/integra/client.rb +192 -0
- data/lib/seriamp/integra/cmd.rb +81 -0
- data/lib/seriamp/integra/executor.rb +32 -0
- data/lib/seriamp/integra/protocol/constants.rb +13 -0
- data/lib/seriamp/integra/protocol/methods.rb +13 -0
- data/lib/seriamp/integra.rb +3 -0
- data/lib/seriamp/sonamp/app.rb +16 -3
- data/lib/seriamp/sonamp/auto_power.rb +167 -0
- data/lib/seriamp/sonamp/client.rb +19 -18
- data/lib/seriamp/sonamp/cmd.rb +8 -30
- data/lib/seriamp/sonamp/executor.rb +56 -0
- data/lib/seriamp/utils.rb +17 -0
- data/lib/seriamp/version.rb +1 -1
- data/lib/seriamp/yamaha/client.rb +19 -27
- data/lib/seriamp/yamaha/cmd.rb +4 -2
- data/lib/seriamp/yamaha/executor.rb +1 -0
- data/seriamp.gemspec +6 -2
- data/spec/sonamp/app_spec.rb +42 -0
- data/spec/sonamp/client_spec.rb +11 -0
- data/spec/sonamp/cmd_spec.rb +11 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/yamaha/app_spec.rb +37 -0
- data/spec/yamaha/client_spec.rb +11 -0
- data/spec/yamaha/cmd_spec.rb +82 -0
- metadata +78 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b1f037dbe23a5b8e4137f844d9c72a66e558ea68b17030b8f74def52cd52a2b
|
4
|
+
data.tar.gz: b0f1a36b133b59ac31f780da05104006ee17cdfa499db61cfec44aefe1a199f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0d53f1ad5da19fb3750168a1e7da77e9e1c0914047e1a63b78ef8c67fbca7530ec40aaa619c5b1d226fca2c1f100519787b83a74a9690053e8cb6c742ecd9abc
|
7
|
+
data.tar.gz: 0a2229dce99ef4f84d2239d9f147740ec24319caf1b71560d2f1caa9cf203eb525d4551bd02041c4b1105d621ee109ffd78763856f36824d7596d3319699d94e
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
seriamp (0.1.14)
|
5
|
+
serialport (~> 1.3)
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
byebug (11.1.3)
|
11
|
+
diff-lcs (1.5.0)
|
12
|
+
faraday (2.7.4)
|
13
|
+
faraday-net_http (>= 2.0, < 3.1)
|
14
|
+
ruby2_keywords (>= 0.0.4)
|
15
|
+
faraday-net_http (3.0.2)
|
16
|
+
mustermann (3.0.0)
|
17
|
+
ruby2_keywords (~> 0.0.1)
|
18
|
+
rack (2.2.4)
|
19
|
+
rack-protection (3.0.5)
|
20
|
+
rack
|
21
|
+
rack-test (2.0.2)
|
22
|
+
rack (>= 1.3)
|
23
|
+
rspec-core (3.12.1)
|
24
|
+
rspec-support (~> 3.12.0)
|
25
|
+
rspec-expectations (3.12.2)
|
26
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
+
rspec-support (~> 3.12.0)
|
28
|
+
rspec-mocks (3.12.3)
|
29
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
30
|
+
rspec-support (~> 3.12.0)
|
31
|
+
rspec-support (3.12.0)
|
32
|
+
ruby2_keywords (0.0.5)
|
33
|
+
serialport (1.3.2)
|
34
|
+
sinatra (3.0.5)
|
35
|
+
mustermann (~> 3.0)
|
36
|
+
rack (~> 2.2, >= 2.2.4)
|
37
|
+
rack-protection (= 3.0.5)
|
38
|
+
tilt (~> 2.0)
|
39
|
+
tilt (2.0.11)
|
40
|
+
|
41
|
+
PLATFORMS
|
42
|
+
x86_64-linux
|
43
|
+
|
44
|
+
DEPENDENCIES
|
45
|
+
byebug
|
46
|
+
faraday (~> 2.7)
|
47
|
+
rack-test
|
48
|
+
rspec-core (~> 3.12)
|
49
|
+
rspec-expectations (~> 3.12)
|
50
|
+
rspec-mocks (~> 3.12)
|
51
|
+
seriamp!
|
52
|
+
sinatra (~> 3.0)
|
53
|
+
|
54
|
+
BUNDLED WITH
|
55
|
+
2.3.15
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# Receiver & Amplifier Serial Control Ruby Library
|
2
2
|
|
3
3
|
## Hardware Requirements
|
4
4
|
|
@@ -70,9 +70,21 @@ Models lower than 1000 level receivers have never had RS-232C to my knowledge.
|
|
70
70
|
- Straight cable required
|
71
71
|
- Receiver socket is female
|
72
72
|
|
73
|
-
### Integra
|
73
|
+
### Integra
|
74
74
|
|
75
|
-
|
75
|
+
Tested with DTR-50.4.
|
76
|
+
|
77
|
+
- Straight cable required (if using a USB to serial adapter which already
|
78
|
+
contains a serial cable with male end, no additional cable may be needed).
|
79
|
+
- Receiver socket is female.
|
80
|
+
- Receiver socket has the nuts for fixing the cable connector.
|
81
|
+
[This FTDI adapter](https://www.amazon.com/gp/product/B0759HSLP1)
|
82
|
+
has screws on the serial end and attaches directly to the receiver.
|
83
|
+
[This PL2303 adapter]((https://www.amazon.com/gp/product/B00IDSM6BW)
|
84
|
+
has nuts on the serial end and does not attach to the receiver, requiring
|
85
|
+
either a straight through female to male serial cable or removing the nuts
|
86
|
+
from one of the ends (the USB to serial adapter is the cheaper device,
|
87
|
+
I modify the adapters rather than the receivers/amplifiers).
|
76
88
|
|
77
89
|
## Protocol Notes
|
78
90
|
|
@@ -131,7 +143,7 @@ to open a TTY in Python, buffering must be disabled.
|
|
131
143
|
See [here](https://www.avsforum.com/threads/enhancing-yamaha-avrs-via-rs-232.1066484/)
|
132
144
|
for more Yamaha-related software.
|
133
145
|
|
134
|
-
## Other Libraries
|
146
|
+
## Other Libraries & Tools
|
135
147
|
|
136
148
|
Yamaha RS232/serial protocol:
|
137
149
|
|
@@ -148,6 +160,20 @@ Yamaha YNCA protocol:
|
|
148
160
|
|
149
161
|
- [yamaha_ynca](https://github.com/mvdwetering/yamaha_ynca)
|
150
162
|
|
163
|
+
Integra serial control:
|
164
|
+
|
165
|
+
- [Many resources](https://www.avforums.com/threads/onkyo-tx-nr-1007-webinterface-programming.1107346/page-14)
|
166
|
+
- [onkyoweb-php](https://github.com/guikubivan/onkyoweb-php)
|
167
|
+
- [onkyo-eiscp](https://github.com/miracle2k/onkyo-eiscp)
|
168
|
+
- [onpc](https://github.com/mkulesh/onpc)
|
169
|
+
- [ISCP/eISCP](https://habr.com/en/post/427985/)
|
170
|
+
- [Decrypting Onkyo firmware](http://divideoverflow.com/2014/04/decrypting-onkyo-firmware-files/)
|
171
|
+
- [Post](https://robotskirts.com/2012/04/28/controlling-onkyo-integra-receivers-via-rs-232/)
|
172
|
+
|
173
|
+
Pioneer serial control:
|
174
|
+
|
175
|
+
- [Manuals](https://www.pioneerelectronics.com/PUSA/Support/Home-Entertainment-Custom-Install/RS-232+&+IP+Codes/A+V+Receivers)
|
176
|
+
|
151
177
|
## Helpful Links
|
152
178
|
|
153
179
|
- [Serial port programming in Ruby](https://www.thegeekdiary.com/serial-port-programming-reading-writing-status-of-control-lines-dtr-rts-cts-dsr/)
|
data/bin/integra
ADDED
data/bin/sonamp
CHANGED
@@ -0,0 +1,56 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'seriamp/sonamp/auto_power'
|
5
|
+
rescue LoadError
|
6
|
+
$: << File.join(File.dirname(__FILE__), '../lib')
|
7
|
+
require 'seriamp/sonamp/auto_power'
|
8
|
+
end
|
9
|
+
require 'optparse'
|
10
|
+
require 'logger'
|
11
|
+
|
12
|
+
options = {}
|
13
|
+
OptionParser.new do |opts|
|
14
|
+
opts.banner = "Usage: sonamp-auto-power [-l log-path] [-D]"
|
15
|
+
|
16
|
+
opts.on("--daemonize", "-D", "Daemonize") do
|
17
|
+
options[:daemonize] = true
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on("--log=PATH", "-l", "Path to log file") do |path|
|
21
|
+
options[:log_path] = path
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on("--sonamp-url=URL", "-s", "Path to Sonamp webapp URL") do |v|
|
25
|
+
options[:sonamp_url] = v
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on("--state=PATH", "-f", "Path to state file") do |path|
|
29
|
+
options[:state_path] = path
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on("--ttl=TTL", "-t", "Delay in seconds for turning amplifier off after receiver is detected off") do |v|
|
33
|
+
options[:ttl] = Integer(v)
|
34
|
+
end
|
35
|
+
|
36
|
+
opts.on("--yamaha-url=URL", "-y", "Path to Yamaha webapp URL") do |v|
|
37
|
+
options[:yamaha_url] = v
|
38
|
+
end
|
39
|
+
|
40
|
+
end.parse!
|
41
|
+
|
42
|
+
logger = Logger.new(STDERR)
|
43
|
+
|
44
|
+
runner = Seriamp::Sonamp::AutoPower.new(
|
45
|
+
logger: logger,
|
46
|
+
sonamp_url: options[:sonamp_url],
|
47
|
+
state_path: options[:state_path],
|
48
|
+
ttl: options[:ttl],
|
49
|
+
yamaha_url: options[:yamaha_url],
|
50
|
+
)
|
51
|
+
|
52
|
+
if options[:daemonize]
|
53
|
+
Process.daemonize
|
54
|
+
end
|
55
|
+
|
56
|
+
runner.run
|
data/bin/yamaha
CHANGED
data/lib/seriamp/all.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
autoload :JSON, 'json'
|
3
|
+
|
4
|
+
module Seriamp
|
5
|
+
class FaradayFacade
|
6
|
+
class HttpError < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(**opts)
|
10
|
+
@options = {}
|
11
|
+
if timeout = opts.delete(:timeout)
|
12
|
+
@options[:timeout] = timeout
|
13
|
+
end
|
14
|
+
|
15
|
+
@conn = Faraday.new(**opts) do |faraday|
|
16
|
+
#faraday.response :logger, nil, { headers: true, bodies: false }
|
17
|
+
#faraday.response :logger
|
18
|
+
end
|
19
|
+
|
20
|
+
@base_url = opts.fetch(:url)
|
21
|
+
end
|
22
|
+
|
23
|
+
attr_reader :options
|
24
|
+
attr_reader :base_url
|
25
|
+
|
26
|
+
def get(uri)
|
27
|
+
conn.get(uri) do |req|
|
28
|
+
configure_request(req)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def get!(url)
|
33
|
+
resp = get(url)
|
34
|
+
if resp.status != 200
|
35
|
+
raise HttpError, "Bad status: #{resp.status} for #{base_url} #{url} with #{options}"
|
36
|
+
end
|
37
|
+
resp.body
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_json(url)
|
41
|
+
resp = get!(url)
|
42
|
+
JSON.parse(resp)
|
43
|
+
end
|
44
|
+
|
45
|
+
def put(uri, body: nil)
|
46
|
+
conn.put(uri) do |req|
|
47
|
+
configure_request(req)
|
48
|
+
if body
|
49
|
+
req.body = body
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def put!(url, **opts)
|
55
|
+
put(url, **opts).tap do |resp|
|
56
|
+
unless resp.success?
|
57
|
+
raise HttpError, "Bad status: #{resp.status} for #{url}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def post(uri, body: nil)
|
63
|
+
conn.post(uri) do |req|
|
64
|
+
configure_request(req)
|
65
|
+
if body
|
66
|
+
req.body = body
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def post!(url, **opts)
|
72
|
+
post(url, **opts).tap do |resp|
|
73
|
+
unless resp.success?
|
74
|
+
raise HttpError, "Bad status: #{resp.status} for #{url}"
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
attr_reader :conn
|
82
|
+
|
83
|
+
def configure_request(req)
|
84
|
+
req.options.timeout = options[:timeout]
|
85
|
+
req.options.read_timeout = options[:timeout]
|
86
|
+
req.options.open_timeout = options[:timeout]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'timeout'
|
4
|
+
require 'seriamp/utils'
|
5
|
+
require 'seriamp/backend'
|
6
|
+
require 'seriamp/integra/protocol/methods'
|
7
|
+
|
8
|
+
module Seriamp
|
9
|
+
module Integra
|
10
|
+
|
11
|
+
RS232_TIMEOUT = 0.25
|
12
|
+
|
13
|
+
class Client
|
14
|
+
include Protocol::Methods
|
15
|
+
|
16
|
+
def initialize(device: nil, glob: nil, logger: nil, retries: true, thread_safe: false)
|
17
|
+
@logger = logger
|
18
|
+
|
19
|
+
@device = device
|
20
|
+
@detect_device = device.nil?
|
21
|
+
@glob = glob
|
22
|
+
@retries = case retries
|
23
|
+
when nil, false
|
24
|
+
0
|
25
|
+
when true
|
26
|
+
1
|
27
|
+
when Integer
|
28
|
+
retries
|
29
|
+
else
|
30
|
+
raise ArgumentError, "retries must be an integer, true, false or nil: #{retries}"
|
31
|
+
end
|
32
|
+
@thread_safe = !!thread_safe
|
33
|
+
|
34
|
+
if thread_safe?
|
35
|
+
@lock = Mutex.new
|
36
|
+
end
|
37
|
+
|
38
|
+
if block_given?
|
39
|
+
begin
|
40
|
+
yield self
|
41
|
+
ensure
|
42
|
+
close
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
attr_reader :device
|
48
|
+
attr_reader :glob
|
49
|
+
attr_reader :logger
|
50
|
+
attr_reader :retries
|
51
|
+
|
52
|
+
def thread_safe?
|
53
|
+
@thread_safe
|
54
|
+
end
|
55
|
+
|
56
|
+
def detect_device?
|
57
|
+
@detect_device
|
58
|
+
end
|
59
|
+
|
60
|
+
def get_power
|
61
|
+
boolean_question('PWR')
|
62
|
+
end
|
63
|
+
|
64
|
+
def status
|
65
|
+
{
|
66
|
+
power: get_power,
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def with_device(&block)
|
71
|
+
if @io
|
72
|
+
yield @io
|
73
|
+
else
|
74
|
+
open_device(&block)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def with_lock
|
79
|
+
if thread_safe?
|
80
|
+
@lock.synchronize do
|
81
|
+
yield
|
82
|
+
end
|
83
|
+
else
|
84
|
+
yield
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
include Protocol::Constants
|
91
|
+
|
92
|
+
EOT = ?\x1a
|
93
|
+
|
94
|
+
def open_device
|
95
|
+
if detect_device? && device.nil?
|
96
|
+
logger&.debug("Detecting device")
|
97
|
+
@device = Seriamp.detect_device(Integra, *glob, logger: logger)
|
98
|
+
if @device
|
99
|
+
logger&.info("Using #{device} as TTY device")
|
100
|
+
else
|
101
|
+
raise NoDevice, "No device specified and device could not be detected automatically"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
logger&.debug("Opening #{device}")
|
106
|
+
@io = Backend::SerialPortBackend::Device.new(device, logger: logger)
|
107
|
+
|
108
|
+
Utils.consume_data(@io.io, logger,
|
109
|
+
"Serial device readable after opening - unread previous response?")
|
110
|
+
|
111
|
+
begin
|
112
|
+
yield @io
|
113
|
+
ensure
|
114
|
+
@io.close rescue nil
|
115
|
+
@io = nil
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def dispatch(cmd)
|
120
|
+
start = Utils.monotime
|
121
|
+
with_device do
|
122
|
+
@io.syswrite(cmd.encode('ascii'))
|
123
|
+
resp = read_response
|
124
|
+
unless resp =~ /\A!1.+\x1a\z/
|
125
|
+
raise "Malformed response: #{resp}"
|
126
|
+
end
|
127
|
+
resp[2...-1]
|
128
|
+
end.tap do
|
129
|
+
elapsed = Utils.monotime - start
|
130
|
+
logger&.debug("Integra: dispatched #{cmd} in #{'%.2f' % elapsed} s")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def read_response
|
135
|
+
resp = +''
|
136
|
+
deadline = Utils.monotime + 1
|
137
|
+
loop do
|
138
|
+
begin
|
139
|
+
chunk = @io.read_nonblock(1000)
|
140
|
+
if chunk
|
141
|
+
resp += chunk
|
142
|
+
break if chunk[-1] == EOT
|
143
|
+
end
|
144
|
+
rescue IO::WaitReadable
|
145
|
+
budget = deadline - Utils.monotime
|
146
|
+
if budget < 0
|
147
|
+
raise CommunicationTimeout
|
148
|
+
end
|
149
|
+
IO.select([@io.io], nil, nil, budget)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
resp
|
153
|
+
end
|
154
|
+
|
155
|
+
def with_retry
|
156
|
+
try = 1
|
157
|
+
begin
|
158
|
+
yield
|
159
|
+
rescue Seriamp::Error, IOError, SystemCallError => exc
|
160
|
+
if try <= retries
|
161
|
+
logger&.warn("Error during operation: #{exc.class}: #{exc} - will retry")
|
162
|
+
try += 1
|
163
|
+
if detect_device?
|
164
|
+
@device = nil
|
165
|
+
end
|
166
|
+
retry
|
167
|
+
else
|
168
|
+
raise
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def question(cmd)
|
174
|
+
dispatch("!1#{cmd}QSTN\r")
|
175
|
+
end
|
176
|
+
|
177
|
+
def boolean_question(cmd)
|
178
|
+
resp = question(cmd)
|
179
|
+
if resp.start_with?(cmd)
|
180
|
+
case Integer(resp[cmd.length...])
|
181
|
+
when 1
|
182
|
+
true
|
183
|
+
when 0
|
184
|
+
false
|
185
|
+
else
|
186
|
+
raise "Bad response #{resp}"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'logger'
|
5
|
+
require 'pp'
|
6
|
+
require 'seriamp/utils'
|
7
|
+
require 'seriamp/detect'
|
8
|
+
require 'seriamp/integra/client'
|
9
|
+
require 'seriamp/integra/executor'
|
10
|
+
|
11
|
+
module Seriamp
|
12
|
+
module Integra
|
13
|
+
class Cmd
|
14
|
+
def initialize(args = ARGV, stdin = STDIN)
|
15
|
+
options = {}
|
16
|
+
OptionParser.new do |opts|
|
17
|
+
opts.banner = "Usage: integra [-d device] command arg..."
|
18
|
+
|
19
|
+
opts.on("-d", "--device DEVICE", "TTY to use (default autodetect)") do |v|
|
20
|
+
options[:device] = v
|
21
|
+
end
|
22
|
+
end.parse!
|
23
|
+
|
24
|
+
@options = options
|
25
|
+
|
26
|
+
@logger = Logger.new(STDERR)
|
27
|
+
@client = Integra::Client.new(device: options[:device], logger: @logger)
|
28
|
+
|
29
|
+
@args = args
|
30
|
+
@stdin = stdin
|
31
|
+
end
|
32
|
+
|
33
|
+
attr_reader :args
|
34
|
+
attr_reader :stdin
|
35
|
+
attr_reader :logger
|
36
|
+
|
37
|
+
def run
|
38
|
+
if args.any?
|
39
|
+
run_command(args)
|
40
|
+
else
|
41
|
+
stdin.each_line do |line|
|
42
|
+
line.strip!
|
43
|
+
line.sub!(/#.*/, '')
|
44
|
+
next if line.empty?
|
45
|
+
|
46
|
+
run_command(line.strip.split(%r,\s+,))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def run_command(args)
|
52
|
+
cmd = args.shift
|
53
|
+
unless cmd
|
54
|
+
raise ArgumentError, "No command given"
|
55
|
+
end
|
56
|
+
|
57
|
+
case cmd
|
58
|
+
when 'detect'
|
59
|
+
device = Seriamp.detect_device(Integra, *args, logger: logger)
|
60
|
+
if device
|
61
|
+
puts device
|
62
|
+
exit 0
|
63
|
+
else
|
64
|
+
STDERR.puts("Integra receiver not found")
|
65
|
+
exit 3
|
66
|
+
end
|
67
|
+
else
|
68
|
+
executor.run_command(cmd, *args)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
attr_reader :client
|
75
|
+
|
76
|
+
def executor
|
77
|
+
@executor ||= Executor.new(client)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Seriamp
|
4
|
+
module Integra
|
5
|
+
class Executor
|
6
|
+
def initialize(client)
|
7
|
+
@client = client
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :client
|
11
|
+
|
12
|
+
def run_command(cmd, *args)
|
13
|
+
cmd = cmd.gsub('_', '-')
|
14
|
+
case cmd
|
15
|
+
when 'detect'
|
16
|
+
device = Seriamp.detect_device(Integra, *args, logger: logger)
|
17
|
+
if device
|
18
|
+
puts device
|
19
|
+
exit 0
|
20
|
+
else
|
21
|
+
STDERR.puts("Integra receiver not found")
|
22
|
+
exit 3
|
23
|
+
end
|
24
|
+
when 'status'
|
25
|
+
pp client.status
|
26
|
+
else
|
27
|
+
raise ArgumentError, "Unknown command: #{cmd}"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|