Remote management protocol

The remote management server implements a two-way protocol between devices and Edge Impulse, which allows users to control devices (for example to acquire new data) straight from the studio. Devices can either connect directly to the remote management service over a websocket (see the protocol on this page), or can connect through a proxy like the serial daemon using the serial protocol. The remote management protocol is not used for data ingestion, use the ingestion service for this. Devices authenticate to the remote management service with an API key.

Data from and to the remote management API can be encoded in either CBOR of JSON.

A comprehensive test suite for devices implementing this protocol is located here: edgeimpulse/integration-tests-firmware.

Connecting and authenticating

To connect, open a websocket connection to either:

wss://remote-mgmt.edgeimpulse.com

or:

ws://remote-mgmt.edgeimpulse.com

Hello request

Then send the following message (encoded in CBOR or JSON):

{
    "hello": {
        "version": 3,
        "apiKey": "ei_8dd502530a5232ff64374815fddc229151e0a82c1d4f23e86097d8acdf882295",
        "deviceId": "15:FE:90:11:1D:18",
        "deviceType": "PORTENTA_H7_M7",
        "connection": "daemon",
        "sensors": [{
            "name": "Camera (320x240)",
            "frequencies": [],
            "maxSampleLengthS": 60000
        }, {
            "name": "Camera (128x96)",
            "frequencies": [],
            "maxSampleLengthS": 60000
        }],
        "supportsSnapshotStreaming": true
    }
}

Fields:

  • hello - message type.
    • version - API version, always 3 (required).
    • apiKey - API key (required).
    • deviceId - unique identifier for this device. Set this when the device has a globally unique identifier (e.g. MAC address). Only a single device with this ID can connect at any given point (required).
    • deviceType - device type, for example the exact model of the device. Should be the same for all similar devices (required).
    • connection - how the device is connected, either ip (direct connection) or daemon (via the serial daemon) (required).
    • sensors - list of sensors that the device supports. The object has three properties: 1) name, human readable name, 2) maxSampleLengthS, which defines the maximum time a device can sample from this sensor (as flash may run out), 3) list of frequencies the sensor supports. Users can only select a single sensor to sample from, so for sensor fusion create synthesized sensors that combine multiple physical sensors (e.g. 'Accelerometor + gyro' in this list). For cameras, set the name of the sensor to Camera (WIDTHxHEIGHT), and the frequencies to an empty array (multiple allowed for multiple resolutions). (required).
    • supportsSnapshotStreaming - set to true if the device supports snapshot streaming (required).

Hello response

The service responds with a message in the form of (in the same format as the request):

{
    "hello": true,
    "err": undefined
}

If the request failed the hello field is set to false, and the err message is set to a string.

Sample request

When a user requests sampling through the studio, the following message is sent to the device (in CBOR or JSON depending on the hello request):

{
    "sample": {
        "label": "wave",
        "length": 10000,
        "path": "/api/training/data",
        "hmacKey": "e561ff...",
        "interval": 10,
        "sensor": "Built-in accelerometer"
    }
}

Fields:

  • sample - message type.
    • label - Label for this data. Use this to populate the x-file-name header when posting data to the ingestion service.
    • length - Sampling length in milliseconds.
    • path - Path of the URL where to post the data.
    • hmacKey - Key to sign the data with, the device does not have to adhere to this request.
    • interval - Interval between samples. This can also be a float. Devices do not have to adhere to this field, e.g. if the sensor does not support this frequency, or if the value is non-sensical.
    • sensor - Name of the sensor to sample from. This field is only populated if the sensors field in the hello request was populated.

Sampling request received

When the sample request is received, respond with:

{
    "sample": true
}

Sampling failed

If sampling cannot start, or when an error occurs during sampling, send:

{
    "sample": false,
    "error": "Reason why sampling failed"
}

This may also be sent after 'Sampling request received' was already sent.

Progress event: sampling started

Indicates that the device started sampling. Send the following message right when sampling starts:

{
    "sampleStarted": true
}

Progress event: processing

If the device is done sampling, but is processing the sample before uploading, such as a device preprocessing audio or signing the file. Send the following message to indicate that the device is processing:

{
    "sampleProcessing": true
}

Progress event: reading from device

If the device is not connected directly to the internet, the daemon needs to pull the data from the device over serial, which could be slow for large files. Send the following message to indicate that this process started, and how far the process is along:

{
    "sampleReading": true,
    "progressPercentage": 33
}

You can send this message multiple times, and the percentage will be updated in the Studio.

Progress event: started uploading

Before you start the upload, send:

{
    "sampleUploading": true
}

Sampling finished

After sampling is completed and the file is uploaded, send:

{
    "sampleFinished": true
}

These messages are used to update the UI in the studio.

Snapshot streaming

Snapshot streaming provides the user with a preview of a connected camera in the Studio.

Start streaming request

When the user chooses a camera in the studio, the following message is sent to the device (in CBOR or JSON depending on the hello request):

{
    "startSnapshot": true
}

Stop streaming request

When snapshot streaming should stop, the following message is sent to the device (in CBOR or JSON depending on the hello request):

{
    "stopSnapshot": true
}

Sending snapshots

To send a snapshot, send the following message from device. Here snapshotFrame is a base64 encoded JPG file:

{
    "snapshotFrame": "/9j/4AAQSkZJRgABAQAASABIAAD/4QjcRX..."
}

You don't have to send this message too often, 5 times a second is plenty for most usecases.

Version history

This lists changes in the remote management protocol.

  • v2 - Changed the type of sensors from a string to a complex type describing frequencies and maximum sample length.
    • For devices still registering with version 1 a default max. sample length of 60 seconds will be set, and a default frequency of 100Hz.
    • If a v1 device registers with sensor name "Built-in accelerometer" the default sample length will be 300 seconds, and the frequencies will be 62.5Hz and 100Hz.
    • If a v1 device registers with sensor name "Built-in microphone" a default frequency of 16KHz will be set.
  • v3 - Add progress percentages for sampleReading and commands for snapshot streaming. For v2 devices the progress percentage is ignored, and supportsSnapshotStreaming is set to false.