更新时间:2024-11-15 07:43:36下载pdf
涂鸦 IoT Core SDK 使用 C 语言实现,支持涂鸦设备模型协议,适用于开发者自主开发硬件设备逻辑业务接入涂鸦。
涂鸦 IoT Core SDK 提供设备激活、发送上下行 DP 和固件 OTA 升级等基础业务接口封装。SDK 不依赖具体设备平台及操作系统环境,也可以运行在单任务环境。仅需要支持 TCP/IP 协议栈及提供 SDK 必要的系统依赖接口,即可完成接入。
您可以在 涂鸦 GitHub 仓库 下载 IoT Core SDK。
该 SDK 的 C 代码文件通过以下目录结构提供:
文件 | 说明 |
---|---|
certs |
设备私钥,设备证书,服务端 CA 根证书 |
docs |
参考文档 |
libraries |
外部依赖库,包含 MQTT client、HTTP client、mbedTLS 等 |
interface |
平台必要移植接口,SDK 功能接口 |
include |
SDK 有文件,包含了 SDK API |
src |
SDK 源代码 |
platform |
平台移植接口适配 |
utils |
通用工具模块 |
examples |
例程 |
您需要在涂鸦开发者平台创建产品,获取授权信息,然后将产品和授权相关信息写入到代码中,实现云服务的接入。详细步骤如下:
登录 涂鸦开发者平台。
单击 创建产品。
选择 行业解决方案 > 智慧工业 > 工业网关 品类。
在 智能化方式 区域选择 生态设备接入,并填写产品相关信息,完成产品创建。
在 功能定义 界面,单击 添加功能 并填写相关参数,完成产品功能定义。
在 设备开发 界面,选择并下载 SDK 方案,单击 下一步 进入激活信息获取页面。
领取授权码,然后单击 注册设备。设备相应信息会显示在下方。
涂鸦提供免费的授权码供测试使用,您可以免费领取 2 个激活码。
将注册的设备信息,填写到 examples/subdevice_basic_demo/subdevice_basic_demo.c
文件中,编译并运行 Demo 即可连接云服务,关于编译的具体流程,请参考下文 编译执行 章节内容。
const char productId[] = "rwosj58aaqjk **** ";
const char deviceId[] = "6c95875d0f5ba69607 **** ";
const char deviceSecret[] = " ******************* ";
可通过购买授权码,在设备管理页面进行设备注册,获取 productId
、deviceId
、deviceSecret
等信息。
本小节以 Ubuntu 系统为例,介绍 SDK 编译步骤。本节介绍同样适用于 Debian 系统。
安装 make
等相关环境依赖。
sudo apt-get install make cmake
进入获取到的 SDK 文件内,新建一个 build
文件夹并且进入该文件夹,输入 cmake..
先进行环境编译,再输入 make
开始编译固件。编译完成后,固件会生成在 build 文件夹下的 bin 文件夹。
mkdir build && cd build
cmake ..
make
进入 bin 文件夹,运行 Demo。SDK 内置了基础的通信 Demo 代码,例如子设备管理基础 Demo。
./bin/subdevice_basic_demo
在设备端查看运行接口。
以下日志显示设备与云端连接成功。
设备成功连接到涂鸦开发者平台后,单击进行刷新,设备状态会显示为在线。
实例化和初始化一个设备对象 tuya_iot_client_t
,用来初始化产品 ID 和授权信息等配置参数。
/* instantiate the client */
tuya_mqtt_context_t* client = &client_instance;
/* initialize the client */
ret = tuya_mqtt_init(client, &(const tuya_mqtt_config_t) {
.host = "m2.tuyacn.com",
.port = 8883,
.cacert = tuya_cacert_pem,
.cacert_len = sizeof(tuya_cacert_pem),
.device_id = deviceId,
.device_secret = deviceSecret,
.keepalive = 60,
.timeout_ms = 2000,
.on_connected = on_connected,
.on_disconnect = on_disconnect,
.on_messages = on_messages
});
定义应用层事件回调,回调函数用于应用层接收 SDK 事件通知,如数据功能点(DP)下发,云端连接状态通知。
/* Tuya SDK event callback */
void on_messages(tuya_mqtt_context_t* context, void* user_data, const tuyalink_message_t* msg)
{
TY_LOGI("on message id:%s, type:%d, code:%d", msg->msgid, msg->type, msg->code);
switch (msg->type) {
case THING_TYPE_MODEL_RSP:
TY_LOGI("Model data:%s", msg->data_string);
break;
case THING_TYPE_PROPERTY_SET:
TY_LOGI("property set:%s", msg->data_string);
break;
case THING_TYPE_PROPERTY_REPORT_RSP:
break;
default:
break;
}
printf("\r\n");
}
启动 TuyaOS SDK 服务。
ret = tuya_mqtt_connect(client);
//TuyaOS SDK 服务任务,数据接收处理,设备在线保活等任务处理:
循环调用将当前线程产生给底层的 Link SDK 客户端。
tuya_mqtt_loop(client);
定义上报函数,调用相关上报接口函数实现数据上报。下方示例为产品连接时,将部分产品数据上报到云端。您可以根据自己产品的数据上报需求,参考该函数编写自身应用代码。
void on_connected(tuya_mqtt_context_t* context, void* user_data)
{
TY_LOGI("on connected");
/* data model test code */
tuyalink_thing_data_model_get(context, NULL);
tuyalink_thing_desired_get(context, NULL, "[\"power\"]");
tuyalink_thing_property_report(context, NULL, "{\"power\": {\"value\":1234,\"time\":1631708204231}}");
tuyalink_thing_property_report_with_ack(context, NULL, "{\"power\":{\"value\":1234,\"time\":1631708204231}}");
tuyalink_thing_event_trigger(context, NULL, "{\"eventCode\":\"boom\",\"eventTime\":1626197189630,\"outputParams\":{\"param1\":100}}");
tuyalink_thing_batch_report(context, "{\"msgId\":\"45lkj3551234001\",\"time\":1626197189638,\"sys\":{\"ack\":1},\"data\":{\"properties\":{\"power\":{\"value\":11,\"time\":1626197189638}},\"events\":{\"boom\":{\"outputParams\": {\"param1\":\"10\"},\"eventTime\":1626197189001}}}}");
}
/*数据上报 API*/
/* data model code */
tuyalink_thing_data_model_get(context, NULL);
tuyalink_thing_desired_get(context, NULL, "[\"power\"]");
tuyalink_thing_property_report(context, NULL, "{\"power\":{\"value\":1234,\"time\":1631708204231}}");
tuyalink_thing_property_report_with_ack(context, NULL, "{\"power\":{\"value\":1234,\"time\":1631708204231}}");
tuyalink_thing_event_trigger(context, NULL, "{\"eventCode\":\"boom\",\"eventTime\":1626197189630,\"outputParams\":{\"param1\":100}}");
tuyalink_thing_batch_report(context, "{\"msgId\":\"45lkj3551234001\",\"time\":1626197189638,\"sys\":{\"ack\":0},\"data\":{\"properties\":{\"power\":{\"value\":11,\"time\":1626197189638}},\"events\":{\"boom\":{\"outputParams\":{\"param1\":\"10\"},\"eventTime\":1626197189001}}}}");}
/* subdevice code */
tuyalink_subdevice_bind(context, "[{\"productId\":\"jtwe4q9jrs0bbc8q\",\"nodeId\":\"123456\",\"clientId\":\"123455asdf\"}]");
tuyalink_subdevice_bind_login(context, "[\"6c17c5ba952143f592b8g1\",\"6c41626e5cea758aees0ik\"]");
tuyalink_subdevice_bind_logout(context, "[\"6c17c5ba952143f592b8g1\"]");
tuyalink_subdevice_topo_add(context, "[{\"productId\":\"jtwe4q9jrs0bbc8q\",\"deviceId\":\"6c17c5ba952143f592b8g1\",\"sign\":\"366508ed895644e70a3006bdef2dbe77ef73e18a\",\"signMethod\":\"hmacSha1\",\"timestamp\":\"1636989480\"}]");
tuyalink_subdevice_topo_delete(context,"[\"6c41626e5cea758aees0ik\"]");
tuyalink_subdevice_topo_get(context);
设备成功连接 MQTT 服务器并上线后,可以在涂鸦开发者平台 设备调试 页面对设备进行调试。
进入 设备调试 页面,单击 选择设备,填入上线设备的 DeviceID,即可获取到设备当前定义的功能点合集。
设备操作的日志信息都会显示在右侧实时日志处,您可以通过日志确认设备当前的信息。
单击功能点操作列的 获取 选项,可以获取到当前设备的数据。
单击功能点操作列的 设置 选项,可以对设备当前的数据进行设置,日志处会显示当前云端下发的 payload 日志信息,通过本地 log 也可以看到云端下发的 payload 信息。
接口信息 | 说明 |
---|---|
函数原型 | int tuya_mqtt_init(tuya_mqtt_context_t* context, const tuya_mqtt_config_t* config); |
功能描述 | 设备初始化 |
输入参数 |
|
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuya_mqtt_connect(tuya_mqtt_context_t* context); |
功能描述 | 启动设备 SDK 服务 |
输入参数 | context :设备管理句柄 |
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuya_mqtt_disconnect(tuya_mqtt_context_t* context); |
功能描述 | 停止设备 SDK 服务 |
输入参数 | context :设备管理句柄 |
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuya_mqtt_loop(tuya_mqtt_context_t* context); |
功能描述 | SDK 后台运行服务 |
输入参数 | context :设备管理句柄 |
输出参数 | 无 |
返回值 | 参考通用错误码 |
备注 | 需要在程序主循环调用该服务函数 |
接口信息 | 说明 |
---|---|
函数原型 | int tuyalink_thing_data_model_get(tuya_mqtt_context_t* context, const char* device_id); |
功能描述 | 使用该函数获取设备的物模型 |
输入参数 |
|
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuyalink_thing_property_report(tuya_mqtt_context_t* context, const char* device_id, const char* data); |
功能描述 | 设备属性上报 |
输入参数 |
|
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuyalink_thing_property_report_with_ack(tuya_mqtt_context_t* context, const char* device_id, const char* data); |
功能描述 | 上报设备的属性并得到云端应答 |
输入参数 |
|
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuyalink_thing_event_trigger(tuya_mqtt_context_t* context, const char* device_id, const char* data); |
功能描述 | 设备事件响应 |
输入参数 |
|
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuyalink_thing_batch_report(tuya_mqtt_context_t* context, const char* data); |
功能描述 | 设备批量上报数据 |
输入参数 |
|
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuyalink_subdevice_bind(tuya_mqtt_context_t* context, const char* data); |
功能描述 | 子设备绑定 |
输入参数 |
|
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuyalink_subdevice_bind_login(tuya_mqtt_context_t* context, const char* data); |
功能描述 | 子设备上线 |
输入参数 |
|
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuyalink_subdevice_bind_logout(tuya_mqtt_context_t* context, const char* data); |
功能描述 | 子设备下线 |
输入参数 |
|
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuyalink_subdevice_topo_add(tuya_mqtt_context_t* context, const char* data); |
功能描述 | 子设备拓扑添加 |
输入参数 |
|
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuyalink_subdevice_topo_delete(tuya_mqtt_context_t* context, const char* data); |
功能描述 | 子设备拓扑删除 |
输入参数 |
|
输出参数 | 无 |
返回值 | 参考通用错误码 |
接口信息 | 说明 |
---|---|
函数原型 | int tuyalink_subdevice_topo_get(tuya_mqtt_context_t* context); |
功能描述 | 子设备拓扑获取 |
输入参数 | context :设备管理句柄 |
输出参数 | 无 |
返回值 | 参考通用错误码 |
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "cJSON.h"
#include "tuya_cacert.h"
#include "tuya_log.h"
#include "tuya_error_code.h"
#include "system_interface.h"
#include "mqtt_client_interface.h"
#include "tuyalink_core.h"
const char productId[] = "3jbcpefnn1jxxxxx";
const char deviceId[] = "6ced2aa564727c01xxxxx";
const char deviceSecret[] = "ac5d367db39xxxxx";
tuya_mqtt_context_t client_instance;
void on_connected(tuya_mqtt_context_t* context, void* user_data)
{
TY_LOGI("on connected");
/* data model test code */
tuyalink_thing_data_model_get(context, NULL);
tuyalink_thing_desired_get(context, NULL, "[\"power\"]");
tuyalink_thing_property_report(context, NULL, "{\"power\":{\"value\":1234,\"time\":1631708204231}}");
tuyalink_thing_property_report_with_ack(context, NULL, "{\"power\":{\"value\":1234,\"time\":1631708204231}}");
tuyalink_thing_event_trigger(context, NULL, "{\"eventCode\":\"boom\",\"eventTime\":1626197189630,\"outputParams\":{\"param1\":100}}");
tuyalink_thing_batch_report(context, "{\"msgId\":\"45lkj3551234001\",\"time\":1626197189638,\"sys\":{\"ack\":0},\"data\":{\"properties\":{\"power\":{\"value\":11,\"time\":1626197189638}},\"events\":{\"boom\":{\"outputParams\":{\"param1\":\"10\"},\"eventTime\":1626197189001}}}}");
}
void on_disconnect(tuya_mqtt_context_t* context, void* user_data)
{
TY_LOGI("on disconnect");
}
void on_messages(tuya_mqtt_context_t* context, void* user_data, const tuyalink_message_t* msg)
{
TY_LOGI("on message id:%s, type:%d, code:%d", msg->msgid, msg->type, msg->code);
switch (msg->type) {
case THING_TYPE_MODEL_RSP:
TY_LOGI("Model data:%s", msg->data_string);
break;
case THING_TYPE_PROPERTY_SET:
TY_LOGI("property set:%s", msg->data_string);
break;
case THING_TYPE_PROPERTY_REPORT_RSP:
break;
default:
break;
}
printf("\r\n");
}
int main(int argc, char** argv)
{
int ret = OPRT_OK;
tuya_mqtt_context_t* client = &client_instance;
ret = tuya_mqtt_init(client, &(const tuya_mqtt_config_t) {
.host = "m2.tuyacn.com",
.port = 8883,
.cacert = tuya_cacert_pem,
.cacert_len = sizeof(tuya_cacert_pem),
.device_id = deviceId,
.device_secret = deviceSecret,
.keepalive = 60,
.timeout_ms = 2000,
.on_connected = on_connected,
.on_disconnect = on_disconnect,
.on_messages = on_messages
});
assert(ret == OPRT_OK);
ret = tuya_mqtt_connect(client);
assert(ret == OPRT_OK);
for (;;) {
/* Loop to receive packets, and handles client keepalive */
tuya_mqtt_loop(client);
}
return ret;
}
该内容对您有帮助吗?
是意见反馈该内容对您有帮助吗?
是意见反馈