Last Updated on : 2025-07-01 02:04:49download
This topic describes how to enable smart control and management of non-smart tools by integrating them as accessories through smart battery packs. This capability has three key features:
Offer a standardized Tuya integration solution for non-smart tools.
Enable smart control and OTA updates for non-smart tools based on smart battery packs, while displaying the non-smart tool’s RN page on the app.
Deliver a microapp management console for smart battery packs and non-smart tools, so brand owners can maintain relationships between battery packs and tools.
The baseline implementation transmits all data via a UINT8_T
pointer, with specific data handled at the application layer. For more information, see the demo tuyaos_demo_ble_accessory
.
typedef struct {
UINT8_T channle;
UINT32_T soft_version;
UINT32_T hard_version;
} accessory_fw_info_t;
typedef struct {
UINT8_T *p_accessory_fw_info;
UINT8_T device_id[DEVICE_ID_LEN];
UINT8_T common_pid[TUYA_BLE_PRODUCT_ID_MAX_LEN];
tuya_ble_product_id_type_t pid_type;
UINT8_T pid_len;
UINT8_T accessory_fw_info_len;
UINT8_T device_id_len;
UINT8_T connect_status; //1-connect 0-disconnect
UINT8_T port_id;
UINT8_T active_status; //1-active 0-not active
UINT16_T short_id;
} tuya_ble_accessory_connection_info_t;
/**@brief Structure about the accessory active information. */
typedef struct {
UINT32_T info_crc;
UINT16_T info_len;
UINT16_T short_id;
UINT8_T device_id[DEVICE_ID_LEN];
} tuya_ble_accessory_active_info_t;
/**@brief Structure about the accessory ID information. */
typedef struct {
UINT8_T id_type;
UINT8_T id_len;
UINT16_T short_id;
} tuya_ble_accessory_id_info_t;
All event handling is invoked within the tuya_ble_protocol_callback
function.
Communication is mediated through the Bluetooth sub-device, which enables bidirectional data transmission between accessories and the app by using pass-through commands.
TUYA_BLE_CB_EVT_WITH_SRC_TYPE_DP_DATA_RECEIVED
Receive DP data along with the data source, and transparently transmit the received data to accessories.
case TUYA_BLE_CB_EVT_WITH_SRC_TYPE_DP_DATA_RECEIVED: {
/* Determine the data source*/
if (event->dp_data_with_src_type_received_data.src_type != DATA_SOURCE_TYPE_ACCESSORY_EQUIPMENT) {
break;
}
/* Verify whether the device information meets requirements */
p_id_info = (tuya_ble_accessory_id_info_t*)event->dp_data_with_src_type_received_data.p_add_info;
if ((p_id_info->id_type != 0) || (p_id_info->id_len != 2)) {
TAL_PR_ERR("TUYA_BLE_CB_EVT_WITH_SRC_TYPE_DP_DATA_RECEIVED id info error.");
break;
}
/* Check if it is a matched accessory based on short ID */
if (tuya_ble_accessory_connection_info_find_by_short_id(p_id_info->short_id, &info_index) == TRUE) {
/* Transmit raw data to accessories*/
tuya_ble_accessory_uart_cmd_dp_data_send_to_accessory(accessory_info[info_index].port_id, event->dp_data_with_src_type_received_data.sn, event->dp_data_with_src_type_received_data.p_data, event->dp_data_with_src_type_received_data.data_len);
/* Report to the app */
tuya_ble_dp_data_with_src_type_send(event->dp_data_with_src_type_received_data.sn, DATA_SOURCE_TYPE_ACCESSORY_EQUIPMENT, DP_SEND_TYPE_ACTIVE, DP_SEND_FOR_CLOUD_PANEL, DP_SEND_WITHOUT_RESPONSE, \
event->dp_data_with_src_type_received_data.add_info_len, event->dp_data_with_src_type_received_data.p_add_info, \
event->dp_data_with_src_type_received_data.p_data, event->dp_data_with_src_type_received_data.data_len);
} else {
TAL_PR_ERR("unknown device: %d", p_id_info->short_id);
}
} break;
TUYA_BLE_CB_EVT_WITH_SRC_TYPE_DP_QUERY
Query the DP data with the data source.
case TUYA_BLE_CB_EVT_WITH_SRC_TYPE_DP_QUERY: {
/* Determine the data source*/
if (event->dp_query_data_with_src_type.src_type != DATA_SOURCE_TYPE_ACCESSORY_EQUIPMENT) {
break;
}
/* Verify whether the device information meets requirements */
p_id_info = (tuya_ble_accessory_id_info_t*)event->dp_query_data_with_src_type.p_add_info;
if ((p_id_info->id_type != 0) || (p_id_info->id_len != 2)) {
TAL_PR_ERR("TUYA_BLE_CB_EVT_WITH_SRC_TYPE_DP_QUERY id info error.");
break;
}
/* Check if it is a matched accessory based on short ID */
if (tuya_ble_accessory_connection_info_find_by_short_id(p_id_info->short_id, &info_index) == TRUE) {
TAL_PR_HEXDUMP_DEBUG("DP Query - accessory:", event->dp_query_data_with_src_type.p_data, event->dp_query_data_with_src_type.data_len);
/*Send work status*/
tuya_ble_accessory_uart_cmd_send_work_mode(accessory_info[info_index].port_id);
/*Send dp query*/
tuya_ble_accessory_uart_cmd_dp_query(accessory_info[info_index].port_id, event->dp_query_data_with_src_type.p_data, event->dp_query_data_with_src_type.data_len);
} else {
TAL_PR_DEBUG("unknown device: %d", p_id_info->short_id);
}
} break;
TUYA_BLE_CB_EVT_DP_DATA_WITH_SRC_TYPE_SEND_RESPONSE
Respond to DP data reporting with the data source.
case TUYA_BLE_CB_EVT_DP_DATA_WITH_SRC_TYPE_SEND_RESPONSE: {
/* Determine the data source*/
if (event->dp_with_src_type_send_response_data.src_type != DATA_SOURCE_TYPE_ACCESSORY_EQUIPMENT) {
break;
}
/* Verify whether the device information meets requirements */
p_id_info = (tuya_ble_accessory_id_info_t*)event->dp_with_src_type_send_response_data.p_add_info;
if ((p_id_info->id_type != 0) || (p_id_info->id_len != 2)) {
TAL_PR_ERR("TUYA_BLE_CB_EVT_DP_DATA_WITH_SRC_TYPE_SEND_RESPONSE id info error.");
break;
}
/* Check if it is a matched accessory based on short ID */
if (tuya_ble_accessory_connection_info_find_by_short_id(p_id_info->short_id, &info_index) == TRUE) {
TAL_PR_DEBUG("DP Send Respondse - accessory:sn:0x%08X,type:%d,mode:%d,ack:%d,status:%d", event->dp_with_src_type_send_response_data.sn,\
event->dp_with_src_type_send_response_data.type, event->dp_with_src_type_send_response_data.mode, event->dp_with_src_type_send_response_data.ack, event->dp_with_src_type_send_response_data.status);
} else {
TAL_PR_ERR("unknown device: %d", p_id_info->short_id);
}
} break;
TUYA_BLE_CB_EVT_DP_DATA_WITH_SRC_TYPE_AND_TIME_SEND_RESPONSE
Respond to DP data reporting with the data source and timestamp.
case TUYA_BLE_CB_EVT_DP_DATA_WITH_SRC_TYPE_AND_TIME_SEND_RESPONSE: {
/* Determine the data source*/
if (event->dp_with_src_type_and_time_send_response_data.src_type != DATA_SOURCE_TYPE_ACCESSORY_EQUIPMENT) {
break;
}
/* Verify whether the device information meets requirements */
p_id_info = (tuya_ble_accessory_id_info_t*)event->dp_with_src_type_and_time_send_response_data.p_add_info;
if ((p_id_info->id_type != 0) || (p_id_info->id_len != 2)) {
TAL_PR_ERR("TUYA_BLE_CB_EVT_DP_DATA_WITH_SRC_TYPE_AND_TIME_SEND_RESPONSE id info error.");
break;
}
/* Check if it is a matched accessory based on short ID */
if (tuya_ble_accessory_connection_info_find_by_short_id(p_id_info->short_id, &info_index) == TRUE) {
TAL_PR_DEBUG("DP Send Respondse - accessory:sn:0x%08X,type:%d,mode:%d,ack:%d,status:%d", event->dp_with_src_type_and_time_send_response_data.sn,\
event->dp_with_src_type_and_time_send_response_data.type, event->dp_with_src_type_and_time_send_response_data.mode, event->dp_with_src_type_and_time_send_response_data.ack, event->dp_with_src_type_and_time_send_response_data.status);
} else {
TAL_PR_ERR("unknown device,%d", p_id_info->short_id);
}
} break;
Accessories and sub-devices communicate via UART using custom commands in the protocol, which only requires implementation at the application layer.
VOID_T tuya_ble_custom_app_uart_common_process(UINT8_T *p_in_data, UINT16_T in_len);
This function is defined as weak in the underlying layer and implemented at the application layer. The compiler will prioritize linking the application-layer version when implemented. The underlying layer has already completed data parsing and forwarding. All input data consists of accessory-reported packets, so you only need to process the received data by calling this interface.
VOID_T tuya_ble_accessory_uart_protocol_process(UINT8_T port_id, UINT8_T *p_in_data, UINT16_T in_len);
The interface handles all commands for interacting with accessories.
TUYA_BLE_ACCESSORY_UART_CMD_OTA_REQUEST
TUYA_BLE_ACCESSORY_UART_CMD_OTA_FILE_INFO
TUYA_BLE_ACCESSORY_UART_CMD_OTA_FILE_OFFSET
TUYA_BLE_ACCESSORY_UART_CMD_OTA_DATA
TUYA_BLE_ACCESSORY_UART_CMD_OTA_END
TUYA_BLE_ACCESSORY_UART_CMD_HANDUP
TUYA_BLE_ACCESSORY_UART_CMD_DEVICE_INFO_REPORT
TUYA_BLE_ACCESSORY_UART_CMD_DP_DATA_REPORT
TUYA_BLE_ACCESSORY_UART_CMD_QUERY_MODULE_MAC
TUYA_BLE_ACCESSORY_UART_CMD_FATORY_CMD
For more information, see the demo tuyaos_demo_ble_accessory
.
// This capability is not supported by default and needs to be enabled through macro definition.
#define TUYA_BLE_ACCESSORY_MOUNT_SUPPORTED 1
// The baseline shall support multi-source data transmission.
#define TUYA_BLE_MUTI_DATA_SOURCE_SUPPORTED 1
// And general serial port capabilities.
#define TUYA_BLE_FEATURE_UART_COMMON_ENABLE 1
Non-smart accessories communicate with the battery pack via UART. The specifications are as follows:
Baud: 9600
Data length: 8 bits
Stop bit: 1
Flow control: none
The RX pin of the battery pack is configured with a weak pull-down while the TX pin of the accessory uses a pull-up resistor. The battery pack periodically checks the RX pin’s state. A sustained pull-down indicates accessory disconnection (offline status), a triggered high level initiates a handshake command, and a successful handshake confirms online status.
The Bluetooth accessory capability is an advanced feature that requires additional PID activation. For more information, contact Tuya’s account manager.
If you have any problems with TuyaOS development, you can post your questions in the Tuya Developer Forum.
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback