Develop a smart light with an IoT SDK-adapted chip

更新时间:
复制 MD 格式

If you use a certified chip module or a module with an integrated IoT SDK, you can develop your product quickly and easily.

Prerequisites

  • You have obtained the firmware code for the module from your chip vendor.

  • You have created a product and defined its features.

  • You have generated a ProductKey, DeviceName, DeviceSecret, and ProductSecret for a single test device.

Procedure

  1. Write the device-specific credentials.

    Flash the firmware using the method provided by the chip vendor. Confirm that the following functions implemented by the vendor can correctly read your device's ProductKey, DeviceName, DeviceSecret, and ProductSecret. Alternatively, to verify the development flow, configure the following HAL functions to read the generated device credentials by default.

    • HAL_GetProductKey

    • HAL_GetDeviceName

    • HAL_GetDeviceSecret

    • HAL_GetProductSecret

  2. Generate and download the TSL model.

    The IoT Platform software development kit (SDK) supports two ways to obtain the Thing Specification Language (TSL) model.

    • Pull the TSL model directly from the cloud

      When the application calls linkkit_start() to initialize the SDK, set the get_tsl_from_cloud input parameter to 1. The device automatically retrieves the model from the cloud after it connects.

    • Set the TSL model locally

      When the application calls linkkit_start() to initialize the SDK, set the get_tsl_from_cloud input parameter to 0 and call linkkit_set_tsl() to set the TSL model.

    1. Click the product you created to go to the product feature definition page.

    2. Click View TSL Model.

    3. Transform the TSL string.

      There are two ways to transform the TSL string.

      • Copy the JSON string locally. Remove all spaces (" "), backspaces ("\b"), and newlines ("\n"). Replace all quotation marks (") with escaped quotation marks (\").

      • Use the TSL format transformation tool.

        1. Execute make reconfig and select the host type (ubuntu or windows).

        2. Execute make to compile the TSL format transformation tool.

          After a successful compilation, the executable file linkkit_tsl_convert is generated in the output/release/bin/ folder.

        3. Save the product's TSL model from the console to a file. Use the linkkit_tsl_convert tool to format the TSL model.

        linkkit_tsl_convert (-isrc_path) [-odst_path] [-s]
            -i source file name
            -o destination file name
            -s slim file
        
        // For example, if the TSL model copied from the console is saved in the file source.txt, the transformed file is saved in destination.txt, and the TSL model is slimmed down, the command is:
        linkkit_tsl_convert -isource.txt -odestination.txt -s         

        Call linkkit_set_tsl and pass the escaped string as the input parameter. The following is an example.

        const char TSL_STRING[] = "{\"schema\":\"http://aliyun/iot/thing/desc/schema\",\"profile\":{\"productKey\":\"productKey123\",\"deviceName\":\"deviceName456\"},\"link\":\"/sys/a1AzoSi5TMc/olin_linkkit_test/thing/\",\"services\":[{\"outputData\":[],\"identifier\":\"set\",\"inputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Main Light Switch\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Red\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Green\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Blue\"}],\"type\":\"struct\"},\"name\":\"RGB Color\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Night Light Switch\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"Manual\",\"1\":\"Reading\",\"2\":\"Cinema\",\"3\":\"Night Light\",\"4\":\"Living\",\"5\":\"Soft\"},\"type\":\"enum\"},\"name\":\"Work Mode\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"Kelvin\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"Color Temperature\"},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Brightness\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"degree\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Lightness\"}],\"type\":\"struct\"},\"name\":\"HSL Color\"},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Value\"}],\"type\":\"struct\"},\"name\":\"HSV Color\"},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"Time\"},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"Double\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"String\"}],\"method\":\"thing.service.property.set\",\"name\":\"set\",\"required\":true,\"callType\":\"sync\",\"desc\":\"Set Properties\"},{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Main Light Switch\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Red\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Green\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Blue\"}],\"type\":\"struct\"},\"name\":\"RGB Color\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Night Light Switch\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"Manual\",\"1\":\"Reading\",\"2\":\"Cinema\",\"3\":\"Night Light\",\"4\":\"Living\",\"5\":\"Soft\"},\"type\":\"enum\"},\"name\":\"Work Mode\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"Kelvin\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"Color Temperature\"},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Brightness\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"degree\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Lightness\"}],\"type\":\"struct\"},\"name\":\"HSL Color\"},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Value\"}],\"type\":\"struct\"},\"name\":\"HSV Color\"},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"Time\"},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"Double\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"String\"}],\"identifier\":\"get\",\"inputData\":[\"LightSwitch\",\"RGBColor\",\"NightLightSwitch\",\"WorkMode\",\"ColorTemperature\",\"Brightness\",\"HSLColor\",\"HSVColor\",\"PropertyTime\",\"Propertypoint\",\"PropertyCharacter\"],\"method\":\"thing.service.property.get\",\"name\":\"get\",\"required\":true,\"callType\":\"sync\",\"desc\":\"Get Properties\"},{\"outputData\":[{\"identifier\":\"Contrastratio\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Contrast\"}],\"identifier\":\"Custom\",\"inputData\":[{\"identifier\":\"transparency\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Transparency\"}],\"method\":\"thing.service.Custom\",\"name\":\"Custom Service\",\"required\":false,\"callType\":\"async\"}],\"properties\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Main Light Switch\",\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Red\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Green\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Blue\"}],\"type\":\"struct\"},\"name\":\"RGB Color\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Night Light Switch\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"Manual\",\"1\":\"Reading\",\"2\":\"Cinema\",\"3\":\"Night Light\",\"4\":\"Living\",\"5\":\"Soft\"},\"type\":\"enum\"},\"name\":\"Work Mode\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"Kelvin\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"Color Temperature\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Brightness\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"degree\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Lightness\"}],\"type\":\"struct\"},\"name\":\"HSL Color\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Value\"}],\"type\":\"struct\"},\"name\":\"HSV Color\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"Time\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"Double\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"String\",\"accessMode\":\"rw\",\"required\":false}],\"events\":[{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Main Light Switch\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Red\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Green\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Blue\"}],\"type\":\"struct\"},\"name\":\"RGB Color\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Night Light Switch\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"Manual\",\"1\":\"Reading\",\"2\":\"Cinema\",\"3\":\"Night Light\",\"4\":\"Living\",\"5\":\"Soft\"},\"type\":\"enum\"},\"name\":\"Work Mode\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"Kelvin\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"Color Temperature\"},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Brightness\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"degree\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Lightness\"}],\"type\":\"struct\"},\"name\":\"HSL Color\"},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Value\"}],\"type\":\"struct\"},\"name\":\"HSV Color\"},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"Time\"},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"Double\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"String\"}],\"identifier\":\"post\",\"method\":\"thing.event.property.post\",\"name\":\"post\",\"type\":\"info\",\"required\":true,\"desc\":\"Report Properties\"},{\"outputData\":[{\"identifier\":\"ErrorCode\",\"dataType\":{\"specs\":{\"0\":\"Normal\"},\"type\":\"enum\"},\"name\":\"Error Code\"}],\"identifier\":\"Error\",\"method\":\"thing.event.Error.post\",\"name\":\"Report Error\",\"type\":\"info\",\"required\":true}]}";
        
        int main()
        {
            get_tsl_from_cloud  = 0;
            linkkit_start(18, get_tsl_from_cloud, linkkit_loglevel_debug, &alinkops, linkkit_cloud_domain_sh, sample_ctx);
        
            linkkit_set_tsl(TSL_STRING, strlen(TSL_STRING));
        
            ...
        }
        									
  3. Compile the SDK.

    For adapted hardware platforms, you can directly compile the SDK library for the chip. The following example uses the esp32 daily environment.

    1. In the SDK root directory, execute make reconfig and select 2.

      SELECT A CONFIGURATION:
      
        1) config.armcc.daily               9) config.h3c.rtk_online
        2) config.esp32.daily              10) config.h3c.rtk_pre
        3) config.esp32.online             11) config.openwrt.c1
        4) config.esp32.pre                12) config.ubuntu.daily
        5) config.esp8266.daily            13) config.ubuntu.online
        6) config.esp8266.online           14) config.ubuntu.online.unittest
        7) config.esp8266.pre              15) config.ubuntu.pre
        8) config.h3c.rtk_daily
        #? 2
      
        SELECTED CONFIGURATION:
      
        VENDOR :   esp32
        MODEL  :   daily
      
      
        CONFIGURE .............................. [base/log]
        CONFIGURE .............................. [base/tls]
        CONFIGURE .............................. [base/utils]
        CONFIGURE .............................. [connectivity/coap]
        CONFIGURE .............................. [connectivity/examples]
        CONFIGURE .............................. [connectivity/mqtt]
        CONFIGURE .............................. [connectivity/ota]
        CONFIGURE .............................. [connectivity/system]
        CONFIGURE .............................. [external/cut]
        CONFIGURE .............................. [hal-impl]
        CONFIGURE .............................. [layers/cm]
        CONFIGURE .............................. [layers/cm/examples]
        CONFIGURE .............................. [layers/dm]
        CONFIGURE .............................. [layers/linkkit]
        CONFIGURE .............................. [layers/linkkit/samples]
        CONFIGURE .............................. [modules/alcs]
        CONFIGURE .............................. [modules/awss-ap]
        CONFIGURE .............................. [sdk-tests]
        CONFIGURE .............................. [service/fota]
      
        BUILDING WITH EXISTING CONFIGURATION:
      
        VENDOR :   esp32
        MODEL  :   daily
      
        Components:
      
        . external/cut
        . connectivity/system
        . connectivity/ota
        . connectivity/mqtt
        . connectivity/coap
        . connectivity/examples
        . layers/dm
        . layers/linkkit
        . layers/linkkit/samples
        . layers/cm
        . layers/cm/examples
        . modules/alcs
        . modules/awss-ap
        . base/log
        . base/utils
        . base/tls
        . hal-impl
        . sdk-tests
        . service/fota
      							
    2. Execute make to generate libilop-esp32.a.

      make
        BUILDING WITH EXISTING CONFIGURATION:
      
        VENDOR :   esp32
        MODEL  :   daily
      
        [AR] libilop-hal.a              <=
        [CC] mqtt-example.o             <= mqtt-example.c                                   
                                           makefile
        [CC] ut_json_parser.o           <= ut_json_parser.c                                 
        [CC] ut_mem_stats.o             <= ut_mem_stats.c                                   
        [CC] ut_json_token.o            <= ut_json_token.c                                  
        [CC] utils_base64.o             <= utils_base64.c   
        ...
      
        [AR] libilop-esp32.a            <=
                                           base/log/lite-log.o
                                           base/utils/json_parser.o
                                           base/utils/json_token.o
                                           base/utils/linked_list.o
                                           base/utils/mem_stats.o
                                           base/utils/string_utils.o
                                           base/utils/utils_base64.o
                                           base/utils/utils_epoch_time.o
                                           base/utils/utils_hmac.o
                                           base/utils/utils_httpc.o
                                           base/utils/utils_list.o
                                           base/utils/utils_md5.o
                                           base/utils/utils_net.o
                                           base/utils/utils_sha1.o
                                           base/utils/utils_timer.o
                                           base/utils/work_queue.o
                                           connectivity/coap/alcs_api.o
                                           connectivity/coap/alcs_client.o
                                           connectivity/coap/alcs_coap.o
                                           connectivity/coap/alcs_server.o
                                           connectivity/coap/CoAPDeserialize.o
                                           connectivity/coap/CoAPExport.o
                                           connectivity/coap/CoAPMessage.o
                                           connectivity/coap/CoAPNetwork.o
                                           connectivity/coap/CoAPObserve.o
                                           connectivity/coap/CoAPPlatform.o
                                           connectivity/coap/CoAPResource.o
                                           connectivity/coap/CoAPSerialize.o
                                           connectivity/coap/CoAPServer.o
                                           connectivity/mqtt/mqtt_client.o
                                           connectivity/mqtt/MQTTConnectClient.o
                                           connectivity/mqtt/MQTTDeserializePublish.o
                                           connectivity/mqtt/mqtt_instance.o
                                           connectivity/mqtt/MQTTPacket.o
                                           connectivity/mqtt/MQTTSerializePublish.o
                                           connectivity/mqtt/MQTTSubscribeClient.o
                                           connectivity/mqtt/MQTTUnsubscribeClient.o
                                           connectivity/ota/ota.o
                                           connectivity/system/ca.o
                                           connectivity/system/class_interface.o
                                           connectivity/system/device.o
                                           connectivity/system/guider.o
                                           connectivity/system/id2_guider.o
                                           connectivity/system/report.o
                                           connectivity/system/sdk-impl.o
                                           layers/cm/iotx_cloud_conn_coap.o
                                           layers/cm/iotx_cloud_conn_http.o
                                           layers/cm/iotx_cloud_conn_mqtt.o
                                           layers/cm/iotx_cm_api.o
                                           layers/cm/iotx_cm_cloud_conn.o
                                           layers/cm/iotx_cm_common.o
                                           layers/cm/iotx_cm_local_conn.o
                                           layers/cm/iotx_cm_log.o
                                           layers/cm/iotx_cm_ota.o
                                           layers/cm/iotx_local_conn_alcs.o
                                           layers/dm/cJSON.o
                                           layers/dm/dm_cm_impl.o
                                           layers/dm/dm_cm_msg_info.o
                                           layers/dm/dm_impl.o
                                           layers/dm/dm_logger.o
                                           layers/dm/dm_slist.o
                                           layers/dm/dm_thing_manager.o
                                           layers/dm/dm_thing.o
                                           layers/linkkit/linkkit_export.o
                                           layers/linkkit/lite_queue.o
                                           modules/alcs/alcs_adapter.o
                                           modules/alcs/alcs_mqtt.o
                                           service/fota/service_ota.o
      							
    3. Write the ProductKey, DeviceName, DeviceSecret, and ProductSecret from Step 1 into the HAL_GetProductKey, HAL_GetDeviceName, HAL_GetDeviceSecret, and HAL_GetProductSecret functions of the target platform, respectively.

    The APIs provided by the Link Kit SDK are in layers/linkkit/include/linkkit_export.h. After you write the device features, link libilop-target_platform.a to compile the firmware and run your program.

Sample code

/** USER NOTIFICATION
 *  this sample code is only used for evaluation or test of the iLop project.
 *  Users should modify this sample code freely according to the product/device TSL, like
 *  property/event/service identifiers, and the item value type(type, length, etc...).
 *  Create user's own execution logic for specific products.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <unistd.h>

#include "linkkit_export.h"

#include "iot_import.h"

/*
 * example for product "Light-Demo"
 */

#define LINKKIT_PRINTF(...)  \
    do {                                                     \
        printf("\e[0;32m%s@line%d\t:", __FUNCTION__, __LINE__);  \
        printf(__VA_ARGS__);                                 \
        printf("\e[0m");                                   \
    } while (0)

/* identifier of property/service/event, users should modify this macros according to your own product TSL. */
#define EVENT_PROPERTY_POST_IDENTIFIER         "post"
#define EVENT_ERROR_IDENTIFIER                 "Error"
#define EVENT_ERROR_OUTPUT_INFO_IDENTIFIER     "ErrorCode"
#define EVENT_CUSTOM_IDENTIFIER                "Custom"

/* specify ota buffer size for ota service, ota service will use this buffer for bin download. */
#define OTA_BUFFER_SIZE                  (512+1)
/* PLEASE set RIGHT tsl string according to your product. */

const char TSL_STRING[] = "{\"schema\":\"http://aliyun/iot/thing/desc/schema\",\"profile\":{\"productKey\":\"productKey123\",\"deviceName\":\"deviceName456\"},\"link\":\"/sys/a1AzoSi5TMc/olin_linkkit_test/thing/\",\"services\":[{\"outputData\":[],\"identifier\":\"set\",\"inputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Main Light Switch\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Red\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Green\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Blue\"}],\"type\":\"struct\"},\"name\":\"RGB Color\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Night Light Switch\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"Manual\",\"1\":\"Reading\",\"2\":\"Cinema\",\"3\":\"Night Light\",\"4\":\"Living\",\"5\":\"Soft\"},\"type\":\"enum\"},\"name\":\"Work Mode\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"Kelvin\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"Color Temperature\"},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Brightness\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"degree\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Lightness\"}],\"type\":\"struct\"},\"name\":\"HSL Color\"},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Value\"}],\"type\":\"struct\"},\"name\":\"HSV Color\"},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"Time\"},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"Double\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"String\"}],\"method\":\"thing.service.property.set\",\"name\":\"set\",\"required\":true,\"callType\":\"sync\",\"desc\":\"Set Properties\"},{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Main Light Switch\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Red\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Green\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Blue\"}],\"type\":\"struct\"},\"name\":\"RGB Color\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Night Light Switch\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"Manual\",\"1\":\"Reading\",\"2\":\"Cinema\",\"3\":\"Night Light\",\"4\":\"Living\",\"5\":\"Soft\"},\"type\":\"enum\"},\"name\":\"Work Mode\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"Kelvin\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"Color Temperature\"},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Brightness\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"degree\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Lightness\"}],\"type\":\"struct\"},\"name\":\"HSL Color\"},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Value\"}],\"type\":\"struct\"},\"name\":\"HSV Color\"},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"Time\"},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"Double\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"String\"}],\"identifier\":\"get\",\"inputData\":[\"LightSwitch\",\"RGBColor\",\"NightLightSwitch\",\"WorkMode\",\"ColorTemperature\",\"Brightness\",\"HSLColor\",\"HSVColor\",\"PropertyTime\",\"Propertypoint\",\"PropertyCharacter\"],\"method\":\"thing.service.property.get\",\"name\":\"get\",\"required\":true,\"callType\":\"sync\",\"desc\":\"Get Properties\"},{\"outputData\":[{\"identifier\":\"Contrastratio\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Contrast\"}],\"identifier\":\"Custom\",\"inputData\":[{\"identifier\":\"transparency\",\"dataType\":{\"specs\":{\"min\":\"0\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Transparency\"}],\"method\":\"thing.service.Custom\",\"name\":\"Custom Service\",\"required\":false,\"callType\":\"async\"}],\"properties\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Main Light Switch\",\"accessMode\":\"rw\",\"required\":true},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Red\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Green\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Blue\"}],\"type\":\"struct\"},\"name\":\"RGB Color\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Night Light Switch\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"Manual\",\"1\":\"Reading\",\"2\":\"Cinema\",\"3\":\"Night Light\",\"4\":\"Living\",\"5\":\"Soft\"},\"type\":\"enum\"},\"name\":\"Work Mode\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"Kelvin\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"Color Temperature\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Brightness\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"degree\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Lightness\"}],\"type\":\"struct\"},\"name\":\"HSL Color\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Value\"}],\"type\":\"struct\"},\"name\":\"HSV Color\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"Time\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"Double\",\"accessMode\":\"rw\",\"required\":false},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"String\",\"accessMode\":\"rw\",\"required\":false}],\"events\":[{\"outputData\":[{\"identifier\":\"LightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Main Light Switch\"},{\"identifier\":\"RGBColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Red\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Red\"},{\"identifier\":\"Green\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Green\"},{\"identifier\":\"Blue\",\"dataType\":{\"specs\":{\"min\":\"0\",\"unitName\":\"None\",\"max\":\"255\"},\"type\":\"int\"},\"name\":\"Blue\"}],\"type\":\"struct\"},\"name\":\"RGB Color\"},{\"identifier\":\"NightLightSwitch\",\"dataType\":{\"specs\":{\"0\":\"Off\",\"1\":\"On\"},\"type\":\"bool\"},\"name\":\"Night Light Switch\"},{\"identifier\":\"WorkMode\",\"dataType\":{\"specs\":{\"0\":\"Manual\",\"1\":\"Reading\",\"2\":\"Cinema\",\"3\":\"Night Light\",\"4\":\"Living\",\"5\":\"Soft\"},\"type\":\"enum\"},\"name\":\"Work Mode\"},{\"identifier\":\"ColorTemperature\",\"dataType\":{\"specs\":{\"unit\":\"K\",\"min\":\"2700\",\"unitName\":\"Kelvin\",\"max\":\"6500\"},\"type\":\"int\"},\"name\":\"Color Temperature\"},{\"identifier\":\"Brightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Brightness\"},{\"identifier\":\"HSLColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"°\",\"min\":\"0\",\"unitName\":\"degree\",\"max\":\"360\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Lightness\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Lightness\"}],\"type\":\"struct\"},\"name\":\"HSL Color\"},{\"identifier\":\"HSVColor\",\"dataType\":{\"specs\":[{\"identifier\":\"Hue\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Hue\"},{\"identifier\":\"Saturation\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Saturation\"},{\"identifier\":\"Value\",\"dataType\":{\"specs\":{\"unit\":\"%\",\"min\":\"0\",\"unitName\":\"Percentage\",\"max\":\"100\"},\"type\":\"int\"},\"name\":\"Value\"}],\"type\":\"struct\"},\"name\":\"HSV Color\"},{\"identifier\":\"PropertyTime\",\"dataType\":{\"specs\":{},\"type\":\"date\"},\"name\":\"Time\"},{\"identifier\":\"Propertypoint\",\"dataType\":{\"specs\":{\"min\":\"-100\",\"max\":\"100\"},\"type\":\"double\"},\"name\":\"Double\"},{\"identifier\":\"PropertyCharacter\",\"dataType\":{\"specs\":{\"length\":\"255\"},\"type\":\"text\"},\"name\":\"String\"}],\"identifier\":\"post\",\"method\":\"thing.event.property.post\",\"name\":\"post\",\"type\":\"info\",\"required\":true,\"desc\":\"Report Properties\"},{\"outputData\":[{\"identifier\":\"ErrorCode\",\"dataType\":{\"specs\":{\"0\":\"Normal\"},\"type\":\"enum\"},\"name\":\"Error Code\"}],\"identifier\":\"Error\",\"method\":\"thing.event.Error.post\",\"name\":\"Report Error\",\"type\":\"info\",\"required\":true}]}";

/* user sample context struct. */
typedef struct _sample_context {
    void* thing;

    int cloud_connected;
    int thing_enabled;

    int service_custom_input_transparency;
    int service_custom_output_contrastratio;
#ifdef SERVICE_OTA_ENABLED
    char ota_buffer[OTA_BUFFER_SIZE];
#endif /* SERVICE_OTA_ENABLED */
} sample_context_t;

sample_context_t g_sample_context;

#ifdef SERVICE_OTA_ENABLED
/* callback function for fota service. */
static void fota_callback(service_fota_callback_type_t callback_type, const char* version)
{
    sample_context_t* sample;

    assert(callback_type < service_fota_callback_type_number);

    sample = &g_sample_context;

    /* temporarily disable thing when ota service invoked */
    sample->thing_enabled = 0;

    linkkit_invoke_ota_service(sample->ota_buffer, OTA_BUFFER_SIZE);

    sample->thing_enabled = 1;

    /* reboot the device... */
}
#endif /* SERVICE_OTA_ENABLED */

static int on_connect(void* ctx)
{
    sample_context_t* sample = ctx;

    sample->cloud_connected = 1;

    LINKKIT_PRINTF("cloud is connected\n");

    return 0;
}

static int on_disconnect(void* ctx)
{
    sample_context_t* sample = ctx;

    sample->cloud_connected = 0;

    LINKKIT_PRINTF("cloud is disconnect\n");

    return 0;
}

static int raw_data_arrived(void* thing_id, void* data, int len, void* ctx)
{
    char raw_data[128] = {0};

    LINKKIT_PRINTF("raw data arrived,len:%d\n", len);

    /* do user's raw data process logical here. */

    /* ............................... */

    /* user's raw data process logical complete */

    snprintf(raw_data, sizeof(raw_data), "test down raw reply data %lld", HAL_UptimeMs());

    linkkit_invoke_raw_service(thing_id, 0, raw_data, strlen(raw_data));

    return 0;
}

static int thing_create(void* thing_id, void* ctx)
{
    sample_context_t* sample = ctx;

    LINKKIT_PRINTF("new thing@%p created.\n", thing_id);

    sample->thing = thing_id;

    return 0;
}

static int thing_enable(void* thing_id, void* ctx)
{
    sample_context_t* sample = ctx;

    sample->thing_enabled = 1;

    return 0;
}

static int thing_disable(void* thing, void* ctx)
{
    sample_context_t* sample = ctx;

    sample->thing_enabled = 0;

    return 0;
}
#ifdef RRPC_ENABLED
static int handle_service_custom(sample_context_t* sample, void* thing, char* service_identifier, int request_id, int rrpc)
#else
static int handle_service_custom(sample_context_t* sample, void* thing, char* service_identifier, int request_id)
#endif /* RRPC_ENABLED */
{
    char identifier[128] = {0};

    /*
     * get input value.
     */
    snprintf(identifier, sizeof(identifier), "%s.%s", service_identifier, "transparency");
    linkkit_get_value(linkkit_method_get_service_input_value, thing, identifier, &sample->service_custom_input_transparency, NULL);

    /*
     * set output value according to user's process result.
     */

    snprintf(identifier, sizeof(identifier), "%s.%s", service_identifier, "Contrastratio");

    sample->service_custom_output_contrastratio = sample->service_custom_input_transparency >= 0 ? sample->service_custom_input_transparency : sample->service_custom_input_transparency * -1;

    linkkit_set_value(linkkit_method_set_service_output_value, thing, identifier, &sample->service_custom_output_contrastratio, NULL);
#ifdef RRPC_ENABLED
    linkkit_answer_service(thing, service_identifier, request_id, 200, rrpc);
#else
    linkkit_answer_service(thing, service_identifier, request_id, 200);
#endif /* RRPC_ENABLED */

    return 0;
}
#ifdef RRPC_ENABLED
static int thing_call_service(void* thing_id, char* service, int request_id, int rrpc, void* ctx)
#else
static int thing_call_service(void* thing_id, char* service, int request_id, void* ctx)
#endif /* RRPC_ENABLED */
{
    sample_context_t* sample = ctx;

    LINKKIT_PRINTF("service(%s) requested, id: thing@%p, request id:%d\n",
                   service, thing_id, request_id);

    if (strcmp(service, "Custom") == 0) {
#ifdef RRPC_ENABLED
        handle_service_custom(sample, thing_id, service, request_id, rrpc);
#else
        handle_service_custom(sample, thing_id, service, request_id);
#endif /* RRPC_ENABLED */
    }

    return 0;
}

static int thing_prop_changed(void* thing_id, char* property, void* ctx)
{
    char* value_str = NULL;
    char property_buf[64] = {0};

    /* get new property value */
    if (strstr(property, "HSVColor") != 0) {
        int hue, saturation, value;

        snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Hue");
        linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &hue, &value_str);

        snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Saturation");
        linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &saturation, &value_str);

        snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Value");
        linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &value, &value_str);

        LINKKIT_PRINTF("property(%s), Hue:%d, Saturation:%d, Value:%d\n", property, hue, saturation, value);

        /* XXX: do user's process logical here. */
    } else if (strstr(property, "HSLColor") != 0) {
        int hue, saturation, lightness;

        snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Hue");
        linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &hue, &value_str);

        snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Saturation");
        linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &saturation, &value_str);

        snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Lightness");
        linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &lightness, &value_str);

        LINKKIT_PRINTF("property(%s), Hue:%d, Saturation:%d, Lightness:%d\n", property, hue, saturation, lightness);
        /* XXX: do user's process logical here. */
    }  else if (strstr(property, "RGBColor") != 0) {
        int red, green, blue;

        snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Red");
        linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &red, &value_str);

        snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Green");
        linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &green, &value_str);

        snprintf(property_buf, sizeof(property_buf), "%s.%s", property, "Blue");
        linkkit_get_value(linkkit_method_get_property_value, thing_id, property_buf, &blue, &value_str);

        LINKKIT_PRINTF("property(%s), Red:%d, Green:%d, Blue:%d\n", property, red, green, blue);
        /* XXX: do user's process logical here. */
    } else {
        linkkit_get_value(linkkit_method_get_property_value, thing_id, property, NULL, &value_str);

        LINKKIT_PRINTF("#### property(%s) new value set: %s ####\n", property, value_str);
    }

    /* do user's process logical here. */
    linkkit_trigger_event(thing_id, EVENT_PROPERTY_POST_IDENTIFIER, property);

    return 0;
}

static linkkit_ops_t alinkops = {
    .on_connect         = on_connect,
    .on_disconnect      = on_disconnect,
    .raw_data_arrived   = raw_data_arrived,
    .thing_create       = thing_create,
    .thing_enable       = thing_enable,
    .thing_disable      = thing_disable,
    .thing_call_service = thing_call_service,
    .thing_prop_changed = thing_prop_changed,
};

static unsigned long long uptime_sec(void)
{
    static unsigned long long start_time = 0;

    if (start_time == 0) {
        start_time = HAL_UptimeMs();
    }

    return (HAL_UptimeMs() - start_time) / 1000;
}
#if 0
static int post_all_prop(sample_context_t* sample)
{
    return linkkit_trigger_event(sample->thing, EVENT_PROPERTY_POST_IDENTIFIER, NULL);
}
#endif
static int post_event_error(sample_context_t* sample)
{
    char event_output_identifier[64];
    snprintf(event_output_identifier, sizeof(event_output_identifier), "%s.%s", EVENT_ERROR_IDENTIFIER, EVENT_ERROR_OUTPUT_INFO_IDENTIFIER);

    int errorCode = 0;
    linkkit_set_value(linkkit_method_set_event_output_value,
                      sample->thing,
                      event_output_identifier,
                      &errorCode, NULL);

    return linkkit_trigger_event(sample->thing, EVENT_ERROR_IDENTIFIER, NULL);
}

#if 0
static int post_event_fault_alert(sample_context_t* sample)
{
    char event_output_identifier[64];
    snprintf(event_output_identifier, sizeof(event_output_identifier), "%s.%s", EVENT_ERROR_IDENTIFIER, EVENT_ERROR_OUTPUT_INFO_IDENTIFIER);

    int errorCode = 0;
    linkkit_set_value(linkkit_method_set_event_output_value,
                      sample->thing,
                      event_output_identifier,
                      &errorCode, NULL);

    return linkkit_trigger_event(sample->thing, EVENT_ERROR_IDENTIFIER, NULL);
}

static int upload_raw_data(sample_context_t* sample)
{
    char raw_data[128] = {0};

    snprintf(raw_data, sizeof(raw_data), "test up raw data %lld", HAL_UptimeMs());

    return linkkit_invoke_raw_service(sample->thing, 1, raw_data, strlen(raw_data));
}
#endif

static int is_active(sample_context_t* sample)
{
    return sample->cloud_connected && sample->thing_enabled;
}

int main(int argc, char* argv[])
{
    sample_context_t* sample_ctx = &g_sample_context;
    int execution_time = 0;
    int get_tsl_from_cloud = 0;
    int exit = 0;
    int ret;
    unsigned long long now = 0;
    unsigned long long prev_sec = 0;

    int opt;
    while ((opt = getopt(argc, argv, "t:g:h")) != -1) {
        switch (opt) {
        case 't':
            execution_time = atoi(optarg);
            break;
        case 'g':
            get_tsl_from_cloud = atoi(optarg);
            break;
        case 'h':
            LINKKIT_PRINTF("-t to specify sample execution time period(minutes); -g to specify if get tsl from cloud(0: not, !0: yes).\n");
            return 0;
            break;
        default:
            break;
        }
    }

    execution_time = execution_time < 1 ? 1 : execution_time;
    LINKKIT_PRINTF("sample execution time: %d minutes\n", execution_time);
    LINKKIT_PRINTF("%s tsl from cloud\n", get_tsl_from_cloud == 0 ? "Not get" : "get");

    memset(sample_ctx, 0, sizeof(sample_context_t));
    sample_ctx->thing_enabled = 1;

    linkkit_start(18, get_tsl_from_cloud, linkkit_loglevel_debug, &alinkops, linkkit_cloud_domain_sh, sample_ctx);
    if (!get_tsl_from_cloud) {
        linkkit_set_tsl(TSL_STRING, strlen(TSL_STRING));
    }
#ifdef SERVICE_OTA_ENABLED
    linkkit_ota_init(fota_callback);
#endif /* SERVICE_OTA_ENABLED */
    while (1) {
        linkkit_dispatch();

        now = uptime_sec();
        if (prev_sec == now) {
#ifdef CMP_SUPPORT_MULTI_THREAD
            HAL_SleepMs(100);
#else
            linkkit_yield(100);
#endif
            continue;
        }
#if 0
        /* about 30 seconds, assume trigger post property event about every 30s. */
        if (now % 30 == 0 && is_active(sample_ctx)) {
            post_all_prop(sample_ctx);
        }

        /* about 31 seconds, assume invoke raw up service about every 31s. */
        if (now % 31 == 0 && is_active(sample_ctx)) {
            upload_raw_data(sample_ctx);
        }

        /* about 60 seconds, assume trigger event about every 60s. */
        if (now % 60 == 0 && is_active(sample_ctx)) {
            post_event_fault_alert(sample_ctx);
        }
#endif
        /* about 60 seconds, assume trigger event about every 60s. */
        if (now % 60 == 0 && is_active(sample_ctx)) {
            post_event_error(sample_ctx);
        }

        if (now % 5 == 0 && is_active(sample_ctx)) {
            ret = linkkit_trigger_deviceinfo_operate(sample_ctx->thing, "[{\"attrKey\":\"Temperature\",\"attrValue\":\"36.8\"}]", linkkit_deviceinfo_operate_update);
        }

        if (exit) break;

        /* after all, this is an sample, give a chance to return... */
        /* modify this value for this sample executaion time period */
        if (now > 60 * execution_time) exit = 1;

        prev_sec = now;
    }

    linkkit_end();

    return 0;
}