Skip to Content
This documentation is provided with the HEAT environment and describes this HEAT instance.

Interface control document

1. Identification

ItemValue
DocumentICD-CMMENTALISTA-001 rev 1
ProductMentalista module (HEAT.Mentalista in the module registry)
Product versions coveredv2.0.1
PeerMentalista’s own web application, running in an automated Chrome session logged into Mentalista’s cloud backend - see Section 2
HostHEAT Capture, HEAT.Capture.ModuleSDK 2.0.5
Data modelHEAT ProtoLib 0.37.0 (bundled with HEAT.Capture.ModuleSDK 2.0.5)
Date2026-09-01
OwnerVRAI Simulation

This document is incomplete in one respect: no unit is stated, by the peer or by this module, for the four prediction values in Section 4.5. See that section for the exact field names; there is no further source to resolve this from.

2. Scope

This document defines the WebSocket-based protocol the Mentalista module exposes: HEAT Capture hosts the listener, and a client connects to it, not the other way around. It covers the listener’s connection handling, the connect command the module sends, and the four event types it recognises in response.

The client this module actually talks to is not the EEG headset. In this deployment the headset connects to Mentalista’s own web application, running in an automated Chrome session (driven via ChromeDriver) that is logged into Mentalista’s cloud backend; that backend performs the prediction inference, and the browser session relays the resulting prediction events down this WebSocket. This module has no visibility into, and no direct interface with, the headset or Mentalista’s backend - its entire contract is with whatever client connects to its listener and speaks the protocol in Section 4.

The module does not process raw sensor data - only prediction events become HEAT data. It does not authenticate a connecting client and does not encrypt the connection.

3. Interface inventory

IDNameDirectionTransportPeer
IF-CMMENTALISTA-01Prediction WebSocketBidirectionalWebSocket over HTTP, no TLSMentalista’s browser-based client

4. IF-CMMENTALISTA-01 Prediction WebSocket

4.1 Transport and addressing

ItemValue
ProtocolWebSocket, upgraded from an HTTP request accepted by a .NET HttpListener
Host and portHost:Port, default localhost:5555; see Configure
PathAny path under the listener’s root is accepted; the module does not route by path
TLSNone. Plain http:///ws://.
Non-WebSocket requestsAnswered with HTTP 400 and closed

4.2 Session and connection lifecycle

The listener exists only while a HEAT Capture session is running: it is created when the session starts and torn down when it ends. This prevents new connections after capture ends. In this release, capture end does not close WebSockets that were already upgraded; they remain active until the peer closes or their receive loop fails. Do not rely on listener teardown to bound the connection’s lifetime.

The module accepts one WebSocket upgrade per incoming request and starts a receive loop for it immediately; it does not track or limit concurrent client connections. Connecting a second client while a first remains connected is not a supported or tested configuration - the module’s connection-state fields are shared across every accepted connection, not scoped per client.

If ConnectOnStartup is enabled, the module waits ConnectInitialDelayMs after the WebSocket opens, then sends the connect command (4.4). If it is disabled, the module considers the connection established immediately with no command exchange.

The peer closes the session with a standard WebSocket close frame; the module acknowledges it and returns to listening for the next connection. Any receive-loop exception (including malformed JSON, 4.7) ends that connection’s receive loop without an application-level close handshake.

4.3 Authentication

None. Any client able to reach Host:Port and complete a WebSocket upgrade is accepted.

4.4 Messages

MessageDirectionPurpose
connectProduct to peerRequests the peer connect to a specific device; see below
readyPeer to productAnnounces the connected device’s name
predictionPeer to productCarries one set of biometric prediction values
commandSuccessPeer to productAcknowledges a command (used here only for connect)
commandErrorPeer to productReports a failed command; drives the connect retry loop

connect command payload, sent by the module:

{ "commandName": "connect", "payload": { "type": "M0" } }

type is "M0" when TargetDevice is Bluetooth (the first paired Bluetooth device matching that filter), or "S06" when TargetDevice is Synthetic (a development test device). Per the module’s own source attribution, M0/S06 targeting and resolution is defined by the Mentalista SDK on the peer side, not by this module.

If the peer responds commandError naming connect, and fewer than ConnectRetryCount retries have already been sent, the module waits (ConnectRetryDelayMs, doubling each retry up to MaxConnectRetryDelayMs) and resends connect. A commandError for any other command name, or for connect after ConnectRetryCount is exhausted, is logged only - the module does not retry further and does not close the connection.

Any event name other than the five above is received and silently ignored.

4.5 Data elements

prediction payload, at payload.predictions:

FieldTypeUnitOptionality
emotion.valencefloatNot stated by the peer or this modulePresent when the backend’s prediction model produced a value
emotion.arousalfloatNot stated by the peer or this modulePresent when the backend’s prediction model produced a value
attention.attention_indexfloatNot stated by the peer or this modulePresent when the backend’s prediction model produced a value
cognitiveLoad.cognitive_indexfloatNot stated by the peer or this modulePresent when the backend’s prediction model produced a value
timestamp (event envelope, not under predictions)integer, millisecondsEpoch not stated by the peerRequired - treated as 0 if absent

ready payload: payload.name (string, optional) - the device name, used as the published entity name when EntityName is not configured.

See Data produced for how these map onto WearableBioSensorComponent.

4.6 Timing

Event-driven; the module never polls the peer. With SendAtNativeRate enabled (default), each prediction event is published as its own SimulationFrame immediately. Disabled, HEAT Capture’s own per-tick poll publishes the most recently received prediction, once, then clears it - a tick with no new prediction since the last one publishes nothing.

4.7 Error behaviour

ConditionObservableModule behaviour
Malformed JSON on the WebSocketError logged, receive loop endsConnection is not actively closed by the module; the peer must reconnect
commandError for connect, retries remainingWarning logged, retry sent after backoffRetries as described in 4.4
commandError for connect, retries exhaustedWarning logged: “Connect retry limit reached”No further retries this connection
prediction with none of the four recognised pathsNothing loggedNo frame published for that event
Non-WebSocket HTTP requestHTTP 400Request closed
Listener fails to bind (for example, port already in use)Error logged, capture start failsModule reports it did not start

5. Data model reference

Output is HEAT ProtoLib SimulationFrame, from HEAT.ProtoLib.CSharp 0.37.0 as bundled with HEAT.Capture.ModuleSDK 2.0.5. This module populates only WearableBioSensorComponent, via a list of BiometricReading values. See HEAT ProtoLib’s message reference for the component’s fields.

The peer’s own JSON event schema is not a VRAI-published specification; per the module’s source comments, its connect/M0/S06 semantics come from the Mentalista vendor’s own SDK documentation, communicated directly to the module’s authors rather than published. This document names only the message and field subset this module actually reads.

6. Units, frames and conventions

ConceptConvention
Prediction valuesNo unit stated by the peer or this module - see Section 1
Time baseThe peer’s own timestamp field, used directly as the published capture time in milliseconds; its epoch is not stated by the peer
Coordinate frameNot applicable - this interface carries no spatial data

7. Configuration affecting the interface

SettingInterface effect
Host, PortListener address. Changing Port moves outside the firewall scope this module’s capability declares - see Section 9
ConnectOnStartup, TargetDevice, ConnectRetryCount, ConnectInitialDelayMs, ConnectRetryDelayMs, MaxConnectRetryDelayMsThe connect command exchange in 4.4
EntityId, EntityNameIdentity of the published entity
SendAtNativeRatePublish timing, 4.6

See Configure for the full settings reference.

8. Compatibility and versioning

Built against HEAT.Capture.ModuleSDK 2.0.5. The peer protocol carries no version field; this module does not detect or reject a peer speaking an incompatible or newer version of the Mentalista protocol - an unrecognised field is silently ignored, but a restructured payload (for example, a renamed predictions key) would stop producing readings with no error.

9. Security considerations

There is no authentication: any client that can reach Host:Port and complete a WebSocket upgrade is accepted and can send a prediction event that becomes captured data, or trigger the connect retry logic. There is no transport encryption (no TLS).

This module declares the network.listen capability for tcp/5555 specifically. HEAT Capture’s host-side firewall scoping is built from that declaration - changing Port in Configure without a matching firewall change moves the listener outside its granted scope. Treat the network between the HEAT Capture workstation and the peer as the security boundary; do not expose this listener beyond an isolated capture network.

New WebSocket upgrades are limited to an active capture session. Existing upgraded connections are not closed automatically when capture ends, so network isolation must remain in place until each peer disconnects.

10. Conformance

  1. Start a HEAT Capture session with this module enabled. Confirm the module’s debug view reports listenerActive: true.
  2. Connect a WebSocket client to ws://Host:Port/ (its configured Host and Port). Confirm the debug view reports socketConnected: true.
  3. With ConnectOnStartup enabled, confirm the client receives a connect command within ConnectInitialDelayMs of connecting, and that replying with commandSuccess for connect flips the debug view’s connection state to connected.
  4. Send a prediction event with all four recognised paths populated. Confirm a WearableBioSensorComponent with four readings appears in HEAT Capture’s captured data within one capture tick, and that the reading names match Section 4.5 exactly.
  5. Reply to a connect command with commandError naming connect. Confirm a retry is sent after approximately ConnectRetryDelayMs, and that retries stop after ConnectRetryCount attempts.

11. Revision history

RevDateProduct versionChange
12026-09-01v2.0.1Initial issue.
Opens your browser's print dialog. Choose "Save as PDF" as the destination.