Cloud Development Manual

Home

Overview

AIOT is a cloud-based IOT platform that provides services such as user management, device management, data collection, and remote control. The data collected by the smart device is stored in the AIOT cloud database. Examples of data collected include power, temperature and humidity, switch status, and the status of windows and doors. At the same time, the AIOT cloud can remotely control devices by issuing control commands. How do developers obtain the data that was collected? Or how to remotely control their own equipment?

The AIOT Open Cloud Platform provides a cloud-based connection interface to meet the needs of third-party developers. Through Open APIs and messaging services, developers can collect data and remotely controlling devices via the cloud. Now we provide the following APIs:

  • Location Management

  • Device Management

  • Scenario Management

  • Resource Management

  • Linkage Management

In addition, the AIOT Open Cloud Platform provides a push notification service, which supports pushing the real-time data reported by the device to a third-party server, meeting developers' requirements for receiving data in real-time.

In the following, this manual describes how to develop third-party applications that utilizes cloud-based connection interfaces. This consists of application creation, configuration, and development.

Preface

A good software development process on a good software system architecture will greatly reduce the software development effort needed. Please refer to the following process.

应用开发流程

A stable and efficient application needs to consider API call performance, message processing performance, high availability of Access-Token, etc. We suggest referencing the following proposed architecture.

应用参考架构图

If the developer is not familiar with the use of API call methods, we recommended the use of a Web API test tool: Postman.

Note: Turn off SSL certificate verification when using Postman.

Application creation and configuration

Creating the application

Login to the AIOT Open Cloud Platform and click on "Create New Application". Enter "Application Name", "Industry Type" and "Description" when prompted. After creating an application, the platform automatically assigns the AppID and AppKey.

Apply for resource permissions

Resource is an abstract term. In this present scenario, the data generated by the device, including the setting parameters and real-time status of the device, are all resources. A device has multiple resources, different resources represent different types of information represented by the data. For example, the switch status (plug_status) is a smart socket resource used for indicating whether the smart socket is currently powered on. By accessing this resource, developers can query for the current status of sockets and remotely switch sockets on or off.

Before accessing a resource, developers need to request permission based on access level. There are two resource access levels, level 1 and level 2. Level 1 represents commonly accessed resources and level 2 represents less commonly accessed resources. When level 1 access is granted to a developer for a type of device, the developer can use all the commonly accessed resources for that type of device in their application. By default, the APP is automatically assigned level 1 access permissions for all types of devices.

If developers need to apply for level 2 access permissions, please visit the "Application Management" page and change to the "Resource Authorization" page, as shown in the following figure.

  • Click the "Apply Resource" button on the right side of each row to apply for resources corresponding to the type of device.
  • Select multiple check boxes on the left, and then click the "Batch Application" button in the upper right corner. You can apply for resources corresponding to multiple device types in batches.

Please wait for the review patiently after submitting the application form.

Apply for API permissions

APIs are the main method for developers to query and control equipment. By default, APIs are automatically assigned common API permissions.

Account authorization

Third-party applications can access and control the devices under the AIOT account only after being authorized by the AIOT account. At the same time, the AIOT platform can push device messages to third-party servers.

Note: Search for "Aqara Home" in the App Store or Apple Store, download and install, then register the Aqara Account.

Currently, the AIOT Open Cloud Platform only provides one authorization method: OAuth 2.0.

OAuth2.0

OAuth2.0 is an open standard that allows users to grant third-party applications access to private resources (such as user information, photos, videos, device data, etc.) stored by users on websites (or Internet of Things platform) without having to provide their username and password to third-party applications.

AIOT Open Cloud Platform implements the OAuth 2.0 standard authorization code (authorization_code) mode, for server-side applications. The OAuth 2.0 authorization process is simple and secure. The time-process diagram is shown below. An access token (token) is obtained after successfully completing the authorization process. After receiving access tokens, developers can use access tokens to gain access to interfaces, get user information, or manipulate users' devices.

Oauth2.0授权码模式时序图

Detailed OAuth 2.0 authorization process is as follows:

Note: The URL in this chapter takes “Mainland China( https://aiot-oauth2.aqara.cn/)” as an example, other area please refer to Country (area code) .

Step 1 Request authorization code

First, third-party applications need to redirect users to the AIOT OAuth 2.0 service through a web browser. After logging in successfully using Aqara account, the AIOT Open Cloud Platform returns the user's authorization code. The validity period of the authorization code is 10 minutes. Please complete the following process within 10 minutes.

  • URL: https://aiot-oauth2.aqara.cn/authorize?client_id=xxx&response_type=code&redirect_uri=xxxx&state=xxx&theme=x
  • Request method: HTTP GET
  • Request parameters
Parameter name Is required? Description
client_id Yes Third-party application ID, AppID
response_type Yes Return type, according to the OAuth 2.0 standard, get the value of the code
redirect_uri Yes Third-party application registration redirect URI
state No The value is an arbitrary string, and the authentication server will return the original value in the parameter
theme No Page theme, currently supports themes 0, 1, and 2, a total of three themes. The default theme 1
  • Return to instructions
GET  HTTP/1.1 302 Found
Location: https://redirect_uri?code=xxx&state=xxx

Step 2 Obtaining the access token

After obtaining the authorization code, the third-party application accesses the following URL, using the authorization code in exchange for obtaining the access token.

  • URL: https://aiot-oauth2.aqara.cn/access_token
  • Request method: HTTP POST (application/x-www-form-urlencoded)
  • Request parameters
Parameter name Is required? Description
client_id Yes Third-party application ID, AppID
client_secret Yes Third-party application key, AppKey
grant_type Yes According to the OAuth 2.0 standard, the value of authorization_code is obtained
code Yes The authorization code obtained during the previous step
redirect_uri Yes The redirect_uri parameter configured in the previous request
  • Return Example (Status Code 200)
{
    "access_token": "xxxxx", 
    "expires_in": 7200, 
    "token_type": "bearer", 
    "openId": "xxx", 
    "refresh_token": "xxxxx", 
    "state": "abcde"
}
  • Return parameter
Parameter name Description
access_token Access token, used to grant third-party applications access to AIOT Open Service credentials
expires_in The remaining time that the access token is valid, in seconds
token_type According to the OAuth 2.0 standard, the value of bearer is obtained
openId Authorized user's unique identifier
refresh_token Refresh token, used to refresh the access token, valid for 30 days
state The value is an arbitrary string, and the authentication server will return the original value in the parameter

Step 3 Refreshing the access token

Since the access token is valid for only 2 hours, the developer needs to use a refresh token to refresh the access token before the access token expires. The recommended refresh interval is 1.5 hours (1 hour and 30 minutes).

  • URL: https://aiot-oauth2.aqara.cn/access_token
  • Request method: HTTP POST (application/x-www-form-urlencoded)
  • Request parameters
Parameter name Is required? Description
client_id Yes Third-party application ID, AppID
client_secret Yes Third-party application key, AppKey
grant_type Yes According to OAuth 2.0 standard, the value of refresh_token is obtained
refresh_token Yes The refresh token obtained during the previous step
  • Return Example (Status Code 200)
{
    "access_token": "xxxxx", 
    "expires_in": 7200, 
    "token_type": "bearer", 
    "openId": "xxx", 
    "refresh_token": "xxxxx", 
    "state": "abcde"
}
  • Return parameter
Parameter name Description
access_token Access token, used to grant third-party applications access to AIOT Open Service credentials
expires_in The remaining time that the access token is valid, in seconds
token_type According to the OAuth 2.0 standard, the value of bearer is obtained
openId Authorized user's unique identifier
refresh_token New refresh token, old refresh token becomes void immediately
state The value is an arbitrary string, and the authentication server will return the original value in the parameter

Note: Please try again if anomalies occur while refreshing the access token!

API call

API call specification

  1. Request URL format: domain name / interface address, such as:https://aiot-open-3rd.aqara.cn/3rd/v1.0/open/device/query
  2. To ensure the security of data transmissions, the API provided by the AIOT Open Cloud Platform transfers data over the HTTPS protocol. The unified domain name of Mainland China is https://aiot-open-3rd.aqara.cn, other area please refer to Country (area code) .
  3. OpenID is a third-party application's unique user identifier. It is the result of encrypting the original AIOT account. Each AIOT user is issued a unique OpenID for each third-party application.
  4. The body of the request and the results returned through the interface using the JSON format.
  5. When querying the device status or controlling the device through the interface, you need to configure the "resource alias" parameter. The values for different resources are different. For information on all resources (alias, value type, meaning, etc.), please visit the AIOT Open Cloud Platform "Application Management -> Resource Authorization" page.
  6. For detailed API definitions of all functions, please visit the "Application Management -> API Access" page in the AIOT Open Cloud Platform.

Call example

you can query the details of a device by calling the interface using the following methods:

  • Request URL:https://aiot-open-3rd.aqara.cn/3rd/v1.0/open/device/query
  • Request mothod: HTTP POST (application/json)
  • Request header example
Key Description (optional)
Appid The application's unique identifier
Sign Signature.
Access-Token Access token obtained via OAuth authorization
Content-Type The result is returned in JSON format,such as:application/json

Note: Make sure the Keys and the corresponding Values are filled in request header. Note that they are case sensitive.

  • Returning results example
  {
    "result": {
        "bindDate": "2017-11-13",
        "chipVersion": "",
        "bindTime": "22:35:18",
        "name": "Bedroom-Motion Sensor",
        "model": "lumi.sensor_motion.xxx",
        "isOnline": 1,
        "firmwareVersion": "1",
        "did": "lumi.xxxxxxxxxxxx",
        "parentId": "lumi.xxxxxxxxxx"
    },
    "code": 0,
    "isBytesData": 0,
    "requestId": "oHjXRsddnm"
  }

Push notification

Developers need to follow these steps to enable the push notification feature if third-party applications need to receive device messages:

  1. Fill in the server configuration;
  2. Authentication service server address;
  3. Subscribe to notification by resource subscribe API;
  4. Implement business logic based on message format.

Special attention should be given to ensure third-party applications receiving notifications must generally return confirmation of recipient in accordance with the provisions of the JSON message format. The format is as follows:

{
    "code": 0|ErrorCode,
    "result": "Custom content"
}

Server configuration

Open the "Application Management -> Push Notification" page, click the "Edit" button on the upper right corner, fill in the configuration information:

  1. URL: The server address, the interface URL used by the third-party server to receive the notification;
  2. Token: arbitrary filled in by the developer, used to generate signatures;
  3. EncodingAESKey: Randomly generated or manually filled in by the developer, will be used to decrypt the message body;
  4. Message encryption and decryption methods: consists of clear text mode, compatibility mode, and secure mode. Changes to the message encryption and decryption mode will take effect immediately. Developers need to be very careful when making modifications.

Detailed descriptions of differences between the message encryption and decryption methods:

  • Plain Text mode: Does not encrypt the message body, low safety factor;
  • Compatibility mode: The message body contains both plaintext and ciphertext to facilitate debugging and maintenance by developers;
  • Safe mode: The message body is pure ciphertext, requires developers to encrypt and decrypt, has a high safety factor.

Note: Presently, only "Safe mode" and "Plain Text mode" are supported. For data security, please use "Safe mode".

Authentication server

Plain Text mode

In plain text mode, the server authentication method is very simple. After the developer saves the server configuration, the AIOT server sends a POST request to the server address (URL) as configured by the developer. The request will carry an "echostr" parameter(JSON format) that consists of a random string. If the third-party server receives the request, please return the "echostr" parameter without any changes to ensure authentication to the server is successful; otherwise, the authentication fails.

Format for sending messages:

{
    "echostr": "jdlfialjf8i"
}

The format for returning messages is as follows:

{
    "code": 0,
    "result": "jdlfialjf8i"
}

Safe mode

Under safe mode, the server authentication method becomes complicated, and similar to the WeChat Public Platform. After the developer saves the server configuration, the AIOT server will send a POST request to the server address (URL) with the following parameters:

  • Token: header signature.
  • EncodingAESKey: AES encryption key (Base64 processing)
  • echostr: random string

Encrypt and decrypt of request body:

public static String encrypt(String src, byte[] key) throws Exception {
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    AlgorithmParameterSpec params = new IvParameterSpec(IV);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, params);
    byte[] content = src.getBytes("utf-8");
    byte[] ret = cipher.doFinal(content);
    return Base64.getEncoder().encodeToString(ret);
}

public static byte[] decrypt(String src, byte[] key) throws Exception {
    byte[] srcByte = Base64.getDecoder().decode(src);
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    AlgorithmParameterSpec params = new IvParameterSpec(IV);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, params);
    byte[] ret = cipher.doFinal(srcByte);
    return ret;
}

If it is confirmed that the GET request is from the LUMI Server, please return the content of the echostr parameter as it is to confirm authenticating to the server was successful; otherwise, the authentication fails. The process of header signature is as follows:

  1. Arrange the "Appid", "Token", and "Time" parameters in dictionary order, then splice these parameters;

Example: appid=xxx&time=xxx&token=xxx

  1. Splice the EncodingAESKey configured by the developer;

Example: appid=xxx&time=xxx&token=xxx&AESKey

  1. MD5(32-bit) for generated characters and the generated number is the value of Sign(lowercase letter). The developer compares the consistency of the Sign to determine if the request originated from the AIOT server.

Message format

At present, the AIOT Open Cloud Platform supports the following two types of messages:

  • Resource Message: resource change information, such as temperature changes, power changes, etc .
  • Device Messages: Device event messages, such as device on-line/off-line, linking/unlinking, etc.

Resource Message

{
    "msgType": "resource", 
    "data": [
        {
            "time": "1503556533000", 
            "attr": "load_power", 
            "value": "3.93", 
            "did": "lumi.158d00011c1cee",
            "model": "xxxx",
            "attach": "xxx"
        }
    ]
}
Parameters Description
msgType Message type, gets the value of resource
time Timestamps, units: millisecond
attr Resources aliases. Please refer to the "Application Management -> Resource Authorization" page for more details regarding each resource.
value The latest value of resources
did Device ID
attach attachment information

Device Message

{
    "msgType": "device", 
    "data": [{
        "openId": "GoeFrrL7mN9SsGRi8WJn4x4YnQpXTS", 
        "name": "Air Conditioning Controller", 
        "model": "lumi.acpartner.aq1", 
        "time": 1503560767000, 
        "event": "DEV_INFO_CHANGED", 
        "did": "lumi.158d00010b4090", 
        "parentId": ""
    }]
}
Parameters Description
msgType Message type, gets the value of device
openId User ID
name Device Name
model Device Type
time Timestamps, units:millisecond
event Event type, please refer to the detailed parameter description in the following table
did Device ID
parentId Parent device (gateway) ID. If this is a gateway, this field is left blank
Event type Description
GW_BIND Link to Gateway
GW_UN_BIND Unlink Gateway
GW_ONLINE Gateway is on-line
GW_OFFLINE Gateway is off-line
SUB_DEV_BIND Link sub-device to network
SUB_DEV_UN_BIND Unlink sub-device from network
SUB_DEV_ONLINE Sub-device is on-line
SUB_DEV_OFFLINE Sub-device is off-line
DEV_INFO_CHANGED Device name change

Description of Return codes

Each time a third-party application calls an interface, it may get a return code indicating it is correct or incorrect. Developers can debug the interface based on the return code information and troubleshoot the error.

Error Code Description
0 Success
100 Timeout
101 Invalid data package
102 Data package has altered
103 Data package may lose
104 Server busy
105 Data package has expired
106 Invalid sign
107 Illegal appKey
108 Token has expired
109 Token is absence
301 Request path error
302 Params error
303 Request params type error
304 Request method not support
305 Header Params error
701 Position not exist
703 Position name duplication
706 Device permission denied
707 Ifttt permission denied
708 Scene permission denied
713 Position not real position
1003 Resource attr illegal
1005 Resource subscribe not register
1206 Delete local linkage failed
1207 Operation failed
2001 Get developer list error
2002 Appid or Appkey illegal
2003 AuthCode incorrect
2004 AccessToken incorrect
2005 AccessToken expired
2006 RefreshToken incorrect
2007 RefreshToken expired
2008 Permission denied
2009 Invalid OpenId
2010 Unauthorized user
2011 The query result is empty
2012 Invalid apply
2013 Developer Permission denied
2014 Resource Permission denied
2015 subscriber faild

Resource definition

Please go to "resource permission" page to get all resource of cloud development, below is a definition of some special resoures.

Resource: ac_state

Compression mode of air conditioning command (4 bytes): (binary)

|0 1 2 3|4 5 6 7|8 9 10 11|12 13 14 15|16 17 18 19 20 21 22 23|24 25 26 27 28 29 30 31|

Position Data Description
[0 ~3] 0: off; 1: on; 2: toggle; E: circle; F: invalid; else: reserve switch
[4 ~ 7] 0: heat; 1: cool; 2: auto; 3: dry; 4: wind; E: circle; F: invalid; else: reserve mode
[8 ~ 11] 0: low; 1: middle; 2: high; 3: auto; E: circle; F: invalid; else: reserve speed
[12 ~ 13] 0: horizontal; 1: vertical; 2: circle; 3: invalid; wind direction
[14 ~ 15] 0: swing; 1: fix; 2: circle; 3: invalid; sweeping
[16 ~ 23] 0 ~ 240; 243: up; 244: down; FF: invalid temperature
[24] default: 0 extension digit
[25] default: 0 compression code
[26] default: 0 LED display
[27] 0: switch command; 1: non-switching command switch command
[28 ~ 31] 00: stateless; 01: stateful; 02: protocal; 03: recommended scenario; 04: semi-state; 11: ignore air conditioning type

Note:

  • [16-23] The temperature value (0~244) is decimal. If temperature is 25 degrees, then binary is 00011001.
  • The value of "ac_state" must be decimal.
  • Mode, speed and wind direction should not be F(invaild), it will probably control failure because the value cannot be recognized. Before setting the value of ac_state, it is better to query the current value of ac_state by API(/open/resource/query), then change the value according to the requirement.

For example: "open air conditioning, mode is cool, speed is low, wind direction is horizontal, sweeping is swing and temperature is 25 degrees". According to the above-metioned, binary is 00010001000000000001100100000001, convert binary to decimal, then the value of ac_state is “285219073”.