seriamp 0.1.11 → 0.1.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/sonamp-web +4 -3
- data/bin/yamaha-web +4 -3
- data/lib/seriamp/sonamp/app.rb +3 -1
- data/lib/seriamp/sonamp/client.rb +25 -4
- data/lib/seriamp/version.rb +1 -1
- data/lib/seriamp/yamaha/app.rb +3 -1
- data/lib/seriamp/yamaha/client.rb +70 -28
- data/seriamp.gemspec +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a8c5974a39756c641ab5fb6e600d0d67095e4e9f18c872225ffb580cea4e70c
|
4
|
+
data.tar.gz: ba47852332bdb66070cf4105c4929ed691fce8eca8dd7f47aaefbeb4effab932
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 185e56b171c6db9ed0822f57de19ac2fea395d075bc615cddf0795c82c2f044b5212e9eb210b90b3dbc4aa603ce6b1553a610924c9ce8b9f02ae860c1f0c873c
|
7
|
+
data.tar.gz: 277dc1f126ca440e3a8539491e1548511f1abfb66e6a21c615ab4ab8bfce67c76c2499b6c6a2ec9efe20050cd1ac732f70cd3870cff98aec927ae57f6f46e1e4
|
data/bin/sonamp-web
CHANGED
@@ -23,9 +23,10 @@ end.parse!
|
|
23
23
|
|
24
24
|
logger = Logger.new(STDERR)
|
25
25
|
|
26
|
-
#Sonamp::App.set :device, options[:device]
|
27
|
-
#Sonamp::App.set :logger, logger
|
28
|
-
Seriamp::Sonamp::App.set :client, Seriamp::Sonamp::Client.new(
|
26
|
+
#Seriamp::Sonamp::App.set :device, options[:device]
|
27
|
+
#Seriamp::Sonamp::App.set :logger, logger
|
28
|
+
Seriamp::Sonamp::App.set :client, Seriamp::Sonamp::Client.new(
|
29
|
+
device: options[:device], logger: logger, thread_safe: true)
|
29
30
|
|
30
31
|
options = Rack::Server::Options.new.parse!(ARGV)
|
31
32
|
Rack::Server.start(options.merge(app: Seriamp::Sonamp::App))
|
data/bin/yamaha-web
CHANGED
@@ -23,9 +23,10 @@ end.parse!
|
|
23
23
|
|
24
24
|
logger = Logger.new(STDERR)
|
25
25
|
|
26
|
-
#Yamaha::App.set :device, options[:device]
|
27
|
-
#Yamaha::App.set :logger, logger
|
28
|
-
Seriamp::Yamaha::App.set :client, Seriamp::Yamaha::Client.new(
|
26
|
+
#Seriamp::Yamaha::App.set :device, options[:device]
|
27
|
+
#Seriamp::Yamaha::App.set :logger, logger
|
28
|
+
Seriamp::Yamaha::App.set :client, Seriamp::Yamaha::Client.new(
|
29
|
+
device: options[:device], logger: logger, thread_safe: true)
|
29
30
|
|
30
31
|
options = Rack::Server::Options.new.parse!(ARGV)
|
31
32
|
Rack::Server.start(options.merge(app: Seriamp::Yamaha::App))
|
data/lib/seriamp/sonamp/app.rb
CHANGED
@@ -12,6 +12,7 @@ module Seriamp
|
|
12
12
|
set :device, nil
|
13
13
|
set :logger, nil
|
14
14
|
set :client, nil
|
15
|
+
set :retries, true
|
15
16
|
|
16
17
|
get '/' do
|
17
18
|
render_json(client.status)
|
@@ -75,7 +76,8 @@ module Seriamp
|
|
75
76
|
|
76
77
|
def client
|
77
78
|
settings.client || begin
|
78
|
-
@client ||= Sonamp::Client.new(settings.device,
|
79
|
+
@client ||= Sonamp::Client.new(settings.device,
|
80
|
+
logger: settings.logger, retries: settings.retries, thread_safe: true)
|
79
81
|
end
|
80
82
|
end
|
81
83
|
|
@@ -10,7 +10,7 @@ module Seriamp
|
|
10
10
|
RS232_TIMEOUT = 3
|
11
11
|
|
12
12
|
class Client
|
13
|
-
def initialize(device: nil, glob: nil, logger: nil, retries: true)
|
13
|
+
def initialize(device: nil, glob: nil, logger: nil, retries: true, thread_safe: false)
|
14
14
|
@logger = logger
|
15
15
|
|
16
16
|
@device = device
|
@@ -26,6 +26,11 @@ module Seriamp
|
|
26
26
|
else
|
27
27
|
raise ArgumentError, "retries must be an integer, true, false or nil: #{retries}"
|
28
28
|
end
|
29
|
+
@thread_safe = !!thread_safe
|
30
|
+
|
31
|
+
if thread_safe?
|
32
|
+
@lock = Mutex.new
|
33
|
+
end
|
29
34
|
end
|
30
35
|
|
31
36
|
attr_reader :device
|
@@ -33,6 +38,10 @@ module Seriamp
|
|
33
38
|
attr_reader :logger
|
34
39
|
attr_reader :retries
|
35
40
|
|
41
|
+
def thread_safe?
|
42
|
+
@thread_safe
|
43
|
+
end
|
44
|
+
|
36
45
|
def detect_device?
|
37
46
|
@detect_device
|
38
47
|
end
|
@@ -182,10 +191,22 @@ module Seriamp
|
|
182
191
|
private
|
183
192
|
|
184
193
|
def with_device(&block)
|
185
|
-
|
186
|
-
|
194
|
+
with_lock do
|
195
|
+
if @io
|
196
|
+
yield @io
|
197
|
+
else
|
198
|
+
open_device(&block)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
def with_lock
|
204
|
+
if thread_safe?
|
205
|
+
@lock.synchronize do
|
206
|
+
yield
|
207
|
+
end
|
187
208
|
else
|
188
|
-
|
209
|
+
yield
|
189
210
|
end
|
190
211
|
end
|
191
212
|
|
data/lib/seriamp/version.rb
CHANGED
data/lib/seriamp/yamaha/app.rb
CHANGED
@@ -13,6 +13,7 @@ module Seriamp
|
|
13
13
|
set :device, nil
|
14
14
|
set :logger, nil
|
15
15
|
set :client, nil
|
16
|
+
set :retries, true
|
16
17
|
|
17
18
|
get '/' do
|
18
19
|
clear_cache
|
@@ -153,7 +154,8 @@ module Seriamp
|
|
153
154
|
|
154
155
|
def client
|
155
156
|
settings.client || begin
|
156
|
-
@client ||= Yamaha::Client.new(settings.device,
|
157
|
+
@client ||= Yamaha::Client.new(settings.device,
|
158
|
+
logger: settings.logger, retries: settings.retries, thread_safe: true)
|
157
159
|
end
|
158
160
|
end
|
159
161
|
|
@@ -14,7 +14,7 @@ module Seriamp
|
|
14
14
|
class Client
|
15
15
|
include Protocol::Methods
|
16
16
|
|
17
|
-
def initialize(device: nil, glob: nil, logger: nil, retries: true)
|
17
|
+
def initialize(device: nil, glob: nil, logger: nil, retries: true, thread_safe: false)
|
18
18
|
@logger = logger
|
19
19
|
|
20
20
|
@device = device
|
@@ -30,6 +30,11 @@ module Seriamp
|
|
30
30
|
else
|
31
31
|
raise ArgumentError, "retries must be an integer, true, false or nil: #{retries}"
|
32
32
|
end
|
33
|
+
@thread_safe = !!thread_safe
|
34
|
+
|
35
|
+
if thread_safe?
|
36
|
+
@lock = Mutex.new
|
37
|
+
end
|
33
38
|
|
34
39
|
if block_given?
|
35
40
|
begin
|
@@ -45,6 +50,10 @@ module Seriamp
|
|
45
50
|
attr_reader :logger
|
46
51
|
attr_reader :retries
|
47
52
|
|
53
|
+
def thread_safe?
|
54
|
+
@thread_safe
|
55
|
+
end
|
56
|
+
|
48
57
|
def detect_device?
|
49
58
|
@detect_device
|
50
59
|
end
|
@@ -56,18 +65,29 @@ module Seriamp
|
|
56
65
|
|
57
66
|
def last_status
|
58
67
|
unless @status
|
59
|
-
|
60
|
-
|
61
|
-
|
68
|
+
with_lock do
|
69
|
+
with_retry do
|
70
|
+
with_device do
|
71
|
+
unless @status
|
72
|
+
do_status
|
73
|
+
end
|
74
|
+
end
|
62
75
|
end
|
63
76
|
end
|
64
77
|
end
|
78
|
+
if @status.nil?
|
79
|
+
raise "This should not happen"
|
80
|
+
end
|
65
81
|
@status.dup
|
66
82
|
end
|
67
83
|
|
68
84
|
def last_status_string
|
69
85
|
unless @status_string
|
70
|
-
|
86
|
+
with_lock do
|
87
|
+
with_retry do
|
88
|
+
with_device do
|
89
|
+
end
|
90
|
+
end
|
71
91
|
end
|
72
92
|
end
|
73
93
|
@status_string.dup
|
@@ -121,6 +141,16 @@ module Seriamp
|
|
121
141
|
end
|
122
142
|
end
|
123
143
|
|
144
|
+
def with_lock
|
145
|
+
if thread_safe?
|
146
|
+
@lock.synchronize do
|
147
|
+
yield
|
148
|
+
end
|
149
|
+
else
|
150
|
+
yield
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
124
154
|
# Shows a message via the on-screen display. The message must be 16
|
125
155
|
# characters or fewer. The message is NOT displayed on the front panel,
|
126
156
|
# it is shown only on the connected TV's OSD.
|
@@ -134,13 +164,15 @@ module Seriamp
|
|
134
164
|
raise ArgumentError, "Message must be no more than 16 characters, #{msg.length} given"
|
135
165
|
end
|
136
166
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
167
|
+
with_lock do
|
168
|
+
with_retry do
|
169
|
+
with_device do
|
170
|
+
@io.syswrite("#{STX}21000#{ETX}".encode('ascii'))
|
171
|
+
@io.syswrite("#{STX}3#{msg[0..3]}#{ETX}".encode('ascii'))
|
172
|
+
@io.syswrite("#{STX}3#{msg[4..7]}#{ETX}".encode('ascii'))
|
173
|
+
@io.syswrite("#{STX}3#{msg[8..11]}#{ETX}".encode('ascii'))
|
174
|
+
@io.syswrite("#{STX}3#{msg[12..15]}#{ETX}".encode('ascii'))
|
175
|
+
end
|
144
176
|
end
|
145
177
|
end
|
146
178
|
|
@@ -265,9 +297,12 @@ module Seriamp
|
|
265
297
|
end
|
266
298
|
break unless again
|
267
299
|
end
|
300
|
+
if resp.length < 10
|
301
|
+
raise HandshakeFailure, "Broken status response: expected at least 10 bytes, got #{resp.length} bytes; concurrent operation on device?"
|
302
|
+
end
|
268
303
|
payload = resp[1...-1]
|
269
|
-
|
270
|
-
|
304
|
+
model_code = payload[0..4]
|
305
|
+
version = payload[5]
|
271
306
|
length = payload[6..7].to_i(16)
|
272
307
|
data = payload[8...-2]
|
273
308
|
if data.length != length
|
@@ -276,11 +311,11 @@ module Seriamp
|
|
276
311
|
unless data.start_with?('@E01900')
|
277
312
|
raise HandshakeFailure, "Broken status response: expected to start with @E01900, actual #{data[0..6]}"
|
278
313
|
end
|
279
|
-
|
280
|
-
|
281
|
-
model_code:
|
282
|
-
model_name: MODEL_NAMES[
|
283
|
-
firmware_version:
|
314
|
+
status_string = data
|
315
|
+
status = {
|
316
|
+
model_code: model_code,
|
317
|
+
model_name: MODEL_NAMES[model_code],
|
318
|
+
firmware_version: version,
|
284
319
|
system_status: data[7].ord - ZERO_ORD,
|
285
320
|
power: power = data[8].ord - ZERO_ORD,
|
286
321
|
main_power: [1, 4, 5, 2].include?(power),
|
@@ -288,7 +323,7 @@ module Seriamp
|
|
288
323
|
zone3_power: [1, 5, 3, 7].include?(power),
|
289
324
|
}
|
290
325
|
if data.length > 9
|
291
|
-
|
326
|
+
status.update(
|
292
327
|
input: input = data[9],
|
293
328
|
input_name: MAIN_INPUTS_GET.fetch(input),
|
294
329
|
multi_ch_input: data[10] == '1',
|
@@ -319,34 +354,41 @@ module Seriamp
|
|
319
354
|
sleep: SLEEP_GET.fetch(data[24]),
|
320
355
|
night: night = data[27],
|
321
356
|
night_name: NIGHT_GET.fetch(night),
|
322
|
-
pure_direct: data[PURE_DIRECT_FIELD.fetch(
|
357
|
+
pure_direct: data[PURE_DIRECT_FIELD.fetch(model_code)] == '1',
|
323
358
|
speaker_a: data[29] == '1',
|
324
359
|
speaker_b: data[30] == '1',
|
325
360
|
# 2 positions on RX-Vx700
|
326
361
|
#format: data[31..32],
|
327
362
|
#sampling: data[33..34],
|
328
363
|
)
|
329
|
-
if
|
330
|
-
|
364
|
+
if model_code == 'R0178'
|
365
|
+
status.update(
|
331
366
|
input_mode: INPUT_MODE_R0178.fetch(data[11]),
|
332
367
|
sampling: data[32],
|
333
368
|
sample_rate: SAMPLE_RATE_R0178.fetch(data[32]),
|
334
369
|
)
|
335
370
|
end
|
336
371
|
end
|
337
|
-
|
372
|
+
|
373
|
+
@model_code, @version, @status_string =
|
374
|
+
model_code, version, status_string
|
375
|
+
@status = status
|
338
376
|
end
|
339
377
|
end
|
340
378
|
|
341
379
|
def remote_command(cmd)
|
342
|
-
|
343
|
-
|
380
|
+
with_lock do
|
381
|
+
with_retry do
|
382
|
+
dispatch("#{STX}0#{cmd}#{ETX}")
|
383
|
+
end
|
344
384
|
end
|
345
385
|
end
|
346
386
|
|
347
387
|
def system_command(cmd)
|
348
|
-
|
349
|
-
|
388
|
+
with_lock do
|
389
|
+
with_retry do
|
390
|
+
dispatch("#{STX}2#{cmd}#{ETX}")
|
391
|
+
end
|
350
392
|
end
|
351
393
|
end
|
352
394
|
|
data/seriamp.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: seriamp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Oleg Pudeyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-01-
|
11
|
+
date: 2023-01-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: serialport
|