onkyo_eiscp_ruby 2.1.5 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d35b01beb072ac7058ef54920b734aff8d4d098ecc702eb9edd21ee818ad7ca0
4
- data.tar.gz: f1112ac834d03f1dea2e50aeed301ac8f0e802b55b00b0f317d7802515ffa84e
3
+ metadata.gz: c4be1b779f00fb4a2ae5f1a843278634349980f925917a0ce17d0ac509504966
4
+ data.tar.gz: 020f9f4e070d878463ac3a7b804b249e8f47817727503b77799688b170acb181
5
5
  SHA512:
6
- metadata.gz: f3a50446a0df21efd8dc6b2397daeb0cf791a997e7f0c27bb9d01c98b9e08fdc99cd68176b464882b29acc64a5f9cbe0748da690da51269f10f8f41f3d75dfc7
7
- data.tar.gz: 65bafa48d392b8578435f006de9b27b8e58b9f16d7ccd7e2d527b38f23c0e2db187204c79f9c2dfe121021907735b51f73b82cef8fb82789ac362b5c3fec228f
6
+ metadata.gz: 448f13a6a6f94e0f8808744d04236b484955b4e85f677177c4011710968320e4c258ae979865f14a8dfc118cdfe720227e7018a1b85403cda772701c10665908
7
+ data.tar.gz: e87725e4498d36c7ae383bb88f2b76273a4336ab504176fe9a2e64ad694a3d921891b6e0af034c301aaf49cac63c859f7f581b5a275d76b7173fb55a790ba371
data/README.md CHANGED
@@ -56,7 +56,7 @@ Using the Library
56
56
  `VERSION`)
57
57
 
58
58
  * You can do most everything through the `Receiver` and `Message` objects. If you
59
- want to accept user input you will probably want to use the Parser module. Be
59
+ want to accept user input you will probably want to use the `Parser` module. Be
60
60
  sure to check out the RDocs or dig through the source code. I try to keep it
61
61
  well commented/documented, and there's more functionality to the library than
62
62
  is shown here:
@@ -82,7 +82,7 @@ Using the Library
82
82
  EISCP::Receiver.discover
83
83
  ```
84
84
 
85
- * Create `Receiver` object from first discovered Receiver on the LAN
85
+ * Create `Receiver` object from first discovered receiver on the LAN
86
86
 
87
87
  ```ruby
88
88
  receiver = EISCP::Receiver.new
@@ -104,8 +104,9 @@ Using the Library
104
104
  end
105
105
  ```
106
106
 
107
- * Receivers created without a block will not connect automatically. You can use
108
- the `connect` method to create a socket and connect to the receiver.
107
+ * `Receivers` created without a block will not connect automatically. If you try
108
+ to send a command it will connect transparently, otherwise you can use the
109
+ `connect` method to explicitly open a socket to the receiver.
109
110
 
110
111
  ```ruby
111
112
  receiver.connect
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.5
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 './receiver'
5
- require_relative './message'
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\r\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00")
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!1ECNTX-NR609/60128/DX/14DAE9E967C8\x19\r\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\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
- "#{reply.zone}: "\
64
- "#{reply.command_description || reply.command} "\
65
- "-> #{reply.value_description || reply.value}"
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 |_value, attr_hash|
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, _value)}' - "\
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 |_value, attr_hash|
118
- puts " '#{EISCP::Dictionary.command_value_to_value_name(command, _value)}' - "\
119
- " #{attr_hash[:description]}"
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} #{reply.command_description || reply.command} -> #{reply.value_description || reply.value}"
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
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'eiscp/mock_receiver'
4
+ require_relative './mock_receiver'
5
5
 
6
6
  puts 'Starting server on 60128...'
7
7
 
@@ -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: nil, value: '', terminator: "\r\n", unit_type: '1', start: '!')
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
@@ -2,6 +2,7 @@
2
2
 
3
3
  module EISCP
4
4
  module Parser
5
+ # Parses commands with dynamic values
5
6
  module DynamicValueParser
6
7
  # Still trying to sort this out.
7
8
  end
@@ -34,7 +34,6 @@ module EISCP
34
34
  def self.validate(packet)
35
35
  packet.header.header_size.size == packet.command.size
36
36
  end
37
-
38
37
  end
39
38
 
40
39
  class EISCPParserException < RuntimeError; end
@@ -28,21 +28,39 @@ module EISCP
28
28
  # Returns an array of discovered Receiver objects.
29
29
  #
30
30
  def discover(discovery_port = Receiver::ONKYO_PORT)
31
+ data = []
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)
31
43
  sock = UDPSocket.new
32
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)
33
51
  sock.send(ONKYO_MAGIC, 0, '<broadcast>', discovery_port)
52
+ end
53
+
54
+ def receive_data(sock)
34
55
  data = []
35
56
  loop do
36
57
  msg, addr = sock.recvfrom_nonblock(1024)
37
58
  data << Receiver.new(addr[2], ecn_string_to_ecn_array(msg))
38
59
  rescue IO::WaitReadable
39
60
  io = IO.select([sock], nil, nil, 0.5)
40
- if io.nil?
41
- return data
42
- else
43
- retry
44
- end
61
+ break if io.nil?
45
62
  end
63
+ data
46
64
  end
47
65
  end
48
66
  end
@@ -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.5
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(/\r\n$/)
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
- Parser.parse("#{eiscp.command}#{@state[eiscp.command]}")
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
@@ -3,7 +3,7 @@
3
3
  # Library for controlling Onkyo receivers over TCP/IP.
4
4
  #
5
5
  module EISCP
6
- VERSION = '2.1.5'
6
+ VERSION = '2.1.7'
7
7
  end
8
8
 
9
9
  require_relative './eiscp/receiver'
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.5
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: 2021-03-30 00:00:00.000000000 Z
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 "