Tuya Connect Kit for C

Last Updated on : 2024-01-02 03:05:20download

Tuya Connect Kit is written in C and aims to help developers connect their proprietary hardware to the Tuya IoT Development Platform. This kit contains the implementation of essential IoT capabilities including IoT device activation, bidirectional data exchange between the cloud and devices, and OTA updates. It is independent of platforms and operating systems (OS), and can run on a single-tasking operating system. If your devices support the TCP/IP protocol stack, you can develop with this SDK to connect your devices to the platform.

Port Tuya Connect Kit

See How to Port Tuya Connect Kit.

Procedure

Step 1: Create product

Log in to the Tuya IoT Development Platform and create a product to get the PID. For more information, see Create Products.

Step 2: Define functions

You need to add or create required data points (DPs). A DP is an abstract representation of a feature you want to apply to a physical device, which can be defined by various data types.

The platform supports six data types, including Boolean, value, enum, fault, string, and raw. For more information, see Function Definition.

Step 3: Get the license

A license is composed of UUID and authKey, which serves as the credential to connect to the platform. You can get the license in the step of Hardware Development.

  1. Select Self-developed Module SDK in Hardware Development, complete details, and click OK.

  2. Click Get 2 Free Licenses.

  3. Select License List as the delivery form.

Step 4: Download Tuya Connect Kit

Download Tuya Connect Kit from GitHub.

The following describes the structure of the kit directory:

  • certs: Private keys, device certificates, and server-side CA root certificates.
  • docs: Development documentation.
  • libraries: External dependencies including MQTT client, HTTP client, and Mbed TLS.
  • interface: The SDK function API, which is required to port to your platform.
  • include: SDK APIs.
  • src: Source code.
  • platform: Interface adaptation used for porting.
  • utils: Common tools.
  • examples: Routines.

Step 5: Configure device information

Write your PID and license in the examples/linux/switch_demo/tuya_config.h file in the SDK, and set the macros TUYA_PRODUCT_KEY, TUYA_DEVICE_UUID, and TUYA_DEVICE_AUTHKEY.

Step 6: Build and run the program on Ubuntu

This section uses Ubuntu as an example to show you how to build and run the program. The build processes also apply to Debian system.

  1. Install make and other dependencies.

    sudo apt-get install make cmake libqrencode-dev
    
  2. Clone the repository from GitHub.

    git clone https://github.com/tuya/tuya-iot-link-sdk-embedded-c.git --recurse-submodules
    
  3. Create a folder to save the build output.

    mkdir build && cd build
    cmake ..
    make
    
  4. Run the demo. The SDK contains the sample code, such as for a switch product.

    ./bin/switch_demo
    
  5. Bind your device with the mobile app.

    You can use the Smart Life app to scan the QR code generated by the program on Linux to bind a device.

(Optional) Step 7: Generate device QR code

Use a QR code generator to make a QR code for your device.

  • The URL format for making QR code

    https://smartapp.tuya.com/s/p?p=<PRODUCT_KEY>&uuid=<UUID>&v=2.0
    
    • <PRODUCT_KEY>: The PID of the product you create on the Tuya IoT Development Platform.
    • <UUID>: The UUID of your device to be added.
  • URL example:

    https://smartapp.tuya.com/s/p?p=U0fxNCEnZptKnQ **&uuid=f2ef8b136911f4** &v=2.0
    

Sample application

  1. Instantiate and initialize a device object tuya_iot_client_t to assign initial values, such as product ID (PID) and authorization information, for this object.

    /* instantiate the client */
    tuya_iot_client_t client;
    
    /* instantiate the config */
    tuya_iot_config_t config = {
        .software_ver = "1.0.0",
        .productkey = <Product ID>,
        .uuid = <UUID>,
        .authkey = <AUTHKEY>,
        .event_handler = user_event_handler_cb
    };
    
    /* initialize the client */
    tuya_iot_init(&client, &config);
    
  2. Define event callbacks in the application layer, used to receive the event notifications from the SDK, such as the data point (DP) data from the cloud or cloud connection status.

    /* Tuya SDK event callback */
    void user_event_handler_on(tuya_iot_client_t* client, tuya_event_msg_t* event)
    {
        switch(event->id){
        case TUYA_EVENT_DP_RECEIVE:
            TY_LOGI("DP recv:%s", (const char*)event->data);
            /* After receiving a DP command, the device executes it and reports the current status.
            Sync status with the app panel. */
            break;
    
        case TUYA_EVENT_MQTT_CONNECTED:
            TY_LOGI("Device MQTT Connected!");
            break;
        ...
    
        default:
            break;
        }
    }
    
  3. Start the Tuya IoT SDK service.

    tuya_iot_start(&client);
    //Tuya IoT SDK service task, data receiving, device keep-alive, and more.
    
  4. Loop the following function to create threads for the underlying Link SDK client.

    tuya_iot_yield(&client);
    

    Example of reporting DP data to the cloud:

    /* Report Boolean data */
    const char bool_value[] = {"{\"101\":true}"};
    tuya_iot_dp_report_json(&client, bool_value);
    
    /* Report value data */
    const char int_value[] = {"{\"102\":123}"};
    tuya_iot_dp_report_json(&client, int_value);
    
    /* Report string data */
    const char string_value[] = {"{\"103\":\"helloworld\"}"};
    tuya_iot_dp_report_json(&client, string_value);
    
    /* Report enum data */
    const char enum_value[] = {"{\"104\":\"auto\"}"};
    tuya_iot_dp_report_json(&client, enum_value);
    
    /* Report raw data */
    const char raw_value[] = {"{\"105\":\"aGVsZA==\"}"};
    tuya_iot_dp_report_json(&client, raw_value);
    
    /* Report data of multiple DPs */
    const char multiple_value[] = {"{\"101\":true,\"102\":123,\"103\":\"hellowrold\",\"104\":\"auto\",\"105\":\"aGVsZA==\"}"};
    tuya_iot_dp_report_json(&client, multiple_value);
    

API description

Initialize SDK

Interface Description
Function prototype int tuya_iot_init(tuya_iot_client_t* client, tuya_iot_config_t* config)
Description Device initialization
Input parameter The handle to client device management.
Configure the initial parameters.
Output parameter None
Return value See Error Codes (int).

Start services

Interface Description
Function prototype int tuya_iot_start(tuya_iot_client_t *client)
Description Start SDK services.
Input parameter The handle to the client context
Output parameter None
Return value See Error Codes (int).

Stop services

Interface Description
Function prototype int tuya_iot_stop(tuya_iot_client_t *client)
Description Stop SDK services.
Input parameter The handle to the client context
Output parameter None
Return value See Error Codes (int).

Run in background

Interface Description
Function prototype int tuya_iot_yield(tuya_iot_client_t* client)
Description The SDK services run in the background.
Input parameter The handle to the client context
Output parameter None
Return value See Error Codes (int).
Notes Call this function in the main loop.

Report DP data

Interface Description
Function prototype int tuya_iot_dp_report_json(tuya_iot_client_t* client, char* dps)
Description Report DP data to the cloud
Input parameter The handle to client device management.
The DP data in JSON.
Output parameter None
Return value See Error Codes (int).
Notes Call this function in the main loop.

Example format

{
    "101":true,           # Boolean
    "102":18,             # Value
    "103":"hello wrold", # String
    "104":"auto",         # Enum
    "105":"aGVsZA==",     # Raw (base64)
    "106":2               # Fault (32bit)
}

For more information, see Function Definition.

Example

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include "tuya_log.h"
#include "tuya_config.h"
#include "tuya_iot.h"
#include "cJSON.h"

/* for App QRCode scan test */
extern void example_qrcode_print(char* productkey, char* uuid);

/* Tuya device handle */
tuya_iot_client_t client;

#define SWITCH_DP_ID_KEY "1"

/* Hardware switch control function */
void hardware_switch_set(bool value)
{
    if (value == true) {
        TY_LOGI("Switch ON");
    } else {
        TY_LOGI("Switch OFF");
    }
}

/* DP data reception processing function */
void tuya_iot_dp_download(tuya_iot_client_t* client, const char* json_dps)
{
    TY_LOGD("Data point download value:%s", json_dps);

    /* Parsing json string to cJSON object */
    cJSON* dps = cJSON_Parse(json_dps);
    if (dps == NULL) {
        TY_LOGE("JSON parsing error, exit!");
        return;
    }

    /* Process dp data */
    cJSON* switch_obj = cJSON_GetObjectItem(dps, SWITCH_DP_ID_KEY);
    if (cJSON_IsTrue(switch_obj)) {
        hardware_switch_set(true);

    } else if (cJSON_IsFalse(switch_obj)) {
        hardware_switch_set(false);
    }

    /* Release cJSON DPS object */
    cJSON_Delete(dps);

    /* Report the received data to synchronize the switch status. */
    tuya_iot_dp_report_json(client, json_dps);
}

/* Tuya SDK event callback */
static void user_event_handler_on(tuya_iot_client_t* client, tuya_event_msg_t* event)
{
    switch(event->id){
    case TUYA_EVENT_DP_RECEIVE:
        tuya_iot_dp_download(client, (const char*)event->data);
        break;

    case TUYA_EVENT_WAIT_ACTIVATE:
        /* Print the QRCode for Tuya App bind */
        example_qrcode_print(client->productkey, client->uuid);
        break;

    case TUYA_EVENT_MQTT_CONNECTED:
        TY_LOGI("Device MQTT Connected!");
        break;

    default:
        break;
    }
}

int main(int argc, char **argv)
{
    int ret = OPRT_OK;

    /* Initialize Tuya device configuration */
    ret = tuya_iot_init(&client, &(const tuya_iot_config_t){
        .productkey = TUYA_PRODUCT_KEY,
        .uuid = TUYA_DEVICE_UUID,
        .authkey = TUYA_DEVICE_AUTHKEY,
        .event_handler = user_event_handler_on
    });

    assert(ret == OPRT_OK);

    /* Start tuya iot task */
    tuya_iot_start(&client);

    for(;;) {
        /* Loop to receive packets, and handles client keepalive */
        tuya_iot_yield(&client);
    }

    return ret;
}