Class: Ruku::Remote

Inherits:
BlankSlate show all
Defined in:
lib/ruku/remote.rb,
lib/ruku/clients/web.rb

Overview

Communicates with a Roku box. Known methods that you can call that correspond with buttons on the physical Roku remote include: up, down, left, right, select, home, fwd, back, pause

Calling methods with the name of the command you want to send has the same effect as calling send_roku_command with the Symbol (or String) representing your command.

Examples:

remote = Remote.new('192.168.1.10') # Use your Roku box IP or hostname
remote.pause                        # Sends play/pause to the Roku box
remote.left.down.select             # Can chain commands if you want to

Actually, all prefixes will work for all commands because they are accepted by the Roku box. Unless more commands are added to introduce ambiguities, this means only one character is needed for a command.

Examples:

remote.h           # Registers as 'home'

remote.d           # This and the following 3 lines register as 'down'
remote.do
remote.dow
remote.down

Despite this working now it is not recommended that you use this in case future added commands create ambiguity and also because it can make code less clear.

Constant Summary collapse

DEFAULT_PORT =

The port on which the Roku box listens for commands

8080
KNOWN_COMMANDS =

Known commands that the Roku box will accept - here mostly for documentation purposes

%w[up down left right select home fwd back pause]

Constants inherited from BlankSlate

BlankSlate::KEEPERS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(host, name = nil, port = DEFAULT_PORT) ⇒ Remote

Returns a new instance of Remote.



72
73
74
# File 'lib/ruku/remote.rb', line 72

def initialize(host, name=nil, port=DEFAULT_PORT)
  @host, @name, @port = host, name, port
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(*args) ⇒ Object

Consider missing methods to be names of commands to send to the box



95
96
97
98
99
100
101
# File 'lib/ruku/remote.rb', line 95

def method_missing(*args)
  # If more than one argument, assume someone is trying to use a method
  # that they don't expect will be turned into a Roku command
  throw 'Roku command takes no arguments' if args.size > 1
  roku_cmd = args[0]
  send_roku_command roku_cmd
end

Instance Attribute Details

#hostObject

Returns the value of attribute host.



70
71
72
# File 'lib/ruku/remote.rb', line 70

def host
  @host
end

#nameObject

Returns the value of attribute name.



70
71
72
# File 'lib/ruku/remote.rb', line 70

def name
  @name
end

#portObject

Returns the value of attribute port.



70
71
72
# File 'lib/ruku/remote.rb', line 70

def port
  @port
end

Class Method Details

.scan(stop_on_first = false) ⇒ Object

Scan for Roku boxes on the local network



56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/ruku/remote.rb', line 56

def self.scan(stop_on_first=false)
  # TODO: don't just use the typical IP/subnet for a home network; figure it out
  boxes = []
  prefix = '192.168.1.'
  (0..255).each do |host|
    info = Socket.getaddrinfo(prefix + host.to_s, DEFAULT_PORT)
    # Is there a better way to identify a Roku box other than looking for a hostname
    # starting with 'NP-'? There probably is - is the better way also quick?
    boxes << Remote.new(info[0][3]) if info[0][2] =~ /^NP-/i
    break if stop_on_first && !boxes.empty?
  end
  boxes
end

Instance Method Details

#<=>(other) ⇒ Object



121
122
123
# File 'lib/ruku/remote.rb', line 121

def <=>(other)
  host <=> other.host
end

#==(other) ⇒ Object

Remotes with the same host are considered equal



109
110
111
# File 'lib/ruku/remote.rb', line 109

def ==(other)
  host == other.host
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


113
114
115
# File 'lib/ruku/remote.rb', line 113

def eql?(other)
  self == other
end

#hashObject



117
118
119
# File 'lib/ruku/remote.rb', line 117

def hash
  host.hash
end

#selectObject

Overide normal Object select to make it work in the Roku remote sense



104
105
106
# File 'lib/ruku/remote.rb', line 104

def select
  send_roku_command :select
end

#send_command(cmd) ⇒ Object

Send a “raw” command to the Roku player that is not formatted in the typical style that the box is expecting to receive.



78
79
80
81
# File 'lib/ruku/remote.rb', line 78

def send_command(cmd)
  use_tcp_socket {|s| s.write cmd}
  self
end

#send_roku_command(cmd) ⇒ Object

Send a command to the Roku box in the form “press CMDn” that is used for known commands.



84
85
86
87
88
89
90
91
92
# File 'lib/ruku/remote.rb', line 84

def send_roku_command(cmd)
  cmd_string = cmd.to_s # In case it's a symbol, basically

  # For some reason the Roku box can be unresponsive with the full 'select' command. It seems
  # that 'sel' will always work, though, so send that.
  cmd_string = 'sel' if cmd_string == 'select'

  send_command "press #{cmd_string}\n"
end

#to_jsonObject



109
110
111
# File 'lib/ruku/clients/web.rb', line 109

def to_json
  "{\"host\":\"#{@host}\",\"name\":\"#{@name}\",\"port\":#{@port}}"
end

#to_sObject



125
126
127
# File 'lib/ruku/remote.rb', line 125

def to_s
  "<Remote host:#{@host}, name:#{@name || '(none)'}>"
end