The Holoseat controller has a two layer communication stack. The lower (private) layer is a custom serial protocol, implemented in JSON messages. The upper (public) layer is a Socket.io event/message API wrapping around the serial protocol. This architecture places the bulk of the responsibility for implementation on the firmware, accessed using the private layer. The public layer is then only responsible for passing messages in/out of the private API and reporting when the Holoseat is disconnected.
This page serves to document both layers. Each event/message will be covered at a conceptual level followed by layer specific information and examples.
| Field | Value |
| Baud Rate | 115200 |
| Data Bits | 8 |
| Parity | None |
| Stop Bit | 1 |
This section covers the events and message that the controller responds to (aka those sent to the controller by clients).
Note, the various set_* events only broadcast their corresponding client events when they receive data that leads to an actual state change. So, if the Holoseat is already enabled and set_enabled is called with a value of True, then no state change will occur and in turn the enabled event will not be broadcast to the clients.
Purpose: Used to establish client connection
Event Specific Inputs
Response
Event Name: connect
Event Data: none
Serial Message: {"event_name":"connect", "client_id":<socket.id>}
Purpose: Used to toggle enabled state
Event Specific Inputs
Response
Event Name: set_enabled
Event Data: {"enabled":<True|False>}
Serial Message: {"event_name":"set_enabled", "client_id":<socket.id>, "data":{"enabled":<True|False>}}
Purpose: Used to give Holoseat a new configuration (aka tell it how to react to cadences)
Event Specific Inputs
Response
{"name":"wasd", "forward":{"hid":"keyboard", "responses":[{"triggerCadence":0, "actions":["w"]}]}, "reverse":{"hid":"keyboard", "responses":[{"triggerCadence":0, "actions":["s"]}]}}
This string would be hard coded into the firmware and used to initialize the default configuration object.
Used by games responding to the cadence stream instead of hid actions.
{"name":"noop", "forward":{"hid":"keyboard", "responses":[]}, "reverse":{"hid":"keyboard", "responses":[]}}
Note the use of empty arrays for the responses. This can be used separately for configurations where only one direction makes sense.
Event Name: set_configuration
Event Data: {"configuration":<configuration object>}
Serial Message: {"event_name":"set_configuration", "client_id":<socket.id>, "data":{"configuration":<configuration object>}}
Purpose: Manage the resistance level of the execise equipment Holoseat is connected to
TBD
TBD
This section covers the events and message that clients must respond to (aka those sent by the controller to clients).
Note, events and messages read from the private layer may leave out the client_id. No client_id indicate public layer shoud broadcast the event/message to all connects clients (this ia the typcial behavior). Otherwise, the event/message should be sent only to th specified client.
Purpose: Updates clients of enabled state when it changes
Event Specific Inputs
Event Name: enabled
Event Data: {"state":<"enabled" | "disabled" | "disconnected">}
Note, The public layer is the layer which determines if the state is "disconnected". This determination is made every time an event is handled by the public layer. If Holoseat is disconnectd, this event will be broadcast to all clients regardless of value in the client_id field or the original event received.
Serial Message: {"event_name":"enabled", "client_id":<socket.id>, "data":{"state":<"enabled" | "disabled">}}
Purpose: Updates clients of cadence when it changes
Event Specific Inputs
Event Name: cadence
Event Data: {"cadence":<current cadence>}
Serial Message: {"event_name":"cadence", "client_id":<socket.id>, "data":{"cadence":<current cadence>}}
Purpose: Updates clients of cadence when it changes
Event Specific Inputs
Event Name: configuration
Event Data: {"configuration":<configuration object>}
Serial Message: {"event_name":"configuration", "client_id":<socket.id>, "data":{"configuration":<configuration object>}}
Purpose: Updates clients on exercise equipment resistance
TBD
TBD
Purpose: Inform clients of attached Holoseat device and its hardware and firmare versions (see Version Scheme for details).
Message Specific Inputs
Message Data: {"type":"controller_version", "message":{"device":"<device name>", "hwVer":"<major version number>", "fwVer":"<major.minor.patch version number>"}}
Serial Message: {"event_name":"message", "client_id":<socket.id>, "data":{"type":"controller_version", "message":{"device":"<device name>", "hwVer":"<major version number>", "fwVer":"<major.minor.patch version number>"}}}
Purpose: Inform clients of error message
Message Specific Data
Message Data: {"type":"controller_error", "message":"<error message>"}
Serial Message: {"event_name":"message", "client_id":<socket.id>, "data":{"type":"controller_error", "message":"<error message>"}}