低功耗保活唤醒 2.0 开发指导

更新时间:2026-06-29 01:47:21LLM 副本以 Markdown 格式查看下载 PDF

本文档基于 tuya_ipc_low_power_api_v2.cty_sdk_lowpower.c 示例代码,介绍 IPC 低功耗保活唤醒 2.0 的实现流程,包含 DP 上报能力。

概述

低功耗 2.0 通过 TCP 长连接 与涂鸦低功耗保活服务器通信,设备休眠时维持连接,收到唤醒指令后再启动完整 IPC SDK。

对比项 1.0 2.0
加密 无/简单 AES-GCM(128/256)
心跳 固定心跳包 PINGREQ/PINGRESP
数据 原始字节 DATA 帧 + 可选 DATAACK
Client ID 设备 ID 加密 Client ID(服务端下发)

相关文件:

  • 协议实现:app_lowpower_sample_v2/src/tuya_ipc_low_power_api_v2.c
  • 头文件:app_lowpower_sample_v2/include/tuya_ipc_low_power_api_v2.h
  • 集成示例:app_main/src/ty_sdk_lowpower.c

接入前提

  • 设备类型配置为 LOW_POWER_DEV
  • 主控 SDK 已初始化并能联网(用于获取保活服务器信息)。
  • 具备 LocalKey(16 字节 AES-128 或 32 字节 AES-256)。
  • 通过 SDK 获取 加密 Client ID(非普通 Device ID)。
// 获取保活服务器(域名 + IP + 端口)
tuya_ipc_get_low_power_server_v2(domain, domain_len, &ip, &port);

// 获取加密 Client ID(2.0 专用,CONNECT 帧使用)
tuya_ipc_get_lowpower_v2_encrypt_devid(encrypt_devid, buf_len);

// 获取 LocalKey
tuya_ipc_get_local_key(local_key, &key_len);

协议帧类型

Type 方向 说明
CONNECT 0x01 设备 → 服务器 建连认证
CONNACK 0x02 服务器 → 设备 建连应答
PINGREQ 0x03 设备 → 服务器 心跳请求
PINGRESP 0x04 服务器 → 设备 心跳应答
DATA 0x05 双向 业务数据(加密)
DATAACK 0x06 双向 数据确认
DISCONNECT 0x07 双向 断开连接

通用帧头(4 字节,大端):

| Type (2B) | Remaining Length (2B) | Payload ... |

建连流程

设备                          保活服务器
 |---- TCP connect ----------->|
 |---- CONNECT (加密) --------->|
 |<--- CONNACK (加密) ----------|
 |     保存 Keepalive + Random |
 |---- PINGREQ (定时) -------->|
 |<--- PINGRESP ---------------|
 |<--- DATA (唤醒) ------------|
 |---- DATAACK (若需要) ------->|

CONNECT 要点

  • Version = 0x02
  • Encryption type:
    • 0x00:AES-128-GCM
    • 0x01:AES-256-GCM
  • Payload 包含:加密 Client ID、12 字节 Nonce、加密的 Keepalive 时长。
  • Keepalive 明文用 LocalKey 加密,无 AAD

CONNACK 要点

  • code == 0 表示成功。
  • 解密后得到:协商 Keepalive(2B) + 10 字节 Random 字符串
  • 后续 DATA/DATAACK 加密时,AAD = 该 Random 字符串。

API

INT_T tuya_ipc_low_power_v2_server_connect(
    TUYA_IP_ADDR_T serverIp, INT_T port,
    CHAR_T *devId, INT_T devIdLen,      // 加密 Client ID
    CHAR_T *pkey, INT_T keyLen,         // LocalKey,16 或 32 字节
    UINT16_T keepaliveSec               // 建议 60s
);

tuya_ipc_low_power_v2_server_connect 失败后必须 退避重试,不可立即连续重连(Demo 使用 10s × fail_cnt 间隔)。

保活与收发

心跳

  • select 超时(建议 = Keepalive 秒数)触发发送 PINGREQ。
  • PINGREQ 仅 4 字节帧头,Remaining Length = 0。
  • 收到 PINGRESP(00 04 00 00)后直接忽略。
tuya_ipc_low_power_v2_pingreq_get(ping_buf, &ping_len);
send(socket, ping_buf, ping_len, 0);

接收 DATA

TUYA_LP_V2_RECV_DATA_T recv_data;
UINT32_T payload_len = sizeof(buf);

tuya_ipc_low_power_v2_recv_data(&recv_data, buf, &payload_len);
// recv_data.type:0x00 = 唤醒,0x01 = 设备数据
// recv_data.ack_required:是否需要回 DATAACK
// recv_data.packet_id / data / data_len

发送 DATA(如上报 DP)

tuya_ipc_low_power_v2_create_data_packet(pkt, &pkt_len, payload, payload_len, FALSE);
send(socket, pkt, pkt_len, 0);

DATA 明文结构(6 字节头 + 业务数据):

| AckFlag (1B) | PacketId (4B) | Type (1B) | Payload ... |
  • Type = 0x01:设备数据(如 DP JSON)。
  • AckFlag & 0x01:要求对端回 DATAACK。

DATAACK

tuya_ipc_low_power_v2_dataack_get(ack_buf, &ack_len, packet_id);

线程安全

socket 收发需加锁,不要在持锁时做 select

// select 在锁外
tuya_ipc_low_power_v2_socket_lock();
send(...) / recv(...) / tuya_ipc_low_power_v2_recv_data(...);
tuya_ipc_low_power_v2_socket_unlock();

推荐集成步骤

独立线程启动保活

参考 ty_sdk_lowpower_start_demo(),在独立线程中运行保活逻辑,避免阻塞主流程。

连接保活服务器

// 优先域名解析 IP,失败再用 SDK 返回 IP,最多重试 3 次 + 退避
tal_net_gethostbyname(domain, TY_AF_INET, &tmp_ip);
tuya_ipc_low_power_v2_server_connect(tmp_ip, port, encrypt_devid, len, local_key, key_len, 60);

主循环

  • select 等待 socket 可读或超时。
  • 超时:发 PINGREQ。
  • 可读:先 Peek 判断 PINGRESP,否则 recv_data 解析 DATA。
  • type == TUYA_LP_V2_DATA_TYPE_WAKEUP启动完整 IPC SDK(唤醒主业务)。
  • ack_required:回 DATAACK。

休眠态上报 DP(可选)

// JSON 格式:{"protocol":4,"data":{"dps":{"1":true}}}
ty_sdk_lowpower_v2_send_dps(dp_array, dp_cnt);

退出清理

tuya_ipc_low_power_v2_disconnect_get(buf, &len, TUYA_LP_V2_DISCONNECT_NORMAL); // 可选
tuya_ipc_low_power_v2_server_close();

关键常量

常量 说明
TUYA_LP_V2_NONCE_LEN 12 GCM Nonce
TUYA_LP_V2_GCM_TAG_LEN 16 GCM Tag
TUYA_LP_V2_RANDOM_STRING_LEN 10 CONNACK 下发的 AAD
单帧最大长度 2048 实现内限制
socket 超时 8s 收发超时

与 1.0 的差异(迁移提示)

1.0 API 2.0 替代
tuya_ipc_low_power_server_connect tuya_ipc_low_power_v2_server_connect(多 Keepalive 参数)
tuya_ipc_low_power_heart_beat_get tuya_ipc_low_power_v2_pingreq_get
tuya_ipc_low_power_wakeup_data_get + 字节比对 recv_data.type == TUYA_LP_V2_DATA_TYPE_WAKEUP
普通 devid tuya_ipc_get_lowpower_v2_encrypt_devid
tuya_ipc_get_low_power_server tuya_ipc_get_low_power_server_v2(多域名)

常见问题

CONNECT 失败?

检查以下:

  • 加密 Client ID 是否正确(必须用 v2 接口获取)。
  • LocalKey 长度是否为 16/32 字节。
  • 网络是否可达。

收不到唤醒?

确认保活线程存活、PINGREQ 按时发送、CONNACK 后 Random 已保存(库内自动处理)。

DATA 解密失败?

确认 CONNACK 已成功;DATA 帧 AAD 为 CONNACK 中的 10 字节 Random。

IPv4、IPv6 的支持情况?

TUYA_IP_ADDR_T 支持 IPv4/IPv6,Demo 默认 IPv4,需按平台适配 tal_net_gethostbyname 地址族。

API 速查

函数 用途
tuya_ipc_low_power_v2_server_connect 建连 + 认证
tuya_ipc_low_power_v2_server_close 关闭连接
tuya_ipc_low_power_v2_socket_fd_get 获取 socket fd
tuya_ipc_low_power_v2_socket_lock/unlock 线程锁
tuya_ipc_low_power_v2_pingreq_get 构建心跳
tuya_ipc_low_power_v2_create_data_packet 构建上行 DATA
tuya_ipc_low_power_v2_recv_data 接收并解密 DATA
tuya_ipc_low_power_v2_dataack_get 构建 DATAACK
tuya_ipc_low_power_v2_disconnect_get 构建 DISCONNECT