onkyo_eiscp_ruby 2.1.6 → 2.1.7
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/VERSION +1 -1
- data/bin/mock_receiver.rb +30 -5
- data/bin/onkyo.rb +19 -11
- data/bin/onkyo_server.rb +1 -1
- data/lib/eiscp/dictionary/dictionary_helpers.rb +0 -3
- data/lib/eiscp/message.rb +4 -2
- data/lib/eiscp/parser/dynamic_value_parser.rb +1 -0
- data/lib/eiscp/receiver/discovery.rb +31 -15
- data/lib/eiscp/receiver.rb +3 -3
- data/lib/eiscp.rb +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: c4be1b779f00fb4a2ae5f1a843278634349980f925917a0ce17d0ac509504966
|
4
|
+
data.tar.gz: 020f9f4e070d878463ac3a7b804b249e8f47817727503b77799688b170acb181
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 448f13a6a6f94e0f8808744d04236b484955b4e85f677177c4011710968320e4c258ae979865f14a8dfc118cdfe720227e7018a1b85403cda772701c10665908
|
7
|
+
data.tar.gz: e87725e4498d36c7ae383bb88f2b76273a4336ab504176fe9a2e64ad694a3d921891b6e0af034c301aaf49cac63c859f7f581b5a275d76b7173fb55a790ba371
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.1.
|
1
|
+
2.1.7
|
data/bin/mock_receiver.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'socket'
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
4
|
+
require_relative '../lib/eiscp/receiver'
|
5
|
+
require_relative '../lib/eiscp/message'
|
6
6
|
|
7
7
|
# Mock server that only responds to ECNQSTN.
|
8
8
|
|
@@ -11,14 +11,39 @@ module EISCP
|
|
11
11
|
#
|
12
12
|
class MockReceiver
|
13
13
|
DISCOVERY_IP = '255.255.255.255'
|
14
|
-
ONKYO_DISCOVERY_RESPONSE = Message.new('ECN',
|
15
|
-
"TX-NR609/60128/DX/14DAE9E967C8\x19\
|
14
|
+
ONKYO_DISCOVERY_RESPONSE = Message.new(command: 'ECN', value:
|
15
|
+
"TX-NR609/60128/DX/14DAE9E967C8\x19"\
|
16
|
+
"\r\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
17
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
18
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
19
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
20
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
21
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
22
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
23
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
24
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
25
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
26
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
27
|
+
"\x00\x00\x00\x00")
|
16
28
|
|
17
29
|
# Create/start the server object.
|
18
30
|
|
19
31
|
def initialize
|
20
32
|
Socket.udp_server_loop(DISCOVERY_IP, Receiver::ONKYO_PORT) do |msg, src|
|
21
|
-
src.reply "ISCP\x00\x00\x00\x10\x00\x00\x00&\x01\x00\x00\x00
|
33
|
+
src.reply "ISCP\x00\x00\x00\x10\x00\x00\x00&\x01\x00\x00\x00"\
|
34
|
+
"!1ECNTX-NR609/60128/DX/14DAE9E967C8\x19\r\n\x00\x00\x00\x00\x00\x00"\
|
35
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
36
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
37
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
38
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
39
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
40
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
41
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
42
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
43
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
44
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
45
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"\
|
46
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00"
|
22
47
|
puts msg
|
23
48
|
end
|
24
49
|
end
|
data/bin/onkyo.rb
CHANGED
@@ -40,6 +40,10 @@ class Options
|
|
40
40
|
opts.on '-m', '--monitor', 'Connect to the first discovered reciever and monitor updates' do |m|
|
41
41
|
@options.monitor = m
|
42
42
|
end
|
43
|
+
|
44
|
+
opts.on '-V', '--version', 'Returns the version number of the onkyo-eiscp-ruby gem this binary belongs to.' do |v|
|
45
|
+
@options.version = v
|
46
|
+
end
|
43
47
|
end
|
44
48
|
|
45
49
|
options.parse!(args)
|
@@ -51,6 +55,11 @@ class Options
|
|
51
55
|
exit 0
|
52
56
|
end
|
53
57
|
|
58
|
+
if @options.version
|
59
|
+
puts EISCP::VERSION
|
60
|
+
exit 0
|
61
|
+
end
|
62
|
+
|
54
63
|
if @options.help
|
55
64
|
puts options
|
56
65
|
exit 0
|
@@ -60,9 +69,9 @@ class Options
|
|
60
69
|
begin
|
61
70
|
rec = EISCP::Receiver.new do |reply|
|
62
71
|
puts "#{Time.now} #{rec.host} "\
|
63
|
-
|
64
|
-
|
65
|
-
|
72
|
+
"#{reply.zone}: "\
|
73
|
+
"#{reply.command_description || reply.command} "\
|
74
|
+
"-> #{reply.value_description || reply.value}"
|
66
75
|
end
|
67
76
|
rec.thread.join
|
68
77
|
rescue Interrupt
|
@@ -93,9 +102,9 @@ class Options
|
|
93
102
|
puts "\n"
|
94
103
|
puts ' Value - Description>'
|
95
104
|
puts "\n"
|
96
|
-
command_hash[:values].each do |
|
105
|
+
command_hash[:values].each do |value, attr_hash|
|
97
106
|
if modelsets.include? attr_hash[:models]
|
98
|
-
puts " '#{EISCP::Dictionary.command_value_to_value_name(command,
|
107
|
+
puts " '#{EISCP::Dictionary.command_value_to_value_name(command, value)}' - "\
|
99
108
|
" #{attr_hash[:description]}"
|
100
109
|
end
|
101
110
|
end
|
@@ -114,9 +123,9 @@ class Options
|
|
114
123
|
puts "\n"
|
115
124
|
puts ' Value - Description>'
|
116
125
|
puts "\n"
|
117
|
-
command_hash[:values].each do |
|
118
|
-
puts " '#{EISCP::Dictionary.command_value_to_value_name(command,
|
119
|
-
|
126
|
+
command_hash[:values].each do |value, attr_hash|
|
127
|
+
puts " '#{EISCP::Dictionary.command_value_to_value_name(command, value)}' - "\
|
128
|
+
" #{attr_hash[:description]}"
|
120
129
|
end
|
121
130
|
puts "\n"
|
122
131
|
end
|
@@ -131,8 +140,6 @@ class Options
|
|
131
140
|
end
|
132
141
|
end
|
133
142
|
|
134
|
-
include EISCP
|
135
|
-
|
136
143
|
@options = Options.parse(ARGV)
|
137
144
|
|
138
145
|
receiver = EISCP::Receiver.discover[0]
|
@@ -143,4 +150,5 @@ rescue StandardError
|
|
143
150
|
raise "Couldn't parse command"
|
144
151
|
end
|
145
152
|
reply = receiver.send_recv(command)
|
146
|
-
puts "#{Time.now}: Response from #{receiver.host}: #{reply.zone.capitalize}
|
153
|
+
puts "#{Time.now}: Response from #{receiver.host}: #{reply.zone.capitalize} "\
|
154
|
+
"#{reply.command_description || reply.command} -> #{reply.value_description || reply.value}"
|
data/bin/onkyo_server.rb
CHANGED
@@ -36,14 +36,12 @@ module EISCP
|
|
36
36
|
return command if attrs[:name] == name
|
37
37
|
end
|
38
38
|
end
|
39
|
-
nil
|
40
39
|
|
41
40
|
else
|
42
41
|
|
43
42
|
@commands[command_zone].each_pair do |command, attrs|
|
44
43
|
return command if attrs[:name] == name
|
45
44
|
end
|
46
|
-
nil
|
47
45
|
|
48
46
|
end
|
49
47
|
end
|
@@ -71,7 +69,6 @@ module EISCP
|
|
71
69
|
return k if v[:name].first == value_name.to_s
|
72
70
|
end
|
73
71
|
end
|
74
|
-
nil
|
75
72
|
rescue StandardError
|
76
73
|
nil
|
77
74
|
end
|
data/lib/eiscp/message.rb
CHANGED
@@ -54,7 +54,9 @@ module EISCP
|
|
54
54
|
# @param [String] value variable length ISCP command value
|
55
55
|
# @param [String] unit_type_character override default unit type character, optional
|
56
56
|
# @param [String] start_character override default start character, optional
|
57
|
-
def initialize(command
|
57
|
+
def initialize(command:, value:, terminator: "\r\n", unit_type: '1', start: '!')
|
58
|
+
raise "All messages require a value, command is #{command} with value: #{value.class}" unless value
|
59
|
+
|
58
60
|
unless Dictionary.known_command?(command)
|
59
61
|
# STDERR.puts "Unknown command #{command}"
|
60
62
|
end
|
@@ -66,7 +68,7 @@ module EISCP
|
|
66
68
|
@start = start
|
67
69
|
@header = { magic: MAGIC,
|
68
70
|
header_size: HEADER_SIZE,
|
69
|
-
data_size: to_iscp.length,
|
71
|
+
data_size: to_iscp.length + terminator.length,
|
70
72
|
version: ISCP_VERSION,
|
71
73
|
reserved: RESERVED }
|
72
74
|
begin
|
@@ -29,22 +29,38 @@ module EISCP
|
|
29
29
|
#
|
30
30
|
def discover(discovery_port = Receiver::ONKYO_PORT)
|
31
31
|
data = []
|
32
|
-
Socket.ip_address_list.each do |
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
32
|
+
Socket.ip_address_list.each do |addr|
|
33
|
+
next unless addr.ipv4?
|
34
|
+
|
35
|
+
sock = setup_socket(addr.ip_address, discovery_port)
|
36
|
+
send_broadcast(sock, discovery_port)
|
37
|
+
data.concat(receive_data(sock))
|
38
|
+
end
|
39
|
+
data
|
40
|
+
end
|
41
|
+
|
42
|
+
def setup_socket(ip_address, discovery_port)
|
43
|
+
sock = UDPSocket.new
|
44
|
+
sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
|
45
|
+
sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_REUSEADDR, true)
|
46
|
+
sock.bind(ip_address, discovery_port)
|
47
|
+
sock
|
48
|
+
end
|
49
|
+
|
50
|
+
def send_broadcast(sock, discovery_port)
|
51
|
+
sock.send(ONKYO_MAGIC, 0, '<broadcast>', discovery_port)
|
52
|
+
end
|
53
|
+
|
54
|
+
def receive_data(sock)
|
55
|
+
data = []
|
56
|
+
loop do
|
57
|
+
msg, addr = sock.recvfrom_nonblock(1024)
|
58
|
+
data << Receiver.new(addr[2], ecn_string_to_ecn_array(msg))
|
59
|
+
rescue IO::WaitReadable
|
60
|
+
io = IO.select([sock], nil, nil, 0.5)
|
61
|
+
break if io.nil?
|
46
62
|
end
|
47
|
-
|
63
|
+
data
|
48
64
|
end
|
49
65
|
end
|
50
66
|
end
|
data/lib/eiscp/receiver.rb
CHANGED
@@ -37,7 +37,7 @@ module EISCP
|
|
37
37
|
attr_reader :thread
|
38
38
|
|
39
39
|
# Default connection timeout value in seconds
|
40
|
-
DEFAULT_TIMEOUT = 0.
|
40
|
+
DEFAULT_TIMEOUT = 0.75
|
41
41
|
|
42
42
|
# Default Onkyo eISCP port
|
43
43
|
ONKYO_PORT = 60_128
|
@@ -146,7 +146,7 @@ module EISCP
|
|
146
146
|
#
|
147
147
|
def recv
|
148
148
|
data = String.new
|
149
|
-
data << @socket.gets until data.match(/\
|
149
|
+
data << @socket.gets until data.match(/\x1A/)
|
150
150
|
Parser.parse(data)
|
151
151
|
end
|
152
152
|
|
@@ -156,7 +156,7 @@ module EISCP
|
|
156
156
|
eiscp = Parser.parse(eiscp) if eiscp.is_a? String
|
157
157
|
send eiscp
|
158
158
|
sleep DEFAULT_TIMEOUT
|
159
|
-
|
159
|
+
Message.new(command: eiscp.command, value: @state[eiscp.command], terminator: "\x1A\r\n")
|
160
160
|
end
|
161
161
|
|
162
162
|
# Return ECN hash with model, port, area, and MAC address
|
data/lib/eiscp.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: onkyo_eiscp_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Rodrigues
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: "\n Control Onkyo receivers over the network.Use the provided binary
|
14
14
|
or\n require the library for use in your scripts.\n "
|