Introduction
Pelion Device Management SDKs are Open Source libraries which provide a convenient way to develop applications that communicate with Pelion Device Management REST APIs.
The SDKs expose Pelion Device Management functionality, without needing to directly access the REST interface, using conventions and paradigms that should be familiar to a developer familiar with the supported languages. In some areas the SDKs also provide an additional degree of abstraction, which should make more complex tasks easier to implement in application code.
- The SDKs are currently available in four languages.
- The SDKs are released publicly via standard package managers for each of the languages.
- The source code is available on GitHub.
- Reference SDK documentation is available to supplement this SDK user guide.
Language | GitHub Repository | Packages | Reference Documentation |
---|---|---|---|
Python | mbed-cloud-sdk-python | PyPI | Python |
Java | mbed-cloud-sdk-java | Maven Central / JCenter | Java |
JavaScript / TypeScript | mbed-cloud-sdk-javascript | npm | JavaScript / Typescript |
C# / .NET | mbed-cloud-sdk-dotnet | NuGet | C# / .Net |
Context
This diagram shows the context of the SDKs fits in the larger picture of Pelion Device Management and application development.
Contribution
Arm has a dedicated team to maintain and extend the SDKs. They are under active development to keep up to date with the latest improvements and features of the Pelion Device Management platform.
Contributions in the form of GitHub Pull Requests to any of the public repositories are very welcome. Alternatively, developers can report feature requests and bugs to the Arm team via GitHub issues.
Getting started
The aim of this section is to get a small script using a Pelion Device Management SDK communicating with the Pelion Device Management platform.
Prerequisites
- Follow the tutorial Connect to Pelion Device Management to connect your Mbed OS IoT device to Pelion Device Management.
- Follow the guide Access Device Management with API keys and create an API Key to use with the SDKs using the Pelion Device Management Portal.
- Setup a development environment suitable for the chosen language.
Installation
// example: initial setup
dotnet add package Mbed.Cloud.SDK
// example: initial setup
npm i mbed-cloud-sdk
# example: initial setup
pip install mbed-cloud-sdk
// example: Initial setup
/*
If using Gradle, you can initialise your project, as follows:
*/
> gradle init --type java-application
/*
Then, add the following dependency to 'build.gradle' file (change 'x', 'y' and 'z' by the appropriate version numbers) :
*/
implementation 'com.arm.mbed.cloud.sdk:mbed-cloud-sdk:x.y.z'
/*
Next time you build your project, the dependencies will be fetched and stored in your package manager cache.
You are then ready to start working with the SDK.
*/
Install the SDK using the package manager.
Configuration
# Example .env file
# Note that the following API key is fake
MBED_CLOUD_SDK_API_KEY=ak_A644VERY4745LONG64RANDOM3254STRINGW555455ITHA564miXTurOFlowercaseANDUPPERCASELETTERSIintersperseDwithNUMBER5
The SDKs use an API key to access the Pelion Device Management REST API, details on how to create an API Key are available in the Prerequisites section.
The recommended method of configuring the SDK during development is by using a .env
file. The file can be located in
any accessible directory between your project and the root directory. Note that .env
files closer to the working
directory (or any variables in the system environment) take priority.
To get started it is only necessary to define the API Key, but the following table describes the full list of configuration options that can be defined:
Environment Variable | Type | Default | Usage |
---|---|---|---|
MBED_CLOUD_SDK_API_KEY |
String | N/A | API Key used for Authentication. |
MBED_CLOUD_SDK_HOST |
URI | Arm's public API | The host on which the Pelion Device Management API is available. This is only likely to be needed if you organisation has its own cloud deployment. |
For other configuration methods please see the following sections:
- Production Deployments when ready to deploy to production.
- Working with Multiple API Keys if it is necessary to work with multiple API Keys.
Hello World
// example: hello world
using System;
using System.Threading.Tasks;
using Mbed.Cloud.Foundation;
public class HelloWorldExamples
{
public static void Main()
{
var options = new DeviceListOptions
{
MaxResults = 10 // Limit to ten devices
};
// List the first ten devices on your Pelion Device Management account.
foreach (var device in new DeviceRepository().List(options))
{
Console.WriteLine($"Hello device {device.Name}");
}
}
}
// example: hello_world
import { DeviceRepository } from "mbed-cloud-sdk";
const main = async () => {
// create an instance of a device repository
const deviceList = new DeviceRepository()
// List the first 10 devices in your Pelion DM account
.list({ maxResults: 10 });
for await (const device of deviceList) {
console.log(`Hello device ${device.name}`);
}
};
main();
# example: hello world
from mbed_cloud.foundation import Device
# List the first 10 devices on your Pelion Device Management account.
for device in Device().list(max_results=10):
print("Hello device %s" % device.name)
// example: hello world
import java.io.IOException;
import com.arm.mbed.cloud.sdk.common.MbedCloudException;
import com.arm.mbed.cloud.sdk.devices.model.DeviceListDao;
import com.arm.mbed.cloud.sdk.devices.model.DeviceListOptions;
public class HelloWorld {
public static void main(String[] args) {
try (DeviceListDao dao = new DeviceListDao()) {
// Listing the first 10 devices on your Pelion Device Management account
dao.list((new DeviceListOptions()).maxResults(10))
.forEach(device -> System.out.println("Hello device " + device.getName()));
} catch (MbedCloudException | IOException exception) {
exception.printStackTrace();
}
}
}
This simple interaction between the SDK and Pelion Device Management shows that everything is set up and working.
Next Steps
The SDKs have several ways to interface with Pelion Device Management and connected devices. The section Interface Overview provides details on how these are organised fit together. However, these resources should help with getting started:
- See Foundation Interface for a guide to working with resources such as accounts or users.
- See Appendix: Foundation Entities for a list of all the entities and methods in the Foundation Interface.
- See Appendix: API to SDK Reference if you're familiar with the REST API and need to find out how to do the equivalent in the SDK.
Interface Overview
There are three conceptual interfaces to each SDK, each gives an increasing level of abstraction over the underlying REST API.
- Client - this offers direct access to the REST API endpoints.
- Foundation - this maps REST resources and HTTP methods onto object orientated Entities and associated method calls.
- Primary - this provides a use case orientated interface and uses concepts such as asynchonous processing to simplify application development.
There is also a Legacy interface which combines some of the functionality of the Foundation and Primary interfaces. This interface can be difficult to understand, so it is recommended that the new interfaces are used wherever possible.
Primary
The Primary interface offers the highest level of abstraction but only covers certain aspects of the API. This is focused around the asynchronous device data e.g. subscriptions and resource interactions.
Foundation
The Foundation interface is designed to be simple to understand and use. It is organised around the concept of an Entity, but these are arranged into large conceptual groups known as Categories. The Categories do not have any impact on how the entities are used but merely serve as an organisation structure.
- Categories are a semantic grouping of functionality (e.g. Accounts, Devices, Security), which includes multiple Entities.
- Entities are a representation of a resource in Pelion (e.g. User, Device), which has one or more methods.
- Methods are actions that can be applied to an Entities (e.g. list, update, delete). They may correspond to one or several underlying calls to Pelion Device Management REST API.
Client
The Client interface is the lowest level and offers direct access to the REST API. It's only recommended for new, complex or highly specific features of the API, when the Primary or Foundation interfaces are not suitable. However, it does provide an easy way to access any Pelion Device Management API endpoint without having to setup the authentication manually.
Legacy
The Legacy interface is arranged around the organisation of Pelion services and it may not be easy to navigate. This interface is in maintenance mode and new REST API endpoints and resource properties will not normally be added to this interface. To each Pelion service, there is a corresponding Module in the SDK:
- Device Directory API: Stores device information and allows device management.
- Update API: Manages device firmware updates.
- Account Management API: Manages accounts and users, creates API keys.
- Connect API: Allows applications to communicate with devices.
- Bootstrap API: Allows applications to control the device bootstrapping process.
- Enrollment API: Allows users to claim the ownership of a device which is not yet assigned to an account.
- Certificates API: Allows users to manage certificates e.g. define a third party bootstrap certificate provider.
- Billing API: Allows users to retrieve billing reports and service package details.
SDK Interface
An SDK Instance is the recommended way for using the SDK. It provides a few useful tools that will help as the application becomes more complex:
- Access to the Foundation and Client interfaces in one place.
- A reusable configuration that contains authentication information, which makes it easy to work with multiple API Keys.
- Management of internal resources dealing with concurrency and connections can be shared and reused.
Getting Started Revisited
// example: hello world with sdk instance
using System;
using System.Threading.Tasks;
using Mbed.Cloud;
using Mbed.Cloud.Foundation;
public class HelloWorldSeparateSdkExamples
{
public static void Main()
{
// Create an instance of the Pelion Device Management SDK
var sdk = new SDK();
var options = new DeviceListOptions
{
MaxResults = 10 // Limit to ten devices
};
// List the first ten devices on your Pelion Device Management account
foreach (var device in sdk.Foundation().DeviceRepository().List(options))
{
Console.WriteLine($"Hello device {device.Name}");
}
}
}
// example: hello_world_with_sdk_instance
import { SDK } from "mbed-cloud-sdk";
const main = async () => {
// create an instance of the Pelion Device Management SDK
const deviceList = new SDK()
.foundation()
.deviceRepository()
// List the first 10 devices in your Pelion DM account
.list({ maxResults: 10 });
for await (const device of deviceList) {
console.log(`Hello device ${device.name}`);
}
};
main();
# example: hello world with sdk instance
from mbed_cloud import SDK
# Create an instance of the Pelion Device Management SDK
pelion_dm_sdk = SDK()
# List the first 10 devices on your Pelion DM account
for device in pelion_dm_sdk.foundation.device().list(max_results=10):
print("Hello device %s" % device.name)
// example: hello world with sdk instance
import com.arm.mbed.cloud.Sdk;
import com.arm.mbed.cloud.sdk.common.ConnectionOptions;
import com.arm.mbed.cloud.sdk.common.MbedCloudException;
import com.arm.mbed.cloud.sdk.devices.model.DeviceListOptions;
public class HelloWorldWithSdkInstance {
public static void main(String[] args) {
// Create an instance of the Pelion Device Management SDK
try (Sdk sdk = Sdk.createSdk(ConnectionOptions.newConfiguration())) {
// Listing the first 10 devices on your Pelion Device Management account
sdk.foundation().getDeviceListDao().list((new DeviceListOptions()).maxResults(10))
.forEach(device -> System.out.println("Hello device " + device.getName()));
} catch (MbedCloudException exception) {
exception.printStackTrace();
}
}
}
This example has the same functionality as the original Hello World example, which accessed a Foundation entity. However, it uses an SDK instance, which is the preferred pattern for more complex applications.
Working with Multiple API Keys
// example: hello world with multiple api keys
using System;
using System.Threading.Tasks;
using Mbed.Cloud;
using Mbed.Cloud.Common;
using Mbed.Cloud.Foundation;
public class MultipleApiKeys
{
public static void Main()
{
// Create instances of the Pelion Device Management SDK for two accounts
var account_one = new SDK(API_KEY_ONE);
var account_two = new SDK(API_KEY_TWO);
var options = new DeviceListOptions
{
MaxResults = 10 // Limit to ten devices
};
// List the first ten devices on the first account
foreach (var device in account_one.Foundation().DeviceRepository().List(options))
{
Console.WriteLine("Account One device " + device.Name);
}
// List the first ten devices on the second account
foreach (var device in account_two.Foundation().DeviceRepository().List(options))
{
Console.WriteLine("Account Two device " + device.Name);
}
}
}
// example: hello_world_with_multiple_api_keys
import { SDK } from "mbed-cloud-sdk";
const main = async () => {
const accountOne = new SDK({ apiKey: process.env.account_one_api_key });
const deviceList = accountOne
.foundation()
.deviceRepository()
.list();
for await (const device of deviceList) {
console.log(`account one device ${device.name}`);
}
const accountTwo = new SDK({ apiKey: process.env.account_two_api_key });
accountTwo
.foundation()
.deviceRepository()
.list();
for await (const device of deviceList) {
console.log(`account two device ${device.name}`);
}
};
main();
# example: hello world with multiple api keys
from mbed_cloud import SDK
# Create instances of the Pelion Device Management SDK for two accounts
account_one = SDK(api_key=ACCOUNT_ONE_API_KEY)
account_two = SDK(api_key=ACCOUNT_TWO_API_KEY)
# List the first 10 devices on the first account
for device in account_one.foundation.device().list(max_results=10):
print("Account One device %s" % device.name)
# List the first 10 devices on the second account
for device in account_two.foundation.device().list(max_results=10):
print("Account Two device %s" % device.name)
// example: hello world with multiple API keys
import com.arm.mbed.cloud.Sdk;
import com.arm.mbed.cloud.sdk.common.ConnectionOptions;
import com.arm.mbed.cloud.sdk.common.MbedCloudException;
import com.arm.mbed.cloud.sdk.devices.model.DeviceListOptions;
public class HelloWorldWithMultipleSdkInstances {
public static void main(String[] args) {
// Create instances of the Pelion Device Management SDK for two accounts
try (Sdk accountOne = Sdk.createSdk(ConnectionOptions.newConfiguration(ACCOUNT_ONE_API_KEY));
Sdk accountTwo = Sdk.createSdk(ConnectionOptions.newConfiguration(ACCOUNT_TWO_API_KEY))) {
// Listing the first 10 devices on the first account
accountOne.foundation().getDeviceListDao().list((new DeviceListOptions()).maxResults(10))
.forEach(device -> System.out.println("Hello device " + device.getName()));
// Listing the first 10 devices on the second account
accountTwo.foundation().getDeviceListDao().list((new DeviceListOptions()).maxResults(10))
.forEach(device -> System.out.println("Hello device " + device.getName()));
} catch (MbedCloudException exception) {
exception.printStackTrace();
}
}
}
When working with a single API Key it is recommended that the SDK configuration is defined globally using environment
variables (or during development via a .env
file) as described in the Configuration section.
However, it is possible to work with multiple API Keys simultaneously by using different SDK instances, where each SDK instance is provided with the configuration at runtime. It is still recommended that the configuration is stored in environment variables (as shown in the examples), rather than being included directly in the source code.
Foundation Interface
This guide provides some examples of how to work with entities for common operations. However, each entity will have different methods and properties depending on the underlying REST API endpoints and resource contents. This will be visible in the associated language reference documentation. The following sections should be of help in discovering available functionality and uses cases:
- Appendix: Foundation Entities - summary of the entities and methods.
- Use Cases - summary of the entities and methods.
Creating an Entity
// example: create an entity
var newUser = new User
{
Email = "csharp.sdk.user@arm.com"
};
await sdk
.Foundation()
.UserRepository()
.Create(newUser);
// example: create_an_entity
const newUser: User = {
email: "javascript.sdk.user@arm.com",
};
await sdk.foundation().userRepository().create(newUser);
# example: create an entity
new_user = pelion_dm_sdk.foundation.user(
email="python.sdk.user@arm.com",
)
new_user.create()
// example: create an entity
User newUser = new User();
newUser.setEmail("java.sdk.user@arm.com");
sdk.foundation().getUserDao().create(newUser);
The SDK allows resources to be created in Pelion Device Management, to do this the create method of the Entity should be called.
Reading an Entity
// example: read an entity
var userOne = await sdk
.Foundation()
.UserRepository()
.Read(userId);
Console.WriteLine($"User email address: {userOne.Email}");
// example: read_an_entity
const userOne = await sdk.foundation().userRepository().read(newUser.id);
console.log(`User email address: ${userOne.email}`);
# example: read an entity
user_one = pelion_dm_sdk.foundation.user(id=user_id).read()
print("User email address: %s" % user_one.email)
// example: read an entity
User userOne = sdk.foundation().getUserDao().read(userId);
System.out.println("User email address: " + userOne.getEmail());
The SDK allows individual resources to be read from Pelion Device Management, to do this the read method of the Entity should be called.
Updating an Entity
// example: update an entity
var userTwo = await sdk
.Foundation()
.UserRepository()
.Read(userId);
userTwo.FullName = "CSharp SDK User";
await sdk
.Foundation()
.UserRepository()
.Update(userTwo.Id, userTwo);
// example: update_an_entity
const userTwo = await sdk.foundation().userRepository().read(newUser.id);
userTwo.fullName = "Javascript SDK User";
await sdk.foundation().userRepository().update(userTwo, userTwo.id);
# example: update an entity
user_two = pelion_dm_sdk.foundation.user(id=user_id).read()
user_two.full_name = "Python SDK User"
user_two.update()
// example: update an entity
User userTwo = sdk.foundation().getUserDao().read(userId);
userTwo.setFullName("Java SDK User");
sdk.foundation().getUserDao().update(userTwo);
The SDK allows individual resources to be updated in Pelion Device Management, to do this the update method of the Entity should be called.
Deleting an Entity
// example: delete an entity
var userThree = await sdk
.Foundation()
.UserRepository()
.Read(userId);
await sdk
.Foundation()
.UserRepository()
.Delete(userThree.Id);
// example: delete_an_entity
const userThree = await sdk.foundation().userRepository().read(newUser.id);
await sdk.foundation().userRepository().delete(userThree.id);
# example: delete an entity
pelion_dm_sdk.foundation.user(id=user_id).delete()
// example: delete an entity
User userThree = sdk.foundation().getUserDao().read(userId);
sdk.foundation().getUserDao().delete(userThree);
The SDK allows individual resources to be deleted from Pelion Device Management, to do this the delete method of the Entity should be called.
Iterating over Entities
// example: list entities
var options = new UserListOptions
{
Order = "ASC",
PageSize = 5,
MaxResults = 10,
Include = "total_count"
};
var userList = sdk
.Foundation()
.UserRepository()
.List(options);
foreach (var user in userList)
{
Console.WriteLine($"{user.FullName}: ({user.Id}): {user.Email}");
}
// example: list_entities
const paginator = sdk
.foundation()
.userRepository()
.list({
maxResults: 10,
pageSize: 5,
order: "ASC",
include: "total_count",
});
for await (const user of paginator) {
console.log(`${user.fullName} (${user.id}): ${user.email}`);
}
console.log(`Total count: ${paginator.totalCount}`);
# example: list entities
paginator = pelion_dm_sdk.foundation.user().list(
order="ASC",
page_size=5,
max_results=10,
include="total_count")
for user in paginator:
print("%s (%s): %s" % (user.full_name, user.id, user.email))
print("Total Count: %d" % paginator.count())
// example: list entities
Paginator<User> paginator = sdk.foundation().getUserListDao()
.list(new UserListOptions().maxResults(10).pageSize(5).order(Order.ASC)
.includeTotalCount());
paginator.forEach(u -> System.out.println(user.getFullName() + " (" + user.getId() + "): " + u.getEmail()));
System.out.println("Total count: " + paginator.count());
Each SDK provides an iterator for list endpoints in the REST API. This avoids the need to store all the entities and instead retrieves them a page at a time from the REST API. This behaviour is transparent to the user of the SDK but can be controlled with the following parameters:
- order - the order of the records based on creation time.
- max results - the maximum number of results (regardless of page size) to retrieve from the REST API.
- page size - the number of results to return in a page (changing this may have a performance impact).
- include - additional data to be returned in the response.
Paginator
// example: read first entity in list
var firstUserInList = sdk
.Foundation()
.UserRepository()
.List()
.FirstOrDefault();
Console.WriteLine($"User email address: {firstUserInList.Email}");
// example: read_first_entity_in_list
const firstUserInList = await sdk
.foundation()
.userRepository()
.list()
.first();
console.log(`User email address: ${firstUserInList.email}`);
# example: read first entity in list
first_user_in_list = pelion_dm_sdk.foundation.user().list().first()
print("User email address: %s" % first_user_in_list.email)
// example: read first entity in list
User firstUserInList = sdk.foundation().getUserListDao().list().first();
System.out.println("User email address: " + firstUserInList.getEmail());
The iteration mechanism is referred to as a Paginator (due to its paging behaviour). In addition to providing the iterator interface, Paginators also have additional utility methods. These vary between languages, please consult the appropriate language reference documentation for full details:
- first() - return the first entity in the list.
- next() - return the next entity in the sequence.
- all() - return all the entities in the list.
Filtering Entities
// example: list entities with filters
var userOptions = new UserListOptions()
.EmailEqualTo("mr.test@mydomain.com")
.StatusIn(UserStatus.ACTIVE, UserStatus.ENROLLING);
userList = sdk
.Foundation()
.UserRepository()
.List(userOptions);
foreach (var user in userList)
{
Console.WriteLine($"{user.FullName}: ({user.Id}): {user.Email}");
}
// example: list_entities_with_filters
const paginator = sdk
.foundation()
.userRepository()
.list({
filter: {
email: "javascript.sdk.user@arm.com",
status: {
in: [
"ACTIVE",
"ENROLLING",
]
}
},
});
for await (const user of paginator) {
console.log(`${user.fullName} (${user.id}): ${user.email}`);
}
console.log(`Total count: ${paginator.totalCount}`);
# example: list entities with filters
from mbed_cloud import ApiFilter
from mbed_cloud.foundation.enums import UserStatusEnum
api_filter = ApiFilter()
api_filter.add_filter("email", "eq", "python.sdk.user@arm.com")
api_filter.add_filter("status", "in", [UserStatusEnum.ACTIVE, UserStatusEnum.ENROLLING])
for user in pelion_dm_sdk.foundation.user().list(filter=api_filter):
print("%s (%s): %s" % (user.full_name, user.id, user.email))
// example: list entities with filters
sdk.foundation().getUserListDao()
.list(new UserListOptions().equalToEmail("java.sdk.user@arm.com")
.inStatuses(Arrays.asList(UserStatus.ACTIVE, UserStatus.ENROLLING)))
.forEach(u -> System.out.println(user.getFullName() + " (" + user.getId() + "): " + u.getEmail()));
Most endpoints which list resources in the Pelion Device Management REST API also provide a filter mechanism to reduce the number of resources returned and find resources of interest. The available filters for each list endpoint will either documented in the language reference documentation or programmatically described in the SDK itself.
Filters can be combined (using an implicit AND) to restrict which resources are returned, as is shown in the examples.
Client Interface
// example: custom api call
var client = new Client(new Config());
var res = await client.CallApi<ResponsePage<User>>(method: HttpMethods.GET, path: "/v3/users", queryParams: new Dictionary<string, object> { { "limit", 2 } });
// example: custom api call
const sdk = new SDK();
const users = await sdk.client.CallApi({ url: "/v3/users", method: "GET", query: { limit: 2 } });
# example: custom api call
from mbed_cloud import SDK
from mbed_cloud.foundation import User
response = SDK().client.call_api('get', '/v3/users', query_params={'limit': 2})
# response object from the`requests` library
for user_data in response.json()['data']:
user = User().from_api(**user_data)
// example: custom api call
/**
* Definition of the REST endpoint.
* <p>
* See the documentation from <a href="https://square.github.io/retrofit/">Retrofit</a> to see how to defined a
* service.
*/
private interface PelionApi {
@GET("v3/users")
Call<UserListResponse> listAllUsers(@retrofit2.http.Query("limit") Integer limit);
}
/**
* Definition of the response object.
*/
private static class UserListResponse {
List<User> data;
public List<User> getData() {
return data;
}
@SuppressWarnings("unused")
public void setData(List<User> data) {
this.data = data;
}
}
// Create a generic client
GenericClient client = GenericClient.newClient(Configuration.get());
// Define how to generate the request based on a set of parameters
CloudRequest<UserListResponse, PelionApi> requestDefinition = new CloudRequest<UserListResponse, PelionApi>() {
@Override
public com.arm.mbed.cloud.sdk.common.CloudRequest.CloudCall<UserListResponse>
defineCall(PelionApi service, Object... parameters) throws MbedCloudException {
return new CloudCall<GenericClientExamples.UserListResponse>() {
@Override
public Call<UserListResponse> call() {
return service.listAllUsers((Integer) parameters[0]);
}
};
}
};
// Make the call with the following set of parameters. here, limit = 2.
UserListResponse response = client.callApi(requestDefinition, Integer.valueOf(2));
for (User user : response.getData()) {
// Do something with users
System.out.println(user);
}
New or highly specific features of the API may be best served using direct API calls. To allow development to continue within the SDK and provide a consistent interface, we present these custom API call methods.
Of course, do let us know if there is an aspect of the API you would like us to cover!
Legacy Interface
In order to perform an action using the Legacy Interface, the API within which the functionality resides needs to be identified.
Each API is represented by a module in the SDK, the methods in the module normally correspond to direct calls to the REST API. The Legacy Interface uses a common model object which combines the request and response objects (as they are defined in the REST API) into a single object.
Reading a Resource
// example: legacy_get_resource
using Mbed.Cloud.Common;
using MbedCloudSDK.Billing.Api;
var billingApi = new BillingApi(new Config());
Console.WriteLine($"Quota remaining: {billingApi.GetQuotaRemaining()}");
// example: legacy_get_resource
import { BillingApi } from "mbed-cloud-sdk";
const billingApi = new BillingApi();
console.log(`Quota remaining: ${await billingApi.getQuotaRemaining()}`);
# example: legacy get resource
from mbed_cloud import BillingAPI
billing_api = BillingAPI()
print("Quota remaining: %s" % billing_api.get_quota_remaining())
// example: legacy get resource
try (Billing billingApi = new Billing(Configuration.get())) {
log("Quota remaining: " + billingApi.getQuotaRemaining());
} catch (MbedCloudException exception) {
// TODO do something with the exception
exception.printStackTrace();
// Fails if an exception happened
}
The Legacy Interface allows individual resources to be read from the REST API.
Listing Resources
// example: legacy_listing_resources
using Mbed.Cloud.Common;
using MbedCloudSDK.Billing.Api;
var billingApi = new BillingApi(new Config());
foreach (var quotaHistory in billingApi.GetQuotaHistory())
{
Console.WriteLine($"Quota change reason: {quotaHistory.Reason}, delta: {quotaHistory.Delta}");
}
// example: legacy_listing_resources
import { BillingApi } from "mbed-cloud-sdk";
const billingApi = new BillingApi();
billingApi.getQuotaHistory()
.then(data => {
data.data.forEach(quotaHistory => {
console.log(`Quota change reason: ${quotaHistory.reason}, delta: ${quotaHistory.delta}`);
});
});
# example: legacy listing resources
from mbed_cloud import BillingAPI
billing_api = BillingAPI()
for quota_history in billing_api.get_quota_history():
print("Quota change reason: %s, delta: %s" % (quota_history.reason, quota_history.delta))
// example: legacy listing resources
try (Billing billingApi = new Billing(Configuration.get())) {
billingApi.getAllQuotaHistory(null)
.forEach(q -> log("Quota change reason: " + q.getReason() + ", delta: " + q.getDelta()));
} catch (MbedCloudException exception) {
// TODO do something with the exception
exception.printStackTrace();
// Fails if an exception happened
}
When a REST API list endpoint is called the Legacy Interface returns a Paginator which allows the resources to be iterated over in a similar way to the Foundation Interface.
Use Cases
Managing Accounts
// example: creating and managing a subtenant account
myAccount = await accountRepo.Create(new Account
{
DisplayName = "new test account",
Aliases = new List<string>() { "alex_test_account" },
EndMarket = "IOT",
AdminFullName = "Alex Logan",
AdminEmail = "alexadmin@admin.com",
});
var userRepo = new SubtenantUserRepository();
// get first subtenant user acociated with the account
var firstUser = accountRepo.Users(myAccount.Id).FirstOrDefault();
var originalPhoneNumber = firstUser.PhoneNumber;
var newPhoneNumber = originalPhoneNumber + "00";
// update the user's phone number
firstUser.PhoneNumber = newPhoneNumber;
await userRepo.Update(myAccount.Id, firstUser.Id, firstUser);
// change it back to the original
firstUser.PhoneNumber = originalPhoneNumber;
await userRepo.Update(myAccount.Id, firstUser.Id, firstUser);
// example: creating and managing a subtenant account
const newAccount: Account = {
displayName: "new test account",
aliases: [
"alex_test_account"
],
endMarket: "IOT",
// Admin user details
adminFullName: "Alex Logan",
adminEmail: "alexadmin@admin.com",
};
myAccount = await accountContext.create(newAccount);
const subtenantUserContext = new SubtenantUserRepository();
// Populate the new user details
const user: SubtenantUser = {
// Link this user to the account
accountId: myAccount.id,
// User details
fullName: "tommi the wombat",
username: "tommi_wombat",
phoneNumber: "0800001066",
email: "tommi_the_wombat@email.com",
};
// create the new user
await subtenantUserContext.create(user, myAccount.id);
# example: creating and managing a subtenant account
from mbed_cloud.foundation import Account, SubtenantUser
# Populate the new account details
new_subtenant = Account(
display_name='sdk test bob',
aliases=['sdk_test_bob_' + random_string()],
end_market='connected warrens',
# Admin user details
admin_full_name='bob the wombat',
admin_email='bob@example.com',
)
# Create the new account
new_subtenant.create()
account_id = new_subtenant.id
print("This is my new Account ID: %s" % account_id)
# Populate the new user details
new_user = SubtenantUser(
# Link this user to the account
account_id=account_id,
# User details
username='JaneDoeSDK',
full_name='Jane Doe',
email='jane.doe@example.com',
phone_number='1800966228',
)
# Create the new user
new_user.create()
// example: creating and managing a subtenant account
try (Sdk sdk = Sdk.createSdk(Configuration.get()); AccountDao myAccountDao = sdk.foundation().getAccountDao();
SubtenantUserDao userDao = sdk.foundation().getSubtenantUserDao();) {
// Fetch my account
myAccountDao.me();
// Create a new User
SubtenantUser user = new SubtenantUser();
user.setAccountId(myAccountDao.getId());
user.setFullName("tommi the wombat");
user.setEmail("tommi_the_wombat@email.com");
user.setUsername("tommi_wombat");
user.setPhoneNumber("0800001066");
userDao.create(user);
// Find this added user in my account user list.
String createdId = userDao.getId();
// Fetch latest details of the current sub-tenant user.
userDao.read();
// Fetching a user from the list of account users
SubtenantUser correspondingUser = StreamSupport.stream(myAccountDao.allUsers(null).spliterator(), false)
.filter(u -> u.getId().equals(createdId)).findFirst().get();
// Delete the created user.
userDao.delete();
} catch (MbedCloudException | IOException exception) {
// TODO do something with the exception
exception.printStackTrace();
}
This is a more complex example demonstrating how to use the interfaces to create and manage a subtenant account.
- First we create the subtenant. We must record the
admin_api_key
field that appears in the response, which the SDK does for us. - We can then use this same key to create a new session with the cloud
- Using our new session, we can instruct the cloud as the subtenant, e.g. to set up a new user.
- Finally, we can use our own aggregator account to perform some read-only actions such as listing the users for our new subtenant.
Renewing a certificate
// example: certificate renew
var myConfig = new CertificateIssuerConfigRepository().List().All().FirstOrDefault(c => c.Reference == "LWM2M");
var connectedDevices = new DeviceRepository()
.List()
.All()
.Where(d => d.State == DeviceState.REGISTERED)
.ToList();
foreach (var device in connectedDevices)
{
await new DeviceRepository().RenewCertificate(myConfig.Reference, device.Id);
}
// example: certificate renew
const certificateIssuerConfigContext = new CertificateIssuerConfigRepository();
const myConfig = (await certificateIssuerConfigContext.list().all()).find(c => c.reference === "LWM2M");
const deviceContext = new DeviceRepository();
const connectedDevices = (await deviceContext.list().all()).filter(device => device.state === "registered");
for (const device of connectedDevices) {
await deviceContext.renewCertificate(myConfig.reference, device.id);
}
# example: certificate renew
# Find all certificate issuers that may be in use
certificate_references = []
for certificate_issuer_config in CertificateIssuerConfig().list():
certificate_references.append(certificate_issuer_config.certificate_reference)
# List all devices
for device in Device().list():
# A certificate can only be renewed on a registered device
if device.state == DeviceStateEnum.REGISTERED:
# It is not possible to determine which certificate issuer has been used on a
# device so try them in turn.
for certificate_reference in certificate_references:
try:
# If the wrong certificate issuer is selected then the renew will fail
device.renew_certificate(certificate_reference)
except ApiErrorResponse:
print("Certificate '%s' could not be renewed on device '%s'" % (
certificate_reference, device.name))
else:
print("Certificate '%s' was renewed on device '%s'" % (
certificate_reference, device.name))
// example: certificate renew
try (Sdk sdk = Sdk.createSdk(Configuration.get()); DeviceDao deviceDao = sdk.foundation().getDeviceDao()) {
// Find the certificate issuers configuration in use. In this case, it is known that the reference is
// "LWM2M".
CertificateIssuerConfig myConfig = StreamSupport.stream(sdk.foundation().getCertificateIssuerConfigListDao()
.getPaginator().spliterator(),
false)
.filter(c -> c.getReference().equals("LWM2M")).findFirst()
.get();
// Renew the certificate of all connected devices
StreamSupport.stream(sdk.foundation().getDeviceListDao().paginator().spliterator(), false)
.filter(d -> d.getState() == DeviceState.REGISTERED).forEach(d -> {
// Configure the DAO with the model of interest
try {
deviceDao.setModel(d);
deviceDao.renewCertificate(myConfig.getReference());
log(myConfig + " was renewed on " + d);
} catch (@SuppressWarnings("unused") MbedCloudException exception) {
// TODO do something with the exception
log(myConfig + " could not be renewed on " + d);
}
});
} catch (MbedCloudException | IOException exception) {
// TODO do something with the exception
exception.printStackTrace();
}
This example shows how to renew the certificate on a device.
- First we list the certificate issuer configs and pick the one we know our devices are using. For this we're using the "LWM2M" config.
- Then we need to get a list of connected devices, by filtering our devices based on their state:
registered
means the device is connected. - We can now call the
renew certificate
method on each device.
Enrolling a device
// example: device enrollment single
var enrollmentRepo = new DeviceEnrollmentRepository();
var enrollment = new DeviceEnrollment
{
EnrollmentIdentity = "A-4E:63:2D:AE:14:BC:D1:09:77:21:95:44:ED:34:06:57:1E:03:B1:EF:0E:F2:59:44:71:93:23:22:15:43:23:12",
};
await enrollmentRepo.Create(enrollment);
// example: device enrollment single
const enrollmentContext = new DeviceEnrollmentRepository();
const enrollment: DeviceEnrollment = {
enrollmentIdentity: "A-4E:63:2D:AE:14:BC:D1:09:77:21:95:44:ED:34:06:57:1E:03:B1:EF:0E:F2:59:44:71:93:23:22:15:43:23:12",
};
await enrollmentContext.create(enrollment);
# example: device enrollment single
# Enroll a single device using the enrollment ID for the device
device_enrollment = DeviceEnrollment(
enrollment_identity = "A-4E:63:2D:AE:14:BC:D1:09:77:21:95:44:ED:34:06:57:1E:03:B1:EF:0E:F2:59:44:71:93:23:22:15:43:23:12")
device_enrollment.create()
There are two different ways to enroll a device.
Firstly, you can enroll one device at a time using the device enrollment
entity.
- Create a new
deviceEnrollment
entity and set theenrollment identity
property. - Call the
create
method to enroll the device.
// example: device enrollment bulk
var bulkRepo = new DeviceEnrollmentBulkCreateRepository();
// use System.IO file open
var bulk = default(DeviceEnrollmentBulkCreate);
using (var file = File.Open(pathToCsv, FileMode.Open))
{
bulk = await bulkRepo.Create(file);
}
bulk = await bulkRepo.Read(bulk.Id);
// example: device enrollment bulk
const bulkCreateContext = new DeviceEnrollmentBulkCreateRepository();
// uses fs readStream so this is a node only example.
const csv = createReadStream(pathToCsv);
let createTask = await bulkCreateContext.create(csv);
// call get to see current state of bulk enrollment
createTask = await bulkCreateContext.read(createTask.id);
const reportFile = await bulkCreateContext.downloadFullReportFile(createTask) as ReadStream;
// stream report file into string and print it
printFile(reportFile);
const errorFile = await bulkCreateContext.downloadErrorsReportFile(createTask) as ReadStream;
printFile(errorFile);
# example: device enrollment bulk
with open("tests/fixtures/bulk_device_enrollment.csv", "rb") as csv_file_handle:
bulk_device_enrollment = DeviceEnrollmentBulkCreate().create(csv_file_handle)
while bulk_device_enrollment.status != DeviceEnrollmentBulkCreateStatusEnum.COMPLETED:
time.sleep(1)
bulk_device_enrollment.get()
print(bulk_device_enrollment.download_full_report_file().read())
print(bulk_device_enrollment.download_errors_report_file().read())
// example: device enrollment bulk
try (Sdk sdk = Sdk.createSdk(Configuration.get());
DeviceEnrollmentBulkCreateDao enrolmentDao = sdk.foundation().getDeviceEnrollmentBulkCreateDao()) {
// file is a csv file containing all the devices which need to be enrolled. See test.csv in the /resources
// folder as example.
enrolmentDao.create(new DataFile(file));
// read current state of bulk enrollment
enrolmentDao.read();
// Wait until the report is ready
// FIXME this is just a cruddy example of waiting for the bulk operation to complete. Better handling should
// be performed in production application.
while (enrolmentDao.getModel().getStatus() != DeviceEnrollmentBulkCreateStatus.COMPLETED) {
Thread.sleep(1000);
enrolmentDao.read();
}
// Download the enrolment report files
FileDownload report = enrolmentDao.downloadFullReportFile((String) null);
log("report", report);
FileDownload errorReport = enrolmentDao.downloadErrorsReportFile((String) null);
log("errorReport", errorReport);
} catch (MbedCloudException | InterruptedException exception) {
// TODO do something with the exception
exception.printStackTrace();
}
Alternatively, you can enroll many devices at the same time using the device enrollment bulk create` entity.
- Create a
.csv
file that contains the identities of the devices you want to enroll. An example of what this file should contain can be found here. - Read this file using whichever mechanism your language provides, and call
create
. - You can check the progress of the enrollment by calling
get
. - When the task has completed, the status will be
completed
.
Launching a firmware update campaign
// example: firmware_update_campaign_launch
var updateCampaignRepo = sdk.Foundation().UpdateCampaignRepository();
var campaign = await updateCampaignRepo.Create(new UpdateCampaign
{
Name = $"campaign - {DateTime.Now}",
Description = "Update campaign for prior 2019 devices",
RootManifestId = firmwareManifest.Id,
DeviceFilterHelper = new DeviceListOptions().CreatedAtLessThan(new DateTime(2019, 1, 1)).Filter,
});
Console.WriteLine((await updateCampaignRepo.Read(campaign.Id)).Phase);
await updateCampaignRepo.Start(campaign.Id);
Console.WriteLine((await updateCampaignRepo.Read(campaign.Id)).Phase);
foreach (var metadata in updateCampaignRepo.DeviceMetadata(campaign.Id))
{
Console.WriteLine(metadata);
}
// example: firmware_update_campaign_launch
const updateCampaignRepo = sdk.foundation().updateCampaignRepository();
const filter: DeviceFilter = {
createdAt: {
lte: [
new Date(2019, 0, 1)
],
}
};
const campaign = await updateCampaignRepo.create({
name: `campaign - ${new Date()}`,
description: "Update campaign for prior 2019 devices",
rootManifestId: firmwareManifest.id,
deviceFilter: encodeFilter(filter),
});
console.log((await updateCampaignRepo.read(campaign.id)).phase);
await updateCampaignRepo.start(campaign.id);
console.log((await updateCampaignRepo.read(campaign.id)).phase);
for await (const metadata of updateCampaignRepo.deviceMetadata(campaign.id)) {
console.log(metadata);
}
# example: firmware update campaign launch
from datetime import datetime
from pprint import pprint
from mbed_cloud import SDK
from mbed_cloud import ApiFilter
pelion_dm_sdk = SDK()
new_campaign = pelion_dm_sdk.foundation.update_campaign(
root_manifest_id=my_manifest_id,
name="campaign - " + str(datetime.now()),
description="Update campaign for prior 2019 devices"
)
# Create a filter for all devices created before the 1st of January 2019 so that these devices will have their
# firmware replaced by the one defined in the manifest.
api_filter = ApiFilter()
api_filter.add_filter("created_at", "lte", datetime(2019, 1, 1))
new_campaign.device_filter_helper = api_filter
# Create the campaign
new_campaign.create()
# Determine the phase of the campaign
print("Campaign Phase:", new_campaign.phase)
# Start the campaign
new_campaign.start()
# Determine the phase of the campaign
new_campaign.read()
print("Campaign Phase:", new_campaign.phase)
# Print all device metadata related to this campaign
for campaign_device_metadata in new_campaign.device_metadata():
pprint(campaign_device_metadata.to_dict())
// example: firmware update campaign launch
UpdateCampaignDao myCampaignDao = sdk.foundation().getUpdateCampaignDao();
// Define an update campaign
UpdateCampaign newCampaign = new UpdateCampaign();
newCampaign.setName("campaign - " + (new Date().toString()));
newCampaign.setDescription("Update campaign for prior 2019 devices");
newCampaign.setRootManifestId(myManifestId);
// All devices created before the 1st of January 2019 will have their firmware replaced by the one defined
// in the manifest
newCampaign.setDeviceFiltersHelper(new DeviceListOptions().lessThanCreatedAt(new GregorianCalendar(2019, 0,
1).getTime())
.getFilter());
// Create the campaign
myCampaignDao.create(newCampaign);
// Determine the phase of the campaign
System.out.println(myCampaignDao.read().getPhase());
// Start the campaign
myCampaignDao.start();
// Determine the phase of the campaign
System.out.println(myCampaignDao.read().getPhase());
// Print all device metadata related to this campaign
myCampaignDao.allDeviceMetadata(null).all().forEach(System.out::println);
The firmware of devices in the field can be automatically and securely updated by launching an update campaign. Provided that a firmware image and a manifest have been uploaded to Pelion Device Management, such a campaign can be created and then started. It is also possible to stop or archive campaigns in progress if need be.
Setting and Getting Device Resource Values
// example: get and set a resource value
using Mbed.Cloud;
using Mbed.Cloud.Common;
using Mbed.Cloud.Foundation;
using Mbed.Cloud.Foundation.Enums;
using MbedCloudSDK.Connect.Api;
// Use the Foundation interface to find a connected device.
var device = sdk
.Foundation()
.DeviceRepository()
.List(new DeviceListOptions().StateEqualTo(DeviceState.REGISTERED))
.FirstOrDefault();
// Use the Legacy interface for find resources
var config = new Config
{
AutostartNotifications = true,
};
using (var connect = new ConnectApi(config))
{
// Find an observable resource
var resource = connect
.ListResources(device.Id)
.FirstOrDefault(r => r.Observable == true);
// Set a resource value
connect.SetResourceValue(resource.DeviceId, resource.Path, "12");
// Get a resource value
var value = connect.GetResourceValue(resource.DeviceId, resource.Path);
Console.WriteLine($"Device {device.Id}, path {resource.Path}, current value: {value}");
}
// example: get and set a resource value
import { ConnectApi, SDK } from "mbed-cloud-sdk";
// Use the Foundation interface to find a connected device.
const device = await sdk.foundation().deviceRepository().list({
filter: {
state: "registered",
}
}).first();
// Use the Legacy interface for find resources
const connectApi = new ConnectApi({
autostartNotifications: true,
});
// Find an observable resource
const resource = (await connectApi.listResources(device.id))
.filter(r => r.observable).pop();
// Set a resource value
await connectApi.setResourceValue(device.id, resource.path, "12");
// Get a resource value
const value = await connectApi.getResourceValue(device.id, resource.path);
console.log(`Device ${device.id}, path ${resource.path}, current value: ${value}`);
await connectApi.stopNotifications();
# example: get and set a resource value
from mbed_cloud.foundation import Device
from mbed_cloud import ApiFilter
from mbed_cloud.foundation.enums import DeviceStateEnum
from mbed_cloud import ConnectAPI
# Use the Foundation interface to find a registered device.
api_filter = ApiFilter()
api_filter.add_filter("state", "eq", DeviceStateEnum.REGISTERED)
device = Device().list(max_results=2, filter=api_filter).next()
# Use the Legacy interface to find resources
connect_api = ConnectAPI()
# Find an observable resource
for resource in connect_api.list_resources(device.id):
if resource.observable:
break
# Set a resource value
connect_api.set_resource_value(device.id, resource.path, "12")
# Get a resource value
value = connect_api.get_resource_value(device.id, resource.path)
print("Device %s, path %s, current value: %s" %(device.id, resource.path, value))
// example: get and set a resource value
try (Sdk sdk = Sdk.createSdk(Configuration.get()); DeviceListDao dao = sdk.foundation().getDeviceListDao()) {
// Use the Foundation interface to find a device.
Paginator<Device> deviceIterator = dao.list(new DeviceListOptions().equalToState(DeviceState.REGISTERED)
.maxResults(1));
Device device = deviceIterator.first();
// Find an observable resource
List<Resource> observableResources = sdk.lowLevelRest().getConnectModule().listObservableResources(device);
Resource resource = observableResources.get(0);
ResourceDao resourceDao = sdk.resource(resource);
// Set a resource value
resourceDao.update("12", ResourceValueType.STRING, new TimePeriod(10));
// Get a resource value
value = resourceDao.read(new TimePeriod(10));
System.out.println("Device " + device.getId() + ", path " + resource.getPath() + ", current value: "
+ value);
resourceDao.close();
} catch (Exception e) {
e.printStackTrace();
}
Interactions with device resource values in the REST API are asynchronous. However, the SDKs provide a simplified way of both setting and getting resource values without worrying about the underlying communication system. This example shows a resource value being set and then the updated value being read back.
Behind the scenes the SDK will handle the asynchronous behaviour of the REST API, which although specific the implementation in the API normally involves creating a separate thread to handle the asynchronous data from the REST API.
Subscribing to Device Resource Values
// example: subscribe to resource values
using Mbed.Cloud.Common;
using MbedCloudSDK.Connect.Api;
var config = new Config
{
AutostartNotifications = true,
};
using (var connect = new ConnectApi(config))
{
var observer = await connect.Subscribe.ResourceValuesAsync("*");
while(true) {
Console.WriteLine(await observer.NextAsync());
}
}
// example: subscribe to resource values
import { ConnectApi } from "mbed-cloud-sdk";
const connect = new ConnectApi();
const observer = connect.subscribe.resourceValues({
deviceId: "*",
});
while (true) {
console.log(await observer.once());
}
# example: subscribe to resource values
from mbed_cloud import ConnectAPI
# Create an instance of the Connect API
connect_api = ConnectAPI()
# Configure a subscription to receive resource value changes on all devices
channel = connect_api.subscribe.channels.ResourceValues(device_id="*")
# Contact Pelion Device Management to actually make the configured subscription
observer = connect_api.subscribe(channel)
# Print the subscription notifications received
while True:
print(observer.next().block())
// example: subscribe to resource values
try (Sdk sdk = Sdk.createSdk(Configuration.get())) {
// Configure a subscription to receive resource value changes on all devices.
// For more information about backpressure strategies, please have a look at related documentation:
// https://github.com/ReactiveX/RxJava/wiki/Backpressure
// For more information about First Value strategies, have a look at
// com.arm.mbed.cloud.sdk.subscribe.model.FirstValue
ResourceValueObserver observer = sdk.subscribe(SubscriptionFilterOptions.newFilter().likeDevice("%"),
BackpressureStrategy.BUFFER, FirstValue.ON_VALUE_UPDATE);
// Print the subscription notifications received
observer.flow().subscribe(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}
It is possible to subscribe to device resource value changes, receiving updates whenever a change to value occurs. This introduces the concept of observers, which allows applications to listen to changes and react accordingly when changes occur. It is also possible to block on the value changing, as in this example, although this may not be so useful in real situations.
The SDK abstracts the underlying REST API concepts of Subscriptions and Pre-Subscriptions to prevent a simple interface. However, this can result in a multitude of HTTP requests. Please see Advanced Usage: Scaling for more information.
Advanced Usage
Scaling
The SDK supports receiving resource values from a large number of devices via the subscription model. These are our recommendations on how to use the Pelion Device Management SDK at this scale.
- Use wildcards to match devices/resources. There is a single resource to control pre-subscriptions in the API: individually registering a million devices would create a million entries. This is unmanageable, so it is best to avoid this approach.
- Do not use subscriptions as these are enabled on a per-device basis and require an API interaction per subscription, resulting in a large number of HTTP requests. By default the SDK abstracts the difference between
subscriptions and pre-subscriptions. To stop the SDK automatically creating subscriptions, use
OnRegistration
as the value of theFirstValueEnum
parameter when subscribing.
Other considerations are those of load and robustness.
- Devices which update resource values once a day would result in a very different load on the receiving system when compared with devices which update resource values once a second. This is dependent on the device and client implementation but could be the most important factor in any architectural decision.
- Having a single client receiving all notifications creates a single point of failure, and is therefore not robust. This may not matter for development but would not be a recommended production architecture.
- For robust deployments it is recommended that a web hook based notification system using DNS load balancing for incoming Webhhook notifications is used to support a high throughput / high reliability solution.
Production Deployments
In production deployments it is recommended that environment variables are used to configure the SDK. These can normally be stored in a secure way within the platform itself.
The configuration options are defined in the Configuration section and have the same name
regardless of whether they are defined in environment variables or in a .env
file.
On-Premise Deployments
MBED_CLOUD_SDK_API_KEY=ak_A644VERY4745LONG64RANDOM3254STRINGW555455ITHA564miXTurOFlowercaseANDUPPERCASELETTERSIintersperseDwithNUMBER5
MBED_CLOUD_SDK_HOST==https://api-pelion-device-management.example.com
The SDKs will use the public Pelion Device Management service by default, so it is not normally necessary to define the
host in the configuration. If a On_premise deployment is being used then the host will need to be configured, this
should either be via an environment variable or using .env
file during development.
Appendix: Known Limitations
This appendix includes known limitations of Pelion Device Management or the SDKs.
- The Pelion Device Management platform only allows a single notification channel per API key. Therefore, multiple instances of the SDKs cannot share the same API key and interact with resource values or create subscriptions.
Appendix: Subscriptions and Pre-Subscriptions
The SDK abstracts the subscriptions and pre-subscription concepts used by the API. The following
background information on how the API works may be helpful:
- Subscriptions are created per-device and only apply to registered/connected devices. These take immediate effect but are not persistent: if the device deregisters the subscription is lost. The client will no longer receive notifications for that device even when it comes back online.
- Pre-subscriptions are created per API key (and use wildcards to identify devices and resources): they are persistent but will only become active after the device registers or re-registers. This means there is a delay between the request for resource value updates and receipt of the first notification.
The default behaviour of the SDK is to expose behaviour which makes sense to the client and hides the differences between subscriptions and pre-subscriptions. This means that using the default SDK behaviour the client will receive value updates in the following cases:
- For all currently connected devices as soon as a value change occurs.
- For new devices matching the configuration when they register.
- For devices even after de-register and registers again after coming back online.
However, there is an overhead which becomes significant when large numbers of devices are used as the SDK makes multiple calls to the REST API to create both subscriptions and pre-subscriptions.
Setting OnRegistration
as the value of the FirstValueEnum
parameter avoids this overhead but means that there will
be a delay before resource value updates are received by the client for connected devices. This is because devices must re-register
before the configured subscription becomes active (re-registering is a periodic occurrence the frequency of which
is application/context specific but is typically once every 10 minutes). Using this setting the client will receive value updates in the following cases:
- For all currently connected devices only after a device re-registers.
- For new devices matching the configuration when they register.
- For devices even after de-register and register again after coming back online.
Appendix: Foundation Entities
This appendix lists all the Foundation interface entities, how they map to REST API calls and any differences in naming or usage.
- Renamed Fields - fields are renamed in the SDK for clarity or to avoid namespace clashes.
- Unused Fields - these fields may be hidden from the user for a variety of reasons, including deprecation and readonly status.
- Added Properties - properties may be added to the SDK for convenience to map to one or more API fields.
Accounts: Account
The following REST API fields are not used by the SDK:
- 'sub_accounts'
Entity Method | REST API Mapping | Notes |
---|---|---|
api_keys | GET: /v3/accounts/{account_id}/api-keys | This lists the api keys of the subtenant account. |
create | POST: /v3/accounts | |
dark_theme_branding_colors | GET: /v3/accounts/{account_id}/branding-colors/dark | This lists the dark theme banding colors of the subtenant account. |
dark_theme_branding_images | GET: /v3/accounts/{account_id}/branding-images/dark | This lists the dark theme banding images of the subtenant account. |
light_theme_branding_colors | GET: /v3/accounts/{account_id}/branding-colors/light | This lists the light theme banding colors of the subtenant account. |
light_theme_branding_images | GET: /v3/accounts/{account_id}/branding-images/light | This lists the light theme banding images of the subtenant account. |
list | GET: /v3/accounts | |
me | GET: /v3/accounts/me | This is provided by the SDK to avoid listing to retrieve the user's own Account. |
read | GET: /v3/accounts/{account_id} | |
trusted_certificates | GET: /v3/accounts/{account_id}/trusted-certificates | This lists the trusted certificates of the subtenant account. |
update | PUT: /v3/accounts/{account_id} | |
user_invitations | GET: /v3/accounts/{account_id}/user-invitations | This lists the user invitations of the subtenant account. |
users | GET: /v3/accounts/{account_id}/users | This lists the users of the subtenant account. |
Accounts: API Key
Entity Method | REST API Mapping | Notes |
---|---|---|
create | POST: /v3/api-keys | |
delete | DELETE: /v3/api-keys/{apikey_id} | |
list | GET: /v3/api-keys | |
me | GET: /v3/api-keys/me | This is provided by the SDK to avoid listing to retrieve the user's own API Key. |
read | GET: /v3/api-keys/{apikey_id} | |
update | PUT: /v3/api-keys/{apikey_id} |
Accounts: Subtenant API Key
Entity Method | REST API Mapping |
---|---|
create | POST: /v3/accounts/{account_id}/api-keys |
delete | DELETE: /v3/accounts/{account_id}/api-keys/{apikey_id} |
read | GET: /v3/accounts/{account_id}/api-keys/{apikey_id} |
update | PUT: /v3/accounts/{account_id}/api-keys/{apikey_id} |
Accounts: Subtenant User
Entity Method | REST API Mapping | Notes |
---|---|---|
create | POST: /v3/accounts/{account_id}/users | |
delete | DELETE: /v3/accounts/{account_id}/users/{user_id} | |
read | GET: /v3/accounts/{account_id}/users/{user_id} | |
update | PUT: /v3/accounts/{account_id}/users/{user_id} |
The API field 'email' is not used by the SDK. The API field 'status' is not used by the SDK. The API field 'two_factor_auth_enabled' is not used by the SDK. |
validate_email | POST: /v3/accounts/{account_id}/users/{user_id}/validate-email |
Accounts: Subtenant User Invitation
Entity Method | REST API Mapping |
---|---|
create | POST: /v3/accounts/{account_id}/user-invitations |
delete | DELETE: /v3/accounts/{account_id}/user-invitations/{invitation_id} |
read | GET: /v3/accounts/{account_id}/user-invitations/{invitation_id} |
Accounts: User
Entity Method | REST API Mapping | Notes |
---|---|---|
create | POST: /v3/users | |
delete | DELETE: /v3/users/{user_id} | |
list | GET: /v3/users | |
read | GET: /v3/users/{user_id} | |
update | PUT: /v3/users/{user_id} |
The API field 'email' is not used by the SDK. The API field 'status' is not used by the SDK. The API field 'two_factor_auth_enabled' is not used by the SDK. |
Accounts: User Invitation
Entity Method | REST API Mapping |
---|---|
create | POST: /v3/user-invitations |
delete | DELETE: /v3/user-invitations/{invitation_id} |
list | GET: /v3/user-invitations |
read | GET: /v3/user-invitations/{invitation_id} |
Branding: Dark Theme Color
Entity Method | REST API Mapping |
---|---|
delete | DELETE: /v3/branding-colors/dark/{reference} |
list | GET: /v3/branding-colors/dark |
read | GET: /v3/branding-colors/dark/{reference} |
update | PUT: /v3/branding-colors/dark/{reference} |
Branding: Dark Theme Image
Entity Method | REST API Mapping |
---|---|
delete | POST: /v3/branding-images/dark/{reference}/clear |
list | GET: /v3/branding-images/dark |
read | GET: /v3/branding-images/dark/{reference} |
update | POST: /v3/branding-images/dark/{reference}/upload-multipart |
Branding: Light Theme Color
Entity Method | REST API Mapping |
---|---|
delete | DELETE: /v3/branding-colors/light/{reference} |
list | GET: /v3/branding-colors/light |
read | GET: /v3/branding-colors/light/{reference} |
update | PUT: /v3/branding-colors/light/{reference} |
Branding: Light Theme Image
Entity Method | REST API Mapping |
---|---|
delete | POST: /v3/branding-images/light/{reference}/clear |
list | GET: /v3/branding-images/light |
read | GET: /v3/branding-images/light/{reference} |
update | POST: /v3/branding-images/light/{reference}/upload-multipart |
Branding: Subtenant Dark Theme Color
Entity Method | REST API Mapping |
---|---|
delete | DELETE: /v3/accounts/{account_id}/branding-colors/dark/{reference} |
read | GET: /v3/accounts/{account_id}/branding-colors/dark/{reference} |
update | PUT: /v3/accounts/{account_id}/branding-colors/dark/{reference} |
Branding: Subtenant Dark Theme Image
Entity Method | REST API Mapping |
---|---|
delete | POST: /v3/accounts/{account_id}/branding-images/dark/{reference}/clear |
read | GET: /v3/accounts/{account_id}/branding-images/dark/{reference} |
update | POST: /v3/accounts/{account_id}/branding-images/dark/{reference}/upload-multipart |
Branding: Subtenant Light Theme Color
Entity Method | REST API Mapping |
---|---|
delete | DELETE: /v3/accounts/{account_id}/branding-colors/light/{reference} |
read | GET: /v3/accounts/{account_id}/branding-colors/light/{reference} |
update | PUT: /v3/accounts/{account_id}/branding-colors/light/{reference} |
Branding: Subtenant Light Theme Image
Entity Method | REST API Mapping |
---|---|
delete | POST: /v3/accounts/{account_id}/branding-images/light/{reference}/clear |
read | GET: /v3/accounts/{account_id}/branding-images/light/{reference} |
update | POST: /v3/accounts/{account_id}/branding-images/light/{reference}/upload-multipart |
Device Update: Campaign Device Metadata
The following fields are renamed between the REST API and SDK:
- 'campaign' is renamed to 'campaign_id' in the SDK.
Entity Method | REST API Mapping |
---|---|
read | GET: /v3/update-campaigns/{campaign_id}/campaign-device-metadata/{campaign_device_metadata_id}/ |
Device Update: Campaign Statistics
Entity Method | REST API Mapping |
---|---|
events | GET: /v3/update-campaigns/{campaign_id}/statistics/{summary_status_id}/event_types/ |
list | GET: /v3/update-campaigns/{campaign_id}/statistics/ |
read | GET: /v3/update-campaigns/{campaign_id}/statistics/{summary_status_id} |
Device Update: Campaign Statistics Events
Entity Method | REST API Mapping |
---|---|
read | GET: /v3/update-campaigns/{campaign_id}/statistics/{summary_status_id}/event_types/{event_type_id} |
Device Update: Firmware Image
The following fields are renamed between the REST API and SDK:
- 'datafile' is renamed to 'datafile_url' in the SDK.
Entity Method | REST API Mapping | Notes |
---|---|---|
create | POST: /v3/firmware-images/ | This is not a standard create method as it uploads a file which creates an entity which contains URIs to the uploaded file. |
delete | DELETE: /v3/firmware-images/{image_id}/ | |
list | GET: /v3/firmware-images/ | |
read | GET: /v3/firmware-images/{image_id}/ |
Device Update: Firmware Manifest
The following fields are renamed between the REST API and SDK:
- 'datafile' is renamed to 'datafile_url' in the SDK.
- 'key_table' is renamed to 'key_table_url' in the SDK.
Entity Method | REST API Mapping | Notes |
---|---|---|
create | POST: /v3/firmware-manifests/ | This is not a standard create method as it uploads a file (or files) which creates an entity which contains URIs to the uploaded file(s). |
delete | DELETE: /v3/firmware-manifests/{manifest_id}/ | |
list | GET: /v3/firmware-manifests/ | |
read | GET: /v3/firmware-manifests/{manifest_id}/ |
Device Update: Update Campaign
The following REST API fields are not used by the SDK:
- 'state'
The following properties are added by the SDK:
- 'device_filter_helper'
Entity Method | REST API Mapping |
---|---|
archive | POST: /v3/update-campaigns/{campaign_id}/archive |
create | POST: /v3/update-campaigns/ |
delete | DELETE: /v3/update-campaigns/{campaign_id}/ |
device_metadata | GET: /v3/update-campaigns/{campaign_id}/campaign-device-metadata/ |
list | GET: /v3/update-campaigns/ |
read | GET: /v3/update-campaigns/{campaign_id}/ |
start | POST: /v3/update-campaigns/{campaign_id}/start |
stop | POST: /v3/update-campaigns/{campaign_id}/stop |
update | PUT: /v3/update-campaigns/{campaign_id}/ |
Devices: Device
Entity Method | REST API Mapping |
---|---|
add_to_group | POST: /v3/device-groups/{device-group-id}/devices/add/ |
create | POST: /v3/devices/ |
delete | DELETE: /v3/devices/{id}/ |
list | GET: /v3/devices/ |
read | GET: /v3/devices/{id}/ |
remove_from_group | POST: /v3/device-groups/{device-group-id}/devices/remove/ |
renew_certificate | POST: /v3/devices/{device-id}/certificates/{certificate-name}/renew |
update | PUT: /v3/devices/{id}/ |
Devices: Device Enrollment
Entity Method | REST API Mapping |
---|---|
create | POST: /v3/device-enrollments |
delete | DELETE: /v3/device-enrollments/{id} |
list | GET: /v3/device-enrollments |
read | GET: /v3/device-enrollments/{id} |
Devices: Device Enrollment Bulk Create
Entity Method | REST API Mapping |
---|---|
create | POST: /v3/device-enrollments-bulk-uploads |
download_errors_report_file | N/A |
download_full_report_file | N/A |
read | GET: /v3/device-enrollments-bulk-uploads/{id} |
Devices: Device Enrollment Bulk Delete
Entity Method | REST API Mapping |
---|---|
delete | POST: /v3/device-enrollments-bulk-deletes |
download_errors_report_file | N/A |
download_full_report_file | N/A |
read | GET: /v3/device-enrollments-bulk-deletes/{id} |
Devices: Device Enrollment Denial
Entity Method | REST API Mapping |
---|---|
list | GET: /v3/device-enrollment-denials |
read | GET: /v3/device-enrollment-denials/{device_enrollment_denial_id} |
Devices: Device Events
Entity Method | REST API Mapping |
---|---|
list | GET: /v3/device-events/ |
read | GET: /v3/device-events/{device_event_id}/ |
Devices: Device Group
Entity Method | REST API Mapping |
---|---|
add_device | POST: /v3/device-groups/{device-group-id}/devices/add/ |
create | POST: /v3/device-groups/ |
delete | DELETE: /v3/device-groups/{device-group-id}/ |
devices | GET: /v3/device-groups/{device-group-id}/devices/ |
list | GET: /v3/device-groups/ |
read | GET: /v3/device-groups/{device-group-id}/ |
remove_device | POST: /v3/device-groups/{device-group-id}/devices/remove/ |
update | PUT: /v3/device-groups/{device-group-id}/ |
Security: Certificate Enrollment
Entity Method | REST API Mapping |
---|---|
list | GET: /v3/certificate-enrollments |
read | GET: /v3/certificate-enrollments/{certificate-enrollment-id} |
Security: Certificate Issuer
Entity Method | REST API Mapping |
---|---|
create | POST: /v3/certificate-issuers |
delete | DELETE: /v3/certificate-issuers/{certificate-issuer-id} |
list | GET: /v3/certificate-issuers |
read | GET: /v3/certificate-issuers/{certificate-issuer-id} |
update | PUT: /v3/certificate-issuers/{certificate-issuer-id} |
verify | POST: /v3/certificate-issuers/{certificate-issuer-id}/verify |
Security: Certificate Issuer Config
The following REST API fields are not used by the SDK:
- 'is_custom'
Entity Method | REST API Mapping |
---|---|
create | POST: /v3/certificate-issuer-configurations |
delete | DELETE: /v3/certificate-issuer-configurations/{certificate-issuer-configuration-id} |
get_default | GET: /v3/certificate-issuer-configurations/lwm2m |
list | GET: /v3/certificate-issuer-configurations |
read | GET: /v3/certificate-issuer-configurations/{certificate-issuer-configuration-id} |
update | PUT: /v3/certificate-issuer-configurations/{certificate-issuer-configuration-id} |
Security: Developer Certificate
The following fields are renamed between the REST API and SDK:
- 'developer_certificate' is renamed to 'certificate' in the SDK.
Entity Method | REST API Mapping |
---|---|
create | POST: /v3/developer-certificates |
delete | DELETE: /v3/trusted-certificates/{cert_id} |
get_trusted_certificate_info | GET: /v3/trusted-certificates/{cert_id} |
read | GET: /v3/developer-certificates/{developerCertificateId} |
Security: Pre Shared Key
The following properties are added by the SDK:
- 'endpoint_name'
- 'id'
Entity Method | REST API Mapping |
---|---|
create | POST: /v2/device-shared-keys |
delete | DELETE: /v2/device-shared-keys/{endpoint_name} |
list | GET: /v2/device-shared-keys |
read | GET: /v2/device-shared-keys/{endpoint_name} |
Security: Server Credentials
Entity Method | REST API Mapping |
---|---|
get_bootstrap | GET: /v3/server-credentials/bootstrap |
get_lwm2m | GET: /v3/server-credentials/lwm2m |
Security: Subtenant Trusted Certificate
The following REST API fields are not used by the SDK:
- 'signature'
The following properties are added by the SDK:
- 'is_developer_certificate'
Entity Method | REST API Mapping | Notes |
---|---|---|
create | POST: /v3/accounts/{account_id}/trusted-certificates | Signature is not used by the SDK as it is a deprecated field. |
delete | DELETE: /v3/accounts/{account_id}/trusted-certificates/{cert_id} | |
get_developer_certificate_info | GET: /v3/developer-certificates/{developerCertificateId} | |
read | GET: /v3/accounts/{account_id}/trusted-certificates/{cert_id} | |
update | PUT: /v3/accounts/{account_id}/trusted-certificates/{cert_id} | Signature is not used by the SDK as it is a deprecated field. |
Security: Trusted Certificate
The following REST API fields are not used by the SDK:
- 'signature'
The following properties are added by the SDK:
- 'is_developer_certificate'
Entity Method | REST API Mapping | Notes |
---|---|---|
create | POST: /v3/trusted-certificates | Signature is not used by the SDK as it is a deprecated field. |
delete | DELETE: /v3/trusted-certificates/{cert_id} | |
get_developer_certificate_info | GET: /v3/developer-certificates/{developerCertificateId} | |
list | GET: /v3/trusted-certificates | |
read | GET: /v3/trusted-certificates/{cert_id} | |
update | PUT: /v3/trusted-certificates/{cert_id} | Signature is not used by the SDK as it is a deprecated field. |
Appendix: API to SDK Reference
This lists the API endpoints and where they are supported in the SDK.
Account Management API
REST API Endpoint | HTTP Method | SDK Interface | SDK Entity/Module | SDK Method | Notes |
---|---|---|---|---|---|
/v3/accounts | GET | Foundation | Account | list | |
POST | Foundation | Account | create | ||
/v3/accounts/me | GET | Foundation | Account | me | This is provided by the SDK to avoid listing to retrieve the user's own Account. |
PUT | Foundation | Account | update | After retrieving the resource using the `me` method, it can modified using using this SDK method. | |
/v3/accounts/{account_id} | GET | Foundation | Account | read | |
PUT | Foundation | Account | update | ||
/v3/accounts/{account_id}/api-keys | GET | Foundation | Account | api_keys | This lists the api keys of the subtenant account. |
POST | Foundation | Subtenant API Key | create | ||
/v3/accounts/{account_id}/api-keys/{apikey_id} | GET | Foundation | Subtenant API Key | read | |
PUT | Foundation | Subtenant API Key | update | ||
DELETE | Foundation | Subtenant API Key | delete | ||
/v3/accounts/{account_id}/branding-colors/dark | GET | Foundation | Account | dark_theme_branding_colors | This lists the dark theme banding colors of the subtenant account. |
PUT | Foundation | Subtenant Dark Theme Color | update | Bulk operation is not appriate for SDK's entity model, this functionality is covered by the update method. | |
/v3/accounts/{account_id}/branding-colors/dark/{reference} | GET | Foundation | Subtenant Dark Theme Color | read | |
PUT | Foundation | Subtenant Dark Theme Color | update | ||
DELETE | Foundation | Subtenant Dark Theme Color | delete | ||
/v3/accounts/{account_id}/branding-colors/light | GET | Foundation | Account | light_theme_branding_colors | This lists the light theme banding colors of the subtenant account. |
PUT | Foundation | Subtenant Light Theme Color | update | Bulk operation is not appriate for SDK's entity model, this functionality is covered by the update method. | |
/v3/accounts/{account_id}/branding-colors/light/{reference} | GET | Foundation | Subtenant Light Theme Color | read | |
PUT | Foundation | Subtenant Light Theme Color | update | ||
DELETE | Foundation | Subtenant Light Theme Color | delete | ||
/v3/accounts/{account_id}/branding-images/dark | GET | Foundation | Account | dark_theme_branding_images | This lists the dark theme banding images of the subtenant account. |
/v3/accounts/{account_id}/branding-images/dark/{reference} | GET | Foundation | Subtenant Dark Theme Image | read | |
/v3/accounts/{account_id}/branding-images/dark/{reference}/clear | POST | Foundation | Subtenant Dark Theme Image | delete | |
/v3/accounts/{account_id}/branding-images/dark/{reference}/upload | POST | Foundation | Subtenant Dark Theme Image | update | The multipart endpoint is used by the SDKs as it offers the same functionality as the standard upload endpoint. |
/v3/accounts/{account_id}/branding-images/dark/{reference}/upload-multipart | POST | Foundation | Subtenant Dark Theme Image | update | |
/v3/accounts/{account_id}/branding-images/light | GET | Foundation | Account | light_theme_branding_images | This lists the light theme banding images of the subtenant account. |
/v3/accounts/{account_id}/branding-images/light/{reference} | GET | Foundation | Subtenant Light Theme Image | read | |
/v3/accounts/{account_id}/branding-images/light/{reference}/clear | POST | Foundation | Subtenant Light Theme Image | delete | |
/v3/accounts/{account_id}/branding-images/light/{reference}/upload | POST | Foundation | Subtenant Light Theme Image | update | The multipart request is more generic and better supported by SDKs. |
/v3/accounts/{account_id}/branding-images/light/{reference}/upload-multipart | POST | Foundation | Subtenant Light Theme Image | update | |
/v3/accounts/{account_id}/trusted-certificates | GET | Foundation | Account | trusted_certificates | This lists the trusted certificates of the subtenant account. |
POST | Foundation | Subtenant Trusted Certificate | create | Signature is not used by the SDK as it is a deprecated field. | |
/v3/accounts/{account_id}/trusted-certificates/{cert_id} | GET | Foundation | Subtenant Trusted Certificate | read | |
PUT | Foundation | Subtenant Trusted Certificate | update | Signature is not used by the SDK as it is a deprecated field. | |
DELETE | Foundation | Subtenant Trusted Certificate | delete | ||
/v3/accounts/{account_id}/user-invitations | GET | Foundation | Account | user_invitations | This lists the user invitations of the subtenant account. |
POST | Foundation | Subtenant User Invitation | create | ||
/v3/accounts/{account_id}/user-invitations/{invitation_id} | GET | Foundation | Subtenant User Invitation | read | |
DELETE | Foundation | Subtenant User Invitation | delete | ||
/v3/accounts/{account_id}/users | GET | Foundation | Account | users | This lists the users of the subtenant account. |
POST | Foundation | Subtenant User | create | ||
/v3/accounts/{account_id}/users/{user_id} | GET | Foundation | Subtenant User | read | |
PUT | Foundation | Subtenant User | update | ||
DELETE | Foundation | Subtenant User | delete | ||
/v3/accounts/{account_id}/users/{user_id}/validate-email | POST | Foundation | Subtenant User | validate_email | |
/v3/api-keys | GET | Foundation | API Key | list | |
POST | Foundation | API Key | create | ||
/v3/api-keys/me | GET | Foundation | API Key | me | This is provided by the SDK to avoid listing to retrieve the user's own API Key. |
PUT | Foundation | API Key | update | After retrieving the resource using the `me` method, it can modified using using this SDK method. | |
/v3/api-keys/{apikey_id} | GET | Foundation | API Key | read | |
PUT | Foundation | API Key | update | ||
DELETE | Foundation | API Key | delete | ||
/v3/branding-colors/dark | GET | Foundation | Dark Theme Color | list | |
PUT | Foundation | Dark Theme Color | update | Bulk operation is not appriate for SDK's entity model, this functionality is covered by the update method. | |
/v3/branding-colors/dark/{reference} | GET | Foundation | Dark Theme Color | read | |
PUT | Foundation | Dark Theme Color | update | ||
DELETE | Foundation | Dark Theme Color | delete | ||
/v3/branding-colors/light | GET | Foundation | Light Theme Color | list | |
PUT | Foundation | Light Theme Color | update | Bulk operation is not appriate for SDK's entity model, this functionality is covered by the update method. | |
/v3/branding-colors/light/{reference} | GET | Foundation | Light Theme Color | read | |
PUT | Foundation | Light Theme Color | update | ||
DELETE | Foundation | Light Theme Color | delete | ||
/v3/branding-images/dark | GET | Foundation | Dark Theme Image | list | |
/v3/branding-images/dark/{reference} | GET | Foundation | Dark Theme Image | read | |
/v3/branding-images/dark/{reference}/clear | POST | Foundation | Dark Theme Image | delete | |
/v3/branding-images/dark/{reference}/upload | POST | Foundation | Dark Theme Image | update | The multipart endpoint is used by the SDKs as it offers the same functionality as the standard upload endpoint. |
/v3/branding-images/dark/{reference}/upload-multipart | POST | Foundation | Dark Theme Image | update | |
/v3/branding-images/light | GET | Foundation | Light Theme Image | list | |
/v3/branding-images/light/{reference} | GET | Foundation | Light Theme Image | read | |
/v3/branding-images/light/{reference}/clear | POST | Foundation | Light Theme Image | delete | |
/v3/branding-images/light/{reference}/upload | POST | Foundation | Light Theme Image | update | The multipart request is more generic and better supported by SDKs. |
/v3/branding-images/light/{reference}/upload-multipart | POST | Foundation | Light Theme Image | update | |
/v3/developer-certificates | POST | Foundation | Developer Certificate | create | |
/v3/developer-certificates/{developerCertificateId} | GET | Foundation Foundation Foundation | Developer Certificate Subtenant Trusted Certificate Trusted Certificate | read get_developer_certificate_info get_developer_certificate_info | |
/v3/server-credentials | GET | Foundation Foundation | Server Credentials Server Credentials | get_bootstrap get_lwm2m | The information returned by this endpoint can be obtained by calling `get_bootstrap`. The information returned by this endpoint can be obtained by calling `get_lwm2m`. |
/v3/server-credentials/bootstrap | GET | Foundation | Server Credentials | get_bootstrap | |
/v3/server-credentials/lwm2m | GET | Foundation | Server Credentials | get_lwm2m | |
/v3/trusted-certificates | GET | Foundation | Trusted Certificate | list | |
POST | Foundation | Trusted Certificate | create | Signature is not used by the SDK as it is a deprecated field. | |
/v3/trusted-certificates/{cert_id} | GET | Foundation Foundation | Developer Certificate Trusted Certificate | get_trusted_certificate_info read | |
PUT | Foundation | Trusted Certificate | update | Signature is not used by the SDK as it is a deprecated field. | |
DELETE | Foundation Foundation | Developer Certificate Trusted Certificate | delete delete | ||
/v3/user-invitations | GET | Foundation | User Invitation | list | |
POST | Foundation | User Invitation | create | ||
/v3/user-invitations/{invitation_id} | GET | Foundation | User Invitation | read | |
DELETE | Foundation | User Invitation | delete | ||
/v3/users | GET | Foundation | User | list | |
POST | Foundation | User | create | ||
/v3/users/{user_id} | GET | Foundation | User | read | |
PUT | Foundation | User | update | ||
DELETE | Foundation | User | delete |
Billing API
REST API Endpoint | HTTP Method | SDK Interface | SDK Entity/Module | SDK Method |
---|---|---|---|---|
/v3/billing-report | GET | Legacy | Billing API | get_report_overview |
/v3/billing-report-active-devices | GET | Legacy | Billing API | get_report_active_devices |
/v3/billing-report-firmware-updates | GET | Legacy | Billing API | get_report_firmware_updates |
/v3/service-packages | GET | Legacy | Billing API | get_service_packages |
/v3/service-packages-quota | GET | Legacy | Billing API | get_quota_remaining |
/v3/service-packages-quota-history | GET | Legacy | Billing API | get_quota_history |
Bootstrap API
REST API Endpoint | HTTP Method | SDK Interface | SDK Entity/Module | SDK Method |
---|---|---|---|---|
/v2/device-shared-keys | GET | Foundation | Pre Shared Key | list |
POST | Foundation | Pre Shared Key | create | |
/v2/device-shared-keys/{endpoint_name} | GET | Foundation | Pre Shared Key | read |
DELETE | Foundation | Pre Shared Key | delete |
Certificate Enrollment API
REST API Endpoint | HTTP Method | SDK Interface | SDK Entity/Module | SDK Method |
---|---|---|---|---|
/v3/certificate-enrollments | GET | Foundation | Certificate Enrollment | list |
/v3/certificate-enrollments/{certificate-enrollment-id} | GET | Foundation | Certificate Enrollment | read |
/v3/devices/{device-id}/certificates/{certificate-name}/renew | POST | Foundation | Device | renew_certificate |
Connect API
REST API Endpoint | HTTP Method | SDK Interface | SDK Entity/Module | SDK Method | Notes |
---|---|---|---|---|---|
/v2/device-requests/{device-id} | POST | Legacy Legacy Legacy | Connect API Connect API Connect API | get_resource_value set_resource_value execute_resource | |
/v2/endpoints/{device-id} | GET | Legacy | Connect API | list_resources | |
/v2/endpoints/{device-id}/{resourcePath} | GET | Legacy | Connect API | get_resource_value | This functionality is available from the stated method but this endpoint is not used by the SDK. |
PUT | Legacy | Connect API | set_resource_value | This functionality is available from the stated method but this endpoint is not used by the SDK. | |
POST | Legacy | Connect API | execute_resource | This functionality is available from the stated method but this endpoint is not used by the SDK. | |
/v2/notification/callback | PUT | Legacy | Connect API | update_webhook | |
GET | Legacy | Connect API | get_webhook | ||
DELETE | Legacy | Connect API | delete_webhook | ||
/v2/notification/pull | GET | Legacy | Connect API | start_notifications | This endpoint is called indirectly to receive asynchronous subscription and resource value data. |
DELETE | Legacy | Connect API | stop_notifications | ||
/v2/subscriptions | DELETE | Legacy | Connect API | delete_presubscriptions | This functionality is available from the stated method but this endpoint is not used by the SDK. |
PUT | Legacy Legacy | Connect API Connect API | update_presubscriptions delete_presubscriptions | ||
GET | Legacy | Connect API | list_presubscriptions | ||
/v2/subscriptions/{device-id} | GET | Legacy | Connect API | list_device_subscriptions | |
DELETE | Legacy | Connect API | delete_device_subscriptions | ||
/v2/subscriptions/{device-id}/{resourcePath} | PUT | Legacy | Connect API | add_resource_subscription | |
DELETE | Legacy | Connect API | delete_resource_subscription | ||
GET | Legacy | Connect API | get_resource_subscription |
Connect Statistics API
REST API Endpoint | HTTP Method | SDK Interface | SDK Entity/Module | SDK Method |
---|---|---|---|---|
/v3/metrics | GET | Legacy | Connect API | list_metrics |
Customer's Third Party CA API
REST API Endpoint | HTTP Method | SDK Interface | SDK Entity/Module | SDK Method | Notes |
---|---|---|---|---|---|
/v3/certificate-issuer-configurations | POST | Foundation | Certificate Issuer Config | create | |
GET | Foundation | Certificate Issuer Config | list | ||
/v3/certificate-issuer-configurations/lwm2m | GET | Foundation | Certificate Issuer Config | get_default | |
PUT | Foundation | Certificate Issuer Config | update | After retrieving the resource using the `lwm2m` method, it can modified using using this SDK method. | |
/v3/certificate-issuer-configurations/{certificate-issuer-configuration-id} | GET | Foundation | Certificate Issuer Config | read | |
PUT | Foundation | Certificate Issuer Config | update | ||
DELETE | Foundation | Certificate Issuer Config | delete | ||
/v3/certificate-issuers | GET | Foundation | Certificate Issuer | list | |
POST | Foundation | Certificate Issuer | create | ||
/v3/certificate-issuers/{certificate-issuer-id} | GET | Foundation | Certificate Issuer | read | |
PUT | Foundation | Certificate Issuer | update | ||
DELETE | Foundation | Certificate Issuer | delete | ||
/v3/certificate-issuers/{certificate-issuer-id}/verify | POST | Foundation | Certificate Issuer | verify |
Device Directory API
REST API Endpoint | HTTP Method | SDK Interface | SDK Entity/Module | SDK Method | Notes |
---|---|---|---|---|---|
/v3/device-events/ | GET | Foundation | Device Events | list | |
/v3/device-events/{device_event_id}/ | GET | Foundation | Device Events | read | |
/v3/device-groups/ | GET | Foundation | Device Group | list | |
POST | Foundation | Device Group | create | ||
/v3/device-groups/{device-group-id}/ | DELETE | Foundation | Device Group | delete | |
GET | Foundation | Device Group | read | ||
PUT | Foundation | Device Group | update | ||
/v3/device-groups/{device-group-id}/devices/ | GET | Foundation | Device Group | devices | |
/v3/device-groups/{device-group-id}/devices/add/ | POST | Foundation Foundation | Device Device Group | add_to_group add_device | |
/v3/device-groups/{device-group-id}/devices/remove/ | POST | Foundation Foundation | Device Device Group | remove_from_group remove_device | |
/v3/device-queries/ | GET | Legacy | Device Directory API | list_queries | |
POST | Legacy | Device Directory API | add_query | ||
/v3/device-queries/{query_id}/ | DELETE | Legacy | Device Directory API | delete_query | |
GET | Legacy | Device Directory API | get_query | ||
PUT | Legacy | Device Directory API | update_query | ||
/v3/devicelog/ | GET | N/A | N/A | N/A | Endpoint is deprecated and is not supported by the SDKs |
/v3/devicelog/{device_event_id}/ | GET | N/A | N/A | N/A | Endpoint is deprecated and is not supported by the SDKs |
/v3/devices/ | GET | Foundation | Device | list | |
POST | Foundation | Device | create | ||
/v3/devices/{id}/ | DELETE | Foundation | Device | delete | |
GET | Foundation | Device | read | ||
PUT | Foundation | Device | update |
Device Enrollment Denial API
REST API Endpoint | HTTP Method | SDK Interface | SDK Entity/Module | SDK Method |
---|---|---|---|---|
/v3/device-enrollment-denials | GET | Foundation | Device Enrollment Denial | list |
/v3/device-enrollment-denials/{device_enrollment_denial_id} | GET | Foundation | Device Enrollment Denial | read |
Enrollment API
REST API Endpoint | HTTP Method | SDK Interface | SDK Entity/Module | SDK Method |
---|---|---|---|---|
/v3/device-enrollments | POST | Foundation | Device Enrollment | create |
GET | Foundation | Device Enrollment | list | |
/v3/device-enrollments-bulk-deletes | POST | Foundation | Device Enrollment Bulk Delete | delete |
/v3/device-enrollments-bulk-deletes/{id} | GET | Foundation | Device Enrollment Bulk Delete | read |
/v3/device-enrollments-bulk-uploads | POST | Foundation | Device Enrollment Bulk Create | create |
/v3/device-enrollments-bulk-uploads/{id} | GET | Foundation | Device Enrollment Bulk Create | read |
/v3/device-enrollments/{id} | GET | Foundation | Device Enrollment | read |
DELETE | Foundation | Device Enrollment | delete |
Update Service API
REST API Endpoint | HTTP Method | SDK Interface | SDK Entity/Module | SDK Method | Notes |
---|---|---|---|---|---|
/v3/firmware-images/ | GET | Foundation | Firmware Image | list | |
POST | Foundation | Firmware Image | create | This is not a standard create method as it uploads a file which creates an entity which contains URIs to the uploaded file. | |
/v3/firmware-images/{image_id}/ | DELETE | Foundation | Firmware Image | delete | |
GET | Foundation | Firmware Image | read | ||
/v3/firmware-manifests/ | GET | Foundation | Firmware Manifest | list | |
POST | Foundation | Firmware Manifest | create | This is not a standard create method as it uploads a file (or files) which creates an entity which contains URIs to the uploaded file(s). | |
/v3/firmware-manifests/{manifest_id}/ | DELETE | Foundation | Firmware Manifest | delete | |
GET | Foundation | Firmware Manifest | read | ||
/v3/update-campaigns/ | GET | Foundation | Update Campaign | list | |
POST | Foundation | Update Campaign | create | ||
/v3/update-campaigns/{campaign_id}/ | DELETE | Foundation | Update Campaign | delete | |
GET | Foundation | Update Campaign | read | ||
PUT | Foundation | Update Campaign | update | ||
/v3/update-campaigns/{campaign_id}/archive | POST | Foundation | Update Campaign | archive | |
/v3/update-campaigns/{campaign_id}/campaign-device-metadata/ | GET | Foundation | Update Campaign | device_metadata | |
/v3/update-campaigns/{campaign_id}/campaign-device-metadata/{campaign_device_metadata_id}/ | GET | Foundation | Campaign Device Metadata | read | |
/v3/update-campaigns/{campaign_id}/metrics | GET | N/A | N/A | N/A | Endpoint is deprecated: Use the statistics endpoint instead. |
/v3/update-campaigns/{campaign_id}/start | POST | Foundation | Update Campaign | start | |
/v3/update-campaigns/{campaign_id}/statistics/ | GET | Foundation | Campaign Statistics | list | |
/v3/update-campaigns/{campaign_id}/statistics/{summary_status_id} | GET | Foundation | Campaign Statistics | read | |
/v3/update-campaigns/{campaign_id}/statistics/{summary_status_id}/event_types/ | GET | Foundation | Campaign Statistics | events | |
/v3/update-campaigns/{campaign_id}/statistics/{summary_status_id}/event_types/{event_type_id} | GET | Foundation | Campaign Statistics Events | read | |
/v3/update-campaigns/{campaign_id}/stop | POST | Foundation | Update Campaign | stop |