本示例演示了使用 TuyaOS 综合 SDK 把IPC网关设备接入到涂鸦 IoT 平台,并实现子设备的入网、指令控制、数据上报、OTA、实时预览、存储回放等功能。

  1. Ubuntu 开发环境。
  2. 涂鸦 IoT 平台 上创建IPC网关和子设备产品。

在开始开发前,我们需要了解 SDK 的初始化流程,这里需要重点关注这几个接口的调用顺序:tuya_iot_inittuya_iot_set_gw_prod_infotuya_iot_sdk_pre_inittuya_iot_sdk_inittuya_iot_sdk_start ,必须按顺序执行。

SDK 初始化流程如下图所示:

常用的头文件:

头文件名称

功能

tuya_iot_com_api.h

封装了 IoT 通用接口,常用的有获取 SDK 信息接口、IoT 基础服务初始化接口、数据点上报接口、获取数据点属性值接口、OTA 接口等。

tuya_iot_sdk_api.h

封装了 SDK 接口,主要是 SDK 预初始化接口、SDK 初始化接口、SDK 启动接口等。

tuya_gw_dp_mgr.h

提供了设备数据点管理回调注册接口,SDK -> Application

tuya_gw_protocol_mgr_user.h

提供了子设备管理回调注册接口,SDK -> Application

uni_log.h

封装了日志打印接口。

常用的接口:

接口名称

接口说明

tuya_iot_init()

IoT 基础服务初始化接口,SDK 所有服务和数据都依赖该接口。

tuya_iot_set_gw_prod_info()

设置产品授权信息接口,也就是 UUID 和 AUTHKEY,必须保证一机一码。

tuya_iot_reg_gw_app_cb()

注册网关应用回调接口,如设备升级、设备重置、设备重启、远程获取日志等通知。

tuya_iot_sdk_reg_netstat_cb()

注册联网状态、有线状态、无线状态变更通知接口。

tuya_iot_sdk_pre_init()

SDK 预备初始化接口。

tuya_iot_sdk_init()

SDK 初始化接口。

tuya_iot_sdk_start()

SDK 启动接口。

tuya_subdev_user_sigle_type_reg()

注册子设备管理接口,如子设备添加、移除、重置、升级、指令下发、心跳查询等通知。

tuya_gw_user_dp_reg()

注册设备数据点管理接口。

dev_report_dp_json_async()

上报 OBJ 类型数据点接口。

dev_report_dp_raw_sync()

上报 RAW 类型数据点接口。

tuya_iot_set_dev_hb_cfg()

配置子设备心跳超时接口,需要在应用启动和绑定子设备时进行配置。

tuya_iot_fresh_dev_hb()

刷新子设备心跳,在 tuya_iot_set_dev_hb_cfg 接口设置的超时时间内刷新心跳,在超时时间内没调用该接口子设备则显示为离线。

tuya_iot_gw_bind_dev()

子设备绑定到涂鸦 IoT 平台接口。

tuya_iot_dev_traversal()

遍历所有子设备接口。

tuya_iot_upgrade_dev()

子设备升级固件下载接口。

tuya_iot_dev_upgd_progress_rept()

子设备升级进度上报接口。

本示例工程使用 JSON 配置文件,把可配置的参数统一放到配置文件中,配置文件如下:

{
    "pid": "YOUR_PID",
    "uuid": "YOUR_UUID",
    "authkey": "YOUR_AUTHKEY",
    "storage_path": "./",
    "log_level": 4,
    "tuya" :{
		"ipc" : {
			"storage_path": "./",
			"media_path" : "./"
		}
	}
}

字段说明:

字段

必须

说明

pid

设备产品 ID,在 涂鸦 IoT 平台 上创建网关产品时由平台生成。

uuid

授权信息,与 authkey 为一对,必须填写自己申请的 UUID。

authkey

授权信息,与 uuid 为一对,必须填写自己申请的 AUTHKEY。

log_level

日志等级,默认是 debug。

storage_path

存储路径,需要有可读性权限,必须以 ‘/' 结束。

SDK 是跨平台的设计,定义了一套标准的 TuyaOS Kernel Layer (简称 TKL)接口来屏蔽系统的差异,接口的定义在 SDK 框架开发包的 adapter 目录。系统适配接口需要由您实现,本示例代码提供了 Linux 系统通用实现,实现代码在示例工程的 tuyaos_adapter 目录。

在本示例中,我们主要关注有线配网的适配接口,使用示例工程提供的通用实现,需要修改 tuyaos_adapter/wired/tkl_wired.c 文件,把 WIRED_IFNAME 的值修改成您使用的网络接口名称。

注意,确保指定的网络接口跟手机在同一个局域网下,手机才能自动发现设备。

配网激活的适配开发指南,请参考 配网激活

上面的启功流程已经介绍了,客户可以SDK init后执行自己的service init(下文称INIT_POINT),也可以在SDK start后启动自己的service start(下文称START_POINT),对于IPC来说,有些业务需要在设备上线后进行初始化,也就是mqtt上线后(下文称MQTT_POINT)。 IPC的业务主要包括实时预览、SD卡存储、SD卡回放、云存储、事件报警等功能,下面针对每个功能对接和启动时机来进行分别介绍。

Ringbuffer对接

初始化

Ringbuffer是所有流媒体业务的基础,可以在START_POINT中开始初始化。 初始化具体代码可以参考user_ipc_ringbuf_demo.cOPERATE_RET TUYA_APP_Init_Ring_Buffer(CONST IPC_MEDIA_INFO_T *pMediaInfo)

使用

ringbuf需要调用open或者close接口来申请和释放句柄,后续其他操作均需要句柄的标识。

/** @brief open a new session for read/write
 * @param[in]     device   device number
 * @param[in]     channel  channel number in device
 * @param[in]     stream   stream number in channel
 * @param[in]     open_type  open type
 * @return user handle
*/
RING_BUFFER_USER_HANDLE_T tuya_ipc_ring_buffer_open(INT_T device, INT_T channel, IPC_STREAM_E stream, RBUF_OPEN_TYPE_E open_type);

/** @brief close session
 * @warning open/close should be called in pair like file
 * @param[in]   handle      user handle return by open
 * @return error code
 * - OPRT_OK      success
 * - Others       failed
*/
OPERATE_RET tuya_ipc_ring_buffer_close(RING_BUFFER_USER_HANDLE_T handle);

客户从编码器中读到视频帧、音频帧后,可以参考user_ipc_ringbuf_demo.cOPERATE_RET TUYA_APP_Put_Frame(RING_BUFFER_USER_HANDLE_T handle, IN CONST MEDIA_FRAME_T *p_frame)的实现,把数据帧送入ringbuf中。

流媒体业务对接

媒体适配层接入

1、媒体适配层是IPC业务需要依赖的,屏蔽硬件差异的接口。涂鸦SDK内部对音视频硬件资源的访问均会通过此层接口。 主要包括以下部分: 抓图回调 : 根据内存大小来抓图 音频播放回调 :根据参数来播放音频,要求异步非阻塞 视频播放回调 :无需关注 文件接收回调 : 无需关注 2、除以上接口外,涂鸦SDK需要外部统一注册音视频参数规格,包含音视频编码格式、码率等信息,参考结构体DEVICE_MEDIA_INFO_T。 3、参考VOID IPC_APP_Media_Adapter_Init()中的实现,在在START_POINT中调用。 4、媒体适配层需外部注册音视频缓冲区,使用ringbuf的情况下,可以ringbuf和媒体适配层初始化后直接调用: OPERATE_RET tuya_ipc_ring_buffer_adapter_register_media_source()启用ringbuf作为音视频缓冲区。

音视频传输模块

初始化

该模块内部包含P2P、web RTC、涂鸦私有转发等模块。统一使用OPERATE_RET tuya_ipc_media_stream_init(MEDIA_STREAM_VAR_T *stream_var)进行模块的初始化。 常供电设备建议在MQTT_POINT进行初始化 参数中max_client_num为同时支持的最大连接数量。on_event_cb为事件通知回调,会将一些app操作通知到外部,比如开始拉流、结束拉流等。

回调处理

on_event_cb是流媒体传输模块最主要的对接内容。所有会回调出来的事件均在tuya_ipc_media_stream_event.hMEDIA_STREAM_EVENT_E定义中,客户可以根据自己的需要来对接不同的事件。这部分内容可以参考user_ipc_p2p_demo.cINT_T __TUYA_APP_p2p_event_cb(IN CONST INT_T device, IN CONST INT_T channel, IN CONST MEDIA_STREAM_EVENT_E event, IN PVOID_T args)的实现。

SD卡存储对接

初始化

MQTT_POINT参考user_ipc_storage_demo.cOPERATE_RET TUYA_APP_Init_Stream_Storage(CHAR_T *storage_path)的实现

录像控制

方式一

参考tuya_ipc_stream_storage.h中接口

方式二

使用tuya_ipc_start_storage(E_ALARM_SD_STORAGE);开启录像 使用tuya_ipc_stop_storage(E_ALARM_SD_STORAGE)结束录像

云存储对接

初始化

MQTT_POINT参考user_ipc_storage_demo.cOPERATE_RET TUYA_APP_Enable_CloudStorage()的实现

录像控制

方式一

使用OPERATE_RET tuya_ipc_cloud_storage_event_start(VOID)开始录像 使用OPERATE_RET tuya_ipc_cloud_storage_event_stop(VOID)结束录像

方式二

使用tuya_ipc_start_storage(E_ALARM_CLOUD_STORAGE);开启录像 使用tuya_ipc_stop_storage(E_ALARM_CLOUD_STORAGE)结束录像

事件报警对接

初始化

因为事件报警的消息是通过mqtt发送的,所以建议模块在MQTT_POINT进行初始化。 参考user_ipc_notify_demo.cOPERATE_RET IPC_APP_event_module_init()

报警上报

参考user_ipc_motion_detect_demo.c中移动侦测整个逻辑的处理,当事件发生时,使用OPERATE_RET tuya_ipc_notify_alarm(CONST CHAR_T *snap_buffer, CONST UINT_T snap_size, CONST NOTIFICATION_NAME_E name, BOOL_T is_notify)上报事件。参数中name为报警类型,is_notify是是否上报到消息中心(对应APP中移动侦测开关的选项)。

通过 IDE 编译本项目,编译成功后会生成一个可执行程序,位于 TuyaOS/output/tuyaos_demo_ipc_<版本号> 目录下,其中版本号是编译时提示您输入的版本号。本示例的配置文件也会自动拷贝到该目录下。

切换到该目录,直接运行程序即可,会看到类似如下的打印信息:

...
[01-01 00:00:00 TUYA D][tuya_ws_db.c:450] init fs. Path: ./
[01-01 00:00:00 TUYA I][kv_storge.c:45] Init Kvs With File:./
[01-01 00:00:00 TUYA D][simplekv.c:928] path:./
[01-01 00:00:00 TUYA D][simplekv.c:964] get encrypt_key[⚌⚌⚌US⚌⚌⚌⚌ykR⚌⚌]
[01-01 00:00:00 TUYA D][simplekv.c:995] both file exist
...
[01-01 00:00:05 TUYA D][tuya_svc_lan.c:838] udp ip: 192.168.1.20
...

程序运行后,打开智慧生活 App,使用 自动发现功能 添加网关设备。

  1. 如何修改 PID、UUID 和 AUTHKEY?
    如果没有修改示例的源代码,编辑 config.json 配置文件,修改 pid/uuid/authkey 字段的值就可以。
  2. 自动发现不了网关设备?
    确认一下手机和网关是不是在同一个局域网,网关可以通过查看日志,观察是否选择正确的网口,打印示例:
    [01-01 00:00:05 TUYA D][tuya_svc_lan.c:838] udp ip: 192.168.1.20