Class: RubyHid::Device

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_hid/device.rb

Overview

The main interface for the Buzz controllers. Primarily used to monitor key pushes and trigger events. Keep a single instance of the class:

`RubyHid::Device.new`

The `each` method exposes events directly as they come in

`device.each { |event| puts event }`

The `start_watching` method starts a background job which runs the events bound to each button via the RubyHid::Button class. You can end this worker with `stop_watching`.

Defined Under Namespace

Classes: Event

Constant Summary collapse

BUTTON_TYPE =

Event types we're interested in, used to filter out meta-data.

1 - button (0, 1) 3 - axis (usually 0 - 255, centred on 128)

1
AXIS_TYPE =
3
ALLOWED_EVENT_TYPES =
[
  BUTTON_TYPE,
  AXIS_TYPE
]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filename = nil, block_size = 24) ⇒ Device

Initialise device, getting event file from /dev/input/by-id/


80
81
82
83
84
85
86
87
# File 'lib/ruby_hid/device.rb', line 80

def initialize(filename=nil, block_size=24)
  raise NoFileSpecifiedError if filename.nil?
  @dev = File.open(filename)
  @block_size = block_size
rescue NoFileSpecifiedError, Errno::ENOENT => er
  puts "Could not find device: are your controllers plugged in?"
  raise er
end

Instance Attribute Details

#workerObject

The worker is a thread which is watching the device


58
59
60
# File 'lib/ruby_hid/device.rb', line 58

def worker
  @worker
end

Class Method Details

.list(search_term = nil) ⇒ Object

List possible devices from /dev/input/by-id/

Or, list devices containing a string with search_term argument


47
48
49
50
51
52
53
# File 'lib/ruby_hid/device.rb', line 47

def Device.list(search_term=nil)
  if search_term
    Dir["/dev/input/by-id/*#{search_term}*event-joystick*"]
  else
    Dir['/dev/input/by-id/*event-joystick*']
  end
end

Instance Method Details

#eachObject

Expose each event to a block of code as it comes in.


112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/ruby_hid/device.rb', line 112

def each
  begin
    loop do
      event = read
      if event
        next unless ALLOWED_EVENT_TYPES.include?(event.type)
        yield event
      end
    end
  rescue Errno::ENODEV
  end
end

#force_rightsObject


37
38
39
40
# File 'lib/ruby_hid/device.rb', line 37

def force_rights
  `sudo chmod 777 /sys/class/leds/*/brightness`
  `sudo chmod 777 /dev/input/event*`
end

#formatObject

The format string which RubyHid uses to decode raw data.


92
93
94
95
96
97
98
99
# File 'lib/ruby_hid/device.rb', line 92

def format
  @format ||= case @block_size
                when 16
                  'llSSl'
                when 24
                  'qqSSl'
              end
end

#readObject

Read a single block.


104
105
106
107
# File 'lib/ruby_hid/device.rb', line 104

def read
  bin = @dev.read @block_size
  Event.new *bin.unpack(format)
end

#start_watchingObject

Start a background worker which scans input file and triggers any events bound to each one.


129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/ruby_hid/device.rb', line 129

def start_watching
  return if @worker
  @worker = Thread.new do
    loop do
      event = read
      next unless ALLOWED_EVENT_TYPES.include?(event.type)
      case event.type
        when BUTTON_TYPE
          RubyHid::Button.trigger_event(event.code, event.value)
        when AXIS_TYPE
          RubyHid::Axis.trigger_event(event.code, event.value)
      end
    end
  end
end

#stop_watchingObject

Stop the background worker, release it's resources.


148
149
150
151
# File 'lib/ruby_hid/device.rb', line 148

def stop_watching
  @worker.kill
  @worker = nil
end