Application Development

Last Updated on : 2022-11-24 09:20:24download

This topic describes how to use a suite of application templates for infrastructure implementation. These ready-built templates can help you quickly accomplish capabilities such as end-to-end communication and key-value database, letting you focus on your application code for a shortened time to market.

Application templates

Extract the downloaded OpenCPU SDK to your system. The application templates are located in the tuyaos_demo_nb_sample folder under the apps directory.

Application Development

Files

The description of the apps directory.

Folder name Description
tuyaos_demo_nb_sample The templates for OpenCPU applications.
tuya_device.c Contain the application code.
tuya_device.h Contain the macro definitions, product information, and public header files.

Build code

Run the following command in the root directory where the extracted OpenCPU SDK resides:

./build_app.sh ./apps/tuyaos_demo_nb_sample mt2625gl_common 1.0.0

If NB is displayed in the output window, it means the project is built successfully.

Application Development

You can find the output in the following directory:

TuyaOS\vendor\mtk2625_SDK280\mt2625_os\project\mt2625_evb\apps\tuya_alpha\output\mt2625gl_common

Application Development

Template features

Application Development

Main functions

  • pre_init

    pre_init is run before the SDK initialization. You can implement the required logic in this function. For example, initialize the wake-up pin and the ADC, turn on the LED indicator, or enable peripherals. If no implementation is provided, pre_init will not be run. Do not set a long time delay in this function.

  • device_init

    device_init is used to initialize the product features. In this function, set the product_key and register callbacks. The following code snippet uses a typical application example to show how to use this function.

    int device_init(void)
    {
        int ret = OPRT_OK;
        // Set the product ID (PID).
        tuya_user_api_set_product_key(PRODUCT_KEY);
        // Set the event capture callback.
        tuya_user_api_event_loop_set_cb(tuya_event_process_cb, NULL);
        // Start the event capture task.
        tuya_user_api_event_loop_start();
        // Set the callback to invoke when commands from the cloud are received.
        tuya_user_api_dp_write_default_cb(tuya_dp_write_cb);
        // Set the callback to invoke when the record-type data is reported.
        tuya_user_api_dp_report_record_ack_register_cb(dp_report_notify_callback);
        // Set the heartbeat interval.
        tuya_user_api_lifetime_set(600);
        // Set the time interval for reporting record-type data in an unstable network connection.
        tuya_user_api_record_dp_lifetime_set(600);
        /*
        You can create user tasks.
        */
        return ret;
    }
    
  • tuya_user_api_event_loop_set_cb(tuya_event_process_cb, NULL)

    • This function is used to set the event capture callbacks. tuya_event_process_cb processes the event ID returned from the SDK, including the following states:

      typedef enum {
          SYSTEM_EVENT_ID_CARD,               // The SIM card is detected.
          SYSTEM_EVENT_NETWORK_READY,        // The NB-IoT device is attached to the network.
          SYSTEM_EVENT_NETWORK_DISCONNECT,   // The network is disconnected.
          SYSTEM_EVENT_GOING_SLEEP,           // The NB-IoT device is going to sleep.
          SYSTEM_EVENT_GOING_REBOOT,          // The NB-IoT device is rebooting.
          EVENT_LWM2M_CONNECTED,              // The LwM2M server is connected.
          EVENT_LWM2M_READY,                  //  The LwM2M service is available.
          EVENT_LWM2M_UPDATE_SUCCESS,        // The data is reported successfully.
          EVENT_LWM2M_RESPONSE_SUCCESS,      // The command is responded successfully.
          EVENT_LWM2M_RESTART,                // The LwM2M server is reconnected.
          EVENT_DEVICE_INFO_RESET,           // The NB-IoT device information is reset.
          EVENT_DEVICE_BIND_ON,              // The NB-IoT device is bound.
          EVENT_DEVICE_UNBIND_ON,            // The NB-IoT device is not bound.
          EVENT_DEVICE_DEACTIVE,             // The NB-IoT device is reset.
          EVENT_POWERKEY_PRESS,              // The POWER key is pressed.
          EVENT_SCHEMA_COMPLETE_ON,          // The schema is complete.
          EVENT_ELOG_SWITCH,                 // The ELOG switch.
          SYSTEM_EVENT_MAX
      } system_event_id_t;
      
    • You can process these states as needed. We recommend you send the message to the user’s task for processing. For example, SYSTEM_EVENT_ID_CARD and SYSTEM_EVENT_NETWORK_DISCONNECT can be used to indicate the user’s network status.

    • The SDK initializes the main events and registers the handler for the main events.

    • For more information about the main events, see the enum values defined to system_event_id_t in the tuya_comm.h file.

    • When the NB-IoT device detects a SIM card, it responds to the event SYSTEM_EVENT_ID_CARD.

    • When the NB-IoT device registers to the network, it responds to the event SYSTEM_EVENT_NETWORK_READY.

    • In the internet service provider (ISP) mode, the NB-IoT device will communicate with the proxy server first and then responds to the event EVENT_LWM2M_READY if its connection with the server works fine.

    • When the NB-IoT device logs in to the proxy server, it responds to the event EVENT_LWM2M_CONNECTED.
      When the NB-IoT device is disconnected from the network, it responds to the event SYSTEM_EVENT_NETWORK_DISCONNECT.

  • tuya_user_api_fota_notify_register

    This function is used for the battery level query and the update task status callback. You implement the function for collecting battery level and returning the battery status.

    typedef enum {
        BATTERY_LEVEL_LOW = 0,
        BATTERY_LEVEL_NORMAL = 1,
    } battery_state_t;
    

    If the battery is low, the firmware update cannot be performed. The update failure will be reported to the cloud to sync with the mobile app.

  • tuya_user_api_mf_test_cb_reg(tuya_user_prod_test)

    To use the production testing feature, the supporting jig and Tuya-defined protocol are required. If you have any questions, submit a service ticket.

    tuya_user_api_mf_test_cb_reg(tuya_user_prod_test) allows you to register callbacks for production testing. The function prototype is as follows:

    /*********************************************************************************
    * @ Features 	Register the callback for production testing.
    * @ Parameters   	user_test_callback: The callback.
    * @ Parameters   	cmd: The subcommand.
    * @ Parameters   	data: The pointer to the subcommand payload.
    * @ Parameters   	len: The length of the subcommand payload.
    * @ Parameters   	ret_data: The pointer to the return value.
    * @ Parameters   	ret_len: The length of the return value.
    * @ The return value. 	0: Success. Other values: Failure.
    *********************************************************************************/
    void tuya_user_api_mf_test_cb_reg(int (*user_test_callback)(IN USHORT_T cmd, IN UCHAR_T *data,IN UINT_T len, OUT UCHAR_T *ret_data,OUT USHORT_T *ret_len));
    

    Sample code:

    int tuya_user_prod_test(USHORT_T cmd, UCHAR_T *data, UINT_T len, OUT UCHAR_T *ret_data, OUT USHORT_T *ret_len)
    {
    switch (cmd){
            // Test the LED indicator.
            case 0x0001:
                    USER_API_LOGI("user prod test, val:%d", data[0]);
                    /* Turn on the LED indicator */
                    *ret_len = sprintf((char *)ret_data, "%s", "{\"ret\":true}");
            break;
    /*
            Other test items.
    */
    }
    }
    
  • multi_dps_report_demo

    This function demonstrates how to report the status of multiple data points (DPs) in one packet. The functions for encoding the corresponding data types are called.

    tuya_user_api_lwdp_encode_string: Encode data of string type.
    tuya_user_api_lwdp_encode_bool: Encode data of Boolean type.
    tuya_user_api_lwdp_encode_int: Encode data of integer type.
    tuya_user_api_lwdp_encode_enum: Encode data of enum type.
    tuya_user_api_lwdp_encode_map: Encode data of map type.
    For more information, see `tuya_user_api.h`.
    
  • tuya_dp_write_cb

    This function demonstrates how to decode the commands received from the cloud. The functions for decoding the corresponding data types are called.

    tuya_user_api_lwdp_decode_string: Decode data of string type.
    tuya_user_api_lwdp_decode_bool: Decode data of Boolean type.
    tuya_user_api_lwdp_decode_int: Decode data of integer type.
    tuya_user_api_lwdp_decode_enum: Decode data of enum type.
    tuya_user_api_lwdp_decode_map: Decode data of map type.
    

    Sample code

    OBJ_SIZE created by tuya_user_api_lwdp_object_new must be greater than or equal to the number of the actual DPs. Otherwise, data reporting errors will occur. Make sure the DP to be reported matches the one you actually create. After reporting the data to the cloud, the SDK will release tuya_user_api_lwdp_object_free(OBJ_SIZE, dataP);.

    void dev_state_report(void)
    {
        USER_API_LOGD("###### dev_state_report ######");
    #define OBJ_SIZE 6
        uint8_t i = 0;
        lwdp_object_t* dataP = tuya_user_api_lwdp_object_new(OBJ_SIZE);
    
        if (dataP == NULL) {
            USER_API_LOGE("dataP == NULL");
            return;
        }
        dataP[i].id = DPID_RSSI;
        tuya_user_api_lwdp_encode_int(tuya_user_api_rssi_get(), &dataP[i++]);
    
        dataP[i].id = DPID_HEARTBEAT_INTERVAL;
        tuya_user_api_lwdp_encode_int(tuya_user_api_get_dev_lifetime(), &dataP[i++]);
    
        dataP[i].id = DPID_HEARTBEAT_TOTAL;
        tuya_user_api_lwdp_encode_int(packet_send_sum, &dataP[i++]);
    
        dataP[i].id = DPID_HEARTBEAT_SUCCESS;
        tuya_user_api_lwdp_encode_int(packet_send_succeed, &dataP[i++]);
    
        tuya_user_api_get_system_runtime(&on_time, NULL);
        dataP[i].id = DPID_POWON_TIME;
        tuya_user_api_lwdp_encode_int(on_time, &dataP[i++]);
    
        dataP[i].id = DPID_POWON_RST;
        tuya_user_api_lwdp_encode_int(tuya_user_api_get_powerOn_result(), &dataP[i++]);
    
        tuya_user_api_dp_report(true, i, dataP);
        tuya_user_api_lwdp_object_free(OBJ_SIZE, dataP);
    #undef OBJ_SIZE   
    }