AiCloud 2.0 SDK Development Tutorial
AiCloud 2.0 SDK Development Tutorial
The following code implements the simplest data receiving and sending operation.
void ICACHE_FLASH_ATTR aicloud_receive(const d_object_t *object) { d_object_t *data = aicloud_object_create(); if (aicloud_receive_get(object, "switch")) { os_printf("cloud try get hardware value: switch\r\n"); aicloud_add_int(data, "switch", aicloud_io_get_relay_state()); aicloud_send(data); } if (aicloud_receive_int(object, "switch")) { os_printf("cloud try set hardware int value: switch\r\n"); aicloud_io_set_relay_state( (uint8_t)aicloud_value_int(object, "switch") ); aicloud_io_set_led_state(aicloud_io_get_relay_state()); aicloud_add_int(data, "switch", aicloud_io_get_relay_state()); aicloud_send(data); } aicloud_object_delete(data); os_printf("%s: memory left=%d\r\n", __func__, system_get_free_heap_size()); } void ICACHE_FLASH_ATTR main(void) { aicloud_run(); aicloud_on_receive(aicloud_receive); }
Example of sending data,
d_object_t *data = aicloud_object_create();//Initialize d_object_t object aicloud_add_int(data,"switch",0); //key-value, send data point aicloud_send(data); //Send data points aicloud_object_delete(data); //Destroy objects and release resources
AiCloud structured data object understanding
Introduction to DObject
DObject is a data object of the aicloud cloud platform, including three data operations: report, read, and write.
Smart hardware sending and receiving data to the cloud and APP are all operations on the aicloud data object DObject. The definition of DObject in esp8266 SDK is “d_object_t”.
DObject receiving operation
DObject reception occurs in the “received cloud platform data” callback function, such as the callback function “aicloud_receive(const d_object_t* object)” registered by “aicloud_on_receive”. There are only two types of data received at this time, namely read data request and write data request.
DObject read data request
First, determine whether DObject is a data read request. In the routine, use “if (aicloud_receive_get(object, “switch”)) to determine whether the cloud platform requests to read “switch” data points. If a data read request occurs, the smart hardware needs to report the “switch” data point operation.
DObject read data request
First, determine whether DObject is a data write request. In the routine, use “if (aicloud_receive_set(object, “switch”))” to determine whether the cloud platform requests to write “switch” data points. For convenience, use “if (aicloud_receive_int(object, “switch”))” to determine whether the cloud platform requests to write integer type “switch” data points. If a data write request occurs and the value of the data point changes, the smart hardware needs to report the “switch” data point operation.
DObject sending operation
DObject report data response
If a DObject read data request is received, or the value of a data point changes, a DObject report data response needs to be sent.
d_object_t * data = aicloud_object_create();//First, create a new DObject object. aicloud_add_int(data, "switch", 0); //Then, add the data points that need to be reported. aicloud_add_string(data, "message", "hello world"); aicloud_add_bool(data, "on", true); aicloud_add_double(data, "temp", -3.14159265); aicloud_send(data); //Next, send the DObject object to the cloud. aicloud_object_delete(data); //Finally, release the DObject object.
Timing of DObject reporting data
For example, when the temperature sensor completes temperature reading, when the switch value is changed, or when the cloud requests to read data, the specified data should be reported. The above rules are summarized as follows:
When the cloud requests to read data, the data is reported.
When the data itself changes, the data is reported.
Architecture understanding
The entire aicloud system architecture includes cloud architecture, hardware architecture, APP architecture, and the interconnection relationship between these subsystems. It mainly realizes the connection between devices and the cloud, the connections between devices and the devices, and the connections between devices and users.
The entire aicloud system includes the DOSS system and all users who use the system.
Glossary
Name | Full Name | Description |
aicloud | aicloud | The entire Internet of Things system including DOSS and its users |
DOSS | aicloud operation support system | Contains the cloud composed of DMS and other infrastructure, the hardware of each platform and its firmware, the APP of each platform and their interconnection |
DMS | Equipment Management System | Subsystem for Equipment Management and Operation |
Hardware and cloud WAN communication protocol
The communication between smart hardware and APP is realized through Broker under WAN.
The role of the Broker (message relay) is to aggregate and distribute messages, and realize many-to-many communication through subscription and publication. Broker realizes data transparent transmission in a wide area network (WAN) environment.
Communication model
When a topic (Topic) is subscribed by a subscriber (Subscribe), all messages published (Publish) to this topic will be received by the subscriber. This is the basic message model of this document, the “subscribe-publish” model.
Basic concepts
Chinese | English | Meaning |
Topic | Topic | Message topic, used to centralize or distribute messages. |
Subscribe | Subscribe | Receive messages from a topic. If a message is published to this topic, the subscriber will receive the message. |
Publish | Publish | Publish a message to a topic. All subscribers who subscribe to the topic will receive this message. |
Publish and Subscribe Relationship
The subscribers and publishers involved in this article are divided into the following three categories, namely devices (smart hardware), APP (user equipment) and cloud (server cluster).
Device, APP and cloud subscription release relationship table
Name | Subscribe | Publish |
Device | app2dev/{device_id} | dev2app/{device_id} |
APP | dev2app/{device_id} | app2dev/{device_id} |
Cloud | Key messages to the queue without subscribing to any messages | Publish messages using the rule engine |
Note: All themes are themes with variables, {<variable name>} corresponds to the specific device id
Key word meaning description
Name | Type | Meaning |
app2dev | Constant | Subject: APP to device, APP sends data to device using this channel. |
dev2app | Constant | Subject: Device to APP, the device uses this channel to send data to APP. |
ser2dev | Constant | Subject: Cloud-to-device, cloud-to-device push notifications use this channel. (Reserved) |
dev2ser | Constant | Subject: Device to cloud, the device uses this channel to send messages to the cloud. (Reserved) |
ser2app | Constant | Subject: Cloud to APP, the cloud pushes business messages and upgrade notifications to APP using this channel. (Reserved) |
app2ser | Constant | Subject: APP to cloud, APP sends messages to cloud using this channel. (Reserved) |
{product_id} | Variable | The unique ID of the product, which is generated by the server and never changes. Used to identify a certain type of product. |
{device_id} | Variable | The unique ID of the device, generated by the server, will never change, and it is not allowed to be deleted. Used to identify a certain device under a certain type of product. |
{app_id} | Variable | The unique ID of the application (APP), which is generated by the server and never changes. Used to identify a certain type of application. (Reserved) |
{client_id} | Variable | The ID of the client, which should be as unique as possible. Generated by the client and will remain unchanged for a long time. Used to identify a certain client under a certain application. |
{user_id} | Variable | The unique ID of the user, generated by the server, will never change, and it is not allowed to be deleted. Used to identify a certain user. |
{username} | Variable | The unique name of the user, registered by the user. Used to identify a certain user. |
Communication protocol
MQTT protocol
MQTT (Message Queuing Telemetry Transport) is an instant messaging protocol developed by IBM, currently Device and cloud,
The APP communicates with the cloud using the MQTT protocol through a TLS encrypted channel.
MQTT is a lightweight publish/subscribe protocol, suitable for some harsh environments, low-bandwidth, unreliable or intermittent communication. It is worth mentioning that mqtt provides three different quality message services:
* Qos 0: “At most once”, the news release completely depends on the underlying TCP/IP network. Message loss or duplication can occur. This level can be used in the following situations, the environmental sensor data, it does not matter if you lose a reading record, because there will be a second transmission soon.
* Qos 1: “At least once” to ensure that the message arrives, but message duplication may occur.
* Qos 2: “Only once” to ensure that the message arrives once. This level can be used in situations where, in the billing system, duplicate or missing messages can lead to incorrect results.
MQTT provides a retained message feature. If message retention is enabled when sending a message to a topic, the message will always exist until the server restarts. The old reserved message will be overwritten by the new reserved message. The reserved message will be received immediately when the topic is subscribed, even if the sender is offline.
MQTT provides the offline legacy message (Last Will Testament, LWT) feature, this message will be sent after the broker finds that the device is offline. Once the LWT is set, this message persists until the server restarts.
MQTT Client ID Naming Rules
MQTT broker does not allow clients with the same client_id to log in at the same time, but the same username and password are not affected, and they can log in at the same time. In order to avoid conflicts between clients on multiple platforms and to facilitate statistics, client_id must comply with the following rules
MQTT Client ID naming rule table under different clients
Client | Rules |
Device (smart hardware) | d:{device_id}:{type}:{uuid} |
iOS APP | u:{user_id}:ios:{uuid} |
android APP | u:{user_id}:android:{uuid} |
Web APP | u:{user_id}:web:{uuid} |
WeChat APP | u:{user_id}:wechat:{uuid} |
Precautions:
The uuid should be guaranteed to remain unchanged after the application is installed, and as unique as possible, so that it can be traced back. The length of uuid is 12 characters, which is convenient for analysis and processing by the statistical engine.
The uuid allows a small probability of repetition, so this field is not unique during database design.
It is recommended to convert the unix timestamp*1000+ms value into a hexadecimal string when the app is started for the first time, and then intercept the first 12 bytes. If it is less than 12 bytes, fill it with a random string. (The addition of the millisecond value takes into account that the same user may open more than one APP at the same time in one second. If you use milliseconds, it is difficult to open multiple APPs at the same time in one millisecond, which is difficult for the same user It’s not unique anymore) Save it after the generation is complete, and ensure that it remains unchanged before uninstalling the APP.
Business Process
The APP obtains the online device list of the server, and obtains the current user's bound device information (including {device_id}).
When the user clicks on the remote online device in the device list, the APP starts the deployment process and obtains the basic information necessary to log in to the MQTT broker.
The APP uses the given user name, password and client_id that meets the naming rules to connect to the MQTT broker in the background.
APP subscribes to dev2app/{device_id}, at the same time, APP issues a request to read device data points to app2dev/{device_id}, and then the device reports the information to the APP.
The APP jumps to the interface of the control device and displays the latest status of the device.
The user operates the data point of the device through the control device interface, and the APP issues a request to write the device data point to app2dev/{device_id} to control the device.
After the APP establishes the MQTT connection, if it receives the report device data point message from the device, it updates the information on the UI.
Data Model
JSON data format
The JSON format is a sub-collection of “JavaScript Programming Language, Standard ECMA-262 3rd Edition” in 1999, which is the modern Internet and Internet of Things
One of the data exchange standards. All data in this system uses JSON data format, and the data structure used in this article is based on JSON.
Basic data structure
The basic data structure contains three elements i, d, and t. Where i is the packet sequence number, d is the metadata, and t is the UNIX timestamp.
JSON basic structure root type description
Name | Meaning | Type | Remarks |
i | Data serial number | number(int) | Generated by the sender and increments from 0. Strings cannot be used. The type must be an integer |
d | Data | Object or array | JSON object when the device reports data or APP writes to the device, and JSON array when APP reads the device |
t | UNIX timestamp | number(int) | The UNIX timestamp of the sender, must be UTC time, and the type must be an integer |
1 Data Element i
i is the stream sequence id of each data to confirm the order of the data packets. This field is generated by the sender, starting from 0, and incrementing by 1 every time a packet is sent.
If the receiving end responds to the data packet, the value of i is used as the stream sequence id of the response packet.
Note: i must be strictly a numeric type, not a string type. For example, allowed key-value pairs: “i”: 0, disallowed key-value pairs: “i”:“0”.
2 Data Element d
d is a data carrier, which can be a JSON object or a JSON array.
When d is object:
At this time, d is a JSON object containing a series of key-value combinations of data points. For the type of value, see Data Point Type for details. There are only two cases in its meaning:
If the data is sent by the device, the device is reporting the data.
If the data is sent by the APP, the APP is writing the device data point.
When d is array:
At this time, d is a JSON array containing a string array composed of a series of data point keys.
There is only one case for its meaning:
The data is sent by the APP, which is a request for the APP to read the device data point.
3 Data Element t
t is the UNIX timestamp of the sender, which is used to confirm the time when the data packet is generated for the statistical system.
Note: t must be strictly numeric, not string type. t must be a standard UNIX timestamp in UTC time. When the time stamp error between the device and the APP exceeds 15 minutes, problems may occur in operations involving encryption and authentication.
Data points
1 Basic Concepts
The data point is the basic attribute abstracted from the device and is the smallest control unit for operating the device. The power switch, the temperature value, the displayed text and image can all be independent data points.
2 Data point type
The data point is expressed in data element d, and is included in d in the form of key-value when d is a JSON object. The key is the name of the data point, expressed as a string. Value is the value or content of the data point, and different data point types correspond to different JSON types.
The data points include the following types:
Type | JSON Value Type | Example | Use | Statistics |
Boolean | true, false | “key”:true,”key“:false | Used to represent the switch value | Statistically friendly, time can be used as the x-axis, and the Boolean value is the y-axis to draw the change curve |
Numerical value | number | “key”:100,”key“:- | Used to represent integer and floating-point numbers | Statistically friendly, you can draw a curve with time as the x-axis and value as the y-axis |
Text | string | “key”:“value” | Used to represent text or string | Statistics are not friendly and can be classified |
Binary | array | “key”:[10,255,20] | Used to represent short binary strings | Statistics are not friendly, can be classified |
Multimedia | object | See multimedia type description for details | Used to represent multimedia data | Statistics are not friendly and can be classified |
It is recommended that when designing smart hardware, consider using statistically friendly data types as much as possible so that the statistical engine can process it.
Boolean type
The Boolean type has only two values, true and false, which has the highest processing efficiency and is statistically friendly. Assuming that ture is 1, and false is 0, time can be used as the x-axis, and the Boolean value can be drawn on the y-axis.
Boolean format example
{ "key":true }
Numeric Type
Numerical types combine integer (int) and floating-point (float) types, which are statistically friendly. The time can be the x-axis and the value can be the y-axis to draw the change curve.
The representation of numbers is similar to most other programming languages. A number includes an integer component that may have a negative sign, and it may be followed by a decimal part or an exponent part. Octal and hexadecimal forms are not allowed. Preceded by 0 is also forbidden. The decimal part is a decimal point followed by one or more Arabic numerals. The exponent part starts with an uppercase or lowercase E, which can be followed by a plus/minus sign. Followed by one or more Arabic numerals. Numeric values cannot be expressed as a sequence of Arabic numerals (such as Infinity and Nan are not allowed).
Example of numeric type format
{ "key":123 }
Text Type
The text type is used to represent text content with a length of less than 128 bytes. If the transmitted text content can be divided into several categories, classification statistics can be performed. Use filtering keywords, support vector machines (SVM) or artificial neural networks and other data mining and machine learning methods to classify text.
Text type format example
{ "key":"value" }
Binary Type
The binary type is used to represent a binary string with a length of less than 128 bytes. If the transmitted binary string can be divided into several categories, classification statistics can be performed. The key binary string can be pre-designated for matching classification. Binary string is a data type that is difficult to perform statistics. It is recommended to use statistically friendly data types to replace it when conditions permit.
The binary type is represented by a JSON array. The elements of the array must be of type number. The range of number is a decimal integer from 0 to 255. Octal and hexadecimal forms are not allowed. Preceded by 0 is also forbidden. Each byte of the binary stream must be converted to a value in the range of 0 to 255 in decimal before it can be used as an element of the JSON array.
Binary type format example
{ "key":[10,255,20] }
Multimedia Type
The multimedia type is a JSON object that contains the type name and URI reference. Multimedia types can represent long binary streams such as images, audio, video, and files. After the hardware or APP receives the object of the multimedia type, it needs to interpret the type, and if it is a supported type, it will parse the URI content. The URI can point to a file stream, RTMP video stream, Websocket, or other custom protocols to expand data types.
Among them, the type name is used to indicate the type of resource. URI is used to indicate the location of the resource.
The URI should satisfy RFC3986.
Multimedia type format description
Name | Meaning | Type | Remarks |
type | Data type | string | Represents the type of multimedia reference, such as mp3, jpg, mp4, dat, etc. |
uri | Reference address | string | Represents the quoted multimedia data stream address, the user needs to use his own program to handle the address |
Examples of multimedia types
{"key":{ "type":"mp3", "uri":"http://www.aicloud.com/demo.mp3"}}
Request type
read
When the APP needs to read the content of the device data point, it should send a read request to the device. After receiving the read request, the device reports the requested data point data.
When APP reads the device, the type of d is a JSON array containing the names of data points, and each element of the array is of type String. After the device receives the request, the report APP needs to read
The parameter of the data point taken. If the JSON array is empty, the device will not report any data.
Example of APP reading smart socket switch data point
{ "i":1, "d":["switch"], "t":1464714257 }
Example of reading smart light r, g, b, cw, iw data points by APP
{ "i":2, "d":["switch","r","g","b","cw","iw"], "t":1464714257 }
write
When the APP needs to set the device data point content, it should send a write request to the device. After receiving the write request, the device performs related control operations. After the execution is completed, the device reports the data of the changed data point.
When APP writes to the device, the type of d is a JSON object containing data point setting information. All setting information is in the form of “key”:value. After the device receives the request, it performs the corresponding operation according to the actual situation. If the JSON object is an empty object, the device does not perform any operation. If the key does not exist, the device does not perform any operation.
Example of APP writing smart socket switch data point
{ "i":3, "d":{ "switch":1 }, "t":1464714257 }
APP write smart light r, g, b, cw, iw data point example
{ "i":4, "d":{ "switch":1, "r":255, "g":255, "b":255, "cw":255, "iw":255 }, "t":1464714257 }
Explanation of different white lights
Keywords | English | Chinese | Color temperature |
CW | Cool White | Cool White | 7000K |
DW | Daylight White | Daylight White | 6000K |
NW | Nature White | Natural White | 4000K |
IW | Incand White | Sunlight | 2700K |
Report
When the data point of the device changes due to environmental or human factors, the changed data point data is reported. This situation includes, but is not limited to, environmental changes, physical switch changes, and changes caused by APP writing data points.
When the device reports data, the type of d is a JSON object that contains the status information of the data point. All status information is in the form of “key”:value.
Example of smart socket reporting status
{ "i":3, "d":{ "switch":1 }, "t":1464714257 }
Example of smart light reporting status
{ "i":4, "d":{ "switch":1, "r":255, "g":255, "b":255, "cw":255, "iw":255 }, "t":1464714257 }
Hardware and APP LAN communication protocol
The communication between intelligent hardware and APP is realized through UDP and TCP protocols under the local area network.
Since UDP and TCP have complementary features, the following two methods are used to realize the communication between APP and hardware in the LAN.
UDP socket
Advantages: It supports broadcast and multicast features and is a connectionless communication method.
Disadvantages: Encryption is not supported, and reliable arrival of packets is not guaranteed (maybe heavy packets or packet loss).
Scope of application: Suitable for network discovery and simple communication between smart hardware and APP in the local area network.
TCP socket
Advantages: Support TLS encryption, ensure that the packet arrives and arrive only once, and it is a connected communication method. Disadvantages: Broadcasting is not supported, and the number of allowed APP connections is limited by smart hardware RAM.
Scope of application: It is suitable for complex communication between smart hardware and APP in the local area network, such as APP controlling smart hardware.
Business Process
Communication flow
*1. Device access to the network
When using the device for the first time, you need to connect the device to the wireless LAN. Set the current user's Wi-Fi SSID and password for the device, so that the device can join the corresponding Wi-Fi. The main ways for the device to access the network are:
Smart Connect
Through smartconfig/esptouch/airkiss and other technologies, it is simple and easy to configure the device to connect to the network under the condition that the user does not use it to switch back to Wi-Fi.
AP distribution network
The user connects to the Wi-Fi AP released by the device and sends the configuration information directly to the device. The APP needs to process the AP configuration success package.
Web distribution network
The user connects to the Wi-Fi AP released by the device, opens the web page through the browser, and sends the configuration information to the device.
Sound distribution network
The device requires special hardware support. The user configures the device to connect to the network by operating the APP to make the speaker emit a sound containing the code.
NFC Distribution Network
The device requires special hardware support. The user sends the configuration information to the device through the NFC function of the mobile phone.
Bluetooth distribution network
The device requires special hardware support. The user sends the configuration information to the device through the Bluetooth function of the mobile phone.
*2. Discover the device
Before APP can perform any operation on the unbound devices in the LAN, the device needs to be discovered first.
When the APP side opens the device list page, the APP sends a specific UDP broadcast packet to the LAN, once per second. At the same time, the APP continuously monitors the UDP packets sent by the devices in the LAN.
After receiving this packet, the device in the local area network responds with a UDP data packet to the APP, which contains the basic information of the device.
After the APP receives the UDP packet that the device answers, it checks whether the device is a bound device. If yes, set the device online status to LAN online; if not, add it to the list of unbound devices. All lists need to be deduplicated according to the device id.
After the APP receives the device information, it also records the IP address and port number of the device.
The packages that the APP needs to process are: smart connection success package, and device startup success notification package.
*3. Bind device
The user must first bind the device to obtain the operation authority of the device.
The APP initiates a binding request (UDP) to the IP address of the device (obtained from the device discovery process), and sends the timestamp ts to the device.
If the network time is not obtained, this time stamp will be used for time service. If the device has obtained the network time, this timestamp will be ignored.
The device performs authorization verification. If the user sets the device to be bindable, the device responds to the binding request of the APP, which includes the device id, the second-level password of the device,
The access_key of the device (device_access_key) and the timestamp of the device (device_ts ).
The APP needs to use these parameters to initiate a request (#1-2-) to the user binding interface in the cloud to execute the bound business logic.
The time stamp of the device may be different from the time stamp of the APP, but the difference of more than 15 minutes may cause the binding failure.
*4. Connect the device (Wide area network control does not have this step)
After the binding is successful, the APP can initiate a TCP connection to the device in the local area network to log in and control the device. If the device is disconnected directly, it is possible that the number of APPs connected to the device has reached the upper limit, and the APP should be converted to WAN connection mode.
*5. Log in to the device (Wide area network control does not have this step)
After the APP successfully establishes a TCP connection with the device, the APP initiates a login request to the device. When logging in, the APP is required to send the time stamp of the APP, the device id and the second-level password of the device. If the login fails, the device will disconnect directly.
*6. Control equipment
After the APP successfully logs in to the device, the APP can send control instructions to the device and receive the data reported by the device. If there is no communication with the device for 30 seconds, you need to send a heartbeat packet to maintain the connection. When receiving the heartbeat packet sent by the device, it needs to respond to the heartbeat packet immediately.
Security Policy
*1. Binding device security policy
Smart hardware can be bound by a physical switch or a logical switch. It may be determined by physical buttons, toggle switches, timers in the device, or virtual switches on the APP. When the device is in a bindable state, the device responds to the binding request of the APP. When the device is in the unbinding state, the device will not respond to the binding request of the APP.
*2. Connected device security policy
After a successful connection, a request to log in to the device must be initiated within 3 seconds, otherwise the connection will be disconnected by the device. If the connection fails repeatedly in a short time for more than a certain number of times, the device will be in the attack protection mode during this period and all connections to the local LAN will be rejected.
*3. Login device security policy
The login must be completed within 3 seconds from the connection, and requires the APP to send the time stamp of the APP, the device id and the second-level password of the device. If the login fails, the device will disconnect directly. When the time stamp of the APP differs from the time stamp of the device by more than 15 minutes, the login fails.
*4. Control equipment security policy
If the APP fails to log in to the device and sends a device control request, the device will immediately disconnect from the APP. When and only after the APP successfully logs in to the device, it can send control instructions to the device and receive the data reported by the device. If the device does not receive any data (including heartbeat packets) sent by the APP for 60 seconds, the device will disconnect from the APP.
Data Frame
A complete data frame includes a fixed-length data header and a variable-length data body.
Fixed-length data header | Variable-length data body |
28 Bytes | sizeof(body) Bytes |
The fixed-length data header has a constant length of 28 bytes and contains 7 uint32_t values.
magic | type | body_length | command | sequence | checksum | flag |
4 Bytes | 4 Bytes | 4 Bytes | 4 Bytes | 4 Bytes | 4 Bytes | 4 Bytes |
The C language structure of the fixed-length data header is defined as follows
//Fixed length data header typedef struct DataHead_t { uint32_t magic; // Magic Code (magic number), always equal to 0xAA33CC55 uint32_t type; // Data frame body type, default is 1 (JSON) uint32_t body_length; // data body length (excluding data header) uint32_t command; // Command, which indicates the operation performed by the data frame uint32_t sequence; // Request packet serial number, increment, return uint32_t checksum; // package body check, reserved uint32_t flag; // Some flags of the request package, reserved } __attribute__((aligned(1), packed)) DataHead_t;
Variable length data body
The variable-length data body is currently in JSON format, and its length must be equal to the length defined in the fixed-length data header.
LAN port definition
Listening port
Type | Role | UDP Port | TCP Port |
Equipment | Server | 12476 | 12518 |
APP | Client | 12517 | Random |
Note: The device and APP use random sending ports (the purpose is to reduce the possibility of port conflicts between applications) and fixed listening ports.
UDP service
SoftAP mode Wi-Fi distribution network
Before the smart hardware joins a Wi-Fi LAN, it must obtain the basic information of the Wi-Fi LAN, such as the SSID and password.
SoftAP Wi-Fi configuration means that the smart hardware releases its own Wi-Fi hotspot. After the mobile APP connects to this hotspot, the APP sends the connected Wi-Fi configuration information to the smart hardware via UDP broadcast. After the smart hardware receives the information, it connects to the Wi-Fi LAN to be connected and disconnects the Wi-Fi connection of the current mobile phone APP.
Request
Data header parameters
Way | Direction | Command | Data Type |
UDP broadcast | APP to device | 2001 | JSON |
Data body example
SoftAP mode Wi-Fi configuration request
{ "ssid": "Wi-Fi_Name", "password": "Wi-Fi_Password" }
Answer
Data header parameters
Way | Direction | Command | Data Type |
UDP Unicast | Device to APP | 3001 | JSON |
Data body example
SoftAP mode Wi-Fi distribution network response
{ "product_id": "pnTSD3ZsRNVgvNn6YRC2Z5", "device_id": "JiEbsXMdn2W5uZtMm6fmr6", "mac": "001122334455" }
Note: If the device completes the cloud registration without mass production test, the device will not respond to the request because the device has not obtained the device ID.
Smartlink distribution network, Airkiss distribution network or WPS distribution network succeeded
When the device successfully joins the wireless LAN through smart connection, Airkiss or WPS configuration, it will send UDP broadcast to the entire LAN. After receiving this broadcast, all APPs in the local area network can learn that the device configuration is successful.
Answer
Data header parameters
Way | Direction | Command | Data Type |
UDP broadcast | Device to APP | 3002 | JSON |
Data body example
Smartlink distribution network, Airkiss distribution network or WPS distribution network successfully responded
{ "product_id": "pnTSD3ZsRNVgvNn6YRC2Z5", "device_id": "JiEbsXMdn2W5uZtMm6fmr6", "mac": "001122334455" }
Note: If the device completes the cloud registration without mass production test, the device will not send the configuration success packet because the device has not obtained the device ID.
The device successfully joined the Wi-Fi LAN
When the network is interrupted due to sudden power failure or Wi-Fi interference, and the device rejoins the Wi-Fi LAN, it will send a broadcast of successful device access. When the APP in the LAN receives this broadcast, it will add this device to the unbound device list or the LAN online device list.
Answer
Data header parameters
Way | Direction | Command | Data Type |
UDP broadcast | Device to APP | 3003 | JSON |
Data body example
The device joins the Wi-Fi LAN successfully answered
{ "product_id": "pnTSD3ZsRNVgvNn6YRC2Z5", "device_id": "JiEbsXMdn2W5uZtMm6fmr6", "mac": "001122334455" }
Note: If the device has not completed the cloud registration without mass production test, the device cannot be discovered.
Bind device
Users must establish a binding relationship with the device before they can control the device. When binding the device, the APP uses the UDP protocol to send a binding request packet to the IP address where the device is located. If the device is in a bindable state, the device will send a binding response packet to the IP address where the APP is located. If the device is in an unbinding state, the device will ignore the binding request of the APP. The binding response packet contains the device ID, device password, and other device information related to binding. After receiving the binding information, the APP initiates a binding request to the cloud, and the cloud completes the binding operation. After the binding is successful, the APP should refresh the device list from the cloud, and the user clicks on the online device entry in the list to complete the Broker deployment and jump to the APP control device interface.
Whether a device can be bound is generally determined by the physical switches, buttons, timers, or logical switches on the device, and the device can be bound to the user after authorization by the user (for example, pressing a certain button). For devices without physical buttons such as bulb lights, they can be bound by default, unless the user disables the binding function of the device in the APP (controls a logical switch in the device, such as binding switch data points).
request
Data header parameters
Way | Direction | Command | Data Type |
UDP unicast | APP to device | 2005 | JSON |
Data body example The binding device request sent by the APP
{ "ts": 1465541792 }
answer
Data header parameters
Way | Direction | Command | Data Type |
UDP Unicast | Device to APP | 3005 | JSON |
Data body example
Bound device response sent by the device
{ "device_id":"JiEbsXMdn2W5uZtMm6fmr6", "password":"0a1704dee5ed7200fcea5f627f6d1fd1", "access_key":"8e0bb23839955bde1346b6e9395347ff", "ts":1465541793 }
Note: If the device has not completed the cloud registration without mass production test, the device cannot be bound.
TCP service
Login device
Before performing any operations (including sending control commands or receiving data reports), you must first log in to the device, otherwise the device will immediately disconnect the TCP connection.
The signature must be calculated according to the timestamp before logging in to the device ( signature ), after the calculation, the timestamp and signature are sent to the device for verification, and the signature algorithm sees the hardware TCPLogin signature policy, the following is an example.
Request
Data header parameters
Way | Direction | Command | Data Type |
TCP | APP to device | 2101 | JSON |
Example of data body Login device request sent by APP
{ "signature":"0a1704dee5ed7200fcea5f627f6d1fd1", "ts":1465541793 }
Answer
Data header parameters
Way | Direction | Command | Data Type |
TCP | Device to APP | 3101 | JSON |
Data body example Successful login response sent by the device
{ "success": true } Login failure response sent by the device <code c> { "success": false, "error_code": 1001, "message": "SIGNATURE INCORRECT" }
Note that if the login fails or the login is not completed within 1500ms after the connection, the device will disconnect the TCP connection.
TCP Heartbeat
When there is no communication between the APP and the device for a long time, the device or the APP needs to send a heartbeat packet to the other party. The heartbeat packet timeout time of APP is generally set to 120s, and the interval for sending heartbeat packets is 50 seconds. When the APP still does not receive the heartbeat packet from the device after the heartbeat packet timeout, the connection between them will be actively disconnected. When the device still does not receive the heartbeat packet of the APP after the heartbeat packet timeout, the device will also actively disconnect. Please note that the heartbeat packet command can only be sent after successfully logging in to the device.
Request
Data header parameters
Way | Direction | Command | Data Type |
TCP | APP to device | 2102 | JSON |
Data body example
Heartbeat packet sent by APP
{ "ts":1465541793 }
Response
Data header parameters
Way | Direction | Command | Data Type |
TCP | Device to APP | 3102 | JSON |
Data body example
Heartbeat packet sent by the device
{ "ts":1465541793 }
Transfer business data
The APP and the device can transmit business data to each other through the transfer of the cloud or the direct connection of the local area network. The specific format of the business data depends on the definition of the actual product, such as the data point structure defined by the manufacturer or the transparent transmission of custom data. Among them, it can be divided into control equipment according to business, reading equipment data and equipment reporting its own data.
For TCP service data format, please refer to Request Type. The data format and request method are the same as WAN communication. The following is an example.
Request
Data header parameters
Way | Direction | Command | Data Type |
TCP | APP to device | 2103 | JSON |
Data body example
Business data sent by APP
{ "i":2, "d":["r","g","b","cw","iw"], "t":1464714257 }
Response
Data header parameters
Way | Direction | Command | Data Type |
TCP | Device to APP | 3103 | JSON |
Data body example
Business data sent by the device
{ "i":4, "d":{ "r":255, "g":255, "b":255, "cw":255, "iw":255 }, "t":1464714257 }
AiCloud SDK interface functions
AiCloud SDK connection API
aicloud_run
Function name | int aicloud_run(void) |
Enter | None |
Return | Return an int, 0 means success, non-zero means failure |
Features | Create aicloud connection tasks, including intranet, WAN, and corresponding network management |
aicloud_on_connected
Function name | void aicloud_on_connected(aicloud_callback_t callback) |
Input | aicloud_callback_t |
Back | None |
Function | Register a user processing function connected to aicloud |
aicloud_on_disconnected
Function name | void aicloud_on_disconnected(aicloud_callback_t callback) |
Input | aicloud_callback_t |
Back | None |
Features | Register a user processing function disconnected from aicloud |
aicloud_on_receive
Function name | void aicloud_on_receive(aicloud_receive_callback_t callback) |
Input | aicloud_receive_callback_t |
Back | None |
Function | Register a user function responsible for receiving processing |
aicloud_on_receive_raw
Function name | void aicloud_on_receive_raw(aicloud_receive_raw_callback_t callback) |
Input | aicloud_receive_raw_callback_t |
Back | None |
Function | Register a user function responsible for receiving raw data processing |
aicloud_on_sent
Function name | void aicloud_on_sent(aicloud_callback_t callback) |
Input | aicloud_callback_t |
Back | None |
Function | Register a user function for sending data processing |
aicloud_send
Function name | bool aicloud_send(const cJSON* object) |
Input | const cJSON* |
Return | Return bool, used to indicate whether the transmission is successful |
Function | Used to send an object in cJSON format |
aicloud_on_state_changed
Function name | void aicloud_on_state_changed(aicloud_state_callback_t callback) |
Input | aicloud_state_callback_t |
Back | None |
Function | Processing function used to register a network status monitor |
aicloud_state
Function name | aicloud_state_t aicloud_state(void) |
Input | void |
Back | aicloud_state_t |
Function | Used to get the connection status with aicloud |
aicloud ESP8266 SDK general API
aicloud_system_recovery
Function name | void aicloud_system_recovery(void) |
Enter | None |
Back | None |
Features | Factory Reset |
aicloud_force_smartlink
Function name | void aicloud_force_smartlink(void) |
Enter | None |
Back | None |
Features | Force to enter smartlink mode |
aicloud_force_aplink
Function name | void aicloud_force_aplink(void) |
Enter | None |
Back | None |
Features | Force into ap mode |
aicloud_set_ssid_prefix
Function name | void aicloud_set_ssid_prefix(const char* sPrefix) |
Input | const char* sPrefix |
Back | None |
Features | Set ap prefix |
aicloud_check_update
Function name | void aicloud_check_update(void) |
Enter | None |
Back | None |
Features | Check firmware update |
aicloud_time_ready
Function name | bool aicloud_time_ready(void) |
Enter | None |
Return | Return bool, whether the time acquisition is successful |
Function | Used to query whether the time is successfully obtained |
aicloud SDK JSON API
aicloud_is_get_object
Function name | bool aicloud_is_get_object(const cJSON* object) |
Input | const cJSON* object a cJSON object |
Return | Return bool, whether it is an array object |
Function | Determine whether the input cJSON object is an array object |
aicloud_is_set_object
Function name | bool aicloud_is_set_object(const cJSON* object) |
Input | const cJSON* object a cJSON object |
Return | Return bool, whether it is an object object |
Function | Determine whether the input cJSON object is an object object |
aicloud_receive_get
Function name | bool aicloud_receive_get(const cJSON *object, const char *key) |
Input | const cJSON* object a cJSON object const char * key a key value key |
Return | Return bool, whether the object (array) object has a key value |
Function | Determine whether the input cJSON (array) object has a key key |
aicloud_receive_set
Function name | bool aicloud_receive_set(const cJSON *object, const char *key) |
Input | const cJSON* object a cJSON object const char * key a key value key |
Return | Return bool, whether the object (object) object has a key value |
Function | Determine whether the input cJSON (object) object has a key key |
aicloud_receive_bool
Function name | bool aicloud_receive_bool(const cJSON *object, const char *key) |
Input | const cJSON* object a cJSON object const char * key a key value key |
Return | Return bool, whether the key value of the object (object) object is bool |
Function | Determine whether the input cJSON (object) object has a key key value is bool |
aicloud_receive_double
Function name | bool aicloud_receive_double(const cJSON *object, const char *key) |
Input | const cJSON* object a cJSON object const char * key a key value key |
Return | Return bool, whether the key value of the object (object) object is double |
Function | Determine whether the input cJSON (object) object has a key key value is double |
aicloud_receive_int
Function name | bool aicloud_receive_int(const cJSON *object, const char *key) |
Input | const cJSON* object a cJSON object const char * key a key value key |
Return | Return bool, whether object (object) object key is int |
Function | Determine whether the input cJSON (object) object has a key key value is int |
aicloud_receive_string
Function name | bool aicloud_receive_string(const cJSON *object, const char *key) |
Input | const cJSON* object a cJSON object const char * key a key value key |
Return | Return bool, whether object (object) object key is string |
Function | Determine whether the input cJSON (object) object has a key and whether the key value is a string |
aicloud_value_bool
Function name | bool aicloud_value_bool(const cJSON *object, const char *key) |
Input | const cJSON* object a cJSON object const char * key a key value key |
Return | Return bool, object(object) object key key value bool value |
Function | Determine whether the input cJSON (object) object has the value of key key bool |
aicloud_value_double
Function name | double aicloud_value_double(const cJSON *object, const char *key) |
Input | const cJSON* object a cJSON object const char * key a key value key |
Return | Return double, object (object) object key key value double value |
Function | Determine whether the input cJSON (object) object has the value of key double |
aicloud_value_int
Function name | int aicloud_value_int(const cJSON *object, const char *key) |
Input | const cJSON* object a cJSON object const char * key a key value key |
Return | Return int, object (object) object key key value int value |
Function | Determine whether the input cJSON (object) object has the value of key key int |
aicloud_value_string
Function name | char *aicloud_value_string(const cJSON *object, const char *key) |
Input | const cJSON* object a cJSON object const char * key a key value key |
Return | Return char*, object (object) object key key value string value |
Function | Determine whether the input cJSON (object) object has the value of key key string |
aicloud_add_bool
Function name | bool aicloud_add_bool(cJSON *object, const char *key, bool value) |
Input | const cJSON* object a cJSON object const char * key a key to compare bool value a bool value to be set |
Return | Return bool, indicating whether the setting is successful |
Function | Set the bool value of the key of the cJSON object |
aicloud_add_double
Function name | bool aicloud=_add_double(cJSON *object, const char *key, double value) |
Input | const cJSON* object a cJSON object const char * key a key to compare double value a double value to be set |
Return | Return bool, indicating whether the setting is successful |
Function | Set the double value of the key of the cJSON object |
aicloud_add_int
Function name | bool aicloud_add_int(cJSON *object, const char *key, int value) |
Input | const cJSON* object a cJSON object const char * key a key to compare int value an int value to be set |
Return | Return bool, indicating whether the setting is successful |
Function | Set the int value of the key key of the cJSON object |
aicloud_add_string
Function name | bool aicloud_add_string(cJSON *object, const char *key, const char* value) |
Input | const cJSON* object a cJSON object \\const char * key a key to compare \\const char value a \\const char value to be set |
Return | Return bool, indicating whether the setting is successful |
Function | Set the const char* value of the key key of the cJSON object |
aicloud_object_create
Function name | cJSON *aicloud_object_create(void) |
Enter | None |
Return | Return cJSON objectobject cJSON object A created cJSON object |
Features | Create a cJSON object |
aicloud_object_delete
Function name | void aicloud_object_delete(cJSON* object) |
Input | const cJSON* object A cJSON object to delete |
Back | None |
Features | Delete a cJSON object |
Cloud to hardware HTTP application interface
Device registration
Request example
curl -X POST -H "Content-Type: application/json" "http://api.vcd.io:4567/v1/device/register accessKey=8e0bb23839955bde1346b6e9 395347ff&signature=e38a3d553bd8f607181c94a64f51eb85&ts=1464714257" -d %%'{%% "productId":"sa4nUnfQisGTZH3EmE8JEE", "mac":"wwwddsads aww2"}'
Return example 200
{ "success": true, "data": { "id": "sa4nUnfQisGTZH3EmE8JEE", "password": "f7ab8e790ee446b102cb70b64b68f7e9" } }
Return example 500
{ "success": false, "errorCode": 500, "message": "Internal error" }
Request parameter
Parameters | Type | Required | Default | Description |
productId | string | yes | none | product id |
mac | string | yes | none | device mac address |
Return parameter
Parameters | Type | Description |
id | string | device id |
password | string | Device password, the password type is First-level password |
Modify device name
Request example
curl -X POST -H "Content-Type: application/json" "http://api.vcd.io:4567/v1/device/deploy accessKey=8e0bb23839955bde1346b6e939 5347ff&ts=1465541792&signature=ad36b179e3d1fb9f8fb368c4b9e99010" -d'{"deviceId "sa4nUnfQisGTZH3EmE8JEE", "deviceName":"bedroom light", "deviceLogo":"http://sss/xxs.jpg"}'
Return example 200
{ "success": true }
Return example 500
{ "success": false, "errorCode": 500, "message": "Internal error" }
Request parameter
Parameters | Type | Required | Default | Description |
deviceId | string | yes | none | device id |
deviceName | string | yes | none | bedroom light |
deviceLogo | string | No | None | Device image logo URL |
Return parameter
Parameters | Type | Description |
None | None | None |
Equipment deployment
Request example
curl -X POST -H "Content-Type: application/json" "http://api.vcd.io:4567/v1/device/deploy accessKey=8e0bb23839955bde1346b6e939 5347ff&ts=1465541792&signature=ad36b179e3d1fb9f8fb368c4b9e99010" -d %%'{% "deviceId":"sa4nUnfQisGTZH3EmE8JEE", "password":"0a1704d ee5ed7200fcea5f627f6d1fd1", "protocol":"mqtts"}'
Return example 200
{ "success": true, "data": { "server": "mqtts://1:8883", "username": "JiEbsXMdn2W5uZtMm6fmr6", "password": "EpGzRRYGu6V3xJxF7VMDZ5", "publicKey": "", "publicKeyVersion": "", "signature": "30210fafc0d640fd4773ca093a478f8c" } }
Return example 500
{ "success": false, "errorCode": 500, "message": "Internal error" }
Request parameter
Parameters | Type | Required | Default | Description |
deviceId | string | yes | none | device id |
password | string | yes | no | device password, the password type is second-level password |
protocol | string | No | mqtts | Device access protocol, optional mqtts, mqtt, wss, ws |
Return parameter
Parameters | Type | Description |
server | string | Device access server |
username | string | Device access user name |
password | string | Device access password, the password type is zero-order password, the password is a random short uuid generated by the server |
publicKey | string | Base64 string of pem key |
publicKeyVersion | string | Current certificate version |
signature | string | Use the same signature strategy to calculate the signature of the return value for client verification (to prevent the risk of DNS hijacking, it is not necessary) |
Device OTA
Request example
curl -X POST -H "Content-Type: application/json" "http://api.vcd.io:4567/v1/device/ota accessKey=8e0bb23839955bde1346b6e939534 7ff&signature=e38a3d553bd8f607181c94a64f51eb85&ts=1464714257" -d'{"deviceId": "sa4nUnfQisGTZH3EmE8JEE", "password":"684b3afe4c ff2f5d9c5e33d019c04048","firmwareId":"sa4nUnfQisGTZH3EmE8JEE","version":""}'
Return example 200
{ "success": true, "data": { "upgrade": true, "version": "", "url": "http://dms.aicloud.com:38080/dms/firmware/download.htm firmwareFileId=sa4nUnfQisGTZH3EmE8JEE", "md5": "" } }
Return example 500
{ "success": false, "errorCode": 500, "message": "Internal error" }
Request parameter
Parameters | Type | Required | Default | Description |
deviceId | string | yes | none | device id |
password | string | yes | no | device password, the password type is second-level password |
firmwareId | string | yes | none | firmware id |
version | string | yes | none | current firmware version number |
Return parameter
Parameters | Type | Description |
upgrade | bool | Need to upgrade |
version | string | The version number of the new firmware |
url | string | The download address of the new firmware |
md5 | string | md5 value of new firmware, user file verification |
1. The download address of the firmware has `Validity Period`, the default is 15 minutes. If the upgrade is not completed within 15 minutes, you need to request this interface or a new download address again. 2. The rule of firmware version number is x.x.x, where x represents a number
Unbind device
The device is unbound and all users bound to the device are unbound.
Request example
curl -X POST -H "Content-Type: application/json" "http://api.vcd.io:4567/v1/device/unbind accessKey=8e0bb23839955bde1346b6e939 5347ff&signature=e38a3d553bd8f607181c94a64f51eb85&ts=1464714257" -d'{"deviceId": "14666251168079293", "password":"684b3afe4cff 2f5d9c5e33d019c04048"}'
Return example 200
{ "success": true, "data": { "result": "SUCCESS" } }
Return example 500
{ "success": false, "errorCode": 500, "message": "Internal error" }
Request parameter
Parameters | Type | Required | Default | Description |
deviceId | string | yes | none | device id |
password | string | yes | none | device password, the password type is second-level password |
Return parameter
Parameters | Type | Description |
result | string | Result |