HeyThings SDK应用指南


版本记录

版本号 修改日期 修改内容
v0.1 2021.03.16 描述SDK基本API的使用,旨在帮助开发者快速接入HeyThings平台

1 SDK Demo目录结构

demo_code/
├── app_src
│   ├── heythings_task.c
│   ├── heythings_task.h
│   ├── user_task.c
│   ├── user_task.h
│   ├── include
│   │   ├── hey_schema_api.h
│   │   └── heythings.h
│   ├── schema
│   │   └── softwareUpdate
│   │       ├── softwareUpdate.pb-c.c
│   │       ├── softwareUpdate.pb-c.h
│   │       ├── softwareUpdate.proto
│   │       ├── software_update_service.c
│   │       └── software_update_service.h
│   │   └── ...
│   └── service
│       └── software_update_user.c
│       └── ...
└── main.c

include HeyThings RTOS SDK 提供的所有API

  • hey_schema_api.h 设备物模型接口,应用层通常无需直接使用,由 app_src/schema/[service name] 进行调用
  • heythings.h HeyThings RTOS SDK 提供的SDK初始化配置、启动和配网等功能

schema 物模型层代码,由HeyThings开放平台自动生成,其调用hey_schema_api.h接口,根据服务功能封装了[service name]_service.h 供应用层调用,该文件夹下应用层通常无需编辑。

service 同时生成[service name]_user.c,生成回调函数体,应用层需补充完整,提供完整的服务功能。

2 开始准备

在使用HeyThings RTOS SDK前,开发者应先熟悉所使用硬件平台的编译,应用创建。

3 SDK启动

应用层在其主函数中调用 heythings_run() 函数,如系统支持多线程,建议单独创建一个线程运行heythings_run()

在 heythings_task.c 的 heythings_run 函数中, 调用顺序如下:

  1. hey_sdk_init(&conf) 初始化配置产品信息和注册sdk状态相关回调函数,HeyThings RTOS SDK 提供的API在init之后都允许调用。
  2. device_services_init() 设备服务初始化,对于每个产品设备,通常有多个物模型,包含如通用模型 (softwareUpdate),在这个函数中,对每个物模型进行初始化,初始化可以设置物模型属性。
  3. hey_sdk_run() 这个函数最后调用,正常会阻塞不返回,sdk接管提供服务。

4 配网

  • hey_setup_start() 配网绑定配置的启动接口(必须) 参考 heythings_task.c 中 device_start_to_setup() 函数,初始化配网参数,并注册相关回调函数
  • hey_setup_confirm() 设备绑定确认接口(可选) 比如设备上有按键,在绑定过程中需要终端用户按按键,应用层调用该函数确认设备允许绑定
  • hey_setup_reset() 设备恢复出厂设置(必须)
    • 清除本地配网信息
  • hey_setup_get_state() 获取绑定状态
    • 重上电应用层可以调用此接口获取绑定状态

5 加入物模型层代码

在开放平台配置物模型,开放平台将自动生成所需物模型层代码,一般有5个文件,如 softwareUpdate 模型有如下文件:

software_update_service.c
software_update_service.h
softwareUpdate.pb-c.c
softwareUpdate.pb-c.h
software_update_user.c
  • 在 app_src/schema/ 下创建以该模型命名的文件夹,在文件夹下放 software_update_service.c software_update_service.h softwareUpdate.pb-c.c softwareUpdate.pb-c.h
  • 在 app_src/service 下放 software_update_user.c

[service name]_user.c 文件是需要应用层填写的,调用接口在 [service name]_service.h 中

5.1 属性使用

  • 属性更新
#include "robot_cleaner_service.h"

static struct robot_cleaner_properties prop;

static enum ROBOT_CLEANER_PROPERTY enumerate[3] = {
    ROBOT_CLEANER_PROPERTY_REMAINTIME,
    ROBOT_CLEANER_PROPERTY_ROBOTMODE,
    ROBOT_CLEANER_PROPERTY_CLEANAREA
};

prop.robotmode = ROBOT_CLEANER_ROBOT_MODE_ZIGZAG;
prop.remaintime = 100;
prop.cleanarea = 1;

int ret = robot_cleaner_properties_update(3, enumerate, &prop);
if (ret != 0) {
    //debug
}
  • 属性写回调
在 robot_cleaner_user.c 中
在 robot_cleaner_properties_write_cb 函数体内

int robot_cleaner_properties_write_cb(size_t count, unsigned int *enumerate, 
                                      struct robot_cleaner_properties *properties)
{
    // This is handled by the application layer
    for (int i = 0; i < count; i++) {
        switch (enumerate[i]) {
        case ROBOT_CLEANER_PROPERTY_POWER:
        break;
        case ROBOT_CLEANER_PROPERTY_MACHINESTATUS:
        break;
        case ROBOT_CLEANER_PROPERTY_ROBOTMODE:
        //get properties
        //properties->robotmode
        break;
        case ROBOT_CLEANER_PROPERTY_REPEATMODE:
        break;
        case ROBOT_CLEANER_PROPERTY_TURBOMODE:
        break;
        case ROBOT_CLEANER_PROPERTY_PROCESSINGPERCENTAGE:
        break;
        //...
        default:
        break;
        }
    }

    /**
    * please pay attention !!!
    * atfer properties setting is complete,
    * call properties update function to sync shadow 
    */
    robot_cleaner_properties_update(count, enumerate, properties);

    return 0;
}

5.2 动作使用

5.2.1 单次动作

  • 对端发起,sdk触发action call cb
在 robot_cleaner_user.c 中
在 robot_cleaner_robot_homing_call_cb 函数体内
int robot_cleaner_robot_homing_call_cb(struct hey_action_ctx *ctx,
                                       struct robot_cleaner_robot_homing_in *action)
{
    // This is handled by the application layer
    // 执行action
    struct robot_cleaner_robot_homing_out out;
    robot_cleaner_robot_homing_return(ctx, &out);
    return 0;
}

5.2.2 流式动作

  • 函数填写
在 software_update_user.c 中

struct user_action_context
{
    hey_action_ctx *ctx;
};

/**
 * @brief start update file action start callback of software update service
 * @param ctx          [action context]
 * @param action       [start update file action in]
 * @param user_context [user context record in SDK as needed, otherwise set it NULL]
 * @return int         [action start handle result, 0 means success]
 */
int software_update_start_update_file_start_cb(struct hey_action_ctx *ctx, 
                                               struct software_update_start_update_file_in *action, 
                                               void **user_context)
{
    // This is handled by the application layer
    // ctx needs to be saved by yourself
    // user_context can be assigned to SDK to record it for you as needed
    struct user_action_context *user_ctx = malloc(sizeof(struct user_action_context));
    if (user_ctx == NULL) {
        software_update_start_update_file_stop(ctx);
        return -1;
    }
    user_ctx->ctx = ctx;
    user_context = &user_ctx;

    return 0;
}

/**
 * @brief start update file action message receive callback of software update service
 * @param user_context [callback data which form action start callback function]
 * @param action       [start update file action in]
 * @return int         [action message callback handle result, 0 means success]
 */
int software_update_start_update_file_message_cb(void *user_context, 
                                                 struct software_update_start_update_file_in *action)
{
    // This is handled by the application layer
    // user_context is assigned to the SDK in the *_start_cb function
    // 保存升级文件
    struct software_update_start_update_file_out out;
    out.code = 0; // 仅举例用,以实际业务为准
    int ret = software_update_start_update_file_send((struct hey_action_ctx *)user_context->ctx, &out);
    if (ret != 0) {
        //debug
    }
    return 0;
}

/**
 * @brief start update file action stop callback of software update service
 *        closed by the peer, user must to call action stop function
 * @param user_context [callback data which form action start callback function]
 * @return none
 */
void software_update_start_update_file_stop_cb(void *user_context)
{
    // This is handled by the application layer
    /* User must call action stop function here !!!
     * for example: software_update_start_update_file_stop(ctx);
     */
    software_update_start_update_file_stop((struct hey_action_ctx *)user_context->ctx);
    free(user_context);
}

5.3 事件使用

  • 应用层主动调用notify
#include "robot_cleaner_service.h"

struct robot_cleaner_event_dust_box_full event;
struct event_notify_attr attr;
attr.importance = 0;
attr.ref_id = 0;
attr.timestamp = 0;
attr.cb_data = NULL;

int64_t ret = robot_cleaner_dust_box_full_notify(&event, &attr);
if (ret < 0)
{
    //debug error code = errno;
}
  • notify result callback
在 robot_cleaner_user.c 中

/**
 * @brief dust box full notify result callback of robot cleaner service
 * @param cb_data [registered callback data by user]
 * @param result  [the result of notify, 0 means success]
 * @return none
*/
void robot_cleaner_dust_box_full_notify_result_cb(void *cb_data, int result)
{
    // This is handled by the application layer
    if (result == 0) {
        //notify success
    }
}

6 编译

基于ESP32平台的demo:源码下载

results matching ""

    No results matching ""