This topic describes how to implement low-power keepalive and wake-up 2.0 for Internet Protocol cameras (IPCs). It is based on the sample code in tuya_ipc_low_power_api_v2.c and ty_sdk_lowpower.c and also covers data point (DP) reporting.
Low-power 2.0 uses a persistent Transmission Control Protocol (TCP) connection to communicate with the Tuya low-power keepalive server. While sleeping, the device keeps the connection alive and starts the full IPC SDK after it receives a wake-up command.
| Item | 1.0 | 2.0 |
|---|---|---|
| Encryption | None or simple | AES-GCM (128/256) |
| Heartbeat | Fixed heartbeat packet | PINGREQ/PINGRESP |
| Data | Raw bytes | DATA frame and optional DATAACK |
| Client ID | Device ID | Encrypted Client ID (issued by the server) |
Related files:
app_lowpower_sample_v2/src/tuya_ipc_low_power_api_v2.capp_lowpower_sample_v2/include/tuya_ipc_low_power_api_v2.happ_main/src/ty_sdk_lowpower.cLOW_POWER_DEV.// Get the keepalive server (domain name, IP address, and port).
tuya_ipc_get_low_power_server_v2(domain, domain_len, &ip, &port);
// Get the encrypted Client ID (2.0 only, used in the CONNECT frame).
tuya_ipc_get_lowpower_v2_encrypt_devid(encrypt_devid, buf_len);
// Get the LocalKey.
tuya_ipc_get_local_key(local_key, &key_len);
| Type | Value | Direction | Description |
|---|---|---|---|
| CONNECT | 0x01 | Device to server | Connection and authentication |
| CONNACK | 0x02 | Server to device | Connection acknowledgment |
| PINGREQ | 0x03 | Device to server | Heartbeat request |
| PINGRESP | 0x04 | Server to device | Heartbeat response |
| DATA | 0x05 | Bidirectional | Business data (encrypted) |
| DATAACK | 0x06 | Bidirectional | Data acknowledgment |
| DISCONNECT | 0x07 | Bidirectional | Disconnect |
Common frame header (4 bytes, big-endian):
| Type (2B) | Remaining Length (2B) | Payload ... |
Device Keepalive server
|----------- TCP connect ----------->|
|------- CONNECT (encrypted) ------->|
|<------- CONNACK (encrypted) -------|
| Save Keepalive + Random |
|------- PINGREQ (periodic) -------->|
|<------------ PINGRESP -------------|
|<--------- DATA (wake-up) ----------|
|------ DATAACK (if required) ------>|
0x020x00: AES-128-GCM0x01: AES-256-GCMcode == 0 indicates success.INT_T tuya_ipc_low_power_v2_server_connect(
TUYA_IP_ADDR_T serverIp, INT_T port,
CHAR_T *devId, INT_T devIdLen, // Encrypted Client ID
CHAR_T *pkey, INT_T keyLen, // LocalKey, 16 or 32 bytes
UINT16_T keepaliveSec // Recommended: 60s
);
If tuya_ipc_low_power_v2_server_connect fails, do not reconnect immediately. Retry after a backoff interval. The demo uses an interval of 10s × fail_cnt.
select timeout to the keepalive interval in seconds to trigger PINGREQ.00 04 00 00).tuya_ipc_low_power_v2_pingreq_get(ping_buf, &ping_len);
send(socket, ping_buf, ping_len, 0);
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 = wake-up, 0x01 = device data
// recv_data.ack_required: Whether DATAACK is required
// recv_data.packet_id / data / data_len
tuya_ipc_low_power_v2_create_data_packet(pkt, &pkt_len, payload, payload_len, FALSE);
send(socket, pkt, pkt_len, 0);
DATA plaintext structure (6-byte header and payload):
| AckFlag (1B) | PacketId (4B) | Type (1B) | Payload ... |
Type = 0x01: Device data (such as DP JSON)AckFlag & 0x01: Requests a DATAACK from the peertuya_ipc_low_power_v2_dataack_get(ack_buf, &ack_len, packet_id);
Lock the socket for send and receive operations. Do not call select while holding the lock.
// Call select outside the lock.
tuya_ipc_low_power_v2_socket_lock();
send(...) / recv(...) / tuya_ipc_low_power_v2_recv_data(...);
tuya_ipc_low_power_v2_socket_unlock();
Run the keepalive logic in a dedicated thread as shown in ty_sdk_lowpower_start_demo() to avoid blocking the main flow.
// Resolve the domain name to an IP first. If it fails, use the IP returned by the SDK. Retry up to three times with backoff.
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 to wait until the socket is readable or the timeout expires.recv_data to parse DATA.type == TUYA_LP_V2_DATA_TYPE_WAKEUP, start the full IPC SDK to resume normal application.ack_required is true, send a DATAACK.// JSON format: {"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); // Optional
tuya_ipc_low_power_v2_server_close();
| Constant | Value | Description |
|---|---|---|
TUYA_LP_V2_NONCE_LEN |
12 | GCM nonce |
TUYA_LP_V2_GCM_TAG_LEN |
16 | GCM tag |
TUYA_LP_V2_RANDOM_STRING_LEN |
10 | AAD from CONNACK |
| Maximum frame length | 2,048 | Implementation limit |
| Socket timeout | 8s | Send and receive timeout |
| 1.0 API | 2.0 API |
|---|---|
tuya_ipc_low_power_server_connect |
tuya_ipc_low_power_v2_server_connect (adds the keepalive parameter) |
tuya_ipc_low_power_heart_beat_get |
tuya_ipc_low_power_v2_pingreq_get |
tuya_ipc_low_power_wakeup_data_get and byte comparison |
recv_data.type == TUYA_LP_V2_DATA_TYPE_WAKEUP |
| Standard device ID | tuya_ipc_get_lowpower_v2_encrypt_devid |
tuya_ipc_get_low_power_server |
tuya_ipc_get_low_power_server_v2 (adds domain name) |
Check the following:
Verify that:
Confirm that CONNACK succeeded. The AAD for DATA frames is the 10-byte random string in the CONNACK payload.
TUYA_IP_ADDR_T supports IPv4 and IPv6. The demo defaults to IPv4. Adapt the address family of tal_net_gethostbyname according to the platform.
| Function | Purpose |
|---|---|
tuya_ipc_low_power_v2_server_connect |
Connect and authenticate |
tuya_ipc_low_power_v2_server_close |
Close the connection |
tuya_ipc_low_power_v2_socket_fd_get |
Get the socket file descriptor |
tuya_ipc_low_power_v2_socket_lock/unlock |
Use the thread lock |
tuya_ipc_low_power_v2_pingreq_get |
Build a heartbeat packet |
tuya_ipc_low_power_v2_create_data_packet |
Build an uplink DATA packet |
tuya_ipc_low_power_v2_recv_data |
Receive and decrypt DATA |
tuya_ipc_low_power_v2_dataack_get |
Build a DATAACK |
tuya_ipc_low_power_v2_disconnect_get |
Build a DISCONNECT |
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback