All Products
Document Center

Device Modelling Programming

Last Updated: May 13, 2020

Device Modelling means to define a product by properties, services and events, a device that supports device modelling may also be referred to as the “Pro Edition.”

Device properties

The SDK provides the option to receive a reply from the cloud when a device reports properties or events. We can use IOT_Ioctl to set the IOTX_IOCTL_RECV_EVENT_REPLY option.

  • Property report description

The following example code describes property reports. /examples/linkkit/linkkit_example_solo.c

You can call the IOT_Linkkit_Report() function to report the properties. When you report the properties, use the JSON encoding according to the property format defined by the cloud. In the example, the user_post_property function shows how to use IOT_Linkkit_Report for property reporting (for reporting exceptions, see the example):

  1. void user_post_property(void)
  2. {
  3. static int example_index = 0;
  4. int res = 0;
  5. user_example_ctx_t *user_example_ctx = user_example_get_ctx();
  6. char *property_payload = "NULL";
  7. ...
  8. ...
  9. /* Normal Example */
  10. property_payload = "{\"LightSwitch\":1}";
  11. example_index++;
  12. ...
  13. ...
  14. res = IOT_Linkkit_Report(user_example_ctx->master_devid, ITM_MSG_POST_PROPERTY,
  15. (unsigned char *)property_payload, strlen(property_payload));
  16. EXAMPLE_TRACE("Post Property Message ID: %d", res);
  17. }

Note: property_payload = “{\”LightSwitch\”:1}” encodes the property as a JSON object.

  • Property setting description

In the example, the device obtains the property value set in the cloud using the callback function user_property_set_event_handler, and reports the data to the cloud as it is. This updates the device property value saved in the device shadow on the cloud, and allows you to process the property value that is received.

Note: This callback function corresponds to the ITE_SERVICE_REQUST event registered using IOT_RegisterCallback when the example is initialized:

  1. static int user_property_set_event_handler(const int devid, const char *request, const int request_len)
  2. {
  3. int res = 0;
  4. user_example_ctx_t *user_example_ctx = user_example_get_ctx();
  5. EXAMPLE_TRACE("Property Set Received, Devid: %d, Request: %s", devid, request);
  6. res = IOT_Linkkit_Report(user_example_ctx->master_devid, ITM_MSG_POST_PROPERTY,
  7. (unsigned char *)request, request_len);
  8. EXAMPLE_TRACE("Post Property Message ID: %d", res);
  9. return 0;
  10. }

Device services

In the device-side example program, when a service call request is received, the following callback function will be invoked:

  1. static int user_service_request_event_handler(const int devid, const char *serviceid, const int serviceid_len,
  2. const char *request, const int request_len,
  3. char **response, int *response_len)
  4. {
  5. int contrastratio = 0, to_cloud = 0;
  6. cJSON *root = NULL, *item_transparency = NULL, *item_from_cloud = NULL;
  7. EXAMPLE_TRACE("Service Request Received, Devid: %d, Service ID: %.*s, Payload: %s", devid, serviceid_len,
  8. serviceid,
  9. request);
  10. /* Parse Root */
  11. root = cJSON_Parse(request);
  12. if (root == NULL || ! cJSON_IsObject(root)) {
  13. EXAMPLE_TRACE("JSON Parse Error");
  14. return -1;
  15. }

Process the received service with the Custom Service ID, assign the value of the service input parameter +1 to the output parameter, and return it to the cloud:

  1. if (strlen("Custom") == serviceid_len && memcmp("Custom", serviceid, serviceid_len) == 0) {
  2. /* Parse Item */
  3. const char *response_fmt = "{\"Contrastratio\":%d}";
  4. item_transparency = cJSON_GetObjectItem(root, "transparency");
  5. if (item_transparency == NULL || ! cJSON_IsNumber(item_transparency)) {
  6. cJSON_Delete(root);
  7. return -1;
  8. }
  9. EXAMPLE_TRACE("transparency: %d", item_transparency->valueint);
  10. contrastratio = item_transparency->valueint + 1;
  11. /* Send Service Response To Cloud */
  12. *response_len = strlen(response_fmt) + 10 + 1;
  13. *response = HAL_Malloc(*response_len);
  14. if (*response == NULL) {
  15. EXAMPLE_TRACE("Memory Not Enough");
  16. return -1;
  17. }
  18. memset(*response, 0, *response_len);
  19. HAL_Snprintf(*response, *response_len, response_fmt, contrastratio);
  20. *response_len = strlen(*response);
  21. } else if (strlen("SyncService") == serviceid_len && memcmp("SyncService", serviceid, serviceid_len) == 0) {
  22. ...
  23. ...
  24. }
  25. cJSON_Delete(root);
  26. return 0;
  27. }

Device events

The example uses IOT_Linkkit_TriggerEvent to report events. It demonstrates how to use IOT_Linkkit_Report to report events (for reporting exceptions, see the example).

  1. void user_post_event(void)
  2. {
  3. static int example_index = 0;
  4. int res = 0;
  5. user_example_ctx_t *user_example_ctx = user_example_get_ctx();
  6. char *event_id = "Error";
  7. char *event_payload = "NULL";
  8. ...
  9. ...
  10. /* Normal Example */
  11. event_payload = "{\"ErrorCode\":0}";
  12. example_index++;
  13. ...
  14. ...
  15. res = IOT_Linkkit_TriggerEvent(user_example_ctx->master_devid, event_id, strlen(event_id),
  16. event_payload, strlen(event_payload));
  17. EXAMPLE_TRACE("Post Event Message ID: %d", res);
  18. }

Format descriptions and examples of the report message

When reporting the properties, the property ID and value are placed in the IOT_Linkkit_Report() payload in JSON format. Format examples for different data types and properties are as follows:

  1. /* Integer data */
  2. char *payload = "{\"Brightness\":50}";
  3. /* Floating-point data reporting */
  4. char *payload = "{\"Temperature\":11.11}";
  5. /* Enumeration data reporting */
  6. char *payload = "{\"WorkMode\":2}";
  7. /* Boolean data reporting. In the TSL definition, the Boolean type is an integer and the value is 0 or 1, which is different from the JSON format integer */
  8. char *payload = "{\"LightSwitch\":1}";
  9. /* String data reporting */
  10. char *payload = "{\"Description\":\"Amazing Example\"}";
  11. /* Time-type data reporting. In the TSL definition, the time type is a string */
  12. char *payload = "{\"Timestamp\":\"1252512000\"}";
  13. /* Composite property reporting. In the TSL definition, the composite property is a JSON object */
  14. char *payload = "{\"RGBColor:{\"Red\":11,\"Green\":22,\"Blue\":33}\"}";
  15. /* Multi-property reporting. If you need to report all the properties and data types mentioned above, simply put them in one JSON object */
  16. char *payload = "{\"Brightness\":50,\"Temperature\":11.11,\"WorkMode\":2,\"LightSwitch\":1,\"Description\":\"Amazing Example\",\"Timestamp\":\"1252512000\",\"RGBColor:{\"Red\":11,\"Green\":22,\"Blue\":33}\"}";
  17. /* After the property payload is ready, use the following API to report it */
  18. IOT_Linkkit_Report(devid, ITM_MSG_POST_PROPERTY, payload, strlen(payload));

The difference between reporting events and properties is that the event ID needs to be extracted and placed in the eventid of IOT_Linkkit_TriggerEvent(). The event report content, namely the output parameters of the event according to the TSL definition, is reported in the same format required for property reporting. The example is as follows:

  1. /* If the Event ID is Error, its output parameter ID is ErrorCode and the data type is enumeration */
  2. char *eventid = "Error";
  3. char *payload = "{\"ErrorCode\":0}";
  4. /* If the Event ID is HeartbeatNotification, it has two output parameters. The first is the Boolean parameter ParkingState, and the second is the floating-point parameter VoltageValue */
  5. char *eventid = "HeartbeatNotification";
  6. char *payload = "{\"ParkingState\":1,\"VoltageValue\":3.0}";
  7. /* After the event payload is ready, use the following API to report it */
  8. IOT_Linkkit_TriggerEvent(devid, event_id, strlen(event_id), payload, strlen(payload));
  9. /* As seen in the above example, when an event has multiple output parameters, the payload format is the same as that of a multi-property report */

List of APIs related to the Device Modelling functions

Function name Description
IOT_Linkkit_Open Creates local resources. Before performing network packet interaction, you need to call this API to obtain a session handle.
IOT_Linkkit_Connect Establishes communication between the master device/gateway and the cloud. Registers the sub-device (if needed) with the cloud, and adds the topology relationship between the master device and the sub-device.
IOT_Linkkit_Yield If the SDK occupies a separate thread, the function only distributes the received network packets to the user’s callback function. Otherwise, it means that the SDK uses the CPU to receive network packets and distribute the messages to the user’s callback function.
IOT_Linkkit_Close If the session handle in the input parameter is the master device/gateway, it closes the network connection and releases all resources occupied by the SDK for this session.
IOT_Linkkit_TriggerEvent Sends event packets to the cloud, such as error code and exception alarm.
IOT_Linkkit_Report Sends upstream packets that do not require cloud service data distribution to the cloud, including property values, device labels, binary data for transparent transmission, and sub-device management.
IOT_Linkkit_Query Sends query packets that require cloud service data distribution to the cloud, including OTA status query, OTA firmware download, sub-device topology query, and NTP time query.
Function Name Description
IOT_RegisterCallback Registers event callback functions for the SDK, such as cloud connection success/failure, property settings/service request arrival, and sub-device management packet reply.
IOT_Ioctl Performs various parameter runtime settings and acquisition for the SDK, as well as acquisition of the running status information. The argument can be any data type.