Class: Fusuma::Plugin::Inputs::Hidraw::HhkbUsbParser

Inherits:
Object
  • Object
show all
Defined in:
lib/fusuma/plugin/inputs/hidraw/hhkb_usb_parser.rb

Constant Summary collapse

BASE_TIMEOUT =

Base timeout value for reading reports

0.03
MAX_TIMEOUT =

Maximum timeout value before failure

0.2
MULTIPLIER =

Multiplier to exponentially increase timeout

1.1
MAX_REPORT_SIZE =

Maximum report size in bytes

5

Instance Method Summary collapse

Constructor Details

#initialize(hidraw_device) ⇒ HhkbUsbParser

Returns a new instance of HhkbUsbParser.

Parameters:



15
16
17
# File 'lib/fusuma/plugin/inputs/hidraw/hhkb_usb_parser.rb', line 15

def initialize(hidraw_device)
  @hidraw_device = hidraw_device
end

Instance Method Details

#parseObject

Parse HID raw device events.



20
21
22
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
# File 'lib/fusuma/plugin/inputs/hidraw/hhkb_usb_parser.rb', line 20

def parse
  File.open(@hidraw_device.hidraw_path, "rb") do |device|
    timeout = nil

    # Continuously read reports from the device.
    while (report = read_with_timeout(device, timeout))
      mouse_state = if report.empty?
        # Handle timeout case
        :end
      else
        # instance.parse_hid_report(report_bytes)
        case mouse_state
        when :begin, :update
          :update
        else
          :begin
        end
      end

      case mouse_state
      when :begin, :update
        timeout = update_timeout(timeout)
      when :end
        timeout = nil
      end

      yield mouse_state
    end
  end
end

#parse_hid_report(report_bytes) ⇒ Symbol?

Parse the HID report to determine its type.

Parameters:

  • report_bytes (String)

    the HID report as byte data

Returns:

  • (Symbol, nil)

    symbol indicating type of report or nil on error



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/fusuma/plugin/inputs/hidraw/hhkb_usb_parser.rb', line 74

def parse_hid_report(report_bytes)
  return :end if report_bytes.nil?

  # buttons, x, y, wheel, ac_pan = report_bytes.unpack("Ccccc") # Retrieve 5-byte report
  # - `C`: 1 byte unsigned integer (button state) (0..255)
  # - `c`: 1 byte signed integer (X-axis) (-127..127)
  # - `c`: 1 byte signed integer (Y-axis) (-127..127)
  # - `c`: 1 byte signed integer (Wheel) (-127..127)
  # - `c`: 1 byte signed integer (AC pan) (-127..127)
  # button_states = buttons.to_s(2).rjust(8, "0").chars.map(&:to_i)

  # puts "Raw bytes: #{report_bytes.inspect}" # Display raw byte sequence
  # puts "# Button: #{button_states.join(" ")} | X: #{x.to_s.rjust(4)} | Y: #{y.to_s.rjust(4)} | Wheel: #{wheel.to_s.rjust(4)} | AC Pan: #{ac_pan.to_s.rjust(4)}"

  :begin
end

#read_with_timeout(device, timeout) ⇒ String

Reads the HID report from the device with a timeout.

Parameters:

  • device (File)

    the opened device file

  • timeout (Float)

    the timeout duration

Returns:

  • (String)

    the HID report as bytes or an empty string on timeout



55
56
57
58
59
60
# File 'lib/fusuma/plugin/inputs/hidraw/hhkb_usb_parser.rb', line 55

def read_with_timeout(device, timeout)
  # puts "Timeout: #{timeout}"  # Log timeout for debugging
  Timeout.timeout(timeout) { device.read(MAX_REPORT_SIZE) }
rescue Timeout::Error
  ""
end

#update_timeout(timeout) ⇒ Float

Update the timeout based on previous value.

Parameters:

  • timeout (Float, nil)

    previously set timeout

Returns:

  • (Float)

    the updated timeout value



65
66
67
68
69
# File 'lib/fusuma/plugin/inputs/hidraw/hhkb_usb_parser.rb', line 65

def update_timeout(timeout)
  return BASE_TIMEOUT if timeout.nil?

  [timeout * MULTIPLIER, MAX_TIMEOUT].min
end