Remote management Protocol (WebSocket)

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, as a result, you will need to use the ingestion service for this. Devices authenticate to the remote management service with an API key.

Remote Management is a part of the Remote Ingestion system. The general architecture is shown below, while this documentation covers only the part marked with red color.

Remote Ingestion Architecture

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

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

Connecting

To connect, open a websocket connection to either:

wss://remote-mgmt.edgeimpulse.com

or:

ws://remote-mgmt.edgeimpulse.com

Remote management service uses standard ports: 80 or 443.

Typical flow

The diagram below shows a typical full session of the remote ingestion process that involves both remote management and ingestion services.

Typical flow

Protocol

After opening the WebSocket connection, the device initiates the communication by sending the Hello message. Messages can be encoded as JSON or CBOR. The format of the Hello message sent by the device determines the encoding of the messages for the rest of the session.

Hello (request)

This is always the first message in the session. Only the device can send this message. The server will respond with the Hello response.

Sender:   device
Type:     request
Response: Hello
{
    "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
        }, {
            "name": "Accelerometer",
            "frequencies": [ 100, 62.5 ],
            "maxSampleLengthS": 600
        } , {
            "name": "Microphone",
            "frequencies": [ 16000 ],
            "maxSampleLengthS": 120
        }],
        "supportsSnapshotStreaming": true
    }
}

Hello (response)

This is the response to the Hello request sent by the device. Only the server can send this message.

Sender:   server
Type:     response
Response: none
{
    "hello": true,
    "err": undefined
}

Sample (request)

When a user requests sampling through the Studio, the following message is sent to the device. The device needs to perform a handshake with the hello message first. This message can be sent by the server only.

Sender:   server
Type:     request
Response: Sample
{
    "sample": {
        "label": "wave",
        "length": 10000,
        "path": "/api/training/data",
        "hmacKey": "15bc5650a2338e083fb74edf6faf6547",
        "interval": 10,
        "sensor": "Accelerometer"
    }
}

Sample (response)

This is the response to the Sample request sent by the Studio. The device needs to send this response. Set the sample field to true if the sampling can start, or to false if the sampling cannot start. This can be sent multiple times, for example first send true to confirm that the device is ready to sample, and then send false if some error occurs.

Sender:   device
Type:     response
Response: none
{
    "sample": true
}

Sample started (notification)

When the sampling starts, send the following message to the Studio. This is a notification, so no response is expected from Studio. This notification is required otherwise, the Studio will report an error to the user.

Sender:   device
Type:     notification
Response: none
{
    "sampleStarted": true
}

Sample processing (notification)

If the device is done sampling but is still 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. This notification is optional.

Sender:   device
Type:     notification
Response: none
{
    "sampleProcessing": true
}

Sample reading (notification)

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. You can send this message multiple times, and the percentage will be updated in the Studio. This message is optional.

Sender:   device / daemon app
Type:     notification
Response: none
{
    "sampleReading": true,
    "progressPercentage": 33
}

Sample uploading (notification)

Send this message before sending samples to the ingestion service. This message is used to update the UI in the Studio. This message is required.

Sender:   device
Type:     notification
Response: none
{
    "sampleUploading": true
}

Sample finished (notification)

Send this notification after sampling is completed and the file is uploaded. This notification is required.

Sender:   device
Type:     notification
Response: none
{
    "sampleFinished": true
}

Start snapshot (request)

If the user selects the camera as a sensor on the ingestion page, the following request is sent to the device to start streaming snapshots. This request is optional, and the device does not have to send the response.

Sender:   server
Type:     request
Response: none
{
    "startSnapshot": true
}

Stop snapshot (request)

When snapshot streaming should stop, the following message is sent to the device. This request is optional, and the device does not have to send the response.

Sender:   server
Type:     request
Response: none
{
    "stopSnapshot": true
}

Snapshot frame (notification)

To send a snapshot from the device, send the following message. The snapshotFrame is a base64 encoded JPG file. You don't have to send this message too often, 5 times a second is plenty for most use cases.

Sender:   device
Type:     notification
Response: none
{
    "snapshotFrame": "/9j/4AAQSkZJRgABAQAASABIAAD/4QjcRX..."
}

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 the 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 the 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.

Last updated