Class: HIDAPI::Engine
- Inherits:
-
Object
- Object
- HIDAPI::Engine
- Defined in:
- lib/hidapi/engine.rb
Overview
A wrapper around the USB context that makes it easy to locate HID devices.
Constant Summary collapse
- HID_CLASS =
Contains the class code for HID devices from LIBUSB.
LIBUSB::CLASS_HID
Instance Method Summary collapse
-
#enumerate(vendor_id = 0, product_id = 0, options = {}) ⇒ Object
Enumerates the HID devices matching the vendor and product IDs.
-
#get_device(vendor_id, product_id, serial_number = nil, options = {}) ⇒ Object
Gets the first device with the specified vendor_id, product_id, and optionally serial_number.
-
#get_device_by_path(path, options = {}) ⇒ Object
Gets the device with the specified path.
-
#initialize ⇒ Engine
constructor
Creates a new engine.
-
#inspect ⇒ Object
:nodoc:.
-
#open(vendor_id, product_id, serial_number = nil, options = {}) ⇒ Object
Opens the first device with the specified vendor_id, product_id, and optionally serial_number.
-
#open_path(path, options = {}) ⇒ Object
Opens the device with the specified path.
-
#to_s ⇒ Object
:nodoc:.
-
#usb_code_for_current_locale ⇒ Object
Gets the USB code for the current locale.
Constructor Details
#initialize ⇒ Engine
Creates a new engine.
14 15 16 |
# File 'lib/hidapi/engine.rb', line 14 def initialize @context = LIBUSB::Context.new end |
Instance Method Details
#enumerate(vendor_id = 0, product_id = 0, options = {}) ⇒ Object
Enumerates the HID devices matching the vendor and product IDs.
Both vendor_id and product_id are optional. They will act as a wild card if set to 0 (the default).
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/hidapi/engine.rb', line 23 def enumerate(vendor_id = 0, product_id = 0, = {}) raise HIDAPI::HidApiError, 'not initialized' unless @context if vendor_id.is_a?(Hash) || (vendor_id.is_a?(String) && .empty?) = vendor_id vendor_id = 0 product_id = 0 end if product_id.is_a?(Hash) || (product_id.is_a?(String) && .empty?) = product_id product_id = 0 end if .is_a?(String) || .is_a?(Symbol) = { as: } end unless .nil? || .is_a?(Hash) raise ArgumentError, 'options hash is invalid' end klass = ( || {}).delete(:as) || 'HIDAPI::Device' klass = Object.const_get(klass) unless klass == :no_mapping filters = { bClass: HID_CLASS } unless vendor_id.nil? || vendor_id.to_i == 0 filters[:idVendor] = vendor_id.to_i end unless product_id.nil? || product_id.to_i == 0 filters[:idProduct] = product_id.to_i end list = @context.devices(filters) if klass != :no_mapping list.to_a.map{ |dev| klass.new(dev) } else list.to_a end end |
#get_device(vendor_id, product_id, serial_number = nil, options = {}) ⇒ Object
Gets the first device with the specified vendor_id, product_id, and optionally serial_number.
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/hidapi/engine.rb', line 68 def get_device(vendor_id, product_id, serial_number = nil, = {}) raise ArgumentError, 'vendor_id must be provided' if vendor_id.to_i == 0 raise ArgumentError, 'product_id must be provided' if product_id.to_i == 0 if serial_number.is_a?(Hash) = serial_number serial_number = nil end klass = ( || {}).delete(:as) || 'HIDAPI::Device' klass = Object.const_get(klass) unless klass == :no_mapping list = enumerate(vendor_id, product_id, as: :no_mapping) return nil unless list && list.count > 0 if serial_number.to_s == '' if klass != :no_mapping return klass.new(list.first) else return list.first end end list.each do |dev| if dev.serial_number == serial_number if klass != :no_mapping return klass.new(dev) else return dev end end end nil end |
#get_device_by_path(path, options = {}) ⇒ Object
Gets the device with the specified path.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/hidapi/engine.rb', line 110 def get_device_by_path(path, = {}) # Our linux setup routine creates convenient /dev/hidapi/* links. # If the user wants to open one of those, we can simple parse the link to generate # the path that the library expects. if File.exist?(path) hidapi_regex = /^\/dev\/hidapi\// usb_bus_regex = /^\/dev\/bus\/usb\/(?<BUS>\d+)\/(?<ADDR>\d+)$/ if hidapi_regex.match(path) path = File.(File.readlink(path), File.dirname(path)) elsif !usb_bus_regex.match(path) raise HIDAPI::DevicePathInvalid, 'Cannot open file paths other than /dev/hidapi/XXX or /dev/bus/usb/XXX/XXX paths.' end # path should now be in the form /dev/bus/usb/AAA/BBB match = usb_bus_regex.match(path) raise HIDAPI::DevicePathInvalid, "Link target does not appear valid (#{path})." unless match interface = (.delete(:interface) || 0).to_s(16) path = HIDAPI::Device.validate_path("#{match['BUS']}:#{match['ADDR']}:#{interface}") end valid_path = HIDAPI::Device.validate_path(path) raise HIDAPI::DevicePathInvalid, "Path should be in BUS:ADDRESS:INTERFACE format with each value being in hexadecimal (ie - 0001:01A:00), not #{path}." unless valid_path path = valid_path klass = ( || {}).delete(:as) || 'HIDAPI::Device' klass = Object.const_get(klass) unless klass == :no_mapping enumerate(as: :no_mapping).each do |usb_dev| usb_dev.settings.each do |intf_desc| if intf_desc.bInterfaceClass == HID_CLASS dev_path = HIDAPI::Device.make_path(usb_dev, intf_desc.bInterfaceNumber) if dev_path == path if klass != :no_mapping return klass.new(usb_dev, intf_desc.bInterfaceNumber) else return usb_dev end end end end end end |
#inspect ⇒ Object
:nodoc:
187 188 189 |
# File 'lib/hidapi/engine.rb', line 187 def inspect # :nodoc: "#<#{self.class.name}:#{self.object_id.to_hex(16)} context=0x#{@context.object_id.to_hex(16)}>" end |
#open(vendor_id, product_id, serial_number = nil, options = {}) ⇒ Object
Opens the first device with the specified vendor_id, product_id, and optionally serial_number.
103 104 105 106 |
# File 'lib/hidapi/engine.rb', line 103 def open(vendor_id, product_id, serial_number = nil, = {}) dev = get_device(vendor_id, product_id, serial_number, ) dev.open if dev end |
#open_path(path, options = {}) ⇒ Object
Opens the device with the specified path.
161 162 163 164 |
# File 'lib/hidapi/engine.rb', line 161 def open_path(path, = {}) dev = get_device_by_path(path, ) dev.open if dev end |
#to_s ⇒ Object
:nodoc:
191 192 193 |
# File 'lib/hidapi/engine.rb', line 191 def to_s # :nodoc: inspect end |
#usb_code_for_current_locale ⇒ Object
Gets the USB code for the current locale.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/hidapi/engine.rb', line 168 def usb_code_for_current_locale @usb_code_for_current_locale ||= begin locale = I18n.locale if locale locale = locale.to_s.partition('.')[0] # remove encoding result = HIDAPI::Language.get_by_code(locale) unless result locale = locale.partition('_')[0] # chop off extra specification result = HIDAPI::Language.get_by_code(locale) end result ? result[:usb_code] : 0 else 0 end end end |