onkyo_eiscp_ruby 0.0.3 → 1.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +154 -33
- data/VERSION +1 -1
- data/bin/mock_receiver.rb +23 -0
- data/bin/onkyo.rb +50 -23
- data/bin/{onkyo-server.rb → onkyo_server.rb} +1 -1
- data/eiscp-commands.yaml +10329 -10318
- data/lib/eiscp/dictionary/dictionary_generators.rb +67 -0
- data/lib/eiscp/dictionary/dictionary_helpers.rb +118 -0
- data/lib/eiscp/dictionary.rb +54 -0
- data/lib/eiscp/message.rb +97 -73
- data/lib/eiscp/parser/dynamic_value_parser.rb +7 -0
- data/lib/eiscp/parser/eiscp_parser.rb +37 -0
- data/lib/eiscp/parser/human_readable_parser.rb +30 -0
- data/lib/eiscp/parser/iscp_parser.rb +29 -0
- data/lib/eiscp/parser.rb +22 -0
- data/lib/eiscp/receiver/command_methods.rb +29 -0
- data/lib/eiscp/receiver/connection.rb +83 -0
- data/lib/eiscp/receiver/discovery.rb +50 -0
- data/lib/eiscp/receiver.rb +71 -153
- data/lib/eiscp.rb +6 -5
- data/onkyo_eiscp_ruby.gemspec +9 -8
- data/test/tc_dictionary.rb +43 -0
- data/test/tc_message.rb +10 -13
- data/test/tc_parser.rb +33 -0
- data/test/tc_receiver.rb +2 -3
- metadata +27 -14
- data/lib/eiscp/command.rb +0 -99
- data/lib/eiscp/mock_receiver.rb +0 -22
- data/test/tc_command.rb +0 -43
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'socket'
|
2
|
+
require_relative '../message'
|
3
|
+
require_relative '../parser'
|
4
|
+
|
5
|
+
module EISCP
|
6
|
+
class Receiver
|
7
|
+
# This module discovers receivers on the local LAN.
|
8
|
+
#
|
9
|
+
module Discovery
|
10
|
+
# ISCP Magic Packet for Autodiscovery
|
11
|
+
ONKYO_MAGIC = Message.new(command: 'ECN', value: 'QSTN', terminator: "\r\n", unit_type: 'x').to_eiscp
|
12
|
+
|
13
|
+
# Populates Receiver attributes with info from ECNQSTN response.
|
14
|
+
#
|
15
|
+
def ecn_string_to_ecn_array(ecn_string)
|
16
|
+
hash = {}
|
17
|
+
message = Parser.parse(ecn_string)
|
18
|
+
array = message.value.split('/')
|
19
|
+
hash[:model] = array.shift
|
20
|
+
hash[:port] = array.shift.to_i
|
21
|
+
hash[:area] = array.shift
|
22
|
+
hash[:mac_address] = array.shift
|
23
|
+
hash
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns an array of discovered Receiver objects.
|
27
|
+
#
|
28
|
+
def discover(discovery_port = Receiver::ONKYO_PORT)
|
29
|
+
sock = UDPSocket.new
|
30
|
+
sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
|
31
|
+
sock.send(ONKYO_MAGIC, 0, '<broadcast>', discovery_port)
|
32
|
+
data = []
|
33
|
+
loop do
|
34
|
+
|
35
|
+
begin
|
36
|
+
msg, addr = sock.recvfrom_nonblock(1024)
|
37
|
+
data << Receiver.new(addr[2], ecn_string_to_ecn_array(msg))
|
38
|
+
rescue IO::WaitReadable
|
39
|
+
io = IO.select([sock], nil, nil, 0.5)
|
40
|
+
if io.nil?
|
41
|
+
return data
|
42
|
+
else
|
43
|
+
retry
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/eiscp/receiver.rb
CHANGED
@@ -1,180 +1,98 @@
|
|
1
|
-
require 'socket'
|
2
|
-
require 'eiscp/message'
|
3
1
|
require 'resolv'
|
2
|
+
require_relative './receiver'
|
3
|
+
require_relative './receiver/discovery'
|
4
|
+
require_relative './receiver/connection'
|
5
|
+
require_relative './receiver/command_methods'
|
4
6
|
|
5
7
|
module EISCP
|
8
|
+
# The EISCP::Receiver class is used to communicate with one or more
|
9
|
+
# receivers the network. A Receiver can be instantiated automatically
|
10
|
+
# using discovery, or by hostname and port.
|
11
|
+
#
|
12
|
+
# receiver = EISCP::Receiver.new # find first receiver on LAN
|
13
|
+
# receiver = EISCP::Receiver.new('192.168.1.12') # default port
|
14
|
+
# receiver = EISCP::Receiver.new('192.168.1.12', 60129) # non standard port
|
15
|
+
#
|
6
16
|
class Receiver
|
17
|
+
extend Discovery
|
18
|
+
include Connection
|
19
|
+
include CommandMethods
|
7
20
|
|
21
|
+
# Receiver's IP address
|
8
22
|
attr_accessor :host
|
23
|
+
# Receiver's model string
|
9
24
|
attr_accessor :model
|
25
|
+
# Receiver's ISCP port
|
10
26
|
attr_accessor :port
|
27
|
+
# Receiver's region
|
11
28
|
attr_accessor :area
|
29
|
+
# Receiver's MAC address
|
12
30
|
attr_accessor :mac_address
|
13
31
|
|
14
|
-
ONKYO_MAGIC = Message.new("ECN", "QSTN", "x").to_eiscp
|
15
|
-
ONKYO_PORT = 60128
|
16
|
-
|
17
32
|
# Create a new EISCP object to communicate with a receiver.
|
18
33
|
# If no host is given, use auto discovery and create a
|
19
34
|
# receiver object using the first host to respond.
|
20
|
-
|
21
|
-
def initialize(host = nil,
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
35
|
+
#
|
36
|
+
def initialize(host = nil, info_hash = {}, &block)
|
37
|
+
# This defines the behavior of CommandMethods by telling it what to do wit
|
38
|
+
# the Message object that results from a CommandMethod being called. All
|
39
|
+
# we're doing here is calling #send_recv
|
40
|
+
#
|
41
|
+
CommandMethods.generate {|message|self.send_recv message}
|
42
|
+
|
43
|
+
# This proc sets the four ECN attributes and initiates a connection to the
|
44
|
+
# receiver.
|
45
|
+
#
|
46
|
+
set_attrs = lambda do |hash|
|
47
|
+
@model = hash[:model]
|
48
|
+
@port = hash[:port]
|
49
|
+
@area = hash[:area]
|
50
|
+
@mac_address = hash[:mac_address]
|
51
|
+
if block_given?
|
52
|
+
connect(@host, @port, &block)
|
26
53
|
else
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
30
|
-
@host = Resolv.getaddress host
|
31
|
-
@port = port
|
32
|
-
unless @model
|
33
|
-
set_info get_ecn
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def set_info(ecn_string)
|
38
|
-
array = self.class.parse_ecn(ecn_string)
|
39
|
-
@model = array.shift
|
40
|
-
@port = array.shift.to_i
|
41
|
-
@area = array.shift
|
42
|
-
@mac_address = array.shift.split("\x19")[0]
|
43
|
-
return self
|
44
|
-
end
|
45
|
-
|
46
|
-
def get_ecn
|
47
|
-
self.class.discover.each do |entry|
|
48
|
-
if @host == entry[1]
|
49
|
-
return entry[0]
|
54
|
+
connect(@host, @port)
|
50
55
|
end
|
51
56
|
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Gets the ECNQSTN response of self using @host
|
55
|
-
# then parses it with parse_ecn, returning an array
|
56
|
-
# with receiver info
|
57
|
-
|
58
|
-
def get_ecn_array
|
59
|
-
self.class.discover.each do |entry|
|
60
|
-
if @host == entry[1]
|
61
|
-
array = self.class.parse_ecn(entry[0])
|
62
|
-
end
|
63
|
-
return array
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
# Returns array containing @model, @port, @area, and @mac_address
|
68
|
-
# from ECNQSTN response
|
69
|
-
|
70
|
-
def self.parse_ecn(ecn_string)
|
71
|
-
message = EISCP::Message.parse(ecn_string)
|
72
|
-
message.parameter.split("/")
|
73
|
-
end
|
74
|
-
|
75
|
-
# Internal method for receiving data with a timeout
|
76
|
-
|
77
|
-
def self.recv(sock, timeout = 0.5)
|
78
|
-
data = []
|
79
|
-
while true
|
80
|
-
ready = IO.select([sock], nil, nil, timeout)
|
81
|
-
if ready != nil
|
82
|
-
then readable = ready[0]
|
83
|
-
else
|
84
|
-
return data
|
85
|
-
end
|
86
|
-
|
87
|
-
|
88
|
-
readable.each do |socket|
|
89
|
-
begin
|
90
|
-
if socket == sock
|
91
|
-
data << sock.recv_nonblock(1024).chomp
|
92
|
-
end
|
93
|
-
rescue IO::WaitReadable
|
94
|
-
retry
|
95
|
-
end
|
96
|
-
end
|
97
57
|
|
58
|
+
# This lambda sets the host IP after resolving it
|
59
|
+
#
|
60
|
+
set_host = lambda do |hostname|
|
61
|
+
@host = Resolv.getaddress hostname
|
98
62
|
end
|
99
|
-
end
|
100
|
-
|
101
|
-
# Returns an array of arrays consisting of a discovery response packet string
|
102
|
-
# and the source ip address of the reciever.
|
103
|
-
|
104
|
-
def self.discover
|
105
|
-
sock = UDPSocket.new
|
106
|
-
sock.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
|
107
|
-
sock.send(ONKYO_MAGIC, 0, '<broadcast>', ONKYO_PORT)
|
108
|
-
data = []
|
109
|
-
while true
|
110
|
-
ready = IO.select([sock], nil, nil, 0.5)
|
111
|
-
if ready != nil
|
112
|
-
then readable = ready[0]
|
113
|
-
else
|
114
|
-
return data
|
115
|
-
end
|
116
|
-
|
117
63
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
64
|
+
# When no host is given, the first discovered host is returned.
|
65
|
+
#
|
66
|
+
# When a host is given without a hash ::discover will be used to find
|
67
|
+
# a receiver that matches.
|
68
|
+
#
|
69
|
+
# Else, use the given host and hash to create a new Receiver object.
|
70
|
+
# This is how ::discover creates Receivers.
|
71
|
+
#
|
72
|
+
case
|
73
|
+
when host.nil?
|
74
|
+
first_found = Receiver.discover[0]
|
75
|
+
set_host.call first_found.host
|
76
|
+
set_attrs.call first_found.ecn_hash
|
77
|
+
when info_hash.empty?
|
78
|
+
set_host.call host
|
79
|
+
Receiver.discover.each do |receiver|
|
80
|
+
receiver.host == @host && set_attrs.call(receiver.ecn_hash)
|
127
81
|
end
|
128
|
-
|
82
|
+
else
|
83
|
+
set_host.call host
|
84
|
+
set_attrs.call info_hash
|
129
85
|
end
|
130
86
|
end
|
131
87
|
|
132
|
-
#
|
133
|
-
|
134
|
-
def
|
135
|
-
|
136
|
-
|
137
|
-
|
88
|
+
# Return ECN hash with model, port, area, and MAC address
|
89
|
+
#
|
90
|
+
def ecn_hash
|
91
|
+
{ model: @model,
|
92
|
+
port: @port,
|
93
|
+
area: @area,
|
94
|
+
mac_address: @mac_address
|
95
|
+
}
|
138
96
|
end
|
139
|
-
|
140
|
-
# Send a packet string and return recieved data string.
|
141
|
-
|
142
|
-
def send_recv(eiscp_packet)
|
143
|
-
sock = TCPSocket.new @host, @port
|
144
|
-
sock.puts eiscp_packet
|
145
|
-
return Receiver.recv(sock, 0.5)
|
146
|
-
end
|
147
|
-
|
148
|
-
# Open a TCP connection to the host and print all received messages until
|
149
|
-
# killed.
|
150
|
-
|
151
|
-
def connect(&block)
|
152
|
-
sock = TCPSocket.new @host, @port
|
153
|
-
while true
|
154
|
-
ready = IO.select([sock], nil, nil, nil)
|
155
|
-
if ready != nil
|
156
|
-
then readable = ready[0]
|
157
|
-
else
|
158
|
-
return
|
159
|
-
end
|
160
|
-
|
161
|
-
readable.each do |socket|
|
162
|
-
begin
|
163
|
-
if socket == sock
|
164
|
-
data = sock.recv_nonblock(1024).chomp
|
165
|
-
if block_given?
|
166
|
-
yield data
|
167
|
-
else
|
168
|
-
puts data
|
169
|
-
end
|
170
|
-
end
|
171
|
-
rescue IO::WaitReadable
|
172
|
-
retry
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
97
|
end
|
180
98
|
end
|
data/lib/eiscp.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# Library for controlling Onkyo receivers over TCP/IP.
|
2
|
-
|
2
|
+
#
|
3
3
|
module EISCP
|
4
|
-
VERSION = '0.0.
|
4
|
+
VERSION = '0.0.4'
|
5
5
|
end
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
require_relative './eiscp/receiver'
|
8
|
+
require_relative './eiscp/message'
|
9
|
+
require_relative './eiscp/dictionary'
|
10
|
+
require_relative './eiscp/parser'
|
data/onkyo_eiscp_ruby.gemspec
CHANGED
@@ -1,27 +1,28 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'onkyo_eiscp_ruby'
|
3
3
|
s.version = File.read(File.expand_path('VERSION', File.dirname(__FILE__))).strip
|
4
|
+
s.licenses = ['MIT']
|
4
5
|
s.platform = Gem::Platform::RUBY
|
5
6
|
s.summary = 'Manipulate Onkyo stereos with the eISCP protocol'
|
6
7
|
s.files = Dir.glob('{bin,config,lib,test,doc}/**/*') +
|
7
|
-
[
|
8
|
-
s.extra_rdoc_files = [
|
8
|
+
['VERSION', 'onkyo_eiscp_ruby.gemspec', 'eiscp-commands.yaml']
|
9
|
+
s.extra_rdoc_files = ['README.md']
|
9
10
|
s.require_path = 'lib'
|
10
11
|
|
11
|
-
s.homepage =
|
12
|
+
s.homepage = 'https://github.com/mikerodrigues/onkyo_eiscp_ruby'
|
12
13
|
|
13
14
|
s.description = %q(
|
14
|
-
Control Onkyo receivers over the network.Use the provided binary
|
15
|
+
Control Onkyo receivers over the network.Use the provided binary or
|
15
16
|
require the library for use in your scripts.
|
16
17
|
)
|
17
18
|
|
18
|
-
s.author =
|
19
|
-
s.email =
|
19
|
+
s.author = 'Michael Rodrigues'
|
20
|
+
s.email = 'mikebrodrigues@gmail.com'
|
20
21
|
|
21
|
-
s.test_files = Dir[
|
22
|
+
s.test_files = Dir['test/tc*.rb']
|
22
23
|
s.executables = %w(
|
23
24
|
onkyo.rb
|
24
|
-
|
25
|
+
onkyo_server.rb
|
25
26
|
)
|
26
27
|
|
27
28
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require_relative '../lib/eiscp/dictionary.rb'
|
2
|
+
require 'minitest/autorun'
|
3
|
+
|
4
|
+
class TestDictionary < MiniTest::Test
|
5
|
+
def test_zone_from_command
|
6
|
+
assert_equal(EISCP::Dictionary.zone_from_command('PWR'), 'main')
|
7
|
+
assert_equal(EISCP::Dictionary.zone_from_command('ZPW'), 'zone2')
|
8
|
+
assert_equal(EISCP::Dictionary.zone_from_command('CDS'), 'dock')
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_command_to_name
|
12
|
+
assert_equal(EISCP::Dictionary.command_to_name('PWR'), 'system-power')
|
13
|
+
assert_equal(EISCP::Dictionary.command_to_name('ZPW'), 'power2')
|
14
|
+
assert_equal(EISCP::Dictionary.command_to_name('PW3'), 'power3')
|
15
|
+
assert_equal(EISCP::Dictionary.command_to_name('PW4'), 'power4')
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_command_name_to_command
|
19
|
+
assert_equal(EISCP::Dictionary.command_name_to_command('system-power'), 'PWR')
|
20
|
+
assert_equal(EISCP::Dictionary.command_name_to_command('master-volume'), 'MVL')
|
21
|
+
assert_equal(EISCP::Dictionary.command_name_to_command('power2'), 'ZPW')
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_command_value_to_value_name
|
25
|
+
assert_equal(EISCP::Dictionary.command_value_to_value_name('PWR', '01'), 'on')
|
26
|
+
assert_equal(EISCP::Dictionary.command_value_to_value_name('PWR', 'QSTN'), 'query')
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_command_value_name_to_value
|
30
|
+
assert_equal(EISCP::Dictionary.command_value_name_to_value('PWR', 'on'), '01')
|
31
|
+
assert_equal(EISCP::Dictionary.command_value_name_to_value('ZPW', 'on'), '01')
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_description_from_command_name
|
35
|
+
assert_equal(EISCP::Dictionary.description_from_command_name('system-power', 'main'), 'System Power Command')
|
36
|
+
assert_equal(EISCP::Dictionary.description_from_command_name('power2', 'zone2'), 'Zone2 Power Command')
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_description_from_command
|
40
|
+
assert_equal(EISCP::Dictionary.description_from_command('PWR'), 'System Power Command')
|
41
|
+
assert_equal(EISCP::Dictionary.description_from_command('ZPW'), 'Zone2 Power Command')
|
42
|
+
end
|
43
|
+
end
|
data/test/tc_message.rb
CHANGED
@@ -1,27 +1,24 @@
|
|
1
|
-
require_relative
|
2
|
-
require
|
1
|
+
require_relative '../lib/eiscp/message'
|
2
|
+
require 'minitest/autorun'
|
3
3
|
|
4
|
-
class TestMessage < Test
|
5
|
-
|
6
|
-
|
7
|
-
DISCOVERY_PACKET = EISCP::Message.new('ECN', 'QSTN', 'x', '!')
|
4
|
+
class TestMessage < MiniTest::Test
|
5
|
+
DISCOVERY_PACKET = EISCP::Message.new(command: 'ECN', value: 'QSTN', terminator: "\r\n", unit_type: 'x', start: '!')
|
8
6
|
DISCOVERY_STRING = DISCOVERY_PACKET.to_eiscp
|
9
7
|
|
10
|
-
|
11
8
|
def test_create_discovery_iscp_message
|
12
|
-
assert_equal(EISCP::Message.new(
|
9
|
+
assert_equal(EISCP::Message.new(command: 'ECN', value: 'QSTN', terminator: "\r\n", unit_type: 'x', start: '!').to_iscp, '!xECNQSTN')
|
13
10
|
end
|
14
11
|
|
15
|
-
def
|
16
|
-
assert_equal(EISCP::Message.
|
12
|
+
def test_create_messages
|
13
|
+
assert_equal(EISCP::Message.new(command: 'PWR', value: '01').to_iscp, '!1PWR01')
|
14
|
+
assert_equal(EISCP::Message.new(command: 'MVL', value: 'QSTN').to_iscp, '!1MVLQSTN')
|
17
15
|
end
|
18
16
|
|
19
17
|
def test_create_discovery_packet_string
|
20
18
|
assert_equal(DISCOVERY_PACKET.to_eiscp, DISCOVERY_STRING)
|
21
19
|
end
|
22
20
|
|
23
|
-
def
|
24
|
-
|
21
|
+
def test_validate_valid_message_with_variable
|
22
|
+
# Commands that return something unexpected like an artist name
|
25
23
|
end
|
26
|
-
|
27
24
|
end
|
data/test/tc_parser.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require_relative '../lib/eiscp/parser'
|
2
|
+
require_relative '../lib/eiscp/message'
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
class TestParser < MiniTest::Test
|
6
|
+
DISCOVERY_PACKET = EISCP::Message.new(command: 'ECN', value: 'QSTN', terminator: "\r\n", unit_type: 'x', start: '!')
|
7
|
+
DISCOVERY_STRING = DISCOVERY_PACKET.to_eiscp
|
8
|
+
|
9
|
+
def test_parse_discovery_iscp_message
|
10
|
+
assert_equal(EISCP::Parser.parse('!xECNQSTN').to_iscp, '!xECNQSTN')
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_parse_iscp_messages
|
14
|
+
assert_equal(EISCP::Parser.parse('PWR 01').to_iscp, '!1PWR01')
|
15
|
+
assert_equal(EISCP::Parser.parse('PWR01').to_iscp, '!1PWR01')
|
16
|
+
assert_equal(EISCP::Parser.parse('!1PWR01').to_iscp, '!1PWR01')
|
17
|
+
assert_equal(EISCP::Parser.parse('!1PWR 01').to_iscp, '!1PWR01')
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_parse_discovery_packet_string
|
21
|
+
assert_equal(EISCP::Parser.parse(DISCOVERY_STRING).to_eiscp, DISCOVERY_PACKET.to_eiscp)
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_parse_human_readable
|
25
|
+
assert_equal(EISCP::Parser.parse('system-power on'), EISCP::Message.new(command: 'PWR', value: '01'))
|
26
|
+
assert_equal(EISCP::Parser.parse('main system-power on'), EISCP::Message.new(command: 'PWR', value: '01'))
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_return_nil_for_fake_human_readable
|
30
|
+
assert_equal(EISCP::Parser.parse('fake-command value'), nil)
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
data/test/tc_receiver.rb
CHANGED
metadata
CHANGED
@@ -1,41 +1,53 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: onkyo_eiscp_ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Rodrigues
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-09-14 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 "
|
15
15
|
email: mikebrodrigues@gmail.com
|
16
16
|
executables:
|
17
17
|
- onkyo.rb
|
18
|
-
-
|
18
|
+
- onkyo_server.rb
|
19
19
|
extensions: []
|
20
20
|
extra_rdoc_files:
|
21
21
|
- README.md
|
22
22
|
files:
|
23
23
|
- README.md
|
24
24
|
- VERSION
|
25
|
-
- bin/
|
25
|
+
- bin/mock_receiver.rb
|
26
26
|
- bin/onkyo.rb
|
27
|
+
- bin/onkyo_server.rb
|
27
28
|
- eiscp-commands.yaml
|
28
29
|
- lib/eiscp.rb
|
29
|
-
- lib/eiscp/
|
30
|
+
- lib/eiscp/dictionary.rb
|
31
|
+
- lib/eiscp/dictionary/dictionary_generators.rb
|
32
|
+
- lib/eiscp/dictionary/dictionary_helpers.rb
|
30
33
|
- lib/eiscp/message.rb
|
31
|
-
- lib/eiscp/
|
34
|
+
- lib/eiscp/parser.rb
|
35
|
+
- lib/eiscp/parser/dynamic_value_parser.rb
|
36
|
+
- lib/eiscp/parser/eiscp_parser.rb
|
37
|
+
- lib/eiscp/parser/human_readable_parser.rb
|
38
|
+
- lib/eiscp/parser/iscp_parser.rb
|
32
39
|
- lib/eiscp/receiver.rb
|
40
|
+
- lib/eiscp/receiver/command_methods.rb
|
41
|
+
- lib/eiscp/receiver/connection.rb
|
42
|
+
- lib/eiscp/receiver/discovery.rb
|
33
43
|
- onkyo_eiscp_ruby.gemspec
|
34
|
-
- test/
|
44
|
+
- test/tc_dictionary.rb
|
35
45
|
- test/tc_message.rb
|
46
|
+
- test/tc_parser.rb
|
36
47
|
- test/tc_receiver.rb
|
37
48
|
homepage: https://github.com/mikerodrigues/onkyo_eiscp_ruby
|
38
|
-
licenses:
|
49
|
+
licenses:
|
50
|
+
- MIT
|
39
51
|
metadata: {}
|
40
52
|
post_install_message:
|
41
53
|
rdoc_options: []
|
@@ -43,21 +55,22 @@ require_paths:
|
|
43
55
|
- lib
|
44
56
|
required_ruby_version: !ruby/object:Gem::Requirement
|
45
57
|
requirements:
|
46
|
-
- -
|
58
|
+
- - '>='
|
47
59
|
- !ruby/object:Gem::Version
|
48
60
|
version: '0'
|
49
61
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
50
62
|
requirements:
|
51
|
-
- -
|
63
|
+
- - '>='
|
52
64
|
- !ruby/object:Gem::Version
|
53
65
|
version: '0'
|
54
66
|
requirements: []
|
55
67
|
rubyforge_project:
|
56
|
-
rubygems_version: 2.2.
|
68
|
+
rubygems_version: 2.2.2
|
57
69
|
signing_key:
|
58
70
|
specification_version: 4
|
59
71
|
summary: Manipulate Onkyo stereos with the eISCP protocol
|
60
72
|
test_files:
|
61
|
-
- test/
|
73
|
+
- test/tc_parser.rb
|
62
74
|
- test/tc_receiver.rb
|
63
|
-
- test/
|
75
|
+
- test/tc_dictionary.rb
|
76
|
+
- test/tc_message.rb
|
data/lib/eiscp/command.rb
DELETED
@@ -1,99 +0,0 @@
|
|
1
|
-
require 'yaml'
|
2
|
-
require 'eiscp/receiver'
|
3
|
-
require 'ostruct'
|
4
|
-
|
5
|
-
module Command
|
6
|
-
|
7
|
-
@@yaml_file_path = File.join(File.expand_path(File.dirname(__FILE__)), '../../eiscp-commands.yaml')
|
8
|
-
@@yaml_object = YAML.load(File.read(@@yaml_file_path))
|
9
|
-
@@modelsets = @@yaml_object["modelsets"]
|
10
|
-
@@yaml_object.delete("modelsets")
|
11
|
-
@@zones = @@yaml_object.map{|k, v| k}
|
12
|
-
@@zones.each {|zone| class_variable_set("@@#{zone}", nil) }
|
13
|
-
@@main = @@yaml_object['main']
|
14
|
-
|
15
|
-
def self.command_to_name(command)
|
16
|
-
return @@main[command]['name']
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.command_name_to_command(name)
|
20
|
-
@@main.each_pair do |command, attrs|
|
21
|
-
if attrs['name'] == name
|
22
|
-
return command
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.command_value_to_value_name(command, value)
|
28
|
-
return @@main[command]['values'][value]['name']
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.command_value_name_to_value(command, name)
|
32
|
-
@@main[command]['values'].each do |k, v|
|
33
|
-
if v['name'] == name.to_s
|
34
|
-
return k
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
|
40
|
-
def self.description_from_command_name(name)
|
41
|
-
@@main.each_pair do |command, attrs|
|
42
|
-
if attrs['name'] == name
|
43
|
-
return @@main[command]['description']
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.description_from_command(command)
|
49
|
-
return @@main[command]['description']
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.description_from_command_value(command, value)
|
53
|
-
return @@main[command]['values'].select do |k, v|
|
54
|
-
if k == value
|
55
|
-
return v['description']
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.list_all_commands
|
61
|
-
@@main.each_pair do |command, attrs|
|
62
|
-
puts "#{command} - #{attrs['name']}: #{attrs['description']}"
|
63
|
-
attrs['values'].each_pair do |k, v|
|
64
|
-
puts "--#{k}:#{v}"
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.list_compatible_commands(modelstring)
|
70
|
-
sets = []
|
71
|
-
@@modelsets.each_pair do |set, array|
|
72
|
-
if array.include? modelstring
|
73
|
-
sets << set
|
74
|
-
end
|
75
|
-
end
|
76
|
-
return sets
|
77
|
-
end
|
78
|
-
|
79
|
-
def self.parse(string)
|
80
|
-
array = string.split(" ")
|
81
|
-
zone = 'main'
|
82
|
-
command_name = ''
|
83
|
-
parameter_name = ''
|
84
|
-
if array.count == 3
|
85
|
-
zone = array.shift
|
86
|
-
command_name = array.shift
|
87
|
-
parameter_name = array.shift
|
88
|
-
elsif array.count == 2
|
89
|
-
command_name = array.shift
|
90
|
-
parameter_name = array.shift
|
91
|
-
end
|
92
|
-
command = Command.command_name_to_command(command_name)
|
93
|
-
parameter = Command.command_value_name_to_value(command, parameter_name)
|
94
|
-
return EISCP::Message.new(command, parameter)
|
95
|
-
end
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
|