Quick start

Updated at:

This topic describes how to send and receive messages on an Ubuntu host using MQTT topics or the Thing Specification Language (TSL) model. The Ubuntu host acts as an Internet of Things (IoT) device to demonstrate how a device connects to Alibaba Cloud IoT Platform. This guide uses Link SDK 3.0.1.

Install the local development environment

You can develop on an Ubuntu system.

  1. Install Ubuntu 16.04

    This guide is based on a 64-bit host that runs Ubuntu 16.04. The guide has not been tested on other Linux distributions. To avoid compatibility issues, we recommend that you install the same distribution.

    You can install the 64-bit desktop version of Ubuntu 16.04.x LTS. You can download it from http://releases.ubuntu.com/16.04.

    If you use the Windows operating system, you can install Virtualbox to obtain a Linux development environment. You can download it from https://www.virtualbox.org/wiki/Downloads.

  2. Install required software

    This SDK requires the following tools for development and compilation: make-4.1, git-2.7.4, gcc-5.4.0, gcov-5.4.0, lcov-1.12, bash-4.3.48, tar-1.28, and mingw-5.3.1.

    Run the following command to install the required software:

    $ sudo apt-get install -y build-essential make git gcc
                                

Connect a device by programming with MQTT topics

  1. Create a product and a device

    Log on to the Alibaba Cloud IoT Platform console with your Alibaba Cloud account to create a product. Because you will implement product features directly using MQTT topics, select the Basic Edition when you create the product.

    After you create the product, add a device. IoT Platform then generates identity information for the device.

    If you are not familiar with how to create products in the cloud, see Create a product and a device.

  2. Implement product features

    1. Understand the SDK root directory structure

      After you obtain the Linkkit SDK, the root directory has the following structure:

      $ ls
      certs  config.bat  external_libs  extract.bat  extract.sh  LICENSE  makefile  make.settings  model.json  README.md  src  tools  wrappers
                                      
    2. Configure the SDK

      By default, the TSL model option is enabled in the SDK. This demo uses the Basic Edition. Therefore, you must first disable the TSL model option.

      $ make menuconfig
                                      
    3. Add the device credentials to the sample code

      You can implement the Hardware Abstraction Layer (HAL) functions that are defined in the SDK to obtain the device identity. This topic uses Ubuntu to impersonate an IoT device. In SDK version 3.0.1, open the wrappers/os/ubuntu/HAL_OS_linux.c file. In versions 3.1.0 and 3.2.0, open the src/mqtt/examples/mqtt_example.c file. Edit the following code snippet and add the device identity information that you obtained from IoT Platform:

      • ProductKey: The unique identifier for the product.

      • ProductSecret: The product secret.

      • DeviceName: The unique identifier for the device.

      • DeviceSecret: The device secret.

      #ifdef DYNAMIC_REGISTER
      ...
      ...
      #else
      #ifdef DEVICE_MODEL_ENABLED
      ...
      ...
      #else
      char _product_key[IOTX_PRODUCT_KEY_LEN + 1]       = "xxxx";  /* Replace with your actual product key. */
      char _product_secret[IOTX_PRODUCT_SECRET_LEN + 1] = "yyyy";  /* Replace with your actual product secret. */
      char _device_name[IOTX_DEVICE_NAME_LEN + 1]       = "zzzz";  /* Replace with your actual device name. */
      char _device_secret[IOTX_DEVICE_SECRET_LEN + 1]   = "ssss";  /* Replace with your device secret. */
      #endif
      #endif
                                      
      Note

      In the IoT Platform console, you must set the permissions for the /${productKey}/${deviceName}/get topic to `Subscribe and Publish`. The following code uses this topic.

    4. Initialize and establish a connection

      The following code snippet is from the src/mqtt/examples/mqtt_example.c MQTT connection sample. It shows the device initialization and connection process.

      Customize MQTT parameters.

      iotx_mqtt_param_t       mqtt_params;
      
      memset(&mqtt_params, 0x0, sizeof(mqtt_params));
      
      /* mqtt_params.request_timeout_ms = 2000; */
      /* mqtt_params.clean_session = 0; */
      /* mqtt_params.keepalive_interval_ms = 60000; */
      /* mqtt_params.write_buf_size = 1024; */
      /* mqtt_params.read_buf_size = 1024; */
      mqtt_params.handle_event.h_fp = example_event_handle;
                                      
      Note

      The commented-out lines in the code show the default values for the MQTT configuration. You do not need to assign these values because the SDK automatically fills them in. If you want to change the default connection parameters, you can uncomment the relevant lines and enter new values.

      Establish an MQTT connection with the server.

      pclient = IOT_MQTT_Construct(&mqtt_params);
      if (NULL == pclient) {
          EXAMPLE_TRACE("MQTT construct failed");
          return -1;
      }
                                      
      Note

      Pass the connection parameter struct to the IOT_MQTT_Construct() function. This initiates the MQTT connection. The function returns a handle if the connection succeeds, or null if it fails.

    5. Report data to the cloud

      The sample file defines the following topic.

      /${productKey}/${deviceName}/get
                                      

      The following code snippet shows how to send data to this topic.

      int example_publish(void *handle)
      {
          int             res = 0;
          const char     *fmt = "/%s/%s/get";
          char           *topic = NULL;
          int             topic_len = 0;
          char           *payload = "{\"message\":\"hello!\"}";
      
          topic_len = strlen(fmt) + strlen(DEMO_PRODUCT_KEY) + strlen(DEMO_DEVICE_NAME) + 1;
          topic = HAL_Malloc(topic_len);
          if (topic == NULL) {
              EXAMPLE_TRACE("memory not enough");
              return -1;
          }
          memset(topic, 0, topic_len);
          HAL_Snprintf(topic, topic_len, fmt, DEMO_PRODUCT_KEY, DEMO_DEVICE_NAME);
      
          res = IOT_MQTT_Publish_Simple(0, topic, IOTX_MQTT_QOS0, payload, strlen(payload));
                                      
      Note

      For the first parameter of IOT_MQTT_Publish_Simple(), you can use the handle that is returned by the previous call to IOT_MQTT_Construct(). You can also use 0. A value of 0 indicates that the SDK uses the current, single, and established MQTT connection to send the message.

    6. Subscribe to and process data from the cloud

      Note

      To keep the publish/subscribe demo simple, the sample code subscribes to the /${productKey}/${deviceName}/get topic. This means that data sent from the device to IoT Platform is then sent back to the device by IoT Platform.

      The following code subscribes to the specified topic and defines a handler function for the received data.

      res = example_subscribe(pclient);
      if (res < 0) {
          IOT_MQTT_Destroy(&pclient);
          return -1;
      }
      
      ...
      ...
      
      int example_subscribe(void *handle)
      {
          ...
          res = IOT_MQTT_Subscribe(handle, topic, IOTX_MQTT_QOS0, example_message_arrive, NULL);
          ...
                                      
      Note

      For the first parameter of IOT_MQTT_Subscribe(), you can use the handle that is returned by the previous call to IOT_MQTT_Construct(). You can also use 0. A value of 0 indicates that the SDK uses the current, single, and established MQTT connection to subscribe to the topic.

      In the sample program, when a message is received from the cloud, the callback function only prints the message.

      void example_message_arrive(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg)
      {
          iotx_mqtt_topic_info_t     *topic_info = (iotx_mqtt_topic_info_pt) msg->msg;
      
          switch (msg->event_type) {
              case IOTX_MQTT_EVENT_PUBLISH_RECEIVED:
                  /* Print the topic name and topic message. */
                  EXAMPLE_TRACE("Message Arrived:");
                  EXAMPLE_TRACE("Topic  : %.*s", topic_info->topic_len, topic_info->ptopic);
                  EXAMPLE_TRACE("Payload: %.*s", topic_info->payload_len, topic_info->payload);
                  EXAMPLE_TRACE("\n");
                  break;
              default:
                  break;
          }
      }
                                      

      The sample code periodically sends data to this topic. When you implement your own product logic, you do not need to periodically send data. You can send data only when you need to report it.

      while (1) {
          if (0 == loop_cnt % 20) {
              example_publish(pclient);
          }
      
          IOT_MQTT_Yield(pclient, 200);
      
          loop_cnt += 1;
      }
                                      
    7. Compile the sample program

      Run the following commands in the SDK root directory:

      make distclean
      make
                                      

      Note: Each time you run the `make` command in the root directory, code is automatically generated in the `output/` folder. If you have modified the code in the `output/` folder, you must back it up first.

      After the compilation is successful, the sample program is generated in the output/release/bin directory:

      $ tree output/release
      output/release/
      +-- bin
      ...
      ...
      |   +-- mqtt-example
      ...
      ...
                                      
  3. Monitor the data

    Run the following command:

    $ ./output/release/bin/mqtt-example
                            

    In the IoT Platform console, you can find your product and view the messages that are reported by the device in Simple Log Service. For more information, see View device data.

    In the Linux console, you can also see the data from the cloud that is printed by the sample program:

    example_message_arrive|031 :: Message Arrived:
    example_message_arrive|032 :: Topic  : /a1MZxO*****/test_01/get
    example_message_arrive|033 :: Payload: {"message":"hello!"}
    example_message_arrive|034 ::
                            

Connect a device by programming with the TSL model

  1. Create a product and a device

    You can create products in Alibaba Cloud IoT Platform and in the various industry services that it supports.

    The TSL model for this sample product is in the model_for_examples.JSON file, located in the ./src/dev_model/examples/ directory. To simplify the setup, you can import this model. First, create your product in the IoT Platform console. Then, in the `model_for_examples.JSON` file, replace the productkey placeholder with your product's productKey. In the console, go to the Product Details page and select the Feature Definition tab. Click Import TSL Model and select the JSON file. Your product will then have all the TSL model definitions from the sample.

  2. Implement product features

    1. Add the device identity information to the sample code.

      The device identity information is returned to the SDK through HAL calls. Because this guide is based on Linux, the relevant HAL implementation is in the wrappers/os/ubuntu/HAL_OS_linux.c file. You must replace the device identity information in the file with the information for your device.

      #ifdef DEVICE_MODEL_ENABLED
      char _product_key[IOTX_PRODUCT_KEY_LEN + 1]       = "a1RIsMLz2BJ";
      char _product_secret[IOTX_PRODUCT_SECRET_LEN + 1] = "fSAF0hle6xL0oRWd";
      char _device_name[IOTX_DEVICE_NAME_LEN + 1]       = "example1";
      char _device_secret[IOTX_DEVICE_SECRET_LEN + 1]   = "RDXf67itLqZCwdMCRrw0N5FHbv5D7jrE";
      
                                      
      Note

      Instead of modifying these global variables, you can directly modify functions, such as HAL_GetProductKey(), to return the device identity information.

    2. Compile and run the program.

      Run the following commands in the SDK root directory.

      $ make distclean
      $ make
                                      

      After the compilation is successful, the Premium Edition sample program, named linkkit-example-solo, is generated in the output/release/bin directory.

      Run the following command in the SDK root directory.

      $ ./output/release/bin/linkkit-example-solo
                                      
  3. Monitor the data

    The sample program periodically reports the value of the Counter property to the cloud. You can view the received property in the cloud. You can also configure this property as read/write, set it in the cloud, and then check the Counter value that is reported from the device again.

    • Property reporting

      The sample uses __user_post_property__ as an example of how to report a property. This sample loops through and reports various payload scenarios. You can observe the messages that are returned when an incorrect payload is reported.

      The following snippet shows the code for reporting a property.

      /* Post  Property Example */
      if (time_now_sec % 11 == 0 && user_master_dev_available()) {
          user_post_property();
      }
                                      

      Observe the sample function for property reporting.

      void user_post_property(void)
      {
          static int example_index = 0;
          int res = 0;
          user_example_ctx_t *user_example_ctx = user_example_get_ctx();
          char *property_payload = "NULL";
      
          if (example_index == 0) {
                                      

      Normal property reporting scenario.

      void user_post_property(void)
      {
          static int cnt = 0;
          int res = 0;
      
          char property_payload[30] = {0};
          HAL_Snprintf(property_payload, sizeof(property_payload), "{\"Counter\": %d}", cnt++);
      
          res = IOT_Linkkit_Report(EXAMPLE_MASTER_DEVID, ITM_MSG_POST_PROPERTY,
                                   (unsigned char *)property_payload, strlen(property_payload));
      
          EXAMPLE_TRACE("Post Property Message ID: %d", res);
      }
                                      

      The following log shows a normal property report.

      [inf] dm_msg_request(205): DM Send Message, URI: /sys/a1X2bEnP82z/test_06/thing/event/property/post, Payload: {"id":"2","version":"1.0","params":{"LightSwitch":1},"method":"thing.event.property.post"}
      [inf] MQTTPublish(2546): Upstream Topic: '/sys/a1X2bEnP82z/test_06/thing/event/property/post'
                                      

      This is the message sent to the cloud.

      > {
      >     "id": "2",
      >     "version": "1.0",
      >     "params": {
      >         "Counter": 1
      >     },
      >     "method": "thing.event.property.post"
      > }
                                      

      This is the acknowledgement received from the cloud.

      < {
      <     "code": 200,
      <     "data": {
      <     },
      <     "id": "1",
      <     "message": "success",
      <     "method": "thing.event.property.post",
      <     "version": "1.0"
      < }
                                      

      This is the log from the user callback function.

      user_report_reply_event_handler.314: Message Post Reply Received, Devid: 0, Message ID: 2, Code: 200, Reply: {}
                                      
    • Property setting

      When a property set request is received, the following callback function is entered.

      static int user_property_set_event_handler(const int devid, const char *request, const int request_len)
      {
          int res = 0;
          user_example_ctx_t *user_example_ctx = user_example_get_ctx();
          EXAMPLE_TRACE("Property Set Received, Devid: %d, Request: %s", devid, request);
                                      

      Send the result of the property setting back to the cloud to update the device property in the cloud.

          res = IOT_Linkkit_Report(user_example_ctx->master_devid, ITM_MSG_POST_PROPERTY,
                                  (unsigned char *)request, request_len);
          EXAMPLE_TRACE("Post Property Message ID: %d", res);
      
          return 0;
      }
                                      

      The log shows the property setting message from the server-side.

      [dbg] iotx_mc_cycle(1774): PUBLISH
      [inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/service/property/set'
      [inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:
                                      

      This is the content of the property setting message received from the cloud.

      < {
      <     "method": "thing.service.property.set",
      <     "id": "161430786",
      <     "params": {
      <         "LightSwitch": 1
      <     },
      <     "version": "1.0.0"
      < }
                                      

      This is the acknowledgement message sent back to the cloud.

      > {
      >     "id": "161430786",
      >     "code": 200,
      >     "data": {
      >     }
      > }
      
      [inf] dm_client_publish(106): Publish Result: 0
      [inf] _iotx_linkkit_event_callback(219): Receive Message Type: 15
      [inf] _iotx_linkkit_event_callback(221): Receive Message: {"devid":0,"payload":{"LightSwitch":1}}
      [dbg] _iotx_linkkit_event_callback(339): Current Devid: 0
      [dbg] _iotx_linkkit_event_callback(340): Current Payload: {"LightSwitch":1}
                                      

      This is the log from the user_property_set_event_handler() sample callback function when a property setting is received.

      user_property_set_event_handler.160: Property Set Received, Devid: 0, Request: {"LightSwitch":1}
                                      

      A command to set a property from the server has now reached and been executed on the device.

      This is the final acknowledgement received for the property report.

      < {
      <     "code": 200,
      <     "data": {
      <     },
      <     "id": "2",
      <     "message": "success",
      <     "method": "thing.event.property.post",
      <     "version": "1.0"
      < }
      
      [dbg] iotx_mc_handle_recv_PUBLISH(1555):         Packet Ident : 00000000
      [dbg] iotx_mc_handle_recv_PUBLISH(1556):         Topic Length : 60
      [dbg] iotx_mc_handle_recv_PUBLISH(1560):           Topic Name : /sys/a1csED27mp7/AdvExample1/thing/event/property/post_reply
      [dbg] iotx_mc_handle_recv_PUBLISH(1563):     Payload Len/Room : 104 / 4935
      [dbg] iotx_mc_handle_recv_PUBLISH(1564):       Receive Buflen : 5000
      [dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...
      [dbg] iotx_mc_deliver_message(1291): topic be matched
      [inf] dm_msg_proc_thing_event_post_reply(258): Event Id: property
      [dbg] dm_msg_response_parse(167): Current Request Message ID: 2
      [dbg] dm_msg_response_parse(168): Current Request Message Code: 200
      [dbg] dm_msg_response_parse(169): Current Request Message Data: {}
      [dbg] dm_msg_response_parse(174): Current Request Message Desc: success
      [dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50
      [dbg] dm_msg_cache_remove(142): Remove Message ID: 2
      [inf] _iotx_linkkit_event_callback(219): Receive Message Type: 30
      [inf] _iotx_linkkit_event_callback(221): Receive Message: {"id":2,"code":200,"devid":0,"payload":{}}
      [dbg] _iotx_linkkit_event_callback(476): Current Id: 2
      [dbg] _iotx_linkkit_event_callback(477): Current Code: 200
      [dbg] _iotx_linkkit_event_callback(478): Current Devid: 0
      user_report_reply_event_handler.300: Message Post Reply Received, Devid: 0, Message ID: 2, Code: 200, Reply: {}
                                      
      Note

      When a real product receives a property setting, it must parse the property and process it accordingly, instead of just sending the value back to the cloud.

    • Event reporting

      The sample uses IOT_Linkkit_TriggerEvent to report an event. This sample loops through and reports various payload scenarios. You can observe the messages that are returned when an incorrect payload is reported.

      Normal event reporting scenario.

      void user_post_event(void)
      {
          int res = 0;
          char *event_id = "HardwareError";
          char *event_payload = "{\"ErrorCode\": 0}";
      
          res = IOT_Linkkit_TriggerEvent(EXAMPLE_MASTER_DEVID, event_id, strlen(event_id),
                                         event_payload, strlen(event_payload));
          EXAMPLE_TRACE("Post Event Message ID: %d", res);
      }
                                      

      In the sample program, the Error event is reported approximately every 10 seconds and cycles through the described scenarios. The following log shows a normal report.

      [inf] dm_msg_request(218): DM Send Message, URI: /sys/a1csED27mp7/AdvExample1/thing/event/HardwareError/post, Payload: {"id":"1","version":"1.0","params":{"ErrorCode":0},"method":"thing.event.HardwareError.post"}
      [dbg] MQTTPublish(319): ALLOC: (136) / [200] @ 0x1195150
      [inf] MQTTPublish(378): Upstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/HardwareError/post'
      [inf] MQTTPublish(379): Upstream Payload:
                                      

      This is the content and log of the event message reported to the cloud.

      > {
      >     "id": "1",
      >     "version": "1.0",
      >     "params": {
      >         "ErrorCode": 0
      >     },
      >     "method": "thing.event.HardwareError.post"
      > }
      
      [inf] dm_client_publish(106): Publish Result: 0
      [dbg] alcs_observe_notify(105): payload:{"id":"1","version":"1.0","params":{"ErrorCode":0},"method":"thing.event.Error.post"}
      [inf] dm_server_send(76): Send Observe Notify Result 0
      [dbg] dm_msg_cache_insert(79): dmc list size: 0
      user_post_event.470: Post Event Message ID: 1
      [dbg] iotx_mc_cycle(1774): PUBLISH
      [inf] iotx_mc_handle_recv_PUBLISH(1549): Downstream Topic: '/sys/a1csED27mp7/AdvExample1/thing/event/HardwareError/post_reply'
      [inf] iotx_mc_handle_recv_PUBLISH(1550): Downstream Payload:
                                      

      This is the content and log of the acknowledgement message received from the cloud.

      < {
      <     "code": 200,
      <     "data": {
      <     },
      <     "id": "1",
      <     "message": "success",
      <     "method": "thing.event.HardwareError.post",
      <     "version": "1.0"
      < }
      
      [dbg] iotx_mc_handle_recv_PUBLISH(1555):         Packet Ident : 00000000
      [dbg] iotx_mc_handle_recv_PUBLISH(1556):         Topic Length : 57
      [dbg] iotx_mc_handle_recv_PUBLISH(1560):           Topic Name : /sys/a1csED27mp7/AdvExample1/thing/event/Error/post_reply
      [dbg] iotx_mc_handle_recv_PUBLISH(1563):     Payload Len/Room : 101 / 4938
      [dbg] iotx_mc_handle_recv_PUBLISH(1564):       Receive Buflen : 5000
      [dbg] iotx_mc_handle_recv_PUBLISH(1575): delivering msg ...
      [dbg] iotx_mc_deliver_message(1291): topic be matched
      [inf] dm_msg_proc_thing_event_post_reply(258): Event Id: Error
      [dbg] dm_msg_response_parse(167): Current Request Message ID: 1
      [dbg] dm_msg_response_parse(168): Current Request Message Code: 200
      [dbg] dm_msg_response_parse(169): Current Request Message Data: {}
      [dbg] dm_msg_response_parse(174): Current Request Message Desc: success
      [dbg] dm_ipc_msg_insert(87): dm msg list size: 0, max size: 50
      [dbg] dm_msg_cache_remove(142): Remove Message ID: 1
      [inf] _iotx_linkkit_event_callback(219): Receive Message Type: 31
      [inf] _iotx_linkkit_event_callback(221): Receive Message: {"id":1,"code":200,"devid":0,"eventid":"Error","payload":"success"}
      [dbg] _iotx_linkkit_event_callback(513): Current Id: 1
      [dbg] _iotx_linkkit_event_callback(514): Current Code: 200
      [dbg] _iotx_linkkit_event_callback(515): Current Devid: 0
      [dbg] _iotx_linkkit_event_callback(516): Current EventID: Error
      [dbg] _iotx_linkkit_event_callback(517): Current Message: success
                                      

      This is the log from the user callback function user_trigger_event_reply_event_handler().

      user_trigger_event_reply_event_handler.310: Trigger Event Reply Received, Devid: 0, Message ID: 1, Code: 200, EventID: Error, Message: success
                                      
    • Service invocation

      Register the handler function for service messages.

      IOT_RegisterCallback(ITE_SERVICE_REQUEST, user_service_request_event_handler);
                                      

      When a service request message is received, the following callback function is entered. The device-side demo shows a simple addition service. The input parameters are NumberA and NumberB, and the response parameter is Result. The sample uses cJSON to parse the property values.

      static int user_service_request_event_handler(const int devid, const char *serviceid, const int serviceid_len,
                                                    const char *request, const int request_len,
                                                    char **response, int *response_len)
      {
          int add_result = 0;
          cJSON *root = NULL, *item_number_a = NULL, *item_number_b = NULL;
          const char *response_fmt = "{\"Result\": %d}";
      
          EXAMPLE_TRACE("Service Request Received, Service ID: %.*s, Payload: %s", serviceid_len, serviceid, request);
      
          /* Parse Root */
          root = cJSON_Parse(request);
          if (root == NULL || !cJSON_IsObject(root)) {
              EXAMPLE_TRACE("JSON Parse Error");
              return -1;
          }
      
          if (strlen("Operation_Service") == serviceid_len && memcmp("Operation_Service", serviceid, serviceid_len) == 0) {
              /* Parse NumberA */
              item_number_a = cJSON_GetObjectItem(root, "NumberA");
              if (item_number_a == NULL || !cJSON_IsNumber(item_number_a)) {
                  cJSON_Delete(root);
                  return -1;
              }
              EXAMPLE_TRACE("NumberA = %d", item_number_a->valueint);
      
              /* Parse NumberB */
              item_number_b = cJSON_GetObjectItem(root, "NumberB");
              if (item_number_b == NULL || !cJSON_IsNumber(item_number_b)) {
                  cJSON_Delete(root);
                  return -1;
              }
              EXAMPLE_TRACE("NumberB = %d", item_number_b->valueint);
      
              add_result = item_number_a->valueint + item_number_b->valueint;
      
              /* Send Service Response To Cloud */
              *response_len = strlen(response_fmt) + 10 + 1;
              *response = (char *)HAL_Malloc(*response_len);
              if (*response == NULL) {
                  EXAMPLE_TRACE("Memory Not Enough");
                  return -1;
              }
              memset(*response, 0, *response_len);
              HAL_Snprintf(*response, *response_len, response_fmt, add_result);
              *response_len = strlen(*response);
          }
      
          cJSON_Delete(root);
          return 0;
      }
                                      

      At this point, you can view the following logs on the device.

      This is the service invocation received from the cloud. The input parameters are NumberA (value: 1) and NumberB (value: 2).

      < {
      <     "method": "thing.service.Operation_Service",
      <     "id": "280532170",
      <     "params": {
      <         "NumberB": 2,
      <         "NumberA": 1
      <     },
      <     "version": "1.0.0"
      < }
                                      

      In the callback function, the values of NumberA and NumberB are added. The sum is assigned to Result and reported to the cloud.

      > {
      >     "id": "280532170",
      >     "code": 200,
      >     "data": {
      >         "Result":  3
      >     }
      > }
      
                                      

      This concludes the explanation of services, properties, and events in the Premium Edition single-product sample.