Public
Authored by Benjamin Tissoires

ratbag-emu diagrams

class diagram

classDiagram
class BaseDevice {
+simulate_actions(action, duration)
-rate
}
class UHID {
+dispatch()
-_process_one_event()
set_report(req, rnum, rtype, data)
+call_input_event()
}
class Endpoint
class Brain {
<<abstract>>
+set_report(req, rnum, rtype, data)
}
class PhysHWComponent {
<<Interface>>
+setNewState(**kwargs)
+getState()
}
class LED {
+brigthness
}
class RGBLed {
+red
+green
+blue
}
class HIDActuator {
+name
+value
+report_id
+get_HID_data(data, action)
}
class OpticalSensor {
+dpi
}
class Button
class Wheel
class LogitechHIDPP20Brain
class SteelSeriesBrain
BaseDevice o-- Endpoint : <dict> endpoints
BaseDevice o-- Brain : brain
BaseDevice o-- PhysHWComponent : <dict> physical_parts
BaseDevice o-- HIDActuator: <dict> HID_parts
UHID <|-- Endpoint
PhysHWComponent <|-- LED
PhysHWComponent <|-- RGBLed
Brain <|-- LogitechHIDPP20Brain
Brain <|-- SteelSeriesBrain
HIDActuator<|--OpticalSensor
HIDActuator<|--Button
HIDActuator<|--Wheel

Sequence diagram for dispatch():

sequenceDiagram
participant CI client
participant BaseDevice
participant @UHID
CI client->> @UHID: dispatch()
@UHID-->> Endpoint: _process_one_event()
Endpoint->>BaseDevice: set_report(req, rnum, rtype, data)
BaseDevice->>Brain: set_report(req, rnum, rtype, data)
Brain->>BaseDevice: set_new_state("RGB1", red: 255)
BaseDevice->>RGBLed: set_new_state(red: 255)

Sequence diagram for simulate_actions() (refresh rate: 1Hz):

sequenceDiagram
CI client->>BaseDevice: simulate_actions(move: {x:3}, duration: 3s)
BaseDevice->>BaseDevice : individual_action = {move: {x: 1}}
BaseDevice->>BaseDevice : data = {}
BaseDevice->>HIDActuator: for each: get_HID_data(data, individual_action)
HIDHWComponent->>HIDActuator: <OpticalSensor> `if move in action and self.name in action[move]:  data[self.report_id]`[self.name] = 1
BaseDevice->>Endpoint : for each: call_input_event(data[endpoint.report_id])
BaseDevice->>Endpoint : for each: call_input_event(data[endpoint.report_id])
BaseDevice->>Endpoint : for each: call_input_event(data[endpoint.report_id])

Notes

  • Brain can not inherit from UHID or EndPoint: it needs to process all endpoints in one place
  • rate is global to SimulatedDevice because it's a parameter only used in simulate_actions(), and it doesn't really make sense to have a special class for it
Edited
2.41 KB
  • @FFY00:

    For instantiating a Logitech G900 for example: you define a logitech-g900.yaml:

    logitech G900:
      type: ratbag-device
      endpoints:
        - 05 00 00...
        - 05 00 00...
        - 05 00 00...
      brain:
        type: LogitechHIDPP20Brain
        parameters:
          features:
             - 0x0001
             - 0x8001
      physical:
        - RGB0:
          type: RGBLed
      actuators:
        - x:
          type: OpticalSensor
          parameters:
            default_dpi: 1000
        - y:
          type: OpticalSensor
          parameters:
            default_dpi: 1000
        - wheel:
          type: Wheel
        - b0:
          type: Button
        - b1:
          type: Button
        - b2:
          type: Button
        - b3:
          type: Button
        - b4:
          type: Button
        - b5:
          type: Button
        - b6:
          type: Button
        - b7:
          type: Button
        - b8:
          type: Button
        - b9:
          type: Button
        - b10:
          type: Button

    BasedDevice then has a class method that takes a dictionary (parsed from the YAML above) and instantiate the matching BaseDevice with all of its components.

    If you want to be fancy, you can implement an include keyword (like @whot did in https://github.com/whot/uji/blob/master/uji.py#L239-L272), so you can define a generic mouse without a brain with the common x, y, wheel and 3 buttons.

Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment