MDS requests
Send requests and subscriptions to any resource of the Movesense API through MDS.
The Movesense mobile library (MDS) gives access to every resource of a Movesense sensor in a REST style. You send a GET, PUT, POST or DELETE request to a resource path, or subscribe to the resource for notifications. Use MDS requests for what the typed API of MovesenseDevice does not cover, such as the LED, the sensor's clock or other sample rates.
The Movesense API reference lists the resources with their methods, parameters and data. The samples on this page use a connected MovesenseDevice named device and a Movesense client named movesense.
Send a request
device.request() sends one request to a resource of the sensor and completes with an MdsResponse:
It takes these parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
method | MdsRequestMethod | Yes | — | The request method, such as MdsRequestMethod.get. |
resource | String | Yes | — | The resource path, such as /Info. It must start with a slash. |
contract | String | No | '{}' | The parameters of the request, as a JSON object. |
The contract is a JSON object with the parameters of the request, named as in the Movesense API reference. Leave it out when the request takes no parameters: it defaults to the empty object '{}'.
MdsRequestMethod has one value for each MDS method:
| Value | Use |
|---|---|
get | Read a resource. |
put | Write a value, which replaces the previous value. |
post | Send a new record to the sensor. |
delete | Remove data from the sensor. |
The response has these properties:
| Property | Type | Description |
|---|---|---|
body | String | The response body as a JSON string, or an empty string when the response has no body. |
statusCode | int | The HTTP-like status code from MDS, such as 200. |
The body of a GET response is a JSON object whose Content holds the value of the resource. Decode it with jsonDecode():
To read /Info as a typed MovesenseDeviceInfo, see Read the device information.
A PUT request takes the new value in its contract. This example turns on the LED of the sensor:
The Movesense API reference marks /Component/Led as deprecated and documents /Component/Leds/<led_index> instead, where the sensor's only LED has the index 0.
Subscribe to a resource
device.subscribe() subscribes to a resource of the sensor and returns a stream of the raw JSON notification bodies, as strings. This example streams the accelerometer at 52 Hz:
The stream is single-subscription. Listening to it opens the MDS subscription, and canceling your StreamSubscription closes it. Each call to subscribe() returns a new stream with its own MDS subscription, which stays open until you cancel it.
Each notification is a JSON object that holds the data in Body. Decode it with jsonDecode():
subscribe() also takes a named contract parameter for subscription parameters, which defaults to '{}'. Do not put the resource in the contract. On Android, the plugin adds the subscription URI to the contract as Uri itself, and on iOS, it passes the URI to MDS separately.
MovesenseHR, MovesenseECG, MovesenseIMU and MovesenseTemperature each have a fromMovesenseData() factory that parses a decoded notification. MovesenseState.fromMovesenseData() takes the MovesenseSystemState component first, then the decoded notification.
To parse ECG or inertial measurement unit (IMU) notifications into typed objects, see Use other sample rates.
Use the client without a device
The Movesense client sends requests and subscriptions without a MovesenseDevice. Its request() and subscribe() take a full URI that names the sensor by its serial number, not a resource path. Build the URIs with the static methods of Mds:
| Method | URI | Built with | Example |
|---|---|---|---|
movesense.request() | suunto://<serial><resource> | Mds.createRequestUri(serial, resource) | suunto://233830000816/Info |
movesense.subscribe() | <serial><resource> | Mds.createSubscriptionUri(serial, resource) | 233830000816/Meas/HR |
MovesenseDevice builds the same URIs from its own serial number. This example sends a GET request and subscribes to the heart rate through the client:
To get typed data from the client, decode each notification and pass it to a fromMovesenseData() factory:
A MovesenseDevice holds the serial number in serial while it is connected. Without a device, take the serial number from the connected event on movesense.connectionEvents:
This sample waits for the next sensor that connects. With several sensors, also compare event.address, and add a timeout in case the connection fails. For connection events, see Follow all connections.
For code written for mdsflutter, see Migrate from mdsflutter.
Handle errors
Requests and subscriptions report failures in these ways:
| Failure | Result |
|---|---|
device.request() while the sensor is not connected | The Future fails with a StateError. |
A MovesenseDevice stream created while the sensor is not connected | The stream emits a StateError and closes. |
| MDS rejects a request | The Future fails with an MdsError that holds the status code from MDS. |
| MDS rejects a subscription | The stream emits an MdsError that holds the status code from MDS, then nothing more. It does not close, so cancel your StreamSubscription. |
| MDS reports an error on a running subscription (Android only) | The stream emits an MdsError that holds the status code from MDS and goes on with the next notification. |
| The request or subscription fails on the phone | An MdsError with status 0, from the Future or on the stream. |
| A notification on a typed stream is not valid JSON or not a JSON object | The stream emits a FormatException and goes on with the next notification. |
| A notification on a typed stream is empty | The stream emits a reading with zero values and empty lists. |
MdsError holds the status code in status and a readable reason in error. Status 0 means that MDS gave no status code. Failures on the phone have this status, for example:
- The contract is not a JSON object. On Android, only subscriptions check the contract; requests pass it to MDS unchanged.
- The app runs on macOS, where MDS is not available.
The sensor may not keep up when it streams several high-rate resources at once, such as heart rate, ECG and IMU data. A subscription may then fail with status 408. If this happens, subscribe to fewer resources at once.
To avoid the StateError, check device.isConnected before you send a request. Catch MdsError around the request:
On a stream, handle errors in onError. With cancelOnError: true, the first error cancels the subscription, which also closes the MDS subscription: