class EISCP::Receiver
The EISCP::Receiver
class is used to communicate with one or more receivers the network. A Receiver
can be instantiated automatically using discovery, or by hostname and port.
receiver = EISCP::Receiver.new # find first receiver on LAN receiver = EISCP::Receiver.new('192.168.1.12') # default port receiver = EISCP::Receiver.new('192.168.1.12', 60129) # non standard port
Constants
- DEFAULT_TIMEOUT
Default connection timeout value in seconds
- ONKYO_PORT
Default Onkyo eISCP port
Attributes
Receiver’s region
Receiver’s IP address
Receiver’s MAC address
Receiver’s model string
Receiver’s ISCP port
Receiver’s connection socket
State object
Receiver’s connection thread
Public Class Methods
Create a new EISCP::Receiver
object to communicate with a receiver. If no host is given, use auto discovery and create a receiver object using the first host to respond.
# File lib/eiscp/receiver.rb, line 49 def initialize(host = nil, info_hash = {}, &block) # Initialize state # @state = {} # This defines the behavior of CommandMethods by telling it what to do # with the Message object that results from a CommandMethod being called. # All we're doing here is calling #send_recv # command_method_proc = proc { |msg| send_recv msg } CommandMethods.generate(&command_method_proc) # This proc sets the four ECN attributes and initiates a connection to the # receiver. # set_attrs = lambda do |hash| @model = hash[:model] @port = hash[:port] @area = hash[:area] @mac_address = hash[:mac_address] connect(&block) if block_given? end # This lambda sets the host IP after resolving it # set_host = lambda do |hostname| @host = Resolv.getaddress hostname end # When no host is given, the first discovered host is returned. # # When a host is given without a hash ::discover will be used to find # a receiver that matches. # # Else, use the given host and hash to create a new Receiver object. # This is how ::discover creates Receivers. # if host.nil? first_found = Receiver.discover[0] set_host.call first_found.host set_attrs.call first_found.ecn_hash elsif info_hash.empty? set_host.call host Receiver.discover.each do |receiver| receiver.host == @host && set_attrs.call(receiver.ecn_hash) end else set_host.call host set_attrs.call info_hash end end
Public Instance Methods
This creates a socket conection to the receiver if one doesn’t exist, and updates or sets the callback block if one is passed.
# File lib/eiscp/receiver.rb, line 118 def connect(&block) @socket ||= TCPSocket.new(@host, @port) update_thread(&block) rescue StandardError => e puts e end
Disconnect from the receiver by closing the socket and killing the connection thread.
# File lib/eiscp/receiver.rb, line 128 def disconnect @thread.kill @socket.close end
Return ECN hash with model, port, area, and MAC address
# File lib/eiscp/receiver.rb, line 164 def ecn_hash { model: @model, port: @port, area: @area, mac_address: @mac_address } end
This will return a human-readable represantion of the receiver’s state.
# File lib/eiscp/receiver.rb, line 173 def human_readable_state hash = {} @state.dup.each do |c, v| hash[Dictionary.command_to_name(c).to_s] = (Dictionary.command_value_to_value_name(c, v) || v.to_s).to_s end hash end
Reads the socket and returns and EISCP::Message
# File lib/eiscp/receiver.rb, line 147 def recv data = String.new data << @socket.gets until data.match(/\r\n$/) Parser.parse(data) end
Sends an EISCP::Message
object or string on the network
# File lib/eiscp/receiver.rb, line 135 def send(eiscp) connect if @socket.nil? || @socket.closed? case eiscp when EISCP::Message @socket.puts(eiscp.to_eiscp) when String @socket.puts eiscp end end
Sends an EISCP::Message
object or string on the network and returns recieved data string.
# File lib/eiscp/receiver.rb, line 155 def send_recv(eiscp) eiscp = Parser.parse(eiscp) if eiscp.is_a? String send eiscp sleep DEFAULT_TIMEOUT Parser.parse("#{eiscp.command}#{@state[eiscp.command]}") end
Runs every command that supports the ‘QSTN’ value. This is a good way to get the sate of the receiver after connecting.
# File lib/eiscp/receiver.rb, line 184 def update_state Thread.new do Dictionary.commands.each do |zone, _commands| Dictionary.commands[zone].each do |command, info| info[:values].each do |value, _| next unless value == 'QSTN' send_recv(Parser.parse("#{command}QSTN")) end end end end end
Private Instance Methods
Manages the thread and uses the same block passed to through connect
.
# File lib/eiscp/receiver.rb, line 102 def update_thread # Kill thread if it exists thread && @thread.kill @thread = Thread.new do loop do message = recv @state[message.command] = message.value yield(message) if block_given? end end end